问题
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