2016-03-23 9 views
2

Iは、ISO-C結合を使用して、FORTRANとCの間にいくつかのレガシーコードを架橋およびモジュール/インターフェースなどだFortran realがC floatと互換性があることを確認するにはどうすればよいですか?

通常、CにFortran配列を渡すとき私は別の配列にそれを単にコピーしたいです右iso-c結合型である。しかし、コードの中には、大きな(マルチGB)配列を渡す必要があるものがあります。この場合、コピーは分かりません。また、第三者コードから来ているため、Fortran配列のタイプを変更することはできませんreal(c_float)

しかし、私は例外をスローするのが喜んで、または基礎となるFortran配列がC浮動小数点ベースのAPIと互換性がない場合、コンパイルに失敗します。

デフォルトのrealがコンパイル時(または実行時)にC floatまたはdoubleと互換性があるかどうかを確認する方法はありますか?

私はintel FortranとCコンパイラを使用しています。

+0

なぜマルチGBアレイをコピーするのが合理的ではないと思いますか?ターゲットとするハードウェアのタイプ – wallyk

+0

@wallyk主に、私はすでにマシン上のメモリ制限に近いところで動いているからです。使用されているメモリにさらに4GBを追加することは、アプリケーションをダウンさせるか、スワップに私を押し込むことになります。どちらも受け入れられません。 –

+0

Fortranコンパイラのマニュアルを見ることをお勧めします。しかし、yore(Fortran 77とも呼ばれる)の時代、REALは倍精度用の「REAL * 8」とは対照的に「REAL * 4」でした。それは倍精度ですか? - Fortran REALがC floatと同じである可能性は非常に高いです。そして、Fortran REALがCダブルであることが判明した場合は、コピーされていないアレイを使用することができますか?そうではありませんか? AFAICRでは、Cコードの配列を変更すると、Cのように呼び出し関数でも配列が変更されます。 –

答えて

3

デフォルトREALの種類とCのfloatと相互運用可能なREALの種類の比較は単純な整数比較に過ぎません。

コンパイルエラーまたはランタイムエラーをこの比較トリガーにすることができます。 Fortranのプロセッサはそれと相互運用REALのない種類を持っていない場合

USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_FLOAT  

! -99 is never a valid kind - so this will fail at compile time 
! if the test condition is false. 
REAL(MERGE(KIND(1.0), -99, C_FLOAT == KIND(1.0)) :: dummy 

又は

IF (C_FLOAT /= KIND(1.0)) & 
    ERROR STOP 'Default REAL isn''t interoperable with FLOAT!!' 

C_FLOAT自体が負の値を有していてもよいです。

(一部15.0.xの場合は、次のifortのバージョンでは、コンパイル時のチェックバリアントのために使用することができます。

USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_FLOAT 
INTEGER, PARAMETER :: dummy_rk = MERGE(C_FLOAT, -99, KIND(1.0) == C_FLOAT) 
! -99 is never a valid kind - so this will fail at compile time 
! if the test condition is false. 
REAL(dummy_rk) :: dummy 
+0

コンパイル時のチェックのために、私は 'エラー#6683を取得します:種類の型パラメータはコンパイル時定数でなければなりません。 [MERGE] ' –

+0

@MichaelAnderson' dummy'変数の種類を指定する式は、F2003サポートが必要な式です。私はあなたが最近のバージョンのリリースを使用していないと思う。それは私のために16.0.2で動作します。 – IanH

+0

うん、今は15で立ち往生してください。だから、今のところ実行時のバージョン –

0

いくつかの問題があります

  • Cのfloatは次のように渡されます。 double C関数のパラメータと式の評価。これは、float(実際には32ビットの浮動小数点数を使用)と定義された変数を含む構造体または配列へのポインタを渡すことによって簡単に克服されます。

  • インテルのFortranには、実際のフレーバーがいくつかあります:real*4,real*8、およびreal*16です。デフォルトでは(コンパイラの設定によってはこれらが変わることがあります)、realは実数* 4、double precisionreal*8です。 documentationを参照してください。

  • Cのlong doubleタイプは、それが実装された場合—は、それは、x86上の式の中間値に対して使用を行いreal*10 —あろうインテルFortran、には相当するものはありません。

  • もちろん、C対Fortranのメジャー列対マイナー列配列レイアウトの問題(2次元配列以上)があります。

それが私だったら、私は知られているのFortranからCからのデータ(1.0、2.0、3.0、4.0、...)とその逆とを渡し、テストを作成することで、開発のための道を切り開くだろうと思います値を印刷するか、値を比較してください。非整数を使用する場合は、必ず適切なイプシロンの比較を使用してください:

  if (abs (c_val - fortran_val) > 0.00001) error(); 
関連する問題