需要 OpenMP 可用性才能在 Rcpp 包中使用
Requiring OpenMP availability for use in an Rcpp package
我已经使用 RcppArmadillo
和 OpenMP
库以及以下命令在 R 中准备了一个包:
RcppArmadillo.package.skeleton("mypackage")
compileAttributes(verbose=TRUE)
此外,在 DESCRIPTION
文件中我添加了:
Imports: Rcpp (>= 0.12.8), RcppArmadillo
LinkingTo:Rcpp, RcppArmadillo
Depends: RcppArmadillo
并在 NAMESPACE
文件中添加:
import(RcppArmadillo)
importFrom(Rcpp, evalCpp)
然后我运行下面的代码在cmd
:
R CMD build mypackage
R CMD INSTALL mypackage.tar.gz
我在我的电脑上构建并安装了这个包,现在我正在使用它。但是我的大学和朋友无法安装该软件包。错误消息是关于 RcppArmadillo
和 OpenMP
库的。
例如:
fatal error: 'omp.h' file not found
有没有人有过这种情况的经验?为了解决这个问题,我必须在我的包中进行哪种类型的设置?
恭喜!您很可能 偶然发现 macOS 缺少 OpenMP
支持。 This has been documented in the Rcpp FAQ as entry 2.10.3.
防御性编码
错误明显的原因是您没有适当保护 OpenMP
代码...例如
Header 内含物受以下保护:
#ifdef _OPENMP
#include <omp.h>
#endif
代码受到以下保护:
#ifdef _OPENMP
// multithreaded OpenMP version of code
#else
// single-threaded version of code
#endif
这假设您不使用预处理器#omp
标签但更深入的omp函数调用。如果是先验,那么代码保护并不重要,因为预处理器标签将被丢弃。
通过 configure.ac
为 OpenMP
创建包要求
不过,以上只是很好的防御编码。如果您的包需要特定功能,那么可能是时候考虑使用名为 configure.ac
的 autoconf
文件来生成 configure
脚本了。
将 configure.ac
放在包的顶层。
packagename/
|- data/
|- inst/
|- man/
|- src/
|- Makevars
|- HelloWorld.cpp
|- DESCRIPTION
|- NAMESPACE
|- configure.ac
|- configure
configure.ac
应包含以下内容:
AC_PREREQ(2.61)
AC_INIT(your_package_name_here, m4_esyscmd_s([awk -e '/^Version:/ {print }' 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
要生成 configure
脚本,运行:
autoconf
完成后,您将需要重建您的包。请注意,如果在 Windows and on macOS you likely need to install it via homebrew.
上,您可能需要安装 autoconf
帮助用户获得可行的OpenMP
编译器
现在,您可能希望确保您的同事能够从您启用 OpenMP
的代码中获得加速增益。为此,必须让您的同事从使用默认系统编译器转向 "true" gcc
或可行的 omp
启用 clang
,从而启用 OpenMP
]编译器。
此处给出了两者在 macOS 上的说明:
http://thecoatlessprofessor.com/programming/openmp-in-r-on-os-x/
我已经使用 RcppArmadillo
和 OpenMP
库以及以下命令在 R 中准备了一个包:
RcppArmadillo.package.skeleton("mypackage")
compileAttributes(verbose=TRUE)
此外,在 DESCRIPTION
文件中我添加了:
Imports: Rcpp (>= 0.12.8), RcppArmadillo
LinkingTo:Rcpp, RcppArmadillo
Depends: RcppArmadillo
并在 NAMESPACE
文件中添加:
import(RcppArmadillo)
importFrom(Rcpp, evalCpp)
然后我运行下面的代码在cmd
:
R CMD build mypackage
R CMD INSTALL mypackage.tar.gz
我在我的电脑上构建并安装了这个包,现在我正在使用它。但是我的大学和朋友无法安装该软件包。错误消息是关于 RcppArmadillo
和 OpenMP
库的。
例如:
fatal error: 'omp.h' file not found
有没有人有过这种情况的经验?为了解决这个问题,我必须在我的包中进行哪种类型的设置?
恭喜!您很可能 偶然发现 macOS 缺少 OpenMP
支持。 This has been documented in the Rcpp FAQ as entry 2.10.3.
防御性编码
错误明显的原因是您没有适当保护 OpenMP
代码...例如
Header 内含物受以下保护:
#ifdef _OPENMP
#include <omp.h>
#endif
代码受到以下保护:
#ifdef _OPENMP
// multithreaded OpenMP version of code
#else
// single-threaded version of code
#endif
这假设您不使用预处理器#omp
标签但更深入的omp函数调用。如果是先验,那么代码保护并不重要,因为预处理器标签将被丢弃。
通过 configure.ac
为 OpenMP
创建包要求
不过,以上只是很好的防御编码。如果您的包需要特定功能,那么可能是时候考虑使用名为 configure.ac
的 autoconf
文件来生成 configure
脚本了。
将 configure.ac
放在包的顶层。
packagename/
|- data/
|- inst/
|- man/
|- src/
|- Makevars
|- HelloWorld.cpp
|- DESCRIPTION
|- NAMESPACE
|- configure.ac
|- configure
configure.ac
应包含以下内容:
AC_PREREQ(2.61)
AC_INIT(your_package_name_here, m4_esyscmd_s([awk -e '/^Version:/ {print }' 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
要生成 configure
脚本,运行:
autoconf
完成后,您将需要重建您的包。请注意,如果在 Windows and on macOS you likely need to install it via homebrew.
上,您可能需要安装autoconf
帮助用户获得可行的OpenMP
编译器
现在,您可能希望确保您的同事能够从您启用 OpenMP
的代码中获得加速增益。为此,必须让您的同事从使用默认系统编译器转向 "true" gcc
或可行的 omp
启用 clang
,从而启用 OpenMP
]编译器。
此处给出了两者在 macOS 上的说明:
http://thecoatlessprofessor.com/programming/openmp-in-r-on-os-x/