openCL-创建子缓冲区返回错误代码13

时间:2018-08-06 15:42:49

标签: c++ buffer opencl multi-gpu

嗨,我是OpenCL的新手,正在使用C ++包装器。尝试同时在两个设备上运行相同的内核。创建了缓冲区,并尝试使用子缓冲区将其分块,然后将这些卡盘传递给内核,然后将它们分派两次-一次发送到Command Queue 1,然后使用主缓冲区的不同块发送给Command Queue 2。

运行时抛出错误-13。除了该问题以外,所有其他子缓冲区均已创建。

任何指导将不胜感激。

使用OpenCL 1.1

//Creating main buffer
cl::Buffer zeropad_buf(openclObjects.context,CL_MEM_READ_ONLY| CL_MEM_COPY_HOST_PTR,(size+2)*(size+2)*cshape[level][1]*sizeof(float),zeropad);
    cl::Buffer output_buf(openclObjects.context,CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR  ,cshape[level][0]*size*size*sizeof(float),output_f);

//Creating sub_buffers for zeropad_buf
    size_t zeropad_buf_size = (size+2)*(size+2)*cshape[level][1]*sizeof(float);
    size_t output_buf_size = cshape[level][0]*size*size*sizeof(float);

    cl_buffer_region zero_rgn_4core = {0, zeropad_buf_size/2};
    **cl_buffer_region zero_rgn_2core = {zeropad_buf_size/2, zeropad_buf_size/2};** //Throws error -13

    cl_buffer_region output_rgn_4core = {0, output_buf_size/2};
    cl_buffer_region output_rgn_2core = {output_buf_size/2, output_buf_size/2};



    cl::Buffer zeropad_buf_4Core = zeropad_buf.createSubBuffer(CL_MEM_READ_ONLY,CL_BUFFER_CREATE_TYPE_REGION, &zero_rgn_4core);
    **cl::Buffer zeropad_buf_2Core = zeropad_buf.createSubBuffer(CL_MEM_READ_ONLY,CL_BUFFER_CREATE_TYPE_REGION, &zero_rgn_2core);** 
    std::cout<<"zero_pad sub-buffer created"<<std::endl;

    cl::Buffer output_buf_4Core = output_buf.createSubBuffer(CL_MEM_READ_WRITE,CL_BUFFER_CREATE_TYPE_REGION, &output_rgn_4core);
    cl::Buffer output_buf_2Core = output_buf.createSubBuffer(CL_MEM_READ_WRITE,CL_BUFFER_CREATE_TYPE_REGION, &output_rgn_2core);

1 个答案:

答案 0 :(得分:0)

来自documentation

  如果在上下文中没有与缓冲区关联的设备的原始值与CL_MISALIGNED_SUB_BUFFER_OFFSET值对齐,则在errcode_ret中返回

CL_DEVICE_MEM_BASE_ADDR_ALIGN

您似乎可能需要对齐拆分区域的偏移量和大小,以位于所有设备CL_DEVICE_MEM_BASE_ADDR_ALIGN属性的最小公倍数(LCM)的整数倍上。

通过这个,我的意思如下:

假设您使用的设备位于变量中

std::vector<cl::Device> devices;

查询每个设备的CL_DEVICE_MEM_BASE_ADDR_ALIGN属性:

cl_uint total_alignment_requirement = 1;
for (cl::Device& dev : devices)
{
    cl_uint device_mem_base_align = 0;
    if (CL_SUCCESS == dev.getInfo(CL_DEVICE_MEM_BASE_ADDR_ALIGN, &device_mem_base_align))
        total_alignment_requirement = std::lcm(total_alignment_requirement, device_mem_base_align);
}

然后,在分配zeropad时,请确保内存与total_alignment_requirement对齐,例如,如果当前正在使用malloc()进行分配,请使用{{1} }。 (更好的是,不要使用posix_memalign()创建缓冲区,如果可以的话,让OpenCL分配内存。)

最后,您的区域也需要对齐:

CL_MEM_USE_HOST_PTR

这可以确保第一个区域在size_t zeropad_split_pos = zeropad_buf_size / 2; zeropad_split_pos -= zeropad_split_pos % total_alignment_requirement; cl_buffer_region zero_rgn_4core = {0, zeropad_split_pos}; cl_buffer_region zero_rgn_2core = {zeropad_split_pos, zeropad_buf_size - zeropad_split_pos}; 的倍数的地址上开始和结束,而第二个区域也从对齐的地址开始。

(我尚未测试此代码,但应该正确无误。请注意,total_alignment_requirement是C ++标准库的一项非常新的功能,因此,如果您的工具链中没有此功能,则需要供应your own lcm function。)