[Rd] Set the number of threads using openmp with .C
Dirk Eddelbuettel
edd at debian.org
Sat Jul 10 20:01:39 CEST 2010
Eduardo,
On 10 July 2010 at 19:31, Eduardo García wrote:
| Hi everybody! Could somebody help me with the following?
|
| I'm trying to run a simple Hello World code in openmp using .C function. The
| C code i have is:
|
| #include <omp.h>
| #include <stdio.h>
| #include <R.h>
|
| void hello_omp(int *n) {
| int th_id, nthreads;
| omp_set_num_threads(*n);
| #pragma omp parallel private(th_id)
| {
| th_id = omp_get_thread_num();
| Rprintf("Hello World from thread %d\n", th_id);
| #pragma omp barrier
| if ( th_id == 0 ) {
| nthreads = omp_get_num_threads();
| Rprintf("There are %d threads\n",nthreads);
| }
| }
| }
|
| Where n is the number of threads that i want.
|
| I compite it with "R CMD SHLIB hello_openmp_R.c -fopenmp" and when I try to
| run it in R using:
|
| dyn.load("hello_openmp_R.so")
| hello_omp=function(n){.C("hello_omp",as.integer(n))}
| hello_omp(3)
| hello_omp(2)
|
| Only 1 thread is been used, instead of 3 and 2:
|
| > hello_omp(3)
| Hello World from thread 0
| There are 1 threads
| [[1]]
| [1] 3
|
|
| > hello_omp(2)
| Hello World from thread 0
| There are 1 threads
| [[1]]
| [1] 2
|
| I also tried to set OMP_NUM_THREADS=3 in the Konsole with "export
| OMP_NUM_THREADS=3", in the .c file directory, but it seems that R don't
| recognize it when calls .C
|
| I am using R version 2.10.1 in Ubuntu 9.10 - Karmic Koala, but i'm newbie in
| Linux.
|
| Thanks a lot in advance for your help !*
You were almost there, but your compile instructions were wrong. You must
pass -fopenmp to gcc. Which you tried, alas wrongly, and then overlooked the
warnings (and I called your file eduardo.c here) :
gcc -std=gnu99 -I/usr/share/R/include -fpic -O3 -Wall -pipe -c eduardo.c -o eduardo.o
eduardo.c: In function ‘hello_omp’:
eduardo.c:7: warning: ignoring #pragma omp parallel
eduardo.c:11: warning: ignoring #pragma omp barrier
One way of passing argument to gcc via 'R CMF foo' is to to use the
PKG_CPPFLAGS and PKG_LIBS arguments. The following shell script builds and
runs the code:
#!/bin/sh
PKG_CPPFLAGS="-fopenmp" \
PKG_LIBS="-lgomp" \
R CMD SHLIB eduardo.c
cat <<EOF | R --silent --no-save
dyn.load("eduardo.so")
hello_omp=function(n){.C("hello_omp",as.integer(n))}
hello_omp(3)
hello_omp(2)
EOF
and this generates the following output:
edd at max:/tmp$ ./eduardo.sh
gcc -std=gnu99 -I/usr/share/R/include -fopenmp -fpic -O3 -Wall -pipe -c eduardo.c -o eduardo.o
gcc -std=gnu99 -shared -o eduardo.so eduardo.o -lgomp -L/usr/lib64/R/lib -lR
> dyn.load("eduardo.so")
> hello_omp=function(n){.C("hello_omp",as.integer(n))}
> hello_omp(3)
Hello World from thread 0
Hello World from thread 2
Hello World from thread 1
There are 3 threads
[[1]]
[1] 3
> hello_omp(2)
Hello World from thread 0
Hello World from thread 1
There are 2 threads
[[1]]
[1] 2
>
edd at max:/tmp$
Have a look at the CRAN package 'inline' which allows you to compile, load,
link such short code snippets much more easily.
Lastly, one word of caution. R is famously single-threaded. You may get
yourself into trouble with OpenMP unless you set locks rather carefully.
There is of course the famous example of Luke Tierney's pnmath (at
http://www.stat.uiowa.edu/~luke/R/experimental/) so there is also some scope
for using this.
Hope this helps.
--
Regards, Dirk
More information about the R-devel
mailing list