我正在尝试在我的笔记本电脑上运行模拟程序(Linux 3.8.0-25-generic x86_64,Ubuntu 13.04)。
它编译好了,但是当我分配一些数组大小时,我得到:
forrtl:severe(179):无法在数组大小计算上分配数组溢出。\
Some googling about this message让我得出结论,这是因为我的程序内存不足而产生的。
为了检查这个假设,我试图将相同的数组分配给一个较小的维度,但仍然遇到同样的问题。
我接下来尝试的是增加堆栈内存,但仍然遇到同样的问题。
这是代码:
program memoria
implicit none
integer :: n,num
complex, dimension(:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:), allocatable :: ddptrj
n=4
num=21
allocate(ddptrj(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,num))
deallocate(ddptrj)
endprogram memoria
我该如何解决这个问题?
答案 0 :(得分:2)
Fortran 2008标准定义了maximum rank of 15。 ifort
allows 31。从May 2013 开始,gfortran
仍然不支持超过7个维度。所以 - 如果你真的需要所有22个维度,请使用ifort
- 但请注意,此功能是标准的扩展,其他编译器可能无法编译您的代码。
编辑:总结评论中的讨论:
有两个问题 - 一个与最大尺寸有关,另一个与数组尺寸有关。
对于不允许22维的编译器,可以使用一个大的1级数组来保存所有元素,并使用步长自己计算元素内的索引。
内部所有数组都在内存中连续存储 - 将其视为 大量排名第一和大小N * M * ... Fortran实际存储了 以列主格式生成的数组。因此存储矩阵Z(NxM) 作为向量A(N * M),并且通过计算对元素的访问 步幅:Z(3,4)在指数A(M *(4-1)+3)。请注意,内存是 两个阵列都一样!
下一个问题是数组大小:
对于n = 2,代码可以工作,因为它适合内存: 复杂的2 ** 21 * 21 = 44040192(16字节),这相当于672 MB。在n = 4时 这变成4 ** 21 * 21,即1344TB。
答案 1 :(得分:0)
如果您使用的是需要22维的方法,那么您几乎肯定需要更改算法。正如人们在其他地方所指出的那样,你不仅会使用大量内存,而且如果你想对该数组中的所有元素做一些事情,那么运行时本身将变得非常庞大。
因为你正在使用Fortran,我的猜测是你正在查看22维度的某种参数空间,并记录每个参数组合的拟合度或可能性。在这种情况下,你应该考虑像MCMC这样的其他算法来探索空间。
但这只是一个猜测 - 如果你告诉我们你试图解决的潜在问题,人们可能会有更多的建议。