C++ clEnqueueCopyBufferRect是如何工作的?
我需要了解clEnqueueCopyBufferRect是如何工作的。 例如,我需要从4x4区域复制3x3区域,让它成为原点为1,1的int数组。 我有两个建议: 它只是复制大小与矩形3x3区域大小匹配的线性区域,因此结果是:C++ clEnqueueCopyBufferRect是如何工作的?,c++,opencl,C++,Opencl,我需要了解clEnqueueCopyBufferRect是如何工作的。 例如,我需要从4x4区域复制3x3区域,让它成为原点为1,1的int数组。 我有两个建议: 它只是复制大小与矩形3x3区域大小匹配的线性区域,因此结果是: 1 1 1 1 0 0 0 0 1 1 1 1 -> 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 0 0 0 0 1 1 1 1 -> 0 1 1 1 1 1 1 1
1 1 1 1 0 0 0 0
1 1 1 1 -> 0 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 0 0
1 1 1 1 0 0 0 0
1 1 1 1 -> 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
或者复制矩形区域,结果是:
1 1 1 1 0 0 0 0
1 1 1 1 -> 0 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 0 0
1 1 1 1 0 0 0 0
1 1 1 1 -> 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
为了检查这一点,我使用了下一个示例代码:
int main(int argc, char * argv[])
{
std::vector<Platform> platforms;
Platform::get(&platforms);
cl::Platform platform = platforms[0];
cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform(), 0};
cl::Context context(CL_DEVICE_TYPE_GPU,cps);
std::string kr_str = "__kernel void StepKernel(__global int* in) { in[get_global_id(1)*4 + get_global_id(0)] = 1;}";
Program program=cl::Program(
context,
cl::Program::Sources(
1,
std::make_pair(kr_str.c_str(),kr_str.length()+1)
)
);
std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
std::vector<cl::Device> device(1,devices[0]);
program.build(device);
cl::Kernel kernel = cl::Kernel(program, "StepKernel");
cl::CommandQueue queue(
context,
device[0],
CL_NONE
);
cl::Buffer in_buffer_on_device(
context,
CL_MEM_READ_WRITE,
16*sizeof(int)
);
cl::Buffer out_buffer_on_host(
context,
CL_MEM_READ_WRITE|CL_MEM_ALLOC_HOST_PTR,
16*sizeof(int)
);
void *ptr_on_host =
queue.enqueueMapBuffer(
out_buffer_on_host,
CL_BLOCKING,
CL_MAP_WRITE|CL_MAP_READ,
0, 16*sizeof(int),
NULL, NULL
);
for(int k = 0; k < 4; k++)
for(int i = 0; i < 4; i++)
static_cast<int*>(ptr_on_host)[k*4 + i] = 0;
cl::size_t<3> origin, region;
origin[0]=0; origin[1]=0; origin[2]=0;
region[0]=4*sizeof(int); region[1]=4; region[2]=1;
Event evt;
queue.enqueueCopyBufferRect(
out_buffer_on_host,
in_buffer_on_device,
origin, origin, region,
sizeof(int)*4,sizeof(int)*4*4,sizeof(int)*4,sizeof(int)*4*4,
NULL,
&evt
);
evt.wait();
kernel.setArg(0,in_buffer_on_device);
queue.enqueueNDRangeKernel(
kernel,
cl::NDRange( 0, 0),
cl::NDRange( 4, 4),
cl::NullRange,
NULL,
&evt
);
evt.wait();
origin[0]=1*sizeof(int); origin[1]=1; origin[2]=0;
region[0]=3*sizeof(int); region[1]=3; region[2]=1;
queue.enqueueCopyBufferRect(
in_buffer_on_device,
out_buffer_on_host,
origin, origin, region,
sizeof(int)*4,sizeof(int)*4*4,sizeof(int)*4,sizeof(int)*4*4,
NULL,
&evt
);
evt.wait();
for(int k = 0; k < 4; k++)
{
for(int i = 0; i < 4; i++)
{
std::cout << static_cast<int*>(ptr_on_host)[k*4 + i]<< "\t";
}
std::cout << std::endl;
}
return 0;
}
所以,如果我没有犯任何错误,CL复制线性区域。所以这样的行为对我来说毫无用处。它复制了矩形区域。否则,它作为API将毫无用处。好吧,当我运行代码时,我得到了矩形区域的情况2。