gpt4 book ai didi

rcpp - RcppArmadillo 和 RcppParallel 的同居

转载 作者:行者123 更新时间:2023-12-04 17:48:06 26 4
gpt4 key购买 nike

以下玩具示例为 parallelFor工作正常( f2f1 的并行版本):

// [[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 返回的向量只包含未初始化的值。

非常感谢您的任何澄清。

最佳答案

这里的问题——你的类应该通过引用而不是值来获取向量。

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

所以你的 worker 应该看起来像(正如你所指出的):

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 ,当按值将其传递给工作人员时,您实际上是将一个全新的向量复制到类中,然后填充该(临时的、复制的)向量——因此原始向量实际上从未被填充。

关于rcpp - RcppArmadillo 和 RcppParallel 的同居,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26234055/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com