我正在使用OpenMP并行化for循环。该程序使用Gurobi C API。
GRBupdatemodel(model);
#pragma omp parallel for
for (int batch = 0; batch < n_batch; ++batch)
{
int cind[1 + n_max];
for (int j = 0; j < n_max; ++j)
{
cind[1 + j] = n_sum + j;
}
double cval[1 + n_max];
cval[0] = 1;
GRBmodel* model_copy = GRBcopymodel(model);
for (int i = 0; i < n_sum; ++i)
{
cind[0] = i;
for (int k = 0; k < n_min; ++k)
{
for (int j = 0; j < n_max; ++j)
{
cval[1 + j] = -*((double*) PyArray_GetPtr(array,(long []) {batch,i,j,k}));
}
GRBaddconstr(model_copy,1 + n_max,cind,cval,GRB_LESS_EQUAL,NULL);
}
}
GRBoptimize(model_copy);
GRBgetdblattrarray(model_copy,GRB_DBL_ATTR_X,n_sum,values[batch]);
GRBgetdblattrarray(model_copy,n_max,max_strategy[batch]);
GRBgetdblattrarray(model_copy,GRB_DBL_ATTR_PI,1,n_sum * n_min,(double *) min_strategies[batch]);
GRBfreemodel(model_copy);
}
此循环的每次迭代都会写入数组values
,max_strategy
和min_strategies
的不同部分。
删除#pragma omp parallel for
会得到正确的结果。添加它会产生不正确的结果,包括nan值。因此,我怀疑循环中存在竞赛条件,但我找不到它。有谁知道可能出了什么问题?我在循环体内仅看到两种类型的写入:
- 对于
cind
,cval
和model_copy
(由GRBgetdblattrarray而言),它们是在循环体内声明的局部变量,因此对每个线程都是私有的。 - 到
values
,max_strategy
和min_strategies
的非重叠部分。