Using OpenMP with clang

后端 未结 4 562
予麋鹿
予麋鹿 2020-12-08 11:28

I have problems compiling OpenMP code using clang (both 3.6 and 3.8 ToT).

I followed this blog post http://blog.llvm.org/2015/05/openmp-support_22.html , but the pro

相关标签:
4条回答
  • 2020-12-08 11:53

    Update

    Building the latest trunk of LLVM/Clang (clang-3.8), installing libiomp5, and specifying the location of the gomp omp header files worked. Note that the Ubuntu package for libiomp5 isn't quite correct, so you will need to add a symlink in /usr/lib from /usr/lib/libiomp5.so to /usr/lib/libiomp5.so.5.

    ./clang++ -I/usr/lib/gcc/x86_64-linux-gnu/4.9/include -fopenmp=libiomp5 -o test test.cpp
    

    I'm using g++-5.1 and clang++-3.6 on Linux Mint 17.2 (essentially Ubuntu trusty) and I see the same results with the following code.

    #include <iostream>
    #include <omp.h>
    int main() {
        #pragma omp parallel num_threads(4)
        {
            #pragma omp critical
            std::cout << "tid = " << omp_get_thread_num() << std::endl;
        }
    }
    

    Running this under ltrace reveals the issue:

    g++

    $ g++ -fopenmp -o test test.cpp
    $ ./test
    tid = 0
    tid = 3
    tid = 2
    tid = 1
    $ ltrace ./test
    __libc_start_main(0x400af6, 1, 0x7ffc937b8198, 0x400bc0 <unfinished ...>
    _ZNSt8ios_base4InitC1Ev(0x6021b1, 0xffff, 0x7ffc937b81a8, 5)   = 0
    __cxa_atexit(0x4009f0, 0x6021b1, 0x602090, 0x7ffc937b7f70)     = 0
    GOMP_parallel(0x400b6d, 0, 4, 0 <unfinished ...>
    GOMP_critical_start(0, 128, 0, 0)                              = 0
    tid = 3
    tid = 2
    omp_get_thread_num(0x7f9fe13894a8, 1, 0, 0x493e0)              = 0
    _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6020a0, 0x400c44, 0, 0x493e0) = 0x6020a0
    _ZNSolsEi(0x6020a0, 0, 0x7f9fe1a03988, 0x203d2064)             = 0x6020a0
    _ZNSolsEPFRSoS_E(0x6020a0, 0x400920, 0x7f9fe1a03988, 0 <unfinished ...>
    _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6020a0, 0x400920, 0x7f9fe1a03988, 0) = 0x6020a0
    <... _ZNSolsEPFRSoS_E resumed> )                               = 0x6020a0
    GOMP_critical_end(0x7f9fe0d2d400, 0x7f9fe0d2e9e0, 0, -1)       = 0
    tid = 1
    tid = 0
    <... GOMP_parallel resumed> )                                  = 0
    _ZNSt8ios_base4InitD1Ev(0x6021b1, 0, 224, 0x7f9fe0d2df50)      = 0x7f9fe1a08940
    +++ exited (status 0) +++
    

    clang

    $ clang++ -fopenmp -o test test.cpp
    $ ./test
    tid = 0
    $ ltrace ./test
    __libc_start_main(0x4009a0, 1, 0x7ffde4782538, 0x400a00 <unfinished ...>
    _ZNSt8ios_base4InitC1Ev(0x6013f4, 0x7ffde4782538, 0x7ffde4782548, 5) = 0
    __cxa_atexit(0x400830, 0x6013f4, 0x6012c8, 0x7ffde4782310)     = 0
    _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6012e0, 0x400a84, 0x7ffde4782548, 6) = 0x6012e0
    omp_get_thread_num(0x7f3e4698c006, 0x7f3e4698c000, 0x7f3e46764988, 1024) = 0
    _ZNSolsEi(0x6012e0, 0, 0x7f3e46764988, 1024)                   = 0x6012e0
    _ZNSolsEPFRSoS_E(0x6012e0, 0x4007a0, 0x7f3e46764988, 0 <unfinished ...>
    _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6012e0, 0x4007a0, 0x7f3e46764988, 0) = 0x6012e0
    tid = 0
    <... _ZNSolsEPFRSoS_E resumed> )                               = 0x6012e0
    _ZNSt8ios_base4InitD1Ev(0x6013f4, 0, 224, 0x7f3e45886f50)      = 0x7f3e46769940
    +++ exited (status 0) +++
    

    You can immediately see the problem: clang++ never calls GOMP_parallel, so you always get one thread. This is crazy behavior on the part of clang. Have you tried building and using the "special" OpenMP version of clang?

    0 讨论(0)
  • 2020-12-08 12:02

    Some additional comments:

    1) You need to use -fopenmp=libomp to enable OpenMP in clang. -fopenmp just links libgomp but ignores all the pragmas. Weird, I know -- and will be changed in the trunk soon.

    2) 3.7 is the first version that supports OpenMP. 3.6 doesn't.

    3) clang is only able to work with libomp. Don't put libgomp (headers or the library) in the way of libomp! clang uses Intel API, not supported by libgomp. -fopenmp=libomp should link correct library.

    0 讨论(0)
  • 2020-12-08 12:03

    I made it work on Linux Mint 17.2. (essentially Ubuntu 14.04) with:

    packages: libiomp-dev clang-3.8

    Compile flag: -fopenmp

    Linker flag: -fopenmp=libiomp5

    Now it compiles and uses multiple threads.

    Here is the modified FindOpenMP.cmake

    0 讨论(0)
  • 2020-12-08 12:06

    OMP_NUM_THREADS environment variable is probably what you want. You can also set it programmatically.

    https://gcc.gnu.org/onlinedocs/libgomp/Environment-Variables.html

    And same for clang.

    0 讨论(0)
提交回复
热议问题