首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RcppArmadillo:使用autoconf禁用OpenMP

RcppArmadillo:使用autoconf禁用OpenMP
EN

Stack Overflow用户
提问于 2017-10-13 06:37:09
回答 2查看 765关注 0票数 2

在Dirk对这个问题的评论中,我提到了RcppArmadillo使用的configure.ac脚本,以便在构建时以编程方式检查OS上是否支持OpenMP。然后,我觉得这听起来太复杂了,对我来说没有必要,但我尝试了一些方法来避免OpenMP问题,但当我在Travis上测试它时,它似乎仍然存在。

所以我现在要做的是:

1. configure.ac

我已经(有些明目张胆地,但我当然会遵守GPL-2许可证)复制了RcppArmadillo使用的RcppArmadillo脚本,删除了一些部件(例如,LAPACK检查)和调整后的名称等等。

2. Makevars

src/Makevars重命名为src/Makevars.in,现在它读取

代码语言:javascript
复制
PKG_CXXFLAGS = -I../inst/include @OPENMP_FLAG@
PKG_LIBS= @OPENMP_FLAG@ $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)

src/Makevars.win

代码语言:javascript
复制
PKG_CXXFLAGS = -I../inst/include -I. $(SHLIB_OPENMP_CXXFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)

3.清理

添加了一个包含

代码语言:javascript
复制
#!/bin/sh
rm -f config.* src/Makevars src/config.h inst/include/pkgConfigGenerated.h

4. pkgConfigated.h

添加了一个文件inst/include/pkgConfigGenerated.h.in,如下所示:

代码语言:javascript
复制
#ifndef pkg__pkgConfigGenerated__h
#define pkg__pkgConfigGenerated__h
@HAVE_OPENMP@
#endif

5. pkgConfig.h

基于RcppArmadilloConfig.h文件,我将inst/include/pkgConfig.h创建为

代码语言:javascript
复制
#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。我还需要做些额外的连接吗?
  • 我还需要做什么吗?

有效的解决方案

根据德克的回答,我做了以下工作。我从configure.ac中借用了RcppArmadillo文件,并包含了我所需要的部分,并做了一些小改动(我在这里包括了所有这些内容,以供将来参考):

代码语言:javascript
复制
## 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

我的主要错误是,我认为在这个autoconf configure.ac 文件中自动调用了来获取 configure**,,但它不是!**

相应的Makevars.in

代码语言:javascript
复制
PKG_CXXFLAGS = @OPENMP_FLAG@
PKG_LIBS= @OPENMP_CFLAG@ $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)

(也许这两个旗子可以简化为一个,但不要修复没有损坏的.)

现在,我可以在Linux和OS上传递构建(除了OS和devel版本的R,因为RcppArmadillo无法安装,但这似乎是一个不同的问题)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-13 11:40:16

一到四似乎没问题,我甚至不认为你需要两份文件。只需设置ARMA_USE_OPENMP或其补体ARMA_DONT_USE_OPENMP

考虑一下,也可以分别通过-DARMA_USE_OPENMP-DARMA_DONT_USE_OPENMP将其添加到编译标志中。

5有点麻烦,因为您似乎不知道如何设置包含标志。有更多的理由不依赖额外的文件,嗯?-)

让我们看看进展如何。我们可以决定帮助提供一个R级函数,您可以从脚本configure (然后可以是bash,或者使用Rscript)调用R级函数。

编辑:刚刚实现了一个可以使用的简单得多的修复方法:简单地将C++98作为编译标准。正如编写R扩展所述:

相反,若要确保假定C++98标准(即使这不是编译器默认设置),请使用 SystemRequirements: C++98 或 CXX_STD = CXX98

这也将关闭Armadillo对OpenMP的偏爱,因为它总是在C++11下运行。

票数 2
EN

Stack Overflow用户

发布于 2017-10-13 14:02:38

参见我在你链接的按下中的评论:

(无法使用OpenMP)只是RcppArmadillo的情况。通过OpenMP在macOS上使用Rcpp是可能的。不过,由于R是单线程的,所以您需要警惕存在的龙。 您可以手动重获OpenMP (在RcppArmadillo中),方法是修改RcppArmadillo的inline.R的本地安装以包含-fopenmp,并删除inst/include/RcppArmadilloConfigGenerated.h中的#define ARMA_DONT_USE_OPENMP 1

因此,您在Travis构建中遇到的问题是RcppArmadillo的二进制构建(来自CRAN)在macOS构建上永久禁用了OpenMP。

为R包编写自己的配置脚本不会覆盖已安装的RcppArmadilloConfigGenerated.h包中包含的RcppArmadillo文件。该文件随后由RcppArmadillo.h调用。唯一可以改变的方法是如果上游RcppArmadillo被修改,这反过来又依赖于Base提供适当的OpenMP检测钩子。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46723854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档