要求在Rcpp包中使用OpenMP可用性

Ham*_*m82 5 r openmp armadillo rcpp r-package

我通过使用RcppArmadilloOpenMP库以及以下命令在R中准备了一个包:

RcppArmadillo.package.skeleton("mypackage")
compileAttributes(verbose=TRUE)
Run Code Online (Sandbox Code Playgroud)

另外,在DESCRIPTION我添加的文件中:

Imports: Rcpp (>= 0.12.8), RcppArmadillo
LinkingTo:Rcpp, RcppArmadillo
Depends: RcppArmadillo
Run Code Online (Sandbox Code Playgroud)

NAMESPACE我添加的文件中:

import(RcppArmadillo)
importFrom(Rcpp, evalCpp)
Run Code Online (Sandbox Code Playgroud)

然后我运行以下代码cmd:

R CMD build mypackage
R CMD INSTALL mypackage.tar.gz
Run Code Online (Sandbox Code Playgroud)

我在我的计算机中构建并安装软件包,现在就使用它.但我的学院和朋友无法安装该软件包.错误消息是关于RcppArmadilloOpenMP库.

例如:

致命错误:找不到'omp.h'文件

有没有人在这种情况下有过经验?我必须在我的包中进行哪种类型的设置来解决这个问题?

coa*_*ess 10

恭喜!你很可能偶然发现macOS缺乏OpenMP支持.这已在Rcpp FAQ中记录为条目2.10.3.


防御性编码

错误显而易见的原因是您没有OpenMP正确保护代码...例如

标题包含受以下内容保护:

#ifdef _OPENMP
  #include <omp.h>
#endif
Run Code Online (Sandbox Code Playgroud)

代码有以下保护:

#ifdef _OPENMP
   // multithreaded OpenMP version of code
#else
   // single-threaded version of code
#endif
Run Code Online (Sandbox Code Playgroud)

这假设您没有使用预处理程序#omp标记,而是更多深入的omp函数调用.如果是先前的,那么代码保护并不重要,因为预处理器标签将被丢弃.

(对于上述宏观方案的长期用户来说,请注意,自R 3.4.0起,该SUPPORT_OPENMP定义已完全删除,以支持_OPENMP.)


创建OpenMPvia 的包需求configure.ac

但是,以上只是很好的防御性编码.如果您的包需要特定功能,那么可能需要考虑使用autoconf调用的文件configure.ac来生成configure脚本.

放置configure.ac在你的包的顶层.

packagename/
|- data/
|- inst/
|- man/
|- src/
   |- Makevars
   |- HelloWorld.cpp
|- DESCRIPTION
|- NAMESPACE
|- configure.ac
|- configure
Run Code Online (Sandbox Code Playgroud)

configure.ac应包含以下内容:

AC_PREREQ(2.61)

AC_INIT(your_package_name_here, m4_esyscmd_s([awk -e '/^Version:/ {print $2}' DESCRIPTION]))
AC_COPYRIGHT(Copyright (C) 2017 your name?)


## Determine Install Location of R
: ${R_HOME=$(R RHOME)}
if test -z "${R_HOME}"; then
    AC_MSG_ERROR([Could not determine R_HOME.])   
fi

## Setup RBin
RBIN="${R_HOME}/bin/R"
CXX=`"${RBIN}" CMD config CXX`
CPPFLAGS=`"${RBIN}" CMD config CPPFLAGS`
CXXFLAGS=`"${RBIN}" CMD config CXXFLAGS`

## Package Requires C++
AC_LANG(C++)
AC_REQUIRE_CPP

## Compiler flag check
AC_PROG_CXX

## Borrowed from BHC/imager/icd/randomForest
# Check for OpenMP 
AC_OPENMP 

# since some systems have broken OMP libraries
# we also check that the actual package will work
ac_pkg_openmp=no
if test -n "${OPENMP_CFLAGS}"; then
  AC_MSG_CHECKING([OpenMP detected, checking if viable for package use])
  AC_LANG_CONFTEST([AC_LANG_PROGRAM([[#include <omp.h>]], [[ return omp_get_num_threads (); ]])])
  "$RBIN" CMD SHLIB conftest.c 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD && "$RBIN" --vanilla -q -e "dyn.load(paste('conftest',.Platform\$dynlib.ext,sep=''))" 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD && ac_pkg_openmp=yes
  AC_MSG_RESULT([${ac_pkg_openmp}])
fi

# if ${ac_pkg_openmp} = "yes" then we have OMP, otherwise it will be "no"
if test "${ac_pkg_openmp}" = no; then 
  AC_MSG_WARN([No OpenMP support. If using GCC, upgrade to >= 4.2. If using clang, upgrade to >= 3.8.0])
  AC_MSG_ERROR([Please use a different compiler.])   
fi 

# Fin
AC_OUTPUT
Run Code Online (Sandbox Code Playgroud)

要生成configure脚本,请运行:

autoconf
Run Code Online (Sandbox Code Playgroud)

完成后,您将需要重建包.注意,您可能需要安装,autoconf如果在Windows和macOS上,您可能需要通过自制软件安装它.


帮助用户获得可行的OpenMP编译器

现在,您可能希望确保您的同事能够从您OpenMP启用的代码中获得加速增益.要做到这一点,必须使OpenMP通过其同事使用系统默认的编译器无论是"真"上移开gcc或可行omp使clang编译器.

这里给出了关于macOS的说明:

http://thecoatlessprofessor.com/programming/openmp-in-r-on-os-x/

  • 自动upvote触发:)简而言之,OpenMP在Linux上非常容易,而不是其他任何地方. (3认同)