【问题标题】:Pyopencl: difference between to_device and BufferPyopencl:to_device 和 Buffer 的区别
【发布时间】:2012-11-03 23:44:27
【问题描述】:

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()

?

【问题讨论】:

    标签: python numpy opencl pyopencl


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 我刚刚意识到您是 PyOpenCL 的作者。非常感谢 PyOpenCL 和您的回答!
    【解决方案2】:

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

    关于第二个问题,我不确定当您在其上调用get()result_gpu 应该是什么类型(您的意思是Buffer.get_host_array()?)无论如何,enqueue_copy() 在@ 的组合之间起作用987654335@、Imagehost,可以有偏移量和区域,并且可以是异步的(使用is_blocking=False),我认为这些功能只能通过这种方式使用(而get() 将被阻塞并返回整个缓冲)。 (reference)

    【讨论】:

      猜你喜欢
      • 2017-12-26
      • 2010-12-30
      • 2016-09-21
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-14
      • 1970-01-01
      相关资源
      最近更新 更多