我有一个非常复杂的OpenCL应用程序。它在5个不同的GPU上激活5个不同的上下文,并在所有GPU上执行相同的内核,将工作分成1024个"块"待处理。
每次内核完成时,都会检查结果,然后给它一个新的块。有时,在运行时,当应用程序启动时(很少在中途运行),它会立即在GetEventInfo调用上发生段错误。
这是在使用回调和clGetEventInfo调用的循环中完成的,以确保在继续下一步之前完成某些操作。
GDB输出:
(gdb) back
#0 0x00007fdc686ab525 in clGetEventInfo () from /usr/lib/libOpenCL.so.1
#1 0x00000000004018c1 in ready (event=0x26a00000267) at gputest.c:165
#2 0x0000000000404b5a in main (argc=9, argv=0x7fffdfe3b268) at gputest.c:544
准备好的功能:
int ready(cl_event event) {
int rdy;
if(!event)
return 0;
clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(cl_int), &rdy, NULL);
if(rdy == CL_COMPLETE)
return 1;
return 0;
}
如何运行内核,事件集和检查。为简洁起见插入了一些伪代码:
while(test if loop is complete) {
for(j = 0; j < GPUS; j++) {
if(gpu[j].waiting && loops < 9999) {
gpu[j].waiting = 0;
offset[j] = loops * 1024 * 1024;
loops++;
EC("kernel init", clEnqueueNDRangeKernel(queues[j], kernel_init[j], 1, &(offset[j]), &global_work_size, &work128, 0, NULL, &events[j]));
gpu[j].readsearch = events[j];
gpu[j].reading = 1;
}
}
for(j = 0; j < GPUS; j++) {
if(gpu[j].reading && ready(gpu[j].readsearch)) {
gpu[j].reading = 0;
gpu[j].waiting = 1;
// unrelated reporting other code here
}
}
}
非常简单。代码还有更多,但它是无关的。准备/检查功能非常简单。我甚至在ready函数中添加了调试来printf事件#以查看它崩溃时发生了什么 - 没什么。没有我能看到的模式。
导致这种情况的原因是什么?
答案 0 :(得分:1)
唉。发现了问题。由于在创建/声明结构时无法初始化值,因此我使用了一些未初始化的值。我malloc了解了gpu结构,然后开始使用它们。 if(gpu [x] .reading&amp;&amp; ...)是随机数据并且完全未初始化。所以有时它是非零的,这允许ready()函数触发。由于gpu [x] .readsearch事件从未在第一时间设置,因此clGetEventInfo遭到轰炸,试图使用内存位置的任何内容。
这是时间编号482,847,意外使用未初始化的变量已经烧毁了我。