简体   繁体   English

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

[英]Eigen and Numpy -> Passing Matrices from Python to C++

I'm working on a simulation project, and I'm trying to figure out the best way to pass matrices between Python and C++.我正在做一个模拟项目,我试图找出在 Python 和 C++ 之间传递矩阵的最佳方法。 I'm using Python's NumPy and C++'s Eigen library, and I'm using PyBind11 to get them to communicate with eachother.我正在使用 Python 的 NumPy 和 C++ 的 Eigen 库,并且我正在使用PyBind11让它们相互通信。

In my code (see below), I first create some arrays using NumPy in my Python script, and then I pass these as parameters to a constructor function of a C++ class I call rmodule , which is essentially going to be the numerical engine of my simulation. In my code (see below), I first create some arrays using NumPy in my Python script, and then I pass these as parameters to a constructor function of a C++ class I call rmodule , which is essentially going to be the numerical engine of my模拟。 I want an instance of my C++ class to have these NumPy arrays as object attributes (so they can be easily referenced), but I'm wondering what the best way to do this is. I want an instance of my C++ class to have these NumPy arrays as object attributes (so they can be easily referenced), but I'm wondering what the best way to do this is.

If I just do a type conversion from a NumPy array to an Eigen matrix, PyBind is going to have to copy all that data to the C++ program.如果我只是从 NumPy 数组到特征矩阵进行类型转换,PyBind 将不得不将所有数据复制到 C++ 程序。 Although this seems like a lot of overhead, I feel like this would be ok if the copying is fast compared to the computations I do with the matrices.尽管这看起来开销很大,但我觉得如果与我对矩阵进行的计算相比,复制速度更快,这将是可以的。

My other choice is to only pass a reference to the NumPy arrays to my C++ instance.我的另一个选择是仅将 NumPy arrays 的引用传递给我的 C++ 实例。 That way, the data is not going to be copied back and forth between Python and C++ - its going to be owned by Python and referenced by the C++ class. That way, the data is not going to be copied back and forth between Python and C++ - its going to be owned by Python and referenced by the C++ class. I think this may give me a performance speedup.我认为这可能会给我带来性能加速。 However, I'm not sure if I'll run into trouble doing this - will I have to work around the GIL in some way?但是,我不确定这样做是否会遇到麻烦——我是否必须以某种方式解决GIL问题? What other things should I keep in mind if this is the better approach?如果这是更好的方法,我还应该记住哪些其他事情?

TLDR: I'm using Python for File I/O and C++ for computations. TLDR:我使用 Python 进行文件 I/O 和 C++ 进行计算。 Should I copy the data back and forth between Python and C++ or just have the data under Python's ownership and pass a reference to that data to C++?我应该在 Python 和 C++ 之间来回复制数据,还是只让数据归 Python 拥有,并将对该数据的引用传递给 C++?

Any help and advice is greatly appreciated.非常感谢任何帮助和建议。


C++ Code: 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?
        ;
}

Python Code: Python 代码:

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()

Figured out a compromise, I'm going to copy the values from Python to C++ once.想出一个折衷方案,我将把 Python 的值复制到 C++ 一次。 and then just past references to the data from C++ to Python.然后只是过去对从 C++ 到 Python 的数据的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM