OpenCL在大2d范围内崩溃
OpenCL crash on big 2d range
在我的程序中,我需要在大型2d数组的每个项目上运行内核一次。该程序在小范围内正确工作-高达约50x50,有时高达100x100。
然而,对于更大的数据集,调用内核会导致显卡驱动程序崩溃。
我在两台使用不同AMD卡的计算机上测试了这个程序,它们表现出完全相同的行为。另外,一维的内核可以正常工作,甚至对于~ 10,000 x 10,000项的庞大数据集也是如此。
同样,从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,因此内核中i的最大值将是100,因为队列参数中使用了N+1,而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在访问全局内存时不擅长捕捉分段错误。您有目的地创建的尝试有时可能在某些卡片上有效,但不能保证。
问题可能是由local-work-size和global-work-size引起的。在使用二维数组时,正确地计算它们是很重要的。对于大值,您的global_id(0)可能大于您在clEnqueueNDRangeKernel()中指定的值。
- 为什么在全局范围内使用"extern int a"似乎不行?
- 错误:未在此范围内声明'reverse'
- 并行用于C++17中数组索引范围内的循环
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- 不计算一个范围内的完美数
- 错误:"imread"未在此范围内声明
- 我在范围内未声明的错误类有问题
- 如何在cpp中使用地图显示给定日期范围内(在下面的问题中)的费率?
- 我有一个数组,我想输入一个范围,然后找到范围内所有偶数的总和?
- 未在此范围内声明错误 'xy'
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- 命名空间范围内的外部 - GCC vs clang vs msvc
- 如何改进一堆在已知值范围内评估变量的 else-if 条件?
- 如何仅使用 While 循环在给定范围内找到可被 7 整除的计数整数
- Socklen_t未在此范围内声明
- 错误:'[' 之前预期的非限定 id 和错误:'users'未在此范围内声明
- 查找给定范围内最长连续 1 的频率
- 全局范围内的对象会导致程序退出时崩溃
- OpenCL在大2d范围内崩溃
- 当C++试图访问向量的元素(在范围内)时,Qt Quick Windows应用程序崩溃