Re: [Rd] Set the number of threads using openmp with .C

From: Dirk Eddelbuettel <edd_at_debian.org>
Date: Sat, 10 Jul 2010 13:01:39 -0500

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

______________________________________________
R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Received on Sat 10 Jul 2010 - 18:09:32 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Sat 10 Jul 2010 - 18:50:14 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.

list of date sections of archive