Я пытаюсь взять следующий код и перевести его в кусок вязания (заимствованный из примеров 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_LIBS
и 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.opts
, в sourceCpp
. Следовательно, я предполагаю, что есть два потенциальных пути:
установка
engine.opts=list(env=...)
для передачи соответствующей среды; однако я получаю сообщение об ошибке (формальный аргумент "env" соответствует нескольким фактическим аргументам).Для установки среды можно использовать параметр ловушки/пользовательского фрагмента, но я не уверен, как именно это можно сделать.
Это с Knitr 1.0.11 и Rcpp 0.10.2.