我跟着Heterogeneous Computing with OpenCL一起跟着我离开了。
它们将图像作为浮点数组传递给enqueueWriteBuffer。我认为在这种情况下,图像没有颜色值。它只是{col,row,col,row,col,row},例如{0,0,0,1,0,2,1,0,1,1,1,2 ...}。
但是当他们将enqueueReadBuffer的大小放在他们期望的H W时,如果你要像我那样做一个数组,那么数组大小就是H W * 2.
// SETUP BUFFERS
Buffer d_ip = Buffer(context, CL_MEM_READ_ONLY, W*H*sizeof(float));
Buffer d_op = Buffer(context, CL_MEM_WRITE_ONLY, W*H*sizeof(float));
queue.enqueueWriteBuffer(d_ip, CL_TRUE, 0, W*H*sizeof(float), img); //img, what is img? the book just says it is my image.
// SETUP RANGES
NDRange globalws(W, H);
NDRange localws(16, 16);
// QUEUE AND READ
queue.enqueueNDRangeKernel(rotn_kernel, NullRange, globalws, localws);
queue.enqueueReadBuffer(d_op, CL_TRUE, 0, W*H*sizeof(float), img);
// X AND Y INSIDE THE KERNEL
const int x = get_global_id(0);
const int y = get_global_id(1);
如果在内核中计算了所有新的像素坐标,你不能只传递一个适当大小的空浮点数组(W H显然虽然我看不到它是如何不是W H * 2)。但后来我尝试对此进行硬编码(在500x300图像上),它炸毁了我的堆栈。
答案 0 :(得分:1)
它不是大小W*H*2
,因为它们可能不像你想象的那样存储数据。通常,存储这种性质的数据,使得第一行数据存储在第一W
个条目中,第二行存储在第二行W
等中;这会产生一个大小为W*H
的数组。因此,要获取有关行X
,列Y
中某些内容的信息,您必须获取索引为(W * X) + Y
的元素
答案 1 :(得分:1)
在编写OpenCL代码时,无论数据是1D,2D还是3D,我总是将每个内核视为读取一组3D数据:
__kernel void TestKernel(__global float *Data){
k = get_global_id(0); //also z
j = get_global_id(1); //also y
i = get_global_id(2); //also x
//Convert 3D to 1D
int linear_coord = i + get_global_size(0)*j + get_global_size(0)*get_global_size(1)*k;
//do stuff
}
在执行clEnqueueNDKernelRange(...)时,只需将维度设置为:
int X = 500;
int Y = 300;
int Z = 1;
size_t GlobalDim = {Z, Y, X};
这让我的所有内核都可以在各个方面轻松运行。
您的代码不会调用任何clSetKernelArg
,您是否添加了这些代码? OpenCL功能是否会导致任何错误?您可能想退后一步并使用OpenCL C代码而不是C ++类。