2

我正在使用 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 'Capeverde' on 'AMD Accelerated Parallel Processing' at 0x2a76d90

>>> pyopencl.VERSION
(2013, 1)

我知道复杂类型的处理不正确,但是如果将它们更改为 np.float32 我仍然会遇到同样的问题。

4

1 回答 1

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类型,或者您调用 30000 次这一事实.real- 这可能每次都会创建一个新缓冲区。此外,您的缓冲区可能对于您的 GPU 来说太大了。尝试将它们的尺寸缩小。

我不确定您的目标是什么,但我强烈建议您避免使用 ElementWise,直到您花更多时间使用标准 PyOpenCL。ElementWise 只是一些语法糖,它可能会混淆 PyOpenCL 所做工作的真实性质。

尝试在没有 ElementWise 的情况下解决问题将帮助您了解数据始终在哪里、如何管理队列以及何时将内存复制到主机或从主机复制内存。

于 2013-11-03T17:23:58.567 回答