fortranプログラムってメモリなくなると「突然segmentation fault」でおちる。
現代にしてこの仕様!!!研究室のqsubシステムとかだと、1ノードを分け合って使うこともあるーメモリの奪い合いが起こって共倒れ、ということにもなるんじゃないかな。どっちかが倒れてくれたら、どっちかは生き延びるのかな。動的メモリ確保なので、仕方ない、といえば仕方ないのかもしれんけど。
いずれにせよ、動的なメモリ管理をしないと計算のバッチサイズを自動化できない。一個ずつ計算して論文にしてる時代は幸せ?だったけど、1000ケースを一括処理できるようにしていかないといけない。
数値計算は、「メモリの許す範囲でメモリは目一杯使い、許さなければon-the-flyでやる」というもの。計算の速さは演算速度xメモリ量x通信速度で決まってくる(ディスクは通信速度〜0なのでスワップはまずい)。
Cにはgetrusageがある。これをfortranから呼び出せば良い。
以下、試してみてください。デバッグに使ってメモリリークを探せました。
(GBになるとinteger(4)で対応できないので注意)。
copilotがだいぶと教えてくれた。
もっと良い方法があれば教えてください!
(たぶん)disk swapがおこると以下のような感じで進んでいく. 540GB/32=16.8GBあるはずなのに
よくわからない。
hhmmss GB
goto iwimag ixx niw=0 10 DateTime= 20240721 221800.98 memused 8.499
goto iwimag ixx niw=1 10 DateTime= 20240721 230358.12 memused 8.559
goto iwimag ixx niw=2 10 DateTime= 20240722 005736.10 memused 8.559
goto iwimag ixx niw=3 10 DateTime= 20240722 010642.06 memused 8.559
goto iwimag ixx niw=4 10 DateTime= 20240722 011532.23 memused 8.559
goto iwimag ixx niw=5 10 DateTime= 20240722 012303.04 memused 8.559
goto iwimag ixx niw=6 10 DateTime= 20240722 013018.45 memused 8.559
goto iwimag ixx niw=7 10 DateTime= 20240722 013735.36 memused 8.559
goto iwimag ixx niw=8 10 DateTime= 20240722 014430.31 memused 8.559
goto iwimag ixx niw=9 10 DateTime= 20240722 015326.07 memused 8.559
goto iwimag ixx niw=10 10 DateTime= 20240722 020024.73 memused 8.559
endof CorrelationSelfEnergy DateTime= 20240722 020901.02 memused 8.559
---11回回しているが、7分の時もあれば45分かかる時もある。アカンな。
real(8) function memused() !in GB
use iso_c_binding
implicit none
type, bind(C) :: c_timeval
integer(c_long) :: tv_sec
integer(c_long) :: tv_usec
endtype c_timeval
type, bind(C) :: c_rusage
type(c_timeval) :: ru_utime
type(c_timeval) :: ru_stime
integer(c_long) :: ru_maxrss
integer(c_long) :: ru_ixrss
integer(c_long) :: ru_idrss
integer(c_long) :: ru_isrss
integer(c_long) :: ru_minflt
integer(c_long) :: ru_majflt
integer(c_long) :: ru_nswap
integer(c_long) :: ru_inblock
integer(c_long) :: ru_oublock
integer(c_long) :: ru_msgsnd
integer(c_long) :: ru_msgrcv
integer(c_long) :: ru_nsignals
integer(c_long) :: ru_nvcsw
integer(c_long) :: ru_nivcsw
end type c_rusage
interface
function getrusage(what,usage) bind(C, name="getrusage")
import :: c_int, c_long, c_rusage
integer(c_int) :: getrusage
integer(c_int), value :: what
type(c_rusage) :: usage
end function getrusage
end interface
type(c_rusage) :: usage
integer(c_int) :: ret
integer :: mpi__info
real(8)::k=1000
ret = getrusage(0,usage)
memused = usage%ru_maxrss/k**2 ! in GB
end function memused