Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /eic-opticks/tests/check_event_timing_profile.py was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 #!/usr/bin/env python3
0002 """Validate a detailed EventTimingProfile CSV."""
0003 
0004 from __future__ import annotations
0005 
0006 import argparse
0007 import csv
0008 from pathlib import Path
0009 
0010 
0011 HEADER = (
0012     "name",
0013     "wall_time_us",
0014     "steady_time_ns",
0015     "vm_kb",
0016     "rss_kb",
0017     "metadata",
0018 )
0019 REQUIRED_PREFIXES = ("A000_SEvt__", "CSGFoundry__", "CSGOptiX__", "A000_QSim__")
0020 INTEGER_FIELDS = ("wall_time_us", "steady_time_ns", "vm_kb", "rss_kb")
0021 
0022 
0023 def fail(path: Path, message: str) -> None:
0024     raise AssertionError(f"{path}: {message}")
0025 
0026 
0027 def main() -> None:
0028     parser = argparse.ArgumentParser(description=__doc__)
0029     parser.add_argument("profile_csv", type=Path)
0030     args = parser.parse_args()
0031 
0032     with args.profile_csv.open(newline="") as stream:
0033         reader = csv.DictReader(stream)
0034         if tuple(reader.fieldnames or ()) != HEADER:
0035             fail(args.profile_csv, f"expected header {HEADER}, found {reader.fieldnames}")
0036         rows = list(reader)
0037 
0038     if not rows:
0039         fail(args.profile_csv, "contains no profile records")
0040 
0041     prior_steady = -1
0042     names: set[str] = set()
0043     prefix_counts = {prefix: 0 for prefix in REQUIRED_PREFIXES}
0044     for line_number, row in enumerate(rows, start=2):
0045         name = row["name"]
0046         names.add(name)
0047         for prefix in REQUIRED_PREFIXES:
0048             prefix_counts[prefix] += name.startswith(prefix)
0049 
0050         values: dict[str, int] = {}
0051         for field in INTEGER_FIELDS:
0052             try:
0053                 values[field] = int(row[field])
0054             except (TypeError, ValueError) as error:
0055                 fail(args.profile_csv, f"row {line_number} {name!r} has invalid {field}={row[field]!r}: {error}")
0056 
0057         if values["steady_time_ns"] < prior_steady:
0058             fail(args.profile_csv, f"row {line_number} {name!r} has decreasing steady_time_ns")
0059         if values["vm_kb"] < 0 or values["rss_kb"] < 0:
0060             fail(args.profile_csv, f"row {line_number} {name!r} has negative memory")
0061         prior_steady = values["steady_time_ns"]
0062 
0063     missing = [prefix for prefix, count in prefix_counts.items() if count == 0]
0064     if missing:
0065         fail(args.profile_csv, f"missing records with prefixes: {', '.join(missing)}")
0066 
0067     launch_pairs = 0
0068     for name in names:
0069         if name.endswith("QSim__simulate_PREL"):
0070             launch_pairs += (name.removesuffix("PREL") + "POST") in names
0071     if launch_pairs == 0:
0072         fail(args.profile_csv, "contains no matching QSim PREL/POST launch pair")
0073 
0074     print(f"PROFILE_RECORDS={len(rows)}")
0075     print(f"PROFILE_LAUNCH_PAIRS={launch_pairs}")
0076 
0077 
0078 if __name__ == "__main__":
0079     main()