Search code examples
c++cclangopenmp

Using OpenMP with clang


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 problem is that the compiled program is executed on a one thread only. I'm using ubuntu 15.04 x64, I have both libgomp and libiopmp installed and I compile my code with the following command:

clang test.c -o test -fopenmp -L/usr/lib/gcc/x86_64-linux-gnu/5.1.1

When I use gcc instead, everything works fine: gcc test.c -o test -fopenmp

I also tried running export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5.1.1:$LD_LIBRARY_PATH but it didn't help. `

Any suggestions?


Solution

  • 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?