如何使用c ++包装器在OpenCL 2.0中将偏移量应用于内核参数

时间:2017-05-16 20:58:56

标签: c++ opencl

在CUDA中,我可以启动相同的内核,通过在k上的for循环中调用下面的代码,在同一个数组的不同部分上同时操作:

kernel<<<blkPerGrd, thdPerBlk, 0, stream[k]>>>(in_array + offset, out_array + out_offset)

我想在OpenCL 2.0中使用C ++包装器做同样的事情。我现在的想法是调用在不同命令队列上排队内核,将in_arrayout_array设置为内核的参数,并将偏移量作为参数传递。所以像这样(在for循环中k):

kernel.setArg(0, in_array);
kernel.setArg(2, in_offset);
kernel.setArg(3, out_array);
kernel.setArg(4, out_offset);
queue[k].enqueueNDRangeKernel(kernel, cl::NullRng, gblRng, lclRange, NULL, NULL);

其中in_arrayout_arraycl::Buffer个对象。

这是否有意义还是有更好的方法来处理偏移?我尝试检查cl::Buffer类是否接受指针算术,但我不认为它。

1 个答案:

答案 0 :(得分:0)

您正在做的是将内核分解为多个部分的可接受方式,但还有其他方法可以实现。

就个人而言,我更喜欢通过更改enqueueNDRangeKernel的参数来启动这些类型的内核。您可能会注意到,您显然已将其中一个参数&#34; null&#34;,或更确切地说,cl::NullRng。这通常是Offset参数,可以用来做你正在尝试做的事情。

Image img;
std::vector<cl::Event> events;
//Do not perform work on an area larger than 100x100 pixels at a time.
for(int x = 0; x < img.width(); x += 100) {
    int end_x = std::min(img.width(), x + 100);
    for(int y = 0; y < img.height(); y += 100) {
        int end_y = std::min(img.height(), y + 100);
        events.emplace_back();
        queue.enqueueNDRangeKernel(kernel, cl::NDRange{x, y}, cl::NDRange{end_x - x, end_y - y}, {}, nullptr, &events.back());
    }
}

queue.enqueueWaitForEvents(events);