carm-roofline 1.0.2.dev2__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.dev2/carm_roofline.egg-info → carm_roofline-1.0.3.dev1}/PKG-INFO +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/architecture.py +6 -9
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/arm.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/config.py +1 -2
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/detect.py +2 -3
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/memory.py +1 -2
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/riscv.py +4 -4
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/x86.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/__init__.py +0 -3
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/benchmark.py +1 -1
- {carm_roofline-1.0.2.dev2 → 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.dev2 → carm_roofline-1.0.3.dev1}/benchmark/generation/code_gen/__init__.py +0 -4
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/generation/code_gen/instruction.py +2 -2
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/generation/code_gen/register.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/generation/parameters.py +4 -6
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/output/arithmetic.py +2 -2
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/output/common.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/output/jsonl.py +3 -3
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/output/memory.py +2 -2
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/output/memory_sweep.py +2 -2
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/output/roofline.py +176 -55
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/result.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/suites/arithmetic.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/suites/base.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/suites/memory.py +2 -2
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/suites/memory_sweep.py +2 -2
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/suites/roofline.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/carm.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1/carm_roofline.egg-info}/PKG-INFO +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/carm_roofline.egg-info/SOURCES.txt +10 -9
- {carm_roofline-1.0.2.dev2 → 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.dev2 → carm_roofline-1.0.3.dev1}/gui/assets/style.css +7 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/gui/components.py +20 -11
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/gui/data.py +157 -40
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/gui/factory.py +196 -83
- {carm_roofline-1.0.2.dev2 → 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.dev2/benchmark/generation → carm_roofline-1.0.3.dev1/isa}/arm.py +5 -5
- carm_roofline-1.0.2.dev2/benchmark/generation/isa.py → carm_roofline-1.0.3.dev1/isa/base.py +9 -6
- {carm_roofline-1.0.2.dev2/benchmark/generation → carm_roofline-1.0.3.dev1/isa}/riscv.py +5 -5
- {carm_roofline-1.0.2.dev2/benchmark/generation → carm_roofline-1.0.3.dev1/isa}/x86.py +4 -4
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/output_utils.py +7 -6
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/__init__.py +3 -3
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/backends.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/config.py +14 -5
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/papi_backend.py +50 -4
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/papi_metrics.py +239 -6
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/perf_backend.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/perf_metrics.py +1 -1
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/shared.py +14 -13
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/pyproject.toml +5 -27
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/roofline_assembly.py +73 -82
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/test/test_gui_data.py +25 -8
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/test/test_isa_codegen_integration.py +6 -6
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/test/test_memory_suite_generation.py +2 -2
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/test/test_output_module.py +147 -34
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/test/test_roofline_assembly.py +267 -15
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/test/test_typed_benchmarks.py +3 -3
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/test_bench/builder.py +1 -1
- carm_roofline-1.0.2.dev2/benchmark/generation/__init__.py +0 -53
- carm_roofline-1.0.2.dev2/utils.py +0 -177
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/LICENSE +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/README.md +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/__init__.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/frequency.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/identity.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/tests/arm/features.c +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/tests/arm/frequency.h +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/tests/arm/vlen.c +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/tests/frequency.c +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/tests/riscv/frequency.h +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/tests/riscv/rvv_version.c +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/tests/riscv/vlen.c +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/tests/x86/cache.c +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/tests/x86/features.c +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/tests/x86/frequency.h +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/architecture/tests/x86/x86_avx512/frequency.h +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/arguments.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/interface.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/output/__init__.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/output/base.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/output/mixed.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/suites/__init__.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/benchmark/suites/mixed.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/carm_roofline.egg-info/dependency_links.txt +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/carm_roofline.egg-info/entry_points.txt +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/carm_roofline.egg-info/requires.txt +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/context.py +0 -0
- {carm_roofline-1.0.2.dev2/benchmark/generation/code_gen → carm_roofline-1.0.3.dev1/core}/data_type.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1/core}/error.py +0 -0
- {carm_roofline-1.0.2.dev2/benchmark/generation/code_gen → carm_roofline-1.0.3.dev1/core}/operation.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1/core}/units.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/exec_interface.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/gui/__init__.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/gui/assets/CARM_icon.svg +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/gui/assets/CHAMP_logo.svg +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/gui/assets/menu_icon.png +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/gui/config.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/aggregation.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/model.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/output.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/papi_loader.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/profiling/perf_loader.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/results_paths.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/run_config.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/setup.cfg +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/test_bench/__init__.py +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/test_bench/test_bench.c +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/test_bench/test_bench.h +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/test_bench/wrapper.inl +0 -0
- {carm_roofline-1.0.2.dev2 → carm_roofline-1.0.3.dev1}/workspace.py +0 -0
|
@@ -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
|
|
|
@@ -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.dev2 → 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.dev2 → 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
|
|
@@ -8,83 +8,204 @@ from datetime import datetime
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
from typing import TYPE_CHECKING, Any
|
|
10
10
|
|
|
11
|
-
from
|
|
12
|
-
|
|
13
|
-
from
|
|
11
|
+
from rich.table import Table
|
|
12
|
+
|
|
13
|
+
from core import ArithmeticIntensity, ArithmeticOperation, Bandwidth, Cycles, Performance
|
|
14
|
+
from output_utils import error, get_console, info, warn
|
|
14
15
|
|
|
15
16
|
from .base import OutputHandler
|
|
16
|
-
from .common import format_precision_label
|
|
17
|
+
from .common import format_precision_label, safe_matplotlib_import, save_or_show_plot
|
|
17
18
|
|
|
18
19
|
if TYPE_CHECKING:
|
|
19
20
|
from benchmark.benchmark import ISABenchmarkSuite
|
|
20
|
-
from benchmark.generation.isa import BaseISA
|
|
21
21
|
from context import CARMContext
|
|
22
|
+
from isa import BaseISA
|
|
22
23
|
|
|
23
24
|
|
|
24
|
-
def
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
Roofline analysis requires both arithmetic intensity and GOPS,
|
|
28
|
-
which are only available from MixedBenchmarkResult.
|
|
25
|
+
def _print_table(context: CARMContext, isa_suites: dict[str, ISABenchmarkSuite]) -> None:
|
|
26
|
+
"""Print a merged roofline summary table.
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
One row per ISA x (data_type, threads, loads, stores) combo, showing peak
|
|
29
|
+
intensity. Values are displayed via their unit class __str__ methods
|
|
30
|
+
(e.g., "8.95 GOPS/s", "380.00 GB/s", "0.02 FLOP/B").
|
|
31
|
+
At verbose >= 3, also prints the arithmetic and memory detail tables.
|
|
32
32
|
"""
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
# we expect attributes 'arithmetic_intensity' and 'performance'
|
|
42
|
-
ai = getattr(res, "arithmetic_intensity", None)
|
|
43
|
-
perf = getattr(res, "performance", None)
|
|
44
|
-
if ai is None or perf is None:
|
|
45
|
-
# nothing to record for this benchmark
|
|
46
|
-
continue
|
|
47
|
-
try:
|
|
48
|
-
ai_val = float(ai)
|
|
49
|
-
perf_val = float(perf)
|
|
50
|
-
except Exception:
|
|
51
|
-
warn(f"Skipping invalid roofline point for {name} (non-numeric)")
|
|
52
|
-
continue
|
|
33
|
+
table = Table(title="Roofline Summary")
|
|
34
|
+
table.add_column("ISA", style="cyan")
|
|
35
|
+
table.add_column("Prec.", justify="left")
|
|
36
|
+
table.add_column("Thr.", style="magenta", justify="right")
|
|
37
|
+
table.add_column("Peak", justify="right")
|
|
38
|
+
for level in _CACHE_LEVELS:
|
|
39
|
+
table.add_column(level, justify="right")
|
|
40
|
+
table.add_column(f"{level} AI", justify="right")
|
|
53
41
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
42
|
+
for isa, suite in sorted(isa_suites.items(), key=lambda kv: kv[0]):
|
|
43
|
+
mem_benches = suite.get_memory_benchmarks()
|
|
44
|
+
arith_benches = suite.get_arithmetic_benchmarks()
|
|
45
|
+
|
|
46
|
+
for (dt, nt, _ld, _st), group in sorted(_group_combos(mem_benches).items()):
|
|
47
|
+
# Collect Bandwidth per cache level from this combo's memory benchmarks
|
|
48
|
+
bw_by_level: dict[str, Bandwidth | None] = dict.fromkeys(_CACHE_LEVELS)
|
|
49
|
+
for bench in group:
|
|
50
|
+
if bench.results is not None and bench.cache_level in bw_by_level:
|
|
51
|
+
bw_by_level[bench.cache_level] = bench.results.bandwidth
|
|
52
|
+
|
|
53
|
+
# Find peak Performance from arithmetic benchmarks matching this combo
|
|
54
|
+
peak_perf: Performance | None = None
|
|
55
|
+
for bench in arith_benches.values():
|
|
56
|
+
if bench.results is None:
|
|
57
|
+
continue
|
|
58
|
+
if bench.params.data_type != dt or bench.params.num_threads != nt:
|
|
59
|
+
continue
|
|
60
|
+
if peak_perf is None or bench.results.performance > peak_perf:
|
|
61
|
+
peak_perf = bench.results.performance
|
|
62
|
+
|
|
63
|
+
row: list[str] = [isa, format_precision_label(dt), str(nt)]
|
|
64
|
+
if peak_perf is not None:
|
|
65
|
+
row.append(str(peak_perf))
|
|
66
|
+
else:
|
|
67
|
+
row.append("-")
|
|
68
|
+
|
|
69
|
+
for level in _CACHE_LEVELS:
|
|
70
|
+
bw = bw_by_level[level]
|
|
71
|
+
if bw is not None and bw.value > 0 and peak_perf is not None:
|
|
72
|
+
ridge = ArithmeticIntensity(peak_perf.value / bw.value)
|
|
73
|
+
row.append(str(bw))
|
|
74
|
+
row.append(str(ridge))
|
|
75
|
+
else:
|
|
76
|
+
row.append("-")
|
|
77
|
+
row.append("-")
|
|
78
|
+
table.add_row(*row)
|
|
79
|
+
|
|
80
|
+
get_console().print(table)
|
|
81
|
+
|
|
82
|
+
if context.run_config.verbose >= 3:
|
|
83
|
+
from . import arithmetic, memory
|
|
84
|
+
|
|
85
|
+
arithmetic._print_table(context, isa_suites)
|
|
86
|
+
memory._print_table(context, isa_suites)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
_ROOFLINE_COLORS = [
|
|
90
|
+
"#1f77b4",
|
|
91
|
+
"#ff7f0e",
|
|
92
|
+
"#2ca02c",
|
|
93
|
+
"#d62728",
|
|
94
|
+
"#9467bd",
|
|
95
|
+
"#8c564b",
|
|
96
|
+
"#e377c2",
|
|
97
|
+
"#7f7f7f",
|
|
98
|
+
"#bcbd22",
|
|
99
|
+
"#17becf",
|
|
100
|
+
]
|
|
101
|
+
_LINE_STYLES = {"L1": "-", "L2": "--", "L3": "-.", "DRAM": ":"}
|
|
102
|
+
_CACHE_LEVELS = ("L1", "L2", "L3", "DRAM")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _plot_roofline_to_axis(
|
|
106
|
+
roofline_data: dict[str, tuple[float, dict[str, float]]],
|
|
107
|
+
ax: Any,
|
|
108
|
+
np: Any,
|
|
109
|
+
) -> None:
|
|
110
|
+
"""Draw roofline curves on a matplotlib log-log axis.
|
|
111
|
+
|
|
112
|
+
For each ISA: horizontal ceiling at peak Gflop/s, and one bandwidth slope
|
|
113
|
+
per cache level (y = bandwidth x AI, clipped at the ceiling).
|
|
114
|
+
"""
|
|
115
|
+
all_ridges: list[float] = []
|
|
116
|
+
for peak_gflops, bw_gbps in roofline_data.values():
|
|
117
|
+
for bw in bw_gbps.values():
|
|
118
|
+
if bw > 0:
|
|
119
|
+
all_ridges.append(peak_gflops / bw)
|
|
120
|
+
|
|
121
|
+
if not all_ridges:
|
|
122
|
+
warn("No valid roofline ridge points to plot")
|
|
123
|
+
return
|
|
57
124
|
|
|
58
|
-
|
|
59
|
-
|
|
125
|
+
ai_min = min(all_ridges) / 10
|
|
126
|
+
ai_max = max(all_ridges) * 10
|
|
127
|
+
ai_values = np.logspace(np.log10(ai_min), np.log10(ai_max), 200)
|
|
128
|
+
if not isinstance(ai_values, list):
|
|
129
|
+
ai_values = list(ai_values)
|
|
60
130
|
|
|
131
|
+
for idx, (isa, (peak_gflops, bw_gbps)) in enumerate(sorted(roofline_data.items())):
|
|
132
|
+
color = _ROOFLINE_COLORS[idx % len(_ROOFLINE_COLORS)]
|
|
61
133
|
|
|
62
|
-
|
|
63
|
-
|
|
134
|
+
# Compute ridge points for this ISA to clip the ceiling
|
|
135
|
+
isa_ridges = [peak_gflops / bw for level in _CACHE_LEVELS if (bw := bw_gbps.get(level, 0)) > 0]
|
|
136
|
+
if isa_ridges:
|
|
137
|
+
min_ridge = min(isa_ridges)
|
|
138
|
+
ceiling_ai = [ai for ai in ai_values if ai >= min_ridge]
|
|
139
|
+
else:
|
|
140
|
+
ceiling_ai = []
|
|
141
|
+
if ceiling_ai:
|
|
142
|
+
ax.plot(
|
|
143
|
+
ceiling_ai,
|
|
144
|
+
[peak_gflops] * len(ceiling_ai),
|
|
145
|
+
color=color,
|
|
146
|
+
linestyle="-",
|
|
147
|
+
linewidth=1.5,
|
|
148
|
+
label=f"{isa} ceiling",
|
|
149
|
+
)
|
|
150
|
+
for level in _CACHE_LEVELS:
|
|
151
|
+
bw = bw_gbps.get(level, 0)
|
|
152
|
+
if bw <= 0:
|
|
153
|
+
continue
|
|
154
|
+
perf = [min(bw * ai, peak_gflops) for ai in ai_values]
|
|
155
|
+
ax.plot(
|
|
156
|
+
ai_values,
|
|
157
|
+
perf,
|
|
158
|
+
color=color,
|
|
159
|
+
linestyle=_LINE_STYLES[level],
|
|
160
|
+
linewidth=1,
|
|
161
|
+
alpha=1,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
ax.set_xscale("log")
|
|
165
|
+
ax.set_yscale("log")
|
|
166
|
+
ax.set_xlabel("Arithmetic Intensity (FLOP/byte)")
|
|
167
|
+
ax.set_ylabel("Performance (Gflop/s)")
|
|
168
|
+
ax.set_title("Roofline Model")
|
|
169
|
+
ax.legend(fontsize=8)
|
|
64
170
|
|
|
65
171
|
|
|
66
172
|
def _write_plot(isa_suites: dict[str, ISABenchmarkSuite], output_path: Path | None = None) -> None:
|
|
67
|
-
"""Generate
|
|
173
|
+
"""Generate and save roofline plot.
|
|
68
174
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
may be added later.
|
|
175
|
+
Draws log-log roofline curves (bandwidth slopes + compute ceiling) per ISA.
|
|
176
|
+
Gracefully handles missing data, invalid values, and I/O errors.
|
|
72
177
|
"""
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
178
|
+
roofline_data: dict[str, tuple[float, dict[str, float]]] = {}
|
|
179
|
+
for isa, suite in sorted(isa_suites.items(), key=lambda kv: kv[0]):
|
|
180
|
+
try:
|
|
181
|
+
peak = suite.get_peak_performance()
|
|
182
|
+
bw_by_level = suite.get_bandwidth_by_level()
|
|
183
|
+
except ValueError:
|
|
184
|
+
warn(f"Skipping {isa} in roofline plot: missing or incomplete benchmark results")
|
|
185
|
+
continue
|
|
186
|
+
peak_gflops = float(peak) / 1e9
|
|
187
|
+
bw_gbps = {level: float(bw) / 1e9 for level, bw in bw_by_level.items()}
|
|
188
|
+
roofline_data[isa] = (peak_gflops, bw_gbps)
|
|
189
|
+
|
|
190
|
+
if not roofline_data:
|
|
82
191
|
warn("No roofline data found")
|
|
83
192
|
return
|
|
84
193
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
194
|
+
plt, np = safe_matplotlib_import()
|
|
195
|
+
if plt is None:
|
|
196
|
+
return
|
|
197
|
+
|
|
198
|
+
fig = None
|
|
199
|
+
try:
|
|
200
|
+
fig, ax = plt.subplots(figsize=(10, 7))
|
|
201
|
+
_plot_roofline_to_axis(roofline_data, ax, np)
|
|
202
|
+
plt.tight_layout()
|
|
203
|
+
save_or_show_plot(output_path, "roofline.png", plt=plt)
|
|
204
|
+
except Exception as e:
|
|
205
|
+
error(f"Failed to generate roofline plot: {e}")
|
|
206
|
+
finally:
|
|
207
|
+
if fig is not None:
|
|
208
|
+
plt.close(fig)
|
|
88
209
|
|
|
89
210
|
|
|
90
211
|
def _to_isa_label(isa_name: str, context: CARMContext) -> str:
|
|
@@ -37,7 +37,7 @@ class ArithmeticBenchmarkSuite(ISABenchmarkSuite):
|
|
|
37
37
|
Raises:
|
|
38
38
|
ValueError: Unsupported precision or unknown ISA name.
|
|
39
39
|
"""
|
|
40
|
-
from
|
|
40
|
+
from isa import BaseISA
|
|
41
41
|
|
|
42
42
|
benchmark = context.benchmarking
|
|
43
43
|
architecture = context.architecture
|