Я учусь использовать RcppParallel в своей работе и пытался установить простой пакет, созданный с помощью Rcpp.package.skeleton (). Пакет содержит три исходных файла: HelloWorld Rcpp (rcpp_hello_world.cpp) и две версии функций преобразования матриц, которые можно найти на веб-сайте RcppParallel (http://gallery.rcpp.org/articles/parallel-matrix-transform/). Серийная версия (matrixSqrt.cpp) и параллельная версия (parallelMatrixSqrt.cpp). Кроме того, я сделал необходимые дополнения к файлам DESCRIPTION и NAMESPACE и сделал Makevars и Makevars.win с предложенными строками.
Проблема в том, что, когда я пытаюсь установить пакет, я получаю следующую ошибку:
parallelMatrixSqrt.cpp: 14: 21: ошибка: NumericMatrix не называет тип
SquareRoot (постоянный вход NumericMatrix, выход NumericMatrix)
Я не знаю, если это проблема с компоновщиком. Файлы Makevars выглядят так:
Makevars
PKG_LIBS += $(shell ${R_HOME}/bin/Rscript -e "RcppParallel::RcppParallelLibs()")
Makevars.win
PKG_CXXFLAGS += -DRCPP_PARALLEL_USE_TBB=1
PKG_LIBS += $(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" \
-e "RcppParallel::RcppParallelLibs()")
РЕДАКТИРОВАТЬ:
Вот так выглядит параллельMatrixSqrt.cpp
#include <RcppParallel.h>
using namespace RcppParallel;
struct SquareRoot : public Worker
{
// source matrix
const RMatrix<double> input;
// destination matrix
RMatrix<double> output;
// initialize with source and destination
SquareRoot(const NumericMatrix input, NumericMatrix output)
: input(input), output(output) {}
// take the square root of the range of elements requested
void operator()(std::size_t begin, std::size_t end) {
std::transform(input.begin() + begin,
input.begin() + end,
output.begin() + begin,
::sqrt);
}
};
// [[Rcpp::export]]
NumericMatrix parallelMatrixSqrt(NumericMatrix x) {
// allocate the output matrix
NumericMatrix output(x.nrow(), x.ncol());
// SquareRoot functor (pass input and output matrixes)
SquareRoot squareRoot(x, output);
// call parallelFor to do the work
parallelFor(0, x.length(), squareRoot);
// return the output matrix
return output;
}
Спасибо
NumericMatrix
класс обеспечивается Rcpp
так что вам нужно получить к нему доступ, потянув в пространство имен Rcpp с помощью
using namespace Rcpp;
или явным образом префикс имени пространства имен, например,
Rcpp::NumericMatrix
Обратите внимание, что предупреждение о том, что избегать использования R / Rcpp API подразумевает отказ от их использования в определении вашего RcppParallel::Worker
функции. Основная причина, по которой вы хотите избежать использования R / Rcpp API в параллельном контексте, заключается в том, что эти процедуры могут:
longjmp
это взрывает вселенную (что, если я правильно понимаю, является допустимым следствием неопределенного поведения в программе на C ++)Как правило, вы можете построить свой Worker
объект из Rcpp
объекты, но, чтобы быть в безопасности, вы обычно хотите хранить связанные данные с локальным RcppParallel::RMatrix<T>
объект, так как этот объект является «более безопасным» в том смысле, что он предоставляет только подпрограммы, которые безопасны для использования в параллельном контексте — в частности, он предоставляет итераторы, которые позволяют использовать его с C ++ STL, чего должно быть достаточно во многих сценариях ,
Других решений пока нет …