RcppArmadillo:使用autoconf禁用OpenMP
RcppArmadillo: Using autoconf to disable OpenMP
在Dirk对这个问题的评论中,我提到了RcppArmadillo使用的configure.ac
脚本,以便在构建时用程序检查OS X上是否支持OpenMP。然后我觉得这听起来太复杂了,没有必要,但我尝试了一些方法来避免OpenMP问题,但当我在Travis上测试它时,它似乎仍然存在。
所以我现在做的是:
1.配置.ac
我已经(有点明目张胆,但我当然会尊重GPL-2许可证)将RcppArmadillo使用的配置.ac脚本复制到我的包中,删除了一些部分(例如LAPACK
检查)并调整了名称等等
2.Makevars
将src/Makevars
重命名为src/Makevars.in
,现在读取
PKG_CXXFLAGS = -I../inst/include @OPENMP_FLAG@
PKG_LIBS= @OPENMP_FLAG@ $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
和src/Makevars.win
PKG_CXXFLAGS = -I../inst/include -I. $(SHLIB_OPENMP_CXXFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
3.清理
添加了包含的cleanup
文件
#!/bin/sh
rm -f config.* src/Makevars src/config.h inst/include/pkgConfigGenerated.h
4.pkgConfigGenerated.h
添加了一个文件inst/include/pkgConfigGenerated.h.in
,如下所示:
#ifndef pkg__pkgConfigGenerated__h
#define pkg__pkgConfigGenerated__h
@HAVE_OPENMP@
#endif
5.pkgConfig.h
基于RcppArmadilloConfig.h
文件,我创建了inst/include/pkgConfig.h
作为
#if defined(WIN32) || defined(_WIN32)
#define ARMA_USE_OPENMP
#else
#include <pkgConfigGenerated.h>
#endif
我的问题:
- 现在我想我需要添加
#include <pkgConfig.h>
我在src
中的cpp文件,因为我认为RcppArmadillo就是这样使用它的。这是正确的吗?当我在Linux上测试它时,它抱怨找不到它:fatal error: pkgConfig.h: No such file or directory
。我需要做一些额外的链接吗 - 我还需要做什么吗
工作解决方案
根据德克的回答,我做了以下几点。我从RcppArmadillo
借用了configure.ac
文件,并包含了我需要的部分,但做了一些小改动(我在这里包含了所有内容,以备将来参考):
## Copyright Dirk Eddelbuettel for RcppArmadillo (GPL-2)
AC_PREREQ(2.61)
AC_INIT([pkg], 0.1.0)
: ${R_HOME=$(R RHOME)}
if test -z "${R_HOME}"; then
AC_MSG_ERROR([Could not determine R_HOME.])
fi
CXX=$(${R_HOME}/bin/R CMD config CXX)
CXXFLAGS=$("${R_HOME}/bin/R" CMD config CXXFLAGS)
AC_LANG(C++)
AC_REQUIRE_CPP
openmp_flag=""
openmp_cflag=""
AC_MSG_CHECKING([for macOS])
RSysinfoName=$("${R_HOME}/bin/Rscript" --vanilla -e 'cat(Sys.info()[["sysname"]])')
if test x"${RSysinfoName}" == x"Darwin"; then
AC_MSG_RESULT([found])
AC_MSG_WARN([OpenMP unavailable and turned off.])
openmp_flag="-DARMA_DONT_USE_OPENMP"
else
AC_MSG_RESULT([not found as on ${RSysinfoName}])
AC_MSG_CHECKING([for OpenMP])
allldflags=$(${R_HOME}/bin/R CMD config --ldflags)
hasOpenMP=$(echo ${allldflags} | grep -- -fopenmp)
if test x"${hasOpenMP}" == x""; then
AC_MSG_RESULT([missing])
openmp_flag="-DARMA_DONT_USE_OPENMP"
else
AC_MSG_RESULT([found])
openmp_flag='$(SHLIB_OPENMP_CXXFLAGS)'
openmp_cflag='$(SHLIB_OPENMP_CFLAGS)'
fi
fi
AC_SUBST([OPENMP_CFLAG], ["${openmp_cflag}"])
AC_SUBST([OPENMP_FLAG], ["${openmp_flag}"])
AC_CONFIG_FILES([src/Makevars])
AC_OUTPUT
我的主要错误是,我认为在这个configure.ac
文件上会自动调用autoconf
来获得configure
,但事实并非如此
对应的Makevars.in
是
PKG_CXXFLAGS = @OPENMP_FLAG@
PKG_LIBS= @OPENMP_CFLAG@ $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
(也许这两个标志可以简化为一个,但不要修复没有损坏的…)
现在我通过了Linux和OS X上的构建(当RcppArmadillo
安装失败时,OS X和devel
版本的R除外,但这似乎是一个不同的问题)。
一到四似乎很好;我甚至不认为你需要两个文件。只需设置ARMA_USE_OPENMP
或其补码ARMA_DONT_USE_OPENMP
即可。
仔细想想,它也可以分别通过-DARMA_USE_OPENMP
或-DARMA_DONT_USE_OPENMP
添加到编译标志中。
Five有点麻烦,因为你似乎不知道如何设置include标志。更多不依赖额外文件的理由,嗯?;-)
让我们看看进展如何。我们可以决定帮助提供一个R级函数,您可以从脚本configure
中调用它(它可以在bash中,也可以使用Rscript
)。
编辑:刚刚实现了一个可以使用的更简单的修复:只需将C++98作为编译标准。正如编写R扩展所说:
相反,为了确保即使在这不是编译器默认值,请使用
SystemRequirements: C++98
或
CXX_STD = CXX98
这也将关闭Armadillo对OpenMP的偏好,而OpenMP在C++11下始终处于启用状态。
请参阅我在您链接的PR中的备注:
(无法使用OpenMP)仅适用于RcppArmadillo。可以通过
// [[Rcpp::plugins(openmp)]]
在带有Rcp的macOS上使用OpenMP。不过,你需要警惕存在的龙,因为R是单线程的。您可以通过修改RppArmadillo的
inline.R
的本地安装以包括-fopenmp
并删除inst/include/RcppArmadilloConfigGenerated.h
中的#define ARMA_DONT_USE_OPENMP 1
来手动重新获得OpenMP(在RppArmodillo中)
因此,Travis版本遇到的问题是RcppArmadillo
的二进制版本(来自CRAN)已在macOS版本上永久禁用OpenMP。
为R程序包编写自己的配置脚本将不会覆盖已安装的RcppArmadillo
程序包中包含的RcppArmadilloConfigGenerated.h
文件。该文件随后由RcppArmadillo.h
调用。唯一可以改变的方法是修改上游RcppArmadillo
,这反过来又依赖于BaseR提供适当的OpenMP检测挂钩。
- 嵌入方指针压缩已禁用
- OpenMP阵列性能较差
- OpenMP卸载说'fatal error: could not find accel/nvptx-none/mkoffload'
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- clang格式:禁用排序包含
- 如何在C++中找到active directory中禁用和锁定的窗口帐户
- 如何在C++生成器中禁用"使用调试.dcus"
- OpenMP:并行更新数组总是需要减少数组吗
- 如何在GTK程序运行时禁用屏幕保护程序/电源管理/屏幕消隐
- 如何使用OpenMP并行这两个循环
- 从python调用openMP共享库时,未定义opnMP函数
- 如何使用OpenMP并行化此矩阵时间矢量运算
- 如何使用OpenMP使这个循环并行
- 如何通过替换顺序代码的while循环来添加OpenMP for循环
- 查找最近配对时的OpenMP竞赛条件
- 为 OpenMP 函数创建别名 ||部分禁用 openMP
- RcppArmadillo:使用autoconf禁用OpenMP
- 在我的c++项目中禁用OpenMP pragma语句
- 如何以一种很好的方式禁用OpenMP指令
- 在运行时本地启用/禁用OpenMP