【发布时间】:2017-05-23 04:45:13
【问题描述】:
我正在使用 OpenACC 处理 LU decomposition 中的 block diagonal matrices。
当我按顺序运行我的代码时,我得到了正确的分解,而在 OpecACC 指令下执行它时,我在进行分解时得到了错误的结果。
LU 分解涉及该类型的嵌套循环(参见hereLUPSolve 函数):
for (unsigned int i = 0; i < N; i++)
for (unsigned int k = 0; k < i; k++)
看来,当在并行区域内的 routine seq 指令中使用这种类型的嵌套循环时,设备总是设法进入嵌套循环 即使 i=0(这也是由于k<i 条件,这是不可能的)。
我做了一个简单的代码来检查它:
#pragma acc routine seq
void test ( int* x, int const n ) {
for (unsigned int i = 0; i < n; i++) {
x[i] = -1;
for (unsigned int k = 0; k < i; k++)
x[i] = k < i;
}
}
int main ( ) {
unsigned const n(4);
unsigned const nb(3);
int x[nb*n];
#pragma acc parallel loop copyout(x[:nb*n])
for (unsigned int b = 0; b < nb; b++)
test(x+b*n,n);
// display x
}
我得到的结果是这个:
x = 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
但是正确的(当我在没有 OpenACC 的情况下运行代码时得到的)应该是:
x = -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1,
我一定是做错了什么,因为它不应该在i=0时进入嵌套循环...
另外,当我将循环直接放在并行区域中(不使用函数调用)时,它确实可以正常工作。
【问题讨论】:
-
这很奇怪,我也尝试过这种类型的嵌套循环:
for (int i = n-1; i >= 0; i--) { for (int k = i+1; k < n; k++) }并且设备不会进入i=n-1的嵌套循环,但是如果我将其更改为:for (int i = n-1; i >= 0; i--) { for (int k = 0; k < n-i-1; k++) }同样奇怪的行为发生了,设备进入i=n-1的嵌套循环......就像0<0对于嵌套循环是真的......我只是不知道我做错了什么,它一定在我的某个地方循环的条件...
标签: c++ nested-loops openacc