00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 module psmile_timer
00037
00038 use psmile_common
00039 use prism_constants, only : prism_error_alloc, prism_error_invalid_arg
00040
00041 implicit none
00042
00043
00044 character (len=max_name) :: app_name
00045
00046
00047 integer :: comm_timer
00048
00049
00050 integer :: comm_size
00051
00052
00053 integer :: comm_rank
00054
00055
00056 character (len=max_name) :: file_name
00057
00058 type timer_details
00059
00060
00061 character (len=max_name) :: label
00062
00063
00064 double precision :: start_wtime, end_wtime
00065
00066
00067 real :: start_ctime, end_ctime
00068 end type timer_details
00069
00070 type (timer_details), allocatable :: timer (:)
00071 real, allocatable :: sum_ctime(:)
00072 double precision, allocatable :: sum_wtime(:)
00073
00074 contains
00075
00076
00077
00078 subroutine psmile_timer_init (num_timer, timer_label, app, file, comm)
00079
00080 integer, intent (in) :: num_timer
00081 character (len=max_name), intent (in) :: timer_label(num_timer)
00082 character (len=*), intent (in) :: app
00083 character (len=*), intent (in) :: file
00084 integer, intent (in) :: comm
00085
00086 integer :: ierror
00087
00088 #ifdef PRISM_ASSERTION
00089 if (num_timer < 1) then
00090 call psmile_error_common ( prism_error_invalid_arg, 'num_timer', &
00091 (/0/), 1, __FILE__, __LINE__ )
00092 return
00093 endif
00094 #endif
00095
00096 app_name = trim (app)
00097 file_name = trim (file)
00098
00099
00100 allocate (timer (num_timer), sum_wtime(num_timer), sum_ctime(num_timer), stat=ierror)
00101
00102 if ( ierror /= 0 ) then
00103 call psmile_error_common ( prism_error_alloc, 'timer, sum_wtime, sum_ctime', &
00104 (/0, num_timer/), 2, __FILE__, __LINE__ )
00105 return
00106 endif
00107
00108 timer(:)%label = timer_label
00109 timer(:)%start_wtime = 0
00110 timer(:)%end_wtime = 0
00111 timer(:)%start_ctime = 0
00112 timer(:)%end_ctime = 0
00113
00114 sum_wtime(:) = 0
00115 sum_ctime(:) = 0
00116
00117
00118 comm_timer = comm
00119
00120 call MPI_Comm_size(comm, comm_size, ierror)
00121 call MPI_Comm_rank(comm, comm_rank, ierror)
00122
00123 #ifdef VERBOSE
00124 print *, '| | timers initialised in processor : ', comm_rank
00125 call psmile_flushstd
00126 #endif
00127
00128 end subroutine psmile_timer_init
00129
00130
00131
00132 subroutine psmile_timer_start (timer_id)
00133
00134 integer, intent (in) :: timer_id
00135
00136 #ifdef PRISM_ASSERTION
00137 if (.not. allocated (timer)) then
00138 call psmile_error_common ( prism_error_invalid_arg, 'timer_id', &
00139 (/0/), 1, __FILE__, __LINE__ )
00140 return
00141 else if (timer_id < 1 .and. timer_id > size (timer)) then
00142 call psmile_error_common ( prism_error_invalid_arg, 'timer_id', &
00143 (/0/), 1, __FILE__, __LINE__ )
00144 return
00145 endif
00146 #endif
00147
00148 timer(timer_id)%start_wtime = MPI_Wtime()
00149 call cpu_time(timer(timer_id)%start_ctime)
00150
00151 end subroutine psmile_timer_start
00152
00153
00154
00155 subroutine psmile_timer_stop (timer_id)
00156
00157 integer, intent (in) :: timer_id
00158
00159 #ifdef PRISM_ASSERTION
00160 if (.not. allocated (timer)) then
00161 call psmile_error_common ( prism_error_invalid_arg, 'timer_id', &
00162 (/0/), 1, __FILE__, __LINE__ )
00163 return
00164 else if (timer_id < 1 .and. timer_id > size (timer)) then
00165 call psmile_error_common ( prism_error_invalid_arg, 'timer_id', &
00166 (/0/), 1, __FILE__, __LINE__ )
00167 return
00168 endif
00169 #endif
00170
00171 timer(timer_id)%end_wtime = MPI_Wtime()
00172 call cpu_time(timer(timer_id)%end_ctime)
00173
00174 sum_wtime(timer_id) = sum_wtime(timer_id) + &
00175 timer(timer_id)%end_wtime - timer(timer_id)%start_wtime
00176 sum_ctime(timer_id) = sum_ctime(timer_id) + &
00177 timer(timer_id)%end_ctime - timer(timer_id)%start_ctime
00178
00179 end subroutine psmile_timer_stop
00180
00181
00182
00183 subroutine psmile_timer_reset (timer_id)
00184
00185 integer, intent (in) :: timer_id
00186
00187 #ifdef PRISM_ASSERTION
00188 if (.not. allocated (timer)) then
00189 call psmile_error_common ( prism_error_invalid_arg, 'timer_id', &
00190 (/0/), 1, __FILE__, __LINE__ )
00191 return
00192 else if (timer_id < 1 .and. timer_id > size (timer)) then
00193 call psmile_error_common ( prism_error_invalid_arg, 'timer_id', &
00194 (/0/), 1, __FILE__, __LINE__ )
00195 return
00196 endif
00197 #endif
00198
00199 timer(timer_id)%start_wtime = 0
00200 timer(timer_id)%start_ctime = 0
00201
00202 timer(timer_id)%end_wtime = 0
00203 timer(timer_id)%end_ctime = 0
00204
00205 sum_wtime(timer_id) = 0
00206 sum_ctime(timer_id) = 0
00207
00208 end subroutine psmile_timer_reset
00209
00210
00211
00212 subroutine psmile_timer_print
00213
00214 real, allocatable :: sum_ctime_global(:,:)
00215 double precision, allocatable :: sum_wtime_global(:,:)
00216
00217
00218
00219 integer, parameter :: output_unit = 901
00220 integer, parameter :: root = 0
00221 integer :: k, n
00222 integer :: ierror
00223
00224 #ifdef PRISM_ASSERTION
00225 if (.not. allocated (timer)) &
00226 call psmile_error_common ( -1, 'psmile_timer_init was not called', &
00227 (/-1/), 1, __FILE__, __LINE__ )
00228 #endif
00229
00230 allocate (sum_ctime_global(size (timer), comm_size), &
00231 sum_wtime_global(size (timer), comm_size), stat=ierror)
00232
00233 if ( ierror /= 0 ) then
00234 call psmile_error_common ( prism_error_alloc, 'sum_ctime_global, sum_wtime_global', &
00235 (/0, 2*(comm_size*size (timer))/), 2, __FILE__, __LINE__ )
00236 return
00237 endif
00238
00239
00240
00241
00242 if (comm_size > 1) then
00243
00244 print *,' Calling MPI_Gather for CPU time in psmile_timer_print, num_timer = ', size (timer)
00245
00246 call MPI_Gather(sum_ctime(1), size (timer), MPI_REAL, sum_ctime_global(1,1), &
00247 size (timer), MPI_REAL, root, comm_timer, ierror)
00248 print *,' error code for MPI_Gather = ', ierror
00249
00250 print *,' Calling MPI_Gather for elaps time in psmile_timer_print, num_timer = ', size (timer)
00251
00252 call MPI_Gather(sum_wtime(1), size (timer), MPI_DOUBLE_PRECISION, sum_wtime_global(1,1), &
00253 size (timer), MPI_DOUBLE_PRECISION, root, comm_timer, ierror)
00254
00255 print *, ' error code for MPI_Gather = ', ierror
00256
00257 else
00258
00259 sum_ctime_global(:,1) = sum_ctime(:)
00260 sum_wtime_global(:,1) = sum_wtime(:)
00261
00262 endif
00263
00264
00265 if (comm_rank == root) then
00266
00267 print *,' Root (process 0) has received timer values from all processes '
00268 open(output_unit, file=trim(file_name), form="FORMATTED", status="UNKNOWN")
00269
00270 write(output_unit,*)' =================================='
00271 write(output_unit,*)' ', trim(app_name)
00272 write(output_unit,*)' Overall CPU time statistics'
00273 write(output_unit,*)' =================================='
00274 write(output_unit,*)''
00275 write(output_unit,'(a)',advance="NO") " P r o c e s s o r s ----------> "
00276 write(output_unit,'(8(3x,i2,5x))')(k,k=1,comm_size)
00277 do n = 1, size (timer)
00278
00279 WRITE(output_unit,'(1x,i3,2x,a24,2x,(8f10.4))') n, timer(n)%label, &
00280 (sum_ctime_global(n,k),k=1,comm_size)
00281 enddo
00282 write(output_unit,*)''
00283 write(output_unit,*)' ======================================'
00284 write(output_unit,*)' ', trim(app_name)
00285 write(output_unit,*)' Overall Elapsed time statistics'
00286 write(output_unit,*)' ======================================'
00287 write(output_unit,*)''
00288 write(output_unit,'(a)',advance="NO") " P r o c e s s o r s ----------> "
00289 write(output_unit,'(8(3x,i2,5x))')(k,k=1,comm_size)
00290 do n = 1, size (timer)
00291
00292 WRITE(output_unit,'(1x,i3,2x,a24,2x,(8f10.4))') n, timer(n)%label, &
00293 (sum_wtime_global(n,k),k=1,comm_size)
00294 enddo
00295 write(output_unit,*)''
00296 write(output_unit,*)' ======================================'
00297
00298 close(output_unit)
00299
00300 endif
00301
00302 deallocate (sum_ctime_global, sum_wtime_global)
00303
00304 deallocate (timer, sum_ctime, sum_wtime)
00305
00306 end subroutine psmile_timer_print
00307
00308 end module psmile_timer