我想在rcppParallel worker中使用arma :: solve。 问题是代码导致R崩溃,可能是由于堆栈不平衡。
为了避免堆栈不平衡问题,我应该在worker中使用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 );
};
在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(2014-10-31,平台: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
并且存在致命错误。