我正在使用pyopencl来加速我使用GPU的计算,目前我对以下问题感到困惑。
我使用以下代码
在for循环中对两个数组进行简单的乘法运算import numpy as np
import pyopencl as cl
import pyopencl.array as cl_array
from pyopencl.elementwise import ElementwiseKernel
ctx = cl.create_some_context(0)
queue = cl.CommandQueue(ctx)
multiply = ElementwiseKernel(ctx,
"float *x, float *y, float *z",
"z[i] = x[i] * y[i]",
"multiplication")
x = cl_array.arange(queue, 1000000, dtype=np.complex64)
y = cl_array.arange(queue, 1000000, dtype=np.complex64)
z = cl_array.empty_like(x)
for n in range(10000):
z = x*y
multiply(x.real, y.real, z.real)
multiply(x, y, z)
最后三行当然是相同的,即乘法。但是,前两个选项会导致以下错误(当然我注释掉了其他两个):
pyopencl.MemoryError: clEnqueueNDRangeKernel failed: mem object allocation failure
我只是丢失了为什么前两个选项遇到分配错误。
注意:
GPU:[0] pyopencl.Device'Prowverde''AMD加速并行处理'在0x2a76d90
>>> pyopencl.VERSION
(2013, 1)
我知道复杂类型没有正确处理,但是如果你把它们改成np.float32我仍然会遇到同样的问题。
答案 0 :(得分:1)
我简化了你的程序并以一种在我的计算机上运行的方式运行它。这是一个适合我的版本:
import numpy as np
import pyopencl as cl
import pyopencl.array as cl_array
from pyopencl.elementwise import ElementwiseKernel
ctx = cl.create_some_context(0)
queue = cl.CommandQueue(ctx)
multiply = ElementwiseKernel(ctx,
"float *x, float *y, float *z",
"z[i] = x[i] * y[i]",
"multiplication")
x = cl_array.arange(queue, 1000000, dtype=np.float32)
y = cl_array.arange(queue, 1000000, dtype=np.float32)
z = cl_array.empty_like(x)
for i in range(10000):
multiply(x, y, z)
该程序使用np.float32
缓冲区运行内核。您的问题可能源于np.complex64
类型,或者您调用.real
30000次 - 这可能每次都会创建一个新缓冲区。此外,您的缓冲区可能太大而不适合您的GPU。尝试将它们的大小缩小。
我不确定您的目标是什么,但我强烈建议您避免使用ElementWise,直到您花费更多时间使用标准PyOpenCL。 ElementWise只是一些语法糖,可以混淆PyOpenCL正在做的事情的本质。
尝试在没有ElementWise的情况下解决您的问题将帮助您随时了解数据的位置,如何管理队列,以及何时将内存复制到主机和从主机复制内存。