我使用Eclipse和GNU Fortran编译器来计算一个大型数组来解决矩阵问题。但是,我已经阅读并注意到,当我将-fopenmp调用到我的编译器设置时,我无法将所有数据读入数组,导致我的project.exe崩溃;否则,程序运行正常。
program Top_tier
integer, parameter:: n=145894, nz_num=4608168
integer ia(n+1), ja(nz_num)
double precision a(nz_num), rhs(n)
integer i
open (21, file='ia.dat')
do i=1, n+1
read(21,*) ia(i)
enddo
close(21)
open (21, file='a.dat')
do i=1, nz_num
read(21,*) a(i)
enddo
close(21)
open (21, file='ja.dat')
do i=1, nz_num
read(21,*) ja(i)
enddo
close(21)
open (21, file='b.dat')
do i=1, n
read(21,*) rhs(i)
enddo
close(21)
End
在我寻找解决方案的过程中,我发现最可能的原因是堆栈大小的限制,可以通过以下事实看出:如果我将nz_num设置为小于或等于26561,程序将运行正常。一种可能的解决方案是设置环境变量以增加stacksize,但程序无法识别何时键入" setenv"或"出口" OMP_STACKSIZE进入程序。难道我做错了什么?有关如何解决这个问题的建议吗?
谢谢!
答案 0 :(得分:1)
您正在堆栈上分配a
,rhs
,ia
ja
,这就是您首先耗尽堆栈空间的原因。我建议总是在堆上分配大型数组:
integer, parameter:: n=145894, nz_num=4608168
integer, dimension(:), allocatable :: ia, ja
double precision, dimension(:), allocatable :: a, rhs
integer i
allocate(ia(n+1), ja(nz_num))
allocate(a(nz_num), rhs(n))
! rest of your code...
deallocate(ia, ja)
deallocate(a, rhs)
不是直接声明一个特定大小的四个数组(导致它们在堆栈上分配),而是将它们声明为可分配的并给出数组的形状。再向下,您可以将阵列分配到所需的大小。可以在运行时选择此大小。这意味着,如果您从文件中读取数组,则还可以在文件开头存储数组的大小,并将其用于分配调用。 最后,与动态分配的内存一样,当您不再需要它们时,不要忘记取消分配它们。
编辑: 而且我忘了说这与openmp没有任何关系,除了openmp线程可能有很小的堆栈大小限制(在这种情况下它只是openmp主线程)。