From mtmorgan at fhcrc.org  Mon Sep 12 22:37:07 2011
From: mtmorgan at fhcrc.org (Martin Morgan)
Date: Mon, 12 Sep 2011 13:37:07 -0700
Subject: [Rd] How to safely using OpenMP pragma inside a .C() function?
In-Reply-To: <B2571962-7567-4F59-A1CB-415088594F47@r-project.org>
References: <1314643732236-3777036.post@n4.nabble.com>
	<B2571962-7567-4F59-A1CB-415088594F47@r-project.org>
Message-ID: <4E6E6D73.7040504@fhcrc.org>

On 08/29/2011 05:36 PM, Simon Urbanek wrote:
>
> On Aug 29, 2011, at 7:48 PM, Alireza Mahani wrote:
>
>> I am trying to parallelize part of a C function that is called from
>> R (via .C) using OpenMP's "parallel for" pragma. I get mixed
>> results: some runs finish with no problem, but some lead to R
>> crashing after issuing a long error message involving memory
>> violations.
>>
>
> You'll have to provide the code. In general it works (even R uses it
> itself), but there are strict requirements (no R API calls) that you
> must adhere to.

Hi Simon et al.,

I'm trying to resolve this dictum (no R API calls) with my understanding 
of OpenMP's shared memory model. For instance I would have thought R API 
calls inside critical sections would be safe, as this (though obviously 
gratuitous) appears to be on my own machine (which I know is no way to 
arrive at a general understanding!)

#include <omp.h>
#include <Rdefines.h>

SEXP omp()
{
     const int n = 40;
     SEXP res = PROTECT(allocVector(INTSXP, n));
     const int it = 1000;
     int j;
     for (j = 0; j < Rf_length(res); ++j)
         INTEGER(res)[j] = 0;

     omp_set_num_threads(n);
     j = 0;
#pragma omp parallel for
     for (int i = 0; i < it; ++i)
#pragma omp critical
     {
         j  = omp_get_thread_num();
         SEXP elt = PROTECT(Rf_ScalarInteger(1));
         INTEGER(res)[j] = INTEGER(res)[j] + INTEGER(elt)[0];
         UNPROTECT(1);
     }

     UNPROTECT(1);
     return res;
}

and

 > dyn.load("omp.so"); table(x <- .Call("omp"))

25
40


?

Martin

 > sessionInfo()
R Under development (unstable) (2011-09-12 r56997)
Platform: x86_64-unknown-linux-gnu (64-bit)

locale:
  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
  [7] LC_PAPER=C                 LC_NAME=C
  [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  utils     datasets  grDevices methods   base

loaded via a namespace (and not attached):
[1] tools_2.14.0


>
>
>> I found this post, which describes how a .Call() function can be
>> made to avoid crashing R by raising the stack limit:
>>
>> http://www.r-bloggers.com/using-openmp-ized-c-code-with-r/
>>
>
> I skimmed through the post and all of the examples are broken - they
> will only work (incidentally) as R internals, not officially (and
> they are unnecessary inefficient).
>
>
>> However, trying this in my .C function doesn't help things. Any
>> suggestions/tips on whether I can safely use OpenMP inside a .C
>> function, and if yes how?
>>
>
> There are issues with OpenMP on some platforms in general (in fact
> pretty much every platform had some issue at some point in time), but
> apart from those you only have to make sure that you declare
> shared/private variables properly and don't use *any* R API calls in
> the parallel part (this includes things like LENGTH, REAL, ...).
>
> Cheers, Simon
>
>
>
>> Thank you, Alireza Mahani
>>
>> -- View this message in context:
>> http://r.789695.n4.nabble.com/How-to-safely-using-OpenMP-pragma-inside-a-C-function-tp3777036p3777036.html
>>
>>
Sent from the R devel mailing list archive at Nabble.com.
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>
>
> ______________________________________________ R-devel at r-project.org
> mailing list https://stat.ethz.ch/mailman/listinfo/r-devel


-- 
Computational Biology
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109

Location: M1-B861
Telephone: 206 667-2793



[Rd] How to safely using OpenMP pragma inside a .C() function?
Martin Morgan