我有以下代码:
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(..);
}
// ...
}
}
}它工作得很完美。
不管怎么说,我可以使用我的第一个代码版本而不会出现错误吗?还是我做错什么了?
发布于 2014-12-02 20:50:20
在这种特殊情况下,OpenMP可能有点混乱。“规格说明”(第2.14.3.6节)规定:
工作共享结构的约简子句中出现的列表项必须在由工作共享构造绑定到的任何工作共享区域中的并行区域中共享。
此外,它还指出(第2.14.1.1节),对于C和C++,
在构造中的作用域中声明的具有自动存储持续时间的变量是私有的。
在您的示例中,变量sum是在函数cicleMkekin的调用范围中声明的,并且作为函数参数具有自动存储持续时间。因此,当您从并行区域内调用cicleMkekin (或者,从与程序执行相一致的隐式顶层并行区域调用)时,sum被视为私有变量。因此,您的result子句确实是非法的,并且您得到的错误消息可能会让人感到困惑,尽管它可能会出现在这个位置上。
在手动内联cicleMkekin调用的代码版本中,可以在并行区域之外声明变量sum。在没有default子句或该变量的所谓显式数据共享属性的情况下,这样的变量确实是共享的(§2.14.1),因此,该版本的代码中的reduction子句是合法的。
https://stackoverflow.com/questions/27253691
复制相似问题