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