nfortでは,ユーザ定義演算子を用いた演算過程で作成される一時オブジェクトの寿命はどのようになっているでしょうか?
現在,ユーザ定義演算子を用いたプログラム(2次元の時間発展問題)を作成しており,問題規模を大きくする(1024x512)と,数百ステップほど進むとout of memoryが発生します.
他製品との比較で申し訳ありませんが,手元の計算機上で,gfortran, intel fortran, nag fortranを用いてコンパイルして試しても,計算の進行に伴ってメモリが増加することはありません.
ユーザ定義演算子を用いている処理をコメントアウトするとout of memoryが発生するまでの時間が長くなることから,ユーザ定義演算子,特に演算子内で生成した一時オブジェクトの解放に問題があるのでは?と推察しています.
生成される一時オブジェクトは,""allocatableな配列を成分に持つユーザ派生型"を成分に持つユーザ定義派生型"です.コードの要点だけを取り出すと,下記のようになります.
type(vector_type) :: u, v
v = u + dt*(-((u.dot.nabla)*u)) !<-こういう演算を頻繁に行うと,out of memoryになるまでの時間が短くなる
派生型や演算子の定義は,かなり省略していますが下記のようになります.詳しくは,2月10日提出のコードでご確認頂ければ幸いです.
type :: vector_type
real(real64), allocatable :: x(:, :)
real(real64), allocatable :: y(:, :)
contains
! 演算子のオーバーロード等
end type
! 演算の過程で作られる一時オブジェクトの型
type :: u_grad_type
type(vector_type) :: u
end type
! ユーザ定義演算子.dot.のインタフェースと関数
interface operator(.dot.)
procedure :: u_dot_nabla
end interface
function u_dot_nabla(u, nabla) result(u_grad)
class(vector_type), intent(in) :: u
class(nabla_type), intent(in) :: nabla ! 使わない
type(u_grad_type) :: u_grad
u_grad%u = u ! 一時オブジェクト u_gradを生成し,uの値をコピーして返却
end function u_dot_nabla
自身のコードでできる事があるかを調べており,final subroutineも実装はしてみましたが,効果がありませんでした.
一応,コンパイラの動作も確認しておきたいと考えて,質問をしています.
よろしくお願いします.
Posted by Degawa on 6 February 2023 at 11:05. |
|