!= CPU æ™‚é–“ã®è¨ˆæ¸¬
!= Monitor of CPU TIME
!
! Authors::   Yasuhiro MORIKAWA
! Version::   $Id: dc_clock.F90,v 1.1 2009-03-20 09:09:53 morikawa Exp $
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2006. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
module dc_clock
  !
  != CPU æ™‚é–“ã®è¨ˆæ¸¬
  != Monitor of CPU TIME
  !
  ! ãƒ—ãƒã‚°ãƒ©ãƒ ã®å‡¦ç†ã«è¦ã—ãŸ CPU æ™‚é–“ã‚’è¨ˆæ¸¬ã—ã¦è¡¨ç¤ºã—ã¾ã™.
  !
  !== Tutorial
  !
  ! * gtool5 ã‚ªãƒ•ã‚£ã‚·ãƒ£ãƒ«ãƒãƒ¥ãƒ¼ãƒˆãƒªã‚¢ãƒ«:
  !   {CPU æ™‚é–“ã®è¨ˆæ¸¬}[link:../tutorial/dc_clock.htm]
  !
  !== Procedures list
  !
  ! DCClockCreate               :: CLOCK åž‹å¤‰æ•°ã®åˆæœŸè¨å®š
  ! DCClockStart                :: è¨ˆæ¸¬ã®é–‹å§‹
  ! DCClockStop                 :: è¨ˆæ¸¬ã®ä¸€æ™‚åœæ¢
  ! DCClockClose                :: æ§‹é€ åž‹ CLOCK å¤‰æ•°ã®çµ‚äº†å‡¦ç†
  ! DCClockGet, DCClockEvalSec  :: CPU æ™‚é–“ (å˜ä½: ç§’) ã®å–å¾—
  ! DCClockToChar               :: CPU æ™‚é–“ã‚’é©å½“ã«æ•´å½¢ã—ã¦æ–‡å—åž‹å¤‰æ•°ã«å¤‰æ›
  ! DCClockPutLine              :: æ§‹é€ åž‹ CLOCK å¤‰æ•°ã®æƒ…å ±ã‚’è¡¨ç¤º
  ! DCClockResult               :: CPU æ™‚é–“ã«é–¢ã™ã‚‹ç·åˆçš„ãªæƒ…å ±ã‚’è¡¨ç¤º
  ! DCClockPredict              :: ãƒ—ãƒã‚°ãƒ©ãƒ ãŒçµ‚äº†ã™ã‚‹ã¾ã§ã®äºˆæ¸¬ CPU æ™‚é–“,
  !                                ãŠã‚ˆã³æ—¥æ™‚ã‚’è¡¨ç¤º
  ! DCClockSetName              :: åç§°ã®å†è¨å®š
  ! #operator(+)                :: åŠ ç®— (dc_clock#CLOCK åž‹åŒå£«)
  ! #operator(-)                :: æ¸›ç®— (dc_clock#CLOCK åž‹åŒå£«)
  !
  !== Usage
  !
  ! å§‹ã‚ã«, æ§‹é€ åž‹ CLOCK ã®å¤‰æ•°ã‚’å®šç¾©ã—, DCClockCreate ã§åˆæœŸåŒ–ã—ã¾ã™.
  ! ãƒ—ãƒã‚°ãƒ©ãƒ ä¸ã®è¨ˆæ¸¬é–‹å§‹åœ°ç‚¹ã§ DCClockStart ã‚’å‘¼ã³å‡ºã—,
  ! è¨ˆæ¸¬ã‚’ä¸€æ™‚åœæ¢ã™ã‚‹åœ°ç‚¹ã§ DCClockStop ã‚’å‘¼ã³å‡ºã—ã¾ã™.
  ! DCClockResult ã«ã‚ˆã£ã¦çµŒéŽæ™‚é–“ã‚’è¡¨ç¤ºã—ã¾ã™.
  ! DCClockPredict ã‚’ä½¿ç”¨ã™ã‚‹ã“ã¨ã§ãƒ—ãƒã‚°ãƒ©ãƒ ãŒçµ‚äº†ã™ã‚‹ã¾ã§ã®æ®‹ã‚Š CPU æ™‚é–“
  ! ã®äºˆæ¸¬å€¤ã‚’è¡¨ç¤ºã™ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™.
  !
  !     program dc_clock_sapmle1
  !       use dc_clock, only: CLOCK, DCClockCreate, DCClockClose, &
  !         & DCClockStart, DCClockStop, DCClockResult, DCClockPredict, &
  !         & operator(+)
  !       implicit none
  !       type(CLOCK):: clock1, clock2
  !       integer:: i, j
  !       integer, parameter:: loop_num = 8
  !       real:: a, b
  !
  !       call DCClockCreate( clk = clock1, & ! (out)
  !         & name = 'exponential' )          ! (in)
  !       call DCClockCreate( clk = clock2, & ! (out)
  !         & name = 'four-operations' )      ! (in)
  !       a = 2.0
  !       b = 1.0
  !       do i = 1, loop_num
  !         call DCClockStart( clk = clock1 ) ! (inout)
  !         do j = 1, 1000000
  !           a = (a**2)**0.3 + 1.0
  !         enddo
  !         call DCClockStop( clk = clock1 )  ! (inout)
  !         call DCClockStart( clk = clock2 ) ! (inout)
  !         do j = 1, 1000000
  !           b = b / 3.0 * 2.0 + 1.0 - 1.0e-1
  !         enddo
  !         call DCClockStop( clk = clock2 ) ! (inout)
  !         call DCClockPredict( &
  !           & clk = clock1 + clock2, &            ! (in)
  !           & progress = real(i)/real(loop_num) ) ! (in)
  !       enddo
  !       call DCClockResult( &
  !         & clks = (/clock1, clock2/), &  ! (in)
  !         & total_auto = .true. )         ! (in)
  !       call DCClockClose( clk = clock1 ) ! (inout)
  !       call DCClockClose( clk = clock2 ) ! (inout)
  !
  !       write(*,*) 'a = ', a
  !       write(*,*) 'b = ', b
  !     end program dc_clock_sapmle1
  !
  !== Note
  !
  ! CPU æ™‚é–“ã¯ã‚·ã‚¹ãƒ†ãƒ  CPU æ™‚é–“ã¨ãƒ¦ãƒ¼ã‚¶ CPU æ™‚é–“ã¨ã«åˆ†ã‘ã‚‹ã“ã¨ãŒ
  ! ã§ãã¾ã™. dc_clock ã§ã¯ CPU æ™‚é–“ã®è¨ˆæ¸¬ã« *cpu_time* ã‚µãƒ–ãƒ«ãƒ¼ãƒãƒ³
  ! (Fortran 95 è¦æ ¼ã§å°Žå…¥ã•ã‚ŒãŸçµ„è¾¼ã¿ã‚µãƒ–ãƒ«ãƒ¼ãƒãƒ³) ã‚’ä½¿ç”¨ã—ã¦ã„ã‚‹ãŸã‚,
  ! è¨ˆæ¸¬ã•ã‚ŒãŸ CPU æ™‚é–“ãŒã‚·ã‚¹ãƒ†ãƒ  CPU æ™‚é–“ãªã®ã‹ãƒ¦ãƒ¼ã‚¶ CPU æ™‚é–“ãªã®ã‹,
  ! ã‚‚ã—ãã¯ä¸¡æ–¹ã®åˆè¨ˆãªã®ã‹ã©ã†ã‹ã¯å‡¦ç†ç³»ã® *cpu_time* ã«ä¾å˜ã—ã¦ã„ã¾ã™.
  ! (å¤§æŠµã¯ä¸¡æ–¹ã®åˆè¨ˆã§ã‚ã‚‹å ´åˆãŒå¤šã„ã‚ˆã†ã§ã™).
  !
  !=== å¾Œæ–¹äº’æ›
  !
  ! ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 20071009 ä»¥å‰ã«åˆ©ç”¨å¯èƒ½ã ã£ãŸä»¥ä¸‹ã®æ‰‹ç¶šãã¯,
  ! å¾Œæ–¹äº’æ›ã®ãŸã‚, ã—ã°ã‚‰ãã¯åˆ©ç”¨å¯èƒ½ã§ã™.
  !
  ! * Create, Close, Start, Stop, PutLine, Result, Set_Name
  !   Get, EvalSec, toChar, Predict
  use dc_types, only: STRING, DP
  use dc_trace, only: BeginSub, EndSub, DbgMessage
  use dc_date_types, only: DC_DIFFTIME, DC_DATETIME
  implicit none
  private
  public:: CLOCK
  public:: DCClockCreate, DCClockClose, DCClockStart, DCClockStop
  public:: DCClockPutLine, DCClockResult, DCClockSetName
  public:: operator(+), operator(-)
  public:: DCClockGet, DCClockEvalSec, DCClocktoChar, DCClockPredict
  !-----------------------------------------------
  ! å¾Œæ–¹äº’æ›ç”¨
  ! For backward compatibility
  public:: Create, Close, Start, Stop, PutLine, Result, Set_Name
  public:: Get, EvalSec, toChar, Predict
  type CLOCK
    !
    ! CPU æ™‚åˆ»è¨ˆæ¸¬ç”¨ã®æ§‹é€ ä½“ã§ã™.
    ! åˆæœŸåŒ–ã«ã¯ Create ã‚’, çµ‚äº†å‡¦ç†ã«ã¯ Close ã‚’ç”¨ã„ã¾ã™.
    !
    ! è©³ã—ã„ä½¿ã„æ–¹ã¯ dc_clock ã® Usage ã‚’å‚ç…§ãã ã•ã„.
    !
    private
    character(STRING):: name
    real(DP):: start_time           ! è¨ˆæ¸¬ã‚’é–‹å§‹ã—ãŸæ™‚é–“
                                    ! (è¨ˆæ¸¬ã®ä¸€æ™‚åœæ¢ä¸ã«ã¯è² ã®å€¤ãŒè¨å®šã•ã‚Œã‚‹)
    real(DP):: elapsed_time         ! çµŒéŽæ™‚é–“ã®ç´¯è¨ˆå€¤
    type(DC_DATETIME):: start_date  ! è¨ˆæ¸¬ã‚’é–‹å§‹ã—ãŸæ—¥æ™‚
    logical:: initialized = .false. ! CLOCK æ§‹é€ ä½“ã®åˆæœŸåŒ–ãƒã‚§ãƒƒã‚¯ç”¨ãƒ•ãƒ©ã‚°
  end type CLOCK
  interface DCClockCreate
    module procedure DCClockCreate0
  end interface
  interface DCClockClose
    module procedure DCClockClose0
  end interface
  interface DCClockStart
    module procedure DCClockStart0
  end interface
  interface DCClockStop
    module procedure DCClockStop0
  end interface
  interface DCClockPutLine
    module procedure DCClockPutLine0
  end interface
  interface DCClockGet
    module procedure DCClockGetR
    module procedure DCClockGetD
  end interface
  interface DCClockEvalSec
    module procedure DCClockEvalSecD
  end interface
  interface DCClockToChar
    module procedure DCClockToChar0
  end interface
  interface DCClockResult
    module procedure DCClockResult0
  end interface
  interface operator(+)
    module procedure DCClockAdd
  end interface
  interface operator(-)
    module procedure DCClockSubtract
  end interface
  interface DCClockSetName
    module procedure DCClockSetName0
  end interface
  interface DCClockPredict
    module procedure DCClockPredict0
  end interface
  !-----------------------------------------------
  ! å¾Œæ–¹äº’æ›ç”¨
  ! For backward compatibility
  interface Create
    module procedure DCClockCreate0
  end interface
  interface Close
    module procedure DCClockClose0
  end interface
  interface Start
    module procedure DCClockStart0
  end interface
  interface Stop
    module procedure DCClockStop0
  end interface
  interface PutLine
    module procedure DCClockPutLine0
  end interface
  interface Get
    module procedure DCClockGetR
    module procedure DCClockGetD
  end interface
  interface EvalSec
    module procedure DCClockEvalSecD
  end interface
  interface toChar
    module procedure DCClockToChar0
  end interface
  interface Result
    module procedure DCClockResult0
  end interface
  interface Set_Name
    module procedure DCClockSetName0
  end interface
  interface Predict
    module procedure DCClockPredict0
  end interface
  character(*), parameter:: version = &
    & '$Name:  $' // &
    & '$Id: dc_clock.F90,v 1.1 2009-03-20 09:09:53 morikawa Exp $'
contains
  subroutine DCClockCreate0(clk, name)
    !
    !=== CLOCK ã®åˆæœŸåŒ–ç”¨ã‚µãƒ–ãƒ«ãƒ¼ãƒãƒ³
    !
    ! CLOCK åž‹ã®å¤‰æ•°ã‚’åˆ©ç”¨ã™ã‚‹éš›ã«ã¯ã¾ãšã“ã®ã‚µãƒ–ãƒ«ãƒ¼ãƒãƒ³ã«ã‚ˆã£ã¦
    ! åˆæœŸåŒ–ã‚’è¡Œã£ã¦ãã ã•ã„. *name* ã«ã¯è¨ˆæ¸¬å†…å®¹ã‚’ä¸Žãˆã¦ãã ã•ã„.
    !
    use dc_message, only: MessageNotify
    use dc_date, only: DCDateTimeCreate
    implicit none
    type(CLOCK), intent(out):: clk
    character(*), intent(in):: name
    character(*), parameter:: subname = 'DCClockCreate'
  continue
    call BeginSub(subname, 'name=%c', c1=trim(name), version=version)
    if (clk % initialized) then
      call MessageNotify('W', subname, 'This argument (type CLOCK) is already initialized.')
      call DbgMessage('already initialized')
      goto 999
    end if
    clk % name = name
    clk % elapsed_time = 0.0
    clk % start_time = - 1.0
    clk % initialized = .true.
    call DCDateTimeCreate(clk % start_date)
    call DbgMessage('normal initialized')
999 continue
    call EndSub(subname)
  end subroutine DCClockCreate0
  subroutine DCClockClose0(clk)
    !
    !=== CLOCK ã®çµ‚äº†ã‚µãƒ–ãƒ«ãƒ¼ãƒãƒ³
    !
    ! CLOCK åž‹ã®å¤‰æ•°ã‚’ã‚¯ãƒãƒ¼ã‚ºã—ã¾ã™.
    !
    implicit none
    type(CLOCK), intent(inout):: clk
    character(*), parameter:: subname = 'DCClockClose'
  continue
    call BeginSub(subname)
    if (clk % initialized) then
      clk % initialized = .false.
      clk % name = ''
    end if
    call EndSub(subname)
  end subroutine DCClockClose0
  subroutine DCClockStart0(clk, err)
    !
    !=== è¨ˆæ¸¬ã®é–‹å§‹
    !
    ! ã“ã®ã‚µãƒ–ãƒ«ãƒ¼ãƒãƒ³ã‚’å‘¼ã‚“ã æ™‚ç‚¹ã§è¨ˆæ¸¬ã‚’é–‹å§‹ã—ã¾ã™.
    !
    ! ç¬¬ä¸€å¼•æ•° *clk* ã«å¯¾ã—ã¦ DCClockCreate ã«ã‚ˆã‚‹åˆæœŸåŒ–ãŒè¡Œã‚ã‚Œã¦ã„ãªã„å ´åˆ,
    ! ã‚¨ãƒ©ãƒ¼ã‚’ç™ºç”Ÿã•ã›ã¾ã™. *err* ã‚’ä¸Žãˆã‚‹å ´åˆã«ã¯ *err* ã« .true. ãŒè¿”ã‚Š,
    ! ãƒ—ãƒã‚°ãƒ©ãƒ ã¯ç¶šè¡Œã•ã‚Œã¾ã™.
    !
    use dc_message, only: MessageNotify
    use dc_string, only: toChar
    use dc_types, only: DP
    use dc_error, only: StoreError, DC_ENOTINIT, DC_NOERR
    use dc_date, only: EvalSec
    implicit none
    type(CLOCK), intent(inout):: clk
    logical, intent(out), optional:: err
    character(STRING):: cause_c
    integer:: stat
    character(*), parameter:: subname = 'DCClockStart'
  continue
    call BeginSub(subname)
    stat = DC_NOERR
    cause_c = 'CLOCK'
    if (.not. clk % initialized) then
      call MessageNotify('W', subname, 'Call Create before Start in dc_clock.')
      call DbgMessage('Ignored because input argument was not initialized.')
      stat = DC_ENOTINIT
      goto 999
    end if
    call cpu_time(clk % start_time) ! (out)
    call DbgMessage('name=%c, cpu_time=%f', &
      & c1=trim(clk % name), d=(/clk % start_time/) )
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname)
  end subroutine DCClockStart0
  subroutine DCClockStop0(clk, err)
    !
    !=== è¨ˆæ¸¬ã®ä¸€æ™‚åœæ¢
    !
    ! ã“ã®ã‚µãƒ–ãƒ«ãƒ¼ãƒãƒ³ã‚’å‘¼ã‚“ã æ™‚ç‚¹ã§è¨ˆæ¸¬ã‚’ä¸€æ™‚åœæ¢ã—ã¾ã™.
    !
    ! ç¬¬ä¸€å¼•æ•° *clk* ã«å¯¾ã—ã¦ DCClockCreate ã«ã‚ˆã‚‹åˆæœŸåŒ–ãŒè¡Œã‚ã‚Œã¦ã„ãªã„å ´åˆ,
    ! ã‚¨ãƒ©ãƒ¼ã‚’ç™ºç”Ÿã•ã›ã¾ã™. *err* ã‚’ä¸Žãˆã‚‹å ´åˆã«ã¯ *err* ã« .true. ãŒè¿”ã‚Š,
    ! ãƒ—ãƒã‚°ãƒ©ãƒ ã¯ç¶šè¡Œã•ã‚Œã¾ã™.
    !
    use dc_message, only: MessageNotify
    use dc_string, only: toChar
    use dc_error, only: StoreError, DC_ENOTINIT, DC_NOERR
    use dc_date, only: EvalSec, operator(+), operator(-)
    use dc_date_types, only: DC_DIFFTIME
    use dc_types, only: DP
    implicit none
    type(CLOCK), intent(inout):: clk
    logical, intent(out), optional:: err
    character(STRING):: cause_c
    real:: stop_time
    integer:: stat
    character(*), parameter:: subname = 'DCClockStop'
  continue
    call BeginSub(subname)
    stat = DC_NOERR
    cause_c = 'CLOCK'
    if (.not. clk % initialized) then
      call MessageNotify('W', subname, 'Call Create before Stop in dc_clock.')
      call DbgMessage('Ignored because input argument was not initialized.')
      stat = DC_ENOTINIT
      goto 999
    elseif (clk % start_time < 0.0_DP) then
      call MessageNotify('W', subname, 'Call Start before Stop in dc_clock.')
      call DbgMessage('Ignored because input argument was not started.')
      goto 999
    end if
    call cpu_time(stop_time)
    clk % elapsed_time = clk % elapsed_time + stop_time - clk % start_time
    clk % start_time = - 1.0
    call DbgMessage('name=%c, cpu_time=%r, elapsed_time=%f', &
      & c1=trim(clk % name), r=(/stop_time/), d=(/clk % elapsed_time/))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname)
  end subroutine DCClockStop0
  subroutine DCClockGetR(clk, sec, err) !:doc-priority 40:
    !
    !=== CPU æ™‚é–“ (å˜ä½: ç§’) ã®å–å¾—
    !
    ! CPU æ™‚é–“ (å˜ä½: ç§’) ã‚’ *sec* ã«å–å¾—ã—ã¾ã™.
    !
    ! ç¬¬ä¸€å¼•æ•° *clk* ã«å¯¾ã—ã¦ DCClockCreate ã«ã‚ˆã‚‹åˆæœŸåŒ–ãŒè¡Œã‚ã‚Œã¦ã„ãªã„å ´åˆ,
    ! ã‚¨ãƒ©ãƒ¼ã‚’ç™ºç”Ÿã•ã›ã¾ã™. *err* ã‚’ä¸Žãˆã‚‹å ´åˆã«ã¯ *err* ã« .true. ãŒè¿”ã‚Š,
    ! ãƒ—ãƒã‚°ãƒ©ãƒ ã¯ç¶šè¡Œã•ã‚Œã¾ã™.
    !
    use dc_types, only: DP
    use dc_message, only: MessageNotify
    use dc_date, only: EvalSec
    use dc_string, only: CPrintf
    use dc_error, only: StoreError, DC_ENOTINIT, DC_NOERR
    implicit none
    type(CLOCK), intent(in):: clk
    real, intent(out):: sec
    logical, intent(out), optional:: err
    character(STRING):: cause_c
    integer:: stat
    character(*), parameter:: subname = 'DCClockGetR'
  continue
    call BeginSub(subname)
    stat = DC_NOERR
    cause_c = 'CLOCK'
    if (.not. clk % initialized) then
      call MessageNotify('W', subname, 'Call Create before Get in dc_clock.')
      call DbgMessage('Ignored because input argument was not initialized.')
      stat = DC_ENOTINIT
      goto 999
    end if
    sec = clk % elapsed_time
    call DbgMessage('name=%c, return sec=<%r>', &
      & c1=trim(clk % name), r=(/sec/))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname)
  end subroutine DCClockGetR
  subroutine DCClockGetD(clk, sec, err) !:doc-priority 60:
    !
    !=== CPU æ™‚é–“ (å˜ä½: ç§’) ã®å–å¾—
    !
    ! CPU æ™‚é–“ (å˜ä½: ç§’) ã‚’ *sec* ã«å–å¾—ã—ã¾ã™.
    !
    ! ç¬¬ä¸€å¼•æ•° *clk* ã«å¯¾ã—ã¦ DCClockCreate ã«ã‚ˆã‚‹åˆæœŸåŒ–ãŒè¡Œã‚ã‚Œã¦ã„ãªã„å ´åˆ,
    ! ã‚¨ãƒ©ãƒ¼ã‚’ç™ºç”Ÿã•ã›ã¾ã™.
    ! ç¬¬äºŒå¼•æ•° *err* ã‚’ä¸Žãˆã‚‹å ´åˆã«ã¯ *err* ã« .true. ãŒè¿”ã‚Š,
    ! ãƒ—ãƒã‚°ãƒ©ãƒ ã¯ç¶šè¡Œã•ã‚Œã¾ã™.
    !
    use dc_types, only: DP
    use dc_string, only: CPrintf
    use dc_message, only: MessageNotify
    use dc_date, only: EvalSec
    use dc_error, only: StoreError, DC_ENOTINIT, DC_NOERR
    implicit none
    type(CLOCK), intent(in):: clk
    real(DP), intent(out):: sec
    logical, intent(out), optional:: err
    character(STRING):: cause_c
    integer:: stat
    character(*), parameter:: subname = 'DCClockGetD'
  continue
    call BeginSub(subname)
    stat = DC_NOERR
    cause_c = 'CLOCK'
    if (.not. clk % initialized) then
      call MessageNotify('W', subname, 'Call Create before Get in dc_clock.')
      call DbgMessage('Ignored because input argument was not initialized.')
      stat = DC_ENOTINIT
      goto 999
    end if
    sec = clk % elapsed_time
    call DbgMessage('name=%c, return sec=<%f>', &
      & c1=trim(clk % name), d=(/sec/))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname)
  end subroutine DCClockGetD
  function DCClockEvalSecD(clk) result(result)
    !
    !=== CPU æ™‚é–“ (å˜ä½: ç§’) ã®å–å¾—
    !
    ! CPU æ™‚é–“ (å˜ä½: ç§’) ã‚’è¿”ã—ã¾ã™.
    !
    ! ç¬¬ä¸€å¼•æ•° *clk* ã«å¯¾ã—ã¦ DCClockCreate
    ! ã«ã‚ˆã‚‹åˆæœŸåŒ–ãŒè¡Œã‚ã‚Œã¦ã„ãªã„å ´åˆ, -1.0 ãŒè¿”ã‚Šã¾ã™.
    !
    use dc_types, only: DP
    implicit none
    type(CLOCK), intent(in):: clk
    real(DP):: result
    logical:: err
  continue
    call DCClockGetD(clk, result, err)
    if (err) result = -1.0_DP
  end function DCClockEvalSecD
  function DCClockToChar0(clk) result(result)
    !
    !=== CPU æ™‚é–“ã‚’é©å½“ã«æ•´å½¢ã—ã¦æ–‡å—åž‹å¤‰æ•°ã«å¤‰æ›
    !
    ! CPU æ™‚é–“ã«é–¢ã—ã¦é©å½“ã«æ•´å½¢ã‚’è¡Œã„, æ–‡å—åž‹å¤‰æ•°ã«å¤‰æ›ã—ã¦è¿”ã—ã¾ã™.
    !
    ! ç¬¬ä¸€å¼•æ•° *clk* ã«å¯¾ã—ã¦ DCClockCreate
    ! ã«ã‚ˆã‚‹åˆæœŸåŒ–ãŒè¡Œã‚ã‚Œã¦ã„ãªã„å ´åˆ, ç©ºæ–‡å—ãŒè¿”ã‚Šã¾ã™.
    !
    use dc_string, only: CPrintf
    use dc_date, only: EvalSec
    implicit none
    type(CLOCK), intent(in):: clk
    character(STRING):: result
    character(20):: clk_name
  continue
    clk_name = clk % name
    if (clk % initialized) then
      result = CPrintf(' %c%c  %c', c1 = clk_name, &
        & c2=trim(result_value_form(clk % elapsed_time)), &
        & c3=trim(fit_unit_value(clk % elapsed_time)))
    else
      result = ''
    end if
  end function DCClockToChar0
  subroutine DCClockPutLine0(clk, unit, indent, err)
    !
    !=== æ§‹é€ åž‹ CLOCK å¤‰æ•°ã®æƒ…å ±ã‚’è¡¨ç¤º
    !
    ! æ§‹é€ åž‹ CLOCK å¤‰æ•°ã«é–¢ã™ã‚‹æƒ…å ±ã‚’è¡¨ç¤ºã—ã¾ã™. *unit* ã«ã¯å‡ºåŠ›å…ˆã®è£…ç½®ç•ªå·ã‚’
    ! ä¸Žãˆã¦ãã ã•ã„. *unit* ã‚’ä¸Žãˆãªã„å ´åˆ, æ¨™æº–å‡ºåŠ›ã¸è¡¨ç¤ºã•ã‚Œã¾ã™.
    !
    ! ç¬¬ä¸€å¼•æ•° *clk* ã«å¯¾ã—ã¦ DCClockCreate ã«ã‚ˆã‚‹åˆæœŸåŒ–ãŒè¡Œã‚ã‚Œã¦ã„ãªã„å ´åˆ,
    ! ã‚¨ãƒ©ãƒ¼ã‚’ç™ºç”Ÿã•ã›ã¾ã™. *err* ã‚’ä¸Žãˆã‚‹å ´åˆã«ã¯ *err* ã« .true. ãŒè¿”ã‚Š,
    ! ãƒ—ãƒã‚°ãƒ©ãƒ ã¯ç¶šè¡Œã•ã‚Œã¾ã™.
    !
    use dc_types, only: STDOUT
    use dc_message, only: MessageNotify
    use dc_string, only: Printf, toChar, CPrintf
    use dc_date, only: EvalSec, EvalDay, toChar
    use dc_error, only: StoreError, DC_ENOTINIT, DC_NOERR
    use dc_types, only: DP
    implicit none
    type(CLOCK), intent(in):: clk
    integer, intent(in), optional:: unit
    character(*), intent(in), optional:: indent
                              ! è¡¨ç¤ºã•ã‚Œã‚‹ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®å—ä¸‹ã’.
                              !
                              ! Indent of displayed messages.
    logical, intent(out), optional:: err
    integer:: out_unit
    character(STRING):: cause_c
    integer:: stat
    integer:: indent_len
    character(STRING):: indent_str
    character(*), parameter:: subname = 'DCClockPutLine'
  continue
    call BeginSub(subname)
    stat = DC_NOERR
    cause_c = 'CLOCK'
    if (.not. clk % initialized) then
      call MessageNotify('W', subname, 'Call Create before PutLine in dc_clock.')
      call DbgMessage('Ignored because input argument was not initialized.')
      stat = DC_ENOTINIT
      goto 999
    end if
    if (present(unit)) then
      out_unit = unit
    else
      out_unit = STDOUT
    end if
    indent_len = 0
    indent_str = ''
    if (present(indent)) then
      if (len(indent) /= 0) then
        indent_len = len(indent)
        indent_str(1:indent_len) = indent
      end if
    end if
    call Printf(out_unit, &
      & indent_str(1:indent_len) // &
      & '#<CLOCK:: @name=%c @clocking=%y @elapsed_time=%f sec. %c @start_date=%c>', &
      & c1=trim(clk % name), l=(/clk % start_time > 0.0_DP/), &
      & d=(/clk % elapsed_time/), &
      & c2=trim(fit_unit_value(clk % elapsed_time)), &
      & c3=trim(toChar(clk % start_date)))
    call DbgMessage('name=%c, output to device number %d', &
      & c1=trim(clk % name), i=(/out_unit/))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname)
  end subroutine DCClockPutLine0
  subroutine DCClockResult0(clks, unit, total_auto, clk_total, total_name, err)
    !
    !=== CPU æ™‚é–“ã®ç·è¨ˆã‚’è¡¨ç¤º
    !
    ! CPU æ™‚é–“ã®ç·è¨ˆã‚’è¡¨ç¤ºã—ã¾ã™. *clks* ã¸, CLOCK å¤‰æ•°ã®é…åˆ—ã‚’
    ! ä¸Žãˆã¦ãã ã•ã„. ãƒ—ãƒã‚°ãƒ©ãƒ ã®æœ€å¾Œã§å‘¼ã³å‡ºã•ã‚Œã‚‹ã“ã¨ã‚’
    ! æƒ³å®šã—ã¦ã„ã¾ã™. *unit* ã«ã¯å‡ºåŠ›å…ˆã®è£…ç½®ç•ªå·ã‚’
    ! ä¸Žãˆã¦ãã ã•ã„. *unit* ã‚’ä¸Žãˆãªã„å ´åˆ, æ¨™æº–å‡ºåŠ›ã¸è¡¨ç¤ºã•ã‚Œã¾ã™.
    !
    ! å¼•æ•° *total_auto* ã« .true. ã‚’ä¸Žãˆã‚‹ã¨, *clks* ã‚’å…¨ã¦è¶³ã—åˆã‚ã›ãŸ
    ! åˆè¨ˆå€¤ã‚’è‡ªå‹•çš„ã«è¡¨ç¤ºã—ã¾ã™. ä¸‹è¨˜ã®å¼•æ•° *clk_total* ãŒä¸Žãˆã‚‰ã‚Œã¦ã„ã‚‹
    ! å ´åˆã¯ *clk_total* ãŒå„ªå…ˆã•ã‚Œã¾ã™.
    !
    ! å¼•æ•° *clk_total* ã« CLOCK å¤‰æ•°ã‚’ä¸Žãˆã‚‹ã¨, ã“ã®å¤‰æ•°ã‚’åˆè¨ˆå€¤ã¨
    ! ã—ã¦è¡¨ç¤ºã—ã¾ã™.
    !
    ! å¼•æ•° *total_name* ã«æ–‡å—åž‹å¤‰æ•°ã‚’ä¸Žãˆã‚‹ã¨, ç·è¨ˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®
    ! å†’é ã«ã“ã®æ–‡å—åˆ—ã‚’å‡ºåŠ›ã—ã¾ã™.
    !
    ! ç¬¬ä¸€å¼•æ•° *clk* ã«å¯¾ã—ã¦ DCClockCreate ã«ã‚ˆã‚‹åˆæœŸåŒ–ãŒè¡Œã‚ã‚Œã¦ã„ãªã„å ´åˆ,
    ! ã‚¨ãƒ©ãƒ¼ã‚’ç™ºç”Ÿã•ã›ã¾ã™. *err* ã‚’ä¸Žãˆã‚‹å ´åˆã«ã¯ *err* ã« .true. ãŒè¿”ã‚Š,
    ! ãƒ—ãƒã‚°ãƒ©ãƒ ã¯ç¶šè¡Œã•ã‚Œã¾ã™.
    !
    use dc_types, only: STDOUT, STRING, DP
    use dc_message, only: MessageNotify
    use dc_string, only: Printf, toChar, CPrintf
    use dc_date, only: EvalSec
    use dc_error, only: StoreError, DC_ENOTINIT, DC_NOERR
    implicit none
    type(CLOCK), intent(in):: clks(:)
    integer, intent(in), optional:: unit
    logical, intent(in), optional:: total_auto
    type(CLOCK), intent(in), optional:: clk_total
    logical, intent(out), optional:: err
    character(*), intent(in), optional:: total_name
    integer:: out_unit, i, clks_size, ra
    character(20):: clk_name
    character(STRING):: cause_c
    character(STRING):: total_name_work
    type(CLOCK):: clk_auto_total
    logical:: total_print_complete
    real(DP):: elapsed_time_val_cor
    integer:: stat
    character(*), parameter:: total_time_mes = '       TOTAL TIME = '
    integer:: myrank_mpi, nprocs_mpi
    character(*), parameter:: subname = 'DCClockResult'
  continue
    call BeginSub(subname)
    stat = DC_NOERR
    cause_c = 'CLOCK'
    clks_size = size(clks)
    do i = 1, clks_size
      if (.not. clks(i) % initialized) then
        call MessageNotify('W', subname, 'Call Create before Result in dc_clock.')
        call DbgMessage('Ignored because input argument was not initialized.')
        stat = DC_ENOTINIT
        goto 999
      end if
    end do
    if (present(unit)) then
      out_unit = unit
    else
      out_unit = STDOUT
    end if
    if (present(total_name)) then
      total_name_work = ' (' // trim(total_name) // ')'
    else
      total_name_work = ''
    end if
    myrank_mpi = -1
    nprocs_mpi = 1
    do ra = 0, nprocs_mpi - 1
      call Printf(out_unit, '')
      if ( myrank_mpi < 0 ) then
        call Printf(out_unit, &
          & ' ############## CPU TIME SUMMARY%c################', &
          & c1=trim(total_name_work) // ' ')
      else
        call Printf(out_unit, &
          & ' ####### CPU TIME SUMMARY%c#### [rank=%06d] ####', &
          & c1=trim(total_name_work) // ' ', &
          & i = (/myrank_mpi/) )
      end if
      do i = 1, clks_size
        clk_name = clks(i) % name
        elapsed_time_val_cor = clks(i) % elapsed_time
        if (elapsed_time_val_cor < 0.0_DP) elapsed_time_val_cor = 0.0_DP
        call Printf(out_unit, &
          & ' %c%c  %c', c1=clk_name, &
          & c2=trim(result_value_form(elapsed_time_val_cor)), &
          & c3=trim(fit_unit_value(clks(i) % elapsed_time)))
      end do
      total_print_complete = .false.
      if (present(clk_total)) then
        if (clk_total % initialized) then
          call Printf(out_unit, &
            & ' ------------------------------------------------')
          elapsed_time_val_cor = clk_total % elapsed_time
          if (elapsed_time_val_cor < 0.0_DP) elapsed_time_val_cor = 0.0_DP
          call Printf(out_unit, &
            & ' %c%c  %c', c1=total_time_mes, &
            & c2=trim(result_value_form(elapsed_time_val_cor)), &
            & c3=trim(fit_unit_value(clk_total % elapsed_time)))
          total_print_complete = .true.
        end if
      end if
      if (present(total_auto) .and. .not. total_print_complete) then
        if (total_auto) then
          clk_auto_total = clks(1)
          if (clks_size > 1) then
            do i = 2, clks_size
              clk_auto_total = clk_auto_total + clks(i)
            end do
          end if
          call Printf(out_unit, &
            & ' ------------------------------------------------')
          elapsed_time_val_cor = clk_auto_total % elapsed_time
          if (elapsed_time_val_cor < 0.0_DP) elapsed_time_val_cor = 0.0_DP
          call Printf(out_unit, &
            & ' %c%c  %c', c1=total_time_mes, &
            & c2=trim(result_value_form(elapsed_time_val_cor)), &
            & c3=trim(fit_unit_value(clk_auto_total % elapsed_time)))
        end if
      end if
      call DbgMessage('total results, output to device number %d', &
        & i=(/out_unit/))
    end do
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname)
  end subroutine DCClockResult0
  function result_value_form(value) result(result)
    !
    ! å¼•æ•° value ã¨ã—ã¦ä¸Žãˆã‚‰ã‚ŒãŸå€ç²¾åº¦å®Ÿæ•°åž‹ã®ãƒ‡ãƒ¼ã‚¿ã‚’,
    ! ä»¥ä¸‹ã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã«æ•´å½¢ã—ã¦æ–‡å—åž‹ã¨ã—ã¦è¿”ã—ã¾ã™.
    !
    !     0.183400E+02
    !
    use dc_types, only: DP, TOKEN
    implicit none
    character(TOKEN):: result
    real(DP), intent(in):: value
  continue
    write(result, "(e15.6)") value
  end function result_value_form
  function fit_unit_value(sec, diff) result(result)
    !
    ! å¼•æ•° sec ã«ä¸Žãˆã‚‰ã‚ŒãŸæ•°å€¤ã‚’ç§’ã¨æ‰±ã„,
    ! ä»¥ä¸‹ã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã«æ•´å½¢ã—ã¦æ–‡å—åž‹ã¨ã—ã¦è¿”ã—ã¾ã™.
    !
    !     (23.18 days)
    !
    ! å˜ä½ã¯ days, hrs., minutes ã‹ã‚‰é©å½“ã«
    ! é¸ã°ã‚Œã¾ã™. (å€¤ãŒ 1 ä»¥ä¸Šã®å€¤ã¨ãªã‚‹ã‚ˆã†ã«é¸ã°ã‚Œã¾ã™).
    ! 1 åˆ†ä»¥å†…ã®å ´åˆã¯ç©ºæ–‡å—ã‚’è¿”ã—ã¾ã™.
    !
    use dc_types, only: DP, TOKEN
    use dc_date_types, only: DC_DIFFTIME
    use dc_date, only: DCDiffTimeCreate, EvalDay, EvalHour, EvalMin, EvalSec
    use dc_types, only: DP
    implicit none
    character(TOKEN):: result
    real(DP), intent(in):: sec
    type(DC_DIFFTIME), intent(in), optional:: diff
    type(DC_DIFFTIME):: diffw
    character(TOKEN):: unit
    real(DP):: value
    character(TOKEN):: cval
  continue
    if ( present(diff) ) then
      diffw = diff
    else
      call DCDiffTimeCreate( diffw, sec = sec )
    end if
    if (EvalDay(diffw) > 1.0_DP) then
      unit = ' days'
      value = EvalDay(diffw)
    elseif (EvalHour(diffw) > 1.0_DP) then
      unit = ' hrs.'
      value = EvalHour(diffw)
    elseif (EvalMin(diffw) > 1.0_DP) then
      unit = ' minutes'
      value = EvalMin(diffw)
    else
      result = ''
      return
    end if
    cval = printf_g5_2(value)
    result = '(' // trim(adjustl(cval)) // trim(unit) // ')'
  end function fit_unit_value
  function printf_g5_2(value) result(result)
    !
    ! å¼•æ•° value ã«ä¸Žãˆã‚‰ã‚ŒãŸæ•°å€¤ãƒ‡ãƒ¼ã‚¿ã‚’
    ! ä»¥ä¸‹ã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã«æ•´å½¢ã—ã¦æ–‡å—åž‹ã¨ã—ã¦è¿”ã—ã¾ã™.
    !
    !     23.18
    !      0.23
    !
    use dc_types, only: DP, TOKEN, STRING
    use dc_string, only: CPrintf
    implicit none
    character(TOKEN):: result
    real(DP), intent(in):: value
    character(TOKEN):: int_part, dem_part
    integer:: dem_int
  continue
    write(int_part, "(i20)") int(value)
    dem_int = nint((value - int(value)) * 100)
    if (dem_int < 0) dem_int = - dem_int
    if (dem_int == 100) then
      dem_int = 0
      write(int_part, "(i20)") int(value) + 1
    end if
    dem_part = CPrintf('%02d', i=(/dem_int/))
    result = trim(adjustl(int_part)) // '.' // trim(dem_part)
  end function printf_g5_2
  function DCClockAdd(clk1, clk2) result(clk_total)
    !
    !=== CLOCK å¤‰æ•°ã‚’è¶³ã—åˆã‚ã›ã‚‹
    !
    ! CLOCK å¤‰æ•° <b>clk1</b> ã¨ <b>clk2</b> ã‚’è¶³ã—åˆã‚ã›ã¾ã™.
    ! ä¸Žãˆã‚‰ã‚ŒãŸ 2 ã¤ã® CLOCK  å¤‰æ•°ã® CPU æ™‚é–“ã‚’åˆè¨ˆã—,
    ! CLOCK å¤‰æ•°ã¨ã—ã¦è¿”ã—ã¾ã™. è¨ˆæ¸¬å†…å®¹ã®åç§°ã¯ <b>clk1</b> ã¨ <b>clk2</b>
    ! ã®åç§°ã‚’ '+' ã§çµ„ã¿åˆã‚ã›ãŸã‚‚ã®ã¨ãªã‚Šã¾ã™.
    !
    use dc_string, only: CPrintf
    use dc_date, only: operator(+), operator(<)
    implicit none
    type(CLOCK), intent(in):: clk1
    type(CLOCK), intent(in):: clk2
    type(CLOCK):: clk_total
  continue
    if (.not. clk1 % initialized .or. .not. clk2 % initialized) then
      clk_total % initialized = .false.
      return
    end if
    clk_total % name = CPrintf('%c+%c', &
      & c1=trim(clk1 % name), c2=trim(clk2 % name))
    clk_total % start_time = - 1.0
    clk_total % initialized = .true.
    clk_total % elapsed_time = 0.0
    if (clk1 % start_date < clk2 % start_date) then
      clk_total % start_date = clk1 % start_date
    else
      clk_total % start_date = clk2 % start_date
    end if
    clk_total % elapsed_time = &
      & clk1 % elapsed_time + clk2 % elapsed_time
  end function DCClockAdd
  function DCClockSubtract(clk1, clk2) result(clk_total)
    !
    !=== CLOCK å¤‰æ•°ã‚’è¶³ã—åˆã‚ã›ã‚‹
    !
    ! CLOCK å¤‰æ•° <b>clk1</b> ã‹ã‚‰ <b>clk2</b> ã‚’å¼•ãã¾ã™.
    ! 1 ã¤ç›®ã® CLOCK å¤‰æ•°ã® CPU æ™‚é–“ã¨
    ! 2 ã¤ç›®ã® CLOCK å¤‰æ•°ã® CPU æ™‚é–“ã¨ã®å·®ã‚’
    ! CLOCK å¤‰æ•°ã¨ã—ã¦è¿”ã—ã¾ã™. è¨ˆæ¸¬å†…å®¹ã®åç§°ã¯ <b>clk1</b> ã¨ <b>clk2</b>
    ! ã®åç§°ã‚’ '-' ã§çµ„ã¿åˆã‚ã›ãŸã‚‚ã®ã¨ãªã‚Šã¾ã™.
    !
    use dc_string, only: CPrintf
    use dc_date, only: operator(-), operator(<)
    implicit none
    type(CLOCK), intent(in):: clk1
    type(CLOCK), intent(in):: clk2
    type(CLOCK):: clk_total
  continue
    if (.not. clk1 % initialized .or. .not. clk2 % initialized) then
      clk_total % initialized = .false.
      return
    end if
    clk_total % name = CPrintf('%c-%c', &
      & c1=trim(clk1 % name), c2=trim(clk2 % name))
    clk_total % start_time = - 1.0
    clk_total % initialized = .true.
    clk_total % elapsed_time = 0.0
    if (clk1 % start_date < clk2 % start_date) then
      clk_total % start_date = clk1 % start_date
    else
      clk_total % start_date = clk2 % start_date
    end if
    clk_total % elapsed_time = &
      & clk1 % elapsed_time - clk2 % elapsed_time
  end function DCClockSubtract
  subroutine DCClockSetName0(clk, name, err)
    !
    !=== æ¸¬å®šå†…å®¹ã®åç§°ã‚’å¤‰æ›´ã™ã‚‹.
    !
    ! CLOCK å¤‰æ•° *clk* ã®è¨ˆæ¸¬å†…å®¹ã®åç§°ã‚’å¤‰æ›´ã—ã¾ã™.
    ! ã“ã®åç§°ã¯ Create ã® *name* å¼•æ•°ã§æŒ‡å®šã•ã‚ŒãŸã‚‚ã®ã§ã™.
    !
    ! ç¬¬ä¸€å¼•æ•° *clk* ã«å¯¾ã—ã¦ DCClockCreate ã«ã‚ˆã‚‹åˆæœŸåŒ–ãŒè¡Œã‚ã‚Œã¦ã„ãªã„å ´åˆ,
    ! ã‚¨ãƒ©ãƒ¼ã‚’ç™ºç”Ÿã•ã›ã¾ã™. *err* ã‚’ä¸Žãˆã‚‹å ´åˆã«ã¯ *err* ã« .true. ãŒè¿”ã‚Š,
    ! ãƒ—ãƒã‚°ãƒ©ãƒ ã¯ç¶šè¡Œã•ã‚Œã¾ã™.
    !
    use dc_message, only: MessageNotify
    use dc_string, only: toChar, CPrintf
    use dc_error, only: StoreError, DC_ENOTINIT, DC_NOERR
    implicit none
    type(CLOCK), intent(inout):: clk
    character(*), intent(in):: name
    logical, intent(out), optional:: err
    character(STRING):: cause_c
    integer:: stat
    character(*), parameter:: subname = 'DCClockSetName'
  continue
    call BeginSub(subname)
    stat = DC_NOERR
    cause_c = 'CLOCK'
    if (.not. clk % initialized) then
      call MessageNotify('W', subname, 'Call Create before Set_Name in dc_clock.')
      call DbgMessage('Ignored because input argument was not initialized.')
      stat = DC_ENOTINIT
      goto 999
    end if
    clk % name = name
    call DbgMessage('set new name "%c"', c1=trim(clk % name))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname)
  end subroutine DCClockSetName0
  subroutine DCClockPredict0(clk, progress, unit, err)
    !
    !=== ãƒ—ãƒã‚°ãƒ©ãƒ ãŒçµ‚äº†ã™ã‚‹ã¾ã§ã®äºˆæ¸¬ CPU æ™‚é–“, ãŠã‚ˆã³æ—¥æ™‚ã‚’è¡¨ç¤º
    !
    ! CLOCK å¤‰æ•° *clk* ã¨ *progress* ã‹ã‚‰, ãƒ—ãƒã‚°ãƒ©ãƒ ãŒ
    ! çµ‚äº†ã™ã‚‹ã¾ã§ã®äºˆæ¸¬ CPU æ™‚é–“, ãŠã‚ˆã³æ—¥æ™‚ã‚’ä»¥ä¸‹ã®ã‚ˆã†ã«è¡¨ç¤ºã—ã¾ã™.
    !
    !     ########## PREDICTION OF CALCULATION ###########
    !     Start Date             2007-03-08T16:49:25+09:00
    !     Current Date           2007-03-08T16:49:27+09:00
    !     Progress     66.67%  [****************         ]
    !     Remaining CPU TIME      0.100000E+01
    !     Completion Date        2007-03-08T16:49:28+09:00
    !
    ! ç¬¬2å¼•æ•°ã§ã‚ã‚‹ *progress* ã«ã¯ 0 ã€œ 1 ã¾ã§ã®å€¤ã‚’ä¸Žãˆã¦ãã ã•ã„.
    ! ãƒ—ãƒã‚°ãƒ©ãƒ ã®é–‹å§‹æ™‚ã‚’ 0, çµ‚äº†æ™‚ã‚’ 1 ã¨ã—ã¾ã™. (ä¾‹ãˆã°,
    ! ãƒ—ãƒã‚°ãƒ©ãƒ ãŒåŠåˆ†é€²ã‚“ã æ™‚ã«ã¯ 0.5 ã‚’ä¸Žãˆã¾ã™).
    !
    ! ã“ã“ã§è¡Œã†ã€Œäºˆæ¸¬ã€ã¨ã¯, ã“ã‚Œã¾ã§ã®çµŒéŽæ™‚é–“ãŠã‚ˆã³
    ! çµ‚äº†ã—ãŸãƒ—ãƒã‚°ãƒ©ãƒ ã®åˆ†é‡ã‹ã‚‰å˜ç´”ãªã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã§å‰²ã‚Šå‡ºã—ã¦ã„ã‚‹
    ! ã‚‚ã®ãªã®ã§, æ£ç¢ºãªäºˆæ¸¬å€¤ã‚’è¿”ã™ã‚ã‘ã§ã¯ã‚ã‚Šã¾ã›ã‚“.
    ! ã‚ãã¾ã§ç›®å®‰ã¨ã—ã¦åˆ©ç”¨ã—ã¦ãã ã•ã„.
    !
    ! å¼•æ•° *unit* ã«ã¯å‡ºåŠ›å…ˆã®è£…ç½®ç•ªå·ã‚’
    ! ä¸Žãˆã¦ãã ã•ã„. *unit* ã‚’ä¸Žãˆãªã„å ´åˆ, æ¨™æº–å‡ºåŠ›ã¸è¡¨ç¤ºã•ã‚Œã¾ã™.
    !
    ! ç¬¬ä¸€å¼•æ•° *clk* ã«å¯¾ã—ã¦ DCClockCreate ã«ã‚ˆã‚‹åˆæœŸåŒ–ãŒè¡Œã‚ã‚Œã¦ã„ãªã„å ´åˆ,
    ! ã‚¨ãƒ©ãƒ¼ã‚’ç™ºç”Ÿã•ã›ã¾ã™. *err* ã‚’ä¸Žãˆã‚‹å ´åˆã«ã¯ *err* ã« .true. ãŒè¿”ã‚Š,
    ! ãƒ—ãƒã‚°ãƒ©ãƒ ã¯ç¶šè¡Œã•ã‚Œã¾ã™.
    !
    use dc_types, only: STDOUT, DP
    use dc_message, only: MessageNotify
    use dc_string, only: toChar, CPrintf, Printf
    use dc_error, only: StoreError, DC_ENOTINIT, DC_NOERR
    use dc_date_types, only: DC_DIFFTIME, DC_DATETIME
    use dc_date, only: operator(+), DCDateTimeCreate, toChar, EvalSec, &
      & DCDiffTimeCreate
    implicit none
    type(CLOCK), intent(in):: clk
    real, intent(in):: progress
    integer, intent(in), optional:: unit
    logical, intent(out), optional:: err
    character(STRING):: cause_c
    integer:: stat, out_unit
    type(DC_DIFFTIME):: remain_diff
    type(DC_DATETIME):: comp_date, cur_date
    character(7):: prog_percent
    character(25):: prog_bar
    integer:: prog_bar_ptr
    real:: prog_valid
    character(*), parameter:: subname = 'DCClockPredict'
  continue
    call BeginSub(subname)
    stat = DC_NOERR
    cause_c = 'CLOCK'
    if (.not. clk % initialized) then
      call MessageNotify('W', subname, 'Call Create before Predict in dc_clock.')
      call DbgMessage('Ignored because input argument was not initialized.')
      stat = DC_ENOTINIT
      goto 999
    end if
    if (progress <= 0.0) then
      call MessageNotify('W', subname, 'Specify 0.0 -- 1.0 value to "progress"')
      return
    elseif (progress > 1.0) then
      call MessageNotify('W', subname, 'Over 1.0 value to "progress" was modified to 1.0')
      prog_valid = 1.0
    else
      prog_valid = progress
    end if
    if (present(unit)) then
      out_unit = unit
    else
      out_unit = STDOUT
    end if
    call DCDiffTimeCreate( remain_diff, &
      & sec = real(nint(EvalSec(clk) / prog_valid * (1.0 - prog_valid)), DP) )
    call DCDateTimeCreate(cur_date)
    comp_date = cur_date + remain_diff
    prog_percent = ''
    prog_percent = adjustr(trim(printf_g5_2(real(prog_valid * 100, DP))) // '%')
    prog_bar = ''
    prog_bar_ptr = int(prog_valid * 25)
    if (prog_bar_ptr > 0) prog_bar(1:prog_bar_ptr) = '*************************'
    call Printf(out_unit, '')
    call Printf(out_unit, &
      & ' ########## PREDICTION OF CALCULATION ###########')
    call Printf(out_unit, &
      & ' Start Date             %c', c1=trim(toChar(clk % start_date)))
    call Printf(out_unit, &
      & ' Current Date           %c', c1=trim(toChar(cur_date)))
    call Printf(out_unit, &
      & ' Progress     %c [%c]', c1=prog_percent, c2=prog_bar)
    call Printf(out_unit, &
      & ' Remaining CPU TIME   %c %c', &
      & c1=trim(result_value_form(EvalSec(remain_diff))), &
      & c2=trim(fit_unit_value(0.0_DP, remain_diff)))
    call Printf(out_unit, &
      & ' Completion Date        %c', c1=trim(toChar(comp_date)))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname)
  end subroutine DCClockPredict0
end module dc_clock