Search code examples
cygwin64-bitopenmpgcc4mingw-w64

How to make OpenMP work with MinGW-64 under Cygwin?


The Scenario

I am developing an application in C99 ANSI C that uses OpenMP and GMP. It's natural habitat will be a linux machine with plenty of cores, so there's basically no big trouble there, but for reasons I do not want to debate here, I have to develop under Cygwin on a 64 bit Windows machine.

When I use the 32 bit version of gcc, something, somewhere, goes horribly wrong and the application is about 60 times slower than a very crude single-threaded version, when it should in fact be faster by a factor that equals the number of CPU's. It makes it impossible to work with. I really don't know what is causing this; Anyway, I have decided to use the 64 bit version of MinGW instead, that'd be x86_64-w64-mingw32-gcc-4.5.3 and his friends, to be precise.

A side note: I am sure that the slowdown is not a flaw in my multithreading, the multithreaded application works correctly and faster on the linux machine.

The actual Problem

Setting up GMP was easy, it can be compiled from source without any trouble and then works like a charm. Compiling the following easy example with -fopenmp also works like a charm:

#include <gmp.h>
#include <omp.h>

int main() {
    #pragma omp parallel
    {
        mpz_t t;
        mpz_init(t);
        mpz_set_si(t,omp_get_thread_num());
        # pragma omp critical
        { 
            gmp_printf("Hello From GMP'd Thread %Zd!\n",t); 
            fflush(stdout);
        }
        mpz_clear(t);
    }
    return 0;
}

However, executing it gives me

$ ./test
test.exe: error while loading shared libraries: ?:
cannot open shared object file: No such file or directory

I am aware of this question, but I would like to make this work without downloading any binaries other than those from an official Cygwin repository. Since my example compiled with the -fopenmp switch, I am convinced that this should also be very much possible.

Can someone help me with that? Thanks a bunch in advance.


Solution

  • I think that "error while loading shared libraries: ?:" means that cygwin does not know where to find libgmp-10.dll and/or libgomp-1.dll.

    Both DLL are required according to Dependency Walker

    dll


    Your program worked after I added the directory that contains both DLL to my PATH:

    #$ x86_64-w64-mingw32-g++ -fopenmp -o w64test gmp_hello.c -lgmp
    #$ file ./w64test.exe
    ./w64test.exe: PE32+ executable (console) x86-64, for MS Windows
    
    #$ ./w64test.exe
    /home/david/SO/hello_openmp/w64test.exe: error while loading shared
     libraries: ?: cannot open shared object file: No such file or
     directory
    
    #$ ls /cygdrive/c/dev/cygwin/usr/x86_64-w64-mingw32/sys-root/mingw/bin/*mp*dll
    
    /cygdrive/c/dev/cygwin/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libgmp-10.dll
    /cygdrive/c/dev/cygwin/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libgomp-1.dll
    
    #$ export PATH=$PATH:/cygdrive/c/dev/cygwin/usr/x86_64-w64-mingw32/sys-root/mingw/bin/
    
    #$ ./w64test.exe
    Hello From GMP'd Thread 1!
    Hello From GMP'd Thread 0!
    

    note

    I compiled and installed gmp-5.0.5 with the following commands:

    ./configure --build=i686-pc-cygwin --host=x86_64-w64-mingw32 --prefix=/usr/x86_64-w64-mingw32/sys-root/mingw  --enable-shared --disable-static
    make -j 2
    make check
    make install
    


    update

    Your program also works with cygwin "GCC Release series 4 compiler".

    #$ g++ -fopenmp -o cygtest gmp_hello.c -lgmp
    #$ ./cygtest.exe
     Hello From GMP'd Thread 1!
     Hello From GMP'd Thread 0!
    
    #$ g++ -v
     Target: i686-pc-cygwin
     Thread model: posix
     gcc version 4.5.3 (GCC)
    

    You might need to install the following packages:

    • libgmp-devel (Development library for GMP)
    • libgmp3 (Runtime library for GMP)
    • libgomp1 (GOMP shared runtime)