Fortran&;OpenMP:如何声明和分配可分配的线程专用阵列

Fortran&;OpenMP:如何声明和分配可分配的线程专用阵列,fortran,openmp,gfortran,fortran90,Fortran,Openmp,Gfortran,Fortran90,我有一个串行代码,我会在模块中声明一组变量,然后在我的程序和子例程的其余部分中使用这些模块。现在我正在尝试并行化这段代码。有一部分代码我想并行运行,除了一个数组,gtmp,它似乎在工作。我希望每个线程都有自己的gtmp版本,并且希望该版本对其各自的线程是私有的,因此我使用了threadprivate指令gtmp仅在代码的并行区域内或仅从代码的并行部分调用的子例程内使用 首先,我将gtmp分配到并行部分之前的代码的串行部分,但这是一个问题,因为当时只有gtmp的主线程“版本”被分配,而gtmp的其

我有一个串行代码,我会在模块中声明一组变量,然后
在我的程序和子例程的其余部分中使用这些模块。现在我正在尝试并行化这段代码。有一部分代码我想并行运行,除了一个数组,
gtmp
,它似乎在工作。我希望每个线程都有自己的
gtmp
版本,并且希望该版本对其各自的线程是私有的,因此我使用了
threadprivate
指令
gtmp
仅在代码的并行区域内或仅从代码的并行部分调用的子例程内使用

首先,我将
gtmp
分配到并行部分之前的代码的串行部分,但这是一个问题,因为当时只有
gtmp
的主线程“版本”被分配,而
gtmp
的其他线程“版本”的
大小为
1
,而不是
gtmp
的预期分配大小(这由“test”
print
语句显示)。我认为这是因为主线程是串行部分中唯一执行代码的线程。因此,我将
allocate
行移动到并行区域中,这允许所有线程具有适当大小/分配的
gtmp
数组,但由于我的并行区域位于循环内,因此当程序在
r
循环的第二次迭代中再次尝试分配
gtmp
时,我会遇到一个错误

注意:
mymod
中的所有其他变量都是给定值

下面是代码中存在问题的简化部分:

module mymod
  integer :: xBins, zBins, rBins, histCosThBins, histPhiBins, cfgRBins
  real(kind=dp),allocatable :: gtmp(:,:,:)
end module mymod

subroutine compute_avg_force
  use mymod
  implicit none
  integer :: r, i, j, ip
  integer :: omp_get_thread_num, tid

  ! I used to allocate 'gtmp' here.

  do r = 1, cfgRBins
    !$omp PARALLEL DEFAULT( none ) &
    !$omp PRIVATE( ip, i, j, tid ) &
    !$omp SHARED( r, xBins, zBins, histCosThBins, histPhiBins )
    allocate( gtmp(4,0:histCosThBins+1,0:histPhiBins+1) )
    tid = omp_get_thread_num()  !debug
    print*, 'test', tid, histCosThBins, histPhiBins, size(gtmp)
    !$omp DO SCHEDULE( guided )
    do ip = 1, (xBins*zBins)
        call subroutine_where_i_alter_gtmp(...)
            ...code to be executed in parallel using gtmp...
    end do !ip
    !$omp END DO
    !$omp END PARALLEL
end do !r
end subroutine compute_avg_force
因此,问题来自这样一个事实,即我需要所有线程都处于活动状态(即在并行区域中),以适当地初始化
gtmp
的所有“版本”,但我的并行区域在一个循环中,我不能多次分配
gtmp

简而言之,在此代码中分配
gtmp
的正确方法是什么?我认为我可以在循环之前创建另一个
omp并行
区域,并使用该区域分配
gtmp
,但这似乎很笨拙,所以我想知道这样做的“正确”方式是什么


谢谢你的帮助

在匆忙中,或者取消分配和重新分配,或者几乎可以肯定的是,最好将并行区域移到外部循环之外,适当地调整范围,并像以前那样在循环之外分配一次。不要使用REAL(8)-参见此处,出于效率原因,passimI无法将并行区域移到
r
循环之外。别担心,我不用真的。我写这篇文章是因为我有另一个模块,我在其中设置了我的精确度,我不想把我的文章也放进去,让它变得更长。我将进行编辑以反映初始化行的实际外观。我认为您可以在并行区域之外替换allocate并将
gtmp
声明为threadprivate。添加
copyin(gtmp)
以获取要传播的
gtmp
的“主”状态。但这可能效率低下,还有其他解决方案:分配一个数组,每个数组由一个线程使用,或者再次在并行区域中分配。
r+1
的结果是否依赖于
r
?好的,从效率角度看,这与在
r
循环之前创建另一个平行区域以及在那里分配
相比,有什么想法吗?否
r+1
的结果与
r
无关。