Fortran 选择类型构造中的关联名称是否由OpenMP自动私有化?
我正在尝试分配一个多态可分配数组Fortran 选择类型构造中的关联名称是否由OpenMP自动私有化?,fortran,polymorphism,openmp,fortran2003,Fortran,Polymorphism,Openmp,Fortran2003,我正在尝试分配一个多态可分配数组ary,它可以接受两种扩展类型的baseType(extType1及其扩展extType2): 为了并行化aryPrintTypes子例程,首先,我认为select type构造会有问题,因为相关的名称这个是在输入之后创建的$OMP并行DO循环。因此,我编写了第一个并行版本,如下所示: !-FIRST PARALLELIZED VERSION : subroutine aryPrintTypes(a)!-------------------------------
ary
,它可以接受两种扩展类型的baseType
(extType1
及其扩展extType2
):
为了并行化aryPrintTypes
子例程,首先,我认为select type
构造会有问题,因为相关的名称这个是在输入之后创建的$OMP并行DO
循环。因此,我编写了第一个并行版本,如下所示:
!-FIRST PARALLELIZED VERSION :
subroutine aryPrintTypes(a)!-----------------------------------------------------------
type(arrayWrapper) , dimension(:), allocatable, intent(in ) :: a !
class(extType1 ) , pointer :: this !
integer :: n, i !
!
n = size(a) !
!$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(SHARED) PRIVATE(i, this) !
do i = 1, n, 1; select type (this=>a(i)%w) !
type is (extType1) !
write(*,*) "Thread #", OMP_GET_THREAD_NUM(), "i =", i, & !
"type is extType1, r1 =", this%r1 !
type is (extType2) !
write(*,*) "Thread #", OMP_GET_THREAD_NUM(), "i =", i, & !
"type is extType2, r2 =", this%r2 !
end select; end do !
!$OMP END PARALLEL DO !
end subroutine aryPrintTypes!----------------------------------------------------------
上面的代码和我预期的一样工作良好。使用8个线程的输出如下所示:
Thread # 0 i = 1 type is extType1, r1 = 1.0000000000000000
Thread # 2 i = 3 type is extType1, r1 = 3.0000000000000000
Thread # 6 i = 7 type is extType1, r1 = 7.0000000000000000
Thread # 5 i = 6 type is extType1, r1 = 6.0000000000000000
Thread # 4 i = 5 type is extType1, r1 = 5.0000000000000000
Thread # 7 i = 8 type is extType1, r1 = 8.0000000000000000
Thread # 3 i = 4 type is extType1, r1 = 4.0000000000000000
Thread # 1 i = 2 type is extType1, r1 = 2.0000000000000000
Thread # 6 i = 7 type is extType2, r2 = 14.000000000000000
Thread # 2 i = 3 type is extType2, r2 = 6.0000000000000000
Thread # 0 i = 1 type is extType2, r2 = 2.0000000000000000
Thread # 5 i = 6 type is extType2, r2 = 12.000000000000000
Thread # 7 i = 8 type is extType2, r2 = 16.000000000000000
Thread # 1 i = 2 type is extType2, r2 = 4.0000000000000000
Thread # 3 i = 4 type is extType2, r2 = 8.0000000000000000
Thread # 4 i = 5 type is extType2, r2 = 10.000000000000000
然而,我后来尝试了第二个并行版本,但没有将这个声明为指针
,令人惊讶的是,它也能工作,并给出与第一个版本相同的结果:
!-SECOND PARALLELIZED VERSION :
subroutine aryPrintTypes(a)!-----------------------------------------------------------
type(arrayWrapper) , dimension(:), allocatable, intent(in ) :: a !
integer :: n, i !
!
n = size(a) !
!$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(PRIVATE) SHARED(a, n) !
do i = 1, n, 1; select type (this=>a(i)%w) !
type is (extType1) !
write(*,*) "Thread #", OMP_GET_THREAD_NUM(), "i =", i, & !
"type is extType1, r1 =", this%r1 !
type is (extType2) !
write(*,*) "Thread #", OMP_GET_THREAD_NUM(), "i =", i, & !
"type is extType2, r2 =", this%r2 !
end select; end do !
!$OMP END PARALLEL DO !
end subroutine aryPrintTypes!----------------------------------------------------------
我在一个大型的内部计算代码中实现了这两个版本,第一个版本与往常一样工作正常,但在第二个版本中,DO循环中的select type
构造无法识别关联名称的类型this
编译器信息:
GNU Fortran (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
编辑:
有一条评论认为select type
中的this
构造与第一个并行版本中声明为指针的this
无关。因此,我删除了第一个版本中的指针
声明,它给出了相同的结果:
!-FIRST PARALLELIZED VERSION **(EDITED)**:
subroutine aryPrintTypes(a)!-----------------------------------------------------------
type(arrayWrapper) , dimension(:), allocatable, intent(in ) :: a !
integer :: n, i !
!
n = size(a) !
!$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(SHARED) PRIVATE(i) !
do i = 1, n, 1; select type (this=>a(i)%w) !
type is (extType1) !
write(*,*) "Thread #", OMP_GET_THREAD_NUM(), "i =", i, & !
"type is extType1, r1 =", this%r1 !
type is (extType2) !
write(*,*) "Thread #", OMP_GET_THREAD_NUM(), "i =", i, & !
"type is extType2, r2 =", this%r2 !
end select; end do !
!$OMP END PARALLEL DO !
end subroutine aryPrintTypes!----------------------------------------------------------
因此提出了一个新问题:OpenMP是否自动私有化了选择类型构造中的关联名称此,而无需声明为私有?它不需要(也不能)声明为私有。associate名称只是执行SELECT TYPE(或associate)语句时选择器指定的对象的同义词
OpenMP 5.0规范在s2.19.1.1中规定:
关联名称保留与在中建立的选择器的关联
关联或选择类型语句
关联名称和选择器之间的关联特定于每个线程
与名称关联的内容是私有的还是共享的取决于选择器的数据共享属性
在示例代码中,选择器的基本对象a
是共享的,但随后的索引确保不同线程不会访问该共享a
的相同元素 您知道吗,选择类型构造中的this
与该构造之外存在的任何this
完全无关?那么这是否意味着OpenMP会自动将this
在选择类型
构造中私有化,并进行/o声明?
!-FIRST PARALLELIZED VERSION **(EDITED)**:
subroutine aryPrintTypes(a)!-----------------------------------------------------------
type(arrayWrapper) , dimension(:), allocatable, intent(in ) :: a !
integer :: n, i !
!
n = size(a) !
!$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(SHARED) PRIVATE(i) !
do i = 1, n, 1; select type (this=>a(i)%w) !
type is (extType1) !
write(*,*) "Thread #", OMP_GET_THREAD_NUM(), "i =", i, & !
"type is extType1, r1 =", this%r1 !
type is (extType2) !
write(*,*) "Thread #", OMP_GET_THREAD_NUM(), "i =", i, & !
"type is extType2, r2 =", this%r2 !
end select; end do !
!$OMP END PARALLEL DO !
end subroutine aryPrintTypes!----------------------------------------------------------