Pyopencl:to_device和Buffer之间的区别

pet*_*hka 8 python numpy opencl pyopencl

import pyopencl as cl
import pyopencl.array as cl_array
import numpy
a = numpy.random.rand(50000).astype(numpy.float32)
mf = cl.mem_flags
Run Code Online (Sandbox Code Playgroud)

有什么区别

a_gpu = cl.Buffer(self.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=a)
Run Code Online (Sandbox Code Playgroud)

a_gpu = cl_array.to_device(self.ctx, self.queue, a)
Run Code Online (Sandbox Code Playgroud)

有什么区别

result =  numpy.empty_like(a)
cl.enqueue_copy(self.queue, result, result_gpu)
Run Code Online (Sandbox Code Playgroud)

result = result_gpu.get()
Run Code Online (Sandbox Code Playgroud)

And*_*ner 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属性中获取它.

  • 我刚才意识到你是PyOpenCL的作者.非常感谢PyOpenCL和您的回答! (4认同)