我尝试了一种隐含的方式来读取OpenCL内核从设备到主机的结果:
input_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(int) * n, input_data, &_err);
output_buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, sizeof(int) * n, output_data, &_err);
clEnqueueNDRangeKernel(...);
在上面的代码片段中,我可以从output_data
中的内核获得正确的结果。但是,对于output_buffer
创建,在我将CL_MEM_USE_HOST_PTR
更改为CL_MEM_COPY_HOST_PTR
后,output_data
保持不变,就像内核尚未执行一样。据我所知,CL_MEM_USE_HOST_PTR
适用于从主机到设备的传输,它首先将input_data
指向的内容复制到不同的内存空间,然后input_buffer
获取内核&#39}。来自这个新空间的输入。我怀疑output_buffer
是否会发生同样的事情,它会将内核的结果复制到其他地方,但不会将它们移动到output_data
指向的空间。
答案 0 :(得分:2)
根据OpenCL标准:
CL_MEM_COPY_HOST_PTR
表示应用程序希望OpenCL实现从host_ptr
引用的内存中复制数据。它不表示将在哪一侧分配内存。 CL_MEM_USE_HOST_PTR
表示应用程序希望OpenCL实现使用host_ptr
引用的内存作为内存对象的存储位。允许OpenCL实现缓存设备内存中host_ptr
指向的缓冲区内容。在设备上执行内核时,可以使用此缓存副本。因此,如果您使用CL_MEM_USE_HOST_PTR
,则设备和放大器之间的数据互连;主机是透明的。不保证可以分配设备端的任何内存量。
回到您的代码段:
input_buffer = clCreateBuffer(...)
将导致在设备端分配sizeof(int) * n
个字节。output_buffer = clCreateBuffer(...)
不会导致设备端的内存分配。您的OpenCL实现可能以某种方式缓存主机端内存的内容,output_data
点,但您现在永远不会。答案 1 :(得分:2)
使用OpenCL 1.x,运行内核后,必须使用clEnqueueMapBuffer
或clEnqueueReadBuffer
将数据返回主机内存,以供CPU进一步使用。没有办法解决它。