OpenCL CLK_LOCAL_MEM_FENCE导致中止陷阱6

时间:2016-02-05 09:35:23

标签: c synchronization opencl

我正在使用OpenCL对图像卷积(info here)进行一些练习。当我使用大小不是正方形的图像(如r x c)时CLK_LOCAL_MEM_FENCE会使程序因中止陷阱6而停止。

我所做的实际上是用适当的值填充本地内存,等待填充本地内存完成的过程,使用barrier(CLK_LOCAL_MEM_FENCE)然后计算值。

似乎当我使用像我已经告诉过你的那些图像屏障(CLK_LOCAL_MEM_FENCE)会给出问题时,如果我评论这个命令一切正常(这很奇怪,因为那里没有)同步)。什么可能导致这个问题的任何想法?

编辑:当高度或宽度或两者不是本地项目大小(16 x 16)的倍数时,问题就出现了。全局项目大小远离16的多个值,如(512 x 512)。

int c = get_global_id(0); 
int r = get_global_id(1); 

int lc = get_local_id(0);
int lr = get_local_id(1);

// this ignores indexes out of the input image.
if (c >= ImageWidth || r >= ImageHeight) return;

// fill a local array...

barrier(CLK_LOCAL_MEM_FENCE);

if (c < outputImageWidth && r < outputImageHeight)
{
     // LOCAL DATA PROCESSED  
     OutputImage[r* outputImageWidth +c] = someValue;
}

2 个答案:

答案 0 :(得分:3)

OpenCL要求每个工作组障碍由该工作组中的每个工作项执行。

在您发布的代码中,您有一个提前退出子句以防止超出范围的访问。这是在OpenCL 1.X中获得良好工作组大小的常见技巧,但不幸的是,这会破坏上述条件,这将导致未定义的行为(通常是挂起或崩溃)。

您需要修改内核以避免这种情况,方法是删除提前退出子句(可能会删除超出范围的工作项,如果适用),或者通过重构内核使其超出 - 范围工作项目在退出之前至少会继续作为障碍。

答案 1 :(得分:2)

您可以更改代码顺序而不影响修复它的行为:

int c = get_global_id(0); 
int r = get_global_id(1); 

int lc = get_local_id(0);
int lr = get_local_id(1);

// fill a local array... with all the threads
// ie: for(i=0;i<size;i+=get_local_size(0))
//        ...

barrier(CLK_LOCAL_MEM_FENCE);

// this ignores indexes out of the input image.
if (c >= ImageWidth || r >= ImageHeight) return;

if (c < outputImageWidth && r < outputImageHeight)
{
     // LOCAL DATA PROCESSED  
     OutputImage[r* outputImageWidth +c] = someValue;
}