使用ifort进行数组复制的程序崩溃

时间:2012-08-28 21:07:14

标签: fortran intel-fortran fortran95

此程序在MacOSX Lion和ifort(IFORT)12.1.0 20111011

上与Illegal instruction: 4崩溃
program foo
      real, pointer :: a(:,:), b(:,:)
      allocate(a(5400, 5400))
      allocate(b(5400, 3600))
      a=1.0
      b(:, 1:3600) = a(:, 1:3600)

      print *, a
      print *, b

      deallocate(a)
      deallocate(b)

end program 

同样的程序适用于gfortran。我没有看到任何问题。有任何想法吗 ?展开副本并对列执行显式循环适用于两个编译器。

请注意,使用allocatable而不是指针我没有问题。

如果语句位于模块内部,则行为相同。 我在ifort(IFORT)12.1.3 20120130上确认了相同的行为。

显然,Linux和ifort 12.1.5没有问题

我尝试使用以下链接选项增加堆栈大小

ifort -Wl,-stack_size,0x40000000,-stack_addr,0xf0000000 test.f90

但我仍然得到同样的错误。增加ulimit -s到同样的问题。

编辑2:我做了一些调试,显然当数组拼接操作时会出现问题

      b(:, 1:3600) = a(:, 1:3600)

涉及一个可疑接近16 M数据的值。

我正在比较所产生的操作码,但如果有办法看到更具交际性的中间代码形式,我很乐意欣赏它。

2 个答案:

答案 0 :(得分:5)

你的程序是正确的(虽然如果你不需要能够重新指定它,我宁愿分配给指针)。问题是ifort默认将所有阵列临时数放在堆栈上,无论它们有多大。并且它似乎需要一个临时的数组用于您在此处执行的复制操作。要解决ifort的愚蠢默认行为,始终在编译时使用-heap-arrays标志。即。

ifort -o test test.f90 -heap-arrays 1600

-heap-arrays背后的数字是应该开始使用堆的阈值。对于低于此值的尺寸,使用堆栈。我在这里选择了一个非常低的数字 - 你可以安全地使用更高的数字。理论上,堆栈阵列更快,但差异通常完全可以忽略不计。我希望英特尔能解决这个问题。每个其他编译器都具有此设置的合理默认值。

答案 1 :(得分:1)

使用“allocatable”而不是“pointer”。

real,allocatable :: a(:,:),b(:,:)

为指针指定浮点数看起来很可疑。