From 07971df5e4ed31798efc0fc4b42abb317f976d32 Mon Sep 17 00:00:00 2001 From: Wataru Otsubo Date: Sat, 27 Jul 2024 17:58:35 +0900 Subject: [PATCH] init: partial slave log parser --- .gitignore | 3 + analysis.jl | 68 +++++++++++++++ failed_reasons.png | Bin 0 -> 40126 bytes slavelog_parser.jl | 207 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 278 insertions(+) create mode 100644 .gitignore create mode 100644 analysis.jl create mode 100644 failed_reasons.png create mode 100644 slavelog_parser.jl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..22cfd68 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +./slavelogs/ +./ps_all.csv +./masterlogs/ diff --git a/analysis.jl b/analysis.jl new file mode 100644 index 0000000..97e9c6b --- /dev/null +++ b/analysis.jl @@ -0,0 +1,68 @@ +using CSV +using DataFrames +using GLMakie + +""" +mapping to unique numbers +""" +function unique_num(v) + uniques = unique(v) + mapping = Dict(uniques .=> eachindex(uniques)) + map(v) do x + mapping[x] + end +end + +df = CSV.read("ps_all.csv", DataFrame) +dropmissing!(df, :position) + +gdf = groupby(df, :position) + +df_stacked = let + preheaders = [:qspip, :recov, :power, :clock] + postheaders = map(preheaders) do sym + Symbol("n" * string(sym)) + end + df = combine( + gdf, + preheaders .=> (v -> count(v .!= 1)) .=> postheaders, + ) + + stack(df, postheaders) +end + +transform!( + df_stacked, + :position => unique_num => :position_id, +) +transform!( + df_stacked, + :variable => unique_num => :variable_id, +) + +colors = Makie.wong_colors() +fig = Figure() +ax = Axis( + fig[1, 1], + title = "failed ones", + xlabel = "position", + xticks = (df_stacked.position_id, df_stacked.position), + xticklabelrotation = π / 3, + ylabel = "counts", +) +barplot!( + ax, + df_stacked.position_id, + df_stacked.value, + stack = df_stacked.variable_id, + color = colors[df_stacked.variable_id |> collect], +) + +Legend( + fig[1, 2], + [PolyElement(polycolor = colors[i]) for i in df_stacked.variable_id |> unique], + df_stacked.variable |> unique, + "entries", +) + +save("failed_reasons.png", fig) diff --git a/failed_reasons.png b/failed_reasons.png new file mode 100644 index 0000000000000000000000000000000000000000..60c845c6e8201ab15b6caf166f1eb50d9eb5afd4 GIT binary patch literal 40126 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 literal 0 HcmV?d00001 diff --git a/slavelog_parser.jl b/slavelog_parser.jl new file mode 100644 index 0000000..c9dbba1 --- /dev/null +++ b/slavelog_parser.jl @@ -0,0 +1,207 @@ +HEADER_QSPIP_START = "=============== Test QAPIp Start ===============" +HEADER_POWER_START = "=============== Test Power Start ===============" +HEADER_ASDTP_START = "=============== Test ASDTP Start ===============" +HEADER_RECOV_START = "=============== Test Recov Start ===============" +HEADER_STARTS = [HEADER_QSPIP_START, HEADER_POWER_START, HEADER_ASDTP_START, HEADER_RECOV_START] + +@enum SlaveLogSection begin + MODE_NONE + MODE_QSPIP + MODE_POWER + MODE_ASDTP + MODE_RECOV +end + +""" +Extract info from slave log filename. +""" +function get_psbid_runid_from_filename(filename::AbstractString)::Tuple{Int64,Int64,Bool} + main, _ext = splitext(filename) + parts = split(main, '_') + psbid = parse(Int64, parts[1]) + runid = parse(Int64, parts[2]) + islongrun = if length(parts) == 3 + true + else + false + end + + (psbid, runid, islongrun) +end + +function is_valid_slavelog(filename::AbstractString)::Bool + error("not yet implemented") +end + +""" + detect_mode_start(line::AbstractString) + +Detect [`SlaveLogSection`](@ref) from section starting header line. +If the line doesn't match any section, returns `nothing`. +""" +function detect_mode_start(line::AbstractString) + if line == HEADER_QSPIP_START + MODE_QSPIP + elseif line == HEADER_POWER_START + MODE_POWER + elseif line == HEADER_ASDTP_START + MODE_ASDTP + elseif line == HEADER_RECOV_START + MODE_RECOV + else + nothing + end +end + +""" + detect_mode_start!(mode::SlaveLogSection, line::AbstractString) + +Detect mode from the `line` and update `mode`. +""" +function detect_mode_start(mode::SlaveLogSection, line::AbstractString) + newmode = detect_mode_start(line) + if !isnothing(newmode) + mode = newmode + end + mode +end + +""" + parse_qspip_section(lines::Base.Iterators.Stateful) + +Parse QSPIp section of given stateful iterator of log. + +# Args +- `lines`: Stateful iterator of slave log file lines +""" +function parse_qspip_section!(lines::Base.Iterators.Stateful) + # TODO + nothing +end + +""" + parse_power_section(lines::Base.Iterators.Stateful) + +Parse Power section of given stateful iterator of log. + +# Args +- `lines`: Stateful iterator of slave log file lines +""" +function parse_power_section!(lines::Base.Iterators.Stateful) + # TODO + nothing +end + +""" +Measurement result for asic in asdtp test. +""" +struct AsdtpMeasurement + before::Float64 + current::Float64 + next::Float64 +end + +function Base.parse(::Type{AsdtpMeasurement}, s::AbstractString) + v = split(s, ':') + @assert length(v) == 3 + AsdtpMeasurement( + parse(Float64, v[1]), + parse(Float64, v[2]), + parse(Float64, v[3]), + ) +end + +""" + parse_asdtp_section(lines::Base.Iterators.Stateful) + +Parse ASDTP section of given stateful iterator of log. + +# Args +- `lines`: Stateful iterator of slave log file lines +""" +function parse_asdtp_section!(lines::Base.Iterators.Stateful) + line_count = 0 + line = popfirst!(lines) + line_count += 1 + results = map(_ -> AsdtpMeasurement[], 1:8) + for asic_id in 1:8 + header_line = "----PP$(asic_id)----" + while line != header_line + line = popfirst!(lines) + line_count += 1 + end + for _ in 1:32 + line = popfirst!(lines) + line_count += 1 + mes = parse(AsdtpMeasurement, line) + push!(results[asic_id], mes) + end + end + @assert length(results[1]) == 32 "unexpected length: $(length(results[1]))" + return results +end + +""" + parse_qspip_section(lines::Base.Iterators.Stateful) + +Parse Recov section of given stateful iterator of log. + +# Args +- `lines`: Stateful iterator of slave log file lines +""" +function parse_recov_section!(lines::Base.Iterators.Stateful) + # TODO + nothing +end + +function parse_slavelog_file(filename::AbstractString) + lines_iter = Iterators.Stateful(eachline(filename)) + + asdtp_results = Any[] + + mode::SlaveLogSection = MODE_NONE + # main loop + while !isempty(lines_iter) + # each sections + if mode == MODE_NONE + line = popfirst!(lines_iter) + mode = detect_mode_start(mode, line) + elseif mode == MODE_QSPIP + parse_qspip_section!(lines_iter) + mode = MODE_NONE + elseif mode == MODE_POWER + parse_power_section!(lines_iter) + mode = MODE_NONE + elseif mode == MODE_ASDTP + result = parse_asdtp_section!(lines_iter) + push!(asdtp_results, result) + mode = MODE_NONE + elseif mode == MODE_RECOV + parse_recov_section!(lines_iter) + mode = MODE_NONE + end + end + + @info "Finished" + return asdtp_results +end + +function eff99_count_map(asdtp_results) + # try(100) × channel(8) × channel(32) + @assert length(asdtp_results) == 100 + @assert length(asdtp_results[begin]) == 8 + @assert length(asdtp_results[begin][begin]) == 32 + map(1:8) do i_asic + map(1:32) do i_channel + sum(1:100) do i_try + asdtp_results[i_try][i_asic][i_channel] != AsdtpMeasurement(0, 1, 0) + end + end + end +end + +map(eachrow(filter(:position => ==("B-0-1"), df))) do row + readdir("slavelogs/") |> + filter(startswith("$(row.motherboard_id)_")) |> + filter(contains("longrun")) +end |> Iterators.flatten