将不连续的内存发送到 OpenCL 中的缓冲区

Send discontiguous memory to a buffer in OpenCL

假设我有一个数组 A[200][200]。

如果我想将 A[0:100][0:200] 发送到 GPU 缓冲区, 我就打电话

clEnqueueWriteBuffer(queue, buffer, CL_TRUE, 0, 100 * 200 * sizeof(float), A, 0, NULL, NULL);

但是如果我想将A[0:200][0:100]发送到GPU缓冲区,我不能调用上面的函数,因为A[0:200][0:100]是不连续的。

发送上述数据有什么明智的方法吗?

你可以使用 clEnqueueWriteBufferRect.

cl_int clEnqueueWriteBufferRect(    
    cl_command_queue command_queue,
    cl_mem buffer,
    cl_bool blocking_write,
    const size_t buffer_origin[3],
    const size_t host_origin[3],
    const size_t region[3],
    size_t buffer_row_pitch,
    size_t buffer_slice_pitch,
    size_t host_row_pitch,
    size_t host_slice_pitch,
    void *ptr,
    cl_uint num_events_in_wait_list,
    const cl_event *event_wait_list,
    cl_event *event
)

对于您的情况,最相关的参数是 host_originregionhost_row_pitch

host_row_pitch:内存中每一行的字节大小。 数组 float A[200][200] 描述了行间距为 200 * sizeof(float).

的行主二维数组

host_origin:您希望发送到设备的主机数据的起始位置。假设 ND 阵列。你的来源只是 size_t[3] {0,0,0}

host_region:您希望从数组中复制的 ND 区域。 您所在的地区是 size_t[3] {100,200,1}。

我建议您仔细阅读文档。很容易犯小错误。

另请注意,在发送之前先将主机数据排列成连续数组可能更有效。 clEnqueueWriteBuffer 可能会启动 DMA 传输,这对于大型连续内存块更有效。