我正在输入一个Conjugate Residual求解器来解决我遇到的问题。在测试了串行工作的所有内容之后,我添加了一些OpenMP指令来加速我的代码,但是有些事情是不对的。
节点值(node
的成员)与我在串行实现中得到的不同。我仔细检查了activeNodes
中没有重复的条目,我想不出这里发生的任何竞争条件。
以下是有问题的代码块。
#pragma omp parallel for num_threads(THREAD_COUNT) reduction(+:residualSum)
for(int i=0;i<activeNodes.size();i++){
auto dataIt = activeNodes.begin();
std::advance(dataIt,i);
GridNode* node = dataIt->second;
node->r = -(node->consts.beta * node->consts.dt2 / (node->mass + EPS_D)) * node->getHessianSum(node->velNext);
node->s = node->r + (node->consts.beta * node->consts.dt2 / (node->mass + EPS_D)) * node->getHessianSum(node->r);
node->p = node->r;
node->q = node->s;
node->gamma = dot(node->r,node->s);
node->alpha = node->gamma / (dot(node->q,node->q) + EPS_D);
residuals[i] = node->alpha * node->alpha * node->p.norm2();
residualSum += residuals[i];
std::cout << "what node->r should be : " << -(node->consts.beta * node->consts.dt2 / (node->mass + EPS_D)) * node->getHessianSum(node->velNext) << std::endl;
std::cout << "node->r after assignment : " << node->r << std::endl;
}
注意:node->getHessianSum()
不会修改任何值。
大部分时间(99%),what node->r should be
完全等于node->r after assignment
。在某些情况下,它们完全不同,就像这里:
what node->r should be : (9.59679e-18,-7.9126e-18,-5.45652e-17)
node->r after assignment : (1.1954e-05,6.24484e-06,-2.01226e-06)
被搞砸的节点因每次运行而异,node->r after assignment
总是不同。
这些错误会破坏所有其他计算。我整天都在调查这个问题,而且我的智慧结束了。关于我的代码有什么问题的任何建议?