fpm
fpm copied to clipboard
Build-in dependencies for fpm: OpenMP
OpenMP is probably one of the easiest non-fpm compatible dependency fpm could provide. OpenMP is usually shipped with the compiler. For the current scope of GCC we only have to add -fopenmp to both compile and link arguments and are done, therefore it might be a useful prototype to explore the usage of built-in dependencies for fpm.
Following the current scheme an empty table would do the trick and is flexible enough to allow customization for other build-in dependencies later.
[dependencies]
openmp = {}
Relevant discussion regarding package name conflicts: https://github.com/fortran-lang/fpm-registry/issues/8, in case a package wants to call itself openmp.
I agree this is should be a simple area to prototype such features, however I'm not a fan of the proposed manifest syntax. IMO, this seems to be more of compiler feature that needs enabling rather than a 'dependency' that needs satisfying.
Perhaps:
[compiler]
openmp = true
Also in the same vein:
[compiler]
lto = true # link-time optimisation
acc = true # OpenACC support
fflags = "-fopt-info" # Appended to built-in flags list
lflags = "-lblas"
fpm will then have a supported list of compilers for which it implements any compiler-specific syntax under the hood.
What do you think?
True, it usually feels like a compiler command when using it, but there is a lot automation for us hidden in the compiler.
I thought of it more like a dependency since it is handled in conda like one (see https://conda-forge.org/docs/maintainer/knowledge_base.html#openmp). Also meson is handling it usually as a dependency rather than a compiler command (see https://mesonbuild.com/Dependencies.html#openmp).
Having a dependency model that allows propagating linker and compiler flags would be well suited for OpenMP as well in fpm. OpenMP would be useful as simple prototype if dependencies require to export link or compile flags to a dependent project. Projects using OpenMP must propagate at least the linker flag, possibly also the library with the OpenMP implementation to dependent projects to allow correct linking.
It would be good to get this implemented so that we can self-bootstrap Fortran fpm with parallel builds enabled.
I am however still opposed to the treatment of OpenMP as a dependency in the manifest syntax; OpenMP isn't just an additional library for linking, it changes the way the compiler behaves in processing sources and in generating code. Similarly the invocation flag and link libraries are different for each compiler. Hence why I think an entry like openmp=true in the existing [build] table is more appropriate (#112). What do other people think?
Having a dependency model that allows propagating linker and compiler flags would be well suited for OpenMP as well in fpm.
Agreed, but I see no reason to conflate the manifest syntax for OpenMP with that of package dependencies.
I think we should get #112 working first, this would allow us to define flags on a per package basis (optimization) and global flags that propagate in the dependency tree (fast-math). Based on this we can easily implement OpenMP as either a build.openmp entry or a dependency.
I am however still opposed to the treatment of OpenMP as a dependency in the manifest syntax; OpenMP isn't just an additional library for linking, it changes the way the compiler behaves in processing sources and in generating code. Similarly the invocation flag and link libraries are different for each compiler.
Keep in mind that OpenMP is versioned as well, how do we deal with the fact that a program requires OpenMP version 4.5 or newer if the compiler used only provides OpenMP 3.x?
Another important thing is linking against the OpenMP runtime, if you use LLVM and GCC toolchains on your system you can link GCC applications with the LLVMs OpenMP runtime library and vice versa, depending on the features used. Same holds true for Intel OpenMP which can safely be linked into GCC compiled application instead of the GCC OpenMP runtime library.
Creating an OpenMP dependency, which exports compiler flags to the dependent projects would allow to safely support various OpenMP implementation including versioning and also gives you the freedom to overwrite the OpenMP dependency by creating a mock fpm-package to export your special OpenMP setup.
Can these cases not also be specified in the [build] table, e.g.:
[build]
openmp = true
openmp-version = "^4.5"
openmp-library = "iomp5"
We will already need logic for correctly exporting compiler options to dependents, why not use the same model for OpenMP?
Perhaps I am misunderstanding you; is your intention that there is no special code for handling OpenMP and that the OpenMP dependency is processed internally in exactly the same way as any other dependency?
I would prefer to extend the current dependency model to support OpenMP on equal footing with normal fpm dependencies. With a solution for #112 we should be able to create an fpm package that will enable OpenMP support in its dependents.
Supporting OpenMP with this approach wouldn't require any special entries in build and allows to test if this is a suitable model for OpenMP before implementing a special shortcut with build.openmp in the package manifest. I'm not opposed to create a build.openmp entry, but I wouldn't make it the first step for supporting OpenMP.
... we should be able to create an fpm package that will enable OpenMP support in its dependents.
Ah I see, I understand what you mean now. Thanks for explaining (and for your patience ;)). This is an elegant approach.
So a hypothetical default OpenMP package manifest might look something like this then:
name="OpenMP"
[build]
compile-args.gfortran= ["-fopenmp"] # append
compile-args.ifort= ["-qopenmp"]
# etc...
or, to introduce a possible general syntax, perhaps:
name="OpenMP"
[build]
[[compiler-arg]]
gfortran= ["-fopenmp"]
ifort= ["-qopenmp"]
# ...
export = "link" # export arg to linker command only
# export = "dependents" # export arg up to dependent packages only
# export = "all" # export arg to entire project
@perazz
Thank you for tagging me on this issue - I'm definitely willing to help.
Can you please help me understand what you're suggesting to accomplish @LKedward @awvwgk :
-
openmp is never really built as a library but I understand one may want to use the LLVM vs the GNU implementation. Do the two libraries have the same API?
-
Then I would see
openmpas a "metapackage", i.e. represent it as a special dependency that has no source or object files, but that propagates additional compile flags (-fopenmp) from the first branch it's used into upstream. -
I would start simple and just enable each compiler's own openmp library where available.
Does that make sense? Or, you were thinking to use openmp as a testbench to propagate package-specific (possibly source-specific) compiler flags?