0

我正在关注使用 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 图像上),它炸毁了我的堆栈。

4

2 回答 2

1

在编写我的 OpenCL 代码时,我总是将每个内核视为读取一组 3D 数据,无论数据是 1D、2D 还是 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};

这让我所有的内核都可以在所有维度上轻松工作。

您的代码没有调用 any clSetKernelArg,您添加了这些吗?OpenCL 函数是否会回退任何错误?您可能想退后一步,使用 OpenCL C 代码而不是 C++ 类。

于 2013-07-24T17:59:51.743 回答
1

它不是大小W*H*2,因为它们可能不像您想象的那样存储数据。通常,存储这种性质的数据时,数据的第一行存储在第一个W条目中,第二行存储在第二个条目中W,依此类推;这会产生一个 size 数组W*H。因此,要获取有关 row X、 column中某些内容的信息Y,您必须获取 index 处的元素(W * X) + Y

于 2013-07-24T17:50:39.037 回答