4

I'm using the Windows version of Clang (LLVM) 8 under Windows.
I'm compiling a code which uses OpenMP.

Under the lib folder of Clang there are 2 files which are OpenMP related:

  1. libomp.lib.
  2. libiomp5md.dll.

My questions are:

  1. When I compile the code I use the flags -Xclang -fopenmp for the compiler. In in GCC and ICC using the flags tell the compiler to link the OpenMP library automatically. What about Clang? Does it do it automatically or must I link with libomp.lib manually? Is there a way to trigger automatic linking to the OpenMP library?
    Answer: This was answered in Michael Klemm's answer below - Use the clang driver both for compiling and linking and then the -fopenmp will work as in GCC.
  2. When I link with libomp.lib manually (Defining as a library for the linker) the output exe requires libomp.dll while the supplied OpenMP Dynamic Library is libiomp5md.dll. Is that a bug or is it because I link manually?
    Answer: The libomp.dll is supplied in the bin folder and not the lib folder.
  3. What's the proper way to utilize OpenMP in Clang under Windows? The clang-cl driver doesn't work with /openmp or -openmp as the MSVC's cl compiler.
    Answer: Currently it can be done either with clang -fopenmp ..., clang-cl -Xclang -fopenmp ... or clang-cl /clang:-fopenmp ... (Which is equivalent of -Xclang -fopenmp).

Remark
On Windows I use Windows Driver of Clang using clang-cl.

Royi
  • 4,640
  • 6
  • 46
  • 64

2 Answers2

2

Adding clarity to what the OpenMP libraries actually are, and how to use them on Windows with clang-cl

libomp.dll and libiomp5md.dll ARE THE SAME FILES!

When compiling for Windows, you link against libomp.lib OR libiomp5md.lib which will link to the same-named DLL at runtime, i.e. libomp.dll OR libiomp5md.dll respectively.

If you load 2 files that use the "different-name DLL," the interpreter will crash and give you a nasty error like: OMP: Error #15: Initializing libiomp5md.dll, but found libomp.dll already initialized.

Why? Because the program has no idea they are the same DLL, they have different names, so it assumes they are different. And it crashes. For this reason only, you can choose to swap which OpenMP DLL you link to in your program.

If your program doesn't crash and give you an error, you can keep using the same link to OpenMP. Otherwise, to silence the error, link to the one that is loaded by another program already.

If using clang-cl.exe which is the "drop-in" Clang replacement for MSVC cl.exe you should pass a compiler argument such as -Xclang -fopenmp which will convert the argument over to "Clang language." Don't forget to still pass to the linker the OpenMP LIB you chose, because on Windows, it won't be automatic.

That's all I've learned as brief as possible about OpenMP linking on Windows.

Matt
  • 2,602
  • 13
  • 36
1

To compile and link OpenMP code with clang on Windows, you will have to pass -fopenmp to both the compiler and the linker:

clang -fopenmp -o bla.obj -c bla.c
clang -fopenmp -o bla.exe bla.obj
Michael Klemm
  • 2,658
  • 1
  • 12
  • 15
  • 1
    I don't think so on Windows - `lld-link: warning: ignoring unknown argument: -fopenmp` (This is the output of the procedure). – Royi May 04 '19 at 10:16
  • I was using the compiler driver to invoke the linker. If you do it that way, the compiler driver will supply the linker with the right libraries when using `-fopenmp`. If you want to invoke the linker yourself, please use -v with the compiler to find out what linker options the compiler driver uses. – Michael Klemm May 04 '19 at 10:24
  • 1
    OK. Then what `DLL` will the compiled EXE require? Could you check? Is it `libiomp5md.dll` or `libomp.dll`? – Royi May 04 '19 at 10:58
  • For me: `"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\Tools\\MSVC\\14.13.26128\\bin\\HostX64\\x64\\link.exe" -out:bla.exe -defaultlib:libcmt "-libpath:C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\Tools\\MSVC\\14.13.26128\\lib\\x64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.16299.0\\ucrt\\x64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.16299.0\\um\\x64" -nologo -nodefaultlib:vcomp.lib -nodefaultlib:vcompd.lib "-libpath:C:\\Program Files\\LLVM\\bin/../lib" -defaultlib:libomp.lib bla.obj` – Michael Klemm May 04 '19 at 11:09
  • 1
    My problem is it links with `libomp.lib` which requires `libomp.dll` while Clang supplies `libiomp5md.dll`. I need somehow to compile in a way it matches the supplied dynamic library of OpenMP which is `libiomp5md.dll`. Check the dependency of your `EXE` which `DLL` does it require for OpenMP? – Royi May 04 '19 at 11:11
  • With the mentioned command lines, my process only pulls in `libomp.dll`. – Michael Klemm May 04 '19 at 14:07
  • Which the problem I raised above. I'd like it to use `libiomp5md.dll` which is what supplied in `Lib` folder. There is another question if when running it will be compatible with Intel OpenMP (Which is the origin of the OpenMP in LLVM / Clang). – Royi May 04 '19 at 15:03
  • OK, then please state exactly what you want to achieve? I stated that the proper way to use OpenMP with clang (on any platform) is to use `-fopenmp`. Are you trying to compile code that you can link with code from the Intel compiler? – Michael Klemm May 04 '19 at 15:15
  • Michael, Read (2) in my question. First of all `-fopenmp` doesn't work on `clang-cl`. It requires `-XClang -fopenmp`. At least in my system. Second, `libomp.lib` is by Intel as well. It has only different name. I want to compile with Clang yet make it require `libiomp5md.dll` (Which is what supplied in `lib` library of LLVM for Windows). – Royi May 04 '19 at 15:37
  • I have done the same with clang-cl: `clang-cl -v /clang:-fopenmp -o bla.exe bla.obj`. It still links with libomp.dll. BTW, my installation of clang has both libomp.dll (which is the default name for the OpenMP runtime for clang) and a `libiomp5md.dll`, but it only provides a `libomp.lib`, which AFAIK is used to link against the corresponding `libomp.dll`. – Michael Klemm May 05 '19 at 04:48
  • The only way to link against `libiomp5md.dll` from clang's bin is to have the `libiomp5md.lib` from the Intel compiler and use that for linkage using an explicit linker command, either through the compiler driver w/o OpenMP flags or by invoking the linker directly. – Michael Klemm May 05 '19 at 05:10
  • This is what the whole question about. Why is the 'dll' of Intel OpenMP is supplied but not the 'lib'? Also, they are the same code, so will they be compatible loaded in parallel? By the I still don’t get how you trigger OpenMP with 'clang-cl' without 'Xclang'. Could you show the command line? – Royi May 05 '19 at 06:21
  • I cannot say why clang ships with `libiomp5md.dll`, but does not supply the .lib file with it. The command line I was using is in my comment: `clang-cl -v /clang:-fopenmp -o bla.exe bla.obj`. If you are OK with the answer about `libiomp5md.dll` taking some more time, I can speak to my Intel colleagues about that part of the question. – Michael Klemm May 05 '19 at 06:27
  • Basically `libomp.lib` in LLVM / Clang should match exactly `libiomp5md.lib` of Intel as the code was contributed by Intel. Now the question what happens when the host uses `libiomp5md.dll` while my application uses `libomp.dll`. Will my application understand they are the same and hence there is no conflicts and no need to reload the functions? I'd be happy to hear your friend opinion on this. – Royi May 05 '19 at 13:01
  • So, `libiomp5md.dll` is a *copy* of `libomp.dll`. This is for historic reasons, as initially, when clang started to use the OpenMP runtime, it linked against `libomp5md.dll`. This was later changed to `libomp.dll` and clang maintains a copy of the old name for compatibility reasons. So, it does not make a difference that you're linking against `libomp.dll`. If you want to have compatibility with the Intel Compiler's OpenMP runtime, then you will need to have a copy of Intel Parallel Studio installed and explicitly link against it's `libiomp5md.dll` using a custom link line. Makes sense? – Michael Klemm May 07 '19 at 17:56
  • I knew `libomp.dll` is basically renamed Intel OpenMP (Read my remarks above). My question is whether it is compatible to work under applications which runs Intel OpenMP? Namely, does the name change cause issues with applications running? – Royi May 07 '19 at 21:54
  • This is what will happen: `OMP: Error #15: Initializing libiomp5md.dll, but found libomp.dll already initialized.` So, you cannot have both `libomp.dll` and `libiomp5md.dll` in the same process space. If you want to mix compilers, you need make sure that either compiler (clang or icl) only uses one of the libraries. – Michael Klemm May 08 '19 at 05:53
  • I see. This is the error I was talking about. It is silly as the code is the same. I wish the LLVM people would make it work. Thank You. – Royi May 08 '19 at 08:29
  • Not sure if is this a problem that LLVM can solve or if this is a Windows problem with shared libraries (it's the same on Linux, BTW). At least the OpenMP runtime detects the issue and tells you about it. You can always explicitly link against `libiomp5md.dll` from the Intel Compiler or file a bug report against LLVM that `libiomp5md.lib` is missing, so that you cannot make the LLVM code compatible with the Intel Compiler. – Michael Klemm May 08 '19 at 08:32
  • I think they could have left the Intel naming and that't it. I totally agree. Marked your answer and +1. By the way, is using `clang-cl /clang:-clangflag` is equivalent of `clang-cl -Xclang -clangflag`? – Royi May 08 '19 at 08:34
  • Sorry, I don't know if that's equivalent. – Michael Klemm May 08 '19 at 08:37