Fortran 2003 との互換性を維持しながら、可能な限り OOP の哲学に従って編成したい Fortran モジュールがあります。一部のデータで動作します。この関数 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
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コンパイラはそれについて文句を言いませんでしたが、関数が戻った後、intent(IN)が適切に定義されなくなったと聞きました
- このスキームをポインターで使用すると、パフォーマンスが低下しますか? これらの aux_ptr に書き込んでいない場合でも、コンパイラはケース 1 と同様にコードを最適化できますか?
いくつかのメモ:
- 関数 do_F は最大 100 回呼び出され、各呼び出しには数分かかり、大きな配列を操作します。
- do_F とは別に、同じデータを操作し、同じ補助変数を使用する do_G および do_H 関数もあります。そのため、そもそも関数に渡す変数の数を減らしたいと考えていました。
- すべての aux 変数を 1 つの型にまとめたくはありません。なぜなら、それらは大規模な HPC コードの残りの部分で使用されるからです。
ありがとう!