Использование arma::solve с RcppParallel: как избежать дисбаланса стека?

Я хочу использовать 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

и есть фатальная ошибка.


person term    schedule 01.01.2015    source источник
comment
@DirkEddelbuettel - код в текущем сообщении использует RMatrix в рабочем процессе, поэтому актуальность предыдущего ответа не ясна?   -  person Martin Morgan    schedule 02.01.2015
comment
Запуск этого кода просто дает мне segfault (Ошибка: использование стека C 140730378409876 слишком близко к пределу), поэтому я думаю, что здесь есть что-то еще, более фундаментально неправильное.   -  person Kevin Ushey    schedule 02.01.2015
comment
Я думаю, что это сообщения об ошибках, напечатанные arma_bad("solve(): solution not found");, или, по крайней мере, добавление CXXFLAGS=-DARMA_DONT_PRINT_ERRORS к ~/.R/Makevars успешно. Я не знаю, каковы будут лучшие практики Rcpp в этом случае...   -  person Martin Morgan    schedule 02.01.2015
comment
@MartinMorgan «внутри» есть объекты Armadillo, которые (в настоящее время) являются прокси-объектами R.   -  person Dirk Eddelbuettel    schedule 02.01.2015
comment
@DirkEddelbuettel Да, вопрос похож на stackoverflow.com/questions/27523979 / Однако проблема по-прежнему возникала в примере, когда я пытался настроить код для решения из этого поста (теперь я изменил вопрос, чтобы сделать подход более похожим на решение из упомянутого поста). Поэтому мой вопрос показался мне не дублирующим. Большое спасибо за ваш ценный намек на то, что «внутри» есть объекты Armadillo, которые (в наши дни) являются прокси-объектами R.   -  person term    schedule 02.01.2015
comment
@MartinMorgan Отлично! Добавление строки: PKG_CXXFLAGS=-DARMA_DONT_PRINT_ERRORS в файл Makevars в папке src разрабатываемого «пакета R» также работает для меня. Для меня это хорошее решение, и я был бы рад принять его в качестве ответа на вопрос, если вы хотите сделать репост. Я не мог бы узнать это самостоятельно. Большое спасибо!   -  person term    schedule 02.01.2015