OpenCL CLK_LOCAL_MEM_FENCE 导致中止陷阱 6
OpenCL CLK_LOCAL_MEM_FENCE causing abort trap 6
我正在使用 OpenCL 对图像 (info here) 进行一些卷积练习。当我使用大小不是正方形的图像(如 r x c)时,CLK_LOCAL_MEM_FENCE
使程序停止并出现 abort trap 6.
我所做的基本上是用适当的值填充本地内存,等待填充本地内存的过程完成,使用 barrier(CLK_LOCAL_MEM_FENCE
) 然后计算值。
似乎当我使用像我告诉过你的关于 barrier(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;
}
OpenCL 要求每个工作组屏障由该工作组中的每个 工作项执行。
在您发布的代码中,您有一个提前退出子句来防止超出范围的访问。这是在 OpenCL 1.X 中获得良好工作组大小的常用技巧,但不幸的是,这打破了上述条件,这将导致未定义的行为(通常是挂起或崩溃)。
您将需要修改您的内核以避免这种情况,方法是删除提前退出子句(如果适用,可能会钳制超出范围的工作项),或者重构内核以便超出-超出范围的工作项在退出前至少继续到障碍。
您可以更改代码顺序而不影响修复它的行为:
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;
}
我正在使用 OpenCL 对图像 (info here) 进行一些卷积练习。当我使用大小不是正方形的图像(如 r x c)时,CLK_LOCAL_MEM_FENCE
使程序停止并出现 abort trap 6.
我所做的基本上是用适当的值填充本地内存,等待填充本地内存的过程完成,使用 barrier(CLK_LOCAL_MEM_FENCE
) 然后计算值。
似乎当我使用像我告诉过你的关于 barrier(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;
}
OpenCL 要求每个工作组屏障由该工作组中的每个 工作项执行。
在您发布的代码中,您有一个提前退出子句来防止超出范围的访问。这是在 OpenCL 1.X 中获得良好工作组大小的常用技巧,但不幸的是,这打破了上述条件,这将导致未定义的行为(通常是挂起或崩溃)。
您将需要修改您的内核以避免这种情况,方法是删除提前退出子句(如果适用,可能会钳制超出范围的工作项),或者重构内核以便超出-超出范围的工作项在退出前至少继续到障碍。
您可以更改代码顺序而不影响修复它的行为:
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;
}