簡體   English   中英

與Cython一起使用多處理時出錯

[英]Error while using Multiprocessing with Cython

我編寫了一個使用Cython實用程序模塊的類。 然后,我嘗試使用Multiprocessing加快處理速度,以同時處理該類的多個實例,但出現錯誤。 Error sending result: '(0, <MemoryView of 'ndarray' at 0x19de04081f0>)'. Reason: 'TypeError('no default __reduce__ due to non-trivial __cinit__',)' Error sending result: '(0, <MemoryView of 'ndarray' at 0x19de04081f0>)'. Reason: 'TypeError('no default __reduce__ due to non-trivial __cinit__',)'我一直在考慮編寫__reduce__函數,但是我所看到的一切都與酸洗類有關,與方法或模塊無關。 我還研究了編寫__cinit__方法的過程,但是__cinit__來似乎很少。

下面是產生錯誤的程序包和模塊布局的簡化表示(實際上有數百個DNG對象要處理,每個對象都引用一個唯一的20ish MB文件,而ljpeg實際上有數百行,稱為數十行到數百行)。每個DNG的次數)。 在該示例中,可以通過刪除數組類型聲明來修復錯誤,但是如果我這樣做,那么實際上,性能影響將比多處理增益大幾個數量級。

可以在不顯着降低速度或進行重大重構的情況下解決此問題嗎?

sequence.py

import multiprocessing

import numpy as np

from dng import DNG


def test_decode():
    input_file = np.zeros(3000, dtype=np.intc)

    pool = multiprocessing.Pool()
    tasks = []

    for i in range(10):
        task = pool.apply_async(thread, (i, input_file))
        tasks.append(task)

    pool.close()
    pool.join()

    for task in tasks:
        print(task.get())


def thread(i, input_file):
    dng = DNG(input_file)
    return i, dng.image


if __name__ == '__main__':
    test_decode()

dng.py

import numpy as np

import ljpeg


class DNG:
    def __init__(self, input_file):

        self.image = ljpeg.decode(input_file)

ljpeg.pyx

cpdef int[:] decode(int[:] encoded_image):
    encoded_image = __bar(encoded_image, 10000, 1000)
    return encoded_image


cdef int[:] __bar(int[:] array, int i, int ii):
    for j in range(i):
        for jj in range(ii):
            array = __foo(array)
    return array


cdef int[:] __foo(int[:] array):
    array[0] += 1
    return array

輸出:

Traceback (most recent call last):
  File "F:/Documents/Python/threading_multi/sequence.py", line 31, in <module>
    test_decode()
  File "F:/Documents/Python/threading_multi/sequence.py", line 22, in test_decode
    print(task.get())
  File "C:\Python36\lib\multiprocessing\pool.py", line 644, in get
    raise self._value
multiprocessing.pool.MaybeEncodingError: Error sending result: '(0, <MemoryView of 'ndarray' at 0x19de04081f0>)'. Reason: 'TypeError('no default __reduce__ due to non-trivial __cinit__',)'

Process finished with exit code 1

我很確定這是將每個線程生成的memoryview返回到主線程的錯誤(因為無法對memoryview進行腌制)。 但是,memoryview本身包裝了另一個可能被腌制的Python對象。

真正不需要指定decode的返回類型(或使其cpdef ),因為它僅是從Python調用的。 decode結束時,返回.base的.base以獲取其包裝的基礎對象:

def decode(int[:] encoding_image):
    # ...
    return encoding_image.base

暫無
暫無

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

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