(git:34ef472)
machine.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief Machine interface based on Fortran 2003 and POSIX
10 !> \par History
11 !> JGH (05.07.2001) : added G95 interface
12 !> - m_flush added (12.06.2002,MK)
13 !> - Missing print_memory added (24.09.2002,MK)
14 !> - Migrate to generic implementation based on F2003 + POSIX (2014, Ole Schuett)
15 !> \author APSI, JGH, Ole Schuett
16 ! **************************************************************************************************
17 MODULE machine
18  USE iso_c_binding, ONLY: c_char, &
19  c_int, &
20  c_ptr, &
21  c_null_char, &
22  c_associated
23  USE iso_fortran_env, ONLY: input_unit, &
24  output_unit
25  USE omp_lib, ONLY: omp_get_wtime
26  USE kinds, ONLY: default_path_length, &
28  dp, &
29  int_8
30 #if defined(__LIBXSMM)
31  USE libxsmm, ONLY: libxsmm_timer_tick, &
32  libxsmm_timer_duration, &
33  libxsmm_get_target_archid, &
34  libxsmm_x86_sse4
35 #endif
36 
37  IMPLICIT NONE
38 
39  ! Except for some error handling code, all code should
40  ! get a unit number from the print keys or from the logger, in order
41  ! to guarantee correct output behavior,
42  ! for example in farming or path integral runs
43  ! default_input_unit should never be used
44  ! but we need to know what it is, as we should not try to open it for output
45  INTEGER, PUBLIC, PARAMETER :: default_output_unit = output_unit, &
46  default_input_unit = input_unit
47 
48 #include "machine_cpuid.h"
49  ! Enumerates the target architectures or instruction set extensions.
50  ! A feature is present if within range for the respective architecture.
51  ! For example, to check for MACHINE_X86_AVX the following is true:
52  ! MACHINE_X86_AVX <= m_cpuid() and MACHINE_X86 >= m_cpuid().
53  ! For example, to check for MACHINE_ARM_SOME the following is true:
54  ! MACHINE_ARM_SOME <= m_cpuid() and MACHINE_ARM >= m_cpuid().
55  INTEGER, PUBLIC, PARAMETER :: &
56  machine_cpu_generic = cp_machine_cpu_generic, &
57  machine_x86_sse4 = cp_machine_x86_sse4, &
58  machine_x86_avx = cp_machine_x86_avx, &
59  machine_x86_avx2 = cp_machine_x86_avx2, &
60  machine_x86_avx512 = cp_machine_x86_avx512, &
61  machine_x86 = machine_x86_avx512 ! marks end of range
62  ! other arch to be added as needed e.g.,
63  !MACHINE_ARM_SOME = 2000
64  !MACHINE_ARM_ELSE = 2001
65  !MACHINE_ARM = MACHINE_ARM_ELSE
66  !MACHINE_PWR_???? = 3000
67 
68  PRIVATE
69 
70  PUBLIC :: m_walltime, m_datum, m_hostnm, m_flush, &
75 
76  INTERFACE
77  ! **********************************************************************************************
78  !> \brief Target architecture or instruction set extension according to compiler target flags.
79  !> \return cpuid according to MACHINE_* integer-parameter.
80  !> \par History
81  !> 04.2019 created [Hans Pabst]
82  ! **********************************************************************************************
83  PURE FUNCTION m_cpuid_static() BIND(C)
84  IMPORT :: c_int
85  INTEGER(C_INT) :: m_cpuid_static
86  END FUNCTION m_cpuid_static
87  END INTERFACE
88 
89  ! Flushing is enabled by default because without it crash reports can get lost.
90  ! For performance reasons it can be disabled via the input in &GLOBAL.
91  LOGICAL, SAVE, PUBLIC :: flush_should_flush = .true.
92 
93  INTEGER(KIND=int_8), SAVE, PUBLIC :: m_memory_max = 0
94 
95 CONTAINS
96 
97 ! **************************************************************************************************
98 !> \brief flushes units if the &GLOBAL flag is set accordingly
99 !> \param lunit ...
100 !> \par History
101 !> 10.2008 created [Joost VandeVondele]
102 !> \note
103 !> flushing might degrade performance significantly (30% and more)
104 ! **************************************************************************************************
105  SUBROUTINE m_flush(lunit)
106  INTEGER, INTENT(IN) :: lunit
107 
108  IF (flush_should_flush) FLUSH (lunit)
109 
110  END SUBROUTINE
111 
112 ! **************************************************************************************************
113 !> \brief returns time from a real-time clock, protected against rolling
114 !> early/easily
115 !> \return ...
116 !> \par History
117 !> 03.2006 created [Joost VandeVondele]
118 !> \note
119 !> same implementation for all machines.
120 !> might still roll, if not called multiple times per count_max/count_rate
121 ! **************************************************************************************************
122  FUNCTION m_walltime() RESULT(wt)
123  REAL(kind=dp) :: wt
124 
125 #if defined(__LIBXSMM)
126  wt = libxsmm_timer_duration(0_int_8, libxsmm_timer_tick())
127 #else
128  wt = omp_get_wtime()
129 #endif
130  END FUNCTION m_walltime
131 
132 ! **************************************************************************************************
133 !> \brief reads /proc/cpuinfo if it exists (i.e. Linux) to return relevant info
134 !> \param model_name as obtained from the 'model name' field, UNKNOWN otherwise
135 ! **************************************************************************************************
136  SUBROUTINE m_cpuinfo(model_name)
137  CHARACTER(LEN=default_string_length) :: model_name
138 
139  INTEGER, PARAMETER :: bufferlen = 2048
140 
141  CHARACTER(LEN=bufferlen) :: buffer
142  INTEGER :: i, icol, iline, imod, stat
143 
144  model_name = "UNKNOWN"
145  buffer = ""
146  OPEN (121245, file="/proc/cpuinfo", action="READ", status="OLD", access="STREAM", iostat=stat)
147  IF (stat == 0) THEN
148  DO i = 1, bufferlen
149  READ (121245, END=999) buffer(I:I)
150  END DO
151 999 CLOSE (121245)
152  imod = index(buffer, "model name")
153  IF (imod > 0) THEN
154  icol = imod - 1 + index(buffer(imod:), ":")
155  iline = icol - 1 + index(buffer(icol:), new_line('A'))
156  IF (iline == icol - 1) iline = bufferlen + 1
157  model_name = buffer(icol + 1:iline - 1)
158  END IF
159  END IF
160  END SUBROUTINE m_cpuinfo
161 
162 ! **************************************************************************************************
163 !> \brief Target architecture or instruction set extension according to CPU-check at runtime.
164 !> \return cpuid according to MACHINE_* integer-parameter.
165 !> \par History
166 !> 04.2019 created [Hans Pabst]
167 ! **************************************************************************************************
168  PURE FUNCTION m_cpuid() RESULT(cpuid)
169  INTEGER :: cpuid
170 #if defined(__LIBXSMM)
171  cpuid = libxsmm_get_target_archid()
172  cpuid = merge(min(machine_x86_sse4 + cpuid - libxsmm_x86_sse4, machine_x86), &
173  machine_cpu_generic, libxsmm_x86_sse4 .LE. cpuid)
174 #else
175  cpuid = m_cpuid_static()
176 #endif
177  END FUNCTION m_cpuid
178 
179 ! **************************************************************************************************
180 !> \brief Determine name of target architecture for a given CPUID.
181 !> \param cpuid integer value (MACHINE_*)
182 !> \return name or short name.
183 !> \par History
184 !> 06.2019 created [Hans Pabst]
185 ! **************************************************************************************************
186  FUNCTION m_cpuid_name(cpuid)
187  INTEGER :: cpuid
188  CHARACTER(len=default_string_length), POINTER :: m_cpuid_name
189 
190  CHARACTER(len=default_string_length), SAVE, TARGET :: name_generic = "generic", &
191  name_unknown = "unknown", name_x86_avx = "x86_avx", name_x86_avx2 = "x86_avx2", &
192  name_x86_avx512 = "x86_avx512", name_x86_sse4 = "x86_sse4"
193 
194  SELECT CASE (cpuid)
195  CASE (machine_cpu_generic)
196  m_cpuid_name => name_generic
197  CASE (machine_x86_sse4)
198  m_cpuid_name => name_x86_sse4
199  CASE (machine_x86_avx)
200  m_cpuid_name => name_x86_avx
201  CASE (machine_x86_avx2)
202  m_cpuid_name => name_x86_avx2
203  CASE (machine_x86_avx512)
204  m_cpuid_name => name_x86_avx512
205  CASE DEFAULT
206  m_cpuid_name => name_unknown
207  END SELECT
208  END FUNCTION m_cpuid_name
209 
210 ! **************************************************************************************************
211 !> \brief returns the energy used since some time in the past.
212 !> The precise meaning depends on the infrastructure is available.
213 !> In the cray_pm_energy case, this is the energy used by the node in kJ.
214 !> \return ...
215 !> \par History
216 !> 09.2013 created [Joost VandeVondele, Ole Schuett]
217 ! **************************************************************************************************
218  FUNCTION m_energy() RESULT(wt)
219  REAL(kind=dp) :: wt
220 
221 #if defined(__CRAY_PM_ENERGY)
222  wt = read_energy("/sys/cray/pm_counters/energy")
223 #elif defined(__CRAY_PM_ACCEL_ENERGY)
224  wt = read_energy("/sys/cray/pm_counters/accel_energy")
225 #else
226  wt = 0.0 ! fallback default
227 #endif
228 
229  END FUNCTION m_energy
230 
231 #if defined(__CRAY_PM_ACCEL_ENERGY) || defined(__CRAY_PM_ENERGY)
232 ! **************************************************************************************************
233 !> \brief reads energy values from the sys-filesystem
234 !> \param filename ...
235 !> \return ...
236 !> \par History
237 !> 09.2013 created [Joost VandeVondele, Ole Schuett]
238 ! **************************************************************************************************
239  FUNCTION read_energy(filename) RESULT(wt)
240  CHARACTER(LEN=*) :: filename
241  REAL(kind=dp) :: wt
242 
243  CHARACTER(LEN=80) :: data
244  INTEGER :: i, iostat
245  INTEGER(KIND=int_8) :: raw
246 
247  OPEN (121245, file=filename, action="READ", status="OLD", access="STREAM")
248  DO i = 1, 80
249  READ (121245, END=999) DATA(I:I)
250  END DO
251 999 CLOSE (121245)
252  DATA(i:80) = ""
253  READ (DATA, *, iostat=iostat) raw
254  IF (iostat .NE. 0) THEN
255  wt = 0.0_dp
256  ELSE
257  ! convert from J to kJ
258  wt = raw/1000.0_dp
259  END IF
260  END FUNCTION read_energy
261 #endif
262 
263 ! **************************************************************************************************
264 !> \brief returns a datum in human readable format using a standard Fortran routine
265 !> \param cal_date ...
266 !> \par History
267 !> 10.2009 created [Joost VandeVondele]
268 ! **************************************************************************************************
269  SUBROUTINE m_datum(cal_date)
270  CHARACTER(len=*), INTENT(OUT) :: cal_date
271 
272  CHARACTER(len=10) :: time
273  CHARACTER(len=8) :: date
274 
275  CALL date_and_time(date=date, time=time)
276  cal_date = date(1:4)//"-"//date(5:6)//"-"//date(7:8)//" "//time(1:2)//":"//time(3:4)//":"//time(5:10)
277 
278  END SUBROUTINE m_datum
279 
280 ! **************************************************************************************************
281 !> \brief Can be used to get a nice core
282 ! **************************************************************************************************
283  SUBROUTINE m_abort()
284  INTERFACE
285  SUBROUTINE abort() BIND(C, name="abort")
286  END SUBROUTINE
287  END INTERFACE
288 
289  CALL abort()
290  END SUBROUTINE m_abort
291 
292 ! **************************************************************************************************
293 !> \brief Returns if a process is running on the local machine
294 !> 1 if yes and 0 if not
295 !> \param pid ...
296 !> \return ...
297 ! **************************************************************************************************
298  FUNCTION m_procrun(pid) RESULT(run_on)
299  INTEGER, INTENT(IN) :: pid
300  INTEGER :: run_on
301 #if defined(__MINGW)
302  run_on = 0
303 #else
304  INTEGER :: istat
305 
306  INTERFACE
307  FUNCTION kill(pid, sig) BIND(C, name="kill") RESULT(errno)
308  IMPORT
309  INTEGER(KIND=C_INT), VALUE :: pid, sig
310  INTEGER(KIND=C_INT) :: errno
311  END FUNCTION
312  END INTERFACE
313 
314  ! If sig is 0, then no signal is sent, but error checking is still
315  ! performed; this can be used to check for the existence of a process
316  ! ID or process group ID.
317 
318  istat = kill(pid=pid, sig=0)
319  IF (istat == 0) THEN
320  run_on = 1 ! no error, process exists
321  ELSE
322  run_on = 0 ! error, process probably does not exist
323  END IF
324 #endif
325  END FUNCTION m_procrun
326 
327 ! **************************************************************************************************
328 !> \brief Returns the total amount of memory [bytes] in use, if known, zero otherwise
329 !> \param mem ...
330 ! **************************************************************************************************
331  SUBROUTINE m_memory(mem)
332 
333  INTEGER(KIND=int_8), OPTIONAL, INTENT(OUT) :: mem
334  INTEGER(KIND=int_8) :: mem_local
335 
336  !
337  ! __NO_STATM_ACCESS can be used to disable the stuff, if getpagesize
338  ! lead to linking errors or /proc/self/statm can not be opened
339  !
340 #if defined(__NO_STATM_ACCESS)
341  mem_local = 0
342 #else
343  INTEGER(KIND=int_8) :: m1, m2, m3
344  CHARACTER(LEN=80) :: data
345  INTEGER :: iostat, i
346 
347  ! the size of a page, might not be available everywhere
348  INTERFACE
349  FUNCTION getpagesize() BIND(C, name="getpagesize") RESULT(RES)
350  IMPORT
351  INTEGER(C_INT) :: res
352  END FUNCTION
353  END INTERFACE
354 
355  !
356  ! reading from statm
357  !
358  mem_local = -1
359  DATA = ""
360  OPEN (121245, file="/proc/self/statm", action="READ", status="OLD", access="STREAM")
361  DO i = 1, 80
362  READ (121245, END=999) DATA(I:I)
363  END DO
364 999 CLOSE (121245)
365  DATA(i:80) = ""
366  ! m1 = total
367  ! m2 = resident
368  ! m3 = shared
369  READ (DATA, *, iostat=iostat) m1, m2, m3
370  IF (iostat .NE. 0) THEN
371  mem_local = 0
372  ELSE
373  mem_local = m2
374 #if defined(__STATM_TOTAL)
375  mem_local = m1
376 #endif
377 #if defined(__STATM_RESIDENT)
378  mem_local = m2
379 #endif
380  mem_local = mem_local*getpagesize()
381  END IF
382 #endif
383 
384  m_memory_max = max(mem_local, m_memory_max)
385  IF (PRESENT(mem)) mem = mem_local
386 
387  END SUBROUTINE m_memory
388 
389 ! **************************************************************************************************
390 !> \brief get more detailed memory info, all units are bytes.
391 !> the only 'useful' option is MemLikelyFree which is an estimate of remaining memory
392 !> assumed to give info like /proc/meminfo while MeMLikelyFree is the amount of
393 !> memory we're likely to be able to allocate, but not necessarily in one chunk
394 !> zero means not available...
395 !> \param MemTotal ...
396 !> \param MemFree ...
397 !> \param Buffers ...
398 !> \param Cached ...
399 !> \param Slab ...
400 !> \param SReclaimable ...
401 !> \param MemLikelyFree ...
402 ! **************************************************************************************************
403  SUBROUTINE m_memory_details(MemTotal, MemFree, Buffers, Cached, Slab, SReclaimable, MemLikelyFree)
404 
405  INTEGER(kind=int_8), OPTIONAL :: memtotal, memfree, buffers, cached, slab, sreclaimable, memlikelyfree
406 
407  INTEGER, PARAMETER :: nbuffer = 10000
408  CHARACTER(LEN=Nbuffer) :: meminfo
409 
410  INTEGER :: i
411 
412  memtotal = 0
413  memfree = 0
414  buffers = 0
415  cached = 0
416  slab = 0
417  sreclaimable = 0
418  memlikelyfree = 0
419  meminfo = ""
420 
421  OPEN (unit=8123, file="/proc/meminfo", access="STREAM", err=901)
422  i = 0
423  DO
424  i = i + 1
425  IF (i > nbuffer) EXIT
426  READ (8123, END=900, ERR=900) meminfo(i:i)
427  END DO
428 900 CONTINUE
429  meminfo(i:nbuffer) = ""
430 901 CONTINUE
431  CLOSE (8123, err=902)
432 902 CONTINUE
433  memtotal = get_field_value_in_bytes('MemTotal:')
434  memfree = get_field_value_in_bytes('MemFree:')
435  buffers = get_field_value_in_bytes('Buffers:')
436  cached = get_field_value_in_bytes('Cached:')
437  slab = get_field_value_in_bytes('Slab:')
438  sreclaimable = get_field_value_in_bytes('SReclaimable:')
439  ! opinions here vary but this might work
440  memlikelyfree = memfree + buffers + cached + sreclaimable
441 
442  CONTAINS
443 
444 ! **************************************************************************************************
445 !> \brief ...
446 !> \param field ...
447 !> \return ...
448 ! **************************************************************************************************
449  INTEGER(int_8) FUNCTION get_field_value_in_bytes(field)
450  CHARACTER(LEN=*) :: field
451 
452  INTEGER :: start
453  INTEGER(KIND=int_8) :: value
454 
455  get_field_value_in_bytes = 0
456  start = index(meminfo, field)
457  IF (start .NE. 0) THEN
458  start = start + len_trim(field)
459  IF (start .LT. nbuffer) THEN
460  READ (meminfo(start:), *, err=999, END=999) value
461  ! XXXXXXX convert from Kb to bytes XXXXXXXX
462  get_field_value_in_bytes = value*1024
463 999 CONTINUE
464  END IF
465  END IF
466  END FUNCTION
467  END SUBROUTINE m_memory_details
468 
469 ! **************************************************************************************************
470 !> \brief ...
471 !> \param hname ...
472 ! **************************************************************************************************
473  SUBROUTINE m_hostnm(hname)
474  CHARACTER(len=*), INTENT(OUT) :: hname
475 #if defined(__MINGW)
476  ! While there is a gethostname in the Windows (POSIX) API, it requires that winsocks is
477  ! initialised prior to using it via WSAStartup(..), respectively cleaned up at the end via WSACleanup().
478  hname = "<unknown>"
479 #else
480  INTEGER :: istat, i
481  CHARACTER(len=default_path_length) :: buf
482 
483  INTERFACE
484  FUNCTION gethostname(buf, buflen) BIND(C, name="gethostname") RESULT(errno)
485  IMPORT
486  CHARACTER(KIND=C_CHAR), DIMENSION(*) :: buf
487  INTEGER(KIND=C_INT), VALUE :: buflen
488  INTEGER(KIND=C_INT) :: errno
489  END FUNCTION
490  END INTERFACE
491 
492  istat = gethostname(buf, len(buf))
493  IF (istat /= 0) THEN
494  WRITE (*, *) "m_hostnm failed"
495  CALL m_abort()
496  END IF
497  i = index(buf, c_null_char) - 1
498  hname = buf(1:i)
499 #endif
500  END SUBROUTINE m_hostnm
501 
502 ! **************************************************************************************************
503 !> \brief ...
504 !> \param curdir ...
505 ! **************************************************************************************************
506  SUBROUTINE m_getcwd(curdir)
507  CHARACTER(len=*), INTENT(OUT) :: curdir
508  TYPE(c_ptr) :: stat
509  INTEGER :: i
510  CHARACTER(len=default_path_length), TARGET :: tmp
511 
512  INTERFACE
513  FUNCTION getcwd(buf, buflen) BIND(C, name="getcwd") RESULT(stat)
514  IMPORT
515  CHARACTER(KIND=C_CHAR), DIMENSION(*) :: buf
516  INTEGER(KIND=C_INT), VALUE :: buflen
517  TYPE(c_ptr) :: stat
518  END FUNCTION
519  END INTERFACE
520 
521  stat = getcwd(tmp, len(tmp))
522  IF (.NOT. c_associated(stat)) THEN
523  WRITE (*, *) "m_getcwd failed"
524  CALL m_abort()
525  END IF
526  i = index(tmp, c_null_char) - 1
527  curdir = tmp(1:i)
528  END SUBROUTINE m_getcwd
529 
530 ! **************************************************************************************************
531 !> \brief ...
532 !> \param dir ...
533 !> \param ierror ...
534 ! **************************************************************************************************
535  SUBROUTINE m_chdir(dir, ierror)
536  CHARACTER(len=*), INTENT(IN) :: dir
537  INTEGER, INTENT(OUT) :: ierror
538 
539  INTERFACE
540  FUNCTION chdir(path) BIND(C, name="chdir") RESULT(errno)
541  IMPORT
542  CHARACTER(KIND=C_CHAR), DIMENSION(*) :: path
543  INTEGER(KIND=C_INT) :: errno
544  END FUNCTION
545  END INTERFACE
546 
547  ierror = chdir(trim(dir)//c_null_char)
548  END SUBROUTINE m_chdir
549 
550 ! **************************************************************************************************
551 !> \brief ...
552 !> \param pid ...
553 ! **************************************************************************************************
554  SUBROUTINE m_getpid(pid)
555  INTEGER, INTENT(OUT) :: pid
556 
557  INTERFACE
558  FUNCTION getpid() BIND(C, name="getpid") RESULT(pid)
559  IMPORT
560  INTEGER(KIND=C_INT) :: pid
561  END FUNCTION
562  END INTERFACE
563 
564  pid = getpid()
565  END SUBROUTINE m_getpid
566 
567 ! **************************************************************************************************
568 !> \brief ...
569 !> \param path ...
570 !> \return ...
571 ! **************************************************************************************************
572  FUNCTION m_unlink(path) RESULT(istat)
573 
574  CHARACTER(LEN=*), INTENT(IN) :: path
575 
576  INTEGER :: istat
577 
578  INTERFACE
579  FUNCTION unlink(path) BIND(C, name="unlink") RESULT(errno)
580  IMPORT
581  CHARACTER(KIND=C_CHAR), DIMENSION(*) :: path
582  INTEGER(KIND=C_INT) :: errno
583  END FUNCTION
584  END INTERFACE
585 
586  istat = unlink(trim(path)//c_null_char)
587  END FUNCTION m_unlink
588 
589 ! **************************************************************************************************
590 !> \brief ...
591 !> \param source ...
592 !> \param TARGET ...
593 ! **************************************************************************************************
594  SUBROUTINE m_mov(source, TARGET)
595 
596  CHARACTER(LEN=*), INTENT(IN) :: source, target
597 
598  INTEGER :: istat
599 
600  INTERFACE
601  FUNCTION rename(src, dest) BIND(C, name="rename") RESULT(errno)
602  IMPORT
603  CHARACTER(KIND=C_CHAR), DIMENSION(*) :: src, dest
604  INTEGER(KIND=C_INT) :: errno
605  END FUNCTION
606  END INTERFACE
607 
608  IF (TARGET == source) THEN
609  WRITE (*, *) "Warning: m_mov ", trim(TARGET), " equals ", trim(source)
610  RETURN
611  END IF
612 
613  ! first remove target (needed on windows / mingw)
614  istat = m_unlink(TARGET)
615  ! ignore istat of unlink
616 
617  ! now move
618  istat = rename(trim(source)//c_null_char, trim(TARGET)//c_null_char)
619  IF (istat .NE. 0) THEN
620  WRITE (*, *) "Trying to move "//trim(source)//" to "//trim(TARGET)//"."
621  WRITE (*, *) "rename returned status: ", istat
622  WRITE (*, *) "Problem moving file"
623  CALL m_abort()
624  END IF
625  END SUBROUTINE m_mov
626 
627 ! **************************************************************************************************
628 !> \brief ...
629 !> \param user ...
630 ! **************************************************************************************************
631  SUBROUTINE m_getlog(user)
632 
633  CHARACTER(LEN=*), INTENT(OUT) :: user
634 
635  INTEGER :: istat
636 
637  ! on a posix system LOGNAME should be defined
638  CALL get_environment_variable("LOGNAME", value=user, status=istat)
639  ! nope, check alternative
640  IF (istat /= 0) &
641  CALL get_environment_variable("USER", value=user, status=istat)
642  ! nope, check alternative
643  IF (istat /= 0) &
644  CALL get_environment_variable("USERNAME", value=user, status=istat)
645  ! fall back
646  IF (istat /= 0) &
647  user = "<unknown>"
648 
649  END SUBROUTINE m_getlog
650 
651 ! **************************************************************************************************
652 !> \brief Retrieve environment variable OMP_STACKSIZE
653 !> \param omp_stacksize Value of OMP_STACKSIZE
654 ! **************************************************************************************************
655  SUBROUTINE m_get_omp_stacksize(omp_stacksize)
656  CHARACTER(LEN=*), INTENT(OUT) :: omp_stacksize
657 
658  INTEGER :: istat
659 
660  omp_stacksize = ""
661  CALL get_environment_variable("OMP_STACKSIZE", value=omp_stacksize, status=istat)
662  ! Fall back, if OMP_STACKSIZE is not set
663  IF (istat /= 0) omp_stacksize = "default"
664 
665  END SUBROUTINE m_get_omp_stacksize
666 
667 END MODULE machine
int m_cpuid_static(void)
This routine determines the CPUID according to the given compiler flags (expected to be similar to Fo...
Definition: machine_cpuid.c:25
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public int_8
Definition: kinds.F:54
integer, parameter, public dp
Definition: kinds.F:34
integer, parameter, public default_string_length
Definition: kinds.F:57
integer, parameter, public default_path_length
Definition: kinds.F:58
Machine interface based on Fortran 2003 and POSIX.
Definition: machine.F:17
integer, parameter, public machine_x86_avx
Definition: machine.F:55
logical, save, public flush_should_flush
Definition: machine.F:91
subroutine, public m_getpid(pid)
...
Definition: machine.F:555
integer, parameter, public default_output_unit
Definition: machine.F:45
subroutine, public m_datum(cal_date)
returns a datum in human readable format using a standard Fortran routine
Definition: machine.F:270
integer, parameter, public machine_x86_sse4
Definition: machine.F:55
subroutine, public m_memory(mem)
Returns the total amount of memory [bytes] in use, if known, zero otherwise.
Definition: machine.F:332
integer, parameter, public machine_cpu_generic
Definition: machine.F:55
integer, parameter, public default_input_unit
Definition: machine.F:45
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition: machine.F:106
integer, parameter, public machine_x86_avx2
Definition: machine.F:55
subroutine, public m_get_omp_stacksize(omp_stacksize)
Retrieve environment variable OMP_STACKSIZE.
Definition: machine.F:656
subroutine, public m_abort()
Can be used to get a nice core.
Definition: machine.F:284
integer function, public m_procrun(pid)
Returns if a process is running on the local machine 1 if yes and 0 if not.
Definition: machine.F:299
pure integer function, public m_cpuid()
Target architecture or instruction set extension according to CPU-check at runtime.
Definition: machine.F:169
subroutine, public m_getcwd(curdir)
...
Definition: machine.F:507
integer, parameter, public machine_x86
Definition: machine.F:55
subroutine, public m_chdir(dir, ierror)
...
Definition: machine.F:536
real(kind=dp) function, public m_energy()
returns the energy used since some time in the past. The precise meaning depends on the infrastructur...
Definition: machine.F:219
subroutine, public m_cpuinfo(model_name)
reads /proc/cpuinfo if it exists (i.e. Linux) to return relevant info
Definition: machine.F:137
integer, parameter, public machine_x86_avx512
Definition: machine.F:55
subroutine, public m_mov(source, TARGET)
...
Definition: machine.F:595
integer(kind=int_8), save, public m_memory_max
Definition: machine.F:93
character(len=default_string_length) function, pointer, public m_cpuid_name(cpuid)
Determine name of target architecture for a given CPUID.
Definition: machine.F:187
subroutine, public m_getlog(user)
...
Definition: machine.F:632
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition: machine.F:123
subroutine, public m_hostnm(hname)
...
Definition: machine.F:474
subroutine, public m_memory_details(MemTotal, MemFree, Buffers, Cached, Slab, SReclaimable, MemLikelyFree)
get more detailed memory info, all units are bytes. the only 'useful' option is MemLikelyFree which i...
Definition: machine.F:404