在循环中入队到设备端队列

时间:2015-10-12 20:47:05

标签: opencl

在我的代码中,我有 kernelA kernelB kernelB 取决于 kernelA 结果。我在这个内核上迭代了数千次,每次迭代都取决于前一次迭代的结果。

剪切的主机端入队代码如下:

for(int x = 0; x < iterations; ++x)
{
    queue.enqueueNDRangeKernel(kernelA, cl::NullRange, cl::NDRange(3*256, 1), cl::NDRange(256, 1));
    queue.enqueueNDRangeKernel(kernelB, cl::NullRange, cl::NDRange(256, 1), cl::NDRange(256, 1));
}
queue.finish();

上面的代码工作正常。

现在我想将上面的代码移植到使用设备端入队并且我在AMD GPU上遇到问题。内核代码:

__attribute__((reqd_work_group_size(256, 1, 1)))
__kernel void kernelA(...){}

__attribute__((reqd_work_group_size(256, 1, 1)))
__kernel void kernelB(...){}

__attribute__((reqd_work_group_size(1, 1, 1)))
__kernel void kernelLauncher(...)
{
    queue_t default_queue = get_default_queue();
    clk_event_t ev1, ev2;

    for (int x = 0; x < iterations; ++x)
    {
        void(^fnKernelA)(void) = ^{ kernelA(
        ... // kernel params come here
            ); };

        if (x == 0)
        {
            enqueue_kernel(default_queue,
                CLK_ENQUEUE_FLAGS_NO_WAIT,
                ndrange_1D(3 * 256, 256),
                0, NULL, &ev1,
                fnKernelA);
        }
        else
        {
            enqueue_kernel(default_queue,
                CLK_ENQUEUE_FLAGS_NO_WAIT,
                ndrange_1D(3 * 256, 256),
                1, &ev2, &ev1, // ev2 sets dependency on kernelB here
                fnKernelA);
        }

        void(^fnKernelB)(void) = ^{ kernelB(
        ... // kernel params come here
            ); };

        enqueue_kernel(default_queue,
            CLK_ENQUEUE_FLAGS_NO_WAIT,
            ndrange_1D(256, 256),
            1, &ev1, &ev2,  // ev1 sets dependency on kernelA here
            fnKernelB);
    }
}

主持人代码:

queue.enqueueNDRangeKernel(kernelLauncher, cl::NullRange, cl::NDRange(1, 1), cl::NDRange(1, 1));

问题是在AMD GPU上运行时从内核返回的结果是错误的。有时内核也会挂起,这可能表明内核同步可能存在问题。相同的代码在Intel CPU上工作正常,不确定这是运气还是内核中的同步点有问题。

更新: enqueue_kernel在第1025个enqueue命令失败,错误为-1。我试图获得更详细的错误(在构建期间添加-g),但无济于事。我将设备队列大小增加到最大但没有改变任何东西(仍然在第1025次排队命令失败)。删除kernelAkernelB的内容也没有改变任何内容。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

回答一个老问题,希望将来可以节省一些时间。如果在设备上查询CL_DEVICE_MAX_ON_DEVICE_EVENTS,它将返回1024。这是您可以在“设备上”排队的最大事件数。这就是为什么它在1025队列上失败。如果您在其他GPU(例如Intel)上运行OpenCL代码,那么您可能很幸运地获得了返回的错误代码,它们是CLK_DEVICE_QUEUE_FULL或-161。 AMD忽略了-g选项,除了在设备上排队失败时,-1似乎一无所获。