【发布时间】:2020-03-09 22:47:54
【问题描述】:
我有一个在矩阵上执行filtering 的python 代码。我使用pybind11 创建了一个C++ 接口,它以序列化方式成功运行(请参阅下面的代码)。
我正在尝试使其并行处理,以希望与其序列化版本相比减少计算时间。为此,我将大小为M×N 的数组拆分为三个大小为M×(N/3) 的子矩阵,以使用相同的接口并行处理它们。
我使用 ppl.h 库创建了一个并行 for 循环,并在每个循环中调用大小为 M×(N/3) 的子矩阵上的 python 函数。
#include <iostream>
#include <ppl.h>
#include "pybind11/embed.h"
#include <pybind11/iostream.h>
#include <pybind11/stl_bind.h>
#include "pybind11/eigen.h"
#include "pybind11/stl.h"
#include "pybind11/numpy.h"
#include "pybind11/functional.h"
#include <Eigen/Dense>
namespace py = pybind11;
class myClass
{
public:
myClass()
{
m_module = py::module::import("myFilterScript");
m_handle = m_module.attr("medianFilter");
};
void medianFilterSerialized(Eigen::Ref<Eigen::MatrixXf> input, int windowSize)
{
Eigen::MatrixXf output;
output.resizeLike(input);
output = m_handle(input, windowSize).cast<Eigen::MatrixXf>();
};
void medianFilterParallelizedUsingPPL(Eigen::Ref<Eigen::MatrixXf> input, int windowSize)
{
Eigen::MatrixXf output;
output.resizeLike(input);
/* Acquire GIL before calling Python code */
//py::gil_scoped_acquire acquire;
Concurrency::parallel_for(size_t(0), size_t(3), [&](size_t i)
{
output.block(0, i * input.cols() / 3, input.rows(), input.cols() / 3) = m_handle(input.block(0, i * input.cols() / 3, input.rows(), input.cols() / 3).array(), windowSize).cast<Eigen::MatrixXf>();
});
//py::gil_scoped_release release;
};
private:
py::scoped_interpreter m_guard;
py::module m_module;
py::handle m_handle;
py::object m_object;
};
int main()
{
myClass c;
Eigen::MatrixXf input = Eigen::MatrixXf::Random(240, 120);
c.medianFilterSerialized(input, 3);
c.medianFilterParallelizedUsingPPL(input, 3);
return 0;
}
myFilterScript.py:
import threading
import numpy as np
import bottleneck as bn # can be installed from https://pypi.org/project/Bottleneck/
def medianFilter(input, windowSize):
return bn.move_median(input, window=windowSize, axis=0)
不管使用py::gil_scoped_acquire,我的代码在到达for循环时都会崩溃:
Access violation reading location // or:
Unhandled exception at 0x00007FF98BB8DB8E (ucrtbase.dll) in Pybind11_Parallelizing.exe: Fatal program exit requested.
是否有人可以帮助我了解 python 模块的加载函数是否可以以多处理或多线程方式并行调用?我的代码中缺少什么?请告诉我。提前致谢。
【问题讨论】:
标签: c++ multiprocessing python-multiprocessing pybind11 gil