在我的代码中,我有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上正常工作,不确定这是运气还是内核中的同步点出了问题。
更新:在第1025个入队命令中,enqueue_kernel
失败,错误为-1
。我试图获取更详细的错误(在构建过程中添加了-g
),但无济于事。我将设备队列的大小增加到最大,但没有任何改变(在1025th enqueue命令上仍然失败)。删除kernelA
和kernelB
的内容也没有任何改变。有什么想法吗?