Я хочу использовать arma::solve в rcppParallel worker. Проблема в том, что код приводит к сбою R, вероятно, из-за дисбаланса стека.
Чтобы избежать проблем с дисбалансом стека, следует использовать объекты RMatrix вместо объектов arma::mat в воркере, насколько я понимаю описание пакета rcppParallel. Однако arma::solve принимает только объекты arma::mat.
Как это делается правильно? Как правильно решить эту проблему?
Большое спасибо за любые предложения/помощь/исправления!
Ниже вы найдете мой подход, который, к сожалению, легко приводит к сбою R (особенно при выполнении несколько раз):
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <iostream>
using namespace Rcpp;
using namespace RcppParallel;
struct MakeITER : public Worker {
// input matrix to read from
const arma::mat MAT;
const arma::colvec VEC;
const int p;
// output matrix to write to
arma::mat res1;
MakeITER( arma::mat res, const arma::mat MAT0,
const arma::colvec VEC0, int p0)
: res1(res), MAT(MAT0), VEC(VEC0), p(p0){
res1.zeros();
}
void operator()(std::size_t begin, std::size_t end) {
int j, m;
arma::colvec coef(p);
for(m = begin; m < end; m++){
try{
coef = arma::solve(MAT, VEC);
for(j=0; j<p; j++) {
res1(j,m) = coef[j];
} ;
}catch(...){
for(j=0; j<p; j++) {
res1(j,m) = arma::datum::nan;
};
}
}
}
};
// [[Rcpp::export]]
arma::mat fuc( arma::mat MAT0, arma::colvec VEC0, int nmkt, int p0) {
// result:
arma::mat res(p0,nmkt);
MakeITER makeit(res, MAT0, VEC0, p0);
parallelFor(0, nmkt, makeit);
return( res );
};
In R:
# setup:
p1 = 5 # dimension of matrix to solve
nrep1= 70 # number of repetitions
set.seed(123)
MAT0 = matrix(rnorm(p1^2)/10,p1,p1)
VEC0 = matrix(rnorm(p1)/10,p1,1)
# Runs okay:
for(i in 1:10){
r1=fuc(MAT0, VEC0, nrep1, p1) ;str(r1)
}
# Results in crash of R (especially when executed serveral times):
for(i in 1:10){
r1=fuc(MAT0*0, VEC0, nrep1, p1) ;str(r1)
}
В Rstudio (версия R 3.1.2 (31 октября 2014 г., платформа: x86_64-w64-mingw32/x64 (64-разрядная)) я обычно получаю следующее сообщение:
Warning: stack imbalance in '.Call', 35 then 33
Warning: stack imbalance in '=', 29 then 27
Warning: stack imbalance in '{', 26 then 24
а потом:
Error: Unable to establish connection with R session
и есть фатальная ошибка.
arma_bad("solve(): solution not found");
, или, по крайней мере, добавлениеCXXFLAGS=-DARMA_DONT_PRINT_ERRORS
к ~/.R/Makevars успешно. Я не знаю, каковы будут лучшие практики Rcpp в этом случае... - person Martin Morgan   schedule 02.01.2015