From edd at debian.org  Sat Jul 10 20:10:18 2010
From: edd at debian.org (Dirk Eddelbuettel)
Date: Sat, 10 Jul 2010 13:10:18 -0500
Subject: [Rd] Set the number of threads using openmp with .C
In-Reply-To: <19512.46467.80330.279994@ron.nulle.part>
References: <AANLkTikbNGO9fDEArAl-QgMvYkIwRqNqe7eox0WVsIKN@mail.gmail.com>
	<19512.46467.80330.279994@ron.nulle.part>
Message-ID: <19512.46986.437728.953109@ron.nulle.part>


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



[Rd] Set the number of threads using openmp with .C
Dirk Eddelbuettel