[Rd] Set the number of threads using openmp with .C
Dirk Eddelbuettel
edd at debian.org
Sat Jul 10 20:10:18 CEST 2010
On 10 July 2010 at 13:01, Dirk Eddelbuettel wrote:
|
| 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.
PS: Using PKG_CFLAGS is slightly better style; the outcome is the same. See
e.g. src/Makevars and src/Makevars.win in the pnmath package referenced
above.
D.
|
| Hope this helps.
|
| --
| Regards, Dirk
|
| ______________________________________________
| R-devel at r-project.org mailing list
| https://stat.ethz.ch/mailman/listinfo/r-devel
--
Regards, Dirk
More information about the R-devel
mailing list