45 use mpi_f08,
only : mpi_wtime, mpi_allreduce, mpi_in_place, &
133 character(len=*),
intent(in) :: name
134 integer,
optional,
intent(in) :: region_id
138 if (.not. this%enabled)
return
140 if (
present(region_id))
then
143 call this%find_region_id(name, id)
147 if (len_trim(this%rt_stats_id(id)) .eq. 0)
then
148 this%rt_stats_id(id) = trim(name)
149 else if (trim(this%rt_stats_id(id)) .ne. trim(name))
then
153 region_data%y = mpi_wtime()
154 call this%region_timestamp%push(region_data)
156 call neko_error(
'Invalid profiling region id')
166 character(len=*),
optional,
intent(in) :: name
167 integer,
optional,
intent(in) :: region_id
168 real(kind=
dp) :: end_time, elapsed_time
170 character(len=1024) :: error_msg
173 if (.not. this%enabled)
return
175 end_time = mpi_wtime()
176 region_data = this%region_timestamp%pop()
178 if (region_data%x .le. 0)
then
179 call neko_error(
'Invalid profiling region closed')
183 if (
present(name))
then
184 if (
present(region_id))
then
187 call this%find_region_id(name, id)
190 if (trim(this%rt_stats_id(id)) .ne. trim(name))
then
191 write(error_msg,
'(A,I0,A,A,A)')
'Invalid profiler region closed (', &
192 id,
', expected: ', trim(this%rt_stats_id(id)),
')'
195 else if (region_data%x .ne. id)
then
197 write(error_msg,
'(A,A,A,A,A)')
'Invalid profiler region closed (', &
198 trim(this%rt_stats_id(region_data%x)),
', expected: ', &
199 trim(this%rt_stats_id(id)),
')'
204 elapsed_time = end_time - region_data%y
205 call this%elapsed_time(region_data%x)%push(elapsed_time)
212 character(len=LOG_SIZE) :: log_buf, fmt
213 character(len=1250) :: hdr
214 real(kind=
dp) :: avg, std, sem, total
215 integer :: i, nsamples, ncols, nrows, col_idx
218 if (.not. this%enabled)
return
220 call neko_log%section(
'Runtime statistics')
222 write(fmt,
'(A,I0,A)')
'(',
rt_stats_max_name_len,
'x,1x,A15,2x,A15,2x,A15)'
223 write(log_buf, fmt)
'Total time',
'Avg. time',
'Range +/-'
232 if (len_trim(this%rt_stats_id(i)) .gt. 0)
then
233 nsamples = this%elapsed_time(i)%size()
235 hdr = trim(hdr) // trim(this%rt_stats_id(i)) //
', '
236 nrows =
max(nrows, nsamples)
237 if (nsamples .gt. 0)
then
238 select type (region_sample => this%elapsed_time(i)%data)
239 type is (double precision)
240 total = sum(region_sample(1:nsamples))
241 call mpi_allreduce(mpi_in_place, total, 1, &
242 mpi_double_precision, mpi_sum,
neko_comm)
244 avg = total / nsamples
245 std = (total - avg)**2 / nsamples
246 sem = std /sqrt(
real(nsamples,
dp))
249 ',1x,E15.7,2x,E15.7,2x,E15.7)'
250 write(log_buf, fmt) this%rt_stats_id(i), total, avg, &
259 if (this%output_profile)
then
261 call profile_data%init(nrows, ncols)
262 do i = 1,
size(this%elapsed_time)
263 if (len_trim(this%rt_stats_id(i)) .gt. 0)
then
264 nsamples = this%elapsed_time(i)%size()
265 col_idx = col_idx + 1
266 if (nsamples .gt. 0)
then
267 select type (region_sample => this%elapsed_time(i)%data)
268 type is (double precision)
269 profile_data%x(1:nsamples,col_idx) = &
270 region_sample(1:nsamples)
271 call mpi_allreduce(mpi_in_place, &
272 profile_data%x(1:nsamples,col_idx), nsamples, &
273 mpi_double_precision, mpi_sum,
neko_comm)
274 profile_data%x(1:nsamples, col_idx) = &
275 profile_data%x(1:nsamples, col_idx) /
pe_size
283 type(
file_t) :: profile_file
284 call profile_file%init(
'profile.csv')
285 call profile_file%set_header(hdr)
286 call profile_file%write(profile_data)
292 call profile_data%free()