我创建了一个C ++类来包装一个巨大的/不可读的fortran代码。此代码不包含公共块或模块,但它具有一些保存语句和等效语句。这个想法是该类包含发送到这些fortran例程的成员来存储临时结果。
我已经使用单线程MPI进程测试了这个C ++类,并且它运行良好。但是,如果我尝试OpenMP并行化,它看起来像在fortran代码中,线程开始篡改其他变量,尤其是内部循环。我实现并行部分的方法是,我创建了一个对象向量,这样每个线程都使用该向量中自己的对象。
我花了一些时间在网上阅读,似乎将fortran函数/子例程定义为递归可能会有所帮助。我已经这样做了,但我仍然得到错误“Fortran运行时错误:循环变量已被修改”。
以下是包装器的简化版本:
int nthreads = 16;
vector<clte*> lte;
lte.resize(nthreads);
for(auto &it:lte) it = new clte(input);
#pragma omp parallel default(shared) private(xx,yy,tt,tid,ele,ele1,ele2,ele3,kk) num_threads(nthreads)
{
tid = omp_get_thread_num();
for(tt = 0; tt < nt; tt++){
for(yy = 0; yy< ny; yy++){
#pragma omp for schedule(dynamic,2)
for(xx = 0; xx < nx; xx++){
/* --- Compute array offsets ---*/
ele = tt*ny*nx*nw*4 + yy*nx*nw*4 + xx*nw*4;
ele1 = tt*ny*nx*ndep + yy*nx*ndep + xx*ndep;
ele2 = tid*ndep;
ele3 = tt*ny*nx*6*ndep*4*nw + yy*nx*6*ndep*nw*4 + xx*6*ndep*nw*4;
/* --- synthesize spectra and gradient---*/
synthOneGrad(lte[tid], nw, ndep, m[tid], dpar, &res[ele], &grad[ele3]);
}// xx
} //yy
} // tt
} // pragma
在synthOneGrad中,每个线程都会调用一个调用fortran函数的方法lte-&gt; eos。
有没有办法强制每个openMP线程在fortran例程中使用自己的私有内存。我确信C ++部分必须是正常的,但这是一个混乱变量的fortran例程。