繁体   English   中英

大二维范围内的OpenCL崩溃

[英]OpenCL crash on big 2d range

在我的程序中,我需要在大型2D阵列的每个项目上运行一次内核。 该程序可在小范围内正常工作-最高可达50x50,有时甚至最高为100x100。

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

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

同样,从matrix[i + (N + 1) * j]表达式中删除i变量也会使内核正常工作而不会出错。

我是错误地设置了范围,还是在内核中出错了,还是问题出在其他地方?

入队范围:

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]; 
}

可能的原因之一-如果您的内核运行时间过长,驱动程序可能会将其删除。 将问题区域切成小块。

考虑这一点,对于100x100输入数组,您将使用N = 100,因此,由于在队列args中使用了N + 1,因此内核中i的最大值将为100,而j的最大值将为99。假设offset =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。

以我的经验,GPU在访问全局内存时不是很擅长捕捉分段错误。 您尝试有意创建一个的尝试有时可以在某些卡片上起作用,但不能保证。

该问题可能是由本地工作规模和全局工作规模引起的。 使用二维数组正确计算它们时,这一点很重要。 对于大值,可能是您的global_id(0)大于clEnqueueNDRangeKernel()中指定的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM