Parallel processing Python中子数组的快速求和
我有一个半径为w的数据立方体a,对于该立方体的每个元素,我想在半径为r的立方体中添加元素和所有周围的值,其中rParallel processing Python中子数组的快速求和,parallel-processing,gpu,numba,Parallel Processing,Gpu,Numba,我有一个半径为w的数据立方体a,对于该立方体的每个元素,我想在半径为r的立方体中添加元素和所有周围的值,其中r=r: x1=x-r 其他: x1=0 如果x=r: y1=y-r 其他: y1=0 如果y=r: z1=z-r 其他: z1=0 如果z
a = numpy.ones(shape=(2*w,2*w,2*w),dtype='float32')
kernel = numpy.ones(shape=(2*r,2*r,2*r),dtype='float32')
b = convolve(a,kernel,mode='constant',cval=0)
那么b的值(2r)(2r)(2r)对于所有不在边上的索引
目前我正在使用一个循环来完成这项工作,它非常慢,特别是对于较大的w和r。我尝试了scipy卷积,但在循环中几乎没有加速。我现在正在研究numba的并行计算特性,但无法找出如何重写代码以使用numba。我有一个Nvidia RTX卡,所以CUDA GPU计算也是可能的
欢迎提出建议
这是我目前的代码:
for x in range(0,w*2):
print(x)
for y in range(0,w*2):
for z in range(0,w*2):
if x >= r:
x1 = x - r
else:
x1 = 0
if x < w*2-r:
x2 = x + r
else:
x2 = w*2 - 1
if y >= r:
y1 = y - r
else:
y1 = 0
if y < w*2-r:
y2 = y + r
else:
y2 = w*2 - 1
if z >= r:
z1 = z - r
else:
z1 = 0
if z < w*2-r:
z2 = z + r
else:
z2 = w*2 - 1
b[x][y][z] = numpy.sum(a[x1:x2,y1:y2,z1:z2])
return b
范围(0,w*2)内x的:
打印(x)
对于范围(0,w*2)内的y:
对于范围(0,w*2)内的z:
如果x>=r:
x1=x-r
其他:
x1=0
如果x=r:
y1=y-r
其他:
y1=0
如果y=r:
z1=z-r
其他:
z1=0
如果z
这是一个非常简单的代码版本,可以与numba一起使用。我发现相对于纯numpy代码,速度提高了10倍。但是,使用FFT卷积算法(例如scipy的fftconvolve)应该能够获得更大的速度提升。你能分享一下你让卷积开始工作的尝试吗
from numba import njit
@njit
def sum_cubes(a,b,w,r):
for x in range(0,w*2):
#print(x)
for y in range(0,w*2):
for z in range(0,w*2):
if x >= r:
x1 = x - r
else:
x1 = 0
if x < w*2-r:
x2 = x + r
else:
x2 = w*2 - 1
if y >= r:
y1 = y - r
else:
y1 = 0
if y < w*2-r:
y2 = y + r
else:
y2 = w*2 - 1
if z >= r:
z1 = z - r
else:
z1 = 0
if z < w*2-r:
z2 = z + r
else:
z2 = w*2 - 1
b[x,y,z] = np.sum(a[x1:x2,y1:y2,z1:z2])
return b
除非你想让立方体偏离中心
假设您确实希望立方体居中,则执行此计算的更快方法是使用scipy的统一过滤器:
from scipy.ndimage import uniform_filter
def sum_cubes_quickly(a,b,w,r):
b = uniform_filter(a,mode='constant',cval=0,size=2*r+1)*(2*r+1)**3
return b
对于w=50,r=10的随机生成数据,进行一些快速运行时比较:
- 原始numpy代码-15.1秒
- Numba'd numpy代码-8.1秒
- 均匀滤光片-13.1毫秒
- 这是一个非常简单的代码版本,可以与numba一起使用。我发现相对于纯numpy代码,速度提高了10倍。但是,使用FFT卷积算法(例如scipy的fftconvolve)应该能够获得更大的速度提升。你能分享一下你让卷积开始工作的尝试吗
from numba import njit
@njit
def sum_cubes(a,b,w,r):
for x in range(0,w*2):
#print(x)
for y in range(0,w*2):
for z in range(0,w*2):
if x >= r:
x1 = x - r
else:
x1 = 0
if x < w*2-r:
x2 = x + r
else:
x2 = w*2 - 1
if y >= r:
y1 = y - r
else:
y1 = 0
if y < w*2-r:
y2 = y + r
else:
y2 = w*2 - 1
if z >= r:
z1 = z - r
else:
z1 = 0
if z < w*2-r:
z2 = z + r
else:
z2 = w*2 - 1
b[x,y,z] = np.sum(a[x1:x2,y1:y2,z1:z2])
return b
除非你想让立方体偏离中心
假设您确实希望立方体居中,则执行此计算的更快方法是使用scipy的统一过滤器:
from scipy.ndimage import uniform_filter
def sum_cubes_quickly(a,b,w,r):
b = uniform_filter(a,mode='constant',cval=0,size=2*r+1)*(2*r+1)**3
return b
对于w=50,r=10的随机生成数据,进行一些快速运行时比较:
- 原始numpy代码-15.1秒
- Numba'd numpy代码-8.1秒
- 均匀滤光片-13.1毫秒