3

我正在尝试采用以下代码并将其转换为 knitr 块(从 Rcpp 示例中借用):

library(Rcpp)
library(inline)

openMPCode <- '
   std::vector<double> x = Rcpp::as<std::vector< double > >(xs);
   size_t n = x.size();
   #pragma omp parallel for shared(x, n)
   for (size_t i=0; i<n; i++) {
     x[i] = ::log(x[i]);
   }
   return Rcpp::wrap(x);
'

## modify the plugin for Rcpp to support OpenMP
settings <- getPlugin("Rcpp")
settings$env$PKG_CXXFLAGS <- paste('-fopenmp', settings$env$PKG_CXXFLAGS)
settings$env$PKG_LIBS <- paste('-fopenmp -lgomp', settings$env$PKG_LIBS)
funOpenMP <- rcpp(signature(xs="numeric"), body=openMPCode, settings=settings)

本质上,主要问题是确保将环境传递到 knitr 块中,以便在编译代码时正确设置PKG_LIBSand 。块的外观PKG_CXXFLAGS示例:knitr

```{r engine='Rcpp'}
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector openmp_log( NumericVector x ) {
  size_t n = x.size();
  #pragma omp parallel for
  for( size_t i=0; i < n; i++ ) {
    x[i] = ::log10( x[i] );
  }
  return x;
}
```

如果我理解正确,knitr 使用sourceCpp块中的任何内容来编译它,并将指定的选项传递engine.optssourceCpp. 因此,我想有两种可能的途径:

  1. 设置engine.opts=list(env=...)以便通过适当的环境;但是,尝试此操作时出现错误(形式参数“env”与多个实际参数匹配)。

  2. A hook / custom chunk option could be used to set the environment, but I'm not sure how this could be done exactly.

This is with knitr 1.0.11 and Rcpp 0.10.2.

4

2 回答 2

3

I did not realize users would pass a custom environment to the Rcpp engine, so I passed a default environment to the env argument in sourceCpp(). Now I have removed the restriction. You can install the development version on Github.

PKG_LIBS mentioned by Dirk should be a different problem here.

于 2013-02-15T05:41:36.337 回答
1

We happen to have realized today that the PKG_LIBS treatment is buggy: overwrites instead of attempts. So I fear this currently does not work with Rcpp Attributes.

You could switch to using a package, or setting your compile etc flags somewhere else.

Edit Feb 16 This is now fixed in SVN.

于 2013-02-14T20:17:19.147 回答