我正在使用 Fortran 语言中的矩阵和向量进行基本的线性代数计算。我已将编译器从 gfortran 更改为 ifort,我发现当我的矩阵变得太大时(特别是当它们的大小为 724 x 724,类型为复杂双精度时),我会收到以下错误(分段错误):
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
dummy 000000000040C9DA Unknown Unknown Unknown
libpthread-2.28.s 00007FB2CAB57CE0 Unknown Unknown Unknown
dummy 0000000000403D57 Unknown Unknown Unknown
dummy 0000000000402B22 Unknown Unknown Unknown
libc-2.28.so 00007FB2CA7BACF3 __libc_start_main Unknown Unknown
dummy 0000000000402A2E Unknown Unknown Unknown
我成功地将问题归结为这个最小的程序:
program dummy
use ifport
use iso_c_binding, dp => c_double, ip => c_int, dcp => c_double_complex
implicit none
integer (ip) :: dim
complex(dcp), dimension(:,:), allocatable :: U
write (*,*) "dim"
read (*,*) dim
print*,""
print *, "Allocating U."
allocate(U(dim,dim))
print *, "dim = ", dim, "dim^2 = ", dim**2, "size(U) = ", size(U)
print *, "Building U..."
U = 0
print *, "U initialized (set to zero)."
print *, "Testing matrix multiplication matmul(U, U)"
U = matmul(U,U)
print *, "U built."
end program
使用
ifort dummy.f90 -o dummy
或 gfortran dummy.f90 -o dummy
进行编译(ifport 不与 gfortran 一起使用)。 -fpp -check all, bounds -warn all -pedantic
等附加标志不会提供有关错误来源的附加信息。
这对于使用 ifort 的
dim = 724
不起作用,而对于使用 gfortran 则适用于更大的尺寸(我已经测试了几千个没有问题)。一旦执行矩阵乘法就会出现错误。事实上,即使在dim = 10000
,我在两个程序中分配第一个矩阵都没有问题,但使用ifort我总是得到分段错误错误(尽管使用gfortran它非常慢,尽管预期这些大小 - 我还没有检查矩阵乘法的结果在任何情况下都是正确的)。
此外,该程序已在两台不同的机器上运行,尽管我预计使用 ifort 的机器不会出现内存问题,因为通过
free
和 cat /proc/cpuinfo/
的简单计算,我有 72 个处理器,每个处理器大约有 10GB 内存(目前没有其他人在使用这个集群)。
因此,通过手动计算,复数双精度类型的矩阵需要具有维度 sqrt(10 * 10^9 / 16) ~ 25000
才能完全填满一个处理器的内存,而我距离这个还差得很远。
错误的根源是什么?由于它很通用,我还没有理解原因,以及 gfortran 和 ifort 之间的不一致。使用不同机器和编译器版本进行测试也将非常感激。谢谢。
通过使用 allocate 的 stat= 和 errmsg= 子句,您可能会得到信息更丰富的错误消息。