Okay, final lightning talk for today is Ludovic talking about geeks.
All right, thank you.
Hello HPC people.
So my name is Ludovic Cortes.
I work at INRIER, which is a French research institute in France in computer science.
And I work as a research engineer.
So I'm very much concerned about engineering issues in general.
And in particular, I'm concerned about deployment.
So if you're an HPC dev room aficionado, we've probably made before.
I gave a couple of talks, I guess, in this room, more specifically about geeks.
So maybe you're afraid about geeks.
It's a software deployment tool.
So we have Easy Builds Pack, also RPM, well, you know, app, et cetera.
And this is yet another deployment tool, if you will.
But we have this very particular vision where, you know, the grand vision where we're trying
to build a tool for reproducible research and HPC.
So the thing here that you see is the vision, so to speak.
So at one end of the spectrum, we have, you know, research articles and we want the research
to be solid.
So we want the computational workflows to be reproducible.
And at the other end of the spectrum on the left, we have archives, source code archives
like software heritage, which we really need to have if we want that scientific source
code to, you know, to remain available over time.
And in the middle, while we need a bunch of tools, in particular, deployment tool like
geeks to reproduce, well, to deploy software reproducibly.
Yes.
So in a nutshell, yes, geeks provides actual tools for reproducible research people.
I'm not going to go into details, but basically you can say, all right, I've made an experiment,
a computational experiment.
So now I'm going to pin the exact revision of geeks that I used.
This is the first command here.
And the second command is, you know, some time later or some colleague wants to reproduce
the results.
And so they use the time machine to jump to that specific revision of geeks.
And from there, they deploy the exact same packages that I have done in that manifest
file, bit for bit.
That's the idea.
All right.
So in HPC, I guess most people in this room would agree.
We have two obsessions.
That's MPI and AVX, well, vector instructions.
We want things to run fast, right?
We have those fancy clusters.
So we want to make sure that the communications are going to be fast.
We want to make sure we're going to use the latest vector instructions of our CPUs.
And that makes a lot of sense.
But sometimes we're going, maybe we have preconceptions about the implications of all this.
So here I'm creating Todd Gamblin, who's maybe in this room actually.
Hi, Todd, if you see me.
This is an example where we, well, Todd here was saying, you know, binaries, distributions
like Debian or Geeks or Fedora, for example, are just targeting the baseline of the CPU,
like A6664 without AVX, for example.
And that's a problem for performance.
Because of course, if you have that latest fancy Intel processor, then you probably want
to use those vector instructions.
But the conclusion that because of this, we cannot use, you know, binary distributions.
Distributions like Geeks or Debian that provide binaries is not entirely accurate.
That's the point I'm trying to make in this talk.
So yeah, as most of you know, there's a whole bunch of vector extensions.
It keeps growing, you know, like every, every few years we have new vector extensions in
Intel or AMD CPUs or even AH64 CPUs, Power 9, et cetera.
And it's even worse if you look at the actual CPU models, for example, this is just for
Intel, there's a whole bunch of things.
It's not always a superset of the previous CPU, you know, we're discussing it the other
day for dinner.
And yeah, sometimes it's complicated.
You cannot tell that Skylake AVX is exactly a superset of Skylake.
It's complicated.
And yet you want to be able to target these CPUs specifically, these micro-architectures.
And it makes a big deal of a difference.
So this is an example from an Agen benchmark.
So Agen is a C++ library for linear algebra, specifically targeting small matrices.
And well, you know, if on my laptop, if I'm targeting, if I'm compiling with MR equals
to Skylake, then I get a throughput that's three times the baseline performance.
So it's a pretty big deal.
So we definitely want to use that.
We want to be able to compile specifically for the CPU micro-architecture that we have.
But so the good news is that to a large extent, that's a solved problem for a long time.
So there is this thing called function multi-versioning that is already used in a number of performance
critical libraries.
So if you look at LeapSea for string comparison, or if you look at OpenBLAST, if you look
at FFTW, GMP for multi-precision arithmetic, you know, many libraries, programming languages,
runtimes, already use function multi-versioning.
So what's the deal here?
Well, roughly when you have function multi-versioning, you can say, well, I have one function that
does some linear algebra stuff, for example, and I'm actually providing several variants
of that function.
And when I start my program at runtime, the loader or, you know, the runtime system is
going to pick the most optimized one for the CPU I have at hand, right?
So if I use GMP, for example, for multi-precision arithmetic, it's going to pick the fastest
implementation it has, you know.
So you can compile GMP once, and then it's going to use the writing at runtime.
And even if you're using GCC or Clang, you can specify in your C code, well, I want this
particular function to be cloned, so to have several variants for each CPU microarchitectures,
and GCC or Clang is going to create several variants of that function so that it can pick
the right one at runtime.
So kind of a solved problem, in a way, well, except in some cases.
Well, one particular case where we have a problem is C++ template libraries, like Agen,
which I was mentioning before, they are not able to benefit from function multi-versioning
in any way.
So when you compile your Agen benchmark, well, you really have to use mRch equals to Skylake,
for example, if you were targeting a Skylake CPU.
And this is because if you look at Agen headers, for example, where there are many places where
you have if depths, do I have AVX 512 at compilation time?
If yes, then I'm going to use the optimized implementation, otherwise, I'm going to use
the baseline implementation.
And this is all happening at compilation time, so you really have to have a solution at compilation
time to address this.
And so this is where Geeks comes in.
So Geeks is, you know, it's a distribution, like Debian, like I was saying, that's targeting
the baseline instruction set, but we came up with a new thing that's called package multi-versioning.
It's actually one year old or something, which is roughly the idea is taking the same idea
of function as function multi-versioning, but applying it at the level of entire packages.
So let's say I have those Agen benchmarks, I can run them using just the baseline X8664
architecture, using this Geeks shell command.
It's, you know, it's taking the Agen benchmarks package, and in that package running the Bench
plus gem command, right, on a small matrix.
And then I can say, all right, now I want to tune that code specifically for my CPU,
and then I just put that extra, that extra dash dash tune option, and it's selling Geeks,
all right, please optimize that Agen benchmarks package directly for the CPU I'm on, which
is Skylake in this case, and this is it.
And what happens behind the scenes is that on the flag, Geeks is creating a new package
variant.
So it's taking that Agen benchmarks package, creating a new package variant that is built
specifically with a compiler wrapper that passes the MRT equals to Skylake flag.
And I get the performance, and I'm happy, right, so this is in Geeks since 2022, and
it's still reproducible, you know, because we can still say, all right, what precise option
did I use, what dash dash tune option did I use, and it's Skylake, all right, so the
build process of the package remains reproducible, right, I'm still getting the same binary if
I use dash dash tune equals to Skylake on my laptop or on some HPC cluster, whatever.
And there are no world rebuilds, which means that the build farm, for example, the official
build farm of the project is providing several variants of those packages, those, you know,
performance sensitive packages built for Skylake, Skylake, AVX, 512, you know, different things.
So if you install them, most likely you're going to get a pre-built binary that's specifically
optimized for that CPU.
And if not, well, that's fine, it's going to be to build it for you, that's okay.
So my conclusion here is, you know, we keep talking about performance of MPI, vector instruction
and so forth.
Well, I think we can have performance, we can have portable performance, that's what
we should aim for, and we can still have reproducibility, we don't have to sacrifice reproducibility
for performance, that's my take on the message.
Thank you.
Thank you very much.
Again, time for one question.
Okay, yeah, this whole dash tune thing looks awesome.
But what if the majority of the computation time is spent in libraries that that library
is actually using?
How do I tell it to optimize those instead as well?
Right.
So the way it works in Geeks, you can annotate packages that really need to be tunable, right?
So you can add a property to a package like, so it would be egg and benchmarks in this
case where it could be the GNU Scientific Library, GSL, and you said this package needs
to be tunable, so if I use dash, dash, tune, please tune specifically this package.
And it's going to work even if you're installing, you know, an application that actually depends
on GSL, for example.
All right, thanks a lot Ludovic.
Thank you.