TABLE OF CONTENTS


ABINIT/m_pstat [ Modules ]

[ Top ] [ Modules ]

NAME

 m_pstat

FUNCTION

 Interface to the /proc/{pid}/status file available on Linux.

COPYRIGHT

  Copyright (C) 2017-2024 ABINIT group (MG)
  This file is distributed under the terms of the
  GNU General Public License, see ~abinit/COPYING
  or http://www.gnu.org/copyleft/gpl.txt .

SOURCE

16 #if defined HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19 
20 #include "abi_common.h"
21 
22 module m_pstat
23 
24  use defs_basis
25  use m_abicore
26  use m_errors
27  use, intrinsic :: iso_c_binding
28  use m_yaml
29 
30  use m_fstrings, only : find_and_select
31  use m_clib,     only : clib_getpid
32 
33  implicit none
34 
35  private

m_pstat/pstat_from_file [ Functions ]

[ Top ] [ m_pstat ] [ Functions ]

NAME

  pstat_from_file

FUNCTION

 Init object from file (useful for debugging).

SOURCE

139 subroutine pstat_from_file(pstat, filepath)
140 
141 !Arguments ------------------------------------
142  class(pstat_t),intent(inout) :: pstat
143  character(len=*),intent(in) :: filepath
144 
145 !Local variables-------------------------------
146  integer :: unit, ierr
147  character(len=500) :: line
148  integer :: istart, istop, iostat
149 ! *************************************************************************
150 
151  pstat%ok = .False.
152  pstat%filepath = filepath
153 
154  open(newunit=unit, file=trim(pstat%filepath), action="read", status="old", iostat=ierr, iomsg=pstat%iomsg)
155  if (ierr /= 0) then
156    close(unit); return
157  end if
158 
159  do
160    read(unit, "(a)", iostat=ierr, end=10, iomsg=pstat%iomsg) line
161    if (ierr > 0) then ! EOF
162      close(unit); return
163    end if
164 
165    ! Parse useful integers
166    if (index(line, "Pid:") == 1) call get_int(line, pstat%pid)
167    if (index(line, "Threads:") == 1) call get_int(line, pstat%threads)
168    if (index(line, "FDSize:") == 1) call get_int(line, pstat%fdsize)
169 
170    ! Parse memory entries
171    if (index(line, "VmRSS:") == 1) call get_mem_mb(line, pstat%vmrss_mb)
172    if (index(line, "VmPeak:") == 1) call get_mem_mb(line, pstat%vmpeak_mb)
173    if (index(line, "VmStk:") == 1) call get_mem_mb(line, pstat%vmstk_mb)
174  end do
175 
176 10 close(unit)
177   pstat%ok = .True.
178   pstat%iomsg = ""
179 
180 contains
181 
182 subroutine get_mem_mb(str, mem_mb)
183  character(len=*),intent(in) :: str
184  real(dp),intent(out) :: mem_mb
185 
186  ! Generic mem entry has format:
187  !VmRSS: 2492 kB
188  real(dp) :: mem_fact
189  istart = index(str, ":") + 1
190  istop = find_and_select(str, &
191                         ["kB", "mB"], &
192                         [one/1024._dp, one], mem_fact, pstat%iomsg) !default=one,
193  ABI_CHECK(istop /= -1, pstat%iomsg)
194  read(str(istart+1:istop-1), fmt=*, iostat=iostat, iomsg=pstat%iomsg) mem_mb
195  ABI_CHECK(iostat == 0, pstat%iomsg)
196  mem_mb = mem_mb * mem_fact
197 end subroutine get_mem_mb
198 
199 subroutine get_int(str, out_ival)
200  character(len=*),intent(in) :: str
201  integer,intent(out) :: out_ival
202  istart = index(str, ":") + 1
203  read(str(istart+1:), fmt=*, iostat=iostat, iomsg=pstat%iomsg) out_ival
204  ABI_CHECK(iostat == 0, pstat%iomsg)
205 end subroutine get_int
206 
207 end subroutine pstat_from_file

m_pstat/pstat_from_pid [ Functions ]

[ Top ] [ m_pstat ] [ Functions ]

NAME

  pstat_from_pid

FUNCTION

   Init object from process identifier (main entry point for client code).

SOURCE

112 subroutine pstat_from_pid(pstat)
113 
114 !Arguments ------------------------------------
115  class(pstat_t),intent(out) :: pstat
116 
117 !Local variables-------------------------------
118  integer(c_int) :: pid
119  character(len=500) :: spid
120 ! *************************************************************************
121 
122  pid = clib_getpid()
123  write(spid, "(i0)") pid
124  spid = adjustl(spid)
125  call pstat%from_file('/proc/'//trim(spid)//'/status')
126 
127 end subroutine pstat_from_pid

m_pstat/pstat_mpi_max [ Functions ]

[ Top ] [ m_pstat ] [ Functions ]

NAME

  pstat_mpi_max

FUNCTION

INPUTS

OUTPUT

SOURCE

263 #if 0
264 
265 subroutine pstat_mpi_max(pstat, vmrss_mb, comm)
266 
267  class(pstat_t),intent(inout) :: pstat
268  real(dp),intent(out) :: vmrss_mb
269  integer,intent(in) :: comm
270  !logical,optional,intent(in) :: reload
271 
272  !integer :: ierr, int_list(5)
273  real(dp) :: real_list(3)
274 
275  call pstat%from_file(pstat%filepath)
276 
277  real_list = [pstat%vmrss_mb, pstat%vmpeak_mb, pstat%vmstk_mb]
278  !call xmpi_max_ip(real_list, comm, ierr)
279 
280  pstat%vmrss_mb = real_list(1)
281  pstat%vmpeak_mb = real_list(2)
282  pstat%vmstk_mb = real_list(3)
283 
284 end subroutine pstat_mpi_max

m_pstat/pstat_print [ Functions ]

[ Top ] [ m_pstat ] [ Functions ]

NAME

  pstat_print

FUNCTION

  Print object in Yaml format.

SOURCE

219 subroutine pstat_print(pstat, units, header, reload)
220 
221  class(pstat_t),intent(inout) :: pstat
222  integer,intent(in) :: units(:)
223  character(len=*),optional,intent(in) :: header
224  logical,optional,intent(in) :: reload
225 
226 !Local variables-------------------------------
227  character(len=500) :: header__
228  type(yamldoc_t) :: ydoc
229 ! *************************************************************************
230 
231  if (present(reload)) then
232    if (reload) call pstat%from_file(pstat%filepath)
233  end if
234 
235  header__ = "unknown"; if (present(header)) header__ = header
236  ydoc = yamldoc_open(header__) !, width=11, real_fmt='(3f8.3)')
237 
238  call ydoc%add_int("pid", pstat%pid)
239  call ydoc%add_int("threads", pstat%threads) !, comment="")
240  call ydoc%add_int("fdsize", pstat%fdsize) !, comment="")
241  call ydoc%add_real("vmrss_mb", pstat%vmrss_mb) !, comment="")
242  call ydoc%add_real("vmpeak_mb", pstat%vmpeak_mb) !, comment="")
243  call ydoc%add_real("vmstk_mb", pstat%vmstk_mb) !, comment="")
244  if (len_trim(pstat%iomsg) > 0) call ydoc%add_string("iomsg", trim(pstat%iomsg))
245 
246  call ydoc%write_units_and_free(units)
247 
248 end subroutine pstat_print

m_pstat/pstat_t [ Types ]

[ Top ] [ m_pstat ] [ Types ]

NAME

 pstat_t

FUNCTION

 This object stores the most important quantites reported in the /proc/{pid}/status file
 in particular the virtual memory VmRSS. See https://docs.kernel.org/filesystems/proc.html

 NB: This file is only available on Linux hence one should always check the value of pstat%ok
 before using quantities such as vmrss_mb.

 Usage:

   call pstat%from_pid()
   call pstat%print([std_out])
   ! reload data and print it
   call pstat%update()
   call pstat%print([std_out])

SOURCE

61  type, public :: pstat_t
62 
63   logical :: ok = .False.
64   ! False if stat file is not available
65 
66   integer :: pid = -1
67   ! Process identifier.
68 
69   integer :: threads = -1
70   ! number of threads.
71 
72   integer :: fdsize = -1
73    ! Number of file descriptor slots currently allocated
74 
75   real(dp) :: vmrss_mb = -one
76   ! Size of memory portions.
77   ! It contains the three following parts (VmRSS = RssAnon + RssFile + RssShmem)
78 
79   real(dp) :: vmpeak_mb = -one
80   ! Peak virtual memory size
81 
82   real(dp) :: vmstk_mb = -one
83   ! Size of stack segments
84 
85   character(len=fnlen) :: filepath = ""
86   ! Path of status file
87 
88   character(len=500) :: iomsg = ""
89   ! Error message returned when parsing filepath
90 
91  contains
92    procedure :: from_pid => pstat_from_pid     ! Init object from process identifier (main entry point).
93    procedure :: from_file => pstat_from_file   ! Init object from file (useful for debugging).
94    procedure :: print => pstat_print           ! Print object.
95  end type pstat_t