Reputation: 412
I am trying a simple example of Open MP, to parallelize a for loop, but I cannot see that the for loop is being executed on more than one core.
Here is the C program:
#include </usr/local/Cellar/gcc/5.1.0/lib/gcc/5/gcc/x86_64-apple-darwin14.5.0/5.1.0/include/omp.h>
#include <stdio.h>
#include <unistd.h>
int main() {
int n;
#pragma omp parallel
{
#pragma omp for
for(n = 0; n < 10; n++)
printf(" Thread %d: %d\n", omp_get_thread_num(), n);
printf("Number of threads: %d\n", omp_get_num_threads());
}
printf("Total number of cores in the CPU: %ld\n", sysconf(_SC_NPROCESSORS_ONLN));
}
The above code is very similar to this example.
When I execute this program and print out the total number of threads being used by it (by default it should be the total number of CPU cores), I find the result 1
. Here is the output:
10:pavithran$ gcc -fopenmp openMPExample.c -o openMPExample.o
10:pavithran$ ./openMPExample.o
Thread 0: 0
Thread 0: 1
Thread 0: 2
Thread 0: 3
Thread 0: 4
Thread 0: 5
Thread 0: 6
Thread 0: 7
Thread 0: 8
Thread 0: 9
Number of threads: 1
Total number of cores in the CPU: 8
10:pavithran$
Why is it that I do not find the numbers being printed by different threads? Why is it that the total number of threads is always 1? Someone please help me in getting the parallel for loop to work.
PS: The first "#include ..." statement contains the explicit path because the simple form: #include <omp.h>
does not seem to work.
Upvotes: 3
Views: 7052
Reputation: 6187
You are compiling your program with Apple's clang version of gcc
that does not support OpenMP. This is why you get the output
$ gcc main.c -fopenmp
main.c:1:10: fatal error: 'omp.h' file not found
#include <omp.h>
^
1 error generated.
when using
#include <omp.h>
as opposed to (the montrosity)
#include </usr/local/Cellar/gcc/5.1.0/lib/gcc/5/gcc/x86_64-apple-darwin14.5.0/5.1.0/include/omp.h>
gcc
Note: Based on the include path I'm assuming use of Homebrew to install gcc
. If that is not the case there is a section at the end on installing gcc
via Homebrew with OpenMP support.
Homebrew installs gcc
as gcc-4.9
or gcc-5
(for both GCC 5.1 and GCC 5.2) depending on the version you have installed. It does not create a symlink for gcc
in /usr/local/bin
and so when you execute gcc
from the command line you will be calling Apple's clang version. This is what we must correct for and there are a multitude of ways in which we can use the Homebrew version of gcc
over Apple's clang version
Explicitly execute gcc
via
$ gcc-5 main.c -fopenmp
Create a symlink for gcc
in /usr/local/bin
with the following commands
$ cd /usr/local/bin
$ ln -s gcc-5 gcc
Now when you execute gcc -v
you should see something similar to the below (providing your $PATH
variable is set up correctly, see below, and you've installed gcc
with OpenMP support via Homebrew, see below)
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc-5
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/5.2.0/libexec/gcc/x86_64-apple-darwin14.4.0/5.2.0/lto-wrapper
Target: x86_64-apple-darwin14.4.0
Configured with: ../configure --build=x86_64-apple-darwin14.4.0 --prefix=/usr/local/Cellar/gcc/5.2.0 --libdir=/usr/local/Cellar/gcc/5.2.0/lib/gcc/5 --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-5 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --enable-libstdcxx-time=yes --enable-stage1-checking --enable-checking=release --enable-lto --with-build-config=bootstrap-debug --disable-werror --with-pkgversion='Homebrew gcc 5.2.0 --without-multilib' --with-bugurl=https://github.com/Homebrew/homebrew/issues --enable-plugin --disable-nls --disable-multilib
Thread model: posix
gcc version 5.2.0 (Homebrew gcc 5.2.0 --without-multilib)
Create an alias for the Homebrew version of gcc
. You can do this by adding a line similar to
alias hgcc='gcc-5'
to your .bashrc
or .bash_profile
. What is even better is to add it to a file called .bash_aliases
and then include it in your .bashrc
or .bash_profile
with
[[ -f ~/.bash_aliases ]] && . ~/.bash_aliases
We would then execute it via hgcc
as in
$ hgcc main.c -fopenmp
gcc
with OpenMP support on OS XTo install gcc
with OpenMP support the easiest route to take is via Homebrew. To do this you need to use the following command as per one of my previous answers
brew install gcc --without-multilib
or if you have already installed gcc
via Homebrew use
brew reinstall gcc --without-multilib
This installs gcc
as gcc-4.9
or gcc-5
(for both GCC 5.1 and GCC 5.2) depending on the version you have installed. It does not create a symlink for gcc
in /usr/local/bin
and so when you execute gcc
from the command line you will be calling Apple's clang version. You can verify this by running gcc -v
which should produce a similar output to the below
$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix
On (my Mac system at least) the default $PATH
includes /usr/local/bin
before /usr/bin
as in
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
If this is not the case for you you will need to edit your .bashrc
or .bash_profile
and add
export PATH=/usr/local/bin:$PATH
This ensures that the Homebrew version of gcc
will be found before any of the Apple versions, when we correct for Homebrew installing it as gcc-4.9
or gcc-5
.
Upvotes: 6
Reputation: 9489
What about setting OMP_NUM_THREADS
environment variable?
What would give you something like this?
> OMP_NUM_THREADS=8 ./openMPExample.o
(BTW, having a binary which name ends with '.o' might not be such a good idea)
Upvotes: 1