【问题标题】:RcppParallel RVector push_back or something similar?RcppParallel RVector push_back 或类似的东西?
【发布时间】:2018-03-13 17:12:57
【问题描述】:

我正在使用 RcppParallel 来加速一些计算。但是,我在这个过程中内存不足,所以我想将结果保存在并行循环中,这些结果通过了一些相关性阈值。下面是一个玩具例子来说明我的观点:

#include <Rcpp.h>
#include <RcppParallel.h>
using namespace Rcpp;

// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::plugins(cpp11)]]
struct Example : public RcppParallel::Worker {
  RcppParallel::RVector<double> xvals, xvals_output, yvals;
  Example(const NumericVector & xvals, NumericVector & yvals, NumericVector & xvals_output) : 
    xvals(xvals), xvals_output(xvals_output), yvals(yvals) {}
  void operator()(std::size_t begin, size_t end) {
    for(std::size_t i=begin; i < end; i++) {
      double y = xvals[i] * (xvals[i] - 1);
      // if(y < 0) {
      //   xvals_output.push_back(xvals[i]);
      //   yvals.push_back(y);
      // }
      xvals_output[i] = xvals[i];
      yvals[i] = y;
    }
  }
};
// [[Rcpp::export]]
List find_values(NumericVector xvals) {
  NumericVector xvals_output(xvals.size());
  NumericVector yvals(xvals.size());
  Example ex(xvals, yvals, xvals_output);
  parallelFor(0, xvals.size(), ex);
  List L = List::create(xvals_output, yvals);
  return(L);
}

R 代码是:

find_values(seq(-10,10, by=0.5))

注释掉的代码是我想做的。

也就是说,我想初始化一个空向量,并仅附加通过某个阈值的 y 值以及相关的 x 值。

在我的实际使用中,我正在计算一个 MxN 矩阵,因此内存是一个问题。

解决这个问题的正确方法是什么?

【问题讨论】:

  • 首先,如果您使用push_back,请使用vector&lt;double&gt; 而不是NumericVector(请参阅why)。
  • 谢谢,我可以使用指向向量的指针 并且它可以工作,但这样做似乎存在一些并发问题(使用多个线程时它会随机崩溃)。

标签: r rcpp rcppparallel


【解决方案1】:

如果有人遇到过类似的问题,这里有一个使用 TBB 中的“concurrent_vector”的解决方案(RcppParallel 在后台使用它并且可以作为标题使用)。

#include <Rcpp.h>
#include <RcppParallel.h>
#include <tbb/concurrent_vector.h>
using namespace Rcpp;

// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::plugins(cpp11)]]
struct Example : public RcppParallel::Worker {
  RcppParallel::RVector<double> xvals;
  tbb::concurrent_vector< std::pair<double, double> > &output;
  Example(const NumericVector & xvals, tbb::concurrent_vector< std::pair<double, double> > &output) : 
    xvals(xvals), output(output) {}
  void operator()(std::size_t begin, size_t end) {
    for(std::size_t i=begin; i < end; i++) {
      double y = xvals[i] * (xvals[i] - 1);
      if(y < 0) {
        output.push_back( std::pair<double, double>(xvals[i], y) );
      }
    }
  }
};
// [[Rcpp::export]]
List find_values(NumericVector xvals) {
  tbb::concurrent_vector< std::pair<double, double> > output;
  Example ex(xvals,output);
  parallelFor(0, xvals.size(), ex);
  NumericVector xout(output.size());
  NumericVector yout(output.size());
  for(int i=0; i<output.size(); i++) {
    xout[i] = output[i].first;
    yout[i] = output[i].second;
  }
  List L = List::create(xout, yout);
  return(L);
}

输出:

> find_values(seq(-10,10, by=0.5))
[[1]]
[1] 0.5

[[2]]
[1] -0.25

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 2010-10-26
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多