We are compiling an application that uses OpenMP. We are using gcc 4.4, with -fopenmp. The app also uses IPP, which includes its own version of OpenMP (libiomp5). (Note: we are disabling IPP's internal threading by calling ippSetNumThread(1). According to Intel's documentation, this should avoid conflicts with other threading libraries. However, linking with IPP still links in libiomp5.so.)
Since libiomp5.so is already linked in, we have not been linking with libgomp.so (gcc's version of OpenMP). For a long time this has worked, but after a seemingly inconsequential change we started seeing very odd OpenMP-related crashes on one of four platforms we support (the other three platforms still work fine).
I can make the crashes go away if I link in libgomp.so as well as libiomp5.so.
I have a couple questions about this:
Is linking with both these libraries safe? It seems like they would both define the same symbols.
Is there a way to tell what version of OpenMP libiomp5.so supports? With gcc 4.4, libgomp.so should be at OpenMP v3.0. I can't find any information in Intel's documentation about the OpenMP version of libiomp5.so.
Since no one has answered for a few days, I'll just report what I've found out independently:
Is linking with both these libraries safe?
No. Here's the most useful page I found on this topic:
http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011/compiler_c/optaps/common/optaps_par_openmp_multiple_compilers.htm
Intel recommends that if you are going to be mixing IPP's internal OpenMP threading with your own OpenMP threading, you link to libiomp5 instead of your compiler's OpenMP library. The current version of libiomp5 provides "source compatibility and object-level interoperability" with gcc's OpenMP, but only if you are using gcc "4.42" (sic; I assume they mean 4.4.2) or later.
Is there a way to tell what version of OpenMP libiomp5.so supports?
Yes. Set the environment variable KMP_VERSION=1, then run your application. You'll get some debugging output printed by libiomp5 to your console. If you are using IPP v7 or later, one line will be something like
Intel(R) OMP API version: 3.0 (200805)
If you are using IPP 6, it won't tell you the API version, but it will tell you when it was built and with which version of the Intel compiler. Then you can check and see what version of OpenMP that compiler supported. (11.0 was the first version of the Intel compiler to support OpenMP v3.0.)
Related
I am trying to understand how exactly I can use OpenACC to offload computation to my nvidia GPU on GCC 5.3. The more I google things the more confused I become. All the guides I find, they involve recompiling the entire gcc along with two libs called nvptx-tools and nvptx-newlib. Other sources say that OpenACC is part of GOMP library. Other sources say that the development for OpenACC support will continue only on GCC 6.x. Also I have read that support for OpenACC is in the main brunch of GCC. However if I compile a program with -fopenacc and -foffload=nvptx-non is just wont work. Can someone explain to me what exactly it takes to compiler and run OpenACC code with gcc 5.3+?
Why some guides seem to require (re)compilation of nvptx-tools, nvptx-newlib, and GCC, if, as some internet sources say, OpenACC support is part of GCC's main branch?
What is the role of the GOMP library in all this?
Is it true that development for OpenACC support will only be happening for GCC 6+ from now on?
When OpenACC support matures, is it the goal to enable it in a similar way we enable OpenMP (i.e., by just adding a couple of compiler flags)?
Can someone also provide answers to all the above after replacing "OpenACC" with "OpenMP 4.0 GPU/MIC offload capability"?
Thanks in advance
The link below contains a script that will compile gcc for OpenACC support.
https://github.com/olcf/OLCFHack15/blob/master/GCC5OffloadTest/auto-gcc5-offload-openacc-build-install.sh
OpenACC is part of GCC's main branch now, but there are some points to note. Even if there are libraries that are part of gcc, when you compile gcc, you have to specify which libraries to compile. Not all of them will be compiled by default. For OpenACC there's an additional problem. Since, NVIDIA drivers are not open source, GCC cannot compile OpenACC directly to binaries. It needs to compile OpenACC to the intermediate NVPTX instructions which the Nvidia runtime will handle. Therefore you also need to install nvptx libs.
GOMP library is the intermediate library that handles both OpenMP and OpenACC
Yes, I think OpenACC development will only be happening in GCC 6, but it may still be backported to GCC 5. But your best best would be to use GCC 6.
While I cannot comment on what GCC developers decide to do, I think in the first point I have already stated what the problems are. Unless NVIDIA make their drivers open source, I think an extra step will always be necessary.
I believe right now OpenMP is planned only for CPU's and MIC. I believe OpenMP support for both will probably become default behavior. I am not sure whether OpenMP targeting NVIDIA GPU's are immediately part of their target, but since GCC is using GOMP for both OpenMP and OpenACC, I believe eventually they might be able to do it. Also, GCC is also targeting HSA using OpenMP, so basically AMD APU's. I am not sure whether AMD GPU's will work the same way, but it maybe possible. Since, AMD is making their drivers open source, I believe they maybe easier to integrate into default behavior.
I want to use openMP library in my project but it seems as if there is no option for openMP in xcode 5.1. if someone knows then please help me
There is clang with OpenMP 3.1/4.0 support (though not official). You can take it here http://clang-omp.github.io/
OpenMP is not a library but a language extension to C, C++ and Fortran. It requires support built into the compiler. Xcode uses compilers based on the LLVM infrastructure. It used to provide two different compiler front-ends - Clang and GCC. Of those two, the former does not have support for OpenMP (yet). The GCC front-end provided some support for old OpenMP features but is no longer part of Xcode. It used to be based on a very old GCC version (4.2.1) and not actively updated since Apple started throwing all their resources into improving Clang.
In other words - no OpenMP support in Xcode 5.1. You can build your own modern (but non-LLVM) GCC from source and use it on the command line, but it's hard to integrate it with Xcode.
I'm installing mingw-w64 on Windows and there are two options: win32 threads and posix threads. I know what is the difference between win32 threads and pthreads but I don't understand what is the difference between these two options. I doubt that if I will choose posix threads it will prevent me from calling WinAPI functions like CreateThread.
It seems that this option specify which threading API will be used by some program or library, but by what? By GCC, libstdc++ or by something else?
I found this:
Whats the difference between thread_posixs and thread_win32 in gcc port of windows?
In short, for this version of mingw, the threads-posix release will use the posix API and allow the use of std::thread, and the threads-win32 will use the win32 API, and disable the std::thread part of the standard.
Ok, if I will select win32 threads then std::thread will be unavailable but win32 threads will still be used. But used by what?
GCC comes with a compiler runtime library (libgcc) which it uses for (among other things) providing a low-level OS abstraction for multithreading related functionality in the languages it supports. The most relevant example is libstdc++'s C++11 <thread>, <mutex>, and <future>, which do not have a complete implementation when GCC is built with its internal Win32 threading model. MinGW-w64 provides a winpthreads (a pthreads implementation on top of the Win32 multithreading API) which GCC can then link in to enable all the fancy features.
I must stress this option does not forbid you to write any code you want (it has absolutely NO influence on what API you can call in your code). It only reflects what GCC's runtime libraries (libgcc/libstdc++/...) use for their functionality. The caveat quoted by #James has nothing to do with GCC's internal threading model, but rather with Microsoft's CRT implementation.
To summarize:
posix: enable C++11/C11 multithreading features. Makes libgcc depend on libwinpthreads, so that even if you don't directly call pthreads API, you'll be distributing the winpthreads DLL. There's nothing wrong with distributing one more DLL with your application.
win32: No C++11 multithreading features.
Neither have influence on any user code calling Win32 APIs or pthreads APIs. You can always use both.
Parts of the GCC runtime (the exception handling, in particular) are dependent on the threading model being used. So, if you're using the version of the runtime that was built with POSIX threads, but decide to create threads in your own code with the Win32 APIs, you're likely to have problems at some point.
Even if you're using the Win32 threading version of the runtime you probably shouldn't be calling the Win32 APIs directly. Quoting from the MinGW FAQ:
As MinGW uses the standard Microsoft C runtime library which comes with Windows, you should be careful and use the correct function to generate a new thread. In particular, the CreateThread function will not setup the stack correctly for the C runtime library. You should use _beginthreadex instead, which is (almost) completely compatible with CreateThread.
Note that it is now possible to use some of C++11 std::thread in the win32 threading mode. These header-only adapters worked out of the box for me:
https://github.com/meganz/mingw-std-threads
From the revision history it looks like there is some recent attempt to make this a part of the mingw64 runtime.
#rubenvb answer is fully correct, use the mingw posix compiler if you want to use std::thread, std::mutex, etc. For everybody who is using CMake, here is an example:
set(CMAKE_CXX_STANDARD 17) # or 20 if you want..
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(THREADS_PREFER_PTHREAD_FLAG ON)
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc-posix)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++-posix)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
set(CMAKE_FIND_ROOT_PATH
/usr/${TOOLCHAIN_PREFIX}
)
Ideal for cross-compiling Linux apps to Windows.
Hint: For people who are using GTK3 and want to cross-compile their GTK application to Windows. You maybe want to download the Mingw Windows GTK bundle, downloaded and packaged from msys2.org so you don't need to: https://gitlab.melroy.org/melroy/gtk-3-bundle-for-windows
so, C++11 has been around for a while and, given there already are compilers supporting it on most platforms, it would be nice to use it in some real software -- e.g. one that can be packaged in as-portable-as-possible package, preferably providing ./configure and so.
Because both Clang and GCC currently need -std=c++11 flag to compile c++11 source, and both sometimes require specific flags to work correctly (see for example How to compile C++11 with clang 3.2 on OSX lion? or C++11 Thread not working ), I'm quite afraid that the package won't work on some platforms that already support c++11 because of wrong invocation of compiler.
Q: Is there some standard how to correctly and portably compile c++11? E.g. autotools/autoconf check or some list of compiler/platform directives that describe all possible needed options? Or does the situation come from the fact that c++11 standard implementations are currently marked as "experimental" and the standard will eventually stabilize and become the default choice, not needing any usage of extra compiler flags?
Thanks
-exa
Well, if you`re trying to write portable code, i would recommend using cmake
a very powerful cross-platform, open-source build system.
Using cmake you should be able to identify the compilers available in your current machine and then generate your makefiles using the flags that you want in each case.
I have been using cmake for almost a year by now and it has significantly reduced the time consumed when trying to get a project compiling in different platforms.
I`m using CMake to generate Makefiles of C++11 projects. The only change in CMakeLists.txt I need to do is add the following:
ADD_DEFINITIONS("-std=gnu++11")
ADD_DEFINITIONS("-D_GLIBCXX_USE_C99_STDINT_TR1")
ADD_DEFINITIONS("-D_GLIBCXX_HAS_GTHREADS")
However, as I use Qt, I re-compile QtSDK with a new gcc version 4.8 and get a complete mingw system that use gcc in version 4.8.
Makings these changes, the project compile and run in Windows XP, Windows 7 and linux both 32 and 64 bits. I didn`t test it in OSX yet.
This question was emerged from this question.
The problem is that there is a NVidia driver for Linux, compiled wth GCC 4.5. The kernel is compiled with GCC 4.6. Well, the stuff doesn't work because of the version number difference between GCCs. (the installer says the driver won't work - for details please visit the link above)
Could one disguise a binary compiled with GCC 4.5 to a binary compiled with GCC 4.6? If it is possible, under what circumstances would it work well?
Your problem is called ABI: Application Binary Interface. This is a set of rules (among others) how functions in a piece of code get their arguments (ordering, padding of types on the stack), naming of the function so the linker can resolve symbols and padding/alignment of fields in structures.
GCC tries to keep the ABI stable between compiler versions but that's not always possible.
For example, GCC 4.4 fixed a bug in packed bit-fields which means that old/new code can't read structures using this feature properly anymore. If you would mix versions before and after 4.4, data corruption would occur without any crashes.
There is no indication in the 4.6 release notes that the ABI was changed but that's something which the Linux kernel can't know - it just reads the compiler version used to compile the code and if the first two numbers change, it assumes that running the code isn't safe.
There are two solutions:
You can compile the Nvidia driver with the same compiler as the kernel. This is strongly recommended
You can patch the version string in the binary. This will trick the kernel into loading the module but at the risk of causing data corruption to internal data structures.