如何解决 openACC 中所需的标量最后一个值

how to resolve scalar last value needed in openACC

在编译 openacc 代码时,我收到以下警告 215,第 239 行 x 循环后所需的标量最后一个值 在第 239 行为 y 循环后所需的标量最后一个值 第 240 行 x 循环后所需的标量最后一个值 在第 240 行为 y 循环后所需的标量最后一个值 第 242 行 x 循环后所需的标量最后一个值 在第 242 行为 y 循环后所需的标量最后一个值 第 246,248 行的 x 循环后所需的标量最后一个值 在第 248,252 行的 y 循环后需要的标量最后一个值

此类警告是否使程序按顺序运行如何在 OpenACC 中使用 lastvalue 子句?

是的,这些警告会导致代码按顺序 运行(假设您使用的是 PGI,请参阅 -Minfo=accel 的编译器反馈输出)。默认情况下,标量首先是私有的。但是,如果标量的值在 OpenACC 计算区域之外使用,编译器无法自动私有化标量,因为它不知道要使用哪个值。

这可能发生在计算区域之后使用标量变量时,例如

#pragma acc parallel loop 
for (int i=...
    x = <expr>
    ...
}
printf("Final X=%d\n",x);

您可以解决这个问题,我将 "x" 放在一个私有子句中,但是为 "x" 打印的值将与循环之前的值保持不变。

另一种可能发生这种情况的情况是在更新计算区域内的全局标量时。在这种情况下,您可能希望将变量放在数据子句中(例如 "copy"),让所有线程共享该变量,然后在更新值时使用 OpenACC "atomic" 指令。

第三种情况是标量通过地址传递给设备子例程。在这种情况下,编译器必须假定其他引用已成为标量。虽然很可能您不打算将全局指针分配给标量,但这是可能的,并且由于编译器对子例程不可见,因此它必须假设它。要解决此问题,请将标量添加到 OpenACC "private" 子句,或更改代码以按值传递标量。请注意,默认情况下 Fortran 按地址传递参数。要按值传递,请在参数声明中使用 F2003 "value" 属性。

如果您遇到的情况与上面所列情况不同,请提供说明问题的示例代码。