Fortran中的PGI、OpenMP和名称列表
我在尝试使用OpenMP和Portland Group编译器读取Fortran程序中的名称列表时遇到问题 我尝试做的很简单:在单个区域中调用read_namelist子例程,在其中初始化要从namelist读取的参数,然后打开、读取、关闭namelist。我在名称列表中读取的参数是threadprivate,读取后我将它们传播到其他线程 虽然它在GNU和英特尔编译器上运行得很好,但在PGI上却失败了,我不知道为什么。我没有得到任何错误,但读取的参数等于默认参数,而不是我从名称列表中读取的参数 下面是我正在尝试做的一个例子:Fortran中的PGI、OpenMP和名称列表,fortran,openmp,pgi,Fortran,Openmp,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的,以防止这种行为。如果有人能给我一个更好的答案,我仍然感兴趣 错误信息是什么?对不起,我忘了精确。我添加了一些例子来澄清我的问题。