meson icon indicating copy to clipboard operation
meson copied to clipboard

Support LLVM flang

Open h-vetinari opened this issue 2 years ago • 14 comments

This is a continuation of #10839, which got closed without any changes.

Flang has a long history, the relevant bits of which are that there's nowadays a "classic" flang, and a new LLVM-based flang (called f18 before it got merged into LLVM). Though they share a name, and developed largely by the same people, they're essentially completely different compilers.

As of LLVM 17, flang is starting to become useable (no more experimental flag necessary to generate executable), however, the naming still has not fully settled, and llvm-flang is currently still using flang-new as the name of the binary until some planned refactoring work is done.

One of the main differences that appeared pretty much immediately when testing this in conda-forge, is that llvm-flang does not use the PGI-style -Minform=inform and will throw an error upon that.

Furthermore, it doesn't support -module, but requires -module-dir. Finally, the runtime libs that need to be linked are different:

-        return search_dirs + ['-lflang', '-lpgmath']
+        return search_dirs + ['-lFortranRuntime', '-lFortranDecimal']

The runtime libs are due for a relatively large overhaul, so in addition with the binary name, supporting flang probably means:

  • having a separate class in fortran.py
  • doing some version-based logic that will switch runtime libs and binary name for LLVM 18/19 (or whenever these things land)

Finally, using llvm-flang also runs into https://github.com/mesonbuild/meson/issues/10778, and into some rsp-limitations resp. path mangling issues (for now worked around by raising MESON_RSP_THRESHOLD to ridiculous levels).

h-vetinari avatar Sep 29 '23 03:09 h-vetinari

Ah yes, and according to meson, flang cannot handle fortran_std=legacy (worked around by using fortran_std=None).

h-vetinari avatar Sep 29 '23 03:09 h-vetinari

In terms of feasibility, I'm happy to note that with a hacked-up version of meson (roughly according to what I'm describing in the OP), I managed to build scipy with meson & flang. :)

So if someone tells me how an acceptable PR for flang-support would roughly look like, I'm happy to give it a shot!

The runtime libs are due for a relatively large overhaul

This landed now as https://github.com/llvm/llvm-project/commit/6403287eff71a3d6f6c862346d6ed3f0f000eb70, but I realised one thing: we probably don't need to add ['-lFortranRuntime', '-lFortranDecimal'] (now ['-lfortran-rt']) at all, because flang should take of this itself. For example, I had forgotten to specify -lFortran_main in the hacked-up version I used for scipy, but it still worked because flang is adding this itself (see the first hunk in the linked commit).

h-vetinari avatar Oct 01 '23 09:10 h-vetinari

but I realised one thing: we probably don't need to add ['-lFortranRuntime', '-lFortranDecimal'] (now ['-lfortran-rt']) at all, because flang should take of this itself.

IIRC the reason we add this isn't for when you build and link with the Fortran compiler, but rather when you build with the Fortran compiler and link with a different compiler as part of a multi-language target. Usually the C++ compiler.

eli-schwartz avatar Oct 02 '23 07:10 eli-schwartz

So if someone tells me how an acceptable PR for flang-support would roughly look like, I'm happy to give it a shot!

Roughly speaking, I think we want to insert naming bikeshed add a compilers/fortran.py class defining the flang-new compiler that does whatever is needed, and indicates itself as fc.get_id() such that people know this is "new flang". We have existing compiler IDs for flang, clang, and llvm, and I'm not sure what the difference is between the latter two...

compilers/detect.py is also going to want to be able to tell based on running $FC --version, that it is "new flang".

There's a list of possible command names for searching for a compiler when $FC has not been defined, but I think we want to hold off on that until we're sure what the final name is going to be.

eli-schwartz avatar Oct 02 '23 07:10 eli-schwartz

Thanks for the feedback!

but I think we want to hold off on that until we're sure what the final name is going to be.

It's going to be flang. There was a long discussion that ultimately got resolved together with LLVM's BDFL; see particularly point 3. here (note also the relatively subdued reception for the proposed intermediate name llvm-flang in the following comments, because very few people much less distros have classic flang).

The only question is how long things will take. There's already an RFC however which proposes to do exactly what's been agreed upon as the final criterion to do the rename, but whether that'll be LLVM 18 or 19 (or later still), who knows. I get the feeling it's not too far off though - in most cases the new lowering already outperforms the old one, and they're just hunting down any remaining perf regressions.

h-vetinari avatar Oct 02 '23 07:10 h-vetinari

The runtime libs are due for a relatively large overhaul

This landed now as llvm/llvm-project@6403287, but I realised one thing: we probably don't need to add ['-lFortranRuntime', '-lFortranDecimal'] (now ['-lfortran-rt']) at all, because flang should take of this itself. For example, I had forgotten to specify -lFortran_main in the hacked-up version I used for scipy, but it still worked because flang is adding this itself (see the first hunk in the linked commit).

I only want to make sure you're aware: AFAICT, the thing you consider landed was reverted pretty quickly (https://reviews.llvm.org/D154869#4652255) -- I don't know if a fixed version has landed in the meantime.

bilderbuchi avatar Oct 05 '23 07:10 bilderbuchi

Yeah, I'm following along. It's pretty standard for big PRs in LLVM to get involved because the merge breaks something somewhere unforeseen. The issue with this one is that the person driving that change has apparently moved on already. In any case, it shouldn't concern the meson setup too much, as I mentioned above, the driver should already add the right linkage to the runtime libs by itself.

h-vetinari avatar Oct 06 '23 00:10 h-vetinari

but I realised one thing: we probably don't need to add ['-lFortranRuntime', '-lFortranDecimal'] (now ['-lfortran-rt']) at all, because flang should take of this itself.

IIRC the reason we add this isn't for when you build and link with the Fortran compiler, but rather when you build with the Fortran compiler and link with a different compiler as part of a multi-language target. Usually the C++ compiler.

Yes, this is exactly what these are for. If the final link is done with a different language (c, c++, rust, etc) these are the flags we need to add manually because normally the native compiler would do this for us

dcbaker avatar Oct 06 '23 02:10 dcbaker

What's the upstream status on this?

eli-schwartz avatar May 16 '24 14:05 eli-schwartz

You have good timing, I just started working on this again yesterday 😅

What's the upstream status on this?

Neither the rename nor the runtime lib refactor has happened yet. So far I was working on hacking enough on meson to get SciPy to compile with flang 18 (which got a lot stricter and will simply fail on unknown flags).

However, I haven't yet looked into how to distinguish llvm-flang (binary currently named flang-new, but will be named flang at some unspecified time in the future), and currently-in-meson flang (binary called flang, now referred to as "classic flang"). Aside from having to switch behaviour based on the version number somehow, there's a collision on the name. Thoughts on this would be appreciated!

If it helps, I can open a WIP PR, but it's going to be in a very rough state.

h-vetinari avatar May 16 '24 22:05 h-vetinari

Well, technically meson doesn't really care what the binary is named except inasmuch as we need to know what to run to try to check for a compiler. There are e.g. environments where gcc is clang because that's all the environment provides and they wanted to "seamlessly make things work for existing users", which is... definitely a choice.

There's also more boring reasons why a simple name check doesn't work, such as the complexity of handling x86_64-pc-linux-gnu-gcc-12 or musl-gcc, the fact that /usr/bin/cc is traditionally a symlink to whichever of GCC/clang are the system default...

As long as meson can tell the difference between classic flang and new flang by parsing the output of --help / --version (I assume checking the version number is good enough given classic flang isn't really based on llvm 18?) we are good to go because that's what we'll base identification off of, not the executable name.

eli-schwartz avatar May 16 '24 22:05 eli-schwartz

@h-vetinari please open a WIP PR with your patches. I was also looking into this and I'd like to help if possible. I can test on linux/windows, too.

LaserEyess avatar May 16 '24 23:05 LaserEyess

I've opened a pull request now: #13323

It's even less functional than I'd want to - i.e. I cannot even build SciPy with it and flang 18 (v17 worked with a prior set of the patches, haven't tested the updated version yet). But perhaps it gives people something to discuss. I'm also building a flang from the upstream main branch to test, so that I can get better feedback on the open issue I have for this.

h-vetinari avatar Jun 14 '24 13:06 h-vetinari

As a quick update: https://github.com/mesonbuild/meson/pull/13323 + the in-progress flang 19 can build SciPy (and pass the test suite). Unfortunately flang 18 is not usable, and the regression fix won't be backported. Otherwise, this should now slowly be approaching something like usability!

h-vetinari avatar Jul 02 '24 11:07 h-vetinari

The preliminary support has now been merged to git master. Let's discuss what else we need to get this polished.

eli-schwartz avatar Jul 29 '24 00:07 eli-schwartz

I was about to close this and open a follow-up issue, but after your comment I edited the OP instead with the open points I'm aware of for improvements.

And of course, testing this on various platforms would be very helpful!

h-vetinari avatar Jul 29 '24 01:07 h-vetinari

@h-vetinari Wanted to say you a big-big thanks for this amazing work!

After finding a workaround for this issue, we were able to build SciPy using LLVM 20 on Amazon Linux (Fedora-based) w/ no extra patches to either SciPy or LLVM nor too much configuration.

  1. Tested SciPy versions: tagged release 1.14.0 and commit 9e9d534b7afac90e8d2fa23be1d0ab1201c1bde1 from the main branch (commit made on Aug 15).
  2. We build it against OpenBLAS, also compiled using flang-new. Tested versions: tagged releases 0.3.28 and 0.3.27 as well as 4944148e663719967755f151c60f5215172bdad7 commit from the develop branch (commit made on Aug 15).

BTW, transition to flang-new from gfortran reduced our scipy buildtime from 7-10 minutes to 1-2.

CC: @BwL1289

gorloffslava avatar Aug 15 '24 08:08 gorloffslava

Awesome!

BTW, transition to flang-new from gfortran reduced our scipy buildtime from 7-10 minutes to 1-2.

I'll note that this was probably due to a hot cache, different build settings, or something like that. Not that much time is spent compiling or linking Fortran code, the heaviest components are C++.

rgommers avatar Aug 15 '24 10:08 rgommers

@rgommers yeah, I have the similar feeling. It's not so huge amount of Fortran code in SciPy.

Probably, this is something related to that flang better interoperates with LLVM ecosystem than gfortran (even if everything else is built with LLVM in both cases), but it's only my hypothesis.

gorloffslava avatar Aug 15 '24 10:08 gorloffslava

thanks @rgommers!

BwL1289 avatar Aug 15 '24 13:08 BwL1289

The rename from flang-new to flang finally landed in LLVM 20: https://github.com/llvm/llvm-project/commit/06eb10dadfaeaadc5d0d95d38bea4bfb5253e077 🥳

h-vetinari avatar Oct 10 '24 10:10 h-vetinari

Also, the runtime libs refactor is progressing and almost there

h-vetinari avatar Oct 10 '24 10:10 h-vetinari

https://github.com/mesonbuild/meson/blob/e0bb042ca0b5f67e310973fa257abb516f2ca956/mesonbuild/compilers/fortran.py#L617-L619

flang 20.1 supports the option: llvm/llvm-project#109210

e-kwsm avatar Jun 17 '25 09:06 e-kwsm