Как передать среду в блок Rcpp с помощью 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_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. Следовательно, я предполагаю, что есть два потенциальных пути:

  1. установка engine.opts=list(env=...) для передачи соответствующей среды; однако я получаю сообщение об ошибке (формальный аргумент "env" соответствует нескольким фактическим аргументам).

  2. Для установки среды можно использовать параметр ловушки/пользовательского фрагмента, но я не уверен, как именно это можно сделать.

Это с Knitr 1.0.11 и Rcpp 0.10.2.


person Kevin Ushey    schedule 14.02.2013    source источник


Ответы (2)


Я не знал, что пользователи будут передавать пользовательскую среду движку Rcpp, поэтому я передал среду по умолчанию аргументу env в sourceCpp(). Теперь я снял ограничение. Вы можете установить разрабатываемую версию на Github.

PKG_LIBS, упомянутый Дирком, здесь должен быть другой проблемой.

person Yihui Xie    schedule 15.02.2013
comment
Ницца. Двойное исправление, поскольку Rcpp в SVN теперь также решает проблему, о которой я упоминал в своем ответе. - person Dirk Eddelbuettel; 15.02.2013

Сегодня случайно поняли, что лечение PKG_LIBS глючит: перезаписывает вместо попыток. Поэтому я боюсь, что в настоящее время это не работает с атрибутами Rcpp.

Вы можете переключиться на использование пакета или установить флаги компиляции и т.д. в другом месте.

Редактировать 16 февраля Теперь это исправлено в SVN.

person Dirk Eddelbuettel    schedule 14.02.2013