首页 > 解决方案 > CRAN 可接受的方式链接到 OpenMP 一些从 Rcpp 调用的 C 代码

问题描述

我正在构建一个 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; }
}

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);}

为了为 C 文件启用 OpenMP,我的第一个想法是Makevars按照 R 扩展手册构建一个这样的:

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

但这会给我带来以下信息:

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).

那么,如果我尝试改为:

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

我会得到:

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).

即使我使用这样的两个标志:

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

我会得到:

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).

因此,由于.cpp代码不需要 omp 链接,我想知道链接文件而不是文件的正确且简约的方式是什么。.c.cpp

标签: ropenmprcpp

解决方案


通常,我们可以在 R 包中混合 C 和 C++ 代码。

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

现在,鉴于g++将输入链接,您似乎应该SHLIB_OPENMP_CXXFLAGS始终使用 - 这建议将您的 C 文件重命名为 C++ 文件。

这一切似乎有点过头了,但这是我会尝试的。并且 CRAN 检查通常都是有充分理由的,因此经验教会了大多数人与他们一起玩。


推荐阅读