Заполняем сложный массив numpy с помощью многопроцессорного модуля

#python #numpy #ctypes #python-multiprocessing

#python #numpy #ctypes #python-многопроцессорная обработка

Вопрос:

Я наткнулся на эту демонстрацию https://jonasteuwen.github.io/numpy/python/multiprocessing/2017/01/07/multiprocessing-numpy-array.html о том, как заполнить массив numpy с помощью модуля многопроцессорной обработки. Я хочу сделать аналогичную вещь в своем коде, но массив, который я заполняю, т. е. мой X , является сложным массивом. Модуль ctypes выдает мне ошибку примерно NotImplementedError: Converting dtype('complex128') to a ctypes type .

Итак, в связанном примере то, что я хочу, эффективно заменяет непараллельную версию:

 X = np.random.random((100, 100))
  

с помощью

 X = np.random.random((100, 100))   1j * np.random.random((100, 100))
  

и

 tmp = np.zeros((100, 100))
  

с помощью

 tmp = np.zeros((100, 100))   1j * np.random.random((100, 100))
  

Я не уверен, как это сделать с помощью модуля numpy.ctypes, но открыт для других идей по достижению аналогичной цели. Спасибо.

Ответ №1:

Решаемая проблема путем разделения массива на действительную и мнимую части, обработки их по отдельности, а затем объединения для формирования комплексной переменной.

 import numpy as np
import itertools
from multiprocessing import Pool #  Process pool
from multiprocessing import sharedctypes

size = 100
block_size = 4

X = np.random.random((size, size))   1j * np.random.random((size, size))
X_r = X.real 
X_i = X.imag
result_r = np.ctypeslib.as_ctypes(np.zeros((size, size)))
result_i = np.ctypeslib.as_ctypes(np.zeros((size, size)))
shared_array_r = sharedctypes.RawArray(result_r._type_, result_r)
shared_array_i = sharedctypes.RawArray(result_i._type_, result_i)

def fill_per_window(args):
    window_x, window_y = args
    tmp_r = np.ctypeslib.as_array(shared_array_r)
    tmp_i = np.ctypeslib.as_array(shared_array_i)

    for idx_x in range(window_x, window_x   block_size):
        for idx_y in range(window_y, window_y   block_size):
            tmp_r[idx_x, idx_y] = X_r[idx_x, idx_y]
            tmp_i[idx_x, idx_y] = X_i[idx_x, idx_y]

window_idxs = [(i, j) for i, j in
           itertools.product(range(0, size, block_size),
                             range(0, size, block_size))]

p = Pool()
res = p.map(fill_per_window, window_idxs)
result_r = np.ctypeslib.as_array(shared_array_r)
result_i = np.ctypeslib.as_array(shared_array_i)
result = result_r   1j * result_i
print(np.array_equal(X, result))