*IF DEF,C97_1A,OR,DEF,RECON,OR,DEF,MAKEBC UIE3F404.58
C ******************************COPYRIGHT****************************** GTS2F400.10405
C (c) CROWN COPYRIGHT 1995, METEOROLOGICAL OFFICE, All Rights Reserved. GTS2F400.10406
C GTS2F400.10407
C Use, duplication or disclosure of this code is subject to the GTS2F400.10408
C restrictions as set forth in the contract. GTS2F400.10409
C GTS2F400.10410
C Meteorological Office GTS2F400.10411
C London Road GTS2F400.10412
C BRACKNELL GTS2F400.10413
C Berkshire UK GTS2F400.10414
C RG12 2SZ GTS2F400.10415
C GTS2F400.10416
C If no contract has been raised with this copy of the code, the use, GTS2F400.10417
C duplication or disclosure of it is strictly prohibited. Permission GTS2F400.10418
C to do so must first be obtained in writing from the Head of Numerical GTS2F400.10419
C Modelling at the above address. GTS2F400.10420
C ******************************COPYRIGHT****************************** GTS2F400.10421
C GTS2F400.10422
SUBROUTINE TIMER(SUB,I) 924,33TIMER1A.3
CFPP$ NOCONCUR R TIMER1A.4
! .................................................................. GIE1F304.2
! SUBROUTINE TIMER GIE1F304.3
! ---------------- GIE1F304.4
! A PROGRAM TO RECORD THE FLOW THROUGH AND TIME SPENT IN EACH GIE1F304.5
! SUBROUTINE OF A MULTI SUBROUTINED PROGRAM. GIE1F304.6
! CALLS TO TIMER MUST BE MADE BEFORE THE FIRST EXECUTABLE STATEMENT GIE1F304.7
! OF EACH SUBROUTINE AND BEFORE EACH RETURN POINT. GIE1F304.8
! GIE1F304.9
! PARAMETERS: GIE1F304.10
! SUB - 8 BYTE CHARACTER STRING CONTAINING NAME OF CALLING GIE1F304.11
! PROGRAM WHICH HAS BEEN LEFT ADJUSTED GIE1F304.12
! GIE1F304.13
! I - I=1 - FIRST CALL FROM MAIN (OR THE HIGHEST LEVEL PROGRAM) GIE1F304.14
! I=2 - LAST CALL FROM MAIN ( OR THE HIGHEST LEVEL PROGRAM) GIE1F304.15
! I=3 - FIRST CALL FROM LOWER SUBROUTINE GIE1F304.16
! I=4 CALL BEFORE RETURN STATEMENTS IN LOWER SUBROUTINE GIE1F304.17
! GIE1F304.18
! ---NOTE :THE CRAY FACILITY PERFTRACE IS MORE APPROPRIATE FOR SINGLE GIE1F304.19
! TASKED TIMING DIAGNOSTICS, BUT A BREAKDOWN OF ELAPSE TIME BY GIE1F304.20
! SUBROUTINE OF MULTITASKED JOBS IS UNAVAILABLE WITHOUT THIS HOMEMADE GIE1F304.21
! TIMER ROUTINE GIE1F304.22
! GIE1F304.23
! REVISED TO CONFORM WITH UM SOFTWARE STANDARDS, THIS VERSION RUNS GIE1F304.24
! ON BOTH THE CRAY & HP WORKSTATIONS. IF THERE ARE > 200 DIFFERENT GIE1F304.25
! SUBROUTINE CALLS TO TIMER, FINAL TABLE REPLACED BY WARNING MESSAGE. GIE1F304.26
! .................................................................. GIE1F304.27
! ---AUTHOR OF THIS REVISION IAN EDMOND GIE1F304.28
! ---DATE 12/04/94 GIE1F304.29
! GIE1F304.30
! Model Modification history from model version 3.0: GIE1F304.31
! version Date GIE1F304.32
CLL 4.1 12/03/96 Changes to avoid clashes with TIMER2A GPB1F401.2
CLL P.Burton GPB1F401.3
!LL 4.5 17/04/98 Modified to cope with action (I) > 100 GPB8F405.20
!LL intended for MPP timer. P.Burton GPB8F405.21
! 4.5 12/06/98 Use CLOCK(...,0,2) for CPUtime on Fujitsu. GRB1F405.8
! RBarnes@ecmwf.int GRB1F405.9
! GIE1F304.33
! Programming standard : GIE1F304.34
! GIE1F304.35
! Logical components covered : D66 GIE1F304.36
! GIE1F304.37
! Project task : GIE1F304.38
! GIE1F304.39
! External documentation: GIE1F304.40
! GIE1F304.41
! --------------------------------------------------------------------- GIE1F304.42
! GIE1F304.43
TIMER1A.54
IMPLICIT NONE GIE1F304.44
TIMER1A.63
INTEGER KLIMIT GIE1F304.45
PARAMETER(KLIMIT=200) GIE1F304.46
CHARACTER*8 SUB,SUBNAME(KLIMIT),RETURNAM(KLIMIT),SWORK GIE1F304.47
INTEGER NENTER(KLIMIT),I,L,J,K,NSUBS,ISTOP,NCALLS,IWORK GIE1F304.48
INTEGER ICALL
PXTIMER1.4
REAL ELAPSE(KLIMIT),TOTE,ELPEND,ELPSTART,CPUSTART,TOT,AT,CPUEND GIE1F304.49
REAL TOTELAP,AVELAP,PCENT,RWORK,TOTLAP,SPEEDUP,P,TIME(KLIMIT) GIE1F304.50
REAL UWORK GIE1F304.51
SAVE SUBNAME,RETURNAM,NENTER,ELAPSE,TIME GIE1F304.52
SAVE K,J,NSUBS,ELPSTART,ISTOP,CPUSTART GIE1F304.53
GIE1F304.54
REAL SECOND GIE1F304.55
*IF DEF,SGI PXTIMEFN.26
REAL (KIND=8) TIMEF PXTIMEFN.27
*ENDIF PXTIMEFN.28
! ----------------------------------------------------------------- GIE1F304.56
IF (I .GT. 100) THEN PXTIMER1.5
ICALL=I-100 PXTIMER1.6
ELSE PXTIMER1.7
ICALL=I PXTIMER1.8
ENDIF PXTIMER1.9
IF (ICALL.EQ.1) THEN
PXTIMER1.10
GIE1F304.58
! First call to timer from the main program GIE1F304.59
! Set up initial values of variables GIE1F304.60
GIE1F304.61
K = 1 GIE1F304.62
J = 0 GIE1F304.63
ISTOP = 0 GIE1F304.64
NSUBS = 1 GIE1F304.65
SUBNAME(1)= SUB GIE1F304.66
GIE1F304.67
DO L=1,KLIMIT GIE1F304.68
ELAPSE(L) = 0.0 GIE1F304.69
TIME(L) = 0.0 GIE1F304.70
NENTER(L) = 0 GIE1F304.71
TIMER1A.68
ENDDO GIE1F304.72
GIE1F304.73
NENTER(1)=1 TIMER1A.69
*IF -DEF,SGI PXTIMEFN.29
CALL TIMEF
(ELPSTART) TIMER1A.70
*ELSE PXTIMEFN.30
ELPSTART=TIMEF() PXTIMEFN.31
*ENDIF PXTIMEFN.32
*IF -DEF,FUJITSU GRB1F405.10
CPUSTART=SECOND
(CPUSTART) GIE1F304.74
*ELSE GRB1F405.11
CALL CLOCK(
CPUSTART,0,2) GRB1F405.12
*ENDIF GRB1F405.13
TIMER1A.73
! ----------------------------------------------------------------- GIE1F304.75
ELSEIF ((ICALL.EQ.2).AND.(ISTOP.EQ.0)) THEN PXTIMER1.11
TIMER1A.79
! Last call to timer from main program GIE1F304.77
! Print out table of results GIE1F304.78
GIE1F304.79
*IF -DEF,FUJITSU GRB1F405.14
! Stop timer GIE1F304.80
*ELSE GRB1F405.15
CALL CLOCK(
CPUEND,0,2) GRB1F405.16
*ENDIF GRB1F405.17
CPUEND=SECOND
() TIMER1A.81
*IF -DEF,SGI PXTIMEFN.33
CALL TIMEF
(ELPEND) TIMER1A.82
*ELSE PXTIMEFN.34
ELPEND=TIMEF() PXTIMEFN.35
*ENDIF PXTIMEFN.36
ELAPSE(1)=ELAPSE(1)+(ELPEND-ELPSTART)*1.E-3 GIE1F304.81
TIME(1)=TIME(1)+CPUEND-CPUSTART GIE1F304.82
GIE1F304.83
! Calculate total time in program GIE1F304.84
TOTE=0.0 GIE1F304.85
TOT=0.0 GIE1F304.86
DO K=1,NSUBS GIE1F304.87
GIE1F304.88
TOTE=TOTE+ELAPSE(K) GIE1F304.89
TOT=TOT+TIME(K) GIE1F304.90
GIE1F304.91
ENDDO GIE1F304.92
GIE1F304.93
! Sort subroutines into time order GIE1F304.94
GIE1F304.95
DO K=1,(NSUBS-1) GIE1F304.96
GIE1F304.97
DO J=(K+1),NSUBS GIE1F304.98
GIE1F304.99
IF (TIME(J).GT.TIME(K)) THEN GIE1F304.100
GIE1F304.101
! Swap the values: GIE1F304.102
RWORK=TIME(K) GIE1F304.103
TIME(K)=TIME(J) GIE1F304.104
TIME(J)=RWORK GIE1F304.105
UWORK=ELAPSE(K) GIE1F304.106
ELAPSE(K)=ELAPSE(J) GIE1F304.107
ELAPSE(J)=UWORK GIE1F304.108
IWORK=NENTER(K) GIE1F304.109
NENTER(K)=NENTER(J) GIE1F304.110
NENTER(J)=IWORK GIE1F304.111
SWORK=SUBNAME(K) GIE1F304.112
SUBNAME(K)=SUBNAME(J) GIE1F304.113
SUBNAME(J)=SWORK GIE1F304.114
GIE1F304.115
ENDIF GIE1F304.116
GIE1F304.117
ENDDO GIE1F304.118
GIE1F304.119
ENDDO GIE1F304.120
GIE1F304.121
GIE1F304.122
! Output timing information GIE1F304.123
GIE1F304.124
GIE1F304.125
WRITE(*,'(''1'',//,20X,'' FLOW TRACE SUMMARY'',/)') GIE1F304.126
WRITE(*,'(4X,''ROUTINE'',6X,''CPU'',6X,''%'',3X, GIE1F304.127
& ''CALLS'',2X,''AVERAGE'',4X,''ELAPSE'',4X,''%'' GIE1F304.128
& ,6X,''AVERAGE'',1X,''CPU'')') GIE1F304.129
WRITE(*,'(17X,''TIME'',4X,''CPU'',9X,''CPUTIME'',4X, GIE1F304.130
& ''TIME'',3X,''ELAPSE'',4X,''ELAPSE'',2X,''SPEEDUP'')') GIE1F304.131
GIE1F304.132
DO K=1,NSUBS GIE1F304.133
GIE1F304.134
SWORK=SUBNAME(K) PXTIMER1.1
TOTLAP=TIME(K) GIE1F304.136
TOTELAP=ELAPSE(K) GIE1F304.137
NCALLS=NENTER(K) GIE1F304.138
AVELAP=TOTELAP/NCALLS GIE1F304.139
P=100.0*TOTLAP/TOT GIE1F304.140
PCENT=100.0*TOTELAP/TOTE GIE1F304.141
AT=TIME(K)/NENTER(K) GIE1F304.142
IF (AVELAP.EQ.0.0) THEN GIE1F304.143
SPEEDUP=0.0 GIE1F304.144
ELSE GIE1F304.145
SPEEDUP=AT/AVELAP GIE1F304.146
ENDIF GIE1F304.147
WRITE(*,'(/,T1,I3,T5,A8,T13,F10.4,T25,F5.2,T30, GIE1F304.148
& I5,T35,F10.4,T45,F10.4,T57,F5.2,T62,F10.4,T74,F5.2)') GIE1F304.149
& K,SWORK,TOTLAP,P,NENTER(K),AT,TOTELAP,PCENT,AVELAP, PXTIMER1.2
& SPEEDUP PXTIMER1.3
GIE1F304.151
ENDDO GIE1F304.152
GIE1F304.153
SPEEDUP=TOT/TOTE GIE1F304.154
WRITE(*,'(/,T3,''**TOTAL'',T12,F11.4,T44,F11.4, GIE1F304.155
& T74,F5.2)')TOT,TOTE,SPEEDUP GIE1F304.156
GIE1F304.157
! ----------------------------------------------------------------- GIE1F304.158
ELSEIF ((ICALL.EQ.3).AND.(ISTOP.EQ.0)) THEN PXTIMER1.12
GIE1F304.160
! First call in subroutine GIE1F304.161
GIE1F304.162
! Switch off timer GIE1F304.163
*IF -DEF,FUJITSU GRB1F405.18
CPUEND=SECOND
() GIE1F304.164
*ELSE GRB1F405.19
CALL CLOCK(
CPUEND,0,2) GRB1F405.20
*ENDIF GRB1F405.21
*IF -DEF,SGI PXTIMEFN.37
CALL TIMEF
(ELPEND) GIE1F304.165
*ELSE PXTIMEFN.38
ELPEND=TIMEF() PXTIMEFN.39
*ENDIF PXTIMEFN.40
ELAPSE(K)=ELAPSE(K)+(ELPEND-ELPSTART)*1.E-3 TIMER1A.84
TIME(K)=TIME(K)+CPUEND-CPUSTART GIE1F304.166
TIMER1A.85
! Save name of calling subroutine GIE1F304.167
J=J+1 TIMER1A.87
RETURNAM(J)=SUBNAME(K) TIMER1A.88
TIMER1A.89
! Check subroutine name GIE1F304.168
DO K=1,NSUBS GIE1F304.169
GIE1F304.170
IF (SUBNAME(K).EQ.SUB) GOTO 10 GIE1F304.171
GIE1F304.172
ENDDO GIE1F304.173
GIE1F304.174
! New subroutine entered GIE1F304.175
NSUBS=NSUBS+1 TIMER1A.95
IF (NSUBS .LE. KLIMIT) THEN GIE1F304.176
GIE1F304.177
SUBNAME(NSUBS)=SUB TIMER1A.96
K=NSUBS TIMER1A.97
TIMER1A.99
ELSE GIE1F304.178
GIE1F304.179
WRITE(*,'(''WARNING: More than''I4 GIE1F304.180
& '' different subroutine calls to TIMER'')')KLIMIT
GIE1F304.181
ISTOP=1 GIE1F304.182
GOTO 9999 GIE1F304.183
GIE1F304.184
ENDIF GIE1F304.185
GIE1F304.186
10 CONTINUE GIE1F304.187
GIE1F304.188
! Start timer for subroutine GIE1F304.189
NENTER(K)=NENTER(K)+1 TIMER1A.101
*IF -DEF,SGI PXTIMEFN.41
CALL TIMEF
(ELPSTART) TIMER1A.102
*ELSE PXTIMEFN.42
ELPSTART=TIMEF() PXTIMEFN.43
*ENDIF PXTIMEFN.44
*IF -DEF,FUJITSU GRB1F405.22
CPUSTART=SECOND
() TIMER1A.103
*ELSE GRB1F405.23
CALL CLOCK(
CPUSTART,0,2) GRB1F405.24
*ENDIF GRB1F405.25
! ----------------------------------------------------------------- GIE1F304.190
ELSEIF ((ICALL.EQ.4).AND.(ISTOP.EQ.0)) THEN PXTIMER1.13
TIMER1A.105
! Return from subroutine GIE1F304.192
TIMER1A.111
! Stop timer GIE1F304.193
*IF -DEF,FUJITSU GRB1F405.26
CPUEND=SECOND
() TIMER1A.113
*ELSE GRB1F405.27
CALL CLOCK(
CPUEND,0,2) GRB1F405.28
*ENDIF GRB1F405.29
*IF -DEF,SGI PXTIMEFN.45
CALL TIMEF
(ELPEND) TIMER1A.114
*ELSE PXTIMEFN.46
ELPEND=TIMEF() PXTIMEFN.47
*ENDIF PXTIMEFN.48
ELAPSE(K)=ELAPSE(K)+(ELPEND-ELPSTART)*1.E-3 TIMER1A.115
TIME(K)=TIME(K)+CPUEND-CPUSTART TIMER1A.116
TIMER1A.117
! Find name of calling program GIE1F304.194
DO K=1,NSUBS GIE1F304.195
GIE1F304.196
IF (SUBNAME(K).EQ.RETURNAM(J)) GOTO 11 GIE1F304.197
GIE1F304.198
ENDDO GIE1F304.199
GIE1F304.200
WRITE(*,'(3X,''Calling prog:-'',1X,A8,1X,''not found
GIE1F304.201
& ,now in'',1X,A8/3X,''TIMER being DISABLED for the rest GIE1F304.202
& of this run'')')RETURNAM(J),SUBNAME(J+1) GIE1F304.203
ISTOP=1 TIMER1A.125
GOTO 9999 GIE1F304.204
11 CONTINUE GIE1F304.205
TIMER1A.128
! Start timer for calling program GIE1F304.206
*IF -DEF,SGI PXTIMEFN.49
CALL TIMEF
(ELPSTART) TIMER1A.130
*ELSE PXTIMEFN.50
ELPSTART=TIMEF() PXTIMEFN.51
*ENDIF PXTIMEFN.52
*IF -DEF,FUJITSU GRB1F405.30
CPUSTART=SECOND
() TIMER1A.131
*ELSE GRB1F405.31
CALL CLOCK(
CPUSTART,0,2) GRB1F405.32
*ENDIF GRB1F405.33
J=J-1 TIMER1A.132
TIMER1A.134
! ----------------------------------------------------------------- GIE1F304.207
ELSEIF ((ICALL.LT.1).OR.(ICALL.GT.6)) THEN
PXTIMER1.14
GPB1F401.5
! If ICALL<1 or ICALL>6 then there is an error. PXTIMER1.15
! If 4<ICALL<=6 then this call PXTIMER1.16
! to TIMER is ignored. These values of I are recognised by the GPB1F401.7
! TIMER3A version. GPB1F401.8
TIMER1A.147
WRITE(*,'(3X, GIE1F304.210
& ''Illegal call to TIMER by subroutine'',1X,A8)')SUB
GIE1F304.211
TIMER1A.150
ENDIF GIE1F304.212
TIMER1A.159
9999 CONTINUE GIE1F304.213
TIMER1A.165
RETURN GIE1F304.214
END GIE1F304.215
TIMER1A.178
GIE1F304.216
*ENDIF TIMER1A.186