Skip to content

Commit 2c841b6

Browse files
authored
[Benchmarks] Benchmarks scripts cleanup (#20460)
1 parent 446a453 commit 2c841b6

File tree

11 files changed

+532
-531
lines changed

11 files changed

+532
-531
lines changed

devops/scripts/benchmarks/CONTRIB.md

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@ The suite is structured around four main components: Suites, Benchmarks, Results
1818
* Represent a single benchmark, usually mapping to a binary execution.
1919
* Must implement the `Benchmark` base class (`benches/base.py`).
2020
* **Required Methods:**
21-
* `setup()`: Initializes the benchmark (e.g., build, download data). Use `self.download()` for data dependencies. **Do not** perform setup in `__init__`.
2221
* `run(env_vars)`: Executes the benchmark binary (use `self.run_bench()`) and returns a list of `Result` objects. Can be called multiple times, must produce consistent results.
23-
* `teardown()`: Cleans up resources. Can be empty. No need to remove build artifacts or downloaded datasets.
2422
* `name()`: Returns a unique identifier string for the benchmark across *all* suites. If a benchmark class is instantiated multiple times with different parameters (e.g., "Submit In Order", "Submit Out Of Order"), the `name()` must reflect this uniqueness.
2523
* **Optional Methods:**
24+
* `setup()`: Initializes the benchmark (e.g., build, download data). Use `self.download()` for data dependencies. **Do not** perform setup in `__init__`.
2625
* `lower_is_better()`: Returns `True` if lower result values are better (default: `True`).
2726
* `description()`: Provides a short description about the benchmark.
2827
* `notes()`: Provides additional commentary about the benchmark results (string).
@@ -163,9 +162,49 @@ The benchmark suite generates an interactive HTML dashboard that visualizes `Res
163162
**Stability:**
164163
* Mark unstable benchmarks with `metadata.unstable` to hide them by default.
165164

165+
## Code Style Guidelines
166+
167+
### Benchmark Class Structure
168+
169+
When creating benchmark classes, follow this consistent structure pattern:
170+
171+
**1. Constructor (`__init__`):**
172+
* Assign all parameters to protected (prefixed with `_`) or private (prefixed with `__`) instance variables.
173+
* Set `self._iterations_regular` and `self._iterations_trace` BEFORE calling `super().__init__()` (required for subclasses of `ComputeBenchmark`).
174+
175+
**2. Method Order:**
176+
* Align with methods order as in the abstract base class `Benchmark`. Not all of them are required, but follow the order for consistency.
177+
* Public methods first, then protected, then private.
178+
179+
### Naming Conventions
180+
181+
**Method Return Values:**
182+
* `name()`: Unique identifier with underscores, lowercase, includes all distinguishing parameters
183+
* Example: `"api_overhead_benchmark_sycl SubmitKernel in order with measure completion"`
184+
* `display_name()`: User-friendly, uses proper capitalization, commas for readability, used for charts titles
185+
* Example: `"SYCL SubmitKernel in order, with measure completion, NumKernels 10"`
186+
187+
**Class method names and variables should follow PEP 8 guidelines.**
188+
* Use lowercase with underscores for method names and variables.
189+
* Use single underscores prefixes for protected variables/methods and double underscores for private variables/methods.
190+
191+
### Description Writing
192+
193+
Descriptions should:
194+
* Clearly state what is being measured
195+
* Include key parameters and their values
196+
* Explain the purpose or what the benchmark tests
197+
* Be 1-3 sentences, clear and concise
198+
* If not needed, can be omitted
199+
200+
### Tag Selection
201+
202+
* Use predefined tags from `benches/base.py` when available
203+
* Tags should be lowercase, descriptive, single words
204+
166205
## Adding New Benchmarks
167206

168-
1. **Create Benchmark Class:** Implement a new class inheriting from `benches.base.Benchmark`. Implement required methods (`setup`, `run`, `teardown`, `name`) and optional ones (`description`, `get_tags`, etc.) as needed.
207+
1. **Create Benchmark Class:** Implement a new class inheriting from `benches.base.Benchmark`. Implement required methods (`run`, `name`) and optional ones (`description`, `get_tags`, etc.) as needed. Follow the code style guidelines above.
169208
2. **Add to Suite:**
170209
* If adding to an existing category, modify the corresponding `Suite` class (e.g., `benches/compute.py`) to instantiate and return your new benchmark in its `benchmarks()` method.
171210
* If creating a new category, create a new `Suite` class inheriting from `benches.base.Suite`. Implement `name()` and `benchmarks()`. Add necessary `setup()` if the suite requires shared setup. Add group metadata via `additional_metadata()` if needed.

devops/scripts/benchmarks/benches/base.py

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,28 @@ def __init__(self, suite):
5656
def name(self) -> str:
5757
pass
5858

59+
@abstractmethod
60+
def run(
61+
self,
62+
env_vars,
63+
run_trace: TracingType = TracingType.NONE,
64+
force_trace: bool = False,
65+
) -> list[Result]:
66+
"""Execute the benchmark with the given environment variables.
67+
68+
Args:
69+
env_vars: Environment variables to use when running the benchmark.
70+
run_trace: The type of tracing to run (NONE, UNITRACE, or FLAMEGRAPH).
71+
force_trace: If True, ignore the traceable() method and force tracing.
72+
73+
Returns:
74+
A list of Result objects with the benchmark results.
75+
76+
Raises:
77+
Exception: If the benchmark fails for any reason.
78+
"""
79+
pass
80+
5981
def display_name(self) -> str:
6082
"""Returns a user-friendly name for display in charts.
6183
By default returns the same as name(), but can be overridden.
@@ -87,44 +109,6 @@ def setup(self):
87109
"""Extra setup steps to be performed before running the benchmark."""
88110
pass
89111

90-
@abstractmethod
91-
def teardown(self):
92-
pass
93-
94-
@abstractmethod
95-
def run(
96-
self,
97-
env_vars,
98-
run_trace: TracingType = TracingType.NONE,
99-
force_trace: bool = False,
100-
) -> list[Result]:
101-
"""Execute the benchmark with the given environment variables.
102-
103-
Args:
104-
env_vars: Environment variables to use when running the benchmark.
105-
run_trace: The type of tracing to run (NONE, UNITRACE, or FLAMEGRAPH).
106-
force_trace: If True, ignore the traceable() method and force tracing.
107-
108-
Returns:
109-
A list of Result objects with the benchmark results.
110-
111-
Raises:
112-
Exception: If the benchmark fails for any reason.
113-
"""
114-
pass
115-
116-
@staticmethod
117-
def get_adapter_full_path():
118-
for libs_dir_name in ["lib", "lib64"]:
119-
adapter_path = os.path.join(
120-
options.ur, libs_dir_name, f"libur_adapter_{options.ur_adapter}.so"
121-
)
122-
if os.path.isfile(adapter_path):
123-
return adapter_path
124-
assert (
125-
False
126-
), f"could not find adapter file {adapter_path} (and in similar lib paths)"
127-
128112
def run_bench(
129113
self,
130114
command,
@@ -268,6 +252,18 @@ def get_metadata(self) -> dict[str, BenchmarkMetadata]:
268252
)
269253
}
270254

255+
@staticmethod
256+
def get_adapter_full_path():
257+
for libs_dir_name in ["lib", "lib64"]:
258+
adapter_path = os.path.join(
259+
options.ur, libs_dir_name, f"libur_adapter_{options.ur_adapter}.so"
260+
)
261+
if os.path.isfile(adapter_path):
262+
return adapter_path
263+
assert (
264+
False
265+
), f"could not find adapter file {adapter_path} (and in similar lib paths)"
266+
271267

272268
class Suite(ABC):
273269
@abstractmethod

devops/scripts/benchmarks/benches/benchdnn.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,6 @@ def setup(self) -> None:
9595
timeout=60 * 20,
9696
)
9797

98-
def teardown(self):
99-
pass
100-
10198

10299
class OneDnnBenchmark(Benchmark):
103100
def __init__(self, suite, bench_driver, bench_name, bench_args, syclgraph=True):
@@ -211,6 +208,3 @@ def _extract_time(self, output):
211208
if values:
212209
return sum(values)
213210
return 0.0
214-
215-
def teardown(self):
216-
pass

0 commit comments

Comments
 (0)