簡體   English   中英

Pybind11:使用Pybind11在C++中轉換numpy數組的問題

[英]Pybind11: Problem of conversion of numpy array in C++ using Pybind11

I am trying to get a Python array from C++ and put it back into a Python function using also C++ with Pybind11. First, I access a dictionary of numpy arrays, and then put each of those numpy arrays into a Python function which just computes the sum of the elements in the array. 給我帶來麻煩的代碼的主要部分是:

        py::array item = list_items.attr("__getitem__")(i); 
    //equivalent to dict.__getitem__[i]

    //code runs if removing the following line
        boost_mod.attr("sum_of_dict")(item).cast<int>(); 
    //calls the function sum_of_dict in the module boost_mod having as argument a 1D numpy array
    //this function computes the sum of the elements in the numpy array, which are all integers 

我想我有一個轉換問題,我不明白如何克服它。 我查看了此文檔鏈接,但沒有幫助。 我還查看了不同的cast陣容,以及其他類似這個另一個的帖子,但它們不適用於我的問題,因為它們不使用 pybind。 對於轉換和使用我的 numpy 陣列 object 的任何幫助或任何提示將不勝感激。 非常感謝


完整代碼如下:

C++代碼

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <chrono>
#include <thread>
#include <Python.h>
namespace py = pybind11;
py::module boost_mod = py::module::import("boost_mod");

int parallelize(py::dict list_items, py::object q_in, py::object q_out){

    unsigned int sum = 0;
    unsigned int len = list_items.attr("__len__")().cast<int>();
    for( unsigned int i = 0; i < len ; i++){

        //PROBLEM IS HERE//
        py::array item = list_items.attr("__getitem__")(i);
        sum+= boost_mod.attr("sum_of_dict")(item).cast<int>();
        std::this_thread::sleep_for(std::chrono::milliseconds(5));

    }
    return sum;
}

PYBIND11_MODULE(cpp_parallel, m) {

    m.doc() = "pybind11 plugin";
    m.def("parallelize", &parallelize,
      "a function");
}

Python 模塊,其中包含 function

import numpy as np
import cpp_parallel as cpp

class child(object):
    def __init__(self, index):
        self.nb = index
        self.total = None

    def sum(self, i, j):
        return self.nb + self.nb

    def create_dict(self):
        self.list_items = {}
        for i in range(self.nb):
            lth = np.random.randint(1,10)
            a = np.random.binomial(size=lth, n=1, p =0.6)
            self.list_items[i] = a
        return self.list_items

    def sum_of_dict(self, element):  # fonction comme eval function
        a = np.sum(element)
        return a

    def sub(self, q_in, q_out):
        //FUNCTION CALLED FROM C++//
        return cpp.parallelize(self.list_items, q_in, q_out)

Python代碼

from multiprocessing import Process, Queue
import time
import boost_mod as test
import cpp_parallel as cpp

q_in = Queue()
q_out = Queue()

q_in.put(True)

dict_evaluated = test.child(1000)
dict_evaluated.create_dict()
dict_evaluated.sub(q_in, q_out)

實際上,我沒有正確實例化我從中調用 function 的模塊。 將 go 歸功於 Wim Lavrijsen。 答案如下:

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <omp.h>
#include <chrono>
#include <thread>
#include <Python.h>
namespace py = pybind11;
py::module boost_mod = py::module::import("boost_mod");


int parallelize(py::object child, py::object q_in, py::object q_out){

    unsigned int sum = 0;
    py::object items = child.attr("list_items");
    unsigned int len = items.attr("__len__")().cast<int>();
    #pragma omp simd reduction (+:sum)
    for( unsigned int i = 0; i < len ; i++){

        py::array item = items.attr("__getitem__")(i);
        sum += child.attr("sum_of_dict")(item).cast<int>();
        bool accord = q_in.attr("get")().cast<bool>();
        if (accord == true){
          q_out.attr("put")(sum);
        }
        accord = false;
        std::this_thread::sleep_for(std::chrono::milliseconds(5));
    }
    return sum;
}

PYBIND11_MODULE(cpp_parallel, m) {

    m.doc() = "pybind11 example plugin";

    m.def("parallelize", &parallelize,
      "the function which parallelizes the evaluation");
}

和子 class:

from multiprocessing import Process, Event, Lock, Queue, Pipe
import time
import numpy as np
import cpp_parallel as cpp

class child(object):
    def __init__(self, index):
        self.nb = index
        self.total = None

    def sum(self, i, j):
        return self.nb + self.nb

    def create_dict(self):
        self.list_items = {}
        for i in range(self.nb):
            lth = np.random.randint(1,10)
            a = np.random.binomial(size=lth, n=1, p =0.6)
            self.list_items[i] = a

    def sum_of_dict(self, element):  # fonction comme eval function
        a = np.sum(element)
        return a

    def sub(self, q_in, q_out):
        return cpp.parallelize(self, q_in, q_out)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM