other/s_timer.f90
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | submodule(m_timer) s_timer | ||
| 2 | #include "petsc.fi" | ||
| 3 | implicit none | ||
| 4 | contains | ||
| 5 | |||
| 6 | ✗ | module subroutine timer_init(this, comm) | |
| 7 | class(BasicTimer), intent(inout) :: this | ||
| 8 | integer, intent(in), optional :: comm | ||
| 9 | |||
| 10 | integer :: ierr, nr_ranks | ||
| 11 | |||
| 12 | ✗ | if (present(comm)) then | |
| 13 | ✗ | this%comm = comm | |
| 14 | else | ||
| 15 | ✗ | this%comm = PETSC_COMM_WORLD | |
| 16 | end if | ||
| 17 | |||
| 18 | ✗ | PetscCallMPI(MPI_Comm_size(this%comm, nr_ranks, ierr)) | |
| 19 | ✗ | PetscCallMPI(MPI_Comm_rank(this%comm, this%my_rank, ierr)) | |
| 20 | |||
| 21 | ✗ | this%start_time = 0.0_wp | |
| 22 | ✗ | this%end_time = 0.0_wp | |
| 23 | ✗ | this%elapsed_time = 0.0_wp | |
| 24 | ✗ | this%start_count = 0 | |
| 25 | ✗ | allocate (this%elapsed_times(nr_ranks)) | |
| 26 | ✗ | this%elapsed_times = -1.0_wp | |
| 27 | ✗ | end subroutine timer_init | |
| 28 | |||
| 29 | ✗ | module subroutine timer_destroy(this) | |
| 30 | type(BasicTimer), intent(inout) :: this | ||
| 31 | |||
| 32 | ✗ | if (allocated(this%elapsed_times)) then | |
| 33 | ✗ | deallocate (this%elapsed_times) | |
| 34 | end if | ||
| 35 | ✗ | end subroutine timer_destroy | |
| 36 | |||
| 37 | ✗ | module subroutine timer_start(this, reset) | |
| 38 | class(BasicTimer), intent(inout) :: this | ||
| 39 | logical, intent(in), optional :: reset | ||
| 40 | |||
| 41 | logical :: reset_ | ||
| 42 | |||
| 43 | ✗ | if (.not. allocated(this%elapsed_times)) call this%init() | |
| 44 | |||
| 45 | reset_ = .false. | ||
| 46 | ✗ | if (present(reset)) reset_ = reset | |
| 47 | |||
| 48 | ✗ | if (reset_) then | |
| 49 | ✗ | this%elapsed_time = 0.0_wp | |
| 50 | ✗ | this%start_count = 0 | |
| 51 | end if | ||
| 52 | |||
| 53 | ✗ | call cpu_time(this%start_time) | |
| 54 | ✗ | this%start_count = this%start_count + 1 | |
| 55 | ✗ | end subroutine timer_start | |
| 56 | |||
| 57 | ✗ | module subroutine timer_stop(this, print_summary, prefix) | |
| 58 | class(BasicTimer), intent(inout) :: this | ||
| 59 | logical, intent(in), optional :: print_summary | ||
| 60 | character(len=*), intent(in), optional :: prefix | ||
| 61 | |||
| 62 | integer :: ierr | ||
| 63 | logical :: print_summary_ | ||
| 64 | character(len=400) :: prefixed_summary | ||
| 65 | |||
| 66 | ✗ | call cpu_time(this%end_time) | |
| 67 | ✗ | this%elapsed_time = this%elapsed_time + this%end_time - this%start_time | |
| 68 | |||
| 69 | ✗ | print_summary_ = present(prefix) | |
| 70 | ✗ | if (present(print_summary)) print_summary_ = print_summary | |
| 71 | |||
| 72 | ✗ | PetscCallMPI(MPI_Allgather(this%elapsed_time, 1, MPI_WP, this%elapsed_times, 1, MPI_WP, this%comm, ierr)) | |
| 73 | |||
| 74 | ✗ | if (this%my_rank == 0 .and. print_summary_) then | |
| 75 | ✗ | if (present(prefix)) then | |
| 76 | ✗ | prefixed_summary = prefix//this%summary_string() | |
| 77 | else | ||
| 78 | ✗ | prefixed_summary = this%summary_string() | |
| 79 | end if | ||
| 80 | ✗ | write (*, '(A)') trim(prefixed_summary) | |
| 81 | end if | ||
| 82 | end subroutine timer_stop | ||
| 83 | |||
| 84 | ✗ | module function timer_minval(this) result(min_time) | |
| 85 | class(BasicTimer), intent(in) :: this | ||
| 86 | real(wp) :: min_time | ||
| 87 | |||
| 88 | ✗ | if (.not. allocated(this%elapsed_times)) then | |
| 89 | min_time = -1.0_wp | ||
| 90 | return | ||
| 91 | end if | ||
| 92 | |||
| 93 | ✗ | min_time = minval(this%elapsed_times) | |
| 94 | end function timer_minval | ||
| 95 | |||
| 96 | ✗ | module function timer_maxval(this) result(max_time) | |
| 97 | class(BasicTimer), intent(in) :: this | ||
| 98 | real(wp) :: max_time | ||
| 99 | |||
| 100 | ✗ | if (.not. allocated(this%elapsed_times)) then | |
| 101 | max_time = -1.0_wp | ||
| 102 | return | ||
| 103 | end if | ||
| 104 | |||
| 105 | ✗ | max_time = maxval(this%elapsed_times) | |
| 106 | end function timer_maxval | ||
| 107 | |||
| 108 | ✗ | module function timer_avgval(this) result(avg_time) | |
| 109 | class(BasicTimer), intent(in) :: this | ||
| 110 | real(wp) :: avg_time | ||
| 111 | |||
| 112 | ✗ | if (.not. allocated(this%elapsed_times)) then | |
| 113 | avg_time = -1.0_wp | ||
| 114 | return | ||
| 115 | end if | ||
| 116 | |||
| 117 | ✗ | avg_time = sum(this%elapsed_times) / size(this%elapsed_times) | |
| 118 | ✗ | end function timer_avgval | |
| 119 | |||
| 120 | ✗ | module function timer_summary_string(this) result(summary) | |
| 121 | class(BasicTimer), intent(in) :: this | ||
| 122 | character(len=40) :: summary | ||
| 123 | |||
| 124 | real(wp) :: max_, factor | ||
| 125 | character(len=10) :: time_unit | ||
| 126 | |||
| 127 | ✗ | if (.not. allocated(this%elapsed_times)) then | |
| 128 | ✗ | summary = 'Timer not initialized.' | |
| 129 | ✗ | return | |
| 130 | end if | ||
| 131 | |||
| 132 | ✗ | max_ = this%maxval() | |
| 133 | |||
| 134 | ✗ | if (max_ < 60._wp) then | |
| 135 | factor = 1.0_wp | ||
| 136 | ✗ | time_unit = 'sec' | |
| 137 | ✗ | else if (max_ < 3600._wp) then | |
| 138 | factor = 1.0_wp / 60.0_wp | ||
| 139 | ✗ | time_unit = 'min' | |
| 140 | else | ||
| 141 | factor = 1.0_wp / 3600.0_wp | ||
| 142 | ✗ | time_unit = 'hr' | |
| 143 | end if | ||
| 144 | |||
| 145 | write (summary, '(A, F0.2, A, F0.2, A, F0.2, 2A)') & | ||
| 146 | ✗ | 'min/avg/max ', & | |
| 147 | ✗ | factor * this%minval(), '/', & | |
| 148 | ✗ | factor * this%avgval(), '/', & | |
| 149 | ✗ | factor * max_, & | |
| 150 | ✗ | ' ', time_unit | |
| 151 | end function timer_summary_string | ||
| 152 | |||
| 153 | end submodule s_timer | ||
| 154 |