Class dc_clock
In: dc_clock.f90

Overview

プログラムの処理に要した CPU 時間を計測して表示します.

List

Create :構造型 CLOCK 変数の初期化
Start :計測の開始
Stop :計測の一時停止
Close :構造型 CLOCK 変数の終了処理
Get, EvalSec :CPU 時間 (単位: 秒) の取得
toChar :CPU 時間を適当に整形して文字型変数に変換
PutLine :構造型 CLOCK 変数の情報を表示
Result :CPU 時間に関する総合的な情報を表示
Predict :プログラムが終了するまでの予測 CPU 時間, および 日時を表示
operator(+) :加算 (dc_clock#CLOCK 型同士)

Usage

始めに, 構造型 CLOCK の変数を定義し, Create で初期化します. プログラム中の計測開始地点で Start を呼び出し, 計測を一時停止する地点で Stop を呼び出します. Result によって経過時間を表示します. Predict を使用することでプログラムが終了するまでの残り CPU 時間 の予測値を表示することが可能です.

    program dc_clock_sapmle1
      use dc_clock, only: CLOCK, Create, Close, Start, Stop, Result, &
        & Predict, operator(+)
      implicit none
      type(CLOCK):: clock1, clock2
      integer:: i, j
      integer, parameter:: loop_num = 8
      real:: a, b

      call Create( clk = clock1, name = 'exponential' )
      call Create( clk = clock2, name = 'four-operations' )
      a = 2.0
      b = 1.0
      do i = 1, loop_num
        call Start( clk = clock1 )
        do j = 1, 1000000
          a = (a**2)**0.3 + 1.0
        enddo
        call Stop( clk = clock1 )
        call Start( clk = clock2 )
        do j = 1, 1000000
          b = b / 3.0 * 2.0 + 1.0 - 1.0e-1
        enddo
        call Stop( clk = clock2 )
        call Predict( clk = clock1 + clock2, progress = real(i)/real(loop_num) )
      enddo
      call Result( clks = (/clock1, clock2/), total_auto = .true. )
      call Close( clk = clock1 )
      call Close( clk = clock2 )

      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 に依存しています. (大抵は両方の合計である場合が多いようです).

Methods

Included Modules

dc_types dc_trace dc_date_types dc_message dc_date dc_string dc_error

Attributes

Derived_Types  []  CLOCK

Public Instance methods

CLOCK()
Derived Type :
name :character(STRING)
start_time :type(DC_DIFFTIME)
: 計測を開始した時間 (計測の一時停止中には負の値が設定される)
elapsed_time :type(DC_DIFFTIME)
: 経過時間の累計値
start_date :type(DC_DATETIME)
: 計測を開始した日時
dummy :logical
initialized = .false. :logical
: CLOCK 構造体の初期化チェック用フラグ

CPU 時刻計測用の構造体です. 初期化には Create を, 終了処理には Close を用います.

詳しい使い方は dc_clock の Usage を参照ください.

Close( clk )
Subroutine :
clk :type(CLOCK), intent(inout)

CLOCK の終了サブルーチン

CLOCK 型の変数をクローズします.

Alias for DCClockClose

Create( clk, name )
Subroutine :
clk :type(CLOCK), intent(out)
name :character(*), intent(in)

CLOCK の初期化用サブルーチン

CLOCK 型の変数を利用する際にはまずこのサブルーチンによって 初期化を行ってください. name には計測内容を与えてください.

Alias for DCClockCreate

EvalSec( clk ) result(result)
Function :
result :real(DP)
clk :type(CLOCK), intent(in)

CPU 時間 (単位: 秒) の取得

CPU 時間 (単位: 秒) を返します.

第一引数 clk に対して Create による初期化が行われていない場合, -1.0 が返ります.

Alias for DCClockEvalSecD

Get( clk, sec, [err] )
Subroutine :
clk :type(CLOCK), intent(in)
sec :real(DP), intent(out)
err :logical, intent(out), optional

CPU 時間 (単位: 秒) の取得

CPU 時間 (単位: 秒) を sec に取得します.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. 第二引数 err を与える場合には err に .true. が返り, プログラムは続行されます.

Alias for DCClockGetD

Get( clk, sec, [err] )
Subroutine :
clk :type(CLOCK), intent(in)
sec :real, intent(out)
err :logical, intent(out), optional

CPU 時間 (単位: 秒) の取得

CPU 時間 (単位: 秒) を sec に取得します.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

Alias for DCClockGetR

Predict( clk, progress, [unit], [err] )
Subroutine :
clk :type(CLOCK), intent(in)
progress :real, intent(in)
unit :integer, intent(in), optional
err :logical, intent(out), optional

プログラムが終了するまでの予測 CPU 時間, および日時を表示

CLOCK 変数 clkprogress から, プログラムが 終了するまでの予測 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 に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

Alias for DCClockPredict

PutLine( clk, [unit], [indent], [err] )
Subroutine :
clk :type(CLOCK), intent(in)
unit :integer, intent(in), optional
indent :character(*), intent(in), optional
: 表示されるメッセージの字下げ.

Indent of displayed messages.

err :logical, intent(out), optional

構造型 CLOCK 変数の情報を表示

構造型 CLOCK 変数に関する情報を表示します. unit には出力先の装置番号を 与えてください. unit を与えない場合, 標準出力へ表示されます.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

Alias for DCClockPutLine

Result( clks, [unit], [total_auto], [clk_total], [total_name], [err] )
Subroutine :
clks(:) :type(CLOCK), intent(in)
unit :integer, intent(in), optional
total_auto :logical, intent(in), optional
clk_total :type(CLOCK), intent(in), optional
total_name :character(*), intent(in), optional
err :logical, intent(out), optional

CPU 時間の総計を表示

CPU 時間の総計を表示します. clks へ, CLOCK 変数の配列を 与えてください. プログラムの最後で呼び出されることを 想定しています. unit には出力先の装置番号を 与えてください. unit を与えない場合, 標準出力へ表示されます.

引数 total_auto に .true. を与えると, clks を全て足し合わせた 合計値を自動的に表示します. 下記の引数 clk_total が与えられている 場合は clk_total が優先されます.

引数 clk_totalCLOCK 変数を与えると, この変数を合計値と して表示します.

引数 total_name に文字型変数を与えると, 総計メッセージの 冒頭にこの文字列を出力します.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

Alias for DCClockResult

Set_Name( clk, name, [err] )
Subroutine :
clk :type(CLOCK), intent(inout)
name :character(*), intent(in)
err :logical, intent(out), optional

測定内容の名称を変更する.

CLOCK 変数 clk の計測内容の名称を変更します. この名称は Createname 引数で指定されたものです.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

Alias for DCClockSetName

Start( clk, [err] )
Subroutine :
clk :type(CLOCK), intent(inout)
err :logical, intent(out), optional

計測の開始

このサブルーチンを呼んだ時点で計測を開始します.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

Alias for DCClockStart

Stop( clk, [err] )
Subroutine :
clk :type(CLOCK), intent(inout)
err :logical, intent(out), optional

計測の一時停止

このサブルーチンを呼んだ時点で計測を一時停止します.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

Alias for DCClockStop

operator(+)( clk1, clk2 ) result(clk_total)
Function :
clk_total :type(CLOCK)
clk1 :type(CLOCK), intent(in)
clk2 :type(CLOCK), intent(in)

CLOCK 変数を足し合わせる

CLOCK 変数 clk1clk2 を足し合わせます. 与えられた 2 つの CLOCK 変数の CPU 時間を合計し, CLOCK 変数として返します. 計測内容の名称は clk1clk2 の名称を ’+’ で組み合わせたものとなります.

Alias for DCClockAdd

toChar( clk ) result(result)
Function :
result :character(STRING)
clk :type(CLOCK), intent(in)

CPU 時間を適当に整形して文字型変数に変換

CPU 時間に関して適当に整形を行い, 文字型変数に変換して返します.

第一引数 clk に対して Create による初期化が行われていない場合, 空文字が返ります.

Alias for DCClockToChar

Private Instance methods

Function :
clk_total :type(CLOCK)
clk1 :type(CLOCK), intent(in)
clk2 :type(CLOCK), intent(in)

CLOCK 変数を足し合わせる

CLOCK 変数 clk1clk2 を足し合わせます. 与えられた 2 つの CLOCK 変数の CPU 時間を合計し, CLOCK 変数として返します. 計測内容の名称は clk1clk2 の名称を ’+’ で組み合わせたものとなります.

[Source]

  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(<), assignment(=)
    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
Subroutine :
clk :type(CLOCK), intent(inout)

CLOCK の終了サブルーチン

CLOCK 型の変数をクローズします.

[Source]

  subroutine DCClockClose(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 DCClockClose
Subroutine :
clk :type(CLOCK), intent(out)
name :character(*), intent(in)

CLOCK の初期化用サブルーチン

CLOCK 型の変数を利用する際にはまずこのサブルーチンによって 初期化を行ってください. name には計測内容を与えてください.

[Source]

  subroutine DCClockCreate(clk, name)
    !
    !=== CLOCK の初期化用サブルーチン
    !
    ! CLOCK 型の変数を利用する際にはまずこのサブルーチンによって
    ! 初期化を行ってください. *name* には計測内容を与えてください.
    !
    use dc_message, only: MessageNotify
    use dc_date, only: assignment(=), Create
    implicit none
    type(CLOCK), intent(out):: clk
    character(*), intent(in):: name
    character(STRING):: endsub_msg
    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.')
      endsub_msg = 'already initialized'
      goto 999
    end if
    clk % name = name
    clk % elapsed_time = 0.0
    clk % start_time = - 1.0
    clk % initialized = .true.
    call Create(clk % start_date)
    endsub_msg = 'normal initialized'
999 continue
    call EndSub(subname, endsub_msg)
  end subroutine DCClockCreate
Function :
result :real(DP)
clk :type(CLOCK), intent(in)

CPU 時間 (単位: 秒) の取得

CPU 時間 (単位: 秒) を返します.

第一引数 clk に対して Create による初期化が行われていない場合, -1.0 が返ります.

[Source]

  function DCClockEvalSecD(clk) result(result)
    !
    !=== CPU 時間 (単位: 秒) の取得
    !
    ! CPU 時間 (単位: 秒) を返します.
    !
    ! 第一引数 *clk* に対して Create 
    ! による初期化が行われていない場合, -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
Subroutine :
clk :type(CLOCK), intent(in)
sec :real(DP), intent(out)
err :logical, intent(out), optional

CPU 時間 (単位: 秒) の取得

CPU 時間 (単位: 秒) を sec に取得します.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. 第二引数 err を与える場合には err に .true. が返り, プログラムは続行されます.

[Source]

  subroutine DCClockGetD(clk, sec, err) !:doc-priority 60:
    !
    !=== CPU 時間 (単位: 秒) の取得
    !
    ! CPU 時間 (単位: 秒) を *sec* に取得します.
    !
    ! 第一引数 *clk* に対して Create による初期化が行われていない場合,
    ! エラーを発生させます.
    ! 第二引数 *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):: endsub_msg, 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.')
      endsub_msg = 'Ignored because input argument was not initialized.'
      stat = DC_ENOTINIT
      goto 999
    end if
    sec = EvalSec(clk % elapsed_time)
    endsub_msg = CPrintf('name=%c, return sec=<%f>', c1=trim(clk % name), d=(/sec/))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname, endsub_msg)
  end subroutine DCClockGetD
Subroutine :
clk :type(CLOCK), intent(in)
sec :real, intent(out)
err :logical, intent(out), optional

CPU 時間 (単位: 秒) の取得

CPU 時間 (単位: 秒) を sec に取得します.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

[Source]

  subroutine DCClockGetR(clk, sec, err) !:doc-priority 40:
    !
    !=== CPU 時間 (単位: 秒) の取得
    !
    ! CPU 時間 (単位: 秒) を *sec* に取得します.
    !
    ! 第一引数 *clk* に対して Create による初期化が行われていない場合,
    ! エラーを発生させます. *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):: endsub_msg, 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.')
      endsub_msg = 'Ignored because input argument was not initialized.'
      stat = DC_ENOTINIT
      goto 999
    end if
    sec = real(EvalSec(clk % elapsed_time))
    endsub_msg = CPrintf('name=%c, return sec=<%r>', c1=trim(clk % name), r=(/sec/))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname, endsub_msg)
  end subroutine DCClockGetR
Subroutine :
clk :type(CLOCK), intent(in)
progress :real, intent(in)
unit :integer, intent(in), optional
err :logical, intent(out), optional

プログラムが終了するまでの予測 CPU 時間, および日時を表示

CLOCK 変数 clkprogress から, プログラムが 終了するまでの予測 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 に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

[Source]

  subroutine DCClockPredict(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* に対して Create による初期化が行われていない場合,
    ! エラーを発生させます. *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: assignment(=), operator(+), Create, toChar, EvalSec
    implicit none
    type(CLOCK), intent(in):: clk
    real, intent(in):: progress
    integer, intent(in), optional:: unit
    logical, intent(out), optional:: err
    character(STRING):: endsub_msg, 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.')
      endsub_msg = '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

    remain_diff = real(nint(EvalSec(clk) / prog_valid * (1.0 - prog_valid)))
    call Create(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(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, endsub_msg)
  end subroutine DCClockPredict
Subroutine :
clk :type(CLOCK), intent(in)
unit :integer, intent(in), optional
indent :character(*), intent(in), optional
: 表示されるメッセージの字下げ.

Indent of displayed messages.

err :logical, intent(out), optional

構造型 CLOCK 変数の情報を表示

構造型 CLOCK 変数に関する情報を表示します. unit には出力先の装置番号を 与えてください. unit を与えない場合, 標準出力へ表示されます.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

[Source]

  subroutine DCClockPutLine(clk, unit, indent, err)
    !
    !=== 構造型 CLOCK 変数の情報を表示
    !
    ! 構造型 CLOCK 変数に関する情報を表示します. *unit* には出力先の装置番号を
    ! 与えてください. *unit* を与えない場合, 標準出力へ表示されます.
    !
    ! 第一引数 *clk* に対して Create による初期化が行われていない場合,
    ! エラーを発生させます. *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):: endsub_msg, 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.')
      endsub_msg = '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=(/EvalSec(clk % start_time) > 0.0_DP/), d=(/EvalSec(clk % elapsed_time)/), c2=trim(fit_unit_value(clk % elapsed_time)), c3=trim(toChar(clk % start_date)))
    endsub_msg = CPrintf('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, endsub_msg)
  end subroutine DCClockPutLine
Subroutine :
clks(:) :type(CLOCK), intent(in)
unit :integer, intent(in), optional
total_auto :logical, intent(in), optional
clk_total :type(CLOCK), intent(in), optional
total_name :character(*), intent(in), optional
err :logical, intent(out), optional

CPU 時間の総計を表示

CPU 時間の総計を表示します. clks へ, CLOCK 変数の配列を 与えてください. プログラムの最後で呼び出されることを 想定しています. unit には出力先の装置番号を 与えてください. unit を与えない場合, 標準出力へ表示されます.

引数 total_auto に .true. を与えると, clks を全て足し合わせた 合計値を自動的に表示します. 下記の引数 clk_total が与えられている 場合は clk_total が優先されます.

引数 clk_totalCLOCK 変数を与えると, この変数を合計値と して表示します.

引数 total_name に文字型変数を与えると, 総計メッセージの 冒頭にこの文字列を出力します.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

[Source]

  subroutine DCClockResult(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* に対して Create による初期化が行われていない場合,
    ! エラーを発生させます. *err* を与える場合には *err* に .true. が返り,
    ! プログラムは続行されます.
    !
    use dc_types, only: STDOUT, STRING
    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
    character(20):: clk_name
    character(STRING):: endsub_msg, cause_c
    character(STRING):: total_name_work
    type(CLOCK):: clk_auto_total
    logical:: total_print_complete
    integer:: stat
    character(*), parameter:: total_time_mes = '       TOTAL TIME = '
    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.')
        endsub_msg = '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
    call Printf(out_unit, '')
    call Printf(out_unit, ' ############## CPU TIME SUMMARY%c################', c1=trim(total_name_work) // ' ')
    do i = 1, clks_size
      clk_name = clks(i) % name
      call Printf(out_unit, ' %c%c  %c', c1=clk_name, c2=trim(result_value_form(EvalSec(clks(i) % elapsed_time))), 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, ' ------------------------------------------------')
        call Printf(out_unit, ' %c%c  %c', c1=total_time_mes, c2=trim(result_value_form(EvalSec(clk_total % elapsed_time))), 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, ' ------------------------------------------------')
        call Printf(out_unit, ' %c%c  %c', c1=total_time_mes, c2=trim(result_value_form(EvalSec(clk_auto_total % elapsed_time))), c3=trim(fit_unit_value(clk_auto_total % elapsed_time)))
      end if
    end if

    endsub_msg = CPrintf('total results, output to device number %d', i=(/out_unit/))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname, endsub_msg)
  end subroutine DCClockResult
Subroutine :
clk :type(CLOCK), intent(inout)
name :character(*), intent(in)
err :logical, intent(out), optional

測定内容の名称を変更する.

CLOCK 変数 clk の計測内容の名称を変更します. この名称は Createname 引数で指定されたものです.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

[Source]

  subroutine DCClockSetName(clk, name, err)
    !
    !=== 測定内容の名称を変更する.
    !
    ! CLOCK 変数 *clk* の計測内容の名称を変更します.
    ! この名称は Create の *name* 引数で指定されたものです.
    !
    ! 第一引数 *clk* に対して Create による初期化が行われていない場合,
    ! エラーを発生させます. *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):: endsub_msg, cause_c
    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 Set_Name in dc_clock.')
      endsub_msg = 'Ignored because input argument was not initialized.'
      stat = DC_ENOTINIT
      goto 999
    end if
    clk % name = name
    endsub_msg = CPrintf('set new name "%c"', c1=trim(clk % name))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname, endsub_msg)
  end subroutine DCClockSetName
Subroutine :
clk :type(CLOCK), intent(inout)
err :logical, intent(out), optional

計測の開始

このサブルーチンを呼んだ時点で計測を開始します.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

[Source]

  subroutine DCClockStart(clk, err)
    !
    !=== 計測の開始
    !
    ! このサブルーチンを呼んだ時点で計測を開始します.
    !
    ! 第一引数 *clk* に対して Create による初期化が行われていない場合,
    ! エラーを発生させます. *err* を与える場合には *err* に .true. が返り,
    ! プログラムは続行されます.
    !
    use dc_message, only: MessageNotify
    use dc_string, only: toChar, CPrintf
    use dc_types, only: DP
    use dc_error, only: StoreError, DC_ENOTINIT, DC_NOERR
    use dc_date, only: assignment(=), EvalSec
    implicit none
    type(CLOCK), intent(inout):: clk
    logical, intent(out), optional:: err
    character(STRING):: endsub_msg, cause_c
    real(DP):: start_time
    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.')
      endsub_msg = 'Ignored because input argument was not initialized.'
      stat = DC_ENOTINIT
      goto 999
    end if
    call cpu_time(start_time)
    clk % start_time = start_time
    endsub_msg = CPrintf('name=%c, cpu_time=%f', c1=trim(clk % name), d=(/EvalSec(clk % start_time)/))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname, endsub_msg)
  end subroutine DCClockStart
Subroutine :
clk :type(CLOCK), intent(inout)
err :logical, intent(out), optional

計測の一時停止

このサブルーチンを呼んだ時点で計測を一時停止します.

第一引数 clk に対して Create による初期化が行われていない場合, エラーを発生させます. err を与える場合には err に .true. が返り, プログラムは続行されます.

[Source]

  subroutine DCClockStop(clk, err)
    !
    !=== 計測の一時停止
    !
    ! このサブルーチンを呼んだ時点で計測を一時停止します.
    !
    ! 第一引数 *clk* に対して Create による初期化が行われていない場合,
    ! エラーを発生させます. *err* を与える場合には *err* に .true. が返り,
    ! プログラムは続行されます.
    !
    use dc_message, only: MessageNotify
    use dc_string, only: toChar, CPrintf
    use dc_error, only: StoreError, DC_ENOTINIT, DC_NOERR
    use dc_date, only: EvalSec, assignment(=), 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):: endsub_msg, cause_c
    type(DC_DIFFTIME):: stop_timediff
    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.')
      endsub_msg = 'Ignored because input argument was not initialized.'
      stat = DC_ENOTINIT
      goto 999
    elseif (EvalSec(clk % start_time) < 0.0_DP) then
      call MessageNotify('W', subname, 'Call Start before Stop in dc_clock.')
      endsub_msg = 'Ignored because input argument was not started.'
      goto 999
    end if
    call cpu_time(stop_time)
    stop_timediff = stop_time
    clk % elapsed_time = clk % elapsed_time + stop_timediff - clk % start_time
    clk % start_time = - 1.0
    endsub_msg = CPrintf('name=%c, cpu_time=%r, elapsed_time=%f', c1=trim(clk % name), r=(/stop_time/), d=(/EvalSec(clk % elapsed_time)/))
999 continue
    call StoreError(stat, subname, err, cause_c)
    call EndSub(subname, endsub_msg)
  end subroutine DCClockStop
Function :
result :character(STRING)
clk :type(CLOCK), intent(in)

CPU 時間を適当に整形して文字型変数に変換

CPU 時間に関して適当に整形を行い, 文字型変数に変換して返します.

第一引数 clk に対して Create による初期化が行われていない場合, 空文字が返ります.

[Source]

  function DCClockToChar(clk) result(result)
    !
    !=== CPU 時間を適当に整形して文字型変数に変換
    !
    ! CPU 時間に関して適当に整形を行い, 文字型変数に変換して返します.
    !
    ! 第一引数 *clk* に対して Create
    ! による初期化が行われていない場合, 空文字が返ります.
    !
    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(EvalSec(clk % elapsed_time))), c3=trim(fit_unit_value(clk % elapsed_time)))
    else
      result = ''
    end if
  end function DCClockToChar
Function :
result :character(TOKEN)
diff :type(DC_DIFFTIME), intent(in)

引数 diff に与えられた DC_DIFFTIME 型変数に格納される日時データを 以下のフォーマットに整形して文字型として返します.

    (23.18 days)

単位は days, hrs., minutes から適当に 選ばれます. (値が 1 以上の値となるように選ばれます). 1 分以内の場合は空文字を返します.

[Source]

  function fit_unit_value(diff) result(result)
    !
    ! 引数 diff に与えられた DC_DIFFTIME 型変数に格納される日時データを
    ! 以下のフォーマットに整形して文字型として返します.
    !
    !     (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: EvalDay, EvalHour, EvalMin, EvalSec
    use dc_types, only: DP
    implicit none
    character(TOKEN):: result
    type(DC_DIFFTIME), intent(in):: diff
    character(TOKEN):: unit
    real(DP):: value
    character(TOKEN):: cval
  continue
    if (EvalDay(diff) > 1.0_DP) then
      unit = ' days'
      value = EvalDay(diff)
    elseif (EvalHour(diff) > 1.0_DP) then
      unit = ' hrs.'
      value = EvalHour(diff)
    elseif (EvalMin(diff) > 1.0_DP) then
      unit = ' minutes'
      value = EvalMin(diff)
    else
      result = ''
      return
    end if
    cval = printf_g5_2(value)
    result = '(' // trim(adjustl(cval)) // trim(unit) // ')'
  end function fit_unit_value
Function :
result :character(TOKEN)
value :real(DP), intent(in)

引数 value に与えられた数値データを 以下のフォーマットに整形して文字型として返します.

    23.18
     0.23

[Source]

  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 :
result :character(TOKEN)
value :real(DP), intent(in)

引数 value として与えられた倍精度実数型のデータを, 以下のフォーマットに整形して文字型として返します.

    0.183400E+02

[Source]

  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
version()
Constant :
version = ’$Name: gt4f90io-20070710 $’ // ’$Id: dc_clock.f90,v 1.15 2007/06/16 06:20:25 morikawa Exp $’ :character(*), parameter

[Validate]