我在尝试使用OpenMP和Portland Group编译器读取Fortran程序中的名单时遇到问题。
我想做的很简单:我在read_namelist
区域调用SINGLE
子程序,在那里我初始化我要从名单中读取的参数,然后打开,读取,关闭名单。我在名单中读取的参数是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
模块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
任何想法或提示都将不胜感激!
答案 0 :(得分:0)
我没有得到确切的理由,但至少我找到了解决方法,使用代码。
如果名单中读取的参数在子程序中是私有的,则可以毫无问题地读取它们;因此取代
call read_nml
通过
call read_nml(nx, ny, nz)
和
的子程序read_nml
subroutine read_nml(nx, ny, nz)
implicit none
integer :: nx, ny, nz
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
运作良好。我想这又是属性的状态(私有)的问题,但我不明白为什么英特尔和GNU编译器没有问题处理它,而PGI编译器无法处理它。实际上,这就是为什么参数是我的模块中的threadprivate,以防止这种行为。如果有人能给我一个比我更好的答案,我仍然感兴趣!