2012-04-20 5 views
0

Fortranモジュールは、OOPの考え方に従ってできるだけ整理したいと考えていますが、Fortran 2003と互換性があります。一時的な配列バッファを解放し、(b)いくつかのデータで動作する関数do_Fを提供する。この関数do_Fはこれらの一時バッファを使用しますが、いくつかの補助型にも依存します。OOP Fortran:インテント(IN)変数へのポインタの保存

私はバッファを型に入れ、必要に応じて初期化/解放する必要があることは明らかです。しかし、do_Fを呼び出すたびにいくつかの議論が行われるので、私はどのデザインを使うのが最適かを確信しています。

  1. がdo_Fがdo_Fが

    を必要とする型へのポインタ

    type object_t 
        ! lots of private buffers 
        real, allocatable :: buf1(:,:,:), buf2(:,:,:), etc. 
    end type object_t 
    
    subroutine init_object(this) 
        type(object_t), intent(INOUT) :: this 
    
        allocate(this%buf1(..., ..., ...)) 
        !... 
    end subroutine init_object 
    
    subroutine do_F(this, data, aux1, aux2, ..., auxN) 
        type(object_t), intent(INOUT) :: this 
        type(data_t), intent(INOUT) :: data 
        type(aux1_t), intent(IN) :: aux1 
        !... 
    
        !do stuff on data using the buffers and values stored 
        ! in aux1 .. auxN 
    end subroutine do_F 
    
  2. 保存呼び出されるたびに種類の多数を渡します

    は以下の実装を検討し、より具体的には、

    type object_t 
        ! lots of private buffers 
        real, allocatable :: buf1(:,:,:), buf2(:,:,:), etc. 
    
        ! pointers to auxiliary types 
        type(aux1_t), pointer :: aux1_ptr 
        !... 
    end type object_t 
    
    subroutine init_object(this, aux1, aux2, ..., auxN) 
        type(object_t), intent(INOUT) :: this 
        type(aux1_t), intent(IN), target :: aux1 
        !... 
    
        allocate(this%buf1(..., ..., ...)) 
        !... 
    
        this%aux1_ptr => aux1 
        !... 
    end subroutine init_object 
    
    subroutine do_F(this, data) 
        type(object_t), intent(INOUT) :: this 
        type(data_t), intent(INOUT) :: data 
    
        !do stuff on data using the buffers and values stored 
        ! in this%aux1_ptr .. this%auxN_ptr 
    end subroutine do_F 
    

私の具体的な質問は次のとおりです。

  1. 実装#2は有効ですか? PGIコンパイラはそれについて文句を言っていませんでしたが、関数が返された後にインテント(IN)が正しく定義されていないと聞きました
  2. このスキームをポインタで使用するとパフォーマンスが低下しますか?たとえ私がこれらのaux_ptrに書き込まなくても、コンパイラは#1の場合と同様に自分のコードを最適化できるでしょうか?

いくつかの注意:

  1. 機能do_Fは〜100倍と呼ばれ、各呼び出しは数分かかり、大きな配列で動作します。
  2. do_F以外に、do_G関数とdo_H関数もあり、同じデータを操作し、同じ補助変数を使用します。そのため、最初に関数に渡される変数の数を減らしたかったのです。
  3. すべてのaux変数を1つのタイプにまとめる必要はありません。なぜなら、それらは大規模なHPCコードの残りの部分で使用されているからです。

ありがとう!

答えて

2

インテントIN変数は、コールの前であった場合、リターン後に明確に定義されます。プロシージャはそれらを変更することはできません。ただし、ターゲットの値を変更できるポインタ変数の値は例外ですが、intent(IN)ポインタ仮引数のポインタの関連付け状態は変更できません。

私は効率についてよく分かりません。バージョン2は素早く読んだ後でよりよく見えます。

+0

downvoterに感謝します。私はそれを修正するためにこれを実際に探していましたが、見つけられませんでした。本当の状態を指しているイアンに感謝します。 –

関連する問題