Parse a single NCU CSV file into a DataFrame. NCU CSV files contain non-CSV lines (==PROF== messages, Python stdout). Only lines starting with '"' are actual CSV rows. The second CSV row is a units row (e.g. "ns", "block") that must be skipped. Numbers use comma as thousands separat
(path: Path)
| 73 | |
| 74 | |
| 75 | def parse_ncu_csv(path: Path) -> pd.DataFrame: |
| 76 | """Parse a single NCU CSV file into a DataFrame. |
| 77 | |
| 78 | NCU CSV files contain non-CSV lines (==PROF== messages, Python stdout). |
| 79 | Only lines starting with '"' are actual CSV rows. The second CSV row is a |
| 80 | units row (e.g. "ns", "block") that must be skipped. Numbers use comma as |
| 81 | thousands separator. Duration is in nanoseconds. |
| 82 | |
| 83 | Returns a DataFrame with columns: kernel_name, duration_us, |
| 84 | averaged across ranks for TP>1. |
| 85 | """ |
| 86 | content = path.read_text() |
| 87 | csv_lines = [line for line in content.splitlines() if line.startswith('"')] |
| 88 | assert csv_lines, f"No CSV data found in {path}" |
| 89 | df = pd.read_csv( |
| 90 | io.StringIO("\n".join(csv_lines)), |
| 91 | skiprows=[1], # skip units row |
| 92 | thousands=",", |
| 93 | ) |
| 94 | assert "Kernel Name" in df.columns and "gpu__time_duration.sum" in df.columns, ( |
| 95 | f"Expected columns 'Kernel Name' and 'gpu__time_duration.sum' in {path}, " |
| 96 | f"got: {list(df.columns)}" |
| 97 | ) |
| 98 | return ( |
| 99 | df.rename(columns={"Kernel Name": "kernel_name", "gpu__time_duration.sum": "duration_ns"}) |
| 100 | .groupby("kernel_name", as_index=False, sort=False) |
| 101 | .agg(duration_us=("duration_ns", "mean")) |
| 102 | .assign(duration_us=lambda d: d["duration_us"] / 1000) |
| 103 | ) |
| 104 | |
| 105 | |
| 106 | def _print_summary(df: pd.DataFrame) -> None: |
no outgoing calls
no test coverage detected