*IF DEF,C97_3A TIMER3A.2
C ******************************COPYRIGHT****************************** TIMER3A.3
C (c) CROWN COPYRIGHT 1996, METEOROLOGICAL OFFICE, All Rights Reserved. TIMER3A.4
C TIMER3A.5
C Use, duplication or disclosure of this code is subject to the TIMER3A.6
C restrictions as set forth in the contract. TIMER3A.7
C TIMER3A.8
C Meteorological Office TIMER3A.9
C London Road TIMER3A.10
C BRACKNELL TIMER3A.11
C Berkshire UK TIMER3A.12
C RG12 2SZ TIMER3A.13
C TIMER3A.14
C If no contract has been raised with this copy of the code, the use, TIMER3A.15
C duplication or disclosure of it is strictly prohibited. Permission TIMER3A.16
C to do so must first be obtained in writing from the Head of Numerical TIMER3A.17
C Modelling at the above address. TIMER3A.18
C ******************************COPYRIGHT****************************** TIMER3A.19
C TIMER3A.20
CLL SUBROUTINE TIMER ------------------------------------------------ TIMER3A.21
CLL TIMER3A.22
CLL Purpose: TIMER3A.23
CLL Allows the recording of time spent in any section of the program TIMER3A.24
CLL Two types of timings are supported: TIMER3A.25
CLL non-inclusive : if a timed section of code (1) contains another TIMER3A.26
CLL timed section of code (2), then the timing for TIMER3A.27
CLL section (1) will not include the time spent in TIMER3A.28
CLL section (2). This is the normal use for the timer TIMER3A.29
CLL routine in the UM up to vn3.4 TIMER3A.30
CLL inclusive : allows the user to measure the time taken between TIMER3A.31
CLL any two points in the code, irrespective of any TIMER3A.32
CLL other calls to the timer routine within the timed TIMER3A.33
CLL section TIMER3A.34
CLL TIMER3A.35
CLL NB: Non-inclusive timers DO INCLUDE any inclusive timer sections TIMER3A.36
CLL contained within them. If this section of code should not be TIMER3A.37
CLL included, then also time it with a non-inclusive timer TIMER3A.38
CLL TIMER3A.39
CLL Timer now also records the time spent in itself TIMER3A.40
CLL Parameters: TIMER3A.41
CLL section_name - 20 byte character string containing name of TIMER3A.42
CLL timer reference TIMER3A.43
CLL TIMER3A.44
CLL action: TIMER3A.45
CLL 1 -> first call to timer (timer initialisation) TIMER3A.46
CLL 2 -> last call to timer (prints out the collected data) TIMER3A.47
CLL 3 -> non-inclusive start timer TIMER3A.48
CLL 4 -> non-inclusive end timer TIMER3A.49
CLL 5 -> inclusive start timer TIMER3A.50
CLL 6 -> inclusive end timer TIMER3A.51
CLL TIMER3A.52
CLL Timer should be called with action=1 before the first executable TIMER3A.53
CLL statement, and with action=2 after the last executable statement. TIMER3A.54
CLL TIMER3A.55
CLL Model Modification History TIMER3A.56
CLL version Date TIMER3A.57
CLL 4.1 16/08/94 Based on old UM timer routine TIMER3A.58
!LL 4.2 08/10/96 Corrected intermediate timer error in APB4F402.1
!LL elapsed times. APB4F402.2
!LL Corrected size of message arg. in APB4F402.3
!LL TIMER_OUTPUT. APB4F402.4
!LL P.Burton APB4F402.5
!LL 4.3 23/01/97 Added better overview for MPP runs GPB3F403.122
!LL Corrected T3E wallclock time calculation GPB3F403.123
!LL P.Burton GPB3F403.124
!LL 4.5 17/04/98 Added barrier to allow imbalance to be GPB8F405.1
!LL included in the correct timer section GPB8F405.2
!LL P.Burton GPB8F405.3
!LL 4.5 09/07/98 Replaced missing array index for GPB0F405.128
!LL last_ni_wallclock_time_elapsed. GPB0F405.129
!LL P. Burton GPB0F405.130
CLL TIMER3A.59
CLL Author : Paul Burton TIMER3A.60
CLL TIMER3A.61
TIMER3A.62
SUBROUTINE TIMER(section_name,action) 924,33TIMER3A.63
TIMER3A.64
IMPLICIT NONE TIMER3A.65
TIMER3A.66
! Arguments: TIMER3A.67
CHARACTER*(*) section_name ! IN reference name for timed section TIMER3A.68
INTEGER action ! IN what action to take TIMER3A.69
TIMER3A.70
! Local variables: TIMER3A.71
! ni prefix = non-inclusive timings TIMER3A.72
! in prefix = inclusive timings TIMER3A.73
TIMER3A.74
TIMER3A.75
INTEGER max_timers ! maximum number of timings to be handled TIMER3A.76
PARAMETER ( max_timers=300 ) TIMER3A.77
TIMER3A.78
CHARACTER*20 ni_timer_name(max_timers), TIMER3A.79
& ! names of timer references TIMER3A.80
& in_timer_name(max_timers) TIMER3A.81
& ! names of timer references TIMER3A.82
TIMER3A.83
INTEGER ni_number_of_times_timed(max_timers), TIMER3A.84
& ! number of times that a section of code TIMER3A.85
& ! has been timed TIMER3A.86
& in_number_of_times_timed(max_timers) TIMER3A.87
& ! number of times that a section of code TIMER3A.88
& ! has been timed TIMER3A.89
TIMER3A.90
INTEGER old_timer(max_timers) TIMER3A.91
& ! the reference of the timer stopped when TIMER3A.92
& ! a new one is started TIMER3A.93
TIMER3A.94
REAL ni_cpu_time_elapsed(max_timers), TIMER3A.95
& ! total amount of cpu time spent in TIMER3A.96
& ! a section of code TIMER3A.97
& ni_wallclock_time_elapsed(max_timers), TIMER3A.98
& ! total amount of wallclock time TIMER3A.99
& in_cpu_time_elapsed(max_timers), TIMER3A.100
& ! total amount of time spent in a section TIMER3A.101
& ! of code TIMER3A.102
& in_wallclock_time_elapsed(max_timers) TIMER3A.103
& ! total amount of wallclock time TIMER3A.104
TIMER3A.105
REAL ni_cpu_time_started, TIMER3A.106
& ! for non-inclusive timer - cpu time TIMER3A.107
& ! of starting TIMER3A.108
& ni_wallclock_time_started, TIMER3A.109
& ! wallclock time of starting TIMER3A.110
& in_cpu_time_started(max_timers), TIMER3A.111
& ! for inclusive timer - cpu time TIMER3A.112
& !of starting TIMER3A.113
& in_wallclock_time_started(max_timers) TIMER3A.114
& ! wallclock time of starting TIMER3A.115
TIMER3A.116
INTEGER current_timer ! for non-inclusive timer - current TIMER3A.117
& ! section of code being timed TIMER3A.118
INTEGER ni_number_of_timers, TIMER3A.119
& ! number of timers currently known about TIMER3A.120
& in_number_of_timers TIMER3A.121
& ! number of timers currently known about TIMER3A.122
TIMER3A.123
LOGICAL in_timer_running(max_timers) TIMER3A.124
& ! is a particular timer running? TIMER3A.125
TIMER3A.126
INTEGER section_ref ! reference of the current section TIMER3A.127
TIMER3A.128
TIMER3A.129
TIMER3A.130
REAL cpu_time_into_timer, TIMER3A.131
& ! cpu time at which timer routine entered TIMER3A.132
& wallclock_time_into_timer ! wallclock " TIMER3A.133
TIMER3A.134
LOGICAL timer_on ! set to FALSE if an error occurs TIMER3A.135
TIMER3A.136
! Saved variables: TIMER3A.137
SAVE ni_timer_name,in_timer_name, TIMER3A.138
& ni_number_of_times_timed,in_number_of_times_timed, TIMER3A.139
& ni_cpu_time_elapsed,in_cpu_time_elapsed, TIMER3A.140
& ni_wallclock_time_elapsed,in_wallclock_time_elapsed, TIMER3A.141
& ni_cpu_time_started,in_cpu_time_started, TIMER3A.142
& ni_wallclock_time_started,in_wallclock_time_started, TIMER3A.143
& current_timer , TIMER3A.144
& ni_number_of_timers, in_number_of_timers, TIMER3A.145
& in_timer_running, TIMER3A.146
& old_timer, timer_on TIMER3A.147
TIMER3A.148
! Magic numbers (action types): TIMER3A.149
INTEGER first_call_to_timer,
TIMER3A.150
& last_call_to_timer, TIMER3A.151
& non_incl_start_timer, TIMER3A.152
& non_incl_end_timer, TIMER3A.153
& incl_start_timer, TIMER3A.154
& incl_end_timer, TIMER3A.155
& intermediate_output TIMER3A.156
TIMER3A.157
PARAMETER ( first_call_to_timer = 1,
TIMER3A.158
& last_call_to_timer = 2,
TIMER3A.159
& non_incl_start_timer = 3, TIMER3A.160
& non_incl_end_timer = 4, TIMER3A.161
& incl_start_timer = 5, TIMER3A.162
& incl_end_timer = 6, TIMER3A.163
& intermediate_output = 7 ) TIMER3A.164
TIMER3A.165
*IF DEF,MPP PXTIMER3.1
*CALL PARVARS
GPB8F405.5
INTEGER info GPB8F405.6
*ENDIF GPB8F405.7
! Loop counters etc. TIMER3A.166
INTEGER I TIMER3A.167
TIMER3A.168
TIMER3A.169
TIMER3A.170
EXTERNAL get_cpu_time,get_wallclock_time TIMER3A.171
REAL get_cpu_time,get_wallclock_time TIMER3A.172
! ---------------------------------------------------------------------- TIMER3A.173
TIMER3A.174
*IF DEF,MPP GPB8F405.8
IF (( action .EQ. first_call_to_timer) .OR.
GPB8F405.9
& ( action .EQ. non_incl_start_timer) .OR. GPB8F405.10
& ( action .EQ. incl_start_timer)) THEN GPB8F405.11
*IF DEF,T3E GPB8F405.12
CALL barrier(
) GPB8F405.13
*ELSE GPB8F405.14
CALL GC_GSYNC(
nproc,info) GPB8F405.15
*ENDIF GPB8F405.16
ENDIF GPB8F405.17
*ENDIF GPB8F405.18
IF (action .GT. 100) action=action-100 GPB8F405.19
! The following line is useful for general debugging purposes TIMER3A.175
! It prints out the name of every timed routine on entry and exit TIMER3A.176
! WRITE(6,*) section_name,' action= ',action TIMER3A.177
TIMER3A.178
! start up the timer timer TIMER3A.179
TIMER3A.180
cpu_time_into_timer = get_cpu_time
() TIMER3A.181
wallclock_time_into_timer = get_wallclock_time
() TIMER3A.182
in_number_of_times_timed(1) = in_number_of_times_timed(1) + 1 TIMER3A.183
TIMER3A.184
! check the length of the section_name TIMER3A.185
TIMER3A.186
IF (LEN(section_name) .GT. 20) THEN TIMER3A.187
WRITE(6,*) 'TIMER has detected a non-fatal ERROR' TIMER3A.188
WRITE(6,*) 'Section name ',section_name,' is too long.' TIMER3A.189
WRITE(6,*) 'Maximum of 20 characters is allowed' TIMER3A.190
WRITE(6,*) section_name,' will be truncated to 20 chars.' TIMER3A.191
ENDIF TIMER3A.192
TIMER3A.193
TIMER3A.194
! diagnose what action to take: TIMER3A.195
TIMER3A.196
IF (action .EQ. first_call_to_timer) THEN
TIMER3A.197
TIMER3A.198
! First call to timer - do initialisation TIMER3A.199
TIMER3A.200
DO I=1,max_timers TIMER3A.201
ni_timer_name(I) = ' ' TIMER3A.202
in_timer_name(I) = ' ' TIMER3A.203
TIMER3A.204
ni_number_of_times_timed(I) = 0 TIMER3A.205
in_number_of_times_timed(I) = 0 TIMER3A.206
TIMER3A.207
ni_cpu_time_elapsed(I) = 0. TIMER3A.208
in_cpu_time_elapsed(I) = 0. TIMER3A.209
ni_wallclock_time_elapsed(I)= 0. TIMER3A.210
in_wallclock_time_elapsed(I)= 0. TIMER3A.211
TIMER3A.212
in_timer_running(I)=.FALSE. TIMER3A.213
ENDDO TIMER3A.214
TIMER3A.215
timer_on = .TRUE. TIMER3A.216
TIMER3A.217
current_timer = 1 TIMER3A.218
ni_number_of_timers = 1 TIMER3A.219
in_number_of_timers = 1 TIMER3A.220
in_timer_name(1) = 'TIMER' TIMER3A.221
TIMER3A.222
! and start the timer running TIMER3A.223
TIMER3A.224
ni_cpu_time_started = get_cpu_time
() TIMER3A.225
ni_wallclock_time_started = get_wallclock_time
() TIMER3A.226
ni_number_of_times_timed(current_timer) = 1 TIMER3A.227
old_timer(current_timer) = 0 TIMER3A.228
ni_timer_name(current_timer) = section_name TIMER3A.229
TIMER3A.230
! ---------------------------------------------------------------------- TIMER3A.231
TIMER3A.232
ELSEIF (timer_on .AND. TIMER3A.233
& ( (action .EQ. last_call_to_timer) .OR. TIMER3A.234
& (action .EQ. intermediate_output) ) )THEN TIMER3A.235
TIMER3A.236
! Last call to timer - or intermediate output required, so TIMER3A.237
! print out table of results TIMER3A.238
TIMER3A.239
IF (action .EQ. last_call_to_timer) THEN
TIMER3A.240
! the only active timer should be no.1 TIMER3A.241
TIMER3A.242
IF (current_timer .NE. 1) THEN TIMER3A.243
WRITE(6,*) 'TIMER has detected an ERROR' TIMER3A.244
WRITE(6,*) 'Attempted to print results without switching ', TIMER3A.245
& 'off all running non-inclusive timers.' TIMER3A.246
WRITE(6,*) '** TIMER SWITCHED OFF FOR REST OF RUN **' TIMER3A.247
timer_on = .FALSE. TIMER3A.248
GOTO 9999 TIMER3A.249
ENDIF TIMER3A.250
TIMER3A.251
! Make sure there are no inclusive timers still running TIMER3A.252
TIMER3A.253
section_ref = 0 TIMER3A.254
DO I=1,in_number_of_timers TIMER3A.255
IF (in_timer_running(I)) section_ref = I TIMER3A.256
ENDDO TIMER3A.257
TIMER3A.258
IF (section_ref .NE.0) THEN TIMER3A.259
WRITE(6,*) 'TIMER has detected an ERROR' TIMER3A.260
WRITE(6,*) 'Attempted to print results without switching ', TIMER3A.261
& 'off all running inclusive timers.' TIMER3A.262
WRITE(6,*) '** TIMER SWITCHED OFF FOR REST OF RUN **' TIMER3A.263
timer_on = .FALSE. TIMER3A.264
GOTO 9999 TIMER3A.265
ENDIF TIMER3A.266
TIMER3A.267
! Just to make sure that timer isn't called again TIMER3A.268
timer_on = .FALSE. TIMER3A.269
TIMER3A.270
! and switch off the top level non-inclusive timer TIMER3A.271
TIMER3A.272
ni_cpu_time_elapsed(current_timer) = TIMER3A.273
& ni_cpu_time_elapsed(current_timer) + TIMER3A.274
& get_cpu_time
() - ni_cpu_time_started TIMER3A.275
TIMER3A.276
ni_wallclock_time_elapsed(current_timer) = TIMER3A.277
& ni_wallclock_time_elapsed(current_timer) + TIMER3A.278
& get_wallclock_time
() - ni_wallclock_time_started TIMER3A.279
TIMER3A.280
ENDIF ! If this is the final call to timer TIMER3A.281
TIMER3A.282
CALL TIMER_OUTPUT
( TIMER3A.283
& in_number_of_timers, ni_number_of_timers, TIMER3A.284
& in_cpu_time_elapsed, ni_cpu_time_elapsed, TIMER3A.285
& in_wallclock_time_elapsed, ni_wallclock_time_elapsed, TIMER3A.286
& in_number_of_times_timed, ni_number_of_times_timed, TIMER3A.287
& in_timer_name, ni_timer_name, TIMER3A.288
& action,section_name) TIMER3A.289
TIMER3A.290
TIMER3A.291
TIMER3A.292
! that's it TIMER3A.293
TIMER3A.294
! ---------------------------------------------------------------------- TIMER3A.295
TIMER3A.296
ELSEIF (timer_on .AND. TIMER3A.297
& (action .EQ. non_incl_start_timer) ) THEN TIMER3A.298
TIMER3A.299
! Start a non-inclusive timer running TIMER3A.300
TIMER3A.301
! Switch off the current timer TIMER3A.302
ni_cpu_time_elapsed(current_timer) = TIMER3A.303
& ni_cpu_time_elapsed(current_timer) + TIMER3A.304
& get_cpu_time
() - ni_cpu_time_started TIMER3A.305
TIMER3A.306
ni_wallclock_time_elapsed(current_timer) = TIMER3A.307
& ni_wallclock_time_elapsed(current_timer) + TIMER3A.308
& get_wallclock_time
() - ni_wallclock_time_started TIMER3A.309
TIMER3A.310
! See if we're already keeping records for this section TIMER3A.311
TIMER3A.312
section_ref = 0 TIMER3A.313
DO I=1,ni_number_of_timers TIMER3A.314
IF (ni_timer_name(I) .EQ. section_name) section_ref = I TIMER3A.315
ENDDO TIMER3A.316
TIMER3A.317
! Check to make sure that there is no timer already running for TIMER3A.318
! this section TIMER3A.319
! (NB an inclusive timer with the same reference name is allowed TIMER3A.320
! to run simultaneously with this one) TIMER3A.321
TIMER3A.322
IF (section_ref .EQ. current_timer) THEN TIMER3A.323
WRITE(6,*) 'TIMER has detected an ERROR' TIMER3A.324
WRITE(6,*) 'Simultaneous non-inclusive timers attempted ', TIMER3A.325
& 'for section ',section_name TIMER3A.326
WRITE(6,*) '** TIMER SWITCHED OFF FOR REST OF RUN **' TIMER3A.327
timer_on = .FALSE. TIMER3A.328
GOTO 9999 TIMER3A.329
ENDIF TIMER3A.330
TIMER3A.331
! calculate the section reference for the new timer TIMER3A.332
TIMER3A.333
IF (section_ref .EQ. 0) THEN TIMER3A.334
! this is a new section TIMER3A.335
section_ref = ni_number_of_timers+1 TIMER3A.336
ni_timer_name(section_ref) = section_name TIMER3A.337
ni_number_of_timers = section_ref TIMER3A.338
ENDIF TIMER3A.339
TIMER3A.340
! check that max_timers isn't exceeded: TIMER3A.341
IF (ni_number_of_timers .GT. max_timers) THEN TIMER3A.342
WRITE(6,*) 'TIMER has detected an ERROR' TIMER3A.343
WRITE(6,*) 'More than ',max_timers,' non-inclusive ', TIMER3A.344
& 'timers is not allowed.' TIMER3A.345
WRITE(6,*) '** TIMER SWITCHED OFF FOR REST OF RUN **' TIMER3A.346
timer_on = .FALSE. TIMER3A.347
GOTO 9999 TIMER3A.348
ENDIF TIMER3A.349
TIMER3A.350
! set up old_timer so that when this new timer is stopped, the TIMER3A.351
! current timer (that we've just stopped) can be restarted TIMER3A.352
TIMER3A.353
old_timer(section_ref)=current_timer TIMER3A.354
TIMER3A.355
! now start up the new timer TIMER3A.356
TIMER3A.357
current_timer = section_ref TIMER3A.358
ni_number_of_times_timed(current_timer) = TIMER3A.359
& ni_number_of_times_timed(current_timer) + 1 TIMER3A.360
ni_cpu_time_started = get_cpu_time
() TIMER3A.361
ni_wallclock_time_started = get_wallclock_time
() TIMER3A.362
TIMER3A.363
! that's it TIMER3A.364
TIMER3A.365
! ---------------------------------------------------------------------- TIMER3A.366
TIMER3A.367
ELSEIF (timer_on .AND. TIMER3A.368
& (action .EQ. non_incl_end_timer) ) THEN TIMER3A.369
TIMER3A.370
! Stop a non-inclusive timer TIMER3A.371
TIMER3A.372
! Make sure that we're being asked to end a timer that's actually TIMER3A.373
! running. TIMER3A.374
TIMER3A.375
IF (ni_timer_name(current_timer) .NE. section_name) THEN TIMER3A.376
WRITE(6,*) 'TIMER has detected an ERROR' TIMER3A.377
WRITE(6,*) 'Attempted to stop a non-active ', TIMER3A.378
& 'non-inclusive timer ',section_name TIMER3A.379
WRITE(6,*) '** TIMER SWITCHED OFF FOR REST OF RUN **' TIMER3A.380
timer_on = .FALSE. TIMER3A.381
GOTO 9999 TIMER3A.382
ENDIF TIMER3A.383
TIMER3A.384
! OK - so stop this timer: TIMER3A.385
TIMER3A.386
ni_cpu_time_elapsed(current_timer) = TIMER3A.387
& ni_cpu_time_elapsed(current_timer) + TIMER3A.388
& get_cpu_time
() - ni_cpu_time_started TIMER3A.389
TIMER3A.390
ni_wallclock_time_elapsed(current_timer) = TIMER3A.391
& ni_wallclock_time_elapsed(current_timer) + TIMER3A.392
& get_wallclock_time
() - ni_wallclock_time_started TIMER3A.393
TIMER3A.394
! and now restart the old timer (ie. the one that was in TIMER3A.395
! operation at the time this one was started) TIMER3A.396
TIMER3A.397
IF (old_timer(current_timer) .EQ. 0) THEN TIMER3A.398
! this means I have just stopped the top level timer - there TIMER3A.399
! are no more to stop. This is an error - I should do this TIMER3A.400
! by calling the timer with action=2 TIMER3A.401
WRITE(6,*) 'TIMER has detected an ERROR' TIMER3A.402
WRITE(6,*) 'The top-level timer has been stopped' TIMER3A.403
WRITE(6,*) '** TIMER SWITCHED OFF FOR REST OF RUN **' TIMER3A.404
timer_on = .FALSE. TIMER3A.405
GOTO 9999 TIMER3A.406
ENDIF TIMER3A.407
TIMER3A.408
current_timer=old_timer(current_timer) TIMER3A.409
ni_cpu_time_started=get_cpu_time
() TIMER3A.410
ni_wallclock_time_started=get_wallclock_time
() TIMER3A.411
TIMER3A.412
! ---------------------------------------------------------------------- TIMER3A.413
TIMER3A.414
ELSEIF (timer_on .AND. TIMER3A.415
& (action .EQ. incl_start_timer) ) THEN TIMER3A.416
TIMER3A.417
! Start an inclusive timer running TIMER3A.418
TIMER3A.419
! See if we're already keeping records for this section TIMER3A.420
TIMER3A.421
section_ref = 0 TIMER3A.422
DO I=1,in_number_of_timers TIMER3A.423
IF (in_timer_name(I) .EQ. section_name) section_ref = I TIMER3A.424
ENDDO TIMER3A.425
TIMER3A.426
! and calculate the section reference TIMER3A.427
TIMER3A.428
IF (section_ref .EQ. 0) THEN TIMER3A.429
! this is a new one TIMER3A.430
section_ref = in_number_of_timers + 1 TIMER3A.431
in_timer_name(section_ref) = section_name TIMER3A.432
in_number_of_timers = section_ref TIMER3A.433
ENDIF TIMER3A.434
TIMER3A.435
! check that max_timers isn't exceeded: TIMER3A.436
TIMER3A.437
IF (in_number_of_timers .GT. max_timers) THEN TIMER3A.438
WRITE(6,*) 'TIMER has detected an ERROR' TIMER3A.439
WRITE(6,*) 'More than ',max_timers,' inclusive ', TIMER3A.440
& 'timers is not allowed.' TIMER3A.441
WRITE(6,*) '** TIMER SWITCHED OFF FOR REST OF RUN **' TIMER3A.442
timer_on = .FALSE. TIMER3A.443
GOTO 9999 TIMER3A.444
ENDIF TIMER3A.445
TIMER3A.446
! Check to make sure that there is no timer already running for TIMER3A.447
! this section TIMER3A.448
! (NB a non-inclusive timer with the same reference name is allowed TIMER3A.449
! to run simultaneously with this one) TIMER3A.450
TIMER3A.451
IF (in_timer_running(section_ref)) THEN TIMER3A.452
WRITE(6,*) 'TIMER has detected an ERROR' TIMER3A.453
WRITE(6,*) 'Inclusive timer already running for ', TIMER3A.454
& section_name TIMER3A.455
WRITE(6,*) '** TIMER SWITCHED OFF FOR REST OF RUN **' TIMER3A.456
timer_on = .FALSE. TIMER3A.457
GOTO 9999 TIMER3A.458
ENDIF TIMER3A.459
TIMER3A.460
! so now we can start the timer for this section TIMER3A.461
in_number_of_times_timed(section_ref) = TIMER3A.462
& in_number_of_times_timed(section_ref) + 1 TIMER3A.463
in_timer_running(section_ref) = .TRUE. TIMER3A.464
in_cpu_time_started(section_ref) = get_cpu_time
() TIMER3A.465
in_wallclock_time_started(section_ref) = get_wallclock_time
() TIMER3A.466
TIMER3A.467
! that's it TIMER3A.468
TIMER3A.469
TIMER3A.470
! ---------------------------------------------------------------------- TIMER3A.471
TIMER3A.472
ELSEIF (timer_on .AND. TIMER3A.473
& (action .EQ. incl_end_timer) ) THEN TIMER3A.474
TIMER3A.475
! Stop an inclusive timer TIMER3A.476
TIMER3A.477
! Find out what the reference number of this timer is TIMER3A.478
TIMER3A.479
section_ref = 0 TIMER3A.480
DO I=1,in_number_of_timers TIMER3A.481
IF (in_timer_name(I) .EQ. section_name) section_ref = I TIMER3A.482
ENDDO TIMER3A.483
TIMER3A.484
IF (section_ref .EQ. 0) THEN TIMER3A.485
WRITE(6,*) 'TIMER has detected an ERROR' TIMER3A.486
WRITE(6,*) 'Attempting to stop a non-existent ', TIMER3A.487
& 'inclusive timer ',section_name TIMER3A.488
WRITE(6,*) '** TIMER SWITCHED OFF FOR REST OF RUN **' TIMER3A.489
timer_on = .FALSE. TIMER3A.490
GOTO 9999 TIMER3A.491
ENDIF TIMER3A.492
TIMER3A.493
! Make sure this timer is actually running at the moment TIMER3A.494
TIMER3A.495
IF (.NOT. in_timer_running(section_ref)) THEN TIMER3A.496
WRITE(6,*) 'TIMER has detected an ERROR' TIMER3A.497
WRITE(6,*) 'Attempting to stop a non-running ', TIMER3A.498
& 'inclusive timer ',section_name TIMER3A.499
WRITE(6,*) '** TIMER SWITCHED OFF FOR REST OF RUN **' TIMER3A.500
timer_on = .FALSE. TIMER3A.501
GOTO 9999 TIMER3A.502
ENDIF TIMER3A.503
TIMER3A.504
! now we can stop it TIMER3A.505
in_cpu_time_elapsed(section_ref) = TIMER3A.506
& in_cpu_time_elapsed(section_ref) + TIMER3A.507
& get_cpu_time
() - in_cpu_time_started(section_ref) TIMER3A.508
TIMER3A.509
in_wallclock_time_elapsed(section_ref) = TIMER3A.510
& in_wallclock_time_elapsed(section_ref) + TIMER3A.511
& get_wallclock_time
() - in_wallclock_time_started(section_ref) TIMER3A.512
TIMER3A.513
in_timer_running(section_ref) = .FALSE. TIMER3A.514
TIMER3A.515
! that's it TIMER3A.516
TIMER3A.517
! ---------------------------------------------------------------------- TIMER3A.518
TIMER3A.519
ELSEIF (timer_on) THEN TIMER3A.520
TIMER3A.521
WRITE(6,*) 'TIMER has detected an ERROR' TIMER3A.522
WRITE(6,*) 'Incorrect action= ',action,' supplied by ', TIMER3A.523
& 'section ',section_name TIMER3A.524
WRITE(6,*) 'Non-fatal error - TIMER will continue' TIMER3A.525
TIMER3A.526
ENDIF TIMER3A.527
TIMER3A.528
9999 CONTINUE TIMER3A.529
TIMER3A.530
! stop the timer timer TIMER3A.531
in_cpu_time_elapsed(1) = in_cpu_time_elapsed(1) + TIMER3A.532
& get_cpu_time
() - cpu_time_into_timer TIMER3A.533
in_wallclock_time_elapsed(1) = in_wallclock_time_elapsed(1) + TIMER3A.534
& get_wallclock_time
() - wallclock_time_into_timer TIMER3A.535
TIMER3A.536
RETURN TIMER3A.537
END TIMER3A.538
TIMER3A.539
!********************************************************************* TIMER3A.540
TIMER3A.541
TIMER3A.542
SUBROUTINE TIMER_OUTPUT( 1TIMER3A.543
& in_number_of_timers, ni_number_of_timers, TIMER3A.544
& in_cpu_time_elapsed, ni_cpu_time_elapsed, TIMER3A.545
& in_wallclock_time_elapsed, ni_wallclock_time_elapsed, TIMER3A.546
& in_number_of_times_timed, ni_number_of_times_timed, TIMER3A.547
& in_timer_name, ni_timer_name, TIMER3A.548
& action,message) TIMER3A.549
TIMER3A.550
IMPLICIT NONE TIMER3A.551
TIMER3A.552
! Arguments TIMER3A.553
TIMER3A.554
INTEGER TIMER3A.555
& in_number_of_timers ! IN number of inclusive timers TIMER3A.556
&, ni_number_of_timers ! IN number of non-inclusive timers TIMER3A.557
&, in_number_of_times_timed(in_number_of_timers) TIMER3A.558
! ! IN number of times timed - inclusive TIMER3A.559
&, ni_number_of_times_timed(ni_number_of_timers) TIMER3A.560
! ! IN number of times timed - non-incl. TIMER3A.561
&, action ! final output or intermediate TIMER3A.562
TIMER3A.563
REAL TIMER3A.564
& in_cpu_time_elapsed(in_number_of_timers) TIMER3A.565
! ! IN elapsed inclusive CPU time TIMER3A.566
&, ni_cpu_time_elapsed(ni_number_of_timers) TIMER3A.567
! ! IN elapsed non-inclusive CPU time TIMER3A.568
&, in_wallclock_time_elapsed(in_number_of_timers) TIMER3A.569
! ! IN elapsed inclusive wallclock time TIMER3A.570
&, ni_wallclock_time_elapsed(ni_number_of_timers) TIMER3A.571
TIMER3A.572
CHARACTER*20 TIMER3A.573
& in_timer_name(in_number_of_timers) TIMER3A.574
! ! IN name of timed section - inclusive TIMER3A.575
&, ni_timer_name(ni_number_of_timers) TIMER3A.576
! ! IN name of timed section - non-incl. TIMER3A.577
APB4F402.6
CHARACTER*(*) APB4F402.7
& message ! IN message to print APB4F402.8
TIMER3A.579
TIMER3A.580
! Local variables TIMER3A.581
TIMER3A.582
INTEGER max_timers TIMER3A.583
PARAMETER(max_timers=300) TIMER3A.584
TIMER3A.585
INTEGER last_call_to_timer,intermediate_output
TIMER3A.586
PARAMETER(last_call_to_timer=2, TIMER3A.587
& intermediate_output=7) TIMER3A.588
TIMER3A.589
INTEGER TIMER3A.590
& number_of_timers TIMER3A.591
&, local_number_of_times_timed(max_timers) TIMER3A.592
TIMER3A.593
REAL TIMER3A.594
& local_cpu_time_elapsed(max_timers) TIMER3A.595
&, local_wallclock_time_elapsed(max_timers) TIMER3A.596
TIMER3A.597
CHARACTER*20 TIMER3A.598
& local_timer_name(max_timers) TIMER3A.599
TIMER3A.600
! Variables required for using intermediate timers TIMER3A.601
! They record the values on the last call to this routine TIMER3A.602
INTEGER TIMER3A.603
& last_in_number_of_times_timed(max_timers) TIMER3A.604
&, last_ni_number_of_times_timed(max_timers) TIMER3A.605
TIMER3A.606
REAL TIMER3A.607
& last_in_cpu_time_elapsed(max_timers) TIMER3A.608
&, last_ni_cpu_time_elapsed(max_timers) TIMER3A.609
&, last_in_wallclock_time_elapsed(max_timers) TIMER3A.610
&, last_ni_wallclock_time_elapsed(max_timers) TIMER3A.611
TIMER3A.612
LOGICAL TIMER3A.613
& first_intermediate_timer_call
TIMER3A.614
TIMER3A.615
DATA first_intermediate_timer_call /.TRUE./
TIMER3A.616
DATA last_in_number_of_times_timed /max_timers*0/ TIMER3A.617
DATA last_ni_number_of_times_timed /max_timers*0/ TIMER3A.618
DATA last_in_cpu_time_elapsed /max_timers*0.0/ TIMER3A.619
DATA last_ni_cpu_time_elapsed /max_timers*0.0/ TIMER3A.620
DATA last_in_wallclock_time_elapsed /max_timers*0.0/ TIMER3A.621
DATA last_ni_wallclock_time_elapsed /max_timers*0.0/ TIMER3A.622
TIMER3A.623
SAVE TIMER3A.624
& last_in_number_of_times_timed, last_ni_number_of_times_timed, TIMER3A.625
& last_in_cpu_time_elapsed, last_ni_cpu_time_elapsed, TIMER3A.626
& last_in_wallclock_time_elapsed, last_ni_wallclock_time_elapsed, TIMER3A.627
& first_intermediate_timer_call
TIMER3A.628
TIMER3A.629
TIMER3A.630
TIMER3A.631
INTEGER sortwork_int ! work variable for sort TIMER3A.632
REAL sortwork_real ! work variable for sort TIMER3A.633
CHARACTER*20 sortwork_char ! work variable for sort TIMER3A.634
TIMER3A.635
REAL total_cpu_time, ! total cpu time spent in program TIMER3A.636
& total_wallclock_time, ! total wallclock time spent in TIMER3A.637
! ! program TIMER3A.638
& average_cpu_elapsed, ! average cpu elapsed time TIMER3A.639
& average_wallclock_elapsed, ! average wallclock elapsed time TIMER3A.640
& percent_of_cpu_total, ! % of cpu time spent in a section TIMER3A.641
& percent_of_wallclock_total, TIMER3A.642
& ! % of wallclock time spent in a TIMER3A.643
! ! section TIMER3A.644
& speed_up ! speed_up=cpu/wallclock TIMER3A.645
TIMER3A.646
*IF DEF,MPP TIMER3A.647
*CALL PARVARS
TIMER3A.648
TIMER3A.649
! These are the declarations for MPP timer TIMER3A.650
TIMER3A.651
INTEGER info, TIMER3A.652
& wallclock_max_pe(max_timers),wallclock_min_pe(max_timers), TIMER3A.653
& cpu_max_pe(max_timers),cpu_min_pe(max_timers) TIMER3A.654
TIMER3A.655
REAL wallclock_mean(max_timers),cpu_mean(max_timers), TIMER3A.656
& wallclock_median(max_timers),cpu_median(max_timers), TIMER3A.657
& wallclock_sd(max_timers),cpu_sd(max_timers), TIMER3A.658
& wallclock_max(max_timers),wallclock_min(max_timers), TIMER3A.659
& cpu_max(max_timers),cpu_min(max_timers), TIMER3A.660
& cpu_total(max_timers),speedup(max_timers), TIMER3A.661
& efficiency(max_timers) TIMER3A.662
TIMER3A.663
INTEGER TIMER3A.664
& summ_n_timers ! number of routines for ni summary TIMER3A.665
&, routine_id ! routine id on this processor TIMER3A.666
TIMER3A.667
REAL TIMER3A.668
& wallclock_times(0:MAXPROC) ! wallclock time from each proc TIMER3A.669
&, cpu_times(0:MAXPROC) ! cpu time from each proc TIMER3A.670
&, total_cpu,max_wall ! total cpu, maxumum wallclock times GPB3F403.125
TIMER3A.671
CHARACTER*20 summ_section(max_timers) ! names of sections TIMER3A.672
COMMON /MPP_TIMER/ summ_n_timers,total_cpu,max_wall, GPB3F403.126
& wallclock_times,cpu_times, TIMER3A.674
& summ_section TIMER3A.675
*ENDIF TIMER3A.676
TIMER3A.677
! Variables for loops etc. TIMER3A.678
INTEGER I,J,K,timer_kind TIMER3A.679
TIMER3A.680
! Check to see if this is an intermediate output, and the first TIMER3A.681
! time it has been called TIMER3A.682
IF ((action .EQ. intermediate_output) .AND. TIMER3A.683
& (first_intermediate_timer_call ) ) THEN
TIMER3A.684
! Copy the arguments into the last_* arrays TIMER3A.685
first_intermediate_timer_call=.FALSE. TIMER3A.686
TIMER3A.687
DO I=1,in_number_of_timers TIMER3A.688
last_in_number_of_times_timed(I)=in_number_of_times_timed(I) TIMER3A.689
last_in_cpu_time_elapsed(I)=in_cpu_time_elapsed(I) TIMER3A.690
last_in_wallclock_time_elapsed(I)= TIMER3A.691
& in_wallclock_time_elapsed(I) TIMER3A.692
ENDDO TIMER3A.693
TIMER3A.694
DO I=1,ni_number_of_timers TIMER3A.695
last_ni_number_of_times_timed(I)=ni_number_of_times_timed(I) TIMER3A.696
last_ni_cpu_time_elapsed(I)=ni_cpu_time_elapsed(I) TIMER3A.697
last_ni_wallclock_time_elapsed(I)= GPB0F405.131
& ni_wallclock_time_elapsed(I) TIMER3A.699
ENDDO TIMER3A.700
TIMER3A.701
GOTO 9999 ! jump to end - no output on first call TIMER3A.702
ENDIF TIMER3A.703
TIMER3A.704
WRITE(6,*) TIMER3A.705
WRITE(6,*) '******************************************' TIMER3A.706
WRITE(6,*) TIMER3A.707
TIMER3A.708
DO timer_kind=1,2 ! 1 is non-inclusive and 2 is inclusive TIMER3A.709
! Copy arguments into local arrays TIMER3A.710
IF (action .EQ. last_call_to_timer) THEN
TIMER3A.711
WRITE(6,*) 'END OF RUN - TIMER OUTPUT' TIMER3A.712
WRITE(6,*) 'Timer information is for whole run' TIMER3A.713
IF (timer_kind .EQ. 1) THEN ! non-inclusive timer TIMER3A.714
number_of_timers=ni_number_of_timers TIMER3A.715
DO I=1,number_of_timers TIMER3A.716
local_timer_name(I)=ni_timer_name(I) TIMER3A.717
local_cpu_time_elapsed(I)=ni_cpu_time_elapsed(I) TIMER3A.718
local_wallclock_time_elapsed(I)= TIMER3A.719
& ni_wallclock_time_elapsed(I) TIMER3A.720
local_number_of_times_timed(I)= TIMER3A.721
& ni_number_of_times_timed(I) TIMER3A.722
ENDDO TIMER3A.723
ELSE ! timer_kind .EQ. 2 - inclusive timer TIMER3A.724
number_of_timers=in_number_of_timers TIMER3A.725
DO I=1,number_of_timers TIMER3A.726
local_timer_name(I)=in_timer_name(I) TIMER3A.727
local_cpu_time_elapsed(I)=in_cpu_time_elapsed(I) TIMER3A.728
local_wallclock_time_elapsed(I)= TIMER3A.729
& in_wallclock_time_elapsed(I) TIMER3A.730
local_number_of_times_timed(I)= TIMER3A.731
& in_number_of_times_timed(I) TIMER3A.732
ENDDO TIMER3A.733
ENDIF ! which timer kind this was TIMER3A.734
ELSE ! this is an intermediate output call TIMER3A.735
WRITE(6,*) 'INTERMEDIATE TIMER OUTPUT :',message TIMER3A.736
WRITE(6,*) 'Timer information is only for code executed ', TIMER3A.737
& 'since last intermediate timer output.' TIMER3A.738
IF (timer_kind .EQ. 1) THEN ! non-inclusive timer TIMER3A.739
number_of_timers=ni_number_of_timers TIMER3A.740
DO I=1,number_of_timers TIMER3A.741
local_timer_name(I)=ni_timer_name(I) TIMER3A.742
local_cpu_time_elapsed(I)=ni_cpu_time_elapsed(I)- TIMER3A.743
& last_ni_cpu_time_elapsed(I) TIMER3A.744
local_wallclock_time_elapsed(I)= TIMER3A.745
& ni_wallclock_time_elapsed(I)- TIMER3A.746
& last_ni_wallclock_time_elapsed(I) TIMER3A.747
local_number_of_times_timed(I)= TIMER3A.748
& ni_number_of_times_timed(I)- TIMER3A.749
& last_ni_number_of_times_timed(I) TIMER3A.750
ENDDO TIMER3A.751
ELSE ! timer kind .EQ. 2 - inclusive timer TIMER3A.752
number_of_timers=in_number_of_timers TIMER3A.753
DO I=1,number_of_timers TIMER3A.754
local_timer_name(I)=in_timer_name(I) TIMER3A.755
local_cpu_time_elapsed(I)=in_cpu_time_elapsed(I)- TIMER3A.756
& last_in_cpu_time_elapsed(I) TIMER3A.757
local_wallclock_time_elapsed(I)= TIMER3A.758
& in_wallclock_time_elapsed(I)- TIMER3A.759
& last_in_wallclock_time_elapsed(I) TIMER3A.760
local_number_of_times_timed(I)= TIMER3A.761
& in_number_of_times_timed(I)- TIMER3A.762
& last_in_number_of_times_timed(I) TIMER3A.763
ENDDO TIMER3A.764
ENDIF ! what timer type TIMER3A.765
ENDIF ! what action to perform TIMER3A.766
TIMER3A.767
! Do work for non-inclusive timers TIMER3A.768
TIMER3A.769
! Calculate the total time in the program (based on non-inclusive TIMER3A.770
! timers) TIMER3A.771
IF (timer_kind .EQ. 1) THEN TIMER3A.772
total_cpu_time = 0.0 TIMER3A.773
total_wallclock_time = 0.0 TIMER3A.774
DO I=1,number_of_timers TIMER3A.775
total_cpu_time = total_cpu_time + local_cpu_time_elapsed(I) TIMER3A.776
total_wallclock_time = TIMER3A.777
& total_wallclock_time + local_wallclock_time_elapsed(I) TIMER3A.778
ENDDO TIMER3A.779
TIMER3A.780
*IF -DEF,MPP GPB3F403.127
WRITE(6,*) 'Total Elapsed CPU Time: ',total_cpu_time TIMER3A.781
WRITE(6,*) 'Total Elapsed Wallclock Time: ', TIMER3A.782
& total_wallclock_time TIMER3A.783
WRITE(6,*) 'Total Speed-up: ', TIMER3A.784
& total_cpu_time/total_wallclock_time TIMER3A.785
*ELSE GPB3F403.128
WRITE(6,*) 'PE ',mype,' Elapsed CPU Time: ', GPB3F403.129
& total_cpu_time GPB3F403.130
WRITE(6,*) 'PE ',mype,' Elapsed Wallclock Time: ', GPB3F403.131
& total_wallclock_time GPB3F403.132
GPB3F403.133
! Calculate the total cpu time over all processors and the GPB3F403.134
! maximum elapsed time - so allowing a speedup to be caclulated GPB3F403.135
GPB3F403.136
total_cpu=total_cpu_time GPB3F403.137
max_wall=total_wallclock_time GPB3F403.138
GPB3F403.139
CALL GC_RSUM(
1,nproc,info,total_cpu) GPB3F403.140
CALL GC_RMAX(
1,nproc,info,max_wall) GPB3F403.141
GPB3F403.142
max_wall=MAX(max_wall,0.000001) GPB3F403.143
WRITE(6,*) GPB3F403.144
WRITE(6,*) 'Total Elapsed CPU Time: ', GPB3F403.145
& total_cpu GPB3F403.146
WRITE(6,*) 'Maximum Elapsed Wallclock Time: ', GPB3F403.147
& max_wall GPB3F403.148
WRITE(6,*) 'Speedup: ',total_cpu/max_wall GPB3F403.149
WRITE(6,*) '--------------------------------------------' GPB3F403.150
*ENDIF GPB3F403.151
TIMER3A.786
ENDIF TIMER3A.787
TIMER3A.788
! Sort subroutines into time order (based on wallclock time) TIMER3A.789
TIMER3A.790
DO I=1,number_of_timers-1 TIMER3A.791
DO J=(I+1),number_of_timers TIMER3A.792
IF (local_wallclock_time_elapsed(J) .GT. TIMER3A.793
& local_wallclock_time_elapsed(I)) THEN TIMER3A.794
TIMER3A.795
! Swap the two entries TIMER3A.796
sortwork_real = local_cpu_time_elapsed(I) TIMER3A.797
local_cpu_time_elapsed(I) = local_cpu_time_elapsed(J) TIMER3A.798
local_cpu_time_elapsed(J) = sortwork_real TIMER3A.799
TIMER3A.800
sortwork_real = local_wallclock_time_elapsed(I) TIMER3A.801
local_wallclock_time_elapsed(I) = TIMER3A.802
& local_wallclock_time_elapsed(J) TIMER3A.803
local_wallclock_time_elapsed(J) = sortwork_real TIMER3A.804
TIMER3A.805
sortwork_int = local_number_of_times_timed(I) TIMER3A.806
local_number_of_times_timed(I) = TIMER3A.807
& local_number_of_times_timed(J) TIMER3A.808
local_number_of_times_timed(J) = sortwork_int TIMER3A.809
TIMER3A.810
sortwork_char = local_timer_name(I) TIMER3A.811
local_timer_name(I) = local_timer_name(J) TIMER3A.812
local_timer_name(J) = sortwork_char TIMER3A.813
TIMER3A.814
ENDIF TIMER3A.815
ENDDO TIMER3A.816
ENDDO TIMER3A.817
TIMER3A.818
20 FORMAT(20X, A45,I4) GPB3F403.152
21 FORMAT(3X,'ROUTINE',6X,'CALLS',2X,'TOT CPU',4X, TIMER3A.820
& 'AVERAGE',3X,'TOT WALL',2X,'AVERAGE',2X, TIMER3A.821
& '% CPU',4X,'% WALL',4X,'SPEED-UP') TIMER3A.822
22 FORMAT(3X,'ROUTINE',6X,'CALLS',2X,'TOT CPU',4X, TIMER3A.823
& 'AVERAGE',3X,'TOT WALL',2X,'AVERAGE',2X,'SPEED-UP') TIMER3A.824
23 FORMAT(/,I3,1X,A12,1X,I4,4(2X,F8.2),2(2X,F6.2),4X,F6.2) TIMER3A.825
IF (timer_kind .EQ. 1) THEN TIMER3A.826
*IF -DEF,MPP GPB3F403.153
WRITE(6,20) 'Non-Inclusive Timer Summary' TIMER3A.827
*ELSE GPB3F403.154
WRITE(6,20) 'Non-Inclusive Timer Summary for PE ',mype GPB3F403.155
*ENDIF GPB3F403.156
WRITE(6,21) TIMER3A.828
ELSE TIMER3A.829
*IF -DEF,MPP GPB3F403.157
WRITE(6,20) 'Inclusive Timer Summary' TIMER3A.830
*ELSE GPB3F403.158
WRITE(6,20) 'Inclusive Timer Summary for PE ',mype GPB3F403.159
*ENDIF GPB3F403.160
WRITE(6,22) TIMER3A.831
ENDIF TIMER3A.832
TIMER3A.833
DO I=1,number_of_timers TIMER3A.834
IF (local_number_of_times_timed(I) .NE. 0) THEN TIMER3A.835
average_cpu_elapsed = local_cpu_time_elapsed(I)/ TIMER3A.836
& local_number_of_times_timed(I) TIMER3A.837
average_wallclock_elapsed = local_wallclock_time_elapsed(I)/ TIMER3A.838
& local_number_of_times_timed(I) TIMER3A.839
ELSE TIMER3A.840
average_cpu_elapsed = 0.0 TIMER3A.841
average_wallclock_elapsed = 0.0 TIMER3A.842
ENDIF TIMER3A.843
TIMER3A.844
IF (local_wallclock_time_elapsed(I) .GT. 0) THEN TIMER3A.845
speed_up=local_cpu_time_elapsed(I)/ TIMER3A.846
& local_wallclock_time_elapsed(I) TIMER3A.847
ELSE TIMER3A.848
speed_up=1.0 TIMER3A.849
ENDIF TIMER3A.850
TIMER3A.851
IF (timer_kind .EQ. 1) THEN ! non-inclusive timer has some TIMER3A.852
! ! extra output TIMER3A.853
TIMER3A.854
percent_of_cpu_total = 100.0*local_cpu_time_elapsed(I)/ TIMER3A.855
& total_cpu_time TIMER3A.856
percent_of_wallclock_total = TIMER3A.857
& 100.0*local_wallclock_time_elapsed(I)/ TIMER3A.858
& total_wallclock_time TIMER3A.859
TIMER3A.860
TIMER3A.861
WRITE(6,23) I,local_timer_name(I), TIMER3A.862
& local_number_of_times_timed(I), TIMER3A.863
& local_cpu_time_elapsed(I),average_cpu_elapsed, TIMER3A.864
& local_wallclock_time_elapsed(I), TIMER3A.865
& average_wallclock_elapsed, TIMER3A.866
& percent_of_cpu_total, TIMER3A.867
& percent_of_wallclock_total,speed_up TIMER3A.868
TIMER3A.869
ELSE ! inclusive timer has slightly less to output TIMER3A.870
TIMER3A.871
WRITE(6,23) I,local_timer_name(I), TIMER3A.872
& local_number_of_times_timed(I), TIMER3A.873
& local_cpu_time_elapsed(I),average_cpu_elapsed, TIMER3A.874
& local_wallclock_time_elapsed(I), TIMER3A.875
& average_wallclock_elapsed,speed_up TIMER3A.876
TIMER3A.877
ENDIF TIMER3A.878
TIMER3A.879
ENDDO TIMER3A.880
TIMER3A.881
TIMER3A.882
*IF DEF,MPP TIMER3A.883
TIMER3A.884
! And now to assemble an overall timing assesment on PE0 TIMER3A.885
! Each PE sends it total wallclock and cpu time spent in each routine TIMER3A.886
! to PE0, which calculates the average, s.d., max and min, and TIMER3A.887
! sorts on the basis of the average wallclock time TIMER3A.888
! TIMER3A.889
! TIMER3A.890
! We'll use the list of routines that PE0 already has as the master TIMER3A.891
! list. TIMER3A.892
TIMER3A.893
IF (mype .EQ. 0) THEN TIMER3A.894
WRITE(6,*) TIMER3A.895
WRITE(6,*) 'MPP Timing information : ' TIMER3A.896
WRITE(6,*) nproc,' processors in configuration ',nproc_x, TIMER3A.897
& ' x ',nproc_y TIMER3A.898
TIMER3A.899
summ_n_timers=number_of_timers TIMER3A.900
DO I=1,summ_n_timers TIMER3A.901
summ_section(I)=local_timer_name(I) TIMER3A.902
ENDDO TIMER3A.903
ENDIF TIMER3A.904
TIMER3A.905
! tell everyone else how many routines to do summary on - and which TIMER3A.906
! routines they are TIMER3A.907
CALL GC_IBCAST(
3213,1,0,nproc,info,summ_n_timers) TIMER3A.908
CALL GC_CBCAST(
3214,20*summ_n_timers,0,nproc,info, TIMER3A.909
& summ_section) TIMER3A.910
TIMER3A.911
TIMER3A.912
DO I=1,summ_n_timers TIMER3A.913
TIMER3A.914
! which section_ref is this for me? TIMER3A.915
TIMER3A.916
routine_id=0 TIMER3A.917
DO J=1,number_of_timers TIMER3A.918
IF (local_timer_name(J) .EQ. summ_section(I)) TIMER3A.919
& routine_id=J TIMER3A.920
ENDDO TIMER3A.921
TIMER3A.922
IF (routine_id .GT. 0) THEN TIMER3A.923
wallclock_times(mype)= TIMER3A.924
& local_wallclock_time_elapsed(routine_id) TIMER3A.925
cpu_times(mype)=local_cpu_time_elapsed(routine_id) TIMER3A.926
ELSE TIMER3A.927
wallclock_times(mype)=0.0 TIMER3A.928
cpu_times(mype)=0.0 TIMER3A.929
ENDIF TIMER3A.930
TIMER3A.931
! send my information to PE 0. TIMER3A.932
CALL GC_GSYNC (
nproc,info) TIMER3A.933
TIMER3A.934
CALL GC_RSEND(
1000+mype,1,0,info,wallclock_times(mype), TIMER3A.935
& wallclock_times(mype)) TIMER3A.936
CALL GC_GSYNC(
nproc,info) TIMER3A.937
TIMER3A.938
IF (mype .EQ. 0) THEN TIMER3A.939
DO J=0,nproc-1 TIMER3A.940
CALL GC_RRECV(
1000+J,1,J,info,wallclock_times(J), TIMER3A.941
& wallclock_times(J)) TIMER3A.942
ENDDO TIMER3A.943
ENDIF TIMER3A.944
CALL GC_GSYNC(
nproc,info) TIMER3A.945
TIMER3A.946
CALL GC_RSEND(
10000+mype,1,0,info,cpu_times(mype), TIMER3A.947
& cpu_times(mype)) TIMER3A.948
CALL GC_GSYNC(
nproc,info) TIMER3A.949
TIMER3A.950
IF (mype .EQ. 0) THEN TIMER3A.951
DO J=0,nproc-1 TIMER3A.952
CALL GC_RRECV(
10000+J,1,J,info,cpu_times(J), TIMER3A.953
& cpu_times(J)) TIMER3A.954
ENDDO TIMER3A.955
ENDIF TIMER3A.956
TIMER3A.957
IF (mype .EQ. 0) THEN TIMER3A.958
! collect all the information - and start calculating the statistics TIMER3A.959
wallclock_mean(I)=0.0 TIMER3A.960
cpu_total(I)=0.0 TIMER3A.961
wallclock_max(I)=-1.0E30 TIMER3A.962
wallclock_min(I)=1.0E30 TIMER3A.963
cpu_max(I)=-1.0E30 TIMER3A.964
cpu_min(I)=1.0E30 TIMER3A.965
TIMER3A.966
DO J=0,nproc-1 TIMER3A.967
TIMER3A.968
wallclock_mean(I)=wallclock_mean(I)+wallclock_times(J) TIMER3A.969
cpu_total(I)=cpu_total(I)+cpu_times(J) TIMER3A.970
TIMER3A.971
IF (wallclock_times(J).GT.wallclock_max(I)) THEN TIMER3A.972
wallclock_max(I)=wallclock_times(J) TIMER3A.973
wallclock_max_pe(I)=J TIMER3A.974
ENDIF TIMER3A.975
IF (wallclock_times(J).LT.wallclock_min(I)) THEN TIMER3A.976
wallclock_min(I)=wallclock_times(J) TIMER3A.977
wallclock_min_pe(I)=J TIMER3A.978
ENDIF TIMER3A.979
IF (cpu_times(J).GT.cpu_max(I)) THEN TIMER3A.980
cpu_max(I)=cpu_times(J) TIMER3A.981
cpu_max_pe(I)=J TIMER3A.982
ENDIF TIMER3A.983
IF (cpu_times(J).LT.cpu_min(I)) THEN TIMER3A.984
cpu_min(I)=cpu_times(J) TIMER3A.985
cpu_min_pe(I)=J TIMER3A.986
ENDIF TIMER3A.987
TIMER3A.988
ENDDO ! loop over processors TIMER3A.989
TIMER3A.990
IF (wallclock_max(I) .GT. 0.0) THEN TIMER3A.991
speedup(I)=cpu_total(I)/wallclock_max(I) TIMER3A.992
ELSE TIMER3A.993
speedup(I)=1.0 TIMER3A.994
ENDIF TIMER3A.995
efficiency(I)=speedup(I)/nproc TIMER3A.996
TIMER3A.997
! and calculate the statistics TIMER3A.998
! first calculate the means TIMER3A.999
wallclock_mean(I)=wallclock_mean(I)/nproc TIMER3A.1000
cpu_mean(I)=cpu_total(I)/nproc TIMER3A.1001
! To stop a divide by zero later: TIMER3A.1002
IF (wallclock_mean(I) .EQ. 0.0) wallclock_mean(I)=1.0E-20 TIMER3A.1003
IF (cpu_mean(I) .EQ. 0.0) cpu_mean(I)=1.0E-20 TIMER3A.1004
! and now the standard deviation TIMER3A.1005
wallclock_sd(I)=0.0 TIMER3A.1006
cpu_sd(I)=0.0 TIMER3A.1007
DO J=0,nproc-1 TIMER3A.1008
wallclock_sd(I)=wallclock_sd(I)+ TIMER3A.1009
& (wallclock_times(J)-wallclock_mean(I))* TIMER3A.1010
& (wallclock_times(J)-wallclock_mean(I)) TIMER3A.1011
cpu_sd(I)=cpu_sd(I)+(cpu_times(J)-cpu_mean(I))* TIMER3A.1012
& (cpu_times(J)-cpu_mean(I)) TIMER3A.1013
ENDDO TIMER3A.1014
wallclock_sd(I)=SQRT(wallclock_sd(I)/nproc) TIMER3A.1015
cpu_sd(I)=SQRT(cpu_sd(I)/nproc) TIMER3A.1016
TIMER3A.1017
! Calculate the median TIMER3A.1018
DO J=0,nproc-2 TIMER3A.1019
DO K=J+1,nproc-1 TIMER3A.1020
IF (wallclock_times(K) .GT. wallclock_times(J)) THEN TIMER3A.1021
sortwork_real=wallclock_times(J) TIMER3A.1022
wallclock_times(J)=wallclock_times(K) TIMER3A.1023
wallclock_times(K)=sortwork_real TIMER3A.1024
ENDIF TIMER3A.1025
IF (cpu_times(K) .GT. cpu_times(J)) THEN TIMER3A.1026
sortwork_real=cpu_times(J) TIMER3A.1027
cpu_times(J)=cpu_times(K) TIMER3A.1028
cpu_times(K)=sortwork_real TIMER3A.1029
ENDIF TIMER3A.1030
ENDDO TIMER3A.1031
ENDDO TIMER3A.1032
TIMER3A.1033
IF (MOD(nproc,2) .EQ. 0) THEN TIMER3A.1034
wallclock_median(I)=(wallclock_times((nproc/2)-1)+ TIMER3A.1035
& wallclock_times(nproc/2))*0.5 TIMER3A.1036
cpu_median(I)=(cpu_times((nproc/2)-1)+ TIMER3A.1037
& cpu_times(nproc/2))*0.5 TIMER3A.1038
ELSE TIMER3A.1039
wallclock_median(I)=wallclock_times(nproc/2) TIMER3A.1040
cpu_median(I)=cpu_times(nproc/2) TIMER3A.1041
ENDIF TIMER3A.1042
TIMER3A.1043
ENDIF ! am I PE 0? TIMER3A.1044
TIMER3A.1045
ENDDO ! loop over sections TIMER3A.1046
TIMER3A.1047
! Sort and output the information on PE 0 TIMER3A.1048
TIMER3A.1049
IF (mype .EQ. 0) THEN TIMER3A.1050
TIMER3A.1051
DO I=1,summ_n_timers-1 TIMER3A.1052
DO J=(I+1),summ_n_timers TIMER3A.1053
IF (wallclock_max(J) .GT. wallclock_max(I)) THEN TIMER3A.1054
TIMER3A.1055
! Swap the entries I and J TIMER3A.1056
TIMER3A.1057
sortwork_char=summ_section(I) TIMER3A.1058
summ_section(I)=summ_section(J) TIMER3A.1059
summ_section(J)=sortwork_char TIMER3A.1060
TIMER3A.1061
sortwork_real=wallclock_mean(I) TIMER3A.1062
wallclock_mean(I)=wallclock_mean(J) TIMER3A.1063
wallclock_mean(J)=sortwork_real TIMER3A.1064
TIMER3A.1065
sortwork_real=wallclock_median(I) TIMER3A.1066
wallclock_median(I)=wallclock_median(J) TIMER3A.1067
wallclock_median(J)=sortwork_real TIMER3A.1068
TIMER3A.1069
sortwork_real=wallclock_sd(I) TIMER3A.1070
wallclock_sd(I)=wallclock_sd(J) TIMER3A.1071
wallclock_sd(J)=sortwork_real TIMER3A.1072
TIMER3A.1073
sortwork_real=wallclock_max(I) TIMER3A.1074
wallclock_max(I)=wallclock_max(J) TIMER3A.1075
wallclock_max(J)=sortwork_real TIMER3A.1076
TIMER3A.1077
sortwork_real=wallclock_min(I) TIMER3A.1078
wallclock_min(I)=wallclock_min(J) TIMER3A.1079
wallclock_min(J)=sortwork_real TIMER3A.1080
TIMER3A.1081
sortwork_int=wallclock_min_pe(I) TIMER3A.1082
wallclock_min_pe(I)=wallclock_min_pe(J) TIMER3A.1083
wallclock_min_pe(J)=sortwork_int TIMER3A.1084
TIMER3A.1085
sortwork_int=wallclock_max_pe(I) TIMER3A.1086
wallclock_max_pe(I)=wallclock_max_pe(J) TIMER3A.1087
wallclock_max_pe(J)=sortwork_int TIMER3A.1088
TIMER3A.1089
sortwork_real=cpu_mean(I) TIMER3A.1090
cpu_mean(I)=cpu_mean(J) TIMER3A.1091
cpu_mean(J)=sortwork_real TIMER3A.1092
TIMER3A.1093
sortwork_real=cpu_median(I) TIMER3A.1094
cpu_median(I)=cpu_median(J) TIMER3A.1095
cpu_median(J)=sortwork_real TIMER3A.1096
TIMER3A.1097
sortwork_real=cpu_sd(I) TIMER3A.1098
cpu_sd(I)=cpu_sd(J) TIMER3A.1099
cpu_sd(J)=sortwork_real TIMER3A.1100
TIMER3A.1101
sortwork_real=cpu_max(I) TIMER3A.1102
cpu_max(I)=cpu_max(J) TIMER3A.1103
cpu_max(J)=sortwork_real TIMER3A.1104
TIMER3A.1105
sortwork_real=cpu_min(I) TIMER3A.1106
cpu_min(I)=cpu_min(J) TIMER3A.1107
cpu_min(J)=sortwork_real TIMER3A.1108
TIMER3A.1109
sortwork_real=cpu_total(I) TIMER3A.1110
cpu_total(I)=cpu_total(J) TIMER3A.1111
cpu_total(J)=sortwork_real TIMER3A.1112
TIMER3A.1113
sortwork_real=speedup(I) TIMER3A.1114
speedup(I)=speedup(J) TIMER3A.1115
speedup(J)=sortwork_real TIMER3A.1116
TIMER3A.1117
sortwork_real=efficiency(I) TIMER3A.1118
efficiency(I)=efficiency(J) TIMER3A.1119
efficiency(J)=sortwork_real TIMER3A.1120
TIMER3A.1121
sortwork_int=cpu_min_pe(I) TIMER3A.1122
cpu_min_pe(I)=cpu_min_pe(J) TIMER3A.1123
cpu_min_pe(J)=sortwork_int TIMER3A.1124
TIMER3A.1125
sortwork_int=cpu_max_pe(I) TIMER3A.1126
cpu_max_pe(I)=cpu_max_pe(J) TIMER3A.1127
cpu_max_pe(J)=sortwork_int TIMER3A.1128
TIMER3A.1129
ENDIF TIMER3A.1130
ENDDO TIMER3A.1131
ENDDO TIMER3A.1132
TIMER3A.1133
! and write out the information TIMER3A.1134
WRITE(6,*) TIMER3A.1135
IF (timer_kind .EQ. 1) THEN TIMER3A.1136
WRITE(6,*) 'MPP : None Inclusive timer summary' TIMER3A.1137
ELSE TIMER3A.1138
WRITE(6,*) 'MPP : Inclusive timer summary' TIMER3A.1139
ENDIF TIMER3A.1140
TIMER3A.1141
WRITE(6,*) TIMER3A.1142
WRITE(6,*) 'WALLCLOCK TIMES' TIMER3A.1143
WRITE(6,40) TIMER3A.1144
DO I=1,summ_n_timers TIMER3A.1145
TIMER3A.1146
WRITE(6,41) I,summ_section(I), TIMER3A.1147
& wallclock_mean(I),wallclock_median(I), TIMER3A.1148
& wallclock_sd(I), TIMER3A.1149
& (wallclock_sd(I)/wallclock_mean(I))*100.0, TIMER3A.1150
& wallclock_max(I),wallclock_max_pe(I), TIMER3A.1151
& wallclock_min(I),wallclock_min_pe(I) TIMER3A.1152
ENDDO TIMER3A.1153
TIMER3A.1154
WRITE(6,*) TIMER3A.1155
WRITE(6,*) 'CPU TIMES (sorted by wallclock times)' TIMER3A.1156
WRITE(6,40) TIMER3A.1157
DO I=1,summ_n_timers TIMER3A.1158
WRITE(6,41) I,summ_section(I), TIMER3A.1159
& cpu_mean(I),cpu_median(I), TIMER3A.1160
& cpu_sd(I), TIMER3A.1161
& (cpu_sd(I)/cpu_mean(I))*100.0, TIMER3A.1162
& cpu_max(I),cpu_max_pe(I), TIMER3A.1163
& cpu_min(I),cpu_min_pe(I) TIMER3A.1164
ENDDO TIMER3A.1165
TIMER3A.1166
WRITE(6,*) TIMER3A.1167
WRITE(6,*) 'PARALLEL SPEEDUP SUMMARY ', TIMER3A.1168
& '(sorted by wallclock times)' TIMER3A.1169
WRITE(6,50) TIMER3A.1170
DO I=1,summ_n_timers TIMER3A.1171
WRITE(6,51) I,summ_section(I),cpu_total(I), TIMER3A.1172
& wallclock_max(I),speedup(I), TIMER3A.1173
& efficiency(I) TIMER3A.1174
ENDDO TIMER3A.1175
TIMER3A.1176
TIMER3A.1177
40 FORMAT(4X,'ROUTINE',11X,'MEAN',3X,'MEDIAN',7X, TIMER3A.1178
& 'SD',3X,'% of mean',6X,'MAX',3X, TIMER3A.1179
& '(PE)',6X,'MIN',3X,'(PE)') TIMER3A.1180
TIMER3A.1181
41 FORMAT(/,I3,1X,A12,1X, TIMER3A.1182
& 3(1X,F8.2),5X,F6.2,'%' TIMER3A.1183
& 2(1X,F8.2,1X,'(',I4,')')) TIMER3A.1184
TIMER3A.1185
50 FORMAT(4X,'ROUTINE',11X,'CPU TOTAL',3X, TIMER3A.1186
& 'WALLCLOCK MAX',3X,'SPEEDUP',3X, TIMER3A.1187
& 'PARALLEL EFFICIENCY') TIMER3A.1188
TIMER3A.1189
51 FORMAT(/,I3,1X,A17,1X, TIMER3A.1190
& 1X,F8.2,8X,F8.2,2X,F8.2,14X,F8.2) TIMER3A.1191
TIMER3A.1192
ENDIF TIMER3A.1193
WRITE(6,*) TIMER3A.1194
TIMER3A.1195
*ENDIF TIMER3A.1196
TIMER3A.1197
ENDDO ! loop over timer kind TIMER3A.1198
TIMER3A.1199
! Finally copy the timer info into the last_* arrays so that the TIMER3A.1200
! intermediate timer can calculate the timings since this point TIMER3A.1201
TIMER3A.1202
DO I=1,in_number_of_timers TIMER3A.1203
last_in_number_of_times_timed(I)=in_number_of_times_timed(I) TIMER3A.1204
last_in_cpu_time_elapsed(I)=in_cpu_time_elapsed(I) TIMER3A.1205
last_in_wallclock_time_elapsed(I)= TIMER3A.1206
& in_wallclock_time_elapsed(I) TIMER3A.1207
ENDDO TIMER3A.1208
TIMER3A.1209
DO I=1,ni_number_of_timers TIMER3A.1210
last_ni_number_of_times_timed(I)=ni_number_of_times_timed(I) TIMER3A.1211
last_ni_cpu_time_elapsed(I)=ni_cpu_time_elapsed(I) TIMER3A.1212
last_ni_wallclock_time_elapsed(I)= APB4F402.9
& ni_wallclock_time_elapsed(I) TIMER3A.1214
ENDDO TIMER3A.1215
TIMER3A.1216
TIMER3A.1217
9999 CONTINUE TIMER3A.1218
TIMER3A.1219
RETURN TIMER3A.1220
TIMER3A.1221
END TIMER3A.1222
TIMER3A.1223
TIMER3A.1224
TIMER3A.1225
TIMER3A.1226
TIMER3A.1227
!******************************************************************* TIMER3A.1228
REAL FUNCTION get_cpu_time() 10,1TIMER3A.1229
TIMER3A.1230
! Gets the cpu time from the system. TIMER3A.1231
TIMER3A.1232
IMPLICIT NONE TIMER3A.1233
REAL SECOND TIMER3A.1234
TIMER3A.1235
get_cpu_time=SECOND
() TIMER3A.1236
TIMER3A.1237
RETURN TIMER3A.1238
END TIMER3A.1239
TIMER3A.1240
REAL FUNCTION get_wallclock_time() 10,1TIMER3A.1241
TIMER3A.1242
! Gets the wallclock time from the wallclock. TIMER3A.1243
TIMER3A.1244
IMPLICIT NONE TIMER3A.1245
REAL temp TIMER3A.1246
*IF DEF,SGI PXTIMEFN.53
REAL (KIND=8) TIMEF PXTIMEFN.54
*ENDIF PXTIMEFN.55
TIMER3A.1247
*IF -DEF,SGI PXTIMEFN.56
CALL TIMEF
(temp) TIMER3A.1248
*ELSE PXTIMEFN.57
temp=TIMEF()/1000.0 PXTIMEFN.58
*ENDIF PXTIMEFN.59
TIMER3A.1249
get_wallclock_time=temp GPB3F403.161
RETURN TIMER3A.1251
END TIMER3A.1252
*ENDIF TIMER3A.1253