Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Telling GCC to *not* link libgomp so it links libiomp5 instead

I need to figure out a compiler/linker directive I can feed into gcc so that it won't automatically link libgomp when -fopenmp is specified.

The reason is that I'm trying to build against Intel's MKL BLAS. MKL requires adding a separate Intel library to handle multithreading (e.g., libmkl_intel_thread or libmkl_gnu_thread). The library for linking MKL against libgomp, however, is not available on every operating system, including mine. This forces me to link libmkl_intel_thread, which in turn must link against libiomp5.

While I am able to build my package, some binaries are linked against both libgomp and libiomp5. I'm not positive this is causing problems, but there have been a few crashes, the linkage-combination is suspicious, and even if it isn't causing crashes its certainly a terrible inefficiency.

I'm trying to do this with gcc 4.9.1.

Avoiding -fopenmp is, unfortunately, not an option. The reason is that this is for compiling a rather large package comprised of several sub-packages, whose Makefiles are not in the greatest shape, and where additional packages from other sources (plug-ins) may be compiled later. Forcing a universal compiler/linker directive isn't difficult. Turning on --enable-openmp, however, activates both -fopenmp, and defines that are used to trigger code related to multi-threading. Trying to separate the three (--enable-openmp, -fopenmp, and code linked to --enable-openmp) isn't feasible.

I've looked through manual pages, and I don't see any directive for gcc that would allow selection of an openmp library. Intel's forums have a very old discussion in which they suggest specifying a static library immediately after -fopenmp followed by --as-needed. Which seems pretty rickety, and also has a lot of potential to interfere with plugin packages. llvm-openmp seems to have considered a -fopenmp=libiomp5 directive at one point, but it seems to have been dropped in the 3.5 release and I'm trying to use gcc anyway.

Thanks.

like image 751
Bob Avatar asked Sep 23 '14 02:09

Bob


1 Answers

I think I have an answer at this point; I've had several exchanges with Intel folks, and I want to share the result. This is a mixture of some of their suggestions and what I came up with on my own:

  1. The short answer is, you can't. Gcc wants to force the use of libgomp at the linker stage. If libiomp is also linked, then both libraries will be linked. Which one will be called? I don't know.

  2. The longer answer is that on some distributions, it may be possible to change gcc's default behavior (adding libgomp whenever -fopenmp is set) by creating a custom libgomp.spec or altering the libgomp.spec installed with gcc. On my distribution (homebrew), this was not feasible; the "libgomp.spec" file is empty, and spec's for libgomp are built-in to gcc. All of those would have to be overridden. And this would have to be redone whenever gcc is updated.

  3. It may be possible on some operating systems to replace every copy and link to libgomp, to a symlink to libiomp5. The binary will then have multiple links leading to the same library, under two different names. What will happen then? I don't know.

  4. What I ended-up doing, is moving from gcc to the clang-omp implementation of llvm. It uses libiomp5 unless told otherwise. My concern about this was that part of my project uses fortran, and there's no llvm fortran compiler. It turns out, though, that even when -fopenmp is given to gfortran, so long as llvm is ultimately doing the linking it will wipe-out any references to libgomp and replace them with libiomp5. clang-omp also may have an option to select the omp library with -fopenmp=[libiomp5|libgomp], but I was not able to get this working consistently. Anyway, the clang-omp implementation of llvm 3.5 covers almost all of the openmp spec, and so far it doesn't appear that anything was lost in the switch. In fact performance improved.

  5. I did, for the record, experiment with using gfortran as an llvm frontend using dragonegg. This book was not worth the candle. Dragonegg isn't compatible with gcc 4.9 so it forces gcc 4.8. It was difficult to setup; appears that it would be difficult to maintain as versions change; the llvm folks are not sure how much support dragonegg will have moving forward; and in all events performance was inferior to just using llvm.

  6. The question that drove me here, was how to get a package with C and fortran components, that uses OpenMP, compiled against MKL, which the MKL libraries for my OS are hardlinked against iomp5 and won't accept gomp. The answer to that is that the only viable option was to move from gcc to clang-omp.

  7. This does leave the question, "is iomp5 'drop-in compatible' with gcc 4.9", as claimed on the OpenMP website. The answer is simply, "no," iomp5 and gcc 4.9 will not work with each other --- at least without substantial modifications to one's toolchain, for which no guidance or documentation is available, and it is not clear whether anyone has done this successfully.

like image 196
Bob Avatar answered Sep 23 '22 02:09

Bob