Skip to content

Commit 39ffbe3

Browse files
q10meta-codesync[bot]
authored andcommitted
Benchmark code refactoring (#5632)
Summary: X-link: https://github.com/facebookresearch/FBGEMM/pull/2583 Pull Request resolved: #5632 - Benchmark code refactoring Reviewed By: henrylhtsang Differential Revision: D100881375 fbshipit-source-id: 2463d5e280ab49738912e32b369e8457ae479212
1 parent b90d878 commit 39ffbe3

3 files changed

Lines changed: 89 additions & 0 deletions

File tree

fbgemm_gpu/fbgemm_gpu/bench/analysis/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@
2323
print_table,
2424
shorten_kernel_name,
2525
)
26+
from fbgemm_gpu.bench.analysis.parsers import detect_phase # noqa: F401
2627
from fbgemm_gpu.bench.analysis.trace import KinetoTrace # noqa: F401
2728
from fbgemm_gpu.bench.analysis.types import KernelStats, StatsMap # noqa: F401
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
# All rights reserved.
4+
#
5+
# This source code is licensed under the BSD-style license found in the
6+
# LICENSE file in the root directory of this source tree.
7+
8+
# pyre-ignore-all-errors
9+
"""Generic trace parsing utilities."""
10+
11+
from __future__ import annotations
12+
13+
14+
def detect_phase(filename: str) -> str:
15+
"""Determine benchmark phase from a trace filename.
16+
17+
Returns ``"fwd"``, ``"fwd_bwd"``, ``"bwd"``, or ``"unknown"``.
18+
19+
The check order matters: ``_benchphase_fwd_bwd_`` and ``_fwd_bwd_`` must be
20+
tested before ``_fwd_`` to avoid misclassifying combined traces as
21+
forward-only.
22+
"""
23+
if "_benchphase_fwd_bwd_" in filename or "_fwd_bwd_" in filename:
24+
return "fwd_bwd"
25+
if "_benchphase_fwd_" in filename or "_fwd_" in filename:
26+
return "fwd"
27+
if "_bwd_" in filename or "bwd" in filename.lower():
28+
return "bwd"
29+
return "unknown"

fbgemm_gpu/fbgemm_gpu/bench/analysis/types.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,23 @@ def stdev_us(self) -> float:
6262
# Instance helpers
6363
# ------------------------------------------------------------------
6464

65+
def summary_tuple(self) -> tuple[int, float, float, float, float, float]:
66+
"""Return ``(count, mean_us, median_us, stdev_us, min_us, max_us)``.
67+
68+
Returns all-NaN tuple when there are no durations.
69+
"""
70+
if not self.durations_us:
71+
_nan = float("nan")
72+
return 0, _nan, _nan, _nan, _nan, _nan
73+
return (
74+
self.count,
75+
self.mean_us,
76+
self.median_us,
77+
self.stdev_us,
78+
self.min_us,
79+
self.max_us,
80+
)
81+
6582
def get(self, attr: str, default: float = nan) -> float:
6683
"""Safe attribute access returning *default* when count == 0."""
6784
if self.count > 0:
@@ -83,6 +100,48 @@ def print_detail(self) -> None:
83100
print(f" Stdev: {self.stdev_us:,.2f} us ({self.stdev_us / 1000:,.4f} ms)")
84101
print()
85102

103+
# ------------------------------------------------------------------
104+
# Factory classmethods
105+
# ------------------------------------------------------------------
106+
107+
@classmethod
108+
def from_trace_file(
109+
cls,
110+
trace_file: str,
111+
kernel_pattern: str,
112+
*,
113+
match_mode: str = "contains",
114+
device_type: str | None = None,
115+
name: str | None = None,
116+
) -> KernelStats:
117+
"""Load a trace file, extract matching durations, and return aggregated stats.
118+
119+
This replaces the common 5-line pattern::
120+
121+
trace = KinetoTrace.from_file(path)
122+
bucketed = trace.extract_durations(pattern)
123+
durations = [d for durs in bucketed.values() for d in durs]
124+
stats = KernelStats(name=pattern, durations_us=durations)
125+
126+
Args:
127+
trace_file: Path to a ``.json`` or ``.json.gz`` Chrome trace.
128+
kernel_pattern: Pattern passed to
129+
:meth:`KinetoTrace.extract_durations`.
130+
match_mode: ``"contains"`` | ``"exact"`` | ``"startswith"`` |
131+
``"regex"``.
132+
device_type: ``"cuda"``, ``"cpu"``, or ``None``.
133+
name: Name for the returned :class:`KernelStats`. Defaults to
134+
*kernel_pattern*.
135+
"""
136+
from fbgemm_gpu.bench.analysis.trace import KinetoTrace
137+
138+
trace = KinetoTrace.from_file(trace_file)
139+
bucketed = trace.extract_durations(
140+
kernel_pattern, match_mode=match_mode, device_type=device_type
141+
)
142+
durations = [d for durs in bucketed.values() for d in durs]
143+
return cls(name=name or kernel_pattern, durations_us=durations)
144+
86145
# ------------------------------------------------------------------
87146
# Collection-level classmethods
88147
# ------------------------------------------------------------------

0 commit comments

Comments
 (0)