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)