counted-float 0.9.2__tar.gz → 0.9.3__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.
- {counted_float-0.9.2 → counted_float-0.9.3}/PKG-INFO +9 -6
- {counted_float-0.9.2 → counted_float-0.9.3}/README.md +7 -4
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/__init__.py +0 -2
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/counting/_builtin_data.py +18 -16
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/models/__init__.py +5 -2
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/models/_flop_weights.py +6 -12
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/models/_flops_benchmark_result.py +0 -1
- counted_float-0.9.3/counted_float/_core/models/_instruction_latencies.py +146 -0
- {counted_float-0.9.2/counted_float/data/specs/arm → counted_float-0.9.3/counted_float/data/arm/v8_x/specs}/arm_v8_cortex_a76.json +29 -11
- counted_float-0.9.3/counted_float/data/arm/v8_x/specs/arm_v9_cortex_n1.json +70 -0
- counted_float-0.9.3/counted_float/data/arm/v8_x/specs/arm_v9_cortex_v1.json +70 -0
- {counted_float-0.9.2/counted_float/data/specs/arm → counted_float-0.9.3/counted_float/data/arm/v8_x/specs}/arm_v9_cortex_x1.json +29 -11
- counted_float-0.9.3/counted_float/data/arm/v9_0/specs/arm_v9_cortex_n2.json +70 -0
- counted_float-0.9.3/counted_float/data/arm/v9_0/specs/arm_v9_cortex_v2.json +70 -0
- {counted_float-0.9.2/counted_float/data/specs/arm → counted_float-0.9.3/counted_float/data/arm/v9_0/specs}/arm_v9_cortex_x2.json +29 -11
- {counted_float-0.9.2/counted_float/data/specs/arm → counted_float-0.9.3/counted_float/data/arm/v9_0/specs}/arm_v9_cortex_x3.json +29 -11
- counted_float-0.9.3/counted_float/data/arm/v9_2/specs/arm_v9_cortex_v3.json +70 -0
- counted_float-0.9.3/counted_float/data/arm/v9_2/specs/arm_v9_cortex_x4.json +70 -0
- counted_float-0.9.3/counted_float/data/arm/v9_2/specs/arm_v9_cortex_x925.json +70 -0
- counted_float-0.9.3/counted_float/data/x86/amd/2017_zen1/analysis_uops_info_zen1+.json +69 -0
- counted_float-0.9.3/counted_float/data/x86/amd/2020_zen3/analysis_agner_fog_r7_5800x.json +70 -0
- counted_float-0.9.3/counted_float/data/x86/amd/2020_zen3/analysis_uops_info_zen3.json +69 -0
- counted_float-0.9.3/counted_float/data/x86/amd/2022_zen4/analysis_agner_fog_r9_7900x.json +70 -0
- counted_float-0.9.3/counted_float/data/x86/amd/2022_zen4/analysis_uops_info_zen4.json +69 -0
- counted_float-0.9.3/counted_float/data/x86/amd/2022_zen4/specs_amd.json +70 -0
- counted_float-0.9.3/counted_float/data/x86/amd/2024_zen5/analysis_agner_fog_r7_9800x3d.json +70 -0
- counted_float-0.9.3/counted_float/data/x86/amd/2024_zen5/specs_amd.json +70 -0
- counted_float-0.9.3/counted_float/data/x86/intel/2017_coffee_lake_gen_8/analysis_agner_fog_coffee_lake.json +71 -0
- counted_float-0.9.3/counted_float/data/x86/intel/2017_coffee_lake_gen_8/analysis_uops_info_coffee_lake.json +69 -0
- counted_float-0.9.3/counted_float/data/x86/intel/2019_sunny_cove_gen_10/analysis_agner_fog_ice_lake.json +70 -0
- counted_float-0.9.3/counted_float/data/x86/intel/2019_sunny_cove_gen_10/analysis_uops_info_ice_lake.json +69 -0
- counted_float-0.9.3/counted_float/data/x86/intel/2019_sunny_cove_gen_10/analysis_uops_info_tiger_lake.json +69 -0
- counted_float-0.9.3/counted_float/data/x86/intel/2021_golden_cove_gen_12/analysis_uops_info_alder_lake_p.json +69 -0
- counted_float-0.9.3/counted_float/data/x86/intel/2021_golden_cove_gen_12/specs_intel.json +70 -0
- counted_float-0.9.3/counted_float/data/x86/intel/2022_raptor_cove_gen_13_14/specs_intel.json +71 -0
- counted_float-0.9.3/counted_float/data/x86/intel/2023_redwood_cove_ultra_1/specs_intel.json +70 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/pyproject.toml +2 -2
- counted_float-0.9.2/counted_float/_core/models/_fpu_instruction.py +0 -22
- counted_float-0.9.2/counted_float/_core/models/_fpu_specs.py +0 -98
- counted_float-0.9.2/counted_float/data/benchmarks/x86/intel/gen7_i5_7200u.json +0 -103
- counted_float-0.9.2/counted_float/data/specs/arm/arm_v7a_cortex_a9.json +0 -52
- counted_float-0.9.2/counted_float/data/specs/arm/arm_v8_cortex_a55.json +0 -52
- counted_float-0.9.2/counted_float/data/specs/x86/amd/zen3_r7_5800x.json +0 -54
- counted_float-0.9.2/counted_float/data/specs/x86/amd/zen4_r9_7900x.json +0 -54
- counted_float-0.9.2/counted_float/data/specs/x86/amd/zen5_r7_9800x3d.json +0 -54
- counted_float-0.9.2/counted_float/data/specs/x86/intel/gen09_coffee_lake.json +0 -57
- counted_float-0.9.2/counted_float/data/specs/x86/intel/gen10_cannon_lake.json +0 -57
- counted_float-0.9.2/counted_float/data/specs/x86/intel/gen11_tiger_lake.json +0 -57
- {counted_float-0.9.2 → counted_float-0.9.3}/.gitignore +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/LICENSE +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/__init__.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/_cli.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/benchmarking/__init__.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/benchmarking/_flops_benchmark_suite.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/benchmarking/_flops_micro_benchmark.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/benchmarking/_micro_benchmark.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/benchmarking/_time_utils.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/compatibility/__init__.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/compatibility/_numba.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/compatibility/_strenum.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/counting/__init__.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/counting/_context_managers.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/counting/_counted_float.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/counting/_global_counter.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/counting/config/__init__.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/counting/config/_config.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/counting/config/_defaults.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/models/_base.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/models/_flop_counts.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/models/_flop_type.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/models/_micro_benchmark_result.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/utils/__init__.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/utils/_formatting.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/utils/_geo_mean.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/utils/_latency.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/utils/_missing_data.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/utils/_timer.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/benchmarking/__init__.py +0 -0
- {counted_float-0.9.2 → counted_float-0.9.3}/counted_float/config/__init__.py +0 -0
- {counted_float-0.9.2/counted_float/data/benchmarks/arm/apple → counted_float-0.9.3/counted_float/data/arm/v8_x/benchmarks}/m3_max_macbook_pro_16.json +0 -0
- /counted_float-0.9.2/counted_float/data/benchmarks/x86/intel/gen12_i7_1265u.json → /counted_float-0.9.3/counted_float/data/x86/intel/2021_golden_cove_gen_12/benchmark_core_i7_1265u.json +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: counted-float
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.3
|
|
4
4
|
Summary: Count floating-point operations in Python code & benchmark relative flop costs.
|
|
5
5
|
Project-URL: Source, https://github.com/bertpl/counted-float
|
|
6
|
-
Project-URL: ChangeLog, https://github.com/bertpl/counted-float/blob/develop/
|
|
6
|
+
Project-URL: ChangeLog, https://github.com/bertpl/counted-float/blob/develop/CHANGELOG.md
|
|
7
7
|
Project-URL: Issues, https://github.com/bertpl/counted-float/issues
|
|
8
8
|
Project-URL: Roadmap, https://github.com/bertpl/counted-float/milestones
|
|
9
9
|
License-File: LICENSE
|
|
@@ -21,9 +21,9 @@ Description-Content-Type: text/markdown
|
|
|
21
21
|
|
|
22
22
|
<!--START_SECTION:images-->
|
|
23
23
|

|
|
24
|
-

|
|
25
|
+

|
|
26
|
+

|
|
27
27
|
<!--END_SECTION:images-->
|
|
28
28
|
|
|
29
29
|
# counted-float
|
|
@@ -148,7 +148,10 @@ counts.total_count() # 2
|
|
|
148
148
|
## 2.3. Weighted FLOP counting
|
|
149
149
|
|
|
150
150
|
The `counted_float` package contains a set of default, built-in FLOP weights, based on both empirical measurements
|
|
151
|
-
and theoretical estimates of the relative cost of different floating point operations.
|
|
151
|
+
and theoretical estimates of the relative cost of different floating point operations.
|
|
152
|
+
|
|
153
|
+
See [fpu_data_sources.md](https://github.com/bertpl/counted-float/tree/develop/docs/analysis_methodology.md) for
|
|
154
|
+
rationale behind choice of data sources and methodology.
|
|
152
155
|
|
|
153
156
|
```
|
|
154
157
|
>>> from counted_float.config import get_flop_weights
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<!--START_SECTION:images-->
|
|
2
2
|

|
|
3
|
-

|
|
4
|
+

|
|
5
|
+

|
|
6
6
|
<!--END_SECTION:images-->
|
|
7
7
|
|
|
8
8
|
# counted-float
|
|
@@ -127,7 +127,10 @@ counts.total_count() # 2
|
|
|
127
127
|
## 2.3. Weighted FLOP counting
|
|
128
128
|
|
|
129
129
|
The `counted_float` package contains a set of default, built-in FLOP weights, based on both empirical measurements
|
|
130
|
-
and theoretical estimates of the relative cost of different floating point operations.
|
|
130
|
+
and theoretical estimates of the relative cost of different floating point operations.
|
|
131
|
+
|
|
132
|
+
See [fpu_data_sources.md](https://github.com/bertpl/counted-float/tree/develop/docs/analysis_methodology.md) for
|
|
133
|
+
rationale behind choice of data sources and methodology.
|
|
131
134
|
|
|
132
135
|
```
|
|
133
136
|
>>> from counted_float.config import get_flop_weights
|
|
@@ -8,7 +8,6 @@ from ._core.models import (
|
|
|
8
8
|
FlopsBenchmarkResults,
|
|
9
9
|
FlopType,
|
|
10
10
|
FlopWeights,
|
|
11
|
-
FPUInstruction,
|
|
12
11
|
Quantiles,
|
|
13
12
|
SystemInfo,
|
|
14
13
|
)
|
|
@@ -23,7 +22,6 @@ __all__ = [
|
|
|
23
22
|
"FlopsBenchmarkResults",
|
|
24
23
|
"FlopType",
|
|
25
24
|
"FlopWeights",
|
|
26
|
-
"FPUInstruction",
|
|
27
25
|
"PauseFlopCounting",
|
|
28
26
|
"Quantiles",
|
|
29
27
|
"SystemInfo",
|
|
@@ -3,10 +3,10 @@ from __future__ import annotations
|
|
|
3
3
|
import math
|
|
4
4
|
from importlib.resources import files
|
|
5
5
|
|
|
6
|
-
from pydantic import ValidationError
|
|
6
|
+
from pydantic import BaseModel, ValidationError
|
|
7
7
|
from rich.console import Console
|
|
8
8
|
|
|
9
|
-
from counted_float._core.models import FlopsBenchmarkResults,
|
|
9
|
+
from counted_float._core.models import FlopsBenchmarkResults, FlopWeights, InstructionLatencies
|
|
10
10
|
|
|
11
11
|
DATA_PACKAGE = "counted_float.data"
|
|
12
12
|
|
|
@@ -64,17 +64,8 @@ class BuiltInData:
|
|
|
64
64
|
def benchmarks(cls) -> dict[str, FlopsBenchmarkResults]:
|
|
65
65
|
return {
|
|
66
66
|
key: FlopsBenchmarkResults.model_validate_json(json_str)
|
|
67
|
-
for key, json_str in _load_json_files_as_dict(files(f"{DATA_PACKAGE}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
# -------------------------------------------------------------------------
|
|
71
|
-
# Specs
|
|
72
|
-
# -------------------------------------------------------------------------
|
|
73
|
-
@classmethod
|
|
74
|
-
def specs(cls) -> dict[str, InstructionLatencies]:
|
|
75
|
-
return {
|
|
76
|
-
key: InstructionLatencies.model_validate_json(json_str)
|
|
77
|
-
for key, json_str in _load_json_files_as_dict(files(f"{DATA_PACKAGE}.specs")).items()
|
|
67
|
+
for key, json_str in _load_json_files_as_dict(files(f"{DATA_PACKAGE}")).items()
|
|
68
|
+
if "benchmark" in key
|
|
78
69
|
}
|
|
79
70
|
|
|
80
71
|
# -------------------------------------------------------------------------
|
|
@@ -146,16 +137,27 @@ def _construct_flop_weights_from_json_str(json_str: str) -> FlopWeights:
|
|
|
146
137
|
"""
|
|
147
138
|
Construct a FlopWeights instance from a JSON string, where the JSON string can represent either...
|
|
148
139
|
- FlopsBenchmarkResults
|
|
149
|
-
-
|
|
140
|
+
- InstructionLatencies_<x>
|
|
150
141
|
:param json_str: (str) JSON string representing either of the aforementioned data structures.
|
|
151
142
|
:return: FlopWeights instance extracted from the input data.
|
|
152
143
|
"""
|
|
153
144
|
|
|
154
145
|
# try all supported classes, all of which have a .flop_weights property
|
|
155
|
-
|
|
146
|
+
return _deserialize_as_any_pydantic_class(
|
|
147
|
+
json_str,
|
|
148
|
+
[
|
|
149
|
+
FlopsBenchmarkResults,
|
|
150
|
+
InstructionLatencies,
|
|
151
|
+
],
|
|
152
|
+
).flop_weights()
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _deserialize_as_any_pydantic_class(json_str: str, pydantic_classes: list[type[BaseModel]]):
|
|
156
|
+
# try all supported classes
|
|
157
|
+
for pydantic_cls in pydantic_classes:
|
|
156
158
|
try:
|
|
157
159
|
obj = pydantic_cls.model_validate_json(json_str)
|
|
158
|
-
return obj
|
|
160
|
+
return obj
|
|
159
161
|
except ValidationError:
|
|
160
162
|
continue
|
|
161
163
|
|
|
@@ -8,6 +8,9 @@ from ._flops_benchmark_result import (
|
|
|
8
8
|
FlopsBenchmarkResults,
|
|
9
9
|
SystemInfo,
|
|
10
10
|
)
|
|
11
|
-
from .
|
|
12
|
-
|
|
11
|
+
from ._instruction_latencies import (
|
|
12
|
+
InstructionLatencies,
|
|
13
|
+
InstructionLatencies_ARM,
|
|
14
|
+
InstructionLatencies_SSE2,
|
|
15
|
+
)
|
|
13
16
|
from ._micro_benchmark_result import MicroBenchmarkResult, Quantiles, SingleRunResult
|
|
@@ -38,11 +38,11 @@ class FlopWeights(MyBaseModel):
|
|
|
38
38
|
# -------------------------------------------------------------------------
|
|
39
39
|
@field_validator("weights")
|
|
40
40
|
@classmethod
|
|
41
|
-
def
|
|
41
|
+
def ensure_all_flop_types_present(cls, v: dict[FlopType, float | int]) -> dict[FlopType, float | int]:
|
|
42
42
|
# make sure all FlopType enum members are present
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
for flop_type in FlopType:
|
|
44
|
+
if flop_type not in v:
|
|
45
|
+
v[flop_type] = math.nan
|
|
46
46
|
return v
|
|
47
47
|
|
|
48
48
|
@field_serializer("weights")
|
|
@@ -103,14 +103,8 @@ class FlopWeights(MyBaseModel):
|
|
|
103
103
|
As a reference duration, we take the geometric mean of the costs for EQUALS, ADD, SUB, and MUL operations.
|
|
104
104
|
"""
|
|
105
105
|
|
|
106
|
-
# step 1) compute reference duration based on
|
|
107
|
-
|
|
108
|
-
flop_costs[FlopType.EQUALS],
|
|
109
|
-
flop_costs[FlopType.ADD],
|
|
110
|
-
flop_costs[FlopType.SUB],
|
|
111
|
-
flop_costs[FlopType.MUL],
|
|
112
|
-
]
|
|
113
|
-
ref_cost = geo_mean([v for v in ref_values if not math.isnan(v)]) # ignore any missing data
|
|
106
|
+
# step 1) compute reference duration based on 1 simple flop type (SUB, MUL and a few others are usually very close)
|
|
107
|
+
ref_cost = flop_costs[FlopType.ADD]
|
|
114
108
|
|
|
115
109
|
# step 2) normalize and construct FlopWeights object
|
|
116
110
|
return FlopWeights(
|
{counted_float-0.9.2 → counted_float-0.9.3}/counted_float/_core/models/_flops_benchmark_result.py
RENAMED
|
@@ -43,7 +43,6 @@ class FlopsBenchmarkResults(MyBaseModel):
|
|
|
43
43
|
benchmark_settings: BenchmarkSettings
|
|
44
44
|
results_ns: FlopsBenchmarkDurations
|
|
45
45
|
|
|
46
|
-
@property
|
|
47
46
|
def flop_weights(self) -> FlopWeights:
|
|
48
47
|
"""
|
|
49
48
|
Returns normalized weights for each flop type based on the benchmark results.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import math
|
|
4
|
+
from typing import Annotated, Literal, Union
|
|
5
|
+
|
|
6
|
+
from pydantic import Field, model_validator
|
|
7
|
+
|
|
8
|
+
from ._base import MyBaseModel
|
|
9
|
+
from ._flop_type import FlopType
|
|
10
|
+
from ._flop_weights import FlopWeights
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# =================================================================================================
|
|
14
|
+
# Single-Instruction Latency
|
|
15
|
+
# =================================================================================================
|
|
16
|
+
class Latency(MyBaseModel):
|
|
17
|
+
note: str = ""
|
|
18
|
+
min_cycles: float | None = None
|
|
19
|
+
max_cycles: float | None = None
|
|
20
|
+
|
|
21
|
+
def geo_mean(self) -> float:
|
|
22
|
+
"""Calculate the geometric mean of min and max cycles."""
|
|
23
|
+
if (self.min_cycles is None) or (self.max_cycles is None):
|
|
24
|
+
return math.nan
|
|
25
|
+
else:
|
|
26
|
+
return math.sqrt(self.min_cycles * self.max_cycles)
|
|
27
|
+
|
|
28
|
+
@model_validator(mode="before")
|
|
29
|
+
@classmethod
|
|
30
|
+
def check_min_max_cycles(cls, values):
|
|
31
|
+
# Fill in missing values if just 1 of 2 is missing
|
|
32
|
+
# (assuming min=max; which is making the least assumptions, as this is the case in most instructions)
|
|
33
|
+
if (values.get("min_cycles") is None) and (values.get("max_cycles") is not None):
|
|
34
|
+
values["min_cycles"] = values["max_cycles"]
|
|
35
|
+
elif (values.get("min_cycles") is not None) and (values.get("max_cycles") is None):
|
|
36
|
+
values["max_cycles"] = values["min_cycles"]
|
|
37
|
+
|
|
38
|
+
# Avoid 0 values. (which in principle can happen in corner cases, but which confuses our analysis)
|
|
39
|
+
if values.get("min_cycles") is not None:
|
|
40
|
+
values["min_cycles"] = max(1.0, values["min_cycles"])
|
|
41
|
+
if values.get("max_cycles") is not None:
|
|
42
|
+
values["max_cycles"] = max(1.0, values["max_cycles"])
|
|
43
|
+
|
|
44
|
+
# Return processed values
|
|
45
|
+
return values
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# =================================================================================================
|
|
49
|
+
# InstructionLatencies - SSE2
|
|
50
|
+
# =================================================================================================
|
|
51
|
+
class InstructionLatencies_SSE2(MyBaseModel):
|
|
52
|
+
# SEE: https://github.com/bertpl/counted-float/tree/develop/counted_float/data/fpu_data_sources.md
|
|
53
|
+
|
|
54
|
+
# --- primary fields ----------------------------------
|
|
55
|
+
architecture: Literal["sse2"] = "sse2"
|
|
56
|
+
|
|
57
|
+
ANDPD: Latency = Latency() # abs(x)
|
|
58
|
+
CVTSD2SI: Latency = Latency() # double -> int
|
|
59
|
+
CVTSI2SD: Latency = Latency() # int -> double
|
|
60
|
+
XORPD: Latency = Latency() # -x
|
|
61
|
+
UCOMISD: Latency = Latency() # x < == > y, x < == > 0 NOTE: should be ranges of UCOMISD & COMISD merged
|
|
62
|
+
MAXSD: Latency = Latency() # max(x,y)
|
|
63
|
+
MINSD: Latency = Latency() # min(x,y)
|
|
64
|
+
ADDSD: Latency = Latency() # x+y
|
|
65
|
+
SUBSD: Latency = Latency() # x-y
|
|
66
|
+
MULSD: Latency = Latency() # x*y
|
|
67
|
+
DIVSD: Latency = Latency() # x/y
|
|
68
|
+
SQRTSD: Latency = Latency() # sqrt(x)
|
|
69
|
+
|
|
70
|
+
# --- helpers -----------------------------------------
|
|
71
|
+
def flop_weights(self) -> FlopWeights:
|
|
72
|
+
return FlopWeights.from_abs_flop_costs(
|
|
73
|
+
{
|
|
74
|
+
FlopType.ABS: self.ANDPD.geo_mean(),
|
|
75
|
+
FlopType.MINUS: self.XORPD.geo_mean(),
|
|
76
|
+
FlopType.EQUALS: self.UCOMISD.geo_mean(),
|
|
77
|
+
FlopType.GTE: self.UCOMISD.geo_mean(),
|
|
78
|
+
FlopType.LTE: self.UCOMISD.geo_mean(),
|
|
79
|
+
FlopType.CMP_ZERO: self.UCOMISD.geo_mean(),
|
|
80
|
+
FlopType.RND: self.CVTSD2SI.geo_mean(),
|
|
81
|
+
FlopType.ADD: self.ADDSD.geo_mean(),
|
|
82
|
+
FlopType.SUB: self.SUBSD.geo_mean(),
|
|
83
|
+
FlopType.MUL: self.MULSD.geo_mean(),
|
|
84
|
+
FlopType.DIV: self.DIVSD.geo_mean(),
|
|
85
|
+
FlopType.SQRT: self.SQRTSD.geo_mean(),
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# =================================================================================================
|
|
91
|
+
# InstructionLatencies - ARM
|
|
92
|
+
# =================================================================================================
|
|
93
|
+
class InstructionLatencies_ARM(MyBaseModel):
|
|
94
|
+
# SEE: https://github.com/bertpl/counted-float/tree/develop/counted_float/data/fpu_data_sources.md
|
|
95
|
+
|
|
96
|
+
# --- primary fields ----------------------------------
|
|
97
|
+
architecture: Literal["arm"] = "arm"
|
|
98
|
+
|
|
99
|
+
FABS: Latency = Latency() # abs(x)
|
|
100
|
+
FCVTZS: Latency = Latency() # double -> int
|
|
101
|
+
SCVTF: Latency = Latency() # int -> double
|
|
102
|
+
FNEG: Latency = Latency() # -x
|
|
103
|
+
FCMP: Latency = Latency() # x < == > y, x < == > 0
|
|
104
|
+
FMAX: Latency = Latency() # max(x,y)
|
|
105
|
+
FMIN: Latency = Latency() # min(x,y)
|
|
106
|
+
FADD: Latency = Latency() # x+y
|
|
107
|
+
FSUB: Latency = Latency() # x-y
|
|
108
|
+
FMUL: Latency = Latency() # x*y
|
|
109
|
+
FDIV: Latency = Latency() # x/y
|
|
110
|
+
FSQRT: Latency = Latency() # sqrt(x)
|
|
111
|
+
|
|
112
|
+
# --- helpers -----------------------------------------
|
|
113
|
+
def flop_weights(self) -> FlopWeights:
|
|
114
|
+
return FlopWeights.from_abs_flop_costs(
|
|
115
|
+
{
|
|
116
|
+
FlopType.ABS: self.FABS.geo_mean(),
|
|
117
|
+
FlopType.MINUS: self.FNEG.geo_mean(),
|
|
118
|
+
FlopType.EQUALS: self.FCMP.geo_mean(),
|
|
119
|
+
FlopType.GTE: self.FCMP.geo_mean(),
|
|
120
|
+
FlopType.LTE: self.FCMP.geo_mean(),
|
|
121
|
+
FlopType.CMP_ZERO: self.FCMP.geo_mean(),
|
|
122
|
+
FlopType.RND: self.FCVTZS.geo_mean(),
|
|
123
|
+
FlopType.ADD: self.FADD.geo_mean(),
|
|
124
|
+
FlopType.SUB: self.FSUB.geo_mean(),
|
|
125
|
+
FlopType.MUL: self.FMUL.geo_mean(),
|
|
126
|
+
FlopType.DIV: self.FDIV.geo_mean(),
|
|
127
|
+
FlopType.SQRT: self.FSQRT.geo_mean(),
|
|
128
|
+
}
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
# =================================================================================================
|
|
133
|
+
# Union Class
|
|
134
|
+
# =================================================================================================
|
|
135
|
+
class InstructionLatencies(MyBaseModel):
|
|
136
|
+
notes: list[str] | None = [""]
|
|
137
|
+
latencies: Annotated[
|
|
138
|
+
Union[
|
|
139
|
+
InstructionLatencies_SSE2,
|
|
140
|
+
InstructionLatencies_ARM,
|
|
141
|
+
],
|
|
142
|
+
Field(discriminator="architecture"),
|
|
143
|
+
]
|
|
144
|
+
|
|
145
|
+
def flop_weights(self) -> FlopWeights:
|
|
146
|
+
return self.latencies.flop_weights()
|
|
@@ -2,51 +2,69 @@
|
|
|
2
2
|
"notes": [
|
|
3
3
|
"Data taken from:",
|
|
4
4
|
"https://developer.arm.com/documentation/PJDOC-466751330-7215/latest/",
|
|
5
|
-
"FPU data processing instructions - aarch64 - exec latency"
|
|
6
|
-
"FCHS=FNEG, FTST=FCMPZ, FRNDINT=FCVT"
|
|
5
|
+
"FPU data processing instructions - aarch64 - exec latency"
|
|
7
6
|
],
|
|
8
7
|
"latencies": {
|
|
8
|
+
"architecture": "arm",
|
|
9
9
|
"FABS": {
|
|
10
|
+
"notes": "",
|
|
10
11
|
"min_cycles": 2,
|
|
11
12
|
"max_cycles": 2
|
|
12
13
|
},
|
|
13
|
-
"
|
|
14
|
+
"FCVTZS": {
|
|
15
|
+
"notes": "",
|
|
16
|
+
"min_cycles": 4,
|
|
17
|
+
"max_cycles": 4
|
|
18
|
+
},
|
|
19
|
+
"SCVTF": {
|
|
20
|
+
"notes": "",
|
|
21
|
+
"min_cycles": 6,
|
|
22
|
+
"max_cycles": 6
|
|
23
|
+
},
|
|
24
|
+
"FNEG": {
|
|
25
|
+
"notes": "",
|
|
14
26
|
"min_cycles": 2,
|
|
15
27
|
"max_cycles": 2
|
|
16
28
|
},
|
|
17
|
-
"
|
|
29
|
+
"FCMP": {
|
|
30
|
+
"notes": "",
|
|
18
31
|
"min_cycles": 2,
|
|
19
32
|
"max_cycles": 2
|
|
20
33
|
},
|
|
21
|
-
"
|
|
34
|
+
"FMAX": {
|
|
35
|
+
"notes": "",
|
|
22
36
|
"min_cycles": 2,
|
|
23
37
|
"max_cycles": 2
|
|
24
38
|
},
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
39
|
+
"FMIN": {
|
|
40
|
+
"notes": "",
|
|
41
|
+
"min_cycles": 2,
|
|
42
|
+
"max_cycles": 2
|
|
28
43
|
},
|
|
29
44
|
"FADD": {
|
|
45
|
+
"notes": "",
|
|
30
46
|
"min_cycles": 2,
|
|
31
47
|
"max_cycles": 2
|
|
32
48
|
},
|
|
33
49
|
"FSUB": {
|
|
50
|
+
"notes": "",
|
|
34
51
|
"min_cycles": 2,
|
|
35
52
|
"max_cycles": 2
|
|
36
53
|
},
|
|
37
54
|
"FMUL": {
|
|
55
|
+
"notes": "",
|
|
38
56
|
"min_cycles": 3,
|
|
39
57
|
"max_cycles": 3
|
|
40
58
|
},
|
|
41
59
|
"FDIV": {
|
|
60
|
+
"notes": "",
|
|
42
61
|
"min_cycles": 7,
|
|
43
62
|
"max_cycles": 15
|
|
44
63
|
},
|
|
45
64
|
"FSQRT": {
|
|
65
|
+
"notes": "",
|
|
46
66
|
"min_cycles": 7,
|
|
47
67
|
"max_cycles": 17
|
|
48
|
-
}
|
|
49
|
-
"F2XM1": null,
|
|
50
|
-
"FYL2X": null
|
|
68
|
+
}
|
|
51
69
|
}
|
|
52
70
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"notes": [
|
|
3
|
+
"Data taken from:",
|
|
4
|
+
"https://developer.arm.com/documentation/109896/0400/",
|
|
5
|
+
"FPU data processing instructions - aarch64 - exec latency"
|
|
6
|
+
],
|
|
7
|
+
"latencies": {
|
|
8
|
+
"architecture": "arm",
|
|
9
|
+
"FABS": {
|
|
10
|
+
"notes": "",
|
|
11
|
+
"min_cycles": 2,
|
|
12
|
+
"max_cycles": 2
|
|
13
|
+
},
|
|
14
|
+
"FCVTZS": {
|
|
15
|
+
"notes": "",
|
|
16
|
+
"min_cycles": 4,
|
|
17
|
+
"max_cycles": 4
|
|
18
|
+
},
|
|
19
|
+
"SCVTF": {
|
|
20
|
+
"notes": "",
|
|
21
|
+
"min_cycles": 6,
|
|
22
|
+
"max_cycles": 6
|
|
23
|
+
},
|
|
24
|
+
"FNEG": {
|
|
25
|
+
"notes": "",
|
|
26
|
+
"min_cycles": 2,
|
|
27
|
+
"max_cycles": 2
|
|
28
|
+
},
|
|
29
|
+
"FCMP": {
|
|
30
|
+
"notes": "",
|
|
31
|
+
"min_cycles": 2,
|
|
32
|
+
"max_cycles": 2
|
|
33
|
+
},
|
|
34
|
+
"FMAX": {
|
|
35
|
+
"notes": "",
|
|
36
|
+
"min_cycles": 2,
|
|
37
|
+
"max_cycles": 2
|
|
38
|
+
},
|
|
39
|
+
"FMIN": {
|
|
40
|
+
"notes": "",
|
|
41
|
+
"min_cycles": 2,
|
|
42
|
+
"max_cycles": 2
|
|
43
|
+
},
|
|
44
|
+
"FADD": {
|
|
45
|
+
"notes": "",
|
|
46
|
+
"min_cycles": 2,
|
|
47
|
+
"max_cycles": 2
|
|
48
|
+
},
|
|
49
|
+
"FSUB": {
|
|
50
|
+
"notes": "",
|
|
51
|
+
"min_cycles": 2,
|
|
52
|
+
"max_cycles": 2
|
|
53
|
+
},
|
|
54
|
+
"FMUL": {
|
|
55
|
+
"notes": "",
|
|
56
|
+
"min_cycles": 3,
|
|
57
|
+
"max_cycles": 3
|
|
58
|
+
},
|
|
59
|
+
"FDIV": {
|
|
60
|
+
"notes": "",
|
|
61
|
+
"min_cycles": 7,
|
|
62
|
+
"max_cycles": 15
|
|
63
|
+
},
|
|
64
|
+
"FSQRT": {
|
|
65
|
+
"notes": "",
|
|
66
|
+
"min_cycles": 7,
|
|
67
|
+
"max_cycles": 17
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"notes": [
|
|
3
|
+
"Data taken from:",
|
|
4
|
+
"https://developer.arm.com/documentation/109897/0600/",
|
|
5
|
+
"FPU data processing instructions - aarch64 - exec latency"
|
|
6
|
+
],
|
|
7
|
+
"latencies": {
|
|
8
|
+
"architecture": "arm",
|
|
9
|
+
"FABS": {
|
|
10
|
+
"notes": "",
|
|
11
|
+
"min_cycles": 2,
|
|
12
|
+
"max_cycles": 2
|
|
13
|
+
},
|
|
14
|
+
"FCVTZS": {
|
|
15
|
+
"notes": "",
|
|
16
|
+
"min_cycles": 3,
|
|
17
|
+
"max_cycles": 3
|
|
18
|
+
},
|
|
19
|
+
"SCVTF": {
|
|
20
|
+
"notes": "",
|
|
21
|
+
"min_cycles": 3,
|
|
22
|
+
"max_cycles": 3
|
|
23
|
+
},
|
|
24
|
+
"FNEG": {
|
|
25
|
+
"notes": "",
|
|
26
|
+
"min_cycles": 2,
|
|
27
|
+
"max_cycles": 2
|
|
28
|
+
},
|
|
29
|
+
"FCMP": {
|
|
30
|
+
"notes": "",
|
|
31
|
+
"min_cycles": 2,
|
|
32
|
+
"max_cycles": 2
|
|
33
|
+
},
|
|
34
|
+
"FMAX": {
|
|
35
|
+
"notes": "",
|
|
36
|
+
"min_cycles": 2,
|
|
37
|
+
"max_cycles": 2
|
|
38
|
+
},
|
|
39
|
+
"FMIN": {
|
|
40
|
+
"notes": "",
|
|
41
|
+
"min_cycles": 2,
|
|
42
|
+
"max_cycles": 2
|
|
43
|
+
},
|
|
44
|
+
"FADD": {
|
|
45
|
+
"notes": "",
|
|
46
|
+
"min_cycles": 2,
|
|
47
|
+
"max_cycles": 2
|
|
48
|
+
},
|
|
49
|
+
"FSUB": {
|
|
50
|
+
"notes": "",
|
|
51
|
+
"min_cycles": 2,
|
|
52
|
+
"max_cycles": 2
|
|
53
|
+
},
|
|
54
|
+
"FMUL": {
|
|
55
|
+
"notes": "",
|
|
56
|
+
"min_cycles": 3,
|
|
57
|
+
"max_cycles": 3
|
|
58
|
+
},
|
|
59
|
+
"FDIV": {
|
|
60
|
+
"notes": "",
|
|
61
|
+
"min_cycles": 7,
|
|
62
|
+
"max_cycles": 15
|
|
63
|
+
},
|
|
64
|
+
"FSQRT": {
|
|
65
|
+
"notes": "",
|
|
66
|
+
"min_cycles": 7,
|
|
67
|
+
"max_cycles": 16
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -2,51 +2,69 @@
|
|
|
2
2
|
"notes": [
|
|
3
3
|
"Data taken from:",
|
|
4
4
|
"https://developer.arm.com/documentation/102174/latest/",
|
|
5
|
-
"FPU data processing instructions - aarch64 - exec latency"
|
|
6
|
-
"FCHS=FNEG, FTST=FCMPZ, FRNDINT=FCVT"
|
|
5
|
+
"FPU data processing instructions - aarch64 - exec latency"
|
|
7
6
|
],
|
|
8
7
|
"latencies": {
|
|
8
|
+
"architecture": "arm",
|
|
9
9
|
"FABS": {
|
|
10
|
+
"notes": "",
|
|
10
11
|
"min_cycles": 2,
|
|
11
12
|
"max_cycles": 2
|
|
12
13
|
},
|
|
13
|
-
"
|
|
14
|
+
"FCVTZS": {
|
|
15
|
+
"notes": "",
|
|
16
|
+
"min_cycles": 3,
|
|
17
|
+
"max_cycles": 3
|
|
18
|
+
},
|
|
19
|
+
"SCVTF": {
|
|
20
|
+
"notes": "",
|
|
21
|
+
"min_cycles": 3,
|
|
22
|
+
"max_cycles": 3
|
|
23
|
+
},
|
|
24
|
+
"FNEG": {
|
|
25
|
+
"notes": "",
|
|
14
26
|
"min_cycles": 2,
|
|
15
27
|
"max_cycles": 2
|
|
16
28
|
},
|
|
17
|
-
"
|
|
29
|
+
"FCMP": {
|
|
30
|
+
"notes": "",
|
|
18
31
|
"min_cycles": 2,
|
|
19
32
|
"max_cycles": 2
|
|
20
33
|
},
|
|
21
|
-
"
|
|
34
|
+
"FMAX": {
|
|
35
|
+
"notes": "",
|
|
22
36
|
"min_cycles": 2,
|
|
23
37
|
"max_cycles": 2
|
|
24
38
|
},
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
39
|
+
"FMIN": {
|
|
40
|
+
"notes": "",
|
|
41
|
+
"min_cycles": 2,
|
|
42
|
+
"max_cycles": 2
|
|
28
43
|
},
|
|
29
44
|
"FADD": {
|
|
45
|
+
"notes": "",
|
|
30
46
|
"min_cycles": 2,
|
|
31
47
|
"max_cycles": 2
|
|
32
48
|
},
|
|
33
49
|
"FSUB": {
|
|
50
|
+
"notes": "",
|
|
34
51
|
"min_cycles": 2,
|
|
35
52
|
"max_cycles": 2
|
|
36
53
|
},
|
|
37
54
|
"FMUL": {
|
|
55
|
+
"notes": "",
|
|
38
56
|
"min_cycles": 3,
|
|
39
57
|
"max_cycles": 3
|
|
40
58
|
},
|
|
41
59
|
"FDIV": {
|
|
60
|
+
"notes": "",
|
|
42
61
|
"min_cycles": 7,
|
|
43
62
|
"max_cycles": 15
|
|
44
63
|
},
|
|
45
64
|
"FSQRT": {
|
|
65
|
+
"notes": "",
|
|
46
66
|
"min_cycles": 7,
|
|
47
67
|
"max_cycles": 16
|
|
48
|
-
}
|
|
49
|
-
"F2XM1": null,
|
|
50
|
-
"FYL2X": null
|
|
68
|
+
}
|
|
51
69
|
}
|
|
52
70
|
}
|