CRAN可接受的将Rcpp调用的某些C代码链接到OpenMP的方式

any*_*ker 5 r openmp rcpp

我正在构建一个R包,其中包含一些.c带有使用OpenMP的代码的文件,并且这些C函数是从.cpp文件中调用的,但是.cpp文件本身并未使用OpenMP。

例如 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; }
}
Run Code Online (Sandbox Code Playgroud)

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);}
Run Code Online (Sandbox Code Playgroud)

为了对C文件启用OpenMP,我的第一步虽然是Makevars按照R扩展手册来构造一个这样的文件:

PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CFLAGS)
Run Code Online (Sandbox Code Playgroud)

但这会给我以下几点:

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).
Run Code Online (Sandbox Code Playgroud)

因此,如果我改为尝试:

PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS)
Run Code Online (Sandbox Code Playgroud)

我会得到:

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).
Run Code Online (Sandbox Code Playgroud)

即使我同时使用两个标志:

PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
PKG_CXXFLAGS = $(SHLIB_OPENMP_CXXFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(SHLIB_OPENMP_CFLAGS)
Run Code Online (Sandbox Code Playgroud)

我会得到:

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).
Run Code Online (Sandbox Code Playgroud)

因此,由于.cpp代码不需要omp链接,所以我想知道链接文件而不是链接文件的正确和最简单的方法是什么。.c.cpp

Dir*_*tel 4

一般来说,我们可以在 R 包中混合 C 和 C++ 代码。

一旦 OpenMP 进入,CRAN 现在似乎更倾向于一致使用SHLIB_OPENMP_CFLAGS SHLIB_OPENMP_CXXFLAGS

现在,考虑到g++将输入链接,您似乎应该使用SHLIB_OPENMP_CXXFLAGS全文——这建议将您的 C 文件重命名为 C++ 文件。

这一切似乎有点过头了,但这就是我会尝试的。CRAN 检查通常都是有充分理由的,因此经验告诉大多数人要配合它们。