F.1.9 Output_Timer Procedure

The main documentation of the Output_Timer Procedure contains additional explanation of this code listing.

  subroutine Output_Timer (Timer, Global, Verbose, Unit)

    use Caesar_Numbers_Module, only: hundred, zero

    ! Input variables.

    type(Timer_type), intent(inout) :: Timer        ! Variable to be output.
    type(logical), intent(in), optional :: Global   ! Global flag.
    type(logical), intent(in), optional :: Verbose  ! Verbosity flag.
    type(integer), intent(in), optional :: Unit     ! Output unit.

    ! Internal variables.

    type(integer) :: A_Unit                     ! Actual output unit.
    type(logical) :: A_Global                   ! Actual global flag.
    type(logical) :: A_Verbose                  ! Actual verbosity flag.
    type(character,80) :: Timer_Name            ! Timer name.
    type(integer) :: Timer_Splits               ! Timer split count.
    type(real) :: Timer_CPU_Max                 ! Timer CPU maximum.
    type(real) :: Timer_CPU_Mean                ! Timer CPU mean.
    type(real) :: Timer_CPU_Min                 ! Timer CPU minimum.
    type(real) :: Timer_CPU_StDev               ! Timer CPU Standard Deviation.
    type(real) :: Timer_CPU_Split_Max           ! Timer CPU Split maximum.
    type(real) :: Timer_CPU_Split_Mean          ! Timer CPU Split mean.
    type(real) :: Timer_CPU_Split_Min           ! Timer CPU Split minimum.
    type(real) :: Timer_CPU_Split_StDev         ! Timer CPU Split Std Dev.
    type(real) :: Timer_Machine_Capacity_Usage  ! Timer machine capacity usage.
    type(real) :: Timer_Wall_Clock_Max          ! Timer Wall Clock maximum.
    type(real) :: Timer_Wall_Clock_Min          ! Timer Wall Clock minimum.
    type(real) :: Timer_Wall_Clock_Mean         ! Timer Wall Clock mean.
    type(real) :: Timer_Wall_Clock_StDev        ! Timer Wall Clock Std Dev.
    type(real) :: Timer_Wall_Clock_Split_Max    ! Timer Wall Clock Split max.
    type(real) :: Timer_Wall_Clock_Split_Min    ! Timer Wall Clock Split min.
    type(real) :: Timer_Wall_Clock_Split_Mean   ! Timer Wall Clock Split mean.
    type(real) :: Timer_Wall_Clock_Split_StDev  ! Timer Wall Clock Split StDev.

    !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ! Verify requirements.

    VERIFY(Valid_State(Timer),5)               ! Timer is valid.

    ! Set unit number.
    
    if (PRESENT(Unit)) then
      A_Unit = Unit
    else
      A_Unit = 6
    end if

    ! Set global flag.
    
    if (PRESENT(Global)) then
      A_Global = Global
    else
      A_Global = .false.
    end if

    ! Set verbosity flag.
    
    if (PRESENT(Verbose)) then
      A_Verbose = Verbose
    else
      A_Verbose = .false.
    end if

    ! Verbose output variables.

    if (A_Verbose) then

      Timer_Name = Name(Timer)
      Timer_Splits = Count(Timer, Global=A_Global, Split=.true.)

      ! CPU statistics.

      Timer_CPU_Mean = &
        Mean(Timer, 'CPU', Global=A_Global, Split=.false.)
      Timer_CPU_StDev = &
        Standard_Deviation(Timer, 'CPU', Global=A_Global, Split=.false.)
      Timer_CPU_Max = &
        Maximum(Timer, 'CPU', Global=A_Global, Split=.false.)
      Timer_CPU_Min = &
        Minimum(Timer, 'CPU', Global=A_Global, Split=.false.)
  
      ! Wall Clock statistics.
  
      Timer_Wall_Clock_Mean = &
        Mean(Timer, 'Wall_Clock', Global=A_Global, Split=.false.)
      Timer_Wall_Clock_StDev = &
        Standard_Deviation(Timer, 'Wall_Clock', Global=A_Global, Split=.false.)
      Timer_Wall_Clock_Max = &
        Maximum(Timer, 'Wall_Clock', A_Global, Split=.false.)
      Timer_Wall_Clock_Min = &
        Minimum(Timer, 'Wall_Clock', Global=A_Global, Split=.false.)
  
      ! Machine Capacity Usage = 
      !   Average CPU Time per PE / Max Wall Clock Time

      if (Timer_Wall_Clock_Max /= zero) then
        Timer_Machine_Capacity_Usage = &
          hundred * Timer_CPU_Mean / Timer_Wall_Clock_Max
      else
        Timer_Machine_Capacity_Usage = zero
      end if

      ! CPU Split statistics.
  
      Timer_CPU_Split_Mean = &
        Mean(Timer, 'CPU', Global=A_Global, Split=.true.)
      Timer_CPU_Split_StDev = &
        Standard_Deviation(Timer, 'CPU', Global=A_Global, Split=.true.)
      Timer_CPU_Split_Max = &
        Maximum(Timer, 'CPU', Global=A_Global, Split=.true.)
      Timer_CPU_Split_Min = &
        Minimum(Timer, 'CPU', Global=A_Global, Split=.true.)
  
      ! Wall Clock Split statistics.
  
      Timer_Wall_Clock_Split_Mean = &
        Mean(Timer, 'Wall_Clock', Global=A_Global, Split=.true.)
      Timer_Wall_Clock_Split_StDev = &
        Standard_Deviation(Timer, 'Wall_Clock', Global=A_Global, Split=.true.)
      Timer_Wall_Clock_Split_Max = &
        Maximum(Timer, 'Wall_Clock', Global=A_Global, Split=.true.)
      Timer_Wall_Clock_Split_Min = &
        Minimum(Timer, 'Wall_Clock', Global=A_Global, Split=.true.)

    ! Non-verbose output variables.

    else

      Timer_Name = Name(Timer)
      Timer_Wall_Clock_Max = &
        Maximum(Timer, 'Wall_Clock', A_Global, Split=.false.)
      Timer_CPU_Mean = Mean(Timer, 'CPU', Global=A_Global, Split=.false.)

    end if

    ! Output Timer Info.

    if (this_is_IO_PE) then
      if (A_Verbose) then
        if (A_Global) then
          write (A_Unit,100) TRIM(Timer_Name), ': *Global values*'
          write (A_Unit,101) 'Total number of splits = ', Timer_Splits
          write (A_Unit,101) 'CPU Time / PE:'
          call Output_Stats_Timer (A_Unit, Timer_CPU_Min, &
            Timer_CPU_Max, Timer_CPU_Mean, Timer_CPU_StDev)
          write (A_Unit,101) 'Wall Clock Time / PE:'
          call Output_Stats_Timer (A_Unit, Timer_Wall_Clock_Min, &
            Timer_Wall_Clock_Max, Timer_Wall_Clock_Mean, &
            Timer_Wall_Clock_StDev)
          write (A_Unit,101) 'CPU Time / Split:'
          call Output_Stats_Timer (A_Unit, Timer_CPU_Split_Min, &
            Timer_CPU_Split_Max, Timer_CPU_Split_Mean, Timer_CPU_Split_StDev)
          write (A_Unit,101) 'Wall Clock Time / Split:'
          call Output_Stats_Timer (A_Unit, Timer_Wall_Clock_Split_Min, &
            Timer_Wall_Clock_Split_Max, Timer_Wall_Clock_Split_Mean, &
            Timer_Wall_Clock_Split_StDev)
          if (Timer_Machine_Capacity_Usage /= zero) then
            write (A_Unit,106) 'Machine Capacity Usage = ', &
              Timer_Machine_Capacity_Usage, '%'
          end if
        else
          write (A_Unit,100) TRIM(Timer_Name), ': *Values for IO PE*'
          write (A_Unit,101) 'Total number of splits = ', Timer_Splits
          write (A_Unit,104) 'CPU Time (Total)        = ', &
            Timer_CPU_Mean
          write (A_Unit,104) 'Wall Clock Time (Total) = ', &
            Timer_Wall_Clock_Mean
          write (A_Unit,101) 'CPU Time / Split:'
          call Output_Stats_Timer (A_Unit, Timer_CPU_Split_Min, &
            Timer_CPU_Split_Max, Timer_CPU_Split_Mean, Timer_CPU_Split_StDev)
          write (A_Unit,101) 'Wall Clock Time / Split:'
          call Output_Stats_Timer (A_Unit, Timer_Wall_Clock_Split_Min, &
            Timer_Wall_Clock_Split_Max, Timer_Wall_Clock_Split_Mean, &
            Timer_Wall_Clock_Split_StDev)
          if (Timer_Machine_Capacity_Usage /= zero) then
            write (A_Unit,106) 'Machine Capacity Usage = ', &
              Timer_Machine_Capacity_Usage, '%'
          end if
        end if
      else
        write (A_Unit,107) TRIM(Timer_Name), &
          ': Max Tot Wall=', Timer_Wall_Clock_Max, &
          ', Avg Tot CPU=', Timer_CPU_Mean
      end if
    end if

    ! Format statements.

100 format (a,a)
101 format (2x,a,i7)
102 format (4x,a,1pe14.7,a,1pe15.7,a)
103 format (4x,a,1pe15.7,:,a,1pe13.7,a,0pf9.4,a)
104 format (2x,a,1pe15.7)
106 format (2x,a,f11.7,a)
107 format (a,a,1pe14.7,a,1pe14.7)

    ! Verify guarantees - none.

    return
  end subroutine Output_Timer

  ! Procedure: Output_Stats_Timer
  !
  ! This supplemental private routine is only used in Output_Timer.

  subroutine Output_Stats_Timer (Unit, Min, Max, Mean, StDev)

    ! Input variables.

    type(integer), intent(in) :: Unit             ! Output unit.
    type(real), intent(in) :: Max                 ! Maximum.
    type(real), intent(in) :: Mean                ! Mean.
    type(real), intent(in) :: Min                 ! Minimum.
    type(real), intent(in) :: StDev               ! Standard Deviation.

    !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ! Verify requirements - none. Cannot put VERIFYs here because
    ! this routine is called from within an "if (this_is_IO_PE)"
    ! block -- no global communication allowed.

    ! Write out statistics.

    write (Unit,100) 'Range     = [[', Min, ',  ', Max, ' ]]'
    if (Mean /= zero) then
      write (Unit,101) 'Average   = ', Mean, ' +/- ', StDev, ' ( +/-', &
        StDev / Mean * 100.d0, '% )' 
    else
      write (Unit,101) 'Average   = ', Mean, ' +/- ', StDev
    end if
    if (Min /= zero) then
      write (Unit,101) 'Max / Min = ', Max / Min
    else
      write (Unit,101) 'Max / Min = Infinite'
    end if

100 format (4x,a,1pe14.7,a,1pe15.7,a)
101 format (4x,a,1pe15.7,:,a,1pe13.7,a,0pf9.4,a)

    ! Verify guarantees - none.

    return
  end subroutine Output_Stats_Timer



Michael L. Hall