CL_OUT_OF_RESOURCES 具有动态并行性的 clEnqueueNDRangeKernel() 返回错误
CL_OUT_OF_RESOURCES error is returned by clEnqueueNDRangeKernel() with dynamic parallelism
产生错误的内核代码:
__kernel void testDynamic(__global int *data)
{
int id=get_global_id(0);
atomic_add(&data[1],2);
}
__kernel void test(__global int * data)
{
int id=get_global_id(0);
atomic_add(&data[0],2);
if (id == 0) {
queue_t q = get_default_queue();
ndrange_t ndrange = ndrange_1D(1,1);
void (^my_block_A)(void) = ^{testDynamic(data);};
enqueue_kernel(q, CLK_ENQUEUE_FLAGS_WAIT_KERNEL,
ndrange,
my_block_A);
}
}
我测试了以下代码以确保 OpenCL 2.0 编译器正常工作。
__kernel void test2(__global int *data)
{
int id=get_global_id(0);
data[id]=work_group_scan_inclusive_add(id);
}
扫描函数给出 0、1、3、6 作为输出,因此 OpenCL 2.0 缩减函数正在运行。
动态并行是 OpenCL 2.0 的扩展吗?如果我删除 enqueue_kernel
命令,结果等于预期值(省略子内核)。
设备:AMD RX550,驱动程序:17.6.2
是否需要在主机端 运行 对 get_default_queue
队列上的 运行 子内核执行特殊命令?目前,命令队列是使用 OpenCL 1.2 方式创建的,如下所示:
commandQueue = cl::CommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE, &err);
get_default_queue()
是否必须是调用父内核的同一个命令队列?问这个是因为我使用相同的命令队列将数据上传到 GPU,然后在一次同步中下载结果。
将解决方案从问题移至答案:
Edit: below API command was the solution:
commandQueue = cl::CommandQueue(context, device,
CL_QUEUE_ON_DEVICE|
CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE |
CL_QUEUE_ON_DEVICE_DEFAULT, &err);
after creating this queue(only 1 per device), didn't use it for anything else and also the parent kernel is enqueued on any other host queue so it looks like get_default_queue() doesn't have to be the parent-calling queue.
Documentation says CL_INVALID_QUEUE_PROPERTIES will be thrown if CL_QUEUE_ON_DEVICE is specified but for my machine, dynamic parallelism works with it and doesn't throw that error(as the upper commandQueue constructor parameters).
产生错误的内核代码:
__kernel void testDynamic(__global int *data)
{
int id=get_global_id(0);
atomic_add(&data[1],2);
}
__kernel void test(__global int * data)
{
int id=get_global_id(0);
atomic_add(&data[0],2);
if (id == 0) {
queue_t q = get_default_queue();
ndrange_t ndrange = ndrange_1D(1,1);
void (^my_block_A)(void) = ^{testDynamic(data);};
enqueue_kernel(q, CLK_ENQUEUE_FLAGS_WAIT_KERNEL,
ndrange,
my_block_A);
}
}
我测试了以下代码以确保 OpenCL 2.0 编译器正常工作。
__kernel void test2(__global int *data)
{
int id=get_global_id(0);
data[id]=work_group_scan_inclusive_add(id);
}
扫描函数给出 0、1、3、6 作为输出,因此 OpenCL 2.0 缩减函数正在运行。
动态并行是 OpenCL 2.0 的扩展吗?如果我删除 enqueue_kernel
命令,结果等于预期值(省略子内核)。
设备:AMD RX550,驱动程序:17.6.2
是否需要在主机端 运行 对 get_default_queue
队列上的 运行 子内核执行特殊命令?目前,命令队列是使用 OpenCL 1.2 方式创建的,如下所示:
commandQueue = cl::CommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE, &err);
get_default_queue()
是否必须是调用父内核的同一个命令队列?问这个是因为我使用相同的命令队列将数据上传到 GPU,然后在一次同步中下载结果。
将解决方案从问题移至答案:
Edit: below API command was the solution:
commandQueue = cl::CommandQueue(context, device, CL_QUEUE_ON_DEVICE| CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE_DEFAULT, &err);
after creating this queue(only 1 per device), didn't use it for anything else and also the parent kernel is enqueued on any other host queue so it looks like get_default_queue() doesn't have to be the parent-calling queue.
Documentation says CL_INVALID_QUEUE_PROPERTIES will be thrown if CL_QUEUE_ON_DEVICE is specified but for my machine, dynamic parallelism works with it and doesn't throw that error(as the upper commandQueue constructor parameters).