首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RcppArmadillo和RcppParallel的共存

RcppArmadillo和RcppParallel的共存
EN

Stack Overflow用户
提问于 2014-10-07 10:36:07
回答 1查看 1.2K关注 0票数 7

下面的parallelFor玩具示例很好(f2f1的并行版本):

代码语言:javascript
复制
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <iostream>
#define vector NumericVector

using namespace Rcpp;
using namespace RcppParallel;


// compute values i/i+1 for i = 0 to n-1
// [[Rcpp::export]]
vector f1(int n) {
  vector x(n);
  for(int i = 0; i < n; i++) x[i] = (double) i/ (i+1);
  return x;
}

struct mytry : public Worker {
  vector output;

  mytry(vector out) : output(out) {}

  void operator()(std::size_t begin, std::size_t end) {
    for(int i = begin; i < end; i++) output[i] = (double) i/ (i+1);
  }

};

// [[Rcpp::export]]
vector f2(int n) {
  vector x(n);
  mytry A(x);
  parallelFor(0, n, A);
  return x;
}

但是,如果我将#define vector NumericVector替换为#define vector arma::vec,则不再起作用。代码编译并运行,f1是好的,但是f2返回的向量只包含未初始化的值。

非常感谢您的任何澄清。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-08 17:21:00

这里的问题是--你的课应该是参考向量,而不是价值向量。

这是因为,在使用RcppParallel时,您通常会为某个对象预先分配内存,然后填充该对象--所以并行工作人员应该引用要填充的对象。

因此,您的员工应该看起来像(正如您已经注意到的):

代码语言:javascript
复制
struct mytry : public Worker {
  vector& output;

  mytry(vector& out) : output(out) {}

  void operator()(std::size_t begin, std::size_t end) {
    for(int i = begin; i < end; i++) output[i] = (double) i/ (i+1);
  }

请注意,这对于Rcpp向量是可行的(也许令人惊讶),因为它们已经是‘代理’对象--只是封装了指向数据的指针的对象。通过值传递Rcpp向量时,可以复制指针(而不是底层数据!)加上一些额外的向量位(例如向量的长度) --因此“复制”保留了对相同数据结构的引用。

当您使用更“经典”的向量(例如arma::vecstd::vector )时,当按值将该向量传递给工作人员时,您实际上是在将一个全新的向量复制到类中,然后填充该向量(临时的、复制的)向量--因此原始向量实际上永远不会被填充。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26234055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档