我有以下代码:
void simulation (MD *md){
double sum;
#pragma omp parallel private (move)
{
for(move = 0; move < maxIterations; ++move)
{
cicleDoMove(md);
cicleForces(md);
cicleMkekin(md,sum);
// ...
}
}
}
在哪里 :
void cicleMkekin(Md *md, double sum){
#pragma omp for reduction(+ : sum)
for (i = 0; i < md->mdsize; i++)
{
sum += mkekin(..);
}
// ..
}
我收到以下错误:
"reduction variable 'sum' is private in outer context"
实际上,如果我将模拟代码更改为:
void simulation (MD *md){
double sum;
#pragma omp parallel private (move)
{
for(move = 0; move < maxIterations; ++move)
{
cicleDoMove(md);
cicleForces(md);
#pragma omp for reduction(+ : sum)
for (i = 0; i < md->mdsize; i++)
{
sum += mkekin(..);
}
// ...
}
}
}
它完美地工作。
无论如何,我可以使用我的第一个代码版本而不会收到该错误吗?还是我做错了什么?
在这种特殊情况下,OpenMP可能会有些混乱。该规范规定(第2.14.3.6节):
在工作共享构造的归约子句中出现的列表项必须在平行区域中共享,该并行区域是由工作共享构造引起的任何工作共享区域绑定到的。
此外,对于C和C ++,它说(§2.14.1.1)
在构造内部的作用域中声明的具有自动存储期限的变量是私有的。
在您的情况下,变量sum
在函数调用的范围内声明,cicleMkekin
并且作为函数参数具有自动存储持续时间。因此,当您cicleMkekin
在并行区域内(或为此,从与程序执行一致的隐式顶级并行区域)进行调用时,sum
被视为私有变量。结果,您的reduce子句确实是非法的,实际上,您所收到的错误消息令人困惑,可能使您感到困惑。
在您手动内联到的调用的代码版本中,您在并行区域之外cicleMkekin
声明了变量sum
。此类变量在没有default
子句或该变量的所谓的明确确定的数据共享属性的情况下,确实是共享的(第2.14.1节),因此,该reduction
代码版本中的子句是合法的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句