Fortranモジュールは、OOPの考え方に従ってできるだけ整理したいと考えていますが、Fortran 2003と互換性があります。一時的な配列バッファを解放し、(b)いくつかのデータで動作する関数do_Fを提供する。この関数do_Fはこれらの一時バッファを使用しますが、いくつかの補助型にも依存します。OOP Fortran:インテント(IN)変数へのポインタの保存
私はバッファを型に入れ、必要に応じて初期化/解放する必要があることは明らかです。しかし、do_Fを呼び出すたびにいくつかの議論が行われるので、私はどのデザインを使うのが最適かを確信しています。
が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
保存呼び出されるたびに種類の多数を渡します
は以下の実装を検討し、より具体的には、
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
私の具体的な質問は次のとおりです。
- 実装#2は有効ですか? PGIコンパイラはそれについて文句を言っていませんでしたが、関数が返された後にインテント(IN)が正しく定義されていないと聞きました
- このスキームをポインタで使用するとパフォーマンスが低下しますか?たとえ私がこれらのaux_ptrに書き込まなくても、コンパイラは#1の場合と同様に自分のコードを最適化できるでしょうか?
いくつかの注意:
- 機能do_Fは〜100倍と呼ばれ、各呼び出しは数分かかり、大きな配列で動作します。
- do_F以外に、do_G関数とdo_H関数もあり、同じデータを操作し、同じ補助変数を使用します。そのため、最初に関数に渡される変数の数を減らしたかったのです。
- すべてのaux変数を1つのタイプにまとめる必要はありません。なぜなら、それらは大規模なHPCコードの残りの部分で使用されているからです。
ありがとう!
downvoterに感謝します。私はそれを修正するためにこれを実際に探していましたが、見つけられませんでした。本当の状態を指しているイアンに感謝します。 –