为什么当矩阵维度过大(在 ifort 中)时,我在此程序中会遇到分割故障问题?

Why do I get a segmentation fault problem in this program when the matrix dimension is too large (in ifort)?

提问人:Another User 提问时间:10/2/2023 最后编辑:Another User 更新时间:10/2/2023 访问量:66

问:

我正在 Fortran 中使用矩阵和向量进行基本的线性代数计算。我已将编译器从 gfortran 更改为 ifort,我发现当我的矩阵变得太大时(特别是当它们的大小为 724 x 724 时,类型为 complex double),我会出现以下错误(分割错误):

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

使用 或 编译(ifport 不与 gfortran 一起使用)。其他标志(例如)不会提供有关错误源的其他信息。ifort dummy.f90 -o dummygfortran dummy.f90 -o dummy-fpp -check all, bounds -warn all -pedantic

这不再适用于 ifort,而它适用于 gfortran 的更大尺寸(我已经测试了几千个没有问题)。一旦执行矩阵乘法,就会出现错误。事实上,即使在我用两个程序分配第一个矩阵都没有问题,但是使用 ifort 我总是得到分割错误错误(尽管使用 gfortran 它非常慢,尽管预计会有这些大小 - 我没有检查矩阵乘法的结果是否正确在任何情况下)。dim = 724dim = 10000

此外,该程序已在两台不同的机器上运行,尽管我不希望使用 ifort 的机器出现内存问题,因为通过简单的计算,我有 72 个处理器,每个处理器都有 ~10GB 内存(目前没有其他人使用这个集群)。 因此,通过挥手计算,复数双精度类型的矩阵需要具有维度才能完全填满一个处理器的内存,而我远未达到这个水平。freecat /proc/cpuinfo/sqrt(10 * 10^9 / 16) ~ 25000

错误的根源是什么?由于它非常通用,我还没有设法理解原因,以及 gfortran 和 ifort 之间的不一致。使用不同的机器和编译器版本进行测试也将非常受欢迎。谢谢。

编译器错误 fortran 矩阵乘法 gfortran intel-fortran

评论


答:

1赞 PierU 10/2/2023 #1

该语句需要一个大小为 的隐藏临时数组。默认情况下,ifort 编译器将分配堆栈上的所有临时数组(大小有限),而 gfortran 编译器会分配堆上的大型数组(仅受机器上可用内存的限制)。U = matmult(U,U)U

所以你这里有 2 个解决方案:

  • 增加堆栈大小。在 linux 上,键入命令以删除堆栈的任何大小限制ulimit unlimited
  • 使用 ifort 选项,该选项强制在堆上分配所有临时(和自动)数组-heap-arrays

评论

0赞 Another User 10/2/2023
它现在按预期工作,非常感谢。这个问题一直让我发疯。我想这就是我缺乏计算机和编译器基础知识的地方(因为我对“堆栈”与“堆”几乎一无所知)。
0赞 PierU 10/2/2023
对于堆栈与堆:stackoverflow.com/questions/79923/...