OpenCL在大2d范围内崩溃

时间:2014-05-26 17:57:37

标签: c++ opencl

在我的程序中,我需要在大型2d阵列的每个项目上运行一次内核。该程序适用于小范围 - 最高约50x50,有时高达100x100。

但是对于较大的数据集,调用内核会导致视频卡驱动程序崩溃。

我在两台具有不同AMD卡的计算机上测试了这个程序,它们表现出完全相同的行为。其他一维内核可以正常工作,即使对于大约10 000 x 10000个项目的大型数据集也是如此。

此外,从i表达式中删除matrix[i + (N + 1) * j]变量会导致内核正常工作。

我是否错误地设置了范围,在内核中出错,或者问题可能在其他地方?

排队范围:

cl::EnqueueArgs args(queue,cl::NDRange(offset, offset+1),cl::NDRange(N+1, N),cl::NullRange);

内核:

void kernel sub(global float* matrix, global const float* vec, int N, int offset) {
  int i = get_global_id(0);
  int j = get_global_id(1);         
  matrix[i + (N + 1) * j] -= matrix[i + (N + 1) * offset] * vec[j]; 
}

3 个答案:

答案 0 :(得分:0)

可能的原因之一 - 如果您的内核运行时间太长,驱动程序可能会丢弃它。将问题区域划分为更小的块。

答案 1 :(得分:0)

考虑到这一点,对于100x100输入数组,你将使用N = 100,因此你的内核中i的最大值将是100,因为在enqueue args中使用了N + 1,而j的最大值将是99我假设偏移= 0.因此i +(N + 1)* j = 100 + 101 * 99 = 10099,它在2D数组之外。

当offset = 1时,i和j的最小值分别为1和2,而最大值为101和100.因此i +(N + 1)* j = 101 + 101 * 100 = 10201。 / p>

根据我的经验,GPU在访问全局内存时不能很好地捕获分段错误。您有意创建一个卡片的尝试可能会在某些卡片上有效但无法保证。

答案 2 :(得分:0)

问题可能是由本地工作规模和全球工作规模造成的。使用二维数组来正确计算它们很重要。对于大值,您的global_id(0)可能大于您在clEnqueueNDRangeKernel()中指定的值。