Fortran 使用ifort进行阵列复制的程序崩溃

Fortran 使用ifort进行阵列复制的程序崩溃,fortran,intel-fortran,fortran95,Fortran,Intel Fortran,Fortran95,此程序在MacOSX Lion和ifort(ifort)12.1.0 20111011上因非法指令: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

此程序在MacOSX Lion和ifort(ifort)12.1.0 20111011上因
非法指令: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 20130上确认相同的行为

显然,Linux和ifort 12.1.5没有问题

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

ifort-Wl,-stack\u size,0x40000000,-stack\u addr,0xf0000000 test.f90

但我还是犯了同样的错误。增加ulimit-s来解决同样的问题

编辑2:我做了更多的调试,显然问题发生在阵列拼接操作时

      b(:, 1:3600) = a(:, 1:3600)
涉及可疑的接近16M数据的值

我正在比较生成的操作码,但是如果有一种方法可以看到一种更具沟通性的中间代码形式,我将非常感激。

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

实型,可分配::a(:,:),b(:,:)

在我看来,给指针分配一个浮点数是可疑的。

您的程序是正确的(尽管如果您不需要重新指向指针,我更希望它是可分配的)。问题是ifort默认情况下会将所有数组临时对象放置在堆栈上,无论它们有多大。在这里执行的复制操作似乎需要一个临时数组。要解决ifort愚蠢的默认行为,请在编译时始终使用-heap arrays标志。即

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

堆后面的数组数是它应该开始使用堆的阈值。对于低于此值的尺寸,将使用堆栈。我在这里选择了一个很低的数字——你可能可以安全地使用较高的数字。理论上,堆栈阵列速度更快,但差异通常可以忽略不计。我希望英特尔能纠正这种行为。其他编译器对此设置都有合理的默认设置。

我在Mac Snow Leopard上的ifort 12.1.1.246中也得到了“非法指令”。我建议在英特尔Fortran论坛上报告或提交错误报告。也许它是在12.1.5中修复的?我在Mac Snow Leopard上通过iPort 12.0.3获得它。也许这个错误已经存在了一段时间……显然,(某些)linux机器上也存在问题:CentOS 5.5和ifort 12.1上的代码SEGFULTS。在fortran中为分配的指针分配一个数字没有什么错。Fotran指针与C指针不同,除了=>运算符和相关的内置指针外,它们的行为大多类似于可分配数组。