6

このプログラムはIllegal instruction: 4MacOSXLionand ifort(IFORT)12.1.020111011でクラッシュします

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で動作します。問題ありません。何か案は ?コピーを展開し、列に対して明示的なループを実行すると、両方のコンパイラで機能します。

ポインタの代わりに割り当て可能であることに注意してください。問題はありません。

ステートメントがモジュール内にあるかどうかに関係なく、動作は同じです。ifort(IFORT)12.1.320120130でも同じ動作を確認します。

どうやら、Linuxとifort12.1.5では問題は発生しません

次のリンクオプションを使用してスタックサイズを増やしてみました

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

しかし、それでも同じエラーが発生します。ulimit-sを同じ問題に増やす。

編集2:もう少しデバッグを行いましたが、アレイのスプライシング操作時に問題が発生するようです

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

16Mのデータに疑わしいほど近い値が含まれます。

作成されたオペコードを比較していますが、よりコミュニケーションのとれた中間コード形式を見る方法があれば、喜んで感謝します。

4

2 に答える 2

6

あなたのプログラムは正しいです(ただし、再指定できる必要がない場合は、ポインターに割り当て可能にすることをお勧めします)。問題は、ifort がデフォルトで配列一時配列をすべてスタックに配置することです。そして、ここで行っているコピー操作のために一時的な配列が必要なようです。ifort のばかげたデフォルトの動作を回避するには、コンパイル時に常に-heap-arrays フラグを使用します。いえ

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

-heap-arrays の後ろの数字は、ヒープの使用を開始するしきい値です。これ以下のサイズの場合、スタックが使用されます。ここではかなり低い数値を選択しました。これより高い数値を使用しても問題はありません。理論的には、スタック配列の方が高速ですが、通常、その差はまったく無視できます。インテルがこの動作を修正してくれることを願っています。他のすべてのコンパイラには、この設定に適したデフォルトがあります。

于 2012-10-29T01:39:04.483 に答える
1

「ポインター」の代わりに「アロケータブル」を使用します。

実数、割り当て可能 :: a(:,:)、b(:,:)

ポインターに浮動小数点数を割り当てることは、私には疑わしいように見えます。

于 2012-10-28T23:50:29.697 に答える