2

mex を使用して matlab からいくつかの fortran コード (f90) をリンクしていますが、時々 matlab がフリーズします。

以前は、データ型の不一致 (integer*4 と integer*8 など) が原因でフリーズが発生していました。

リンクしているコードには多くの暗黙的に定義された変数が含まれているため、たまにしか発生しない非表示のデータ型の競合があるかどうか疑問に思っています。

フリーズの原因としてデータ型の不一致を排除するために、コンパイラですべての変数を明示的に宣言する必要があるようにしたいと考えています。

質問:

  1. コンパイル時にすべての変数を明示的に宣言するよう gfortran に要求するにはどうすればよいですか? それができない場合、少なくとも警告を受け取る方法はありますか?

  2. すべてのアーキテクチャで特定の種類として gfortran によって解釈される「実際の」データ型はありますか? もしそうなら、それはどれですか (real*4, real*8, ...)?

  3. gfortran に「実際の」データ型を特定の種類、たとえば「real*4」として解釈させる方法はありますか?

  4. matlab でコンパイルされた mex ルーチンから呼び出されたときに fortran コードがフリーズする理由 (データ型の不一致以外) に関するアイデアはありますか?

助けてくれてありがとう。

これを理解するまで、暗黙的に定義されたすべての変数をリストしようとする多くのコード行を調べます。言うまでもなく、このような退屈な仕事から解放してくれる人には、とても感謝しています...

一番、

G.

4

4 に答える 4

2

既に述べたように、ソース コードでは暗黙的な noneを使用できます。利点は、これがすべてのコンパイラに移植できることです。

gfortran では、コンパイラ オプション-fimplicit-noneを使用できます。この利点は、暗黙的な none を含めるのを忘れた場合でも、明示的に入力するのを忘れた変数をキャッチできることです。他のほとんどのコンパイラには同様のオプションがあります。

どちらも強く推奨されます -- 暗黙の型付けは有害であり、タイプミスによって意図しない変数が作成される可能性があります。

単純な「本物」が何を意味するかは、コンパイラ次第です。特定の要件がある場合は、より具体的な宣言を使用することをお勧めします。最良の方法は、選択された実際の種類の組み込み関数を使用してパラメーターを定義し、それを使用することです。同様の議論については、Fortran を参照してください: integer*4 vs integer(4) vs integer(kind=4)

于 2010-08-24T19:23:16.233 に答える
2

IMPLICIT NONEおよびコンパイラオプションは既に述べました。

浮動小数点演算について話しましょう。問題は、(ここで述べた ss ) MATLAB は、 IEEE® 標準 754に従って倍精度 (または倍精度) と単精度 (または単精度) の両方のデータ型を構築しますが、Fortran 標準ではデフォルトと倍精度実数を必要としません。この規格に適合すること。ご覧のとおり、標準ドキュメントでは別の名前も使用されています (デフォルトは実数で、単精度ではありません)。

MODULE kinds

  IMPLICIT NONE

  INTEGER, PARAMETER :: fortran_default = kind(0.0)
  INTEGER, PARAMETER :: fortran_double = kind(0.0D0)
  INTEGER, PARAMETER :: ieee_single = selected_real_kind(7, 38)
  INTEGER, PARAMETER :: ieee_double = selected_real_kind(15, 307)

END MODULE kinds

カインド仕様の最初の 2 つの文字列では、デフォルトの実数と倍精度の実数のカインドを取得する便利な方法を使用しました。次の 2 種類は、前述の IEEE 規格に対応しています。

PROGRAM main

  USE kinds

  IMPLICIT NONE

  REAL(kind=ieee_single) :: is
  REAL(kind=ieee_double) :: id
  REAL(kind=fortran_default) :: fs
  REAL(kind=fortran_double) :: fd

  PRINT *, kind(is), precision(is), range(is)
  PRINT *, kind(id), precision(id), range(id)
  PRINT *, kind(fs), precision(fs), range(fs)
  PRINT *, kind(fd), precision(fd), range(fd)

END PROGRAM main 

私のマシン (Mac OS X 10.6、gfortran 4.5.1) での出力は次のとおりです。

   8          15         307
   8          15         307
   4           6          37
   8          15         307

したがって、Fortran のデフォルトの実数種は、IEEE 標準の単精度浮動小数点数種と等しくありません。

そのため、バグの原因になる可能性があります。精度がどこかで失われ、一部の変数が 0.0 よりわずかに大きい/小さい代わりに 0.0 に等しくなり、この値 (正確に 0.0) で除算します。まあ、それはプログラムをフリーズすることができます。

于 2010-08-24T20:36:50.337 に答える
1
  1. を追加することにより、すべての変数を明示的に宣言するように要求できますimplicit none
  2. デフォルトの「実際の」データ型はreal*4です。
  3. コマンドラインフラグ-fdefault-real-8を使用して、宣言されたすべての変数を強制real的にreal*8

注(より多くのコードを作成するため、必ずしも現在のバグを解決しようとはしません):Fortran 90コードを使用している場合は、または構文ではなく、またはgfortranreal(kind=4)を使用できます。コマンドラインフラグを使用して実数または整数のサイズを設定するのではなく、変数を使用して適切な数値を保持します(使用するすべてのコンパイラがサポートしているため、通常は4または8を使用しますが、必要に応じて非常にポータブルで、ルーチンを使用する必要があります)real(kind=8)real*4real*8integer, parameter :: REAL_SIZEselected_real_kind

于 2010-08-24T18:56:16.137 に答える
0

これらの1つは、Fortran 77以降、ほとんどのコンパイラーで機能します。

implicit none

また

implicit undefined(a-z)

Realアーキテクチャに依存します。デフォルトのサイズは通常、コマンドラインオプションで変更できます。

Matlabとのリンクの経験はありません。

于 2010-08-24T18:55:55.013 に答える