【问题标题】:Stack imbalance with RcppParallelRcppParallel 的堆栈不平衡
【发布时间】:2014-12-17 10:57:43
【问题描述】:

我编写了以下代码来训练自己使用 RcppParallel。这只是一个玩具示例。

// [[Rcpp::depends(RcppParallel)]]
#include <Rcpp.h>
#include <RcppParallel.h>
#include <iostream>
using namespace Rcpp;
using namespace RcppParallel;


struct Lapin : public Worker {
  // input pars
  const NumericVector input;
  const size_t dim;

  // outputs a matrix
  NumericMatrix output;

  // two constructors
  Lapin(const NumericVector input, const int dim) : input(input), dim(dim), output(NumericMatrix(dim,dim)) {}

  Lapin(const Lapin & jeannot, Split) : input(jeannot.input), dim(jeannot.dim), output(NumericMatrix(dim,dim)) {}

  // the working operator
  void operator()(size_t begin, size_t end) {
    for(size_t k = begin; k < end; k++) {
      for(size_t i = 0; i < dim; i++) {
        for(size_t j = 0; j < dim; j++) {
          output(i,j) += input(k)+i+j;
        }
      }
    }
  }

  // the join
  void join(const Lapin & peter) {
    output += peter.output;
  }
};

// [[Rcpp::export]]
NumericMatrix f(NumericVector A, size_t dim) {
  Lapin groumf(A, dim);
  parallelReduce(0, A.length(), groumf);
  return groumf.output;
}

这是在 R 中发生的事情,在 sourceCpp-ing 之后:

> f(rep(1,1100), 5)
     [,1] [,2] [,3] [,4] [,5]
[1,] 1100 2200 3300 4400 5500
[2,] 2200 3300 4400 5500 6600
[3,] 3300 4400 5500 6600 7700
[4,] 4400 5500 6600 7700 8800
[5,] 5500 6600 7700 8800 9900
> sourceCpp("parallel-matrix-reduce.cpp")
> f(rep(1,1100), 5)
Warning: stack imbalance in '.Call', 6 then 11
     [,1] [,2] [,3] [,4] [,5]
[1,] 1100 2200 3300 4400 5500
[2,] 2200 3300 4400 5500 6600
[3,] 3300 4400 5500 6600 7700
[4,] 4400 5500 6600 7700 8800
[5,] 5500 6600 7700 8800 9900

请注意,这种行为是不稳定的:有时,我根本没有任何警告,有时是第一次运行......我想我的会话信息在这里很有用:

> sessionInfo()
R version 3.1.2 (2014-10-31)
Platform: x86_64-redhat-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=fr_FR.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=fr_FR.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=fr_FR.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] Rcpp_0.11.3

loaded via a namespace (and not attached):
[1] RcppParallel_4.3.3 tools_3.1.2       

提前感谢大家的回答和cmets。

编辑 正如 Dirk 在下面解释的那样,这是由于在 Worker 中使用了 R 类型,这使垃圾收集器感到困惑。我通过使用犰狳矩阵解决了这个问题(我对 RMatrix 有点困惑)。这是更正后的代码:

// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <iostream>
using namespace Rcpp;
using namespace RcppParallel;


struct Lapin : public Worker {
  // input pars
  const arma::vec input;
  const size_t dim;

  // outputs a matrix
  arma::mat output;

  // two constructors
  Lapin(const arma::vec input, const int dim) : input(input), dim(dim), output(arma::mat(dim,dim)) {
    output.zeros();
  }

  Lapin(const Lapin & jeannot, Split) : input(jeannot.input), dim(jeannot.dim), output(arma::mat(dim,dim)) {
    output.zeros();
  }

  // the working operator
  void operator()(size_t begin, size_t end) {
    for(size_t k = begin; k < end; k++) { 
      for(size_t i = 0; i < dim; i++) {
        for(size_t j = 0; j < dim; j++) {
          output(i,j) += input(k)+i+j;
        } 
      }
    }
  }
  // the join
  void join(const Lapin & peter) {
    output += peter.output;
  }
};

// [[Rcpp::export]]
arma::mat f(arma::vec & A, size_t dim) {
  Lapin groumf(A, dim);
  parallelReduce(0, A.size(), groumf);
  return groumf.output;
}

【问题讨论】:

  • 不确定它的相关性,但堆栈不平衡警告在R internals 的第 5.9.1 节中有简要介绍。
  • 谢谢,一点帮助都没有。在不要直接使用PROTECT和UNPROTECT,留给Rcpp和RcppParallel...

标签: rcpp


【解决方案1】:

仔细查看 Rcpp 库中的 example such as the parallel distance

它确实使用NumericMatrix,而是使用RMatrix&lt;double&gt;。我会在这里做同样的事情,并且通常主张在运行并行段时不要依赖与 R 类型的接触。

【讨论】:

  • 非常感谢德克。我不得不承认我跳过了这个例子中明确提到的细节。我会试试,让你知道。我有点惊讶,因为这段代码在我的台式计算机上运行良好,但在我的“计算集群”上运行良好,你是否知道这种行为是否依赖于架构?
  • 呸,我的意思是说包含您的答案的已编辑问题
  • 我们可以使用 List 作为输入解析吗?我在使用列表时遇到问题。请看我的问题stackoverflow.com/questions/37562779/…
猜你喜欢
  • 2016-10-15
  • 2016-05-06
  • 1970-01-01
  • 2011-05-22
  • 1970-01-01
  • 2014-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多