如何在python中将函数调用与返回的ndarrays并行化?

时间:2017-11-03 08:39:48

标签: python multiprocessing

我正在寻找一种方法来解决我的多处理模块的问题。为了让您更好地了解我的操作,请参阅以下说明。

解释

我的input_data是一个ndarray,其中包含282240个uint32类型的元素    '    在calculation_function()我使用for循环来计算    每12位结果并将其放入output_data

因为这非常慢,我将input_data分成例如4或8    零件并计算calculation_function()中的每个零件。

现在我正在寻找一种方法,如何平行4或8功能    呼叫

数据的顺序是基本的,因为数据在图像中    每个像素必须处于正确的位置。所以函数调用没有。 1    计算第一个和最后一个函数调用的最后一个像素    图像。

计算工作正常,图像可以完全重建    从我的算法,但我需要并行化来加快时间    关键方面。

要点: 一个输入ndarray分为4或8个部分。在每个部分中都有70560或35280 uint32值。从每12位我计算一个Pixel有4或8个函数调用。每个函数返回一个带有188160或94080像素的ndarray。所有返回值将连续放在一起并重新整形为图像。

已经完成的工作: 计算已经完成,我可以重建我的图像

问题: 函数调用是连续完成的,但每次图像重建都很慢

主要目标: 通过并行化函数调用来加速函数调用。

代码:

def decompress(payload,WIDTH,HEIGHT):
    # INPUTS / OUTPUTS
    n_threads = 4                                                                           
    img_input = np.fromstring(payload, dtype='uint32')                                      
    img_output = np.zeros((WIDTH * HEIGHT), dtype=np.uint32)                            
    n_elements_part = np.int(len(img_input) / n_threads)                                    
    input_part=np.zeros((n_threads,n_elements_part)).astype(np.uint32)                      
    output_part =np.zeros((n_threads,np.int(n_elements_part/3*8))).astype(np.uint32)        

    # DEFINE PARTS (here 4 different ones)
    start = np.zeros(n_threads).astype(np.int)                          
    end = np.zeros(n_threads).astype(np.int)                            
    for i in range(0,n_threads):
        start[i] = i * n_elements_part
        end[i] = (i+1) * n_elements_part -1

    # COPY IMAGE DATA
    for idx in range(0,n_threads):
        input_part [idx,:] = img_input[start[idx]:end[idx]+1]


    for idx in range(0,n_threads):                          # following line is the function_call that should be parallized
        output_part[idx,:] = decompress_part2(input_part[idx],output_part[idx])



    # COPY PARTS INTO THE IMAGE
    img_output[0     : 188160] = output_part[0,:]
    img_output[188160: 376320] = output_part[1,:]
    img_output[376320: 564480] = output_part[2,:]
    img_output[564480: 752640] = output_part[3,:]

    # RESHAPE IMAGE
    img_output = np.reshape(img_output,(HEIGHT, WIDTH))

    return img_output

请不要照顾我的初学者编程风格:) 只是寻找一个解决方案如何使用多处理模块并行化函数调用并返回返回的ndarrays。

----------------------------------------------- ------------------------------

我将我的问题转移到一个不太复杂的例子中: 是否有可能平行调用函数的for循环的每次迭代?

import numpy as np

def split(data,parts,step, length):
    data_array=np.zeros((parts,step))

    for i in range(parts):  
        data_array[i,:] = data[i*step:(i+1)*step]

    return(data_array)

def mul(arr, scalar):
    result = np.multiply(arr,scalar)
    return(result)

data = np.linspace(1.0, 100.0, num=24).astype(int)
parts = 4
length=len(data)
step = np.int(length/parts)
scalar = 2
data_array = split(data,parts,step,length)                      
res_array = np.zeros((parts,step))
print(data_array)

for idx in range(parts):
    test = data_array[idx,:]
    res_array[idx,:] = mul(test,scalar) # Line to be parallized !

print('\n',res_array)

1 个答案:

答案 0 :(得分:2)

使用multiprocessing模块:

import multiprocessing

def calculation_function(some_array):
    # some logic
    # return result

chunksize = 4    # points to the number of processes and number of chunks to be processed
with multiprocessing.Pool(chunksize) as p:
    results = (p.map(calculation_function, entire_ndarray, chunksize))

现在,results包含可迭代的处理结果。

  

multiprocessing.Pool.map(func, iterable[, chunksize])
这个方法   将 iterable 划分为多个块,并将其提交给   进程池作为单独的任务。这些块的(近似)大小   可以通过将 chunksize 设置为正整数来指定。