如何在不复制基础数据的情况下从 Eigen::Tensor 创建 Rcpp NumericVector

问题描述

如果我在 Eigen 中创建一个大张量,并且我喜欢将张量作为多维数组返回给 R。我知道如何使用如下数据复制来完成。问题:是否可以在没有数据复制步骤的情况下进行?

#include <Rcpp.h>
#include <RcppEigen.h>
#include <unsupported/Eigen/CXX11/Tensor>

// [[Rcpp::depends(RcppEigen)]]
using namespace Rcpp;

template <typename T>
NumericVector copyFromTensor(const T& x) 
{ 
    int n = x.size();
    NumericVector ans(n);
    IntegerVector dim(x.NumDimensions);
    for (int i = 0; i < x.NumDimensions; ++i) {
      dim[i] = x.dimension(i);
    }
    memcpy((double*)ans.begin(),(double*)x.data(),n * sizeof(double));
    ans.attr("dim") = dim;
    return ans;
}

// [[Rcpp::export]]
NumericVector getTensor() {
    Eigen::Tensor<double,3> x(4,3,1);
    x.setRandom();
    return copyFromTensor(x);
}

/*** R
getTensor()
*/

解决方法

作为一般规则,您可以零复制一个您的 C++ 代码中,数据来自 R 并且已经由 R 管理。

在将数据返回给 R 的 C++ 代码输出过程中,必须复制任何未使用 R 分配器创建的内容。

这里您的对象 x 是堆栈分配的,因此您需要一个副本。有关 R 分配器,请参阅编写 R 扩展;当你创建一个新的 Tensor 对象时,Eigen 可能会让你使用它。不是微不足道的一步。我想我会接受副本。