我目前正在学习将OpenMP与Fortran一起使用,并且作为实践,我尝试生成两个大的随机实数数组并将它们相乘。我尝试做的第一件事是并行生成数组。在这里,我遇到了一个困惑的问题。起初,我的代码如下所示:
program omp_test
use omp_lib
implicit none
!Variable definitions.
integer,parameter :: n=1000 !Matrix size.
real*8,dimension(n,n) :: A,B !Matrices.
integer :: row,col !Loop variables.
write(*,*) "Before OMP assignment."
!Parallel loop to assign a random number to every element in A and B.
!$OMP PARALLEL DO
do row = 1,n
do col=1,n
A(row,col)=rand()
B(row,col)=rand()
end do
end do
!$OMP END PARALLEL DO
write(*,*) "After OMP assignment."
end program omp_test
此代码(与gfortran和-fopenmp -O3标志一起编译)导致输出
Segmentation fault (core dumped)
没什么,甚至没有回溯。如果我将矩阵大小更改为512x512,它仍然会以相同的方式崩溃,但是511x511可以正常工作(更改OMP_STACKSIZE似乎无济于事)。如果我在编译过程中省略了-fopenmp标志,它也可以正常工作。请注意,甚至不会执行write语句。如果删除分配循环或删除OMP标志,则没有问题,因此循环的存在会导致程序在到达循环之前崩溃。但是,如果我一开始将A和B分配更改为
real*8,dimension(:,:),allocatable :: A,B
,并在第一个write语句之后直接使用
分配它们allocate(A(n,n))
allocate(B(n,n))
对于所有矩阵大小都可以正常运行。我怀疑rand()在某种程度上可能是使用SAVE的罪魁祸首,但我不明白为什么如果这样的话,为什么它对可分配数组有效。
有人知道这个问题是什么以及如何解决?