9

import pyopencl as cl
import pyopencl.array as cl_array
import numpy
a = numpy.random.rand(50000).astype(numpy.float32)
mf = cl.mem_flags

和有什么区别

a_gpu = cl.Buffer(self.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=a)

a_gpu = cl_array.to_device(self.ctx, self.queue, a)

?

和有什么区别

result =  numpy.empty_like(a)
cl.enqueue_copy(self.queue, result, result_gpu)

result = result_gpu.get()

?

4

2 回答 2

18

缓冲区是 CL 的版本malloc,而pyopencl.array.Array它类似于计算设备上的 numpy 数组。

因此,对于您的问题第一部分的第二个版本,您可以编写a_gpu + 2以获得一个新数组,该数组中的每个数字都添加了 2,而在 的情况下Buffer,PyOpenCL 只能看到一袋字节并且不能执行任何这样的操作。

您的问题的第二部分反过来也是一样的:如果您有一个 PyOpenCL 数组,.get()请将数据复制回来并将其转换为(基于主机的)numpy 数组。由于 numpy 数组是在 Python 中获取连续内存的更方便的方法之一,因此第二个变体enqueue_copy也以 numpy 数组结尾——但请注意,您可以将此数据复制到任何大小的数组中(只要它足够大)和任何类型 - 复制作为一个字节包执行,同时.get()确保您在主机上获得相同的大小和类型。

额外的事实:每个 PyOpenCL 数组下面当然有一个 Buffer。您可以从.data属性中获取它。

于 2012-11-24T16:50:43.823 回答
3

要回答第一个问题,Buffer(hostbuf=...)可以用任何实现缓冲区接口参考)的东西来调用。 pyopencl.array.to_device(...)必须使用ndarray( reference ) 调用。 ndarray实现缓冲区接口并在任一位置工作。但是,只hostbuf=...希望与例如 a bytearray(也实现缓冲区接口)一起使用。我还没有证实这一点,但这似乎是文档所建议的。

关于第二个问题,我不确定result_gpu当你调用它时应该是什么类型get()(你的意思是Buffer.get_host_array()?)无论如何,在和enqueue_copy()的组合之间工作Buffer,可以有偏移量和区域,并且可以是异步的(用) ,并且我认为这些功能只能以这种方式使用(而将阻塞并返回整个缓冲区)。(参考Imagehostis_blocking=Falseget()

于 2012-11-21T06:13:30.490 回答