0

Fortran 2003 との互換性を維持しながら、可能な限り OOP の哲学に従って編成したい Fortran モジュールがあります。一部のデータで動作します。この関数 do_F はこれらの一時バッファーを使用しますが、いくつかの補助型にも依存します。

バッファを型に入れ、必要に応じて初期化/解放する必要があることは明らかです。ただし、do_F の各呼び出しには複数の引数が必要なため、どの設計戦略を使用するのが最適かは確信しています。

より具体的には、次の実装を検討してください。

  1. 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. do_F が必要とする型へのポインターを保存します。

     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コンパイラはそれについて文句を言いませんでしたが、関数が戻った後、intent(IN)が適切に定義されなくなったと聞きました
  2. このスキームをポインターで使用すると、パフォーマンスが低下しますか? これらの aux_ptr に書き込んでいない場合でも、コンパイラはケース 1 と同様にコードを最適化できますか?

いくつかのメモ:

  1. 関数 do_F は最大 100 回呼び出され、各呼び出しには数分かかり、大きな配列を操作します。
  2. do_F とは別に、同じデータを操作し、同じ補助変数を使用する do_G および do_H 関数もあります。そのため、そもそも関数に渡す変数の数を減らしたいと考えていました。
  3. すべての aux 変数を 1 つの型にまとめたくはありません。なぜなら、それらは大規模な HPC コードの残りの部分で使用されるからです。

ありがとう!

4

1 に答える 1

2

インテントIN変数は、呼び出し前であれば、戻り後に明確に定義されます。プロシージャはそれらを変更することはできません。例外は、ポインター変数の値です。この場合、ターゲットの値を変更できますが、intent(IN)ポインターダミー引数のポインターの関連付けステータスは変更できません。

効率についてはよくわかりませんが。バージョン2は、簡単に読んだ後の方が見栄えがします。

于 2012-04-20T05:45:00.207 に答える