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@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

Reply via email to