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@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel



______________________________________________ R-devel@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

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to