Eigen 和 Numpy -> 将矩阵从 Python 传递到C++



我正在做一个模拟项目,我正在尝试找出在Python和C++之间传递矩阵的最佳方法。我正在使用Python的NumPy和C++的Eigen库,并且我正在使用PyBind11使它们相互通信。

在我的代码中(见下文),我首先在我的 Python 脚本中使用 NumPy 创建一些数组,然后将这些数组作为参数传递给我调用rmodule的C++类的构造函数,它本质上将成为我模拟的数字引擎。我希望我的C++类的一个实例将这些 NumPy 数组作为对象属性(以便可以轻松引用它们),但我想知道这样做的最佳方法是什么。

如果我只是从 NumPy 数组到 Eigen 矩阵进行类型转换,PyBind 将不得不将所有数据复制到 C++ 程序中。虽然这似乎有很多开销,但我觉得如果复制速度快,与我对矩阵所做的计算相比,这是可以的。

我的另一个选择是只将对 NumPy 数组的引用传递给我的C++实例。这样,数据就不会在Python和C++之间来回复制 - 它将归Python所有并由C++类引用。我认为这可能会给我性能提升。但是,我不确定这样做是否会遇到麻烦 - 我是否必须以某种方式解决 GIL?如果这是更好的方法,我还应该记住哪些其他事情?

TLDR: 我使用Python进行文件I/O,C++用于计算。我应该在 Python 和C++之间来回复制数据,还是只是将数据归 Python 所有并将对该数据的引用传递给C++?

任何帮助和建议将不胜感激。

<小时 />

C++ 代码:

#include <pybind11/pybind11.h>
#include <random>
#include <iostream>
#include "Eigen/Dense"
#define R = 8.134 // Universal Gas Constant (J mol^-1 ºK^-1)
namespace py = pybind11;
using namespace Eigen;
class rmodule {
/** Encapsulated time-stepping logic that
can be easily constructed and referenced
by the Python interpreter.
:attributes:
C   - Concentration Vector
F   - Standard ΔGº_f of metabolites
T   - Temperature (ºK)
S   - Stoichiometric Matrix
*/
VectorXf C;
VectorXf F;
double   T = 0.0;
MatrixXf S;
public:
rmodule(VectorXf pyC, MatrixXf pyS, VectorXf pyF, double pyT) {
/** Copies numpy array data into C++ Eigen classes. */
C   = pyC;
S   = pyS;
F   = pyF;
T   = pyT;
}
~rmodule(){     // TODO -- Will need to free data structures
;
}
};
PYBIND11_MODULE(reaction, m) {
m.doc() = "ERT reaction module";    // TODO -- How to bind?
py::class_<rmodule>(m, "rmodule")
.def(py::init<>()) // Here is the Problem! What should I do here? Reference or value?
;
}

蟒蛇代码:

import parser
import react   # react is the name of my binary once I compile
import numpy as np
def main():
"""Program Driver"""
P = parser.Parser("test1.txt")
P.ReadData() # Builds numpy arrays
C = P.GetC()    # Initial Concentrations #
S = P.GetS()    # Stoichiometric Matrix #
F = P.GetF()    # Standard ΔGº #
rmodule = react.rmodule(C, S, F, T=273.15)

if __name__ == "__main__":
main()

想出了一个折衷方案!我将把值从 Python 复制到C++一次,然后只是过去对数据的引用从 C++ 复制到 Python。

最新更新