Linux Fortran OpenMP - 从 OpenMP 任务调用的子例程访问全局变量

Pet*_*vin 6 linux fortran openmp intel-fortran

从 OpenMP 任务调用的内部子例程访问程序全局变量是否合法/有效?

ifort 2021.7.0 20220726 不会报告错误,但似乎会根据编译器选项产生随机结果。例子:

program test1
  implicit none
  integer :: i, j, g
  g = 42
  !$OMP PARALLEL DEFAULT(SHARED)
     !$OMP SINGLE
        i = 0
        j = 1
        do while (j < 60)
           i = i + 1
           !$OMP TASK DEFAULT(SHARED) FIRSTPRIVATE(i,j)
              call sub(i,j)
           !$OMP END TASK
           j = j + j
        end do
     !$OMP END SINGLE
  !$OMP END PARALLEL
  stop

contains

  subroutine sub(i,j)
    implicit none
    integer i,j
    !$OMP CRITICAL(unit6)
       write(6,*) i,j,g
    !$OMP END CRITICAL(unit6)
  end subroutine sub

end program test1
Run Code Online (Sandbox Code Playgroud)

编译为:ifort -o test1 test1.f90 -qopenmp -warn all -check all

预期结果:

           5          16          42
           4           8          42
           6          32          42
           3           4          42
           2           2          42
           1           1          42
Run Code Online (Sandbox Code Playgroud)

得到的结果:

           2           2  -858993460
           5          16  -858993460
           4           8  -858993460
           6          32  -858993460
           1           1  -858993460
           3           4  -858993460
Run Code Online (Sandbox Code Playgroud)

注意:输出行的顺序并不重要——只是第三列中的数字应该是 42。

通过更改编译器选项会获得不同的意外结果。例如,对于“ifort -o test1 test1.f90 -qopenmp -warn all -O0”,第三列是 256,对于“ifort -o test1 test1.f90 -qopenmp -O0”,第三列是 -740818552。

当然,g 可以作为参数传递给 sub(),但是我正在协助处理的程序有数十个共享全局变量(在并行部分中不会改变),并且子例程调用会深入几层。

谢谢,彼得·麦加文。

小智 0

请尝试 oneAPI 编译器包 2022.2 或 2022.3。

/iusers/xtian/temp$ ifx -qopenmp  jimtest.f90
/iusers/xtian/temp$ ./a.out
           2           2          42
           1           1          42
           3           4          42
           5          16          42
           4           8          42
           6          32          42
Run Code Online (Sandbox Code Playgroud)