carm-roofline 1.0.2.dev1__tar.gz → 1.0.3.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {carm_roofline-1.0.2.dev1/carm_roofline.egg-info → carm_roofline-1.0.3.dev1}/PKG-INFO +15 -4
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/README.md +14 -3
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/__init__.py +8 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/architecture.py +6 -9
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/arm.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/config.py +1 -2
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/detect.py +2 -3
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/identity.py +115 -13
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/memory.py +1 -2
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/riscv.py +4 -4
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/x86.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/__init__.py +0 -3
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/benchmark.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/benchmarking.py +1 -4
- carm_roofline-1.0.3.dev1/benchmark/generation/__init__.py +10 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/generation/code_gen/__init__.py +0 -4
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/generation/code_gen/instruction.py +2 -2
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/generation/code_gen/register.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/generation/parameters.py +4 -6
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/output/arithmetic.py +2 -2
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/output/common.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/output/jsonl.py +3 -3
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/output/memory.py +2 -2
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/output/memory_sweep.py +2 -2
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/output/roofline.py +176 -55
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/result.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/suites/arithmetic.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/suites/base.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/suites/memory.py +2 -2
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/suites/memory_sweep.py +2 -2
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/suites/roofline.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/carm.py +5 -2
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1/carm_roofline.egg-info}/PKG-INFO +15 -4
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/carm_roofline.egg-info/SOURCES.txt +10 -9
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/carm_roofline.egg-info/top_level.txt +2 -3
- carm_roofline-1.0.3.dev1/core/__init__.py +33 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/gui/assets/style.css +7 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/gui/components.py +20 -11
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/gui/data.py +157 -40
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/gui/factory.py +196 -83
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/gui/ids.py +1 -0
- carm_roofline-1.0.3.dev1/isa/__init__.py +44 -0
- {carm_roofline-1.0.2.dev1/benchmark/generation → carm_roofline-1.0.3.dev1/isa}/arm.py +5 -5
- carm_roofline-1.0.2.dev1/benchmark/generation/isa.py → carm_roofline-1.0.3.dev1/isa/base.py +9 -6
- {carm_roofline-1.0.2.dev1/benchmark/generation → carm_roofline-1.0.3.dev1/isa}/riscv.py +5 -5
- {carm_roofline-1.0.2.dev1/benchmark/generation → carm_roofline-1.0.3.dev1/isa}/x86.py +4 -4
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/output_utils.py +7 -6
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/__init__.py +5 -3
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/aggregation.py +20 -20
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/backends.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/config.py +17 -15
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/output.py +6 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/papi_backend.py +50 -4
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/papi_metrics.py +239 -6
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/perf_backend.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/perf_metrics.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/shared.py +36 -27
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/pyproject.toml +5 -27
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/roofline_assembly.py +73 -82
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/test/test_gui_data.py +25 -8
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/test/test_isa_codegen_integration.py +6 -6
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/test/test_memory_suite_generation.py +2 -2
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/test/test_output_module.py +147 -34
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/test/test_roofline_assembly.py +267 -15
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/test/test_typed_benchmarks.py +3 -3
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/test_bench/builder.py +1 -1
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/test_bench/test_bench.c +2 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/test_bench/test_bench.h +2 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/test_bench/wrapper.inl +7 -0
- carm_roofline-1.0.2.dev1/benchmark/generation/__init__.py +0 -53
- carm_roofline-1.0.2.dev1/utils.py +0 -177
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/LICENSE +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/frequency.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/tests/arm/features.c +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/tests/arm/frequency.h +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/tests/arm/vlen.c +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/tests/frequency.c +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/tests/riscv/frequency.h +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/tests/riscv/rvv_version.c +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/tests/riscv/vlen.c +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/tests/x86/cache.c +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/tests/x86/features.c +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/tests/x86/frequency.h +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/architecture/tests/x86/x86_avx512/frequency.h +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/arguments.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/interface.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/output/__init__.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/output/base.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/output/mixed.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/suites/__init__.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/suites/mixed.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/carm_roofline.egg-info/dependency_links.txt +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/carm_roofline.egg-info/entry_points.txt +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/carm_roofline.egg-info/requires.txt +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/context.py +0 -0
- {carm_roofline-1.0.2.dev1/benchmark/generation/code_gen → carm_roofline-1.0.3.dev1/core}/data_type.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1/core}/error.py +0 -0
- {carm_roofline-1.0.2.dev1/benchmark/generation/code_gen → carm_roofline-1.0.3.dev1/core}/operation.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1/core}/units.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/exec_interface.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/gui/__init__.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/gui/assets/CARM_icon.svg +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/gui/assets/CHAMP_logo.svg +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/gui/assets/menu_icon.png +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/gui/config.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/model.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/papi_loader.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/profiling/perf_loader.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/results_paths.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/run_config.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/setup.cfg +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/test_bench/__init__.py +0 -0
- {carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/workspace.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: carm-roofline
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.3.dev1
|
|
4
4
|
Summary: CARM: Cache-Aware Roofline Model benchmarking and visualization toolkit
|
|
5
5
|
Author: CHaMP Team
|
|
6
6
|
License: Apache License
|
|
@@ -246,7 +246,6 @@ Dynamic: license-file
|
|
|
246
246
|
|
|
247
247
|
# The CARM Tool
|
|
248
248
|
|
|
249
|
-
|
|
250
249
|
Cache-Aware Roofline Model (CARM) toolkit - benchmark, visualize and profile Intel, AMD, ARM, RISC-V CPUs and NVIDIA, AMD GPUs.
|
|
251
250
|
|
|
252
251
|
The package provides:
|
|
@@ -258,6 +257,10 @@ The package provides:
|
|
|
258
257
|
> [!WARNING]
|
|
259
258
|
> The development branch and associated python package are still experimental, and do not include all features yet. For a stable release, please refer to the main branch.
|
|
260
259
|
|
|
260
|
+
## Documentation
|
|
261
|
+
|
|
262
|
+
You can find the full documentation at [https://champ-hub.github.io/carm-roofline](https://champ-hub.github.io/carm-roofline/).
|
|
263
|
+
|
|
261
264
|
## Installation
|
|
262
265
|
|
|
263
266
|
Install from PyPI:
|
|
@@ -279,10 +282,17 @@ source carm-env/bin/activate
|
|
|
279
282
|
pip install carm-roofline[all]
|
|
280
283
|
```
|
|
281
284
|
|
|
285
|
+
If cloning the repository directly (e.g. for development or access to example applications), use `--recurse-submodules` to also fetch the examples:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
git clone --recurse-submodules https://github.com/champ-hub/carm-roofline
|
|
289
|
+
```
|
|
290
|
+
|
|
282
291
|
## Requirements
|
|
283
292
|
|
|
284
293
|
- Python 3.9+
|
|
285
|
-
-
|
|
294
|
+
- C compiler (e.g. gcc, clang)
|
|
295
|
+
- Optional: [PAPI](https://github.com/icl-utk-edu/papi) headers and binaries for profiling
|
|
286
296
|
|
|
287
297
|
## Command-Line Interface
|
|
288
298
|
|
|
@@ -296,7 +306,7 @@ Available subcommands:
|
|
|
296
306
|
|
|
297
307
|
- `benchmark` - run benchmark suites
|
|
298
308
|
- `gui` - launch the results dashboard
|
|
299
|
-
- `profile` -
|
|
309
|
+
- `profile` - profile an application with PAPI or perf
|
|
300
310
|
|
|
301
311
|
Show help:
|
|
302
312
|
|
|
@@ -304,6 +314,7 @@ Show help:
|
|
|
304
314
|
carm --help
|
|
305
315
|
carm benchmark --help
|
|
306
316
|
carm gui --help
|
|
317
|
+
carm profile --help
|
|
307
318
|
```
|
|
308
319
|
|
|
309
320
|
## Basic Usage
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
# The CARM Tool
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
Cache-Aware Roofline Model (CARM) toolkit - benchmark, visualize and profile Intel, AMD, ARM, RISC-V CPUs and NVIDIA, AMD GPUs.
|
|
6
5
|
|
|
7
6
|
The package provides:
|
|
@@ -13,6 +12,10 @@ The package provides:
|
|
|
13
12
|
> [!WARNING]
|
|
14
13
|
> The development branch and associated python package are still experimental, and do not include all features yet. For a stable release, please refer to the main branch.
|
|
15
14
|
|
|
15
|
+
## Documentation
|
|
16
|
+
|
|
17
|
+
You can find the full documentation at [https://champ-hub.github.io/carm-roofline](https://champ-hub.github.io/carm-roofline/).
|
|
18
|
+
|
|
16
19
|
## Installation
|
|
17
20
|
|
|
18
21
|
Install from PyPI:
|
|
@@ -34,10 +37,17 @@ source carm-env/bin/activate
|
|
|
34
37
|
pip install carm-roofline[all]
|
|
35
38
|
```
|
|
36
39
|
|
|
40
|
+
If cloning the repository directly (e.g. for development or access to example applications), use `--recurse-submodules` to also fetch the examples:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git clone --recurse-submodules https://github.com/champ-hub/carm-roofline
|
|
44
|
+
```
|
|
45
|
+
|
|
37
46
|
## Requirements
|
|
38
47
|
|
|
39
48
|
- Python 3.9+
|
|
40
|
-
-
|
|
49
|
+
- C compiler (e.g. gcc, clang)
|
|
50
|
+
- Optional: [PAPI](https://github.com/icl-utk-edu/papi) headers and binaries for profiling
|
|
41
51
|
|
|
42
52
|
## Command-Line Interface
|
|
43
53
|
|
|
@@ -51,7 +61,7 @@ Available subcommands:
|
|
|
51
61
|
|
|
52
62
|
- `benchmark` - run benchmark suites
|
|
53
63
|
- `gui` - launch the results dashboard
|
|
54
|
-
- `profile` -
|
|
64
|
+
- `profile` - profile an application with PAPI or perf
|
|
55
65
|
|
|
56
66
|
Show help:
|
|
57
67
|
|
|
@@ -59,6 +69,7 @@ Show help:
|
|
|
59
69
|
carm --help
|
|
60
70
|
carm benchmark --help
|
|
61
71
|
carm gui --help
|
|
72
|
+
carm profile --help
|
|
62
73
|
```
|
|
63
74
|
|
|
64
75
|
## Basic Usage
|
|
@@ -5,7 +5,13 @@ import contextvars
|
|
|
5
5
|
from exec_interface import ExecutionInterface
|
|
6
6
|
|
|
7
7
|
from .architecture import Architecture
|
|
8
|
-
from .identity import
|
|
8
|
+
from .identity import (
|
|
9
|
+
MachineSignature,
|
|
10
|
+
detect_machine_signature,
|
|
11
|
+
generate_run_name,
|
|
12
|
+
signature_from_architecture,
|
|
13
|
+
write_machine_json,
|
|
14
|
+
)
|
|
9
15
|
from .memory import SimpleMemoryTopology
|
|
10
16
|
|
|
11
17
|
# Context variable to hold the execution interface, for compatibility with simulation and native execution
|
|
@@ -31,4 +37,5 @@ __all__ = [
|
|
|
31
37
|
"get_execution_interface",
|
|
32
38
|
"set_execution_interface",
|
|
33
39
|
"signature_from_architecture",
|
|
40
|
+
"write_machine_json",
|
|
34
41
|
]
|
|
@@ -5,13 +5,12 @@ from pathlib import Path
|
|
|
5
5
|
from typing import TYPE_CHECKING, Any
|
|
6
6
|
|
|
7
7
|
from arguments import InsertsArguments, positive_int
|
|
8
|
-
from
|
|
9
|
-
from
|
|
8
|
+
from core import Frequency, UserError
|
|
9
|
+
from isa import INCOMPATIBLE_ISAS, ISA_NAME_TO_CLASS
|
|
10
10
|
from output_utils import configure_verbosity, debug, detail, format_if_container, warn
|
|
11
|
-
from units import Frequency
|
|
12
11
|
|
|
13
12
|
if TYPE_CHECKING:
|
|
14
|
-
from
|
|
13
|
+
from isa import BaseISA
|
|
15
14
|
|
|
16
15
|
from .config import load_memory_topology_from_toml
|
|
17
16
|
from .detect import DetectedArchitecture, detect_for_isa, native_detect
|
|
@@ -32,7 +31,7 @@ def check_isa_compatibility(selected_isas: list[type[BaseISA]]) -> None:
|
|
|
32
31
|
|
|
33
32
|
# Check for special incompatibilities within the same family
|
|
34
33
|
isa_set = set(selected_isas)
|
|
35
|
-
for incompatible_pair in
|
|
34
|
+
for incompatible_pair in INCOMPATIBLE_ISAS:
|
|
36
35
|
if incompatible_pair.issubset(isa_set):
|
|
37
36
|
pair_names = ", ".join(isa.name for isa in incompatible_pair)
|
|
38
37
|
raise UserError(f"Incompatible ISAs selected: {pair_names}")
|
|
@@ -245,10 +244,8 @@ class Architecture(InsertsArguments):
|
|
|
245
244
|
detected = native_detect(threads=num_threads)
|
|
246
245
|
isa_strs = detected.isa or []
|
|
247
246
|
|
|
248
|
-
self.isa: list[type[BaseISA]] = [
|
|
247
|
+
self.isa: list[type[BaseISA]] = [ISA_NAME_TO_CLASS[isa_str] for isa_str in isa_strs]
|
|
249
248
|
else:
|
|
250
|
-
from benchmark.generation import ISA_NAME_TO_CLASS
|
|
251
|
-
|
|
252
249
|
self.isa = [ISA_NAME_TO_CLASS[isa_name] for isa_name in args.isa]
|
|
253
250
|
# Verify that the selected ISAs are compatible
|
|
254
251
|
check_isa_compatibility(self.isa)
|
|
@@ -279,7 +276,7 @@ class Architecture(InsertsArguments):
|
|
|
279
276
|
|
|
280
277
|
@staticmethod
|
|
281
278
|
def insert_arguments(parser: argparse.ArgumentParser) -> None:
|
|
282
|
-
from
|
|
279
|
+
from isa import ISA_NAME_TO_CLASS
|
|
283
280
|
|
|
284
281
|
parser.add_argument(
|
|
285
282
|
"-i",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from architecture.detect import DetectedArchitecture, TestContext, run_generic_tests
|
|
4
|
-
from
|
|
4
|
+
from isa import ArmNeon, ArmScalar, ArmSVE
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def detect(threads: int = 1) -> DetectedArchitecture:
|
|
@@ -15,12 +15,11 @@ from dataclasses import dataclass
|
|
|
15
15
|
from pathlib import Path
|
|
16
16
|
from typing import TYPE_CHECKING, Any
|
|
17
17
|
|
|
18
|
-
from
|
|
18
|
+
from core import Frequency, UserError
|
|
19
19
|
from output_utils import debug, detail, warn
|
|
20
|
-
from units import Frequency
|
|
21
20
|
|
|
22
21
|
if TYPE_CHECKING:
|
|
23
|
-
from
|
|
22
|
+
from isa import BaseISA
|
|
24
23
|
|
|
25
24
|
from .memory import MemoryTopology
|
|
26
25
|
|
|
@@ -11,6 +11,8 @@ machine yields the same name across runs.
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
13
|
import hashlib
|
|
14
|
+
import json
|
|
15
|
+
import os
|
|
14
16
|
import platform
|
|
15
17
|
import re
|
|
16
18
|
from dataclasses import dataclass
|
|
@@ -22,6 +24,8 @@ from .memory import MemoryLevelInfo, MemoryTopology, MemoryTopologyLike
|
|
|
22
24
|
if TYPE_CHECKING:
|
|
23
25
|
from .architecture import Architecture
|
|
24
26
|
|
|
27
|
+
_BYTES_PER_GIB = 1024**3
|
|
28
|
+
|
|
25
29
|
|
|
26
30
|
@dataclass(frozen=True)
|
|
27
31
|
class CpuInfo:
|
|
@@ -55,17 +59,52 @@ class MachineSignature:
|
|
|
55
59
|
vendor: str
|
|
56
60
|
memory_levels: tuple[MemoryLevelSignature, ...]
|
|
57
61
|
|
|
62
|
+
def _canonical_hash_string(self) -> str:
|
|
63
|
+
"""Canonical string fed to SHA-256 for the config hash.
|
|
64
|
+
|
|
65
|
+
Format: ``arch=<arch>;vendor=<vendor>;levels=<levels>`` where
|
|
66
|
+
``<levels>`` is a ``|``-separated list of
|
|
67
|
+
``<name>:<size_bytes>:<instances>:<num_sharing_threads>``.
|
|
68
|
+
"""
|
|
69
|
+
levels_str = "|".join(
|
|
70
|
+
f"{lvl.name}:{lvl.size_bytes}:{lvl.instances}:{lvl.num_sharing_threads}" for lvl in self.memory_levels
|
|
71
|
+
)
|
|
72
|
+
return f"arch={self.arch};vendor={self.vendor};levels={levels_str}"
|
|
73
|
+
|
|
58
74
|
@property
|
|
59
75
|
def config_hash(self) -> str:
|
|
60
76
|
"""Deterministic 8-char hex SHA256 of non-model-name fields.
|
|
61
77
|
|
|
62
78
|
Hash inputs: arch, vendor, memory_levels (name, size, instances, sharing).
|
|
79
|
+
|
|
80
|
+
.. note::
|
|
81
|
+
DRAM ``size_bytes`` comes from ``/proc/zoneinfo`` ``present`` pages
|
|
82
|
+
(physical capacity, stable across reboots). Falls back to a
|
|
83
|
+
rounded-``MemTotal`` value when zoneinfo is unavailable.
|
|
84
|
+
``num_sharing_threads`` is set to 0 for DRAM (not a hardware
|
|
85
|
+
property; CPU online count may vary). Cache-level fields are
|
|
86
|
+
used verbatim.
|
|
63
87
|
"""
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return
|
|
88
|
+
return hashlib.sha256(self._canonical_hash_string().encode("utf-8")).hexdigest()[:8]
|
|
89
|
+
|
|
90
|
+
def to_dict(self) -> dict[str, object]:
|
|
91
|
+
"""Serialize all fields for machine.json debugging output."""
|
|
92
|
+
return {
|
|
93
|
+
"model_name": self.model_name,
|
|
94
|
+
"arch": self.arch,
|
|
95
|
+
"vendor": self.vendor,
|
|
96
|
+
"config_hash": self.config_hash,
|
|
97
|
+
"hash_input": self._canonical_hash_string(),
|
|
98
|
+
"memory_levels": [
|
|
99
|
+
{
|
|
100
|
+
"name": lvl.name,
|
|
101
|
+
"size_bytes": lvl.size_bytes,
|
|
102
|
+
"instances": lvl.instances,
|
|
103
|
+
"num_sharing_threads": lvl.num_sharing_threads,
|
|
104
|
+
}
|
|
105
|
+
for lvl in self.memory_levels
|
|
106
|
+
],
|
|
107
|
+
}
|
|
69
108
|
|
|
70
109
|
|
|
71
110
|
def read_cpuinfo() -> CpuInfo:
|
|
@@ -102,21 +141,69 @@ def read_cpuinfo() -> CpuInfo:
|
|
|
102
141
|
return CpuInfo(model_name=model_name, vendor=vendor)
|
|
103
142
|
|
|
104
143
|
|
|
144
|
+
def _get_physical_ram_bytes() -> int | None:
|
|
145
|
+
"""Total physical RAM (bytes) from ``/proc/zoneinfo``, or ``None``.
|
|
146
|
+
|
|
147
|
+
Sums the ``present`` field across all zones — this is the number of
|
|
148
|
+
physical pages present, derived from the firmware's e820/device-tree
|
|
149
|
+
memory map at boot. It reflects hardware capacity and is stable across
|
|
150
|
+
reboots, unlike ``MemTotal`` which subtracts kernel runtime reservations.
|
|
151
|
+
"""
|
|
152
|
+
try:
|
|
153
|
+
with open("/proc/zoneinfo") as f:
|
|
154
|
+
total_present = 0
|
|
155
|
+
for line in f:
|
|
156
|
+
parts = line.strip().split()
|
|
157
|
+
if len(parts) == 2 and parts[0] == "present":
|
|
158
|
+
total_present += int(parts[1])
|
|
159
|
+
return total_present * os.sysconf("SC_PAGE_SIZE")
|
|
160
|
+
except (OSError, ValueError):
|
|
161
|
+
return None
|
|
162
|
+
|
|
163
|
+
|
|
105
164
|
def _levels_from_topology(topology: MemoryTopologyLike | None) -> tuple[MemoryLevelSignature, ...]:
|
|
106
|
-
"""Convert a memory topology to a tuple of deterministic level signatures.
|
|
165
|
+
"""Convert a memory topology to a tuple of deterministic level signatures.
|
|
166
|
+
|
|
167
|
+
DRAM levels use the ``present`` page count from ``/proc/zoneinfo`` (a
|
|
168
|
+
hardware-capacity value stable across reboots). Falls back to rounding
|
|
169
|
+
the topology's ``MemTotal``-based size to the nearest GiB when zoneinfo
|
|
170
|
+
is unavailable (containers, odd kernels).
|
|
171
|
+
|
|
172
|
+
``num_sharing_threads`` is set to 0 for DRAM (not a hardware property;
|
|
173
|
+
``shared_cpu_list`` varies with CPU online count).
|
|
174
|
+
|
|
175
|
+
Cache levels (L1/L2/L3) are passed through unchanged.
|
|
176
|
+
"""
|
|
177
|
+
# Read physical RAM once — stable firmware value
|
|
178
|
+
physical_ram = _get_physical_ram_bytes()
|
|
179
|
+
|
|
107
180
|
if topology is None:
|
|
108
181
|
return ()
|
|
109
182
|
levels: list[MemoryLevelSignature] = []
|
|
110
183
|
for lvl in topology:
|
|
111
184
|
if isinstance(lvl, MemoryLevelInfo):
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
185
|
+
if lvl.name == "DRAM":
|
|
186
|
+
if physical_ram is not None:
|
|
187
|
+
size_bytes = physical_ram
|
|
188
|
+
else:
|
|
189
|
+
size_bytes = round(int(lvl.size) / _BYTES_PER_GIB) * _BYTES_PER_GIB
|
|
190
|
+
levels.append(
|
|
191
|
+
MemoryLevelSignature(
|
|
192
|
+
name=lvl.name,
|
|
193
|
+
size_bytes=size_bytes,
|
|
194
|
+
instances=lvl.instances,
|
|
195
|
+
num_sharing_threads=0,
|
|
196
|
+
)
|
|
197
|
+
)
|
|
198
|
+
else:
|
|
199
|
+
levels.append(
|
|
200
|
+
MemoryLevelSignature(
|
|
201
|
+
name=lvl.name,
|
|
202
|
+
size_bytes=int(lvl.size),
|
|
203
|
+
instances=lvl.instances,
|
|
204
|
+
num_sharing_threads=lvl.num_sharing_threads,
|
|
205
|
+
)
|
|
118
206
|
)
|
|
119
|
-
)
|
|
120
207
|
return tuple(levels)
|
|
121
208
|
|
|
122
209
|
|
|
@@ -206,3 +293,18 @@ def _short_model_name(name: str) -> str:
|
|
|
206
293
|
def generate_run_name(signature: MachineSignature) -> str:
|
|
207
294
|
"""Generate ``"<short_model>_<config_hash>"`` (e.g. ``"Ryzen-7-7735HS_59486dd1"``)."""
|
|
208
295
|
return f"{_short_model_name(signature.model_name)}_{signature.config_hash}"
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def write_machine_json(signature: MachineSignature, directory: Path) -> None:
|
|
299
|
+
"""Write machine.json to *directory* if it does not already exist.
|
|
300
|
+
|
|
301
|
+
The file contains the full MachineSignature serialized as JSON, including
|
|
302
|
+
all hash inputs and the computed hash, so future runs can debug why a
|
|
303
|
+
machine hash changed.
|
|
304
|
+
"""
|
|
305
|
+
path = directory / "machine.json"
|
|
306
|
+
if path.exists():
|
|
307
|
+
return
|
|
308
|
+
directory.mkdir(parents=True, exist_ok=True)
|
|
309
|
+
with open(path, "x", encoding="utf-8") as f:
|
|
310
|
+
json.dump(signature.to_dict(), f, indent=2, sort_keys=True)
|
|
@@ -9,9 +9,8 @@ from enum import Enum
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
from typing import Protocol, runtime_checkable
|
|
11
11
|
|
|
12
|
-
from
|
|
12
|
+
from core import Bytes, UserError
|
|
13
13
|
from output_utils import debug, format_if_container
|
|
14
|
-
from units import Bytes
|
|
15
14
|
|
|
16
15
|
_CPU_ROOT = Path("/sys/devices/system/cpu")
|
|
17
16
|
|
|
@@ -3,8 +3,8 @@ from __future__ import annotations
|
|
|
3
3
|
import tempfile
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
-
from benchmark import generation as bench_gen
|
|
7
6
|
from exec_interface import ExecutionInterface
|
|
7
|
+
from isa import RISCV_RVV, RISCV_RVV_071, RISCVScalar
|
|
8
8
|
|
|
9
9
|
from .detect import ROOT, DetectedArchitecture, TestContext, run_generic_tests
|
|
10
10
|
|
|
@@ -24,7 +24,7 @@ def detect(threads: int = 1) -> DetectedArchitecture:
|
|
|
24
24
|
detected = run_generic_tests(ctx, threads=threads)
|
|
25
25
|
|
|
26
26
|
# Build ISA list with scalar as base
|
|
27
|
-
isa_list = [
|
|
27
|
+
isa_list = [RISCVScalar.name]
|
|
28
28
|
|
|
29
29
|
# Detect RVV version using RISC-V specific test
|
|
30
30
|
exec_iface = _get_execution_interface()
|
|
@@ -33,9 +33,9 @@ def detect(threads: int = 1) -> DetectedArchitecture:
|
|
|
33
33
|
if rvv_version_probe_path.exists():
|
|
34
34
|
# Try compiling with RVV 1.0 flag first (most common)
|
|
35
35
|
if _can_compile_rvv(exec_iface, rvv_version_probe_path, "RISCV_RVV"):
|
|
36
|
-
isa_list.append(
|
|
36
|
+
isa_list.append(RISCV_RVV.name)
|
|
37
37
|
elif _can_compile_rvv(exec_iface, rvv_version_probe_path, "RISCV_RVV_0_7_1"):
|
|
38
|
-
isa_list.append(
|
|
38
|
+
isa_list.append(RISCV_RVV_071.name)
|
|
39
39
|
|
|
40
40
|
detected.isa = isa_list
|
|
41
41
|
|
|
@@ -11,7 +11,6 @@ from .benchmark import (
|
|
|
11
11
|
MixedBenchmarkResult,
|
|
12
12
|
)
|
|
13
13
|
from .benchmarking import Benchmarking, TestType
|
|
14
|
-
from .generation import ALL_ISAS, BaseISA
|
|
15
14
|
from .interface import generate_microbenchmarks, run_full_benchmark
|
|
16
15
|
from .result import OutputFormat
|
|
17
16
|
from .suites import (
|
|
@@ -23,13 +22,11 @@ from .suites import (
|
|
|
23
22
|
)
|
|
24
23
|
|
|
25
24
|
__all__ = [
|
|
26
|
-
"ALL_ISAS",
|
|
27
25
|
"ArithmeticBenchmark",
|
|
28
26
|
"ArithmeticBenchmarkResult",
|
|
29
27
|
"ArithmeticBenchmarkSuite",
|
|
30
28
|
"BaseBenchmark",
|
|
31
29
|
"BaseBenchmarkResult",
|
|
32
|
-
"BaseISA",
|
|
33
30
|
"Benchmarking",
|
|
34
31
|
"ISABenchmarkSuite",
|
|
35
32
|
"MemoryBenchmark",
|
|
@@ -8,9 +8,9 @@ from __future__ import annotations
|
|
|
8
8
|
from abc import ABC, abstractmethod
|
|
9
9
|
from dataclasses import dataclass, field
|
|
10
10
|
|
|
11
|
+
from core import ArithmeticIntensity, Bandwidth, Bytes, Performance, Seconds
|
|
11
12
|
from output_utils import debug
|
|
12
13
|
from test_bench.builder import MicrobenchmarkFunctionSpec
|
|
13
|
-
from units import ArithmeticIntensity, Bandwidth, Bytes, Performance, Seconds
|
|
14
14
|
|
|
15
15
|
from .generation import ArithmeticBenchmarkParams, BenchmarkParams, MemoryBenchmarkParams
|
|
16
16
|
|
|
@@ -10,11 +10,8 @@ from enum import Enum
|
|
|
10
10
|
from typing import TypeVar
|
|
11
11
|
|
|
12
12
|
from arguments import InsertsArguments, enum_action, positive_float, positive_int
|
|
13
|
-
from
|
|
13
|
+
from core import ArithmeticOperation, Bytes, DataType, Operations
|
|
14
14
|
from output_utils import warn
|
|
15
|
-
from units import Bytes, Operations
|
|
16
|
-
|
|
17
|
-
from .generation import DataType
|
|
18
15
|
|
|
19
16
|
|
|
20
17
|
class TestType(Enum):
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .parameters import ArithmeticBenchmarkParams, BenchmarkParams, MemoryBenchmarkParams, MemoryLayoutMode
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"ArithmeticBenchmarkParams",
|
|
7
|
+
"BenchmarkParams",
|
|
8
|
+
"MemoryBenchmarkParams",
|
|
9
|
+
"MemoryLayoutMode",
|
|
10
|
+
]
|
{carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/generation/code_gen/__init__.py
RENAMED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from . import instruction
|
|
4
|
-
from .data_type import DataType
|
|
5
4
|
from .instruction import ControlInstructions, TypedInstructions, escape_for_inline_asm
|
|
6
|
-
from .operation import Operation
|
|
7
5
|
from .register import CyclicRegisterSet, HelperRegisterSet, TypedRegisterSets
|
|
8
6
|
|
|
9
7
|
__all__ = [
|
|
10
8
|
"ControlInstructions",
|
|
11
9
|
"CyclicRegisterSet",
|
|
12
|
-
"DataType",
|
|
13
10
|
"HelperRegisterSet",
|
|
14
|
-
"Operation",
|
|
15
11
|
"TypedInstructions",
|
|
16
12
|
"TypedRegisterSets",
|
|
17
13
|
"escape_for_inline_asm",
|
{carm_roofline-1.0.2.dev1 → carm_roofline-1.0.3.dev1}/benchmark/generation/code_gen/instruction.py
RENAMED
|
@@ -3,8 +3,8 @@ from __future__ import annotations
|
|
|
3
3
|
from enum import Enum, auto
|
|
4
4
|
from typing import Union, overload
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
|
|
6
|
+
from core import ArithmeticOperation, DataType, MemoryOperation, Operation
|
|
7
|
+
|
|
8
8
|
from .register import CyclicRegisterSet
|
|
9
9
|
|
|
10
10
|
# Type alias for objects that can be converted to string
|
|
@@ -4,14 +4,12 @@ from dataclasses import dataclass
|
|
|
4
4
|
from enum import Enum
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
import
|
|
8
|
-
from benchmark.generation.code_gen.operation import ArithmeticOperation
|
|
9
|
-
from units import Bytes, Operations
|
|
7
|
+
from core import ArithmeticOperation, Bytes, Operations
|
|
10
8
|
|
|
11
9
|
if TYPE_CHECKING:
|
|
12
10
|
from benchmark.benchmarking import LoadStoreRatio
|
|
13
11
|
|
|
14
|
-
from
|
|
12
|
+
from core import DataType
|
|
15
13
|
|
|
16
14
|
|
|
17
15
|
class BenchParamError(Exception):
|
|
@@ -52,14 +50,14 @@ class ArithmeticBenchmarkParams(BenchmarkParams):
|
|
|
52
50
|
params = ArithmeticBenchmarkParams(
|
|
53
51
|
data_type=DataType.f32,
|
|
54
52
|
operation=ArithmeticOperation.fma,
|
|
55
|
-
num_ops=
|
|
53
|
+
num_ops=Operations(1000),
|
|
56
54
|
thread_affinity=[0, 1, 2, 3],
|
|
57
55
|
)
|
|
58
56
|
spec = isa.generate_arithmetic(params)
|
|
59
57
|
"""
|
|
60
58
|
|
|
61
59
|
operation: ArithmeticOperation
|
|
62
|
-
num_ops:
|
|
60
|
+
num_ops: Operations
|
|
63
61
|
|
|
64
62
|
def __post_init__(self) -> None:
|
|
65
63
|
super().__post_init__()
|
|
@@ -8,8 +8,8 @@ from typing import TYPE_CHECKING, Any
|
|
|
8
8
|
|
|
9
9
|
from rich.table import Table
|
|
10
10
|
|
|
11
|
+
from core import Cycles
|
|
11
12
|
from output_utils import error, get_console, warn
|
|
12
|
-
from units import Cycles
|
|
13
13
|
|
|
14
14
|
from .base import NON_ROOFLINE_CSV_ERROR_MSG, OutputHandler
|
|
15
15
|
from .common import (
|
|
@@ -47,7 +47,7 @@ def _collect_gops_by_isa(isa_suites: dict[str, ISABenchmarkSuite]) -> dict[str,
|
|
|
47
47
|
|
|
48
48
|
def _print_table(context: CARMContext, isa_suites: dict[str, ISABenchmarkSuite]) -> None:
|
|
49
49
|
from benchmark.benchmark import ArithmeticBenchmarkResult
|
|
50
|
-
from
|
|
50
|
+
from isa import BaseISA
|
|
51
51
|
|
|
52
52
|
print_extra = context.run_config.verbose >= 3
|
|
53
53
|
|
|
@@ -13,16 +13,16 @@ from datetime import datetime
|
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
from typing import TYPE_CHECKING
|
|
15
15
|
|
|
16
|
+
from core import Cycles
|
|
16
17
|
from output_utils import info, warn
|
|
17
18
|
from roofline_assembly import RecordType
|
|
18
|
-
from units import Cycles
|
|
19
19
|
|
|
20
20
|
if TYPE_CHECKING:
|
|
21
21
|
from benchmark.benchmark import ArithmeticBenchmark, MemoryBenchmark
|
|
22
|
-
from benchmark.generation.isa import BaseISA
|
|
23
22
|
from benchmark.suites.base import ISABenchmarkSuite
|
|
24
23
|
from context import CARMContext
|
|
25
|
-
from
|
|
24
|
+
from core import Frequency
|
|
25
|
+
from isa import BaseISA
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def _serialize_arithmetic(
|
|
@@ -9,9 +9,9 @@ from typing import TYPE_CHECKING, Any
|
|
|
9
9
|
from rich.table import Table
|
|
10
10
|
|
|
11
11
|
from benchmark.benchmark import MemoryBenchmarkResult
|
|
12
|
-
from
|
|
12
|
+
from core import Cycles
|
|
13
|
+
from isa import BaseISA
|
|
13
14
|
from output_utils import error, warn
|
|
14
|
-
from units import Cycles
|
|
15
15
|
|
|
16
16
|
from .base import NON_ROOFLINE_CSV_ERROR_MSG, OutputHandler
|
|
17
17
|
from .common import (
|
|
@@ -9,10 +9,10 @@ from typing import TYPE_CHECKING, Any
|
|
|
9
9
|
from rich.table import Table
|
|
10
10
|
|
|
11
11
|
from benchmark.benchmark import MemoryBenchmarkResult
|
|
12
|
-
from benchmark.generation.isa import BaseISA
|
|
13
12
|
from benchmark.suites import MemorySweepBenchmarkSuite
|
|
13
|
+
from core import Cycles
|
|
14
|
+
from isa import BaseISA
|
|
14
15
|
from output_utils import error, warn
|
|
15
|
-
from units import Cycles
|
|
16
16
|
|
|
17
17
|
from .base import NON_ROOFLINE_CSV_ERROR_MSG, OutputHandler
|
|
18
18
|
from .common import safe_matplotlib_import, save_or_show_plot
|