CRAN-acceptable way of linking to OpenMP some C code called from Rcpp

﹥>﹥吖頭↗ 提交于 2021-02-07 14:43:15

问题


I’m building an R package that has some .c files with code that uses OpenMP, and these C functions are called from .cpp files, but the .cpp files themselves don’t make any use of OpenMP.

e.g. cfile.c:

int parallel_function(double *x, int n)
{   
    int i;
    #pragma omp parallel for firstprivate(x, n)
    for (i = 0; i < n; i++){ x[i] *= 2; }
}

cppfile.cpp:

#include <Rcpp.h>
using namespace Rcpp;
extern “C” {
    int parallel_function(double *x, int n);
}
// [[Rcpp::export]]
void multiply_by_two(NumericVector x, int n){parallel_function(x.begin(), n);}

In order to enable OpenMP for the C files, my first though was to construct a Makevars like this, following the R extensions manual:

PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CFLAGS)

But that will throw me the following:

Check: use of SHLIB_OPENMP_*FLAGS in Makefiles, Result: NOTE
    src/Makevars: SHLIB_OPENMP_CFLAGS is included in PKG_LIBS but linking is by C++
  Use of these macros is discussed in sect 1.2.1.1 of 'Writing R
  Extensions'. The macros for different languages may differ so the
  matching macro must be used in PKG_CXXFLAGS (etc) and match that used
  in PKG_LIBS (except for Fortran: see the manual).

So then, if I try instead:

PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS)

I would get:

Check: use of SHLIB_OPENMP_*FLAGS in Makefiles, Result: NOTE
    src/Makevars: SHLIB_OPENMP_CFLAGS is included in PKG_CFLAGS but not in PKG_LIBS
    src/Makevars: SHLIB_OPENMP_CXXFLAGS is included in PKG_LIBS but not in PKG_CXXFLAGS
  Use of these macros is discussed in sect 1.2.1.1 of 'Writing R
  Extensions'. The macros for different languages may differ so the
  matching macro must be used in PKG_CXXFLAGS (etc) and match that used
  in PKG_LIBS (except for Fortran: see the manual).

Even if I use both flags like this:

PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
PKG_CXXFLAGS = $(SHLIB_OPENMP_CXXFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(SHLIB_OPENMP_CFLAGS)

I would get:

Check: use of SHLIB_OPENMP_*FLAGS in Makefiles, Result: NOTE
    src/Makevars: SHLIB_OPENMP_CFLAGS is included in PKG_LIBS but linking is by C++
    src/Makevars: it is not portable to include multiple SHLIB_OPENMP_*' macros in PKG_LIBS
  Use of these macros is discussed in sect 1.2.1.1 of 'Writing R
  Extensions'. The macros for different languages may differ so the
  matching macro must be used in PKG_CXXFLAGS (etc) and match that used
  in PKG_LIBS (except for Fortran: see the manual).

So, since the .cpp code does not require omp linkage, I’m wondering what would be the correct and minimalist way of linking the .c files but not the .cpp files.


回答1:


In general, we can mix C and C++ code in an R package.

Once OpenMP enters, CRAN now seems to stronly prefer consistent use of either SHLIB_OPENMP_CFLAGS or SHLIB_OPENMP_CXXFLAGS.

Now, given that g++ will enter for linking, it would seem that you should use SHLIB_OPENMP_CXXFLAGS throughout -- which suggests renaming your C files to be C++ files.

It all seems a little over the top, but that is what I would try. And the CRAN checks are usually all there for a good reason so experience has taught most of to play along with them.



来源:https://stackoverflow.com/questions/54056594/cran-acceptable-way-of-linking-to-openmp-some-c-code-called-from-rcpp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!