(git:9dda3dd)
Loading...
Searching...
No Matches
machine.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 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! **************************************************************************************************
17MODULE 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(__LIBXS)
31 USE libxs, ONLY: libxs_timer_tick, libxs_timer_duration, libxs_cpuid, &
32 libxs_target_arch_generic, libxs_x86_sse42, libxs_x86_avx, libxs_x86_avx2, &
33 libxs_x86_avx512, libxs_aarch64, libxs_aarch64_sve128, &
34 libxs_aarch64_sve256, libxs_aarch64_sve512, &
35 c_null_ptr
36#endif
37
38 IMPLICIT NONE
39
40 ! Except for some error handling code, all code should
41 ! get a unit number from the print keys or from the logger, in order
42 ! to guarantee correct output behavior,
43 ! for example in farming or path integral runs
44 ! default_input_unit should never be used
45 ! but we need to know what it is, as we should not try to open it for output
46 INTEGER, PUBLIC, PARAMETER :: default_output_unit = output_unit, &
47 default_input_unit = input_unit, &
49
50#include "machine_cpuid.h"
51 ! Enumerates the target architectures or instruction set extensions.
52 ! A feature is present if within range for the respective architecture.
53 ! For example, to check for MACHINE_X86_AVX the following is true:
54 ! MACHINE_X86_AVX <= m_cpuid() and MACHINE_X86 >= m_cpuid().
55 ! For example, to check for MACHINE_ARM_SOME the following is true:
56 ! MACHINE_ARM_SOME <= m_cpuid() and MACHINE_ARM >= m_cpuid().
57 INTEGER, PUBLIC, PARAMETER :: &
58 machine_cpu_generic = cp_machine_cpu_generic, &
59 !
60 machine_x86_sse4 = cp_machine_x86_sse4, &
61 machine_x86_avx = cp_machine_x86_avx, &
62 machine_x86_avx2 = cp_machine_x86_avx2, &
63 machine_x86_avx512 = cp_machine_x86_avx512, &
65 !
66 machine_arm_arch64 = cp_machine_arm_arch64, &
67 machine_arm_sve128 = cp_machine_arm_sve128, &
68 machine_arm_sve256 = cp_machine_arm_sve256, &
69 machine_arm_sve512 = cp_machine_arm_sve512, &
71 !
72 ! other archs to be added as needed
73 machine_cpu_unknown = cp_machine_unknown ! marks end of range
74
75 PRIVATE
76
82
83 INTERFACE
84 ! **********************************************************************************************
85 !> \brief Target architecture or instruction set extension according to compiler target flags.
86 !> \return cpuid according to MACHINE_* integer-parameter.
87 !> \par History
88 !> 04.2019 created [Hans Pabst]
89 ! **********************************************************************************************
90 PURE FUNCTION m_cpuid_static() BIND(C)
91 IMPORT :: c_int
92 INTEGER(C_INT) :: m_cpuid_static
93 END FUNCTION m_cpuid_static
94
95 ! **********************************************************************************************
96 !> \brief Trace OpenMP constructs if ennvironment variable CP2K_OMP_TRACE=1.
97 !> \return Number of OpenMP issues encountered (negative if OMPT disabled).
98 !> \par History
99 !> 11.2024 created [Hans Pabst]
100 ! **********************************************************************************************
101 FUNCTION m_omp_trace_issues() BIND(C, name="openmp_trace_issues")
102 IMPORT :: c_int
103 INTEGER(C_INT) :: m_omp_trace_issues
104 END FUNCTION m_omp_trace_issues
105 END INTERFACE
106
107 ! Flushing is enabled by default because without it crash reports can get lost.
108 ! For performance reasons it can be disabled via the input in &GLOBAL.
109 LOGICAL, SAVE, PUBLIC :: flush_should_flush = .true.
110
111 INTEGER(KIND=int_8), SAVE, PUBLIC :: m_memory_max = 0
112
113CONTAINS
114
115! **************************************************************************************************
116!> \brief flushes units if the &GLOBAL flag is set accordingly
117!> \param lunit ...
118!> \par History
119!> 10.2008 created [Joost VandeVondele]
120!> \note
121!> flushing might degrade performance significantly (30% and more)
122! **************************************************************************************************
123 SUBROUTINE m_flush(lunit)
124 INTEGER, INTENT(IN) :: lunit
125
126 IF (flush_should_flush) FLUSH (lunit)
127
128 END SUBROUTINE m_flush
129
130! **************************************************************************************************
131!> \brief returns time from a real-time clock, protected against rolling
132!> early/easily
133!> \return ...
134!> \par History
135!> 03.2006 created [Joost VandeVondele]
136!> \note
137!> same implementation for all machines.
138!> might still roll, if not called multiple times per count_max/count_rate
139! **************************************************************************************************
140 FUNCTION m_walltime() RESULT(wt)
141 REAL(kind=dp) :: wt
142
143#if defined(__LIBXS)
144 wt = libxs_timer_duration(0_int_8, libxs_timer_tick())
145#else
146 wt = omp_get_wtime()
147#endif
148 END FUNCTION m_walltime
149
150! **************************************************************************************************
151!> \brief reads /proc/cpuinfo if it exists (i.e. Linux) to return relevant info
152!> \param model_name as obtained from the 'model name' field, UNKNOWN otherwise
153! **************************************************************************************************
154 SUBROUTINE m_cpuinfo(model_name)
155 CHARACTER(LEN=default_string_length), INTENT(OUT) :: model_name
156
157 INTEGER, PARAMETER :: bufferlen = 2048
158
159 CHARACTER(LEN=bufferlen) :: buffer
160 INTEGER :: i, icol, iline, stat
161
162 model_name = "UNKNOWN"
163 buffer = ""
164 OPEN (121245, file="/proc/cpuinfo", action="READ", status="OLD", access="STREAM", iostat=stat)
165 IF (stat == 0) THEN
166 DO i = 1, bufferlen
167 READ (121245, END=999) buffer(I:I)
168 END DO
169999 CLOSE (121245)
170 i = index(buffer, "model name")
171 IF (i > 0) THEN
172 icol = i - 1 + index(buffer(i:), ":")
173 iline = icol - 1 + index(buffer(icol:), new_line('A'))
174 IF (iline == icol - 1) iline = bufferlen + 1
175 model_name = buffer(icol + 1:iline - 1)
176 END IF
177 END IF
178 END SUBROUTINE m_cpuinfo
179
180! **************************************************************************************************
181!> \brief Target architecture or instruction set extension according to CPU-check at runtime.
182!> \return cpuid according to MACHINE_* integer-parameter.
183!> \par History
184!> 04.2019 created [Hans Pabst]
185!> 09.2024 update+arm [Hans Pabst]
186! **************************************************************************************************
187 PURE FUNCTION m_cpuid()
188 INTEGER :: m_cpuid
189#if !defined(__LIBXS)
191#else
192
193 INTEGER :: archid
195 archid = libxs_cpuid(c_null_ptr)
196 IF (libxs_x86_sse42 <= archid .AND. archid < libxs_x86_avx) THEN
198 ELSE IF (libxs_x86_avx <= archid .AND. archid < libxs_x86_avx2) THEN
200 ELSE IF (libxs_x86_avx2 <= archid .AND. archid < libxs_x86_avx512) THEN
202 ELSE IF (libxs_x86_avx512 <= archid .AND. archid <= 1999) THEN
204 END IF
205
206 IF (m_cpuid == machine_cpu_unknown) THEN
207 IF (libxs_aarch64 <= archid .AND. archid < libxs_aarch64_sve128) THEN
209 ELSE IF (libxs_aarch64_sve128 <= archid .AND. archid < libxs_aarch64_sve256) THEN
211 ELSE IF (libxs_aarch64_sve256 <= archid .AND. archid < libxs_aarch64_sve512) THEN
213 ELSE IF (libxs_aarch64_sve512 <= archid .AND. archid <= 2999) THEN
215 END IF
216 END IF
217
218 IF (m_cpuid == machine_cpu_unknown .AND. libxs_target_arch_generic <= archid .AND. archid <= 2999) THEN
220 END IF
221#endif
222 END FUNCTION m_cpuid
223
224! **************************************************************************************************
225!> \brief Determine name of target architecture for a given CPUID.
226!> \param cpuid integer value (MACHINE_*)
227!> \return short name of ISA extension.
228!> \par History
229!> 06.2019 created [Hans Pabst]
230!> 09.2024 update+arm [Hans Pabst]
231! **************************************************************************************************
232 PURE FUNCTION m_cpuid_name(cpuid)
233 INTEGER, INTENT(IN), OPTIONAL :: cpuid
234 CHARACTER(len=default_string_length) :: m_cpuid_name
235
236 INTEGER :: isa
237
238 IF (PRESENT(cpuid)) THEN
239 isa = cpuid
240 ELSE
241 isa = m_cpuid()
242 END IF
243
244 SELECT CASE (isa)
246 m_cpuid_name = "generic"
247 CASE (machine_x86_sse4)
248 m_cpuid_name = "x86_sse4"
249 CASE (machine_x86_avx)
250 m_cpuid_name = "x86_avx"
251 CASE (machine_x86_avx2)
252 m_cpuid_name = "x86_avx2"
253 CASE (machine_x86_avx512)
254 m_cpuid_name = "x86_avx512"
255 CASE (machine_arm_arch64)
256 m_cpuid_name = "arm_arch64"
257 CASE (machine_arm_sve128)
258 m_cpuid_name = "arm_sve128"
259 CASE (machine_arm_sve256)
260 m_cpuid_name = "arm_sve256"
261 CASE (machine_arm_sve512)
262 m_cpuid_name = "arm_sve512"
263 CASE DEFAULT
264 m_cpuid_name = "unknown"
265 END SELECT
266 END FUNCTION m_cpuid_name
267
268! **************************************************************************************************
269!> \brief Determine vector-length for a given CPUID.
270!> \param cpuid integer value (MACHINE_*)
271!> \param typesize number of bytes of scalar type
272!> \return vector-length in number of elements.
273!> \par History
274!> 12.2024 created [Hans Pabst]
275! **************************************************************************************************
276 PURE FUNCTION m_cpuid_vlen(cpuid, typesize)
277 INTEGER, INTENT(IN), OPTIONAL :: cpuid, typesize
278 INTEGER :: m_cpuid_vlen
279
280 INTEGER :: isa, nbytes
281
282 IF (PRESENT(typesize)) THEN
283 nbytes = typesize
284 ELSE
285 nbytes = 8 ! double-precision
286 END IF
287
288 IF (0 < nbytes .AND. nbytes <= 16) THEN ! sanity check
289 IF (PRESENT(cpuid)) THEN
290 isa = cpuid
291 ELSE
292 isa = m_cpuid()
293 END IF
294
295 SELECT CASE (isa)
296 CASE (machine_x86_sse4)
297 m_cpuid_vlen = 16/nbytes
298 CASE (machine_arm_arch64) ! NEON
299 m_cpuid_vlen = 16/nbytes
300 CASE (machine_arm_sve128)
301 m_cpuid_vlen = 16/nbytes
302 CASE (machine_x86_avx)
303 m_cpuid_vlen = 32/nbytes
304 CASE (machine_x86_avx2)
305 m_cpuid_vlen = 32/nbytes
306 CASE (machine_arm_sve256)
307 m_cpuid_vlen = 32/nbytes
308 CASE (machine_x86_avx512)
309 m_cpuid_vlen = 64/nbytes
310 CASE (machine_arm_sve512)
311 m_cpuid_vlen = 64/nbytes
312 CASE DEFAULT ! unknown or generic
313 m_cpuid_vlen = 1 ! scalar
314 END SELECT
315 ELSE ! fallback
316 m_cpuid_vlen = 1 ! scalar
317 END IF
318 END FUNCTION m_cpuid_vlen
319
320! **************************************************************************************************
321!> \brief returns the energy used since some time in the past.
322!> The precise meaning depends on the infrastructure is available.
323!> In the cray_pm_energy case, this is the energy used by the node in kJ.
324!> \return ...
325!> \par History
326!> 09.2013 created [Joost VandeVondele, Ole Schuett]
327! **************************************************************************************************
328 FUNCTION m_energy() RESULT(wt)
329 REAL(kind=dp) :: wt
330
331#if defined(__CRAY_PM_ENERGY)
332 wt = read_energy("/sys/cray/pm_counters/energy")
333#elif defined(__CRAY_PM_ACCEL_ENERGY)
334 wt = read_energy("/sys/cray/pm_counters/accel_energy")
335#else
336 wt = 0.0 ! fallback default
337#endif
338
339 END FUNCTION m_energy
340
341#if defined(__CRAY_PM_ACCEL_ENERGY) || defined(__CRAY_PM_ENERGY)
342! **************************************************************************************************
343!> \brief reads energy values from the sys-filesystem
344!> \param filename ...
345!> \return ...
346!> \par History
347!> 09.2013 created [Joost VandeVondele, Ole Schuett]
348! **************************************************************************************************
349 FUNCTION read_energy(filename) RESULT(wt)
350 CHARACTER(LEN=*) :: filename
351 REAL(kind=dp) :: wt
352
353 CHARACTER(LEN=80) :: data
354 INTEGER :: i, iostat
355 INTEGER(KIND=int_8) :: raw
356
357 OPEN (121245, file=filename, action="READ", status="OLD", access="STREAM")
358 DO i = 1, 80
359 READ (121245, END=999) DATA(I:I)
360 END DO
361999 CLOSE (121245)
362 DATA(i:80) = ""
363 READ (DATA, *, iostat=iostat) raw
364 IF (iostat /= 0) THEN
365 wt = 0.0_dp
366 ELSE
367 ! convert from J to kJ
368 wt = raw/1000.0_dp
369 END IF
370 END FUNCTION read_energy
371#endif
372
373! **************************************************************************************************
374!> \brief Returns a human readable timestamp
375!> \param timestamp Timestamp string
376!> \par History
377!> 10.2009 created [Joost VandeVondele]
378!> 08.2025 modified [Matthias Krack]
379! **************************************************************************************************
380 SUBROUTINE m_timestamp(timestamp)
381 CHARACTER(len=timestamp_length), INTENT(OUT) :: timestamp
382
383 CHARACTER(len=10) :: time
384 CHARACTER(len=8) :: date
385
386 CALL date_and_time(date=date, time=time)
387 timestamp = date(1:4)//"-"//date(5:6)//"-"//date(7:8)//" "// &
388 time(1:2)//":"//time(3:4)//":"//time(5:10)
389
390 END SUBROUTINE m_timestamp
391
392! **************************************************************************************************
393!> \brief Can be used to get a nice core
394! **************************************************************************************************
395 SUBROUTINE m_abort()
396 INTERFACE
397 SUBROUTINE abort() BIND(C, name="abort")
398 END SUBROUTINE abort
399 END INTERFACE
400
401 CALL abort()
402 END SUBROUTINE m_abort
403
404! **************************************************************************************************
405!> \brief Returns if a process is running on the local machine
406!> 1 if yes and 0 if not
407!> \param pid ...
408!> \return ...
409! **************************************************************************************************
410 FUNCTION m_procrun(pid) RESULT(run_on)
411 INTEGER, INTENT(IN) :: pid
412 INTEGER :: run_on
413
414 INTEGER :: istat
415 INTERFACE
416 FUNCTION kill(pid, sig) RESULT(errno) BIND(C, name="kill")
417 IMPORT
418 INTEGER(KIND=C_INT), VALUE :: pid, sig
419 INTEGER(KIND=C_INT) :: errno
420 END FUNCTION kill
421 END INTERFACE
422
423 ! If sig is 0, then no signal is sent, but error checking is still
424 ! performed; this can be used to check for the existence of a process
425 ! ID or process group ID.
426
427 istat = kill(pid=pid, sig=0)
428 IF (istat == 0) THEN
429 run_on = 1 ! no error, process exists
430 ELSE
431 run_on = 0 ! error, process probably does not exist
432 END IF
433 END FUNCTION m_procrun
434
435! **************************************************************************************************
436!> \brief Returns the total amount of memory [bytes] in use, if known, zero otherwise
437!> \param mem ...
438! **************************************************************************************************
439 SUBROUTINE m_memory(mem)
440
441 INTEGER(KIND=int_8), OPTIONAL, INTENT(OUT) :: mem
442 INTEGER(KIND=int_8) :: mem_local
443
444 ! __NO_STATM_ACCESS can be used to disable the stuff, if getpagesize
445 ! lead to linking errors or /proc/self/statm can not be opened
446 !
447#if defined(__NO_STATM_ACCESS)
448 mem_local = 0
449#else
450 INTEGER(KIND=int_8) :: m1, m2, m3
451 CHARACTER(LEN=80) :: data
452 INTEGER :: iostat, i
453
454 ! the size of a page, might not be available everywhere
455 INTERFACE
456 FUNCTION getpagesize() BIND(C, name="getpagesize") RESULT(RES)
457 IMPORT
458 INTEGER(C_INT) :: res
459 END FUNCTION getpagesize
460 END INTERFACE
461
462 ! reading from statm
463 !
464 mem_local = -1
465 DATA = ""
466 OPEN (121245, file="/proc/self/statm", action="READ", status="OLD", access="STREAM")
467 DO i = 1, 80
468 READ (121245, END=999) DATA(I:I)
469 END DO
470999 CLOSE (121245)
471 DATA(i:80) = ""
472 ! m1 = total
473 ! m2 = resident
474 ! m3 = shared
475 READ (DATA, *, iostat=iostat) m1, m2, m3
476 IF (iostat /= 0) THEN
477 mem_local = 0
478 ELSE
479 mem_local = m2
480#if defined(__STATM_TOTAL)
481 mem_local = m1
482#endif
483#if defined(__STATM_RESIDENT)
484 mem_local = m2
485#endif
486 mem_local = mem_local*getpagesize()
487 END IF
488#endif
489
490 m_memory_max = max(mem_local, m_memory_max)
491 IF (PRESENT(mem)) mem = mem_local
492
493 END SUBROUTINE m_memory
494
495! **************************************************************************************************
496!> \brief get more detailed memory info, all units are bytes.
497!> the only 'useful' option is MemLikelyFree which is an estimate of remaining memory
498!> assumed to give info like /proc/meminfo while MeMLikelyFree is the amount of
499!> memory we're likely to be able to allocate, but not necessarily in one chunk
500!> zero means not available...
501!> \param MemTotal ...
502!> \param MemFree ...
503!> \param Buffers ...
504!> \param Cached ...
505!> \param Slab ...
506!> \param SReclaimable ...
507!> \param MemLikelyFree ...
508! **************************************************************************************************
509 SUBROUTINE m_memory_details(MemTotal, MemFree, Buffers, Cached, Slab, SReclaimable, MemLikelyFree)
510
511 INTEGER(kind=int_8), OPTIONAL :: memtotal, memfree, buffers, cached, slab, sreclaimable, memlikelyfree
512
513 INTEGER, PARAMETER :: nbuffer = 10000
514 CHARACTER(LEN=Nbuffer) :: meminfo
515
516 INTEGER :: i
517
518 memtotal = 0
519 memfree = 0
520 buffers = 0
521 cached = 0
522 slab = 0
523 sreclaimable = 0
524 memlikelyfree = 0
525 meminfo = ""
526
527 OPEN (unit=8123, file="/proc/meminfo", access="STREAM", err=901)
528 i = 0
529 DO
530 i = i + 1
531 IF (i > nbuffer) EXIT
532 READ (8123, END=900, ERR=900) meminfo(i:i)
533 END DO
534900 CONTINUE
535 meminfo(i:nbuffer) = ""
536901 CONTINUE
537 CLOSE (8123, err=902)
538902 CONTINUE
539 memtotal = get_field_value_in_bytes('MemTotal:')
540 memfree = get_field_value_in_bytes('MemFree:')
541 buffers = get_field_value_in_bytes('Buffers:')
542 cached = get_field_value_in_bytes('Cached:')
543 slab = get_field_value_in_bytes('Slab:')
544 sreclaimable = get_field_value_in_bytes('SReclaimable:')
545 ! opinions here vary but this might work
546 memlikelyfree = memfree + buffers + cached + sreclaimable
547
548 CONTAINS
549
550! **************************************************************************************************
551!> \brief ...
552!> \param field ...
553!> \return ...
554! **************************************************************************************************
555 INTEGER(int_8) FUNCTION get_field_value_in_bytes(field)
556 CHARACTER(LEN=*) :: field
557
558 INTEGER :: start
559 INTEGER(KIND=int_8) :: value
560
561 get_field_value_in_bytes = 0
562 start = index(meminfo, field)
563 IF (start /= 0) THEN
564 start = start + len_trim(field)
565 IF (start < nbuffer) THEN
566 READ (meminfo(start:), *, err=999, END=999) value
567 ! XXXXXXX convert from Kb to bytes XXXXXXXX
568 get_field_value_in_bytes = value*1024
569999 CONTINUE
570 END IF
571 END IF
572 END FUNCTION get_field_value_in_bytes
573 END SUBROUTINE m_memory_details
574
575! **************************************************************************************************
576!> \brief ...
577!> \param hname ...
578! **************************************************************************************************
579 SUBROUTINE m_hostnm(hname)
580 CHARACTER(len=*), INTENT(OUT) :: hname
581 INTEGER :: istat, i
582 CHARACTER(len=default_path_length) :: buf
583
584 INTERFACE
585 FUNCTION gethostname(buf, buflen) BIND(C, name="gethostname") RESULT(errno)
586 IMPORT
587 CHARACTER(KIND=C_CHAR), DIMENSION(*) :: buf
588 INTEGER(KIND=C_INT), VALUE :: buflen
589 INTEGER(KIND=C_INT) :: errno
590 END FUNCTION gethostname
591 END INTERFACE
592
593 istat = gethostname(buf, len(buf))
594 IF (istat /= 0) THEN
595 WRITE (*, *) "m_hostnm failed"
596 CALL m_abort()
597 END IF
598 i = index(buf, c_null_char) - 1
599 hname = buf(1:i)
600 END SUBROUTINE m_hostnm
601
602! **************************************************************************************************
603!> \brief ...
604!> \param curdir ...
605! **************************************************************************************************
606 SUBROUTINE m_getcwd(curdir)
607 CHARACTER(len=*), INTENT(OUT) :: curdir
608 TYPE(c_ptr) :: stat
609 INTEGER :: i
610 CHARACTER(len=default_path_length), TARGET :: tmp
611
612 INTERFACE
613 FUNCTION getcwd(buf, buflen) BIND(C, name="getcwd") RESULT(stat)
614 IMPORT
615 CHARACTER(KIND=C_CHAR), DIMENSION(*) :: buf
616 INTEGER(KIND=C_INT), VALUE :: buflen
617 TYPE(c_ptr) :: stat
618 END FUNCTION getcwd
619 END INTERFACE
620
621 stat = getcwd(tmp, len(tmp))
622 IF (.NOT. c_associated(stat)) THEN
623 WRITE (*, *) "m_getcwd failed"
624 CALL m_abort()
625 END IF
626 i = index(tmp, c_null_char) - 1
627 curdir = tmp(1:i)
628 END SUBROUTINE m_getcwd
629
630! **************************************************************************************************
631!> \brief ...
632!> \param dir ...
633!> \param ierror ...
634! **************************************************************************************************
635 SUBROUTINE m_chdir(dir, ierror)
636 CHARACTER(len=*), INTENT(IN) :: dir
637 INTEGER, INTENT(OUT) :: ierror
638
639 INTERFACE
640 FUNCTION chdir(path) BIND(C, name="chdir") RESULT(errno)
641 IMPORT
642 CHARACTER(KIND=C_CHAR), DIMENSION(*) :: path
643 INTEGER(KIND=C_INT) :: errno
644 END FUNCTION chdir
645 END INTERFACE
646
647 ierror = chdir(trim(dir)//c_null_char)
648 END SUBROUTINE m_chdir
649
650! **************************************************************************************************
651!> \brief ...
652!> \param pid ...
653! **************************************************************************************************
654 SUBROUTINE m_getpid(pid)
655 INTEGER, INTENT(OUT) :: pid
656
657 INTERFACE
658 FUNCTION getpid() BIND(C, name="getpid") RESULT(pid)
659 IMPORT
660 INTEGER(KIND=C_INT) :: pid
661 END FUNCTION getpid
662 END INTERFACE
663
664 pid = getpid()
665 END SUBROUTINE m_getpid
666
667! **************************************************************************************************
668!> \brief ...
669!> \param path ...
670!> \return ...
671! **************************************************************************************************
672 FUNCTION m_unlink(path) RESULT(istat)
673
674 CHARACTER(LEN=*), INTENT(IN) :: path
675
676 INTEGER :: istat
677
678 INTERFACE
679 FUNCTION unlink(path) BIND(C, name="unlink") RESULT(errno)
680 IMPORT
681 CHARACTER(KIND=C_CHAR), DIMENSION(*) :: path
682 INTEGER(KIND=C_INT) :: errno
683 END FUNCTION unlink
684 END INTERFACE
685
686 istat = unlink(trim(path)//c_null_char)
687 END FUNCTION m_unlink
688
689! **************************************************************************************************
690!> \brief ...
691!> \param source ...
692!> \param TARGET ...
693! **************************************************************************************************
694 SUBROUTINE m_mov(source, TARGET)
695
696 CHARACTER(LEN=*), INTENT(IN) :: source, target
697
698 INTEGER :: istat
699 LOGICAL :: src_exists
700
701 INTERFACE
702 FUNCTION rename(src, dest) BIND(C, name="rename") RESULT(errno)
703 IMPORT
704 CHARACTER(KIND=C_CHAR), DIMENSION(*) :: src, dest
705 INTEGER(KIND=C_INT) :: errno
706 END FUNCTION rename
707 END INTERFACE
708
709 IF (TARGET == source) THEN
710 WRITE (*, *) "Warning: m_mov ", trim(TARGET), " equals ", trim(source)
711 RETURN
712 END IF
713
714 ! first remove target (needed on windows)
715 istat = m_unlink(TARGET)
716 ! ignore istat of unlink
717
718 ! now move
719 istat = rename(trim(source)//c_null_char, trim(TARGET)//c_null_char)
720 IF (istat /= 0) THEN
721 ! Source already moved by a concurrent rank: benign, nothing to back up.
722 INQUIRE (file=source, exist=src_exists)
723 IF (.NOT. src_exists) RETURN
724 WRITE (*, *) "Trying to move "//trim(source)//" to "//trim(TARGET)//"."
725 WRITE (*, *) "rename returned status: ", istat
726 WRITE (*, *) "Problem moving file"
727 CALL m_abort()
728 END IF
729 END SUBROUTINE m_mov
730
731! **************************************************************************************************
732!> \brief ...
733!> \param user ...
734! **************************************************************************************************
735 SUBROUTINE m_getlog(user)
736
737 CHARACTER(LEN=*), INTENT(OUT) :: user
738
739 INTEGER :: istat
740
741 ! on a posix system LOGNAME should be defined
742 CALL get_environment_variable("LOGNAME", value=user, status=istat)
743 ! nope, check alternative
744 IF (istat /= 0) &
745 CALL get_environment_variable("USER", value=user, status=istat)
746 ! nope, check alternative
747 IF (istat /= 0) &
748 CALL get_environment_variable("USERNAME", value=user, status=istat)
749 ! fall back
750 IF (istat /= 0) &
751 user = "<unknown>"
752
753 END SUBROUTINE m_getlog
754
755! **************************************************************************************************
756!> \brief Retrieve environment variable OMP_STACKSIZE
757!> \param omp_stacksize Value of OMP_STACKSIZE
758! **************************************************************************************************
759 SUBROUTINE m_omp_get_stacksize(omp_stacksize)
760 CHARACTER(LEN=*), INTENT(OUT) :: omp_stacksize
761
762 INTEGER :: istat
763
764 omp_stacksize = ""
765 CALL get_environment_variable("OMP_STACKSIZE", value=omp_stacksize, status=istat)
766 ! Fall back, if OMP_STACKSIZE is not set
767 IF (istat /= 0) omp_stacksize = "default"
768
769 END SUBROUTINE m_omp_get_stacksize
770
771END MODULE machine
Target architecture or instruction set extension according to compiler target flags.
Definition machine.F:90
Trace OpenMP constructs if ennvironment variable CP2K_OMP_TRACE=1.
Definition machine.F:101
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:57
logical, save, public flush_should_flush
Definition machine.F:109
subroutine, public m_getpid(pid)
...
Definition machine.F:655
integer, parameter, public machine_arm_sve512
Definition machine.F:57
integer, parameter, public default_output_unit
Definition machine.F:46
integer, parameter, public machine_x86_sse4
Definition machine.F:57
subroutine, public m_memory(mem)
Returns the total amount of memory [bytes] in use, if known, zero otherwise.
Definition machine.F:440
integer, parameter, public machine_cpu_generic
Definition machine.F:57
integer, parameter, public default_input_unit
Definition machine.F:46
integer, parameter, public timestamp_length
Definition machine.F:46
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:124
integer, parameter, public machine_arm_sve256
Definition machine.F:57
integer, parameter, public machine_x86_avx2
Definition machine.F:57
subroutine, public m_abort()
Can be used to get a nice core.
Definition machine.F:396
subroutine, public m_timestamp(timestamp)
Returns a human readable timestamp.
Definition machine.F:381
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:411
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:510
pure integer function, public m_cpuid()
Target architecture or instruction set extension according to CPU-check at runtime.
Definition machine.F:188
subroutine, public m_getcwd(curdir)
...
Definition machine.F:607
integer, parameter, public machine_x86
Definition machine.F:57
subroutine, public m_chdir(dir, ierror)
...
Definition machine.F:636
pure integer function, public m_cpuid_vlen(cpuid, typesize)
Determine vector-length for a given CPUID.
Definition machine.F:277
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:329
integer, parameter, public machine_arm
Definition machine.F:57
subroutine, public m_cpuinfo(model_name)
reads /proc/cpuinfo if it exists (i.e. Linux) to return relevant info
Definition machine.F:155
subroutine, public m_mov(source, target)
...
Definition machine.F:695
pure character(len=default_string_length) function, public m_cpuid_name(cpuid)
Determine name of target architecture for a given CPUID.
Definition machine.F:233
integer, parameter, public machine_x86_avx512
Definition machine.F:57
integer, parameter, public machine_arm_arch64
Definition machine.F:57
subroutine, public m_omp_get_stacksize(omp_stacksize)
Retrieve environment variable OMP_STACKSIZE.
Definition machine.F:760
integer, parameter, public machine_cpu_unknown
Definition machine.F:57
integer(kind=int_8), save, public m_memory_max
Definition machine.F:111
integer, parameter, public machine_arm_sve128
Definition machine.F:57
subroutine, public m_getlog(user)
...
Definition machine.F:736
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:141
subroutine, public m_hostnm(hname)
...
Definition machine.F:580