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!----------------------------------------------------------