我在尝试使用 OpenMP 和 Portland Group 编译器读取 Fortran 程序中的名单时遇到问题。
我想做的很简单:我read_namelist
在一个区域中调用一个子程序SINGLE
,在其中初始化我想从名单中读取的参数,然后打开、读取、关闭名单。我在名单中读取的参数是线程私有的,我在读取后将它们传播到其他线程。
虽然它在 GNU 和 Intel 编译器上工作得很好,但在 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
该模块params
非常简单,仅包含:
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
如果我用 Intel 或 GNU 编译器编译相同的代码(仍然有 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
任何想法或提示将不胜感激!