output_system_log Module Subroutine

module subroutine output_system_log(self, time, Matrix, domain)

Arguments

Type IntentOptional Attributes Name
class(type_output), intent(inout) :: self
type(type_time), intent(in) :: time
type(type_crs), intent(in) :: Matrix
type(type_domain), intent(inout) :: domain

Calls

proc~~output_system_log~~CallsGraph proc~output_system_log output_system_log proc~get_compiler_name get_compiler_name proc~output_system_log->proc~get_compiler_name proc~get_compiler_version get_compiler_version proc~output_system_log->proc~get_compiler_version proc~get_cpu_architecture get_cpu_architecture proc~output_system_log->proc~get_cpu_architecture proc~get_hostname get_hostname proc~output_system_log->proc~get_hostname proc~get_memory_usage get_memory_usage proc~output_system_log->proc~get_memory_usage proc~get_os get_os proc~output_system_log->proc~get_os proc~get_username get_username proc~output_system_log->proc~get_username interface~c_get_cpu_architecture c_get_cpu_architecture proc~get_cpu_architecture->interface~c_get_cpu_architecture proc~c_ptr_to_string c_ptr_to_string proc~get_cpu_architecture->proc~c_ptr_to_string interface~c_get_rss_kb c_get_rss_kb proc~get_memory_usage->interface~c_get_rss_kb interface~c_get_os c_get_os proc~get_os->interface~c_get_os proc~get_os->proc~c_ptr_to_string

Called by

proc~~output_system_log~~CalledByGraph proc~output_system_log output_system_log interface~output_system_log type_output%output_system_log interface~output_system_log->proc~output_system_log

Source Code

    module subroutine output_system_log(self, time, Matrix, domain)
        implicit none
        class(type_output), intent(inout) :: self
        type(type_time), intent(in) :: time
        type(Type_CRS), intent(in) :: Matrix
        type(type_domain), intent(inout) :: domain

        character(:), allocatable :: username
        character(:), allocatable :: hostname
        character(:), allocatable :: compiler
        character(:), allocatable :: compiler_version
        character(:), allocatable :: architecture
        character(:), allocatable :: os
!$      character(:), allocatable :: openmp_version
!$      integer(int32) :: max_threads
!$      integer(int32) :: num_threads
        integer(int32) :: num_unit, ios
        integer(int64) :: rss_kb
        real(real64) :: rss_mb

        integer(int32) :: i
        real(real64) :: component_total_time ! 「Total」を除いた合計時間
        real(real64) :: total_section_time ! 「Total」セクションの時間
        integer(int32), parameter :: nRepeat = 50

        character(len=32) :: fmt
        integer(int32) :: width

        ! 保険として初期化
        fmt = ''

        username = get_username()
        hostname = get_hostname()
        compiler = get_compiler_name()
        compiler_version = get_compiler_version()
        architecture = get_cpu_architecture()
        os = get_os()
!$      openmp_version = get_openmp_version()
!$      max_threads = omp_get_num_procs()
!$      num_threads = omp_get_max_threads()

        rss_mb = get_memory_usage()
        ! 幅の計算。log10(0) の回避と最小幅保証
        width = max(6, int(log10(max(1.0d0, rss_mb))) + 6)
        ! フォーマット文字列の構築
        write (fmt, '(a,i0,a)') '(a,f', width, '.4,a)'

        open (newunit=num_unit, file=self%log_file_name, status='replace', action='write', iostat=ios)
        if (ios /= 0) then
            write (*, *) "Error opening log file: ", self%log_file_name
            stop
        end if
        write (num_unit, '(a)') repeat('=', nRepeat)
        write (num_unit, '(a)') "FTDSS System Log" !&
        write (num_unit, '(a)') repeat('=', nRepeat)
        write (num_unit, '(a)') "Username           : "//trim(username) !&
        write (num_unit, '(a)') "Hostname           : "//trim(hostname) !&
        write (num_unit, '(a)') "OS                 : "//trim(os) !&
        write (num_unit, '(a)') "Architecture       : "//trim(architecture) !&
        write (num_unit, '(a)') "Compiler           : "//trim(compiler) !&
        write (num_unit, '(a)') "Compiler Version   : "//trim(compiler_version) !&
        write (num_unit, fmt)   "RSS Memory Usage   : ", rss_mb, " MB" !&
!$      write (num_unit, '(a)') "OpenMP Version     : "//trim(openmp_version) !&
!$      write (num_unit, '(a)') "OpenMP Max Threads : "//trim(to_string(max_threads)) !&
!$      write (num_unit, '(a)') "OpenMP Threads     : "//trim(to_string(num_threads)) !&
        write (num_unit, '(a)') repeat('=', nRepeat)
        write (num_unit, '(a)') "Time Information" !&
        write (num_unit, '(a)') repeat('=', nRepeat)
        write (num_unit, '(a)') trim(time%start%label)//" Time : "//time%start%date(1:4)//"-"//time%start%date(5:6)//"-"//time%start%date(7:8)//"T"//time%start%time(1:2)//":"//time%start%time(3:4)//":"//time%start%time(5:6)//trim(time%start%zone)
        write (num_unit, '(a)') trim(time%end%label)//" Time   : "//time%end%date(1:4)//"-"//time%end%date(5:6)//"-"//time%end%date(7:8)//"T"//time%end%time(1:2)//":"//time%end%time(3:4)//":"//time%end%time(5:6)//trim(time%end%zone)

        component_total_time = 0.0d0
        total_section_time = 0.0d0

        ! --- 先に合計を計算 ---
        do i = 1, size(time%sections)
            ! 'Total'セクションは別で保持し、部品の合計からは除外する
            if (trim(adjustl(time%sections(i)%label)) == "Total") then
                total_section_time = time%sections(i)%total_time
            else
                component_total_time = component_total_time + time%sections(i)%total_time
            end if
        end do

        write (num_unit, '(a)') repeat('=', nRepeat)
        write (num_unit, '(a)') "Performance Profiling Report"
        write (num_unit, '(a)') repeat('=', nRepeat)
        write (num_unit, '(a10, a15, a15)') "Section", "Time (sec)", "Percentage"
        write (num_unit, '(a)') repeat('-', nRepeat)

        ! --- 各セクションの結果を出力 ---
        do i = 1, size(time%sections)
            if (trim(adjustl(time%sections(i)%label)) == "Total") cycle

            if (component_total_time > 0.0d0) then
                write (num_unit, '(a10, f15.4, f14.4, a)') trim(time%sections(i)%label), &
                    time%sections(i)%total_time, &
                    (time%sections(i)%total_time / component_total_time) * 100.0d0, " %"
            else
                write (num_unit, '(a10, f15.4, a)') trim(time%sections(i)%label), time%sections(i)%total_time, " (N/A %)"
            end if
        end do

        write (num_unit, '(a)') repeat('-', nRepeat)

        ! 'Total'セクションが計測されていれば、それも表示
        if (total_section_time > 0.0d0) then
            write (num_unit, '(a10, f15.4, a)') "Total", total_section_time, ""
        else
            write (num_unit, '(a10, f15.4, a)') "Total", component_total_time, ""
        end if

        write (num_unit, '(a)') repeat('=', nRepeat)
        write (num_unit, '(a)') "Matrix Information"
        write (num_unit, '(a)') repeat('-', nRepeat)
        write (num_unit, '(a)') "Matrix type : CRS"
        write (num_unit, '(a,i0)') "Matrix size : ", Matrix%num_row
        write (num_unit, '(a,i0)') "Matrix nnz  : ", Matrix%nnz
        write (num_unit, '(a)') repeat('-', nRepeat)
        write (num_unit, '(a,i0)') "Coloring Count : ", Domain%Colors%num_colors
        write (num_unit, '(a)') repeat('=', nRepeat)

        close (num_unit)
    end subroutine output_system_log