diff --git a/src/fiat/gstats/gstats_label.F90 b/src/fiat/gstats/gstats_label.F90
index eb183b56..1d17ab58 100644
--- a/src/fiat/gstats/gstats_label.F90
+++ b/src/fiat/gstats/gstats_label.F90
@@ -21,11 +21,9 @@ SUBROUTINE GSTATS_LABEL(KNUM, CTYPE, CDESC)
INTEGER(KIND=JPIM) :: ILEN, ITLEN
IF (KNUM < 0 .OR. KNUM > JPMAXSTAT) CALL ABOR1('GSTATS_LABEL:ILLEGAL KNUM')
-ILEN = LEN(CDESC)
-ILEN = MIN(ILEN,50)
-ITLEN = LEN(CTYPE)
-ITLEN = MIN(ILEN,3)
IF (CCDESC(KNUM) == '') THEN
+ ILEN = MIN(LEN(CDESC), LEN(CCDESC(KNUM)))
+ ITLEN = MIN(LEN(CTYPE), LEN(CCTYPE(KNUM)))
CCDESC(KNUM) = CDESC(1:ILEN)
CCTYPE(KNUM) = CTYPE(1:ITLEN)
ELSEIF (CCDESC(KNUM)(1:ILEN) /= CDESC(1:ILEN)) THEN
diff --git a/src/fiat/gstats/gstats_print.F90 b/src/fiat/gstats/gstats_print.F90
index e56a3779..6fe5ad82 100644
--- a/src/fiat/gstats/gstats_print.F90
+++ b/src/fiat/gstats/gstats_print.F90
@@ -54,10 +54,11 @@ SUBROUTINE GSTATS_PRINT(KULOUT,PAVEAVE,KLEN)
! P.Towers 11-May-2011 : mpl comms statistics output
! F. Vana 05-Mar-2015 Support for single precision
! G. Mozdzynski 18-Aug-2015 Avoid confusion, procs are tasks
+! M. Plesske 05-Nov-2025 added LCSV_STATS
! ------------------------------------------------------------------
USE EC_PARKIND, ONLY: JPRD, JPIM
-USE YOMGSTATS, ONLY: JPMAXDELAYS, JPMAXSTAT, NPROC_STATS, LXML_STATS, MYPROC_STATS, LSYNCSTATS, &
+USE YOMGSTATS, ONLY: JPMAXDELAYS, JPMAXSTAT, NPROC_STATS, LXML_STATS, LCSV_STATS, MYPROC_STATS, LSYNCSTATS, &
& LDETAILED_STATS, LSTATS_COMMS, LSTATS_OMP, LBARRIER_STATS2, JBMAXBASE, &
& NBAR_PTR, CCDESC, CCTYPE, LSTATS, TIMESUM, TIMESQSUM, TIMEMAX, TIMESUMB, &
& TIMELCALL, NCALLS, TTCPUSUM, TVCPUSUM, JPTAGSTAT, NPRCIDS_STATS, LSTATS_MPL, &
@@ -73,6 +74,9 @@ SUBROUTINE GSTATS_PRINT(KULOUT,PAVEAVE,KLEN)
REAL(KIND=JPRD) :: PAVEAVE(0:KLEN)
CHARACTER*7 CLACTION(0:3)
CHARACTER(LEN=JPMAXDELAYS*10) CLTEMP
+CHARACTER(LEN=128) :: CSVNAME
+CHARACTER(LEN=32) :: CSVCOLS(15)
+
INTEGER(KIND=JPIM),PARAMETER :: JPARRAYS=8
REAL(KIND=JPRD) :: ZREABUF(JPARRAYS*(JPMAXSTAT+1))
REAL(KIND=JPRD) :: ZAVEAVE(0:JPMAXSTAT),ZAVEMAX(0:JPMAXSTAT),ZTIMELCALL(0:JPMAXSTAT),&
@@ -94,7 +98,7 @@ SUBROUTINE GSTATS_PRINT(KULOUT,PAVEAVE,KLEN)
! LOCAL INTEGER SCALARS
INTEGER(KIND=JPIM) :: ICALLS, ILBUF, ILSEND, ILRECV, &
- &ISEND, ITAG, JJ, JNUM, JROC, JCALL, ICALLER,IACTION
+ &ISEND, ITAG, JJ, I, JNUM, JROC, JCALL, ICALLER,IACTION
INTEGER(KIND=JPIM) :: IMEM, INUM, JMEM
INTEGER(KIND=JPIM) :: JDELAY, IDELAY
INTEGER(KIND=JPIM) :: NSEND,NRECV
@@ -112,7 +116,7 @@ SUBROUTINE GSTATS_PRINT(KULOUT,PAVEAVE,KLEN)
REAL(KIND=JPRD) :: TOTRECVBYTES(501:1000)
REAL(KIND=JPRD) :: TOTSENDBYTESSUM
REAL(KIND=JPRD) :: TOTRECVBYTESSUM
-INTEGER(KIND=JPIM) :: IXMLLUN
+INTEGER(KIND=JPIM) :: IXMLLUN, ICSVUN
! ------------------------------------------------------------------
@@ -151,6 +155,71 @@ SUBROUTINE GSTATS_PRINT(KULOUT,PAVEAVE,KLEN)
ENDIF
ENDDO
ENDIF
+
+! CSV OUTPUT FOR EACH RANK
+IF (LSTATS .AND. LCSV_STATS) THEN
+ ! OPENING THE FILE
+ CSVCOLS='NaN'
+ WRITE(CSVNAME, '(A,I0,A)') 'gstats.', MYPROC_STATS, '.csv'
+ IF (NPROC_STATS <= 1) WRITE(KULOUT, '(A,A)') "GSTATS writing file ", CSVNAME
+ IF (NPROC_STATS > 1) WRITE(KULOUT, '(A,I0,A)') "GSTATS writing files gstats.{1..", NPROC_STATS, "}.csv"
+ OPEN (NEWUNIT=ICSVUN, FILE=CSVNAME, ACTION='write')
+ !write header
+ WRITE(ICSVUN,'(A)') 'GSTATS ID, SECTION, NUMCALLS, TOTAL TIME, MAX TIME, AVE TIME, AVE TIME CPU, AVE TIME VECTOR, STDDEV, NUMSENDS, BYTES SEND, AVE BYTES SEND, NUMRECVS, BYTES RECV, AVE BYTES RECV'
+
+ ! WRITING OUTPUT FOR EVERY RECORDED GSTATS SECTION
+ DO JNUM=0,JPMAXSTAT
+ IF (NCALLS(JNUM) > 1) THEN
+ ! TIMING INFORMATION
+ ICALLS = NCALLS(JNUM)/2
+ IF (ICALLS > 1) THEN
+ ZSTDDEV = 1000._JPRD*SQRT(MAX((TIMESQSUM(JNUM)-TIMESUM(JNUM)**2/REAL(ICALLS,JPRD))/REAL(ICALLS-1,JPRD),0.0_JPRD))
+ ELSE
+ ZSTDDEV= 0.0_JPRD
+ ENDIF
+ WRITE(CSVCOLS(1), '(I0)') JNUM
+ CSVCOLS(2) = CCDESC(JNUM)
+ WRITE(CSVCOLS(3), '(I0)') ICALLS
+ WRITE(CSVCOLS(4), '(F0.6)') TIMESUM(JNUM)
+ WRITE(CSVCOLS(5), '(F0.6)') TIMEMAX(JNUM)*1000._JPRD
+ WRITE(CSVCOLS(6), '(F0.6)') TIMESUM(JNUM)/ICALLS*1000._JPRD
+ WRITE(CSVCOLS(7), '(F0.6)') TTCPUSUM(JNUM)/ICALLS*1000._JPRD
+ WRITE(CSVCOLS(8), '(F0.6)') TVCPUSUM(JNUM)/ICALLS*1000._JPRD
+ WRITE(CSVCOLS(9), '(F0.6)') ZSTDDEV
+
+ ! COMMUNICATION INFORMATION
+ IF (LSTATS_MPL .AND. JNUM > 500 .AND. JNUM < 1001) THEN
+ IF(NUMSEND(JNUM) /= 0) THEN
+ AVGSENDLEN=SENDBYTES(JNUM)*1.E-3_JPRD/NUMSEND(JNUM)
+ ELSE
+ AVGSENDLEN=0.0_JPRD
+ ENDIF
+ IF(NUMRECV(JNUM) /= 0) THEN
+ AVGRECVLEN=RECVBYTES(JNUM)*1.E-3_JPRD/NUMRECV(JNUM)
+ ELSE
+ AVGRECVLEN=0.0_JPRD
+ ENDIF
+ WRITE(CSVCOLS(10), '(I0)') NUMSEND(JNUM)
+ WRITE(CSVCOLS(11), '(F0.6)') SENDBYTES(JNUM)
+ WRITE(CSVCOLS(12), '(F0.6)') AVGSENDLEN
+ WRITE(CSVCOLS(13), '(I0)') NUMRECV(JNUM)
+ WRITE(CSVCOLS(14), '(F0.6)') RECVBYTES(JNUM)
+ WRITE(CSVCOLS(15), '(F0.6)') AVGRECVLEN
+ ENDIF
+ ! WRITE TO CSV FILE
+ DO I = 1, 14
+ WRITE(ICSVUN, '(2A)', advance='no') TRIM(CSVCOLS(I)), ','
+ ENDDO
+ WRITE(ICSVUN, '(A)') TRIM(CSVCOLS(15))
+ CSVCOLS='NaN'
+ ENDIF
+ ENDDO
+
+ ! CLOSING CSV FILES
+ CLOSE(ICSVUN)
+ENDIF
+
+! COLLECTING ALL INFORMATION AT RANK 1 AND COMPUTING FURTHER METRICS
IF (LSTATS .AND. MYPROC_STATS /= 1) THEN
JJ = 1
DO JNUM=0,JPMAXSTAT
@@ -568,7 +637,6 @@ SUBROUTINE GSTATS_PRINT(KULOUT,PAVEAVE,KLEN)
&'',ZFRAC,'',&
&'',ZUNBAL,'',''
ENDIF
-
ZT_SUM=ZT_SUM+ZMEANT
ENDIF
ENDDO
@@ -906,7 +974,9 @@ SUBROUTINE GSTATS_PRINT(KULOUT,PAVEAVE,KLEN)
WRITE(KULOUT,'(" ")')
WRITE(KULOUT,'(" ")')
ENDIF
- CALL MPL_BARRIER(CDSTRING='GSTATS_PRINT')
+ IF (NPROC_STATS > 1) THEN
+ CALL MPL_BARRIER(CDSTRING='GSTATS_PRINT')
+ ENDIF
ENDDO
IF( MYPROC_STATS == 1 )THEN
WRITE(KULOUT,'("MAXIMUM TOTAL UNEXPECTED DELAY TIME (SECS) =",F9.1)') ZDELAY_MAX
@@ -1009,6 +1079,5 @@ SUBROUTINE GSTATS_PRINT(KULOUT,PAVEAVE,KLEN)
WRITE(IXMLLUN,'(A)')''
CLOSE(IXMLLUN)
ENDIF
-
RETURN
END SUBROUTINE GSTATS_PRINT
diff --git a/src/fiat/gstats/gstats_setup.F90 b/src/fiat/gstats/gstats_setup.F90
index e4a30add..8c63f0d0 100644
--- a/src/fiat/gstats/gstats_setup.F90
+++ b/src/fiat/gstats/gstats_setup.F90
@@ -11,7 +11,7 @@
SUBROUTINE GSTATS_SETUP( KPROC,KMYPROC,KPRCIDS,&
& LDSTATS,LDSTATSCPU,LDSYNCSTATS,LDDETAILED_STATS,LDBARRIER_STATS,LDBARRIER_STATS2,&
& LDSTATS_OMP,LDSTATS_COMMS,LDSTATS_MEM,KSTATS_MEM,LDSTATS_ALLOC,&
- & LDTRACE_STATS,KTRACE_STATS,KPRNT_STATS,LDXML_STATS)
+ & LDTRACE_STATS,KTRACE_STATS,KPRNT_STATS,LDXML_STATS,LDCSV_STATS)
!**** *GSTATS_SETUP* - Setup stats package
@@ -56,7 +56,7 @@ SUBROUTINE GSTATS_SETUP( KPROC,KMYPROC,KPRCIDS,&
USE EC_PARKIND, ONLY: JPIM, JPRD
USE YOMGSTATS, ONLY: LSTATS, LSTATSCPU, LSYNCSTATS, LDETAILED_STATS, LBARRIER_STATS, &
- & LBARRIER_STATS2, LXML_STATS, LSTATS_OMP, LSTATS_COMMS, NSTATS_MEM, &
+ & LBARRIER_STATS2, LXML_STATS, LCSV_STATS, LSTATS_OMP, LSTATS_COMMS, NSTATS_MEM, &
& LSTATS_MEM, LSTATS_ALLOC, LTRACE_STATS, NTRACE_STATS, MYPROC_STATS, &
& NPROC_STATS, NPRCIDS_STATS, NCALL_TRACE, TIME_TRACE, LSTATS_MPL, NUMSEND, &
& NUMRECV, SENDBYTES, RECVBYTES, UNKNOWN_NUMSEND, UNKNOWN_NUMRECV, &
@@ -82,15 +82,17 @@ SUBROUTINE GSTATS_SETUP( KPROC,KMYPROC,KPRCIDS,&
LOGICAL :: LDSTATS_MEM
LOGICAL :: LDSTATS_ALLOC
LOGICAL :: LDXML_STATS
+LOGICAL, OPTIONAL :: LDCSV_STATS
! ------------------------------------------------------------------
LSTATS = LDSTATS
LSTATSCPU = LDSTATSCPU
LSYNCSTATS = LDSYNCSTATS
-LDETAILED_STATS=LDDETAILED_STATS
-LBARRIER_STATS=LDBARRIER_STATS
-LBARRIER_STATS2=LDBARRIER_STATS2
-LXML_STATS=LDXML_STATS
+LDETAILED_STATS = LDDETAILED_STATS
+LBARRIER_STATS = LDBARRIER_STATS
+LBARRIER_STATS2 = LDBARRIER_STATS2
+LXML_STATS = LDXML_STATS
+IF (PRESENT(LDCSV_STATS)) LCSV_STATS = LDCSV_STATS
LSTATS_OMP = LDSTATS_OMP
LSTATS_COMMS = LDSTATS_COMMS
NSTATS_MEM = KSTATS_MEM
@@ -99,6 +101,7 @@ SUBROUTINE GSTATS_SETUP( KPROC,KMYPROC,KPRCIDS,&
LTRACE_STATS = LDTRACE_STATS
IF (LTRACE_STATS) NTRACE_STATS = KTRACE_STATS
+
MYPROC_STATS = KMYPROC
NPROC_STATS = KPROC
ALLOCATE(NPRCIDS_STATS(NPROC_STATS))
diff --git a/src/fiat/gstats/yomgstats.F90 b/src/fiat/gstats/yomgstats.F90
index 508c9798..d1b16270 100644
--- a/src/fiat/gstats/yomgstats.F90
+++ b/src/fiat/gstats/yomgstats.F90
@@ -29,6 +29,7 @@ MODULE YOMGSTATS
! start of timing event
! LDETAILED_STATS - TRUE for more detail in output
! LXML_STATS - TRUE for stats output in XML
+! LCSV_STATS - TRUE for stats output in CSV per rank
! LSTATS_OMP - TRUE for gathering timing statistics on OpenMP regions
! 1001-1999
! LSTATS_COMMS - TRUE for gathering detailed timing of Message passing
@@ -71,6 +72,7 @@ MODULE YOMGSTATS
LOGICAL :: LSTATSCPU = .TRUE.
LOGICAL :: LSYNCSTATS = .FALSE.
LOGICAL :: LXML_STATS = .FALSE.
+LOGICAL :: LCSV_STATS = .FALSE.
LOGICAL :: LDETAILED_STATS = .TRUE.
LOGICAL :: LBARRIER_STATS = .FALSE.
LOGICAL :: LBARRIER_STATS2 = .FALSE.
@@ -123,11 +125,11 @@ MODULE YOMGSTATS
INTEGER(KIND=JPIM),PARAMETER :: JPMAXDELAYS=1000
INTEGER(KIND=JPIM) :: NDELAY_COUNTER(1:JPMAXDELAYS)
REAL(KIND=JPRD) :: TDELAY_VALUE(1:JPMAXDELAYS)
-CHARACTER*10 :: CDELAY_TIME(1:JPMAXDELAYS)
+CHARACTER(LEN=10) :: CDELAY_TIME(1:JPMAXDELAYS)
INTEGER(KIND=JPIM) :: NDELAY_INDEX = 0
-CHARACTER*50 :: CCDESC(0:JPMAXSTAT) = ""
-CHARACTER*3 :: CCTYPE(0:JPMAXSTAT) = ""
+CHARACTER(LEN=50) :: CCDESC(0:JPMAXSTAT) = ""
+CHARACTER(LEN=3) :: CCTYPE(0:JPMAXSTAT) = ""
INTEGER(KIND=JPIM) :: NPROC_STATS = 1
INTEGER(KIND=JPIM) :: MYPROC_STATS = 1
diff --git a/src/fiat/include/fiat/gstats_setup.intfb.h b/src/fiat/include/fiat/gstats_setup.intfb.h
index 1f3243b6..6175a029 100644
--- a/src/fiat/include/fiat/gstats_setup.intfb.h
+++ b/src/fiat/include/fiat/gstats_setup.intfb.h
@@ -12,7 +12,7 @@ INTERFACE
SUBROUTINE GSTATS_SETUP( KPROC,KMYPROC,KPRCIDS,&
& LDSTATS,LDSTATSCPU,LDSYNCSTATS,LDDETAILED_STATS,LDBARRIER_STATS,LDBARRIER_STATS2,&
& LDSTATS_OMP,LDSTATS_COMMS,LDSTATS_MEM,KSTATS_MEM,LDSTATS_ALLOC,&
- & LDTRACE_STATS,KTRACE_STATS,KPRNT_STATS,LDXML_STATS)
+ & LDTRACE_STATS,KTRACE_STATS,KPRNT_STATS,LDXML_STATS,LDCSV_STATS)
USE EC_PARKIND, ONLY : JPIM
LOGICAL :: LDSTATS
LOGICAL :: LDSTATSCPU
@@ -31,6 +31,7 @@ INTEGER(KIND=JPIM) :: KPRNT_STATS
LOGICAL :: LDSTATS_MEM
LOGICAL :: LDSTATS_ALLOC
LOGICAL :: LDXML_STATS
+LOGICAL, OPTIONAL :: LDCSV_STATS
END SUBROUTINE
END INTERFACE
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 9795b9a2..ef0eea3d 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -284,6 +284,17 @@ add_test(NAME fiat_test_namelist
-P ${CMAKE_CURRENT_SOURCE_DIR}/test_program_output.cmake )
# ----------------------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------------------
+# Tests: test_gstats_fortran (only gstats print csv so far)
+ecbuild_add_test(
+ TARGET fiat_test_gstats
+ SOURCES test_gstats.F90
+ LIBS fiat
+ LINKER_LANGUAGE Fortran
+ )
+# ----------------------------------------------------------------------------------------
+
# Test installation of fiat is working
configure_file( test-install.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-install.sh @ONLY )
diff --git a/tests/test_gstats.F90 b/tests/test_gstats.F90
new file mode 100644
index 00000000..d00ffcf4
--- /dev/null
+++ b/tests/test_gstats.F90
@@ -0,0 +1,184 @@
+! (C) COPYRIGHT 2005- ECMWF.
+!
+! LICENSE: APACHE LICENSE VERSION 2.0
+! SEE http://www.apache.org/licenses/LICENSE-2.0
+! IN APPLYING THIS LICENCE, ECMWF DOES NOT WAIVE ANY PRIVILEGES
+! AND DOES NOT SUBMIT TO ANY JURISDICTION.
+
+PROGRAM TEST_GSTATS
+ USE YOMGSTATS, ONLY : JPMAXSTAT
+ USE EC_PARKIND, ONLY : JPRD
+ USE EC_LUN, ONLY : NULOUT
+ IMPLICIT NONE
+ REAL(JPRD) :: AVEARRAY(0:JPMAXSTAT)
+
+ CALL TEST_INIT()
+ CALL GSTATS(0,0)
+ CALL GSTATS(1,0)
+ CALL WORK_SECTION_1()
+ CALL GSTATS(1,1)
+ CALL GSTATS(2,0)
+ CALL WORK_SECTION_2()
+ CALL GSTATS(2,1)
+ CALL GSTATS(0,1)
+ CALL GSTATS_PRINT(NULOUT,AVEARRAY, JPMAXSTAT)
+
+ ! CHECK THAT THE CSV FILE EXISTS
+ CALL CHECK_OUTPUT()
+ CALL TEST_END()
+
+CONTAINS
+
+ ! ---------------------------------------------------------------------
+ SUBROUTINE WORK_SECTION_1
+ IMPLICIT NONE
+ REAL(JPRD) :: X
+ INTEGER :: I
+ X = 0.0_JPRD
+ DO I = 1, 5000000
+ X = X + SIN(REAL(I))
+ END DO
+ END SUBROUTINE WORK_SECTION_1
+ ! ---------------------------------------------------------------------
+
+ SUBROUTINE WORK_SECTION_2
+ IMPLICIT NONE
+ REAL(JPRD) :: X
+ INTEGER :: I
+ X = 1.0
+ DO I = 1, 4000000
+ X = X * 1.0000001_JPRD
+ END DO
+ END SUBROUTINE WORK_SECTION_2
+ ! ---------------------------------------------------------------------
+
+ SUBROUTINE TEST_INIT
+ USE MPL_MODULE, ONLY : MPL_RANK, MPL_NUMPROC, MPL_INIT
+ USE EC_LUN, ONLY : NULOUT
+
+ INTEGER :: KPROC, KMYPROC, JPROC
+ INTEGER, ALLOCATABLE :: KPRCIDS(:)
+ LOGICAL :: LDSTATS, LDSTATSCPU, LDSYNCSTATS
+ LOGICAL :: LDDETAILED_STATS, LDBARRIER_STATS, LDBARRIER_STATS2
+ LOGICAL :: LDSTATS_OMP, LDSTATS_COMMS, LDSTATS_MEM
+ LOGICAL :: LDSTATS_ALLOC, LDTRACE_STATS, LDXML_STATS, LDCSV_STATS
+ INTEGER :: KSTATS_MEM, KTRACE_STATS, KPRNT_STATS
+ LOGICAL :: LUSE_MPI
+
+#include "gstats_setup.intfb.h"
+
+ ! INITIALIZE ENVIRONMENT
+ LUSE_MPI = DETECT_MPIRUN()
+ KPROC = 1
+ KMYPROC = 1
+ IF (LUSE_MPI) THEN
+ CALL MPL_INIT(LDINFO=.TRUE.)
+ KMYPROC = MPL_RANK
+ KPROC = MPL_NUMPROC
+ ENDIF
+ IF (KMYPROC == 1) THEN
+ WRITE(0,*) "LUSE_MPI: ", LUSE_MPI
+ WRITE(0,*) "NPROC: ", KPROC
+ ELSE
+ ! All other ranks set EC_LUN's NULOUT to /dev/null
+ OPEN(UNIT=NULOUT, FILE='/dev/null')
+ ENDIF
+ ALLOCATE(KPRCIDS(KPROC))
+
+ LDSTATS = .TRUE.
+ LDSTATSCPU = .FALSE.
+ LDSYNCSTATS = .FALSE.
+ LDDETAILED_STATS = .TRUE.
+ LDBARRIER_STATS = .FALSE.
+ LDBARRIER_STATS2 = .FALSE.
+ LDSTATS_OMP = .FALSE.
+ LDSTATS_COMMS = .FALSE.
+ LDSTATS_MEM = .FALSE.
+ KSTATS_MEM = 0
+ LDSTATS_ALLOC = .FALSE.
+ LDTRACE_STATS = .FALSE.
+ KTRACE_STATS = 0
+ KPRNT_STATS = KPROC
+ LDXML_STATS = .FALSE.
+ LDCSV_STATS = .TRUE.
+ DO JPROC = 1, KPROC
+ KPRCIDS(JPROC) = JPROC
+ ENDDO
+
+ CALL GSTATS_SETUP( KPROC, KMYPROC, KPRCIDS, &
+ LDSTATS, LDSTATSCPU, LDSYNCSTATS, LDDETAILED_STATS, &
+ LDBARRIER_STATS, LDBARRIER_STATS2, &
+ LDSTATS_OMP, LDSTATS_COMMS, LDSTATS_MEM, KSTATS_MEM, LDSTATS_ALLOC, &
+ LDTRACE_STATS, KTRACE_STATS, KPRNT_STATS, LDXML_STATS, LDCSV_STATS )
+ CALL GSTATS_LABEL(0, " ", "TOTAL EXECUTION")
+ CALL GSTATS_LABEL(1, "CAT 1", "WORK 1") ! Note that second argument will be truncated to 3 chars
+ CALL GSTATS_LABEL(2, "CAT 1", "WORK 2") ! Note that second argument will be truncated to 3 chars
+ CALL GSTATS_PSUT
+
+ END SUBROUTINE TEST_INIT
+ ! ---------------------------------------------------------------------
+
+ SUBROUTINE TEST_END
+ USE MPL_MODULE, ONLY : MPL_END, MPL_NUMPROC
+ IF (MPL_NUMPROC > 0) THEN
+ CALL MPL_END(LDMEMINFO=.FALSE.)
+ ENDIF
+ END SUBROUTINE TEST_END
+ ! ---------------------------------------------------------------------
+
+ SUBROUTINE CHECK_OUTPUT
+ USE MPL_MODULE, ONLY : MPL_RANK, MPL_NUMPROC
+ IMPLICIT NONE
+ LOGICAL :: EXISTS
+ CHARACTER(LEN=32) :: FNAME
+ INTEGER :: U
+ INTEGER :: MYPROC
+
+ MYPROC = 1
+ IF (MPL_NUMPROC > 0) THEN
+ MYPROC = MPL_RANK
+ ENDIF
+ WRITE(FNAME, '(A,I0,A)') 'gstats.', MYPROC, '.csv'
+
+ INQUIRE(FILE=FNAME, EXIST=EXISTS)
+
+ IF (.NOT. EXISTS) THEN
+ PRINT *, "ERROR: GSTATS DID NOT CREATE FILE: ", TRIM(FNAME)
+ STOP 1
+ ELSE
+ OPEN(NEWUNIT=U, FILE=FNAME, STATUS='OLD')
+ CLOSE(U, STATUS='DELETE')
+ PRINT *, "OK: FILE GENERATED: ", TRIM(FNAME)
+ END IF
+ END SUBROUTINE CHECK_OUTPUT
+ ! ---------------------------------------------------------------------
+
+ function detect_mpirun() result(lmpi_required)
+ logical :: lmpi_required
+ integer :: ilen
+ integer, parameter :: nvars = 5
+ character(len=32), dimension(nvars) :: cmpirun_detect
+ character(len=4) :: clenv_dr_hook_assert_mpi_initialized
+ integer :: ivar
+ lmpi_required = .false.
+#if defined(NOMPI)
+ return
+#endif
+ ! Environment variables that are set when mpirun, srun, aprun, ... are used
+ cmpirun_detect(1) = 'OMPI_COMM_WORLD_SIZE' ! openmpi
+ cmpirun_detect(2) = 'ALPS_APP_PE' ! cray pe
+ cmpirun_detect(3) = 'PMI_SIZE' ! intel
+ cmpirun_detect(4) = 'SLURM_NTASKS' ! slurm
+ cmpirun_detect(5) = 'FIAT_USE_MPI' ! forced
+
+ do ivar = 1, nvars
+ call get_environment_variable(name=trim(cmpirun_detect(ivar)), length=ilen)
+ if (ilen > 0) then
+ lmpi_required = .true.
+ exit ! break
+ endif
+ enddo
+ end function
+
+ END PROGRAM TEST_GSTATS
+
\ No newline at end of file