Skip to content

Commit

Permalink
Merge pull request #114 from MineralsCloud:TimedItem
Browse files Browse the repository at this point in the history
Deprecate `parse_clock`, use `parse(TimedItem)`
  • Loading branch information
singularitti authored Oct 26, 2023
2 parents 417e75c + 4e91ca8 commit 6bf3998
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 58 deletions.
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ version = "0.4.0"
AbInitioSoftwareBase = "df5135bc-470e-46c6-b451-292e27ca5b84"
CrystallographyBase = "93b1d1cd-a8ea-4aa5-adb1-b2407ea0ba8d"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
PyFortran90Namelists = "e44308e6-bd5b-11e9-2850-49daf8f1ec40"
QuantumESPRESSOBase = "51b62caa-b28f-11e9-38c2-1f67cb498e05"
ReadableRegex = "cbbcb084-453d-4c4c-b292-e315607ba6a4"
Expand Down
71 changes: 38 additions & 33 deletions src/PWscf/output.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
# using Dates: DateTime, DateFormat
using Dates: Hour, Minute, Millisecond
using DataFrames: AbstractDataFrame, DataFrame, groupby
using QuantumESPRESSOBase.PWscf
using VersionParsing: vparse

export TimedItem

struct SubroutineError
name::String
cerr::String
msg::String
end

struct ParseError <: Exception
msg::String
end

export Diagonalization,
Preamble,
Davidson,
Expand All @@ -29,7 +35,6 @@ export Diagonalization,
parse_fft_dimensions,
parse_iteration_head,
parse_electrons_energies,
parse_clock,
parse_input_name,
isoptimized,
isjobdone,
Expand Down Expand Up @@ -391,39 +396,39 @@ function parse_fft_dimensions(str::AbstractString)::Maybe{NamedTuple}
return (; zip((:ng, :nr1, :nr2, :nr3), parsed)...)
end # function parse_fft_dimensions

function parse_clock(str::AbstractString)::Maybe{AbstractDataFrame}
m = match(TIME_BLOCK, str)
m === nothing && return nothing
content = only(m.captures)
struct TimedItem
name::String
cpu::Millisecond
wall::Millisecond
calls::Maybe{UInt64}
end

info = DataFrame(;
subroutine=String[], item=String[], CPU=Float64[], wall=Float64[], calls=Int[]
)
for regex in [
SUMMARY_TIME_BLOCK
INIT_RUN_TIME_BLOCK
ELECTRONS_TIME_BLOCK
C_BANDS_TIME_BLOCK
SUM_BAND_TIME_BLOCK
EGTERG_TIME_BLOCK
H_PSI_TIME_BLOCK
GENERAL_ROUTINES_TIME_BLOCK
PARALLEL_ROUTINES_TIME_BLOCK
]
block = match(regex, content)
if block !== nothing
for m in eachmatch(TIME_ITEM, block[:body])
push!(
info,
[block[:head] m[1] map(x -> parse(Float64, x), m.captures[2:4])...],
)
end
end
function Base.parse(::Type{TimedItem}, str::AbstractString)
matched = match(TIMED_ITEM, str)
if isnothing(matched)
nothing
else
name, cpu, wall = matched[1], parsetime(matched[2]), parsetime(matched[3])
return TimedItem(
name, cpu, wall, isnothing(matched[4]) ? nothing : parse(UInt64, matched[5])
)
end
# m = match(TERMINATED_DATE, content)
# info["terminated date"] = parse(DateTime, m.captures[1], DateFormat("H:M:S"))
return info
end # function parse_clock
end

function parsetime(str::AbstractString)
compound = match(r"(\d+)h\s*(\d+)m", str)
seconds = match(r"(\d+\.\d{2})s", str)
if isnothing(seconds) && !isnothing(compound)
hours = parse(UInt64, compound[1])
minutes = parse(UInt64, compound[2])
return convert(Millisecond, Hour(hours) + Minute(minutes))
elseif isnothing(compound) && !isnothing(seconds)
seconds = parse(Float64, seconds[1])
return Millisecond(1000seconds)
else
throw(ParseError("unrecognized time format!"))
end
end

function parse_input_name(str::AbstractString)
m = match(READING_INPUT_FROM, str)
Expand Down
34 changes: 9 additions & 25 deletions src/PWscf/regexes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -200,31 +200,15 @@ const CONVERGED_ELECTRONS_ENERGY = Regex(
"m",
)
const TIME_BLOCK = r"(init_run\X+?This run was terminated on:.*)"
# This format is from https://github.com/QEF/q-e/blob/4132a64/PW/src/print_clock_pw.f90#L29-L33.
const SUMMARY_TIME_BLOCK = r"""
(?<head>)
(?<body>
init_run\s+:.*
\s*electrons\s+:.*
\s*(?:update_pot\s+.*)? # This does not always exist.
\s*(?:forces\s+:.*)? # This does not always exist.
\s*(?:stress\s+:.*)? # This does not always exist.
)
"""mx
const TIME_ITEM = Regex(
"\\s*([\\w0-9:]+)\\s+:\\s*$(FIXED_POINT_REAL)s\\sCPU\\s*$(FIXED_POINT_REAL)s\\sWALL\\s\\(\\s*$INTEGER\\scalls\\)",
)
# This format is from https://github.com/QEF/q-e/blob/4132a64/PW/src/print_clock_pw.f90#L35-L36.
const INIT_RUN_TIME_BLOCK = r"Called by (?<head>init_run):(?<body>\X+?)^\s*$"m
# This format is from https://github.com/QEF/q-e/blob/4132a64/PW/src/print_clock_pw.f90#L53-L54.
const ELECTRONS_TIME_BLOCK = r"Called by (?<head>electrons):(?<body>\X+?)^\s*$"m
# This format is from https://github.com/QEF/q-e/blob/4132a64/PW/src/print_clock_pw.f90#L78-L79.
const C_BANDS_TIME_BLOCK = r"Called by (?<head>c_bands):(?<body>\X+?)^\s*$"m
const SUM_BAND_TIME_BLOCK = r"Called by (?<head>sum_band):(?<body>\X+?)^\s*$"m
const EGTERG_TIME_BLOCK = r"Called by (?<head>\*egterg):(?<body>\X+?)^\s*$"m
const H_PSI_TIME_BLOCK = r"Called by (?<head>h_psi):(?<body>\X+?)^\s*$"m
const GENERAL_ROUTINES_TIME_BLOCK = r"(?<head>General routines)(?<body>\X+?)^\s*$"m
const PARALLEL_ROUTINES_TIME_BLOCK = r"(?<head>Parallel routines)(?<body>\X+?)^\s*$"m
const TIME_FORMAT = r"(\d+h\s*\d+m|\d+\.\d{2}s)"
const TIMED_ITEM =
r"([\w:]+)\s*:\s*" *
TIME_FORMAT *
r"\s*CPU\s*" *
TIME_FORMAT *
r"\s*WALL" *
r"(\s*\(\s*(\d+)\s*calls\))?" *
r"$" # Match the last row
const TERMINATED_DATE = r"This run was terminated on:(.+)" # TODO: Date
const JOB_DONE = r"JOB DONE\."
# These formats are from https://github.com/QEF/q-e/blob/4132a64/UtilXlib/error_handler.f90#L48-L68.
Expand Down

0 comments on commit 6bf3998

Please sign in to comment.