Pybind11: Доступ к python объекту с OpenMP с помощью цикла for - PullRequest
0 голосов
/ 11 января 2020

Я пытаюсь использовать функцию c ++ для всех элементов словаря python. Для этого я использую для l oop в C ++ по всем элементам словаря. В этом случае, насколько я понимаю, это можно ускорить, используя предложение #pragma omp parallel for simd. Однако при запуске я получаю сообщение об ошибке:

G C Объект уже отслежен
Процесс завершен с кодом выхода 139 (прерван сигналом 11: SIGSEGV)

Редактировать

Я прочитал в этом сообщении , что проблема связана с доступом к объекту Python в c ++, однако это не так go в дальнейшее обсуждение. Я предполагаю, что проблема заключается в доступе к объекту 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

1 Ответ

1 голос
/ 11 января 2020

Проблема действительно заключается в доступе к объекту 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

...