使用OpenMP时如何在子程序中分配指针?

时间:2011-12-23 02:51:06

标签: pointers fortran openmp allocation fortran2003

如下面的代码示例所示,主程序尝试使用OpenMP来调用子例程。在该子例程中,创建并迭代本地指针变量。该程序生成Subscript #1 of the array PTEMPINTLIST has value 208 which is greater than the upper bound of 207个错误(具体数字不同)。我已经创建了包含用户派生类型omp-private,但似乎调用的子例程中的局部变量也应该声明为omp-private,但我不确定这是否属实,我不知道#39} ; t知道如何实现这一目标。

你能帮忙评论一下为什么程序会出现这样的错误吗?更重要的是,您是否可以帮助评论在使用OpenMP时如何在子例程中分配指针的最佳实践?

不知道为什么fortran代码没有着色。有人可以帮忙评论如何为代码着色,以便它更具可读性吗?

编译器是英特尔Fortran编译器,版本如下:

[root@localhost new]# ifort --version
ifort (IFORT) 12.1.0 20111011
Copyright (C) 1985-2011 Intel Corporation.  All rights reserved.

错误消息如下所示:

[root@localhost new]# ifort test_omp.f90 -warn -check -g -trace -openmp -static
[root@localhost new]# ./a.out 
 Thread numbers are:            8
 Thread            0  -            1
 Thread            0  -            2
 Thread            0  -            3
 Thread            0  -            4
 Thread            0  -            5
 Thread            0  -            6
 Thread            0  -            7
 Thread            0  -            8
 Thread            0  -            9
 Thread            0  -           10
 Thread numbers are:            8
 Thread            7  -            1
 Thread            7  -            2
 Thread            7  -            3
 Thread            7  -            4
 Thread            7  -            5
 Thread            7  -            6
 Thread            7  -            7
 Thread            7  -            8
 Thread            7  -            9
 Thread            7  -           10
 Thread            7  -           11
 Thread            7  -           12
 Thread            7  -           13
 Thread            7  -           14
 Thread            7  -           15
 Thread            7  -           16
 Thread            7  -           17
 Thread            7  -           18
 Thread            7  -           19
 Thread            7  -           20
 Thread            7  -           21
 Thread            7  -           22
 Thread            7  -           23
 Thread            7  -           24
 Thread            7  -           25
 Thread            7  -           26
 Thread            7  -           27
 Thread            7  -           28
 Thread            7  -           29
 Thread            7  -           30
 Thread            7  -           31
 Thread            7  -           32
 Thread            7  -           33
 Thread            7  -           34
 Thread            7  -           35
 Thread            7  -           36
 Thread            7  -           37
 Thread            7  -           38
 Thread            7  -           39
 Thread            7  -           40
 Thread            7  -           41
 Thread            7  -           42
 Thread            7  -           43
 Thread            7  -           44
 Thread            7  -           45
 Thread            7  -           46
 Thread            7  -           47
 Thread            7  -           48
 Thread            7  -           49
 Thread            7  -           50
 Thread            7  -           51
 Thread            7  -           52
 Thread            7  -           53
 Thread            7  -           54
 Thread            7  -           55
 Thread            7  -           56
 Thread            7  -           57
 Thread            7  -           58
 Thread            7  -           59
 Thread            7  -           60
 Thread            7  -           61
 Thread            7  -           62
 Thread            7  -           63
 Thread            7  -           64
 Thread            7  -           65
 Thread            7  -           66
 Thread            7  -           67
 Thread            7  -           68
 Thread            7  -           69
 Thread            7  -           70
 Thread            7  -           71
 Thread            7  -           72
 Thread            7  -           73
 Thread            7  -           74
 Thread            7  -           75
 Thread            7  -           76
 Thread            7  -           77
 Thread            7  -           78
 Thread            7  -           79
 Thread            7  -           80
 Thread            7  -           81
 Thread            7  -           82
 Thread            7  -           83
 Thread            7  -           84
 Thread            7  -           85
 Thread            7  -           86
 Thread            7  -           87
 Thread            7  -           88
 Thread            7  -           89
 Thread            7  -           90
 Thread            7  -           91
 Thread            7  -           92
 Thread            7  -           93
 Thread            7  -           94
 Thread            7  -           95
 Thread            7  -           96
 Thread            7  -           97
 Thread            7  -           98
 Thread            7  -           99
 Thread            7  -          100
 Thread            7  -          101
 Thread            7  -          102
 Thread            7  -          103
 Thread            7  -          104
 Thread            7  -          105
 Thread            7  -          106
 Thread            7  -          107
 Thread            7  -          108
 Thread            7  -          109
 Thread            7  -          110
 Thread            7  -          111
 Thread            7  -          112
 Thread            7  -          113
 Thread            7  -          114
 Thread            7  -          115
 Thread            7  -          116
 Thread            7  -          117
 Thread            7  -          118
 Thread            7  -          119
 Thread            7  -          120
 Thread            7  -          121
 Thread            7  -          122
 Thread            7  -          123
 Thread            7  -          124
 Thread            7  -          125
 Thread            7  -          126
 Thread            7  -          127
 Thread            7  -          128
 Thread            7  -          129
 Thread            7  -          130
 Thread            7  -          131
 Thread            7  -          132
 Thread            7  -          133
 Thread            7  -          134
 Thread            7  -          135
 Thread            7  -          136
 Thread            7  -          137
 Thread            7  -          138
 Thread            7  -          139
 Thread            7  -          140
 Thread            7  -          141
 Thread            7  -          142
 Thread            7  -          143
 Thread            7  -          144
 Thread            7  -          145
 Thread            7  -          146
 Thread            7  -          147
 Thread            7  -          148
 Thread            7  -          149
 Thread            7  -          150
 Thread            7  -          151
 Thread            7  -          152
 Thread            7  -          153
 Thread            7  -          154
 Thread            7  -          155
 Thread            7  -          156
 Thread            7  -          157
 Thread            7  -          158
 Thread            7  -          159
 Thread            7  -          160
 Thread            7  -          161
 Thread            7  -          162
 Thread            7  -          163
 Thread            7  -          164
 Thread            7  -          165
 Thread            7  -          166
 Thread            7  -          167
 Thread            7  -          168
 Thread            7  -          169
 Thread            7  -          170
 Thread            7  -          171
 Thread            7  -          172
 Thread            7  -          173
 Thread            7  -          174
 Thread            7  -          175
 Thread            7  -          176
 Thread            7  -          177
 Thread            7  -          178
 Thread            7  -          179
 Thread            7  -          180
 Thread            7  -          181
 Thread            7  -          182
 Thread            7  -          183
 Thread            7  -          184
 Thread            7  -          185
 Thread            7  -          186
 Thread            7  -          187
 Thread            7  -          188
 Thread            7  -          189
 Thread            7  -          190
 Thread            7  -          191
 Thread            7  -          192
 Thread            7  -          193
 Thread            7  -          194
 Thread            7  -          195
 Thread            7  -          196
 Thread            7  -          197
 Thread            7  -          198
 Thread            7  -          199
 Thread            7  -          200
 Thread            7  -          201
 Thread            7  -          202
 Thread            7  -          203
 Thread            7  -          204
 Thread            7  -          205
 Thread            7  -          206
 Thread            7  -          207
forrtl: severe (408): fort: (2): Subscript #1 of the array PTEMPINTLIST has value 208 which is greater than the upper bound of 207

Image              PC                Routine            Line        Source             
a.out              00000000004F0C6A  Unknown               Unknown  Unknown
a.out              00000000004EF766  Unknown               Unknown  Unknown
a.out              0000000000426700  Unknown               Unknown  Unknown
a.out              000000000040235F  Unknown               Unknown  Unknown
a.out              0000000000402881  Unknown               Unknown  Unknown
a.out              0000000000400D09  testopenmp_1_allo          39  omp.f90
a.out              00000000004006BE  MAIN__                     23  omp.f90
a.out              00000000004A4CF3  Unknown               Unknown  Unknown

代码示例为:

    module MyModule
        type :: MyType
            integer, dimension(:), pointer :: pIntList => null ()
        end type 
    end module MyModule

    program TestOpenMP_1_AllocationWithinSubroutines

        use MyModule
        use omp_lib
        implicit none

        type(MyType) :: instance
        integer :: threadCount 
        integer :: threadId 
        integer :: I

!$omp parallel private (instance, threadCount, threadId, I)
        threadCount = OMP_GET_NUM_THREADS()
        write (*,*) 'Thread numbers are: ', threadCount
        threadId = OMP_GET_THREAD_NUM()
        allocate (instance%pIntList(200 + threadId))
        CALL IterateList(instance) 
!$omp end parallel

        read (*,*)

    contains

        subroutine IterateList(aInstance)
            type(MyType) :: aInstance
            integer, dimension(:), pointer :: pTempIntList => null()
            integer :: threadId
            threadId = OMP_GET_THREAD_NUM()
            allocate (pTempIntList(size(aInstance%pIntList)))
            do I = 1, size(pTempIntList)
                pTempIntList(I) = I 
                !write (*,*) pTempIntList(I)
                write (*,*) 'Thread ',threadId, ' - ',pTempIntList(I)
            end do          
        end subroutine 

    end program TestOpenMP_1_AllocationWithinSubroutines

2 个答案:

答案 0 :(得分:3)

使用主程序中包含的子程序gfortran会给出错误消息:“在文件test_OpenMP.f90 / Fortran运行时错误的第36行:循环变量已被修改”

显然,“pTempIntList”的大小始终设置为相同的值(在运行之间变化),显然使用随机线程的大小(aInstance%pIntList)。对于经过该线程的线程来说,这个太小了。以下是一个有效的版本。对于gfortran和ifort,删除“=> null()”似乎是必要的。我不知道是否应该如此,但由于两个编译器需要它......

试试这个版本:

module MyModule
  type :: MyType
      integer, dimension(:), pointer :: pIntList
  end type

contains
   subroutine IterateList(aInstance)
      use omp_lib
      integer :: I
      type(MyType) :: aInstance
      integer, dimension(:), pointer :: pTempIntList
      integer :: threadId
      threadId = OMP_GET_THREAD_NUM()
      allocate (pTempIntList(size(aInstance%pIntList)))
      do I = 1, size(pTempIntList)
          write (*, *) i, threadID, size(aInstance%pIntList), size (pTempIntList)
          pTempIntList(I) = I
      end do
   end subroutine IterateList

end module MyModule

program TestOpenMP_1_AllocationWithinSubroutines

   use MyModule
   use omp_lib
   implicit none

   type(MyType) :: instance
   integer :: threadCount
   integer :: threadId
   integer :: I

   !$omp parallel private (instance, threadCount, threadId, I)
   threadCount = OMP_GET_NUM_THREADS()
   write (*,*) 'Thread numbers are: ', threadCount
   threadId = OMP_GET_THREAD_NUM()
   allocate (instance%pIntList(200 + threadId))
   CALL IterateList(instance)
   !$omp end parallel

end program TestOpenMP_1_AllocationWithinSubroutines

答案 1 :(得分:2)

我认为您正在遇到变量初始化为其赋予save属性的问题。使用空指针初始化pTempIntList意味着它将在子例程的不同调用之间保存。我不确定实现的细节,但猜测可能是子程序的所有调用实际上都共享了这个变量的内存。

你真的应该认真考虑Anycorn的评论。使用可分配变量通常比指针更安全。如果可以使用allocatables完成,请使用它们。