Проблема с скомпилированными объектами Cython и многопроцессорностью на Python 3 - PullRequest
0 голосов
/ 14 января 2020

У меня есть библиотека объектов, скомпилированная с использованием Cython. Когда я пытаюсь использовать эти объекты в простом сценарии, используя python 3 с мультипроцессором (Пул) python выдает ошибку засоления. Странная вещь в том, что если я использую python 2, everithing работает как положено (компилирует код с помощью Cython в python 2 и запускает его с python 2). Более того, когда я пытаюсь выполнить простой сценарий для выбора объектов Cython на python 3 (без многопроцессорной обработки), проблем не возникает.

Вот небольшой пример того, что у меня есть:

example_lib.pyx:

'''
example_lib.pyx
'''

#import numpy as np

include "cython_object.pyx"

cython_object.pyx:

cdef class CythonObject:
    def __init__(self, str name, int a, int b):

        self._name = name
        self._a = a
        self._b = b

    property Name:
        '''
        Returns the name of the object.
        '''   
        def __get__(self):
            return self._name

    property A:
        '''
        Returns a.
        '''   
        def __get__(self):
            return self._a

    property B:
        '''
        Returns b.
        '''   
        def __get__(self):
            return self._b

    cpdef getSum(self):
        return self._a + self._b

    cpdef dict pack(self):
        cdef dict pack = { 'name': self._name
                         , 'a'   : self._a
                         , 'b'   : self._b
                         }
        return pack

    cpdef unPack(self, dict pack):
        self._name = str(pack['name'])
        self._a = int(pack['a'])
        self._b = int(pack['b'])

example_lib_setup:

try:
    from setuptools import setup
    from setuptools import Extension
except ImportError:
    from distutils.core import setup
    from distutils.extension import Extension
from Cython.Build import cythonize
import numpy

setup(
    name = 'cythonobjects'
   ,ext_modules = cythonize("example_lib.pyx")
   ,include_dirs=[numpy.get_include()]
)     

test.py:

import multiprocessing
from example_lib import *

def runReplica(inputs):
    (i, objs) = inputs
    for obj,pack in objs:
        obj.unPack(pack)
        print('Rep:{}. Name: {}. {} + {} = {}'.format(i, obj.Name, obj.A, obj.B, obj.getSum()))

if __name__ == '__main__':

    obj1 = CythonObject('obj1', 2, 3)
    obj2 = CythonObject('obj2', 4, 2)

    objs = [obj1, obj2]

    num_rep = 3
    num_pool = 2

    packs = [(obj,obj.pack()) for obj in objs]
    if num_pool==1 or num_rep==1:
        for i in range(num_rep):
            runReplica((i,packs))
    else:
        pool = multiprocessing.Pool(num_pool)
        print ("Running parallelized replicas")
        pool.map(runReplica,[(i,packs) for i in range(num_rep)])

Makefile:

PYTHON=py -3
PYTHONVERSION=36
PYTHONHOME=C:\Python36
NUMPYINCLUDE=C:\Python36\lib\site-packages\numpy\core\include
CYTHON=cython.exe
CC=gcc
RM=rm
RMR= rm -r
MKDIR=mkdir
MKDIRR=mkdir -r
RMDIR=rmdir /s /q
CP=cp
UIC= pyside-uic
RCC= pyside-rcc
DEV=0
DEBUG=0

all:
    make example_pyd

example_pyd:
    $(PYTHON) example_lib_setup.py build_ext --inplace
    -$(RM) example_lib.c

test:
    $(PYTHON) test.py

clean:
ifeq ($(PYTHONVERSION),27)
    $(RM) example_lib.pyd
endif
ifeq ($(PYTHONVERSION),36)
    $(RM) example_lib.cp36-win_amd64.pyd
endif
    -$(RMR) build

Они были протестированы на платформе windows 10 с использованием Python 3.6.7, cython 0.25.2 , Python 2.7.14 и та же версия Cython (для py2).

Для компиляции с python 2 измените значения связанных переменных в Makefile.

Заранее спасибо ,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...