我需要对大型数组的元素执行一个函数,并且我想使用多处理优化代码,以便我可以利用超级计算机上的所有内核。
这是我在这里提出的问题的后续行动。
我使用了代码:
import numpy as np
from scipy import misc, ndimage
import itertools
from pathos.multiprocessing import ProcessPool
import time
start = time.time()
#define the original array a as
a= np.load('100by100by100array.npy')
n= a.ndim #number of dimensions
imx, imy, imz = np.shape(a)
print('imx,imy,imz = '+str(imx)+','+str(imy)+','+str(imz))
#define the distorted array b as
imsd = 1 #how blurry the distorted image is
b = ndimage.filters.gaussian_filter(a, imsd, order=0, output=None, mode='reflect', cval=0.0)#, truncate=4.0)
#define a window/weighting function, i.e. a Gaussian for which the local values are computed
wsd = float(1.5) #sd for the window function
#create a n dimensional distribution
x, y, z = np.ogrid[0:imx, 0:imy, 0:imz]
r = (x**2 + y**2 + z**2)**0.5
G1= (2*np.pi)**(-(np.float(n)/2))*(wsd**(np.float(n)))*np.exp(-0.5*wsd**(-2)*(r)**2)
def SSIMfunc(triple):
cenx=triple[0]
ceny=triple[1]
cenz=triple[2]
G= np.roll(G1, shift=cenx, axis=0)
G= np.roll(G, shift=ceny, axis=1)
if cenz is not None:
G= np.roll(G, shift=cenz, axis=2)
#define the mean
mu_a = np.sum(G*a)
mu_b = np.sum(G*b)
#define the sample standard deviation
sd_a = (np.sum(G*(a - mu_a)**2))**(0.5)
sd_b = (np.sum(G*(b - mu_b)**2))**(0.5)
sd_ab= np.sum(G*(a - mu_a)*(b - mu_b))
C1=0.001
l= (2*mu_a*mu_b+C1)/(mu_a**2 + mu_b**2 +C1)
C2=0.001
c= (2*sd_a*sd_b+C2)/(sd_a**2 + sd_b**2 +C2)
C3=0.001
s= (sd_ab +C3)/(sd_a*sd_b +C3)
return l*c*s
pool = ProcessPool()
SSIMarray = np.zeros((imx,imy,imz))
if __name__ == '__main__':
results = pool.map(SSIMfunc, list(itertools.product(range(0,imx), range(0,imy), range(0,imz))))
SSIMarray = np.reshape(results, (imx,imy,imz))
M= imx*imy*imz
MSSIM = (M**(-1))*np.sum(SSIMarray)
print('MSSIM ='+str(MSSIM))
end = time.time()
print(end - start)
如果我导入并使用 40*40*40 数组,那么它只需要 8 秒的挂墙时间和 < 3 分钟的 cpu 时间。
但是,导入和使用 100*100*100 数组意味着代码不会在超过 5 小时的 cpu 时间或 10 分钟的 walltime,甚至超过 1 小时的 walltime 内完成运行。
我猜想通过 map 传递这么大的数组有问题,但我还没有找到解决方案。使用 CProfile 问题似乎是
“thread.lock”对象的“获取”方法
将函数应用于大量元素的正确方法是什么?
请注意,我不能简单地将数组分成几部分,因为数组中每个元素的函数值也取决于该元素周围的值。