Pybind11:使用 for 循环通过 OpenMP 访问 python 对象
Pybind11: Accessing python object with OpenMP using for-loop
我正在尝试对 python 字典的所有元素运行一个 c++ 函数。为此,我在字典的所有元素上使用 c++ 中的 for 循环。在这种情况下,据我所知,可以使用 #pragma omp parallel for simd
子句加快速度。但是,当我 运行 它时,我得到错误:
GC Object already Tracked
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
编辑
我在这篇文章post上读到,问题出在 C++ 中访问 Python 对象的方式,但没有进一步讨论。我想问题出在使用多个线程访问 python 对象。我目前仍在寻找。
如有任何提示,我们将不胜感激。
非常感谢。
C++代码
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <omp.h>
#include <chrono>
#include <thread>
namespace py = pybind11;
py::module nn = py::module::import("neat.nn");
py::object create_seq(
py::object self
){
unsigned int z;
#pragma omp parallel for simd
for(z = 0; z < 50000; z++){
double value = self.attr("dict").attr("__getitem__")(z).cast<double>();
value *=2;
self.attr("dict").attr("__setitem__")(z, value);
}
return self;
}
PYBIND11_MODULE(error, m){
m.doc() = "pybind11 module for iterating over generations";
m.def("create_seq", &create_seq,
"the function which creates a sequence");
}
Python代码
import os
import error
class func():
def __init__(self):
dictionary = {}
for i in range(50000):
dictionary[i] = i
self.dict = dictionary
self.array = None
def modify_dict(self):
return error.create_seq(self)
if __name__ == '__main__':
# Determine path to configuration file. This path manipulation is
# here so that the script will run successfully regardless of the
# current working directory.
local_dir = os.path.dirname(__file__)
a = func()
a.modify_dict()
print(a.dict)
编译:
g++ -O3 -Wall -shared -std=c++14 -fopenmp -fPIC `python3 -m pybind11 --includes` openmp.cpp -o error.so
问题确实是使用多线程访问 python 对象。我不知道确切的原因,但这根本不可能。诀窍是将 python 对象转换为 python 对象的列表,必须将其转换为向量。只有这样,多个线程才能访问向量的各种 python 对象。
在我的例子中,我传递的不是整个字典,而是列表中字典的值,然后将这个列表转换为 python 个对象的向量。
在简历中是这样的:
error.create_seq(list(dict.values()))
在 C++ 中:
std::vector<py::object> = dict.cast<std::vector<py::object>>();
然后可以应用 #pragma omp parallel
子句
我正在尝试对 python 字典的所有元素运行一个 c++ 函数。为此,我在字典的所有元素上使用 c++ 中的 for 循环。在这种情况下,据我所知,可以使用 #pragma omp parallel for simd
子句加快速度。但是,当我 运行 它时,我得到错误:
GC Object already Tracked
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
编辑
我在这篇文章post上读到,问题出在 C++ 中访问 Python 对象的方式,但没有进一步讨论。我想问题出在使用多个线程访问 python 对象。我目前仍在寻找。
如有任何提示,我们将不胜感激。
非常感谢。
C++代码
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <omp.h>
#include <chrono>
#include <thread>
namespace py = pybind11;
py::module nn = py::module::import("neat.nn");
py::object create_seq(
py::object self
){
unsigned int z;
#pragma omp parallel for simd
for(z = 0; z < 50000; z++){
double value = self.attr("dict").attr("__getitem__")(z).cast<double>();
value *=2;
self.attr("dict").attr("__setitem__")(z, value);
}
return self;
}
PYBIND11_MODULE(error, m){
m.doc() = "pybind11 module for iterating over generations";
m.def("create_seq", &create_seq,
"the function which creates a sequence");
}
Python代码
import os
import error
class func():
def __init__(self):
dictionary = {}
for i in range(50000):
dictionary[i] = i
self.dict = dictionary
self.array = None
def modify_dict(self):
return error.create_seq(self)
if __name__ == '__main__':
# Determine path to configuration file. This path manipulation is
# here so that the script will run successfully regardless of the
# current working directory.
local_dir = os.path.dirname(__file__)
a = func()
a.modify_dict()
print(a.dict)
编译:
g++ -O3 -Wall -shared -std=c++14 -fopenmp -fPIC `python3 -m pybind11 --includes` openmp.cpp -o error.so
问题确实是使用多线程访问 python 对象。我不知道确切的原因,但这根本不可能。诀窍是将 python 对象转换为 python 对象的列表,必须将其转换为向量。只有这样,多个线程才能访问向量的各种 python 对象。
在我的例子中,我传递的不是整个字典,而是列表中字典的值,然后将这个列表转换为 python 个对象的向量。
在简历中是这样的:
error.create_seq(list(dict.values()))
在 C++ 中:
std::vector<py::object> = dict.cast<std::vector<py::object>>();
然后可以应用 #pragma omp parallel
子句