在Python中使用CUDA展开简单可并行化的for循环

3 投票
1 回答
3091 浏览
提问于 2025-04-18 01:17

我在Python中有一个for循环,我想把它展开到GPU上去。我想这应该有个简单的解决办法,但我还没找到。

我们的函数会遍历一个numpy数组中的元素,进行一些数学运算,然后把结果存储到另一个numpy数组里。每次循环都会把一些结果加到这个结果数组中。我们代码可能会有一个很大的简化,像这样:

import numpy as np

a = np.arange(100)
out = np.array([0, 0])
for x in xrange(a.shape[0]):
  out[0] += a[x]
  out[1] += a[x]/2.0

我该如何在Python中展开这样的循环,以便在GPU上运行呢?

1 个回答

2

首先可以去这个网站看看:http://documen.tician.de/pycuda/,那里有个例子。

import pycuda.autoinit
import pycuda.driver as drv
import numpy

from pycuda.compiler import SourceModule
mod = SourceModule("""
__global__ void multiply_them(float *dest, float *a, float *b)
{
  const int i = threadIdx.x;
  dest[i] = a[i] * b[i];
}
""")

multiply_them = mod.get_function("multiply_them")

a = numpy.random.randn(400).astype(numpy.float32)
b = numpy.random.randn(400).astype(numpy.float32)

dest = numpy.zeros_like(a)
multiply_them(
        drv.Out(dest), drv.In(a), drv.In(b),
        block=(400,1,1), grid=(1,1))

print dest-a*b

你需要把想要并行处理的代码部分放在C语言的代码段里,然后从Python中调用它。

对于你的例子,数据的大小需要大于100,这样才有意义。你需要找到一种方法把数据分成多个块。如果你想加1,000,000个数字,可以把它分成1000个块。在并行处理的代码中分别加每个块的值,然后在Python中把结果加起来。

不过,加法并不是这种并行处理的自然任务。显卡通常是对每个像素执行相同的任务,而你的任务需要对多个像素进行操作。

可能先学习CUDA会更好。相关的讨论可以参考这个链接:理解CUDA的网格维度、块维度和线程组织(简单解释)

撰写回答