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

Ste*_*ini 6 fortran fortran95 intel-fortran

该程序Illegal instruction: 4在MacOSX Lion和ifort(IFORT)12.1.0 20111011上崩溃

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 
Run Code Online (Sandbox Code Playgroud)

同一个程序与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)
Run Code Online (Sandbox Code Playgroud)

涉及可疑接近16 M数据的值.

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

ama*_*rea 6

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

ifort -o test test.f90 -heap-arrays 1600
Run Code Online (Sandbox Code Playgroud)

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


Nor*_*t S 1

使用“可分配”而不是“指针”。

真实的、可分配的 :: a(:,:), b(:,:)

对我来说,将浮点数分配给指针看起来很可疑。

  • 在 Fortran 中将数字分配给已分配的指针没有任何问题。Fotran 指针与 C 指针不同,除了 => 运算符和关联的内置函数之外,其行为大多类似于可分配数组。 (2认同)