45 use mpi_f08,
only : mpi_wtime, mpi_allreduce, mpi_in_place, &
128 character(len=*) :: name
129 integer,
intent(in) :: region_id
132 if (.not. this%enabled_)
then
137 if (len_trim(this%rt_stats_id(region_id)) .eq. 0)
then
138 this%rt_stats_id(region_id) = trim(name)
140 if (trim(this%rt_stats_id(region_id)) .ne. trim(name))
then
144 region_data%x = region_id
145 region_data%y = mpi_wtime()
146 call this%region_timestamp_%push(region_data)
148 call neko_error(
'Invalid profiling region id')
156 character(len=*) :: name
157 integer,
intent(in) :: region_id
158 real(kind=
dp) :: end_time, elapsed_time
161 if (.not. this%enabled_)
then
165 end_time = mpi_wtime()
167 if (trim(this%rt_stats_id(region_id)) .ne. trim(name))
then
168 call neko_error(
'Invalid profiler region closed (' // name //
', &
169 &expected: ' // trim(this%rt_stats_id(region_id)) //
')')
171 region_data = this%region_timestamp_%pop()
173 if (region_data%x .gt. 0)
then
174 elapsed_time = end_time - region_data%y
175 call this%elapsed_time_(region_data%x)%push(elapsed_time)
183 character(len=LOG_SIZE) :: log_buf
184 character(len=1250) :: hdr
185 real(kind=
dp) :: avg, std, sem, total
186 integer :: i, nsamples, ncols, nrows, col_idx
189 if (.not. this%enabled_)
then
193 call neko_log%section(
'Runtime statistics')
195 write(log_buf,
'(A,A,1x,A,1x,A)')
' ',&
196 ' Total time ',
' Avg. time ',
' Range +/-'
198 write(log_buf,
'(A)') &
199 '--------------------------------------------------------------------'
205 do i = 1,
size(this%elapsed_time_)
206 if (len_trim(this%rt_stats_id(i)) .gt. 0)
then
207 nsamples = this%elapsed_time_(i)%size()
209 hdr = trim(hdr) // trim(this%rt_stats_id(i)) //
', '
210 nrows =
max(nrows, nsamples)
211 if (nsamples .gt. 0)
then
212 select type (region_sample => this%elapsed_time_(i)%data)
213 type is (double precision)
214 total = sum(region_sample(1:nsamples))
215 call mpi_allreduce(mpi_in_place, total, 1, &
216 mpi_double_precision, mpi_sum,
neko_comm)
218 avg = total / nsamples
219 std = (total - avg)**2 / nsamples
220 sem = std /sqrt(
real(nsamples,
dp))
222 write(log_buf,
'(A, E15.7,1x,1x,E15.7,1x,1x,E15.7)') &
223 this%rt_stats_id(i), total, avg, 2.5758_dp * sem
231 if (this%output_profile_)
then
233 call profile_data%init(nrows, ncols)
234 do i = 1,
size(this%elapsed_time_)
235 if (len_trim(this%rt_stats_id(i)) .gt. 0)
then
236 nsamples = this%elapsed_time_(i)%size()
237 col_idx = col_idx + 1
238 if (nsamples .gt. 0)
then
239 select type (region_sample => this%elapsed_time_(i)%data)
240 type is (double precision)
241 profile_data%x(1:nsamples,col_idx) = &
242 region_sample(1:nsamples)
243 call mpi_allreduce(mpi_in_place, &
244 profile_data%x(1:nsamples,col_idx), nsamples, &
245 mpi_double_precision, mpi_sum,
neko_comm)
246 profile_data%x(1:nsamples, col_idx) = &
247 profile_data%x(1:nsamples, col_idx) /
pe_size
255 type(
file_t) :: profile_file
256 call profile_file%init(
'profile.csv')
257 call profile_file%set_header(hdr)
258 call profile_file%write(profile_data)
264 call profile_data%free()