Fortran中的PGI、OpenMP和名称列表

Fortran中的PGI、OpenMP和名称列表,fortran,openmp,pgi,Fortran,Openmp,Pgi,我在尝试使用OpenMP和Portland Group编译器读取Fortran程序中的名称列表时遇到问题 我尝试做的很简单:在单个区域中调用read_namelist子例程,在其中初始化要从namelist读取的参数,然后打开、读取、关闭namelist。我在名称列表中读取的参数是threadprivate,读取后我将它们传播到其他线程 虽然它在GNU和英特尔编译器上运行得很好,但在PGI上却失败了,我不知道为什么。我没有得到任何错误,但读取的参数等于默认参数,而不是我从名称列表中读取的参数 下

我在尝试使用OpenMP和Portland Group编译器读取Fortran程序中的名称列表时遇到问题

我尝试做的很简单:在单个区域中调用read_namelist子例程,在其中初始化要从namelist读取的参数,然后打开、读取、关闭namelist。我在名称列表中读取的参数是threadprivate,读取后我将它们传播到其他线程

虽然它在GNU和英特尔编译器上运行得很好,但在PGI上却失败了,我不知道为什么。我没有得到任何错误,但读取的参数等于默认参数,而不是我从名称列表中读取的参数

下面是我正在尝试做的一个例子:

program read_input
  !$ use OMP_LIB
  use params
  implicit none

  integer :: rank=0, nthreads=1

  !$OMP PARALLEL DEFAULT(PRIVATE)
  !$ rank = OMP_GET_THREAD_NUM()
  !$ nthreads = OMP_GET_NUM_THREADS()   
  !$OMP SINGLE 
  print*, 'There is ', nthreads, ' threads running'

  call read_nml
  !$OMP END SINGLE COPYPRIVATE(nx, ny, nz)

  print*, 'Rank: ', rank
  print*, 'nx, ny, nz: ', nx, ny, nz
  !$OMP END PARALLEL   

contains
  subroutine read_nml
    use params
    implicit none
    namelist /input_params/ nx, ny, nz

    call default_parameters
    print*, 'nx, ny, nz (default): ', nx, ny, nz

    open(unit=1, file='input', status='old')
    read(1, input_params)
    close(1)
    print*, 'nx, ny, nz (read): ', nx, ny, nz

    return
  end subroutine read_nml

  subroutine default_parameters
    use params
    implicit none

    nx = 2; ny = 2; nz = 2

    return
  end subroutine default_parameters
end program read_input
模块参数非常简单,仅包含:

module params
  integer :: nx, ny, nz
  !$OMP THREADPRIVATE(nx, ny, nz)
end module params
使用pgfortran编译,以下是我使用2个线程得到的输出:

 Start program: read_input
 There is             2  threads running
 nx, ny, nz (default):             2            2            2
 Rank:             0
 nx, ny, nz:             2            2            2
 Rank:             1
 nx, ny, nz:             2            2            2
 Start program: read_input
 There is            2  threads running
 nx, ny, nz (default):            2           2           2
 nx, ny, nz (read):           10          10          10
 Rank:            0
 nx, ny, nz:           10          10          10
 Rank:            1
 nx, ny, nz:           10          10          10
如果我用Intel或GNU编译器编译同一段代码,仍然有两个线程:

 Start program: read_input
 There is             2  threads running
 nx, ny, nz (default):             2            2            2
 Rank:             0
 nx, ny, nz:             2            2            2
 Rank:             1
 nx, ny, nz:             2            2            2
 Start program: read_input
 There is            2  threads running
 nx, ny, nz (default):            2           2           2
 nx, ny, nz (read):           10          10          10
 Rank:            0
 nx, ny, nz:           10          10          10
 Rank:            1
 nx, ny, nz:           10          10          10

任何想法或暗示都将不胜感激

我不知道确切的原因,但至少我找到了一个解决办法,玩代码

如果名称列表中读取的参数在子例程中是私有的,则可以毫无问题地读取这些参数;因此取代

call read_nml

子例程通过


效果很好。我想这又是一个属性私有状态的问题,但我不明白为什么Intel和GNU编译器处理它时没有问题,而PGI编译器却无法处理它。实际上,这就是为什么在我的模块中参数是threadprivate的,以防止这种行为。如果有人能给我一个更好的答案,我仍然感兴趣

错误信息是什么?对不起,我忘了精确。我添加了一些例子来澄清我的问题。