Passing GCC to a * not * libgomp link, so it binds libiomp5 instead

I need to find out the compiler / linker directive that I can pass to gcc so that it does not bind libgomp automatically when -fopenmp is specified.

The reason is because I'm trying to build against Intel MKL BLAS. MKL requires the addition of a separate Intel library to handle multithreading (for example, libmkl_intel_thread or libmkl_gnu_thread). However, the library for linking MKL to libgomp is not available on every operating system, including mine. This forces me to bind libmkl_intel_thread, which in turn must bind to libiomp5.

While I can create my package, some binaries are related to libgomp and libiomp5. I’m not sure if this is causing problems, but there have been several failures, the communication combination is suspicious, and even if it does not cause failures, this is certainly terrible inefficiency.

I am trying to do this with gcc 4.9.1.

Avoiding -fopenmp is unfortunately not an option. The reason is that it is for compiling a rather large package consisting of several subpackages whose Make files do not have the largest shape and where additional packages from other sources (plugins) can be compiled later. Enforcing a universal compiler / linker directive is easy. Enabling --enable-openmp, however, activates both of the -fopenmp options and determines which ones are used to run multithreaded code. Trying to split the three (--enable-openmp, -fopenmp and the code associated with --enable-openmp) is not possible.

I have looked through the manual pages and I do not see any directive for gcc that would allow me to select the openmp library. There is a very old discussion on Intel forums in which they suggest specifying a static library immediately after -fopenmp, followed by -a-need. Which seems rather shaky and also has great potential to interfere with plugin packages. llvm-openmp seems to be reading the -fopenmp = libiomp5 directive at some point, but it seems to have been reset in version 3.5, and I'm still trying to use gcc.

Thanks.

+6
source share
3 answers

I think I have an answer to that; I had several exchanges with Intel representatives and I want to share the results. This is a mixture of some of their suggestions and what I came up with myself:

  • Short answer: you cannot. Gcc wants to force use of libgomp at the linker stage. If libiomp is also linked, then both libraries will be linked. Which one will be called? I dont know.

  • The longer answer is that on some distributions it is possible to change the default behavior of gcc (by adding libgomp when installing -fopenmp) by creating your own libgomp.spec or by changing the libgomp.spec installed with gcc. In my distribution (homegrown) this was not possible; the file "libgomp.spec" is empty, and the spec for libgomp is built into gcc. All must be redefined. And it will need to be redone when updating gcc.

  • On some operating systems, it may be possible to replace each copy and link to libgomp with a symbolic link to libiomp5. Then the binary will have several links leading to the same library, under two different names. What will happen then? I dont know.

  • What I ended up doing is moving from gcc to the clang-omp llvm implementation. It uses libiomp5 unless otherwise specified. My concern about this was that part of my project uses fortran and there is no llvm fortran compiler. It turns out, however, that even when -fopenmp is provided by gfortran, while llvm ultimately makes the link, it will destroy any links to libgomp and replace them with libiomp5. clang-omp may also be able to select the omp library with -fopenmp = [libiomp5 | libgomp], but I could not achieve this sequence. In any case, the implementation of clang-omp llvm 3.5 covers almost the entire openmp specification, and so far it has not seemed that nothing was lost in the switch. In fact, performance has improved.

  • I did a recording experiment using gfortran as the llvm interface using dragonegg. This book was not worth the candle. Dragonegg is not compatible with gcc 4.9, so it forces gcc 4.8. It was hard to configure; it seems that with changes it will be difficult to maintain; llvm people are not sure how much dragonegg support will go forward; and in all cases the performance was worse than using llvm.

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

  • This leaves the question: "is iomp5 compatible" compatible with gcc 4.9 ", as stated on the OpenMP website. The answer is simple: no, iomp5 and gcc 4.9 will not work with each other - at least without significant changes to one a toolchain for which there is no guidance or documentation, and it is unclear if anyone has done this successfully.

+4
source

GCC does not support binding to the Intel OpenMP runtime library. The GCC internal code transformer converts OpenMP directives to ligomp specific calls, and they have an API different from the one pointed to by libiomp . In addition, mixing two separate OpenMP delays into one executable file (or into one process if modules with OpenMP support load dynamically) is a recipe for disaster. This is the reason why the MKL multithreaded driver comes in two flavors: one Intel and one GNU. The fact that the latter is missing on some machines is probably a defect in the installation.

Edit: Obviously, Intel's OpenMP environment provides a level of compatibility with GNU, which means that it could be used as a replacement for libgomp . At least the characters:

 $ nm libiomp5.a | sort | grep GOMP_ 0000000000000000 T GOMP_barrier@ @VERSION 0000000000000000 T GOMP_barrier@GOMP _1.0 0000000000000000 T __kmp_api_GOMP_barrier 0000000000000000 T __kmp_api_GOMP_barrier_10_alias ... 

In this case, you need to do the following:

  • save -fopenmp when compiling the code so that GCC recognizes OpenMP pragmas and converts the code to the corresponding calls in libgomp ;
  • If GCC is used to link an executable or shared library, do not pass the -fopenmp during the link phase; instead go -L/path/to/libiomp5 -liomp5 ;
  • If GNU ld is used to link the executable / module, replace -lgomp with -liomp5 .

If you cannot make the above changes, the thread on the Intel forums makes sense because of the way linker resolves link to link links, although it is really more hacked. Passing -Wl,--as-needed causes GNU ld not to allocate DT_NEEDED tags for any library that follows it on the command line, unless that library satisfies the undefined symbolic link, assuming the GCC driver will insert -lgomp somewhere after provided by the user. The idea is to prevent libgomp from linking to the executable even when there are no unresolved references to GOMP_... , which usually should not be so, since all links, even those from dynamically loaded modules, must be executed by libiomp5 . Preventing libgomp from loading RTLD is important because it has some constructor routines that are called whether characters are imported or not, and things that can interfere with IOMP.

The reference link will not work on non-ELF systems such as OS X. The Mach-O link editor does not support --as-needed , although there may be a different mechanism to achieve the same result on this OS.

+7
source

I am a technical support engineer on the Intel MKL team. This post has recently caught our attention. The Intel MKL stream layer really requires libiomp5, i.e. Intel OpenMP Runtime Library. For proper communication with libiomp5 using GCC, the code must be compiled without the use of '-fopenmp'. And then in the link line you must explicitly specify libmkl_intel_thread and libiomp5.

The current MKL documentation does not provide enough explanation for this usage model. And the MKL line adviser is directly violated. I apologize for all the inconvenience and misunderstanding. We will install a communications consultant as soon as possible and improve the User Guide to better assist GCC users on OS X.

+2
source

Source: https://habr.com/ru/post/975691/


All Articles