注意:用于指定用户事件的排队命令
event_wait_list
clEnqueue***
命令的clSetUserEventStatus
参数必须确保这一点 使用等待设置等待的这些用户事件的状态 在发布OpenCL的任何OpenCL API之前ev1 = clCreateUserEvent(ctx, NULL); clEnqueueWriteBuffer(cq, buf1, CL_FALSE, ..., 1, &ev1, NULL); clEnqueueWriteBuffer(cq, buf2, CL_FALSE,...); clReleaseMemObject(buf2); // <--- UNDEFINED clSetUserEventStatus(ev1, CL_COMPLETE);
调用除事件对象以外的对象;否则行为 未定义。
因此,如果我在队列中等待用户事件,我不能在任何OpenCL对象上调用release?
这似乎是一个奇怪的要求?它的目的是什么?或者,为什么会如此?
他们给出的例子是:
{{1}}
导致未定义的行为?
答案 0 :(得分:0)
考虑一下他们给出的例子。
我们有一个有序队列,我们创建了一个用户事件:
ev1 = clCreateUserEvent(ctx, NULL); // (1)
然后我们想要写入缓冲区,但我们希望它等待我们的事件:
clEnqueueWriteBuffer(cq, buf1, CL_FALSE, ..., 1, &ev1, NULL); // (2)
我们想要在前一个缓冲区之后写一个缓冲区(正在等待我们的事件):
clEnqueueWriteBuffer(cq, buf2, CL_FALSE,...); // (3)
我们从尚未通过的第二个clEnqueueWriteBuffer
释放缓冲区,因为我们仍在等待用户事件。在这种情况下(4)发生在(3)之前,所以我们不知道在释放内存对象时会发生什么。
clReleaseMemObject(buf2); // <--- UNDEFINED // (4)
我们最终完成了我们的用户事件,导致(2)和(3)在(4)完成后发生。
clSetUserEventStatus(ev1, CL_COMPLETE); // (5)
基本上,以这种方式执行计算可能会导致问题,因为clReleaseMemObject
未插入clCommandQueue
并且可能会破坏我们期望的依赖关系。