产生错误的内核代码:
__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,然后在单个同步中下载结果。
答案 0 :(得分:0)
将解决方案从问题转移到答案:
API命令下面的编辑是解决方案:
commandQueue = cl::CommandQueue(context, device, CL_QUEUE_ON_DEVICE| CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE_DEFAULT, &err);
创建此队列后(每个设备只有1个),没有将其用于其他任何内容,并且父内核也在任何其他主机队列上排队,因此看起来get_default_queue()不一定是父 - 呼叫队列。
文档说如果指定了CL_QUEUE_ON_DEVICE,则会抛出CL_INVALID_QUEUE_PROPERTIES,但是对于我的机器,动态并行性与它一起使用并且不会抛出该错误(作为上面的commandQueue构造函数参数)。