【问题标题】:How does eigen raw buffer change even when reference is passed to a function即使将引用传递给函数,特征原始缓冲区如何变化
【发布时间】:2017-03-11 15:12:43
【问题描述】:

我正在构建一个 C++ 程序,该程序能够通过原始缓冲区与 python 交互,具体来说,numpy。我正在使用特征库进行矩阵运算。然后我发现了这种非常奇怪的行为。

您可能知道,numpy 中的 ndarray 是行主要的,所以我在我的 C++ 程序中创建了一个行主要矩阵映射,以便包装来自 numpy 的 PyObject 的原始缓冲区。但是,我的程序中的所有函数都使用列主矩阵,因此,这些函数是使用具有列主特征矩阵类型的 const 引用参数实现的。我注意到,即使我在这类函数中传递了行主矩阵映射,程序运行良好并且可以保证正确性。尽管如此,我仍然想弄清楚为什么会发生这种情况

我在一个函数中打印了行主矩阵映射和列主矩阵的原始缓冲区内的数据内容。我发现数据布局已经以某种方式改变了。所以我的问题是,这是怎么发生的?是否有对此负责的内存副本?

我还编写了一个简单的 C++ 程序,它完全按照我上面描述的方式进行。任何人都可以把它当作这个问题的演示。

#include <Eigen/Dense>
#include <Eigen/Core>
#include <iostream>

using MatMap = Eigen::Map< Eigen::Matrix<int, Eigen::Dynamic,    
                          Eigen::Dynamic, Eigen::RowMajor> >;

using Mat = Eigen::Matrix<int, Eigen::Dynamic,
                        Eigen::Dynamic, Eigen::ColMajor>;

void Func(const Mat &m, int dim) {
  // Print internal raw buffer of m
  std::cout << std::endl;
  for (int i = 0; i < dim * dim; i++)
    std::cout << *(m.data() + i) << std::endl;
  std::cout << std::endl;
}

int main() {
  int dim = 3;

  // Raw buffer
  int *raw = new int[dim * dim];

  for (int i = 0; i < dim * dim; i++)
    raw[i] = i;

  // Matrix Map
  MatMap mat(nullptr, 0, 0);

  // Create
  new (&mat) MatMap(raw, dim, dim);

  // Print raw buffer of mat
  std::cout << std::endl;
  for (int i = 0; i < dim * dim; i++)
    std::cout << *(mat.data() + i) << std::endl;
  std::cout << std::endl;

  // Function call
  Func(mat, dim);

  return 0;
}

上面程序的结果是这样的:

0
1
2
3
4
5
6
7
8


0
3
6
1
4
7
2
5
8

【问题讨论】:

    标签: c++ matrix eigen


    【解决方案1】:

    这种行为是完全可以预料的。当使用不同于Mat 对象的第一个参数调用void Func(const Mat &amp;m, int dim) 时,它会被复制到Mat 类型的临时对象中。这是可能的,因为参数是一个 const 引用,并且存在来自任何 Eigen 表达式的隐式 Matrix 构造函数。更准确地说,这是调用Func(mat, dim); 时发生的情况:

    Mat tmp(mat);
    Func(tmp,dim);
    tmp.~Mat();
    

    tmpmat 都表示同一个矩阵,但存储顺序不同。

    【讨论】:

      猜你喜欢
      • 2010-10-11
      • 2015-04-19
      • 1970-01-01
      • 2022-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-27
      相关资源
      最近更新 更多