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()