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

From: Simon Urbanek <simon.urbanek_at_r-project.org>
Date: Wed, 31 Aug 2011 08:37:45 -0400

On Aug 30, 2011, at 12:57 PM, pawelm wrote:

> Simon,
>
> I found that files R-2.13.1/src/library/stats/src/distance.c and
> R-2.13.1/src/main/array.c have openmp code (example below). I have couple
> questions regarding best practices when using R internals and openmp.
>
> Can we use R-2.13.1/src/library/stats/src/distance.c and
> R-2.13.1/src/main/array.c as an example how to interact with R code and R
> internals?
> What are my other options if I want to work with SEXP structures in my
> parallel code?
>

I forgot to answer this one in my previous response, sorry.

The short answer is none. If you can't access what you need before the omp loop you may be in trouble. For example you can't allocate anything in the parallel code, so you can't create character elements or assign objects. There are some things (very few) you can do like using ISNA() or ISNAN() but the trouble is that without looking at the sources you don't know what you can do (note that the pragma below declares R_NaReal although it actually uses NA_REAL -- in theory that is only possible in internal R code because it knows that NA_REAL is defined as R_NaReal variable and not a fixed constant - which is entirely a matter of implementation and thus not under your control).

Cheers,
Simon

> Thank you
> Regards
>
> =============
>
> #ifdef HAVE_OPENMP
> /* This gives a spurious -Wunused-but-set-variable error */
> if (R_num_math_threads > 0)
> nthreads = R_num_math_threads;
> else
> nthreads = 1; /* for now */
> #pragma omp parallel for num_threads(nthreads) default(none) \
> private(j, i, ix, rx) \
> firstprivate(x, ans, n, p, type, cnt, sum, \
> NaRm, keepNA, R_NaReal, R_NaInt, OP)
> #endif
> for (j = 0; j < p; j++) {
> switch (type) {
> case REALSXP:
> rx = REAL(x) + n*j;
> if (keepNA)
> for (sum = 0., i = 0; i < n; i++) sum += *rx++;
> else {
> for (cnt = 0, sum = 0., i = 0; i < n; i++, rx++)
> if (!ISNAN(*rx)) {cnt++; sum += *rx;}
> else if (keepNA) {sum = NA_REAL; break;}
> }
> break;
> case INTSXP:
> ix = INTEGER(x) + n*j;
> for (cnt = 0, sum = 0., i = 0; i < n; i++, ix++)
> if (*ix != NA_INTEGER) {cnt++; sum += *ix;}
> else if (keepNA) {sum = NA_REAL; break;}
> break;
> case LGLSXP:
> ix = LOGICAL(x) + n*j;
> for (cnt = 0, sum = 0., i = 0; i < n; i++, ix++)
> if (*ix != NA_LOGICAL) {cnt++; sum += *ix;}
> else if (keepNA) {sum = NA_REAL; break;}
> break;
> default:
> /* we checked the type above, but be sure */
> UNIMPLEMENTED_TYPEt("do_colsum", type);
> }
> if (OP == 1) {
> if (cnt > 0) sum /= cnt; else sum = NA_REAL;
> }
> REAL(ans)[j] = sum;
> }
>
>
> --
> View this message in context: http://r.789695.n4.nabble.com/How-to-safely-use-OpenMP-pragma-inside-a-C-function-tp3777036p3779214.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 Received on Wed 31 Aug 2011 - 12:40:13 GMT

This quarter's messages: by month, or sorted: [ by date ] [ by thread ] [ by subject ] [ by author ]

All messages

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 Wed 31 Aug 2011 - 20:50:25 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