(git:d18deda)
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 + libxsmm_config_version_minor*10000 + libxsmm_config_version_update*100 + libxsmm_config_version_patch)))
34#define __LIBXSMM2
35#endif
36 USE libxsmm, ONLY: libxsmm_timer_tick, libxsmm_timer_duration, libxsmm_get_target_archid, &
37 libxsmm_target_arch_generic, libxsmm_x86_sse4, libxsmm_x86_avx, libxsmm_x86_avx2, &
38#if defined(__libxsmm2)
39 libxsmm_x86_avx512_skx, libxsmm_aarch64_v81, libxsmm_aarch64_sve128
40#else
41 libxsmm_x86_avx512_skx => libxsmm_x86_avx512_core
42#endif
43#endif
44
45 IMPLICIT NONE
46
47 ! Except for some error handling code, all code should
48 ! get a unit number from the print keys or from the logger, in order
49 ! to guarantee correct output behavior,
50 ! for example in farming or path integral runs
51 ! default_input_unit should never be used
52 ! but we need to know what it is, as we should not try to open it for output
53 INTEGER, PUBLIC, PARAMETER :: default_output_unit = output_unit, &
54 default_input_unit = input_unit
55
56#include "machine_cpuid.h"
57 ! Enumerates the target architectures or instruction set extensions.
58 ! A feature is present if within range for the respective architecture.
59 ! For example, to check for MACHINE_X86_AVX the following is true:
60 ! MACHINE_X86_AVX <= m_cpuid() and MACHINE_X86 >= m_cpuid().
61 ! For example, to check for MACHINE_ARM_SOME the following is true:
62 ! MACHINE_ARM_SOME <= m_cpuid() and MACHINE_ARM >= m_cpuid().
63 INTEGER, PUBLIC, PARAMETER :: &
64 machine_cpu_generic = cp_machine_cpu_generic, &
65 !
66 machine_x86_sse4 = cp_machine_x86_sse4, &
67 machine_x86_avx = cp_machine_x86_avx, &
68 machine_x86_avx2 = cp_machine_x86_avx2, &
69 machine_x86_avx512 = cp_machine_x86_avx512, &
71 !
72 machine_arm_arch64 = cp_machine_arm_arch64, &
73 machine_arm_sve128 = cp_machine_arm_sve128, &
74 machine_arm_sve256 = cp_machine_arm_sve256, &
75 machine_arm_sve512 = cp_machine_arm_sve512, &
77 !
78 ! other archs to be added as needed
79 machine_cpu_unknown = cp_machine_unknown ! marks end of range
80
81 PRIVATE
82
83 PUBLIC :: m_walltime, m_datum, m_hostnm, m_flush, &
88
89 INTERFACE
90 ! **********************************************************************************************
91 !> \brief Target architecture or instruction set extension according to compiler target flags.
92 !> \return cpuid according to MACHINE_* integer-parameter.
93 !> \par History
94 !> 04.2019 created [Hans Pabst]
95 ! **********************************************************************************************
96 PURE FUNCTION m_cpuid_static() BIND(C)
97 IMPORT :: c_int
98 INTEGER(C_INT) :: m_cpuid_static
99 END FUNCTION m_cpuid_static
100
101 ! **********************************************************************************************
102 !> \brief Trace OpenMP constructs if ennvironment variable CP2K_OMP_TRACE=1.
103 !> \return Number of OpenMP issues encountered (negative if OMPT disabled).
104 !> \par History
105 !> 11.2024 created [Hans Pabst]
106 ! **********************************************************************************************
107 FUNCTION m_omp_trace_issues() BIND(C, name="openmp_trace_issues")
108 IMPORT :: c_int
109 INTEGER(C_INT) :: m_omp_trace_issues
110 END FUNCTION m_omp_trace_issues
111 END INTERFACE
112
113 ! Flushing is enabled by default because without it crash reports can get lost.
114 ! For performance reasons it can be disabled via the input in &GLOBAL.
115 LOGICAL, SAVE, PUBLIC :: flush_should_flush = .true.
116
117 INTEGER(KIND=int_8), SAVE, PUBLIC :: m_memory_max = 0
118
119CONTAINS
120
121! **************************************************************************************************
122!> \brief flushes units if the &GLOBAL flag is set accordingly
123!> \param lunit ...
124!> \par History
125!> 10.2008 created [Joost VandeVondele]
126!> \note
127!> flushing might degrade performance significantly (30% and more)
128! **************************************************************************************************
129 SUBROUTINE m_flush(lunit)
130 INTEGER, INTENT(IN) :: lunit
131
132 IF (flush_should_flush) FLUSH (lunit)
133
134 END SUBROUTINE
135
136! **************************************************************************************************
137!> \brief returns time from a real-time clock, protected against rolling
138!> early/easily
139!> \return ...
140!> \par History
141!> 03.2006 created [Joost VandeVondele]
142!> \note
143!> same implementation for all machines.
144!> might still roll, if not called multiple times per count_max/count_rate
145! **************************************************************************************************
146 FUNCTION m_walltime() RESULT(wt)
147 REAL(kind=dp) :: wt
148
149#if defined(__LIBXSMM)
150 wt = libxsmm_timer_duration(0_int_8, libxsmm_timer_tick())
151#else
152 wt = omp_get_wtime()
153#endif
154 END FUNCTION m_walltime
155
156! **************************************************************************************************
157!> \brief reads /proc/cpuinfo if it exists (i.e. Linux) to return relevant info
158!> \param model_name as obtained from the 'model name' field, UNKNOWN otherwise
159! **************************************************************************************************
160 SUBROUTINE m_cpuinfo(model_name)
161 CHARACTER(LEN=default_string_length), INTENT(OUT) :: model_name
162
163 INTEGER, PARAMETER :: bufferlen = 2048
164
165 CHARACTER(LEN=bufferlen) :: buffer
166 INTEGER :: i, icol, iline, stat
167
168 model_name = "UNKNOWN"
169 buffer = ""
170 OPEN (121245, file="/proc/cpuinfo", action="READ", status="OLD", access="STREAM", iostat=stat)
171 IF (stat == 0) THEN
172 DO i = 1, bufferlen
173 READ (121245, END=999) buffer(I:I)
174 END DO
175999 CLOSE (121245)
176 i = index(buffer, "model name")
177 IF (i > 0) THEN
178 icol = i - 1 + index(buffer(i:), ":")
179 iline = icol - 1 + index(buffer(icol:), new_line('A'))
180 IF (iline == icol - 1) iline = bufferlen + 1
181 model_name = buffer(icol + 1:iline - 1)
182 END IF
183 END IF
184 END SUBROUTINE m_cpuinfo
185
186! **************************************************************************************************
187!> \brief Target architecture or instruction set extension according to CPU-check at runtime.
188!> \return cpuid according to MACHINE_* integer-parameter.
189!> \par History
190!> 04.2019 created [Hans Pabst]
191!> 09.2024 update+arm [Hans Pabst]
192! **************************************************************************************************
193 PURE FUNCTION m_cpuid()
194 INTEGER :: m_cpuid
195#if defined(__LIBXSMM)
196 m_cpuid = libxsmm_get_target_archid()
197 IF (libxsmm_x86_sse4 <= m_cpuid .AND. m_cpuid < libxsmm_x86_avx) THEN
199 ELSE IF (libxsmm_x86_avx <= m_cpuid .AND. m_cpuid < libxsmm_x86_avx2) THEN
201 ELSE IF (libxsmm_x86_avx2 <= m_cpuid .AND. m_cpuid < libxsmm_x86_avx512_skx) THEN
203 ELSE IF (libxsmm_x86_avx512_skx <= m_cpuid .AND. m_cpuid <= 1999) THEN
205#if defined(__LIBXSMM2)
206 ELSE IF (libxsmm_aarch64_v81 <= m_cpuid .AND. m_cpuid < libxsmm_aarch64_sve128) THEN
208 ELSE IF (libxsmm_aarch64_sve128 <= m_cpuid .AND. m_cpuid < 2401) THEN ! LIBXSMM_AARCH64_SVE512
210 ELSE IF (2401 <= m_cpuid .AND. m_cpuid <= 2999) THEN
212#endif
213 ELSE IF (libxsmm_target_arch_generic <= m_cpuid .AND. m_cpuid <= 2999) THEN
215 ELSE
217 END IF
218#else
220#endif
221 END FUNCTION m_cpuid
222
223! **************************************************************************************************
224!> \brief Determine name of target architecture for a given CPUID.
225!> \param cpuid integer value (MACHINE_*)
226!> \return short name of ISA extension.
227!> \par History
228!> 06.2019 created [Hans Pabst]
229!> 09.2024 update+arm [Hans Pabst]
230! **************************************************************************************************
231 PURE FUNCTION m_cpuid_name(cpuid)
232 INTEGER, OPTIONAL, INTENT(IN) :: cpuid
233 CHARACTER(len=default_string_length) :: m_cpuid_name
234
235 INTEGER :: isa
236
237 IF (PRESENT(cpuid)) THEN
238 isa = cpuid
239 ELSE
240 isa = m_cpuid()
241 END IF
242
243 SELECT CASE (isa)
245 m_cpuid_name = "generic"
246 CASE (machine_x86_sse4)
247 m_cpuid_name = "x86_sse4"
248 CASE (machine_x86_avx)
249 m_cpuid_name = "x86_avx"
250 CASE (machine_x86_avx2)
251 m_cpuid_name = "x86_avx2"
252 CASE (machine_x86_avx512)
253 m_cpuid_name = "x86_avx512"
254 CASE (machine_arm_arch64)
255 m_cpuid_name = "arm_arch64"
256 CASE (machine_arm_sve128)
257 m_cpuid_name = "arm_sve128"
258 CASE (machine_arm_sve256)
259 m_cpuid_name = "arm_sve256"
260 CASE (machine_arm_sve512)
261 m_cpuid_name = "arm_sve512"
262 CASE DEFAULT
263 m_cpuid_name = "unknown"
264 END SELECT
265 END FUNCTION m_cpuid_name
266
267! **************************************************************************************************
268!> \brief Determine vector-length for a given CPUID.
269!> \param cpuid integer value (MACHINE_*)
270!> \param typesize number of bytes of scalar type
271!> \return vector-length in number of elements.
272!> \par History
273!> 12.2024 created [Hans Pabst]
274! **************************************************************************************************
275 PURE FUNCTION m_cpuid_vlen(cpuid, typesize)
276 INTEGER, OPTIONAL, INTENT(IN) :: cpuid, typesize
277
278 INTEGER :: isa, m_cpuid_vlen, nbytes
279
280 IF (PRESENT(typesize)) THEN
281 nbytes = typesize
282 ELSE
283 nbytes = 8 ! double-precision
284 END IF
285
286 IF (0 < nbytes .AND. nbytes <= 16) THEN ! sanity check
287 IF (PRESENT(cpuid)) THEN
288 isa = cpuid
289 ELSE
290 isa = m_cpuid()
291 END IF
292
293 SELECT CASE (isa)
294 CASE (machine_x86_sse4)
295 m_cpuid_vlen = 16/nbytes
296 CASE (machine_arm_arch64) ! NEON
297 m_cpuid_vlen = 16/nbytes
298 CASE (machine_arm_sve128)
299 m_cpuid_vlen = 16/nbytes
300 CASE (machine_x86_avx)
301 m_cpuid_vlen = 32/nbytes
302 CASE (machine_x86_avx2)
303 m_cpuid_vlen = 32/nbytes
304 CASE (machine_arm_sve256)
305 m_cpuid_vlen = 32/nbytes
306 CASE (machine_x86_avx512)
307 m_cpuid_vlen = 64/nbytes
308 CASE (machine_arm_sve512)
309 m_cpuid_vlen = 64/nbytes
310 CASE DEFAULT ! unknown or generic
311 m_cpuid_vlen = 1 ! scalar
312 END SELECT
313 ELSE ! fallback
314 m_cpuid_vlen = 1 ! scalar
315 END IF
316 END FUNCTION m_cpuid_vlen
317
318! **************************************************************************************************
319!> \brief returns the energy used since some time in the past.
320!> The precise meaning depends on the infrastructure is available.
321!> In the cray_pm_energy case, this is the energy used by the node in kJ.
322!> \return ...
323!> \par History
324!> 09.2013 created [Joost VandeVondele, Ole Schuett]
325! **************************************************************************************************
326 FUNCTION m_energy() RESULT(wt)
327 REAL(kind=dp) :: wt
328
329#if defined(__CRAY_PM_ENERGY)
330 wt = read_energy("/sys/cray/pm_counters/energy")
331#elif defined(__CRAY_PM_ACCEL_ENERGY)
332 wt = read_energy("/sys/cray/pm_counters/accel_energy")
333#else
334 wt = 0.0 ! fallback default
335#endif
336
337 END FUNCTION m_energy
338
339#if defined(__CRAY_PM_ACCEL_ENERGY) || defined(__CRAY_PM_ENERGY)
340! **************************************************************************************************
341!> \brief reads energy values from the sys-filesystem
342!> \param filename ...
343!> \return ...
344!> \par History
345!> 09.2013 created [Joost VandeVondele, Ole Schuett]
346! **************************************************************************************************
347 FUNCTION read_energy(filename) RESULT(wt)
348 CHARACTER(LEN=*) :: filename
349 REAL(kind=dp) :: wt
350
351 CHARACTER(LEN=80) :: data
352 INTEGER :: i, iostat
353 INTEGER(KIND=int_8) :: raw
354
355 OPEN (121245, file=filename, action="READ", status="OLD", access="STREAM")
356 DO i = 1, 80
357 READ (121245, END=999) DATA(I:I)
358 END DO
359999 CLOSE (121245)
360 DATA(i:80) = ""
361 READ (DATA, *, iostat=iostat) raw
362 IF (iostat .NE. 0) THEN
363 wt = 0.0_dp
364 ELSE
365 ! convert from J to kJ
366 wt = raw/1000.0_dp
367 END IF
368 END FUNCTION read_energy
369#endif
370
371! **************************************************************************************************
372!> \brief returns a datum in human readable format using a standard Fortran routine
373!> \param cal_date ...
374!> \par History
375!> 10.2009 created [Joost VandeVondele]
376! **************************************************************************************************
377 SUBROUTINE m_datum(cal_date)
378 CHARACTER(len=*), INTENT(OUT) :: cal_date
379
380 CHARACTER(len=10) :: time
381 CHARACTER(len=8) :: date
382
383 CALL date_and_time(date=date, time=time)
384 cal_date = date(1:4)//"-"//date(5:6)//"-"//date(7:8)//" "//time(1:2)//":"//time(3:4)//":"//time(5:10)
385
386 END SUBROUTINE m_datum
387
388! **************************************************************************************************
389!> \brief Can be used to get a nice core
390! **************************************************************************************************
391 SUBROUTINE m_abort()
392 INTERFACE
393 SUBROUTINE abort() BIND(C, name="abort")
394 END SUBROUTINE
395 END INTERFACE
396
397 CALL abort()
398 END SUBROUTINE m_abort
399
400! **************************************************************************************************
401!> \brief Returns if a process is running on the local machine
402!> 1 if yes and 0 if not
403!> \param pid ...
404!> \return ...
405! **************************************************************************************************
406 FUNCTION m_procrun(pid) RESULT(run_on)
407 INTEGER, INTENT(IN) :: pid
408 INTEGER :: run_on
409#if defined(__MINGW)
410 run_on = 0
411#else
412 INTEGER :: istat
413
414 INTERFACE
415 FUNCTION kill(pid, sig) BIND(C, name="kill") RESULT(errno)
416 IMPORT
417 INTEGER(KIND=C_INT), VALUE :: pid, sig
418 INTEGER(KIND=C_INT) :: errno
419 END FUNCTION
420 END INTERFACE
421
422 ! If sig is 0, then no signal is sent, but error checking is still
423 ! performed; this can be used to check for the existence of a process
424 ! ID or process group ID.
425
426 istat = kill(pid=pid, sig=0)
427 IF (istat == 0) THEN
428 run_on = 1 ! no error, process exists
429 ELSE
430 run_on = 0 ! error, process probably does not exist
431 END IF
432#endif
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
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 .NE. 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 .NE. 0) THEN
564 start = start + len_trim(field)
565 IF (start .LT. 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
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#if defined(__MINGW)
582 ! While there is a gethostname in the Windows (POSIX) API, it requires that winsocks is
583 ! initialised prior to using it via WSAStartup(..), respectively cleaned up at the end via WSACleanup().
584 hname = "<unknown>"
585#else
586 INTEGER :: istat, i
587 CHARACTER(len=default_path_length) :: buf
588
589 INTERFACE
590 FUNCTION gethostname(buf, buflen) BIND(C, name="gethostname") RESULT(errno)
591 IMPORT
592 CHARACTER(KIND=C_CHAR), DIMENSION(*) :: buf
593 INTEGER(KIND=C_INT), VALUE :: buflen
594 INTEGER(KIND=C_INT) :: errno
595 END FUNCTION
596 END INTERFACE
597
598 istat = gethostname(buf, len(buf))
599 IF (istat /= 0) THEN
600 WRITE (*, *) "m_hostnm failed"
601 CALL m_abort()
602 END IF
603 i = index(buf, c_null_char) - 1
604 hname = buf(1:i)
605#endif
606 END SUBROUTINE m_hostnm
607
608! **************************************************************************************************
609!> \brief ...
610!> \param curdir ...
611! **************************************************************************************************
612 SUBROUTINE m_getcwd(curdir)
613 CHARACTER(len=*), INTENT(OUT) :: curdir
614 TYPE(c_ptr) :: stat
615 INTEGER :: i
616 CHARACTER(len=default_path_length), TARGET :: tmp
617
618 INTERFACE
619 FUNCTION getcwd(buf, buflen) BIND(C, name="getcwd") RESULT(stat)
620 IMPORT
621 CHARACTER(KIND=C_CHAR), DIMENSION(*) :: buf
622 INTEGER(KIND=C_INT), VALUE :: buflen
623 TYPE(c_ptr) :: stat
624 END FUNCTION
625 END INTERFACE
626
627 stat = getcwd(tmp, len(tmp))
628 IF (.NOT. c_associated(stat)) THEN
629 WRITE (*, *) "m_getcwd failed"
630 CALL m_abort()
631 END IF
632 i = index(tmp, c_null_char) - 1
633 curdir = tmp(1:i)
634 END SUBROUTINE m_getcwd
635
636! **************************************************************************************************
637!> \brief ...
638!> \param dir ...
639!> \param ierror ...
640! **************************************************************************************************
641 SUBROUTINE m_chdir(dir, ierror)
642 CHARACTER(len=*), INTENT(IN) :: dir
643 INTEGER, INTENT(OUT) :: ierror
644
645 INTERFACE
646 FUNCTION chdir(path) BIND(C, name="chdir") RESULT(errno)
647 IMPORT
648 CHARACTER(KIND=C_CHAR), DIMENSION(*) :: path
649 INTEGER(KIND=C_INT) :: errno
650 END FUNCTION
651 END INTERFACE
652
653 ierror = chdir(trim(dir)//c_null_char)
654 END SUBROUTINE m_chdir
655
656! **************************************************************************************************
657!> \brief ...
658!> \param pid ...
659! **************************************************************************************************
660 SUBROUTINE m_getpid(pid)
661 INTEGER, INTENT(OUT) :: pid
662
663 INTERFACE
664 FUNCTION getpid() BIND(C, name="getpid") RESULT(pid)
665 IMPORT
666 INTEGER(KIND=C_INT) :: pid
667 END FUNCTION
668 END INTERFACE
669
670 pid = getpid()
671 END SUBROUTINE m_getpid
672
673! **************************************************************************************************
674!> \brief ...
675!> \param path ...
676!> \return ...
677! **************************************************************************************************
678 FUNCTION m_unlink(path) RESULT(istat)
679
680 CHARACTER(LEN=*), INTENT(IN) :: path
681
682 INTEGER :: istat
683
684 INTERFACE
685 FUNCTION unlink(path) BIND(C, name="unlink") RESULT(errno)
686 IMPORT
687 CHARACTER(KIND=C_CHAR), DIMENSION(*) :: path
688 INTEGER(KIND=C_INT) :: errno
689 END FUNCTION
690 END INTERFACE
691
692 istat = unlink(trim(path)//c_null_char)
693 END FUNCTION m_unlink
694
695! **************************************************************************************************
696!> \brief ...
697!> \param source ...
698!> \param TARGET ...
699! **************************************************************************************************
700 SUBROUTINE m_mov(source, TARGET)
701
702 CHARACTER(LEN=*), INTENT(IN) :: source, target
703
704 INTEGER :: istat
705
706 INTERFACE
707 FUNCTION rename(src, dest) BIND(C, name="rename") RESULT(errno)
708 IMPORT
709 CHARACTER(KIND=C_CHAR), DIMENSION(*) :: src, dest
710 INTEGER(KIND=C_INT) :: errno
711 END FUNCTION
712 END INTERFACE
713
714 IF (TARGET == source) THEN
715 WRITE (*, *) "Warning: m_mov ", trim(TARGET), " equals ", trim(source)
716 RETURN
717 END IF
718
719 ! first remove target (needed on windows / mingw)
720 istat = m_unlink(TARGET)
721 ! ignore istat of unlink
722
723 ! now move
724 istat = rename(trim(source)//c_null_char, trim(TARGET)//c_null_char)
725 IF (istat .NE. 0) THEN
726 WRITE (*, *) "Trying to move "//trim(source)//" to "//trim(TARGET)//"."
727 WRITE (*, *) "rename returned status: ", istat
728 WRITE (*, *) "Problem moving file"
729 CALL m_abort()
730 END IF
731 END SUBROUTINE m_mov
732
733! **************************************************************************************************
734!> \brief ...
735!> \param user ...
736! **************************************************************************************************
737 SUBROUTINE m_getlog(user)
738
739 CHARACTER(LEN=*), INTENT(OUT) :: user
740
741 INTEGER :: istat
742
743 ! on a posix system LOGNAME should be defined
744 CALL get_environment_variable("LOGNAME", value=user, status=istat)
745 ! nope, check alternative
746 IF (istat /= 0) &
747 CALL get_environment_variable("USER", value=user, status=istat)
748 ! nope, check alternative
749 IF (istat /= 0) &
750 CALL get_environment_variable("USERNAME", value=user, status=istat)
751 ! fall back
752 IF (istat /= 0) &
753 user = "<unknown>"
754
755 END SUBROUTINE m_getlog
756
757! **************************************************************************************************
758!> \brief Retrieve environment variable OMP_STACKSIZE
759!> \param omp_stacksize Value of OMP_STACKSIZE
760! **************************************************************************************************
761 SUBROUTINE m_omp_get_stacksize(omp_stacksize)
762 CHARACTER(LEN=*), INTENT(OUT) :: omp_stacksize
763
764 INTEGER :: istat
765
766 omp_stacksize = ""
767 CALL get_environment_variable("OMP_STACKSIZE", value=omp_stacksize, status=istat)
768 ! Fall back, if OMP_STACKSIZE is not set
769 IF (istat /= 0) omp_stacksize = "default"
770
771 END SUBROUTINE m_omp_get_stacksize
772
773END MODULE machine
Target architecture or instruction set extension according to compiler target flags.
Definition machine.F:96
Trace OpenMP constructs if ennvironment variable CP2K_OMP_TRACE=1.
Definition machine.F:107
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:63
logical, save, public flush_should_flush
Definition machine.F:115
subroutine, public m_getpid(pid)
...
Definition machine.F:661
integer, parameter, public machine_arm_sve512
Definition machine.F:63
integer, parameter, public default_output_unit
Definition machine.F:53
subroutine, public m_datum(cal_date)
returns a datum in human readable format using a standard Fortran routine
Definition machine.F:378
integer, parameter, public machine_x86_sse4
Definition machine.F:63
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:63
integer, parameter, public default_input_unit
Definition machine.F:53
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:130
integer, parameter, public machine_arm_sve256
Definition machine.F:63
integer, parameter, public machine_x86_avx2
Definition machine.F:63
subroutine, public m_abort()
Can be used to get a nice core.
Definition machine.F:392
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:407
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:194
subroutine, public m_getcwd(curdir)
...
Definition machine.F:613
integer, parameter, public machine_x86
Definition machine.F:63
subroutine, public m_chdir(dir, ierror)
...
Definition machine.F:642
pure integer function, public m_cpuid_vlen(cpuid, typesize)
Determine vector-length for a given CPUID.
Definition machine.F:276
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:327
integer, parameter, public machine_arm
Definition machine.F:63
subroutine, public m_cpuinfo(model_name)
reads /proc/cpuinfo if it exists (i.e. Linux) to return relevant info
Definition machine.F:161
subroutine, public m_mov(source, target)
...
Definition machine.F:701
pure character(len=default_string_length) function, public m_cpuid_name(cpuid)
Determine name of target architecture for a given CPUID.
Definition machine.F:232
integer, parameter, public machine_x86_avx512
Definition machine.F:63
integer, parameter, public machine_arm_arch64
Definition machine.F:63
subroutine, public m_omp_get_stacksize(omp_stacksize)
Retrieve environment variable OMP_STACKSIZE.
Definition machine.F:762
integer, parameter, public machine_cpu_unknown
Definition machine.F:63
integer(kind=int_8), save, public m_memory_max
Definition machine.F:117
integer, parameter, public machine_arm_sve128
Definition machine.F:63
subroutine, public m_getlog(user)
...
Definition machine.F:738
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:147
subroutine, public m_hostnm(hname)
...
Definition machine.F:580