stop_benchmark Subroutine

private impure subroutine stop_benchmark(this, flops)

Uses

    • face
  • proc~~stop_benchmark~2~~UsesGraph proc~stop_benchmark~2 forbenchmark_coarray::benchmark%stop_benchmark face face proc~stop_benchmark~2->face

Stops the currently active benchmark, calculates performance metrics, and writes the results to the file and terminal.

Type Bound

benchmark

Arguments

Type IntentOptional Attributes Name
class(benchmark), intent(inout) :: this

Benchmark object

procedure(Fun), optional :: flops

Function to calculate Floating Point Operations Per Second (optional)


Calls

proc~~stop_benchmark~2~~CallsGraph proc~stop_benchmark~2 forbenchmark_coarray::benchmark%stop_benchmark colorize colorize proc~stop_benchmark~2->colorize ctimer_stop ctimer_stop proc~stop_benchmark~2->ctimer_stop dtimer_stop dtimer_stop proc~stop_benchmark~2->dtimer_stop mtimer_stop mtimer_stop proc~stop_benchmark~2->mtimer_stop otimer_stop otimer_stop proc~stop_benchmark~2->otimer_stop proc~write_benchmark~2 forbenchmark_coarray::benchmark%write_benchmark proc~stop_benchmark~2->proc~write_benchmark~2 timer_stop timer_stop proc~stop_benchmark~2->timer_stop

Source Code

   impure subroutine stop_benchmark(this, flops)
      !! author: Seyed Ali Ghasemi
      !! Stops the currently active benchmark, calculates performance metrics, and writes the results to the file and terminal.
      !!
      use face

      interface
         impure function Fun(argi, argr)
            import rk, ik
            integer(ik), dimension(:), intent(in), optional :: argi
            real(rk),    dimension(:), intent(in), optional :: argr
            real(rk)                                        :: Fun
         end function Fun
      end interface

      procedure(Fun), optional :: flops !! Function to calculate Floating Point Operations Per Second (optional)

      class(benchmark), intent(inout)     :: this                 !! Benchmark object
      real(rk)                            :: elapsed_time_average !! Average elapsed time for the benchmark in all images
      real(rk)                            :: elapsed_time_min     !! Minimum elapsed time for the benchmark in all images
      real(rk)                            :: elapsed_time_max     !! Maximum elapsed time for the benchmark in all images
      real(rk)                            :: flops_total          !! Total floating-point operations per second in all images
      real(rk), dimension(:), allocatable :: elapsed_times        !! Array of elapsed times in all images
      integer                             :: i

      select case (trim(this%timer))
       case ('wall')
         call this%marks_co(this%imark)%time%timer_stop(message=' Elapsed time :',nloops=this%nloops)
         this%marks_co(this%imark)%elapsed_time = this%marks_co(this%imark)%time%elapsed_time
       case ('date_and_time')
         call this%marks_co(this%imark)%time%dtimer_stop(message=' Elapsed time :',nloops=this%nloops)
         this%marks_co(this%imark)%elapsed_time = this%marks_co(this%imark)%time%elapsed_dtime
       case ('cpu')
         call this%marks_co(this%imark)%time%ctimer_stop(message=' Elapsed time :',nloops=this%nloops)
         this%marks_co(this%imark)%elapsed_time = this%marks_co(this%imark)%time%cpu_time
       case ('omp')
#if defined(USE_OMP)
         call this%marks_co(this%imark)%time%otimer_stop(message=' Elapsed time :',nloops=this%nloops)
         this%marks_co(this%imark)%elapsed_time = this%marks_co(this%imark)%time%omp_time
#else
         error stop 'Use -DUSE_OMP to enable OpenMP.'
#endif
       case ('mpi')
#if defined(USE_MPI)
         call this%marks_co(this%imark)%time%mtimer_stop(message=' Elapsed time :',nloops=this%nloops)
         this%marks_co(this%imark)%elapsed_time = this%marks_co(this%imark)%time%mpi_time
#else
         error stop 'Use -DUSE_MPI to enable MPI.'
#endif
      end select

      if (present(flops)) then
         if (this%marks_co(this%imark)%elapsed_time <= epsilon(0.0_rk)) error stop 'Elapsed time is too small.'
         this%marks_co(this%imark)%flops = flops(this%argi,this%argr)/this%marks_co(this%imark)%elapsed_time
         print'(a,f7.3,a)', ' Performance  :', this%marks_co(this%imark)%flops,' [GFLOPS/image]'
      else
         this%marks_co(this%imark)%flops = 0.0_rk
      end if

      sync all

      if (this_image() == 1) then
         allocate(elapsed_times(num_images()))
         do i = 1, num_images()
            elapsed_times(i) = this%marks_co(this%imark)[i]%elapsed_time
         end do
         elapsed_time_max = maxval(elapsed_times)
         elapsed_time_min = minval(elapsed_times)
         elapsed_time_average = sum(elapsed_times)/num_images()

         if (present(flops)) flops_total = 0.0_rk
         do i = 1,num_images()
            if (present(flops)) flops_total = flops_total + this%marks_co(this%imark)[i]%flops
         end do
      end if
      call co_broadcast(elapsed_time_average, 1)
      call co_broadcast(elapsed_time_min, 1)
      call co_broadcast(elapsed_time_max, 1)
      if (present(flops)) call co_broadcast(flops_total, 1)
      this%marks(this%imark)%elapsed_time_average = elapsed_time_average
      this%marks(this%imark)%elapsed_time_min = elapsed_time_min
      this%marks(this%imark)%elapsed_time_max = elapsed_time_max

      if (this%marks(1)%elapsed_time_max <= epsilon(0.0_rk)) error stop 'Maximum elapsed time for the reference benchmark is too small.'
      this%marks(this%imark)%speedup_max_total = this%marks(1)%elapsed_time_max/this%marks(this%imark)%elapsed_time_max


      if (this_image()==1) then
         print'(a,f7.3,a)', colorize(' Elapsed time (max)     :', color_fg='blue'),&
            this%marks(this%imark)%elapsed_time_max, ' [s]'
         print'(a,f7.3,a)', colorize(' Elapsed time (min)     :', color_fg='blue'),&
            this%marks(this%imark)%elapsed_time_min, ' [s]'

         print'(a,f7.3,a)', colorize(' Elapsed time (average) :', color_fg='blue'),&
            this%marks(this%imark)%elapsed_time_average, ' [s]'

         print'(a,f7.3,a)', colorize(' Speedup (max)          :', color_fg='blue'),&
            this%marks(this%imark)%speedup_max_total, ' [-]'
         if (present(flops)) print'(a,f7.3,a)', colorize(' Performance  (total)   :', color_fg='cyan'),&
            flops_total, ' [GFLOPS]'
         print'(a)', ''
      end if


      if (present(flops)) then
         this%marks(this%imark)%flops_total = flops_total
      else
         this%marks(this%imark)%flops_total = 0.0_rk
      end if

      call this%write_benchmark()
   end subroutine stop_benchmark