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

该程序因非法指令而崩溃:MacOSX Lion和ifort上的4(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

同一个程序与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数据的值.

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

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

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

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

相关文章
相关标签/搜索