compiling openmp, macports gcc, and eclipse cdt - openmp

I am newbie in openmp. The following is the environment.
OS : Mac OSX Mavericks
Compiler : gcc (MacPorts gcc48 4.8.2_0) 4.8.2
IDE : Eclipse Kepler CDT plugin
I wrote the following openmp program
#include < stdio.h>
#include < omp.h>
int main()
{
#pragma omp parallel
{
int i=omp_get_thread_num();
printf("hello (%d)",i);
printf("world (%d)",i);
}
}
I compiled the above program and got the error that omp.h is not found and lgomp not found. Hence I added in the project properties an include path with /opt/local/lib/gcc48/gcc/x86_64-apple-darwin13/4.8.2/include and a library path /opt/local/lib/gcc48. The include path had the omp.h file and the library path had the file libomp.o.
I include the -fopenmp option in both the linker and the compiler option through project properties. It is compiling with gcc -I/opt/local/lib/gcc48/gcc/x86_64-apple-darwin13/4.8.2/include -O0 -g3 -Wall -c -fmessage-length=0 -fopenmp -MMD -MP -MF"src/OpenMPCourseExamples.d" -MT"src/OpenMPCourseExamples.d" -o "src/OpenMPCourseExamples.o" "../src/OpenMPCourseExamples.c" and linking with the command "gcc -L/opt/local/lib/gcc48 -fopenmp -o "OpenMPCourseExamples" ./src/OpenMPCourseExamples.o".
With the above command it compiles without an error but with a warning - "warning: unknown pragma ignored [-Wunknown-pragmas] #pragma omp parallel".
Also, I set an environment variable in the launch properties with OMP_NUM_THREADS=4. I ran the program that compiled with the above warning. I am getting only "hello (0)world (0)". I was under the impression that I should start four threads and should see the other outputs of "hello(1)world(1)hello(2)world(2)hello(3)world(3)" in some ordering as well. Now, here are my following questions.
Why am I getting the #pragma warning?
Is the compiler really detecting the openmp and building with openmp?
If everything is correct, why am I not seeing four different threads getting started?

The final steps that worked for openmp, macports gcc compiler, eclipse CDT in mac osx mavericks are.
Enable "Make ToolChain(s) Preferred" in Eclipse->Preference->C/C++->New C/C++ Project Wizard.
sudo port select --list gcc and set it sudo port select --set gcc with mp-gcc.
File->New Project->C Project (not C++) and create a hello world project.
In Project->Properties->C/C++ Build->Settings->Tool Settings set the following. (a) GCC C Compiler to /opt/local/bin/gcc-mp-4.8 (b)MAC OSX Linker to /opt/local/bin/gcc-mp-4.8
Build the hello world project and make sure, it compiles and runs successfully.
Include the open mp code. The code asked in the question of this page.
Go to again Project->Properties->C/C++ Build->Settings->Tool Settings set the following. (a) GCC Compiler ->Miscellaneous add -fopenmp (b) MacOSx Linker->Miscellaneous set -fopenmp
Build the code again.
The above steps worked good for me.

MacPorts configures the GCC build process with --program-suffix=-mp-${major} and therefore all compiler executables have the -mp-4.8 suffix. When you call gcc, you end up using Apple's Clang compiler, which does not support OpenMP and therefore does not recognise the -fopenmp option and #pragma omp ....
You have to do the following changes to the project settings:
Change the compiler command to gcc-mp-4.8
Change the linker command to gcc-mp-4.8
Remove the explicit specification of the include and library paths since the presence of -fopenmp adds them automatically.

Related

setting g++ mode to C++11

I am trying to build cmake source, which requires C++11.
The build halts and apparently the complaint is that C++11 is not detected. The g++ mode is actually set to -std=gnu++17
This is part of the console log
---------------------------------------------
CMake 3.18.20200919, Copyright 2000-2020 Kitware, Inc. and Contributors
Found GNU toolchain
C compiler on this system is: gcc
C++ compiler on this system is: g++ -std=gnu++17
Makefile processor on this system is: make
g++ has setenv
g++ has unsetenv
g++ does not have environ in stdlib.h
g++ has stl wstring
g++ has <ext/stdio_filebuf.h>
---------------------------------------------
g++ -std=gnu++17 -DCMAKE_BOOTSTRAP -DCMake_HAVE_CXX_MAKE_UNIQUE=1 -c $HOME/Apps/CMake-master/Source/cmAddCustomCommandCommand.cxx -o cmAddCustomCommandCommand.o
This is part of the error in the log file...
In file included from /usr/include/c++/5/unordered_map:35:0,
from cmake_bootstrap_11920_test.cxx:4:
/usr/include/c++/5/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support \
^
cmake_bootstrap_11920_test.cxx:7:2: error: #error "Compiler is not in a mode aware of C++11."
#error "Compiler is not in a mode aware of C++11."
^
cmake_bootstrap_11920_test.cxx:70:16: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
int Member = 1;
Looking around on the web, I noticed that C++11 is only available after gcc version 4.6.
I checked my version, and it seems to be above.
g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
I understand the -std=c++11 flag is used to enable the C++11 features in g++, but I don't seem to know what I am doing in this case.
I tried editing the CompileFlags.cmake file, but no change occurs.
I came upon this page which points to the cmake source I am using.
It says...
bootstrap: Require compiler mode aware of C++11
Some compilers have enough features enabled in their default modes to
pass our simple C++11 unique_ptr check but do not enable enough to build
CMake. Poison this case so that we choose one of the explicit `-std=`
options for such compilers.
Not sure what that means exactly.
How exactly do I change the g++ mode, to C++11, so that on running the bootstrap command, C++11 is used?
Or, in other words, how do I change std to point to C++11 (-std=c++11)?
First of all, you have g++ version 5.4.0 in your host PC installed, which is good, cause it means this is also supports the C++11, which you want to use.
To set it up, you could define it in your CMakeList.txt file:
set (CMAKE_CXX_STANDARD 11)
that should do the trick.
Please also check the documentation:
https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html
Usually, I would suggest to use the latest standard that you compiler is supporting (https://gcc.gnu.org/projects/cxx-status.html), cause you'll get also the latest features introduced in that standard. Exception for this rather in case you are working with legacy codes.

LLVM / Clang 8 Compilation of OpenMP Code in Windows

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:
libomp.lib.
libiomp5md.dll.
My questions are:
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.
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.
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.
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.
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

Using -Os/-Oz with Android NDK and cmake for release builds

Using: Andorid Studio 3.1.3, NDKr17b, gradle plugin 3.1.3, gradle-4.5.1-all.zip
I am not able to produce any release build of a shared library using cmake it fails with the following:
arm-linux-androideabi/bin/ld: fatal error: Optimization level must be between 0 and 3
Here is cmake release configuration I use
release {
externalNativeBuild {
cmake {
arguments "-DCMAKE_BUILD_TYPE=Release",
"-DANDROID_CPP_FEATURES=rtti exceptions",
"-DANDROID_STL=c++_static",
"-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON"
cppFlags "-ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden -Os"
cFlags "-ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden -Os"
}
}
consumerProguardFiles 'proguard-project.txt'
}
I found that ld is called with the following options:
-plugin /home/myhome/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/../lib64/LLVMgold.so -plugin-opt=mcpu=generic -plugin-opt=Os -plugin-opt=-function-sections -plugin-opt=-data-sections
And the problem is existence of "-plugin-opt=Os", when I run the command without this option it links, even that all source is compiled with the proper optimization level.
Using the same configuration with ndk-build works fine (ld call has no such option, it just loads the LLVMgold.so plugin, with no --plugin-opt=Os).
So my question is why this option "-plugin-opt=Os" is applied and how can I remove it? Is this comes from cmake or its from ninja?
I see you're also the filer of this bug, but for anyone else landing here, this is a bug in the Clang LTO plugin: https://github.com/android-ndk/ndk/issues/721.
Even this is a bug in Clang LTO plugin (https://reviews.llvm.org/D30920) - it can be avoided - note that ndk-build system is using the same toolchain, but this problem does not exist.
The solution is to not pass Os option to Clang LTO plugin ("-plugin-opt=Os")
and this can be done by removing -Os option from generic ANDROID_COMPILER_FLAGS_RELEASE, instead pass this option directly to your makefiles, this way it will not be added to Clang LTO plugin. But since ANDROID_COMPILER_FLAGS_RELEASE is not user variable, the only way to do this is to comment two lines (510, 512) in ndk-bundle/build/cmake/android.toolchain.cmake inside Android Sdk folder

Compiling library in g++ using C++11

I'm been attempting to compile an open-source C++ library (QuantLib-1.7) on my mac for several days but I seem to be encountering some kind of C++11 compatibility issue.
When I run make && sudo make install from the terminal the compilation seems to work except for a bunch of errors of the form
Making all in BermudanSwaption
g++ -DHAVE_CONFIG_H -I. -I../../ql -I../.. -I../.. -I/opt/local/include -g -O2 -MT BermudanSwaption.o -MD -MP -MF .deps/BermudanSwaption.Tpo -c -o BermudanSwaption.o BermudanSwaption.cpp
In file included from BermudanSwaption.cpp:22:
In file included from ../../ql/quantlib.hpp:43:
In file included from ../../ql/experimental/all.hpp:25:
In file included from ../../ql/experimental/volatility/all.hpp:21:
In file included from ../../ql/experimental/volatility/zabr.hpp:31:
In file included from ../../ql/math/statistics/incrementalstatistics.hpp:35:
In file included from /opt/local/include/boost/accumulators/statistics/stats.hpp:14:
In file included from /opt/local/include/boost/accumulators/statistics_fwd.hpp:12:
/opt/local/include/boost/mpl/print.hpp:50:19: warning: in-class initialization
of non-static data member is a C++11 extension [-Wc++11-extensions]
const int m_x = 1 / (sizeof(T) - sizeof(T));
^
1 warning generated.
I'm guessing this has something to do with g++ not being correctly configured for C++11. I'm familiar with the fact that C++11 can be invoked by compiling with g++ -std=c++11. However, despite a lot of googling I can't find a way to modify the makefile such that -std=c++11 is called when I run make && sudo make install.
Any help would be greatly appreciated.
Here is the section of the makefile which I believe is relevant:
BOOST_INCLUDE = -I/opt/local/include
BOOST_LIB = -L/opt/local/lib
BOOST_THREAD_LIB =
BOOST_UNIT_TEST_DEFINE = -DQL_WORKING_BOOST_STREAMS
BOOST_UNIT_TEST_LIB = boost_unit_test_framework-mt
BOOST_UNIT_TEST_MAIN_CXXFLAGS = -DBOOST_TEST_DYN_LINK
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = gcc -E
CPPFLAGS = -I/opt/local/include
CXX = g++
CXXCPP = g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
Here is the output from running "g++ -v":
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
Makefile.am: https://www.dropbox.com/s/v5j7qohwfup81od/Makefile.am?dl=0
Makefile.in: https://www.dropbox.com/s/t92hft9ea2ar1zw/Makefile.in?dl=0
QuantLib-1.7 directory: https://www.dropbox.com/sh/ulj0y68m8x35zg8/AAA-w7L2_YWIP8_KnwURErzYa?dl=0
Full error log: https://www.dropbox.com/s/g09lcnma8skipv7/errors.txt?dl=0
Add something like
CXXFLAGS += -std=c++11
to your Makefile. This will work regardless of the Darwin-specific munging of the g++ executable---it's really clang++.
References:
https://gcc.gnu.org/onlinedocs/gcc-5.2.0/gcc/C_002b_002b-Dialect-Options.html#C_002b_002b-Dialect-Options
https://gcc.gnu.org/projects/cxx0x.html
http://clang.llvm.org/cxx_status.html
https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
As you already have, and are familiar with homebrew, my suggestion would be to use that to install and manage quantlib like this:
brew install quantlib
That will then build and put all the files in /usr/local/Cellar/quantlib under some version number that is not of importance. The important thing is the the tools are then linked into /usr/local/bin so all you need to do is make sure that /usr/local/bin is in your PATH.
That gives you access to the tool quantlib-config which is always linked to the latest version and it knows which version that is. So, if you run:
quantlib-config --cflags
it will tell you what the correct path is for your includes like this:
-I/usr/local/Cellar/quantlib/1.6.1/include
Likewise, if you run:
quantlib-config --libs
it will tell you the correct linking directories and libraries for your latest version.
In short, all you need to do to compile is:
g++ $(quantlib-config --cflags --libs)
and it will always pull in the version you are using.
Note that if you use a Makefile, you will need to double the dollar signs.
This is how I eventually managed to compile the Quantlib library for future reference. It is probably not the most efficient/elegant method but it appears to work.
I followed the steps given in http://quantlib.org/install/macosx.shtml and found that running make && sudo make install led to the error reported in the OP.
Create a new static library C++ project in Eclipse called 'Quantlib'
Copy the ql directory located in the .tar file to the Quantlib Eclipse workspace
Right-click Quantlib > Properties > C/C++ Build > Settings > Cross G++ Compiler: Change the Language standard to ISO C++ 11 (-std=c++0x)
Right-click Quantlib > C/C++ General > Paths and Symbols: Add the following include directories for GNU C++
opt/local/include
/Quantlib (check "Is a workspace directory")
/opt/local/include/boost.
Build the Quantlib project (around 34 min on MacBook Air 1.8 GHz Intel Core i7)
Create a new C++ executable project (e.g. BermudanSwaption) and copy the BermudanSwaption.cpp into the BermudanSwaption Eclipse workspace
Repeat steps 4. and 5. for the BermudanSwaption Eclipse project
Right-click BermudanSwaption > Properties > C/C++ General > Paths and Symbols > References: check Quantlib (the Library Paths tab should now contain the entry '/Quantlib/Debug')
Build and run the BermudanSwaption executable project
QuantLib-1.7
OSX Yosemite 10.10.5
Eclipse C/C++ Development Tools Version: 8.8.0.201509131935
Xcode Version 7.1 (7B91b)
xcode-select version 2339.

Cross compilation: GCC ignores --sysroot

I'm trying to cross compile programs (currently avconv from libav) for a Nokia N9 phone using arm-linux-gnueabi-gcc from Linux Mint's 64-bit repository. The compiler's libc version is 2.15 and the phone has libc-2.10.1. They have an incompatibility in the math library, which gives me a segfault when I compile and run the avconv program from libav.
I'd need to compile and link against the older libc version, but I haven't managed to get the --sysroot option to work.
I made a small test program to avoid repeatedly configuring and compiling libav.
arm-linux-gnueabi-gcc --sysroot=/opt/CrossCompilation/NokiaN9/ -o output.sysroot hello.c
arm-linux-gnueabi-gcc -o output.nosysroot hello.c
Both commands create an identical output file. This is what hello.c looks like:
#include <stdio.h>
#include <math.h>
int main() {
printf("Hello, World! Sin = %f\n", sin(0.6451));
}
The strangest part is that gcc completely ignores the --sysroot option. If I pass a nonexisting directory to sysroot, it still produces exactly the same output binary:
arm-linux-gnueabi-gcc --sysroot=/foo/bar -o output.foobar hello.c
It doesn't even complain about any errors. What's the problem?
since I wasted a few days messing with this before reading the comments, I'm going to post artless noise's comments as an answer:
"Run the compiler with arm-linux-gnueabi-gcc -v and look at the value of --with-sysroot; this is the directory the compiler was built with. If you have this directory present on your machine (maybe with a different compiler), then the --sysroot may not work[; and if you do not see --with-sysroot and instead see --with-libs, it] means your gcc is compiled without --sysroot support."

Resources