counted-float 1.0.1__py3-none-any.whl

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.
Files changed (40) hide show
  1. counted_float/__init__.py +39 -0
  2. counted_float/_core/__init__.py +0 -0
  3. counted_float/_core/_backwards_compat.py +6 -0
  4. counted_float/_core/_optional_deps.py +49 -0
  5. counted_float/_core/benchmarking/__init__.py +10 -0
  6. counted_float/_core/benchmarking/_flops_benchmark_suite.py +189 -0
  7. counted_float/_core/benchmarking/_flops_micro_benchmark.py +64 -0
  8. counted_float/_core/benchmarking/_micro_benchmark.py +113 -0
  9. counted_float/_core/benchmarking/_models.py +31 -0
  10. counted_float/_core/benchmarking/_time_utils.py +70 -0
  11. counted_float/_core/counting/__init__.py +3 -0
  12. counted_float/_core/counting/_builtin_data.py +25 -0
  13. counted_float/_core/counting/_context_managers.py +95 -0
  14. counted_float/_core/counting/_counted_float.py +201 -0
  15. counted_float/_core/counting/_global_counter.py +98 -0
  16. counted_float/_core/counting/config/__init__.py +6 -0
  17. counted_float/_core/counting/config/_config.py +54 -0
  18. counted_float/_core/counting/config/_defaults.py +49 -0
  19. counted_float/_core/counting/models/__init__.py +13 -0
  20. counted_float/_core/counting/models/_base.py +6 -0
  21. counted_float/_core/counting/models/_flop_counts.py +75 -0
  22. counted_float/_core/counting/models/_flop_type.py +47 -0
  23. counted_float/_core/counting/models/_flop_weights.py +85 -0
  24. counted_float/_core/counting/models/_flops_benchmark_result.py +69 -0
  25. counted_float/_core/counting/models/_fpu_instruction.py +22 -0
  26. counted_float/_core/counting/models/_fpu_specs.py +94 -0
  27. counted_float/_core/data/__init__.py +0 -0
  28. counted_float/_core/data/benchmarks/__init__.py +0 -0
  29. counted_float/_core/data/benchmarks/apple_m3_max.json +103 -0
  30. counted_float/_core/data/benchmarks/intel_i5_7200u.json +103 -0
  31. counted_float/_core/data/benchmarks/intel_i7_1265u.json +103 -0
  32. counted_float/_core/data/specs/__init__.py +0 -0
  33. counted_float/_core/data/specs/amd_zen4_r9_7900x.json +52 -0
  34. counted_float/_core/data/specs/intel_gen11_tiger_lake.json +52 -0
  35. counted_float/benchmarking/__init__.py +14 -0
  36. counted_float/config/__init__.py +15 -0
  37. counted_float-1.0.1.dist-info/METADATA +289 -0
  38. counted_float-1.0.1.dist-info/RECORD +40 -0
  39. counted_float-1.0.1.dist-info/WHEEL +4 -0
  40. counted_float-1.0.1.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,85 @@
1
+ from __future__ import annotations
2
+
3
+ import math
4
+ from typing import Iterable
5
+
6
+ from pydantic import field_serializer, field_validator
7
+
8
+ from ._base import MyBaseModel
9
+ from ._flop_type import FlopType
10
+
11
+
12
+ class FlopWeights(MyBaseModel):
13
+ weights: dict[FlopType, float | int]
14
+
15
+ # -------------------------------------------------------------------------
16
+ # Helpers
17
+ # -------------------------------------------------------------------------
18
+ def round(self) -> FlopWeights:
19
+ """Round all weights to the nearest integer, with minimum of 1."""
20
+ return FlopWeights(
21
+ weights={k: max(1, round(v)) for k, v in self.weights.items()},
22
+ )
23
+
24
+ # -------------------------------------------------------------------------
25
+ # Validation
26
+ # -------------------------------------------------------------------------
27
+ @field_validator("weights")
28
+ @classmethod
29
+ def check_all_flop_types_present(cls, v: dict[FlopType, float | int]) -> dict[FlopType, float | int]:
30
+ # make sure all FlopType enum members are present
31
+ missing = [member for member in FlopType if member not in v]
32
+ if missing:
33
+ raise ValueError(f"Missing weights for flop types: {missing}")
34
+ return v
35
+
36
+ @field_serializer("weights")
37
+ def serialize_weights(self, weights: dict[FlopType, float | int]) -> dict[str, float | int]:
38
+ # make sure we serialize using the enum values as keys
39
+ return {k.value: v for k, v in weights.items()}
40
+
41
+ # -------------------------------------------------------------------------
42
+ # Custom visualization
43
+ # -------------------------------------------------------------------------
44
+ def show(self):
45
+ print("{")
46
+ for k, v in self.weights.items():
47
+ if isinstance(v, float):
48
+ print(f" {k.long_name()}".ljust(40) + f": {v:9.5f}")
49
+ else:
50
+ print(f" {k.long_name()}".ljust(40) + f": {v:>4}")
51
+ print("}")
52
+
53
+ # -------------------------------------------------------------------------
54
+ # Factory methods
55
+ # -------------------------------------------------------------------------
56
+ @classmethod
57
+ def as_geo_mean(cls, all_flop_weights: Iterable[FlopWeights]) -> FlopWeights:
58
+ """Computes geo-mean of a collection of FlopWeights instances."""
59
+ all_flop_weights = list(all_flop_weights)
60
+ return FlopWeights(
61
+ weights={
62
+ flop_type: pow(
63
+ math.prod(fw.weights[flop_type] for fw in all_flop_weights),
64
+ 1 / len(all_flop_weights),
65
+ ) # take geometric mean of all weights for this flop_type
66
+ for flop_type in FlopType
67
+ }
68
+ )
69
+
70
+ @classmethod
71
+ def from_abs_flop_costs(cls, flop_costs: dict[FlopType, float]) -> FlopWeights:
72
+ """
73
+ Computes FlopWeights based on absolute costs (in clock cycles, nanoseconds, ...) of each flop type.
74
+ As a reference duration, we take the geometric mean of the costs for EQUALS, ADD, SUB, and MUL operations.
75
+ """
76
+
77
+ # step 1) compute reference duration
78
+ ref_cost = (
79
+ flop_costs[FlopType.EQUALS] * flop_costs[FlopType.ADD] * flop_costs[FlopType.SUB] * flop_costs[FlopType.MUL]
80
+ ) ** (1 / 4)
81
+
82
+ # step 2) normalize and construct FlopWeights object
83
+ return FlopWeights(
84
+ weights={flop_type: flop_cost / ref_cost for flop_type, flop_cost in flop_costs.items()},
85
+ )
@@ -0,0 +1,69 @@
1
+ from __future__ import annotations
2
+
3
+ from ._base import MyBaseModel
4
+ from ._flop_type import FlopType
5
+ from ._flop_weights import FlopWeights
6
+
7
+
8
+ # =================================================================================================
9
+ # Flops Benchmark Metadata
10
+ # =================================================================================================
11
+ class SystemInfo(MyBaseModel):
12
+ platform_processor: str
13
+ platform_machine: str
14
+ platform_system: str
15
+ platform_release: str
16
+ platform_python_version: str
17
+ platform_python_implementation: str
18
+ platform_python_compiler: str
19
+ psutil_cpu_count_logical: int
20
+ psutil_cpu_count_physical: int
21
+
22
+
23
+ class BenchmarkSettings(MyBaseModel):
24
+ array_size: int
25
+ n_runs_total: int
26
+ n_runs_warmup: int
27
+ n_seconds_per_run_target: float
28
+
29
+
30
+ # =================================================================================================
31
+ # Main Flops Benchmark Information
32
+ # =================================================================================================
33
+ class Quantiles(MyBaseModel):
34
+ """Class to represent a fixed set of quantiles of an (empirical) distribution."""
35
+
36
+ q25: float
37
+ q50: float
38
+ q75: float
39
+
40
+
41
+ class FlopsBenchmarkDurations(MyBaseModel):
42
+ # baseline + flops benchmarking results in nanoseconds per <array_size> flops
43
+ baseline: Quantiles
44
+ flops: dict[FlopType, Quantiles]
45
+
46
+
47
+ class FlopsBenchmarkResults(MyBaseModel):
48
+ system_info: SystemInfo
49
+ benchmark_settings: BenchmarkSettings
50
+ results_ns: FlopsBenchmarkDurations
51
+
52
+ @property
53
+ def flop_weights(self) -> FlopWeights:
54
+ """
55
+ Returns normalized weights for each flop type based on the benchmark results.
56
+ 1) first of all, we only consider median values of the benchmark results
57
+ 2) compute duration for each flop type _minus_ baseline duration per <array_size> flops
58
+ 3) convert to flop weights by taking a few simple flop types as reference (see FlopWeights implementation)
59
+ """
60
+
61
+ # step 1) collect median values for all results
62
+ median_baseline_ns = self.results_ns.baseline.q50
63
+ median_flops_ns = {k: v.q50 for k, v in self.results_ns.flops.items()}
64
+
65
+ # step 2) surplus durations for each flop type, on top of baseline duration
66
+ flop_durations_ns = {flop_type: median_flops_ns[flop_type] - median_baseline_ns for flop_type in FlopType}
67
+
68
+ # step 3) convert to FlopWeights
69
+ return FlopWeights.from_abs_flop_costs(flop_costs=flop_durations_ns)
@@ -0,0 +1,22 @@
1
+ from counted_float._core._backwards_compat import StrEnum
2
+
3
+
4
+ class FPUInstruction(StrEnum):
5
+ """
6
+ Enum of relevant x87 FPU instructions.
7
+ Background:
8
+ - [FIL] "Simply FPU", by Raymond Filiatreault, available at: https://masm32.com/masmcode/rayfil/tutorial/index.html
9
+ """
10
+
11
+ FABS = "FABS" # absolute value of float
12
+ FCHS = "FCHS" # change sign of float
13
+ FCOM = "FCOM" # compare two floats (a == b, a > b, a < b)
14
+ FTST = "FTST" # test if float is zero (a >= 0)
15
+ FRNDINT = "FRNDINT" # round float to integer (ceil or floor)
16
+ FADD = "FADD" # addition of two floats (a + b)
17
+ FSUB = "FSUB" # subtraction of two floats (a - b)
18
+ FMUL = "FMUL" # multiplication of two floats (a * b)
19
+ FDIV = "FDIV" # division of two floats (a / b)
20
+ FSQRT = "FSQRT" # square root of float (sqrt(a))
21
+ F2XM1 = "F2XM1" # 2 raised to the power of float minus 1 (2**a - 1)
22
+ FYL2X = "FYL2X" # logarithm base 2 of float (log2(a))
@@ -0,0 +1,94 @@
1
+ from __future__ import annotations
2
+
3
+ import math
4
+
5
+ from pydantic import field_validator
6
+
7
+ from . import FlopType
8
+ from ._base import MyBaseModel
9
+ from ._flop_weights import FlopWeights
10
+ from ._fpu_instruction import FPUInstruction
11
+
12
+
13
+ class Latency(MyBaseModel):
14
+ min_cycles: int
15
+ max_cycles: int
16
+
17
+ def geo_mean(self) -> float:
18
+ """Calculate the geometric mean of min and max cycles."""
19
+ return math.sqrt(self.min_cycles * self.max_cycles)
20
+
21
+
22
+ class InstructionLatencies(MyBaseModel):
23
+ """Provides FPU instruction latency (in min/max processor cycles) per flop type."""
24
+
25
+ latencies: dict[FPUInstruction, Latency]
26
+
27
+ # -------------------------------------------------------------------------
28
+ # Helpers
29
+ # -------------------------------------------------------------------------
30
+ @property
31
+ def flop_weights(self) -> FlopWeights:
32
+ """
33
+ Calculates estimated flop weights based on instruction latencies.
34
+
35
+ Note that some FPU instructions (e.g. FCOM) correspond to multiple flop types and some flop types (e.g. a^b)
36
+ consist of multiple FPU instructions.
37
+
38
+ Background:
39
+ - [FIL] "Simply FPU", by Raymond Filiatreault, available at: https://masm32.com/masmcode/rayfil/tutorial/index.html
40
+
41
+ | Math operation | FPU instruction | Comment |
42
+ |-----------------------------|------------------------------|-----------------------|
43
+ | abs(a) | `FABS` | |
44
+ | -a | `FCHS` | |
45
+ | a==b, a>=b, a>b | `FCOM` | |
46
+ | a>0, a>=0, a==0 | `FTST` | |
47
+ | round(a), floor(a), ceil(a) | `FRNDINT` | See [FIL], chapter 8 |
48
+ | a+b | `FADD` | |
49
+ | a-b | `FSUB` | |
50
+ | a*b | `FMUL` | |
51
+ | a/b | `FDIV` | |
52
+ | sqrt(a) | `FSQRT` | |
53
+ | log2(a) | `FYL2X` | |
54
+ | 2^a | > `F2XM1` | See [FIL], chapter 11 |
55
+ | a^b | > `FYL2X` + `F2XM1` + `FMUL` | See [FIL], chapter 11 |
56
+ """
57
+
58
+ # step 1) take geo_mean of all instruction latencies
59
+ lat = {k: v.geo_mean() for k, v in self.latencies.items()}
60
+
61
+ # step 2) convert instruction latencies to estimated flop costs
62
+ I = FPUInstruction
63
+ est_flop_type_latencies = {
64
+ FlopType.ABS: lat[I.FABS],
65
+ FlopType.MINUS: lat[I.FCHS],
66
+ FlopType.EQUALS: lat[I.FCOM],
67
+ FlopType.GTE: lat[I.FCOM],
68
+ FlopType.LTE: lat[I.FCOM],
69
+ FlopType.CMP_ZERO: lat[I.FTST],
70
+ FlopType.RND: lat[I.FRNDINT],
71
+ FlopType.ADD: lat[I.FADD],
72
+ FlopType.SUB: lat[I.FSUB],
73
+ FlopType.MUL: lat[I.FMUL],
74
+ FlopType.DIV: lat[I.FDIV],
75
+ FlopType.SQRT: lat[I.FSQRT],
76
+ FlopType.POW2: lat[I.F2XM1],
77
+ FlopType.LOG2: lat[I.FYL2X],
78
+ FlopType.POW: lat[I.F2XM1] + lat[I.FYL2X] + lat[I.FMUL], # a^b = 2^(b*log2(a))
79
+ }
80
+
81
+ # step 3) convert to normalized FlopWeights by using a few simple flop types as reference (see FlopWeights)
82
+ return FlopWeights.from_abs_flop_costs(est_flop_type_latencies)
83
+
84
+ # -------------------------------------------------------------------------
85
+ # Validation
86
+ # -------------------------------------------------------------------------
87
+ @field_validator("latencies")
88
+ @classmethod
89
+ def check_all_instructions_present(cls, v: dict[FPUInstruction, Latency]) -> dict[FPUInstruction, Latency]:
90
+ # make sure all FPUInstruction enum members are present
91
+ missing = [member for member in FPUInstruction if member not in v]
92
+ if missing:
93
+ raise ValueError(f"Missing latencies for FPU instructions: {missing}")
94
+ return v
File without changes
File without changes
@@ -0,0 +1,103 @@
1
+ {
2
+ "system_info": {
3
+ "platform_processor": "arm",
4
+ "platform_machine": "arm64",
5
+ "platform_system": "Darwin",
6
+ "platform_release": "24.5.0",
7
+ "platform_python_version": "3.13.5",
8
+ "platform_python_implementation": "CPython",
9
+ "platform_python_compiler": "Clang 20.1.4 ",
10
+ "psutil_cpu_count_logical": 16,
11
+ "psutil_cpu_count_physical": 16
12
+ },
13
+ "benchmark_settings": {
14
+ "array_size": 1000,
15
+ "n_runs_total": 30,
16
+ "n_runs_warmup": 10,
17
+ "n_seconds_per_run_target": 0.5
18
+ },
19
+ "results_ns": {
20
+ "baseline": {
21
+ "q25": 180.70256378127044,
22
+ "q50": 181.9446176139497,
23
+ "q75": 183.10434616173248
24
+ },
25
+ "flops": {
26
+ "abs(x)": {
27
+ "q25": 284.28075017907906,
28
+ "q50": 292.3296343924162,
29
+ "q75": 296.61165546013325
30
+ },
31
+ "x>=0": {
32
+ "q25": 300.14336262601694,
33
+ "q50": 303.58112640145805,
34
+ "q75": 306.1948869947011
35
+ },
36
+ "round(x)": {
37
+ "q25": 298.31250819549473,
38
+ "q50": 304.39334992215333,
39
+ "q75": 311.7635501410813
40
+ },
41
+ "-x": {
42
+ "q25": 314.0143053880841,
43
+ "q50": 318.967762723343,
44
+ "q75": 325.5434245996779
45
+ },
46
+ "x==y": {
47
+ "q25": 319.24691665128887,
48
+ "q50": 322.4171760496964,
49
+ "q75": 327.6530252090009
50
+ },
51
+ "x>=y": {
52
+ "q25": 314.5796205515281,
53
+ "q50": 325.89943547082476,
54
+ "q75": 334.41104676760983
55
+ },
56
+ "x<=y": {
57
+ "q25": 318.20367539805585,
58
+ "q50": 321.12704488008126,
59
+ "q75": 329.7065581012761
60
+ },
61
+ "x+y": {
62
+ "q25": 312.08389463997486,
63
+ "q50": 319.3948649650657,
64
+ "q75": 326.92923334349905
65
+ },
66
+ "x-y": {
67
+ "q25": 313.18114328243973,
68
+ "q50": 320.7397985073316,
69
+ "q75": 330.6903906826164
70
+ },
71
+ "x*y": {
72
+ "q25": 316.74533056524433,
73
+ "q50": 321.116820553393,
74
+ "q75": 327.94291060846274
75
+ },
76
+ "sqrt(x)": {
77
+ "q25": 432.3789304009608,
78
+ "q50": 436.45438936204613,
79
+ "q75": 440.62596066215315
80
+ },
81
+ "x/y": {
82
+ "q25": 481.98645275049824,
83
+ "q50": 482.9500509728068,
84
+ "q75": 487.07500098437885
85
+ },
86
+ "2^x": {
87
+ "q25": 1772.9965944238375,
88
+ "q50": 1775.0265760379637,
89
+ "q75": 1780.0759553768837
90
+ },
91
+ "log2(x)": {
92
+ "q25": 2149.927421080074,
93
+ "q50": 2160.9350300536785,
94
+ "q75": 2175.8008708926454
95
+ },
96
+ "x^y": {
97
+ "q25": 6551.587641746191,
98
+ "q50": 6571.279149427383,
99
+ "q75": 6581.455023997079
100
+ }
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,103 @@
1
+ {
2
+ "system_info": {
3
+ "platform_processor": "Intel64 Family 6 Model 142 Stepping 9, GenuineIntel",
4
+ "platform_machine": "AMD64",
5
+ "platform_system": "Windows",
6
+ "platform_release": "10",
7
+ "platform_python_version": "3.11.7",
8
+ "platform_python_implementation": "CPython",
9
+ "platform_python_compiler": "MSC v.1916 64 bit (AMD64)",
10
+ "psutil_cpu_count_logical": 4,
11
+ "psutil_cpu_count_physical": 2
12
+ },
13
+ "benchmark_settings": {
14
+ "array_size": 1000,
15
+ "n_runs_total": 30,
16
+ "n_runs_warmup": 10,
17
+ "n_seconds_per_run_target": 0.5
18
+ },
19
+ "results_ns": {
20
+ "baseline": {
21
+ "q25": 1211.1493417753495,
22
+ "q50": 1307.2530382631453,
23
+ "q75": 1391.3488203907768
24
+ },
25
+ "flops": {
26
+ "abs(x)": {
27
+ "q25": 1623.6614903570153,
28
+ "q50": 2170.525467066671,
29
+ "q75": 2724.9706170025684
30
+ },
31
+ "x>=0": {
32
+ "q25": 1539.4815340210503,
33
+ "q50": 1718.7036334858058,
34
+ "q75": 1827.9410638004579
35
+ },
36
+ "round(x)": {
37
+ "q25": 1457.0065953300357,
38
+ "q50": 1558.30311733864,
39
+ "q75": 1676.8450343779364
40
+ },
41
+ "-x": {
42
+ "q25": 1488.868161557058,
43
+ "q50": 1653.2690554752812,
44
+ "q75": 2280.2974533618644
45
+ },
46
+ "x==y": {
47
+ "q25": 1655.6262344708268,
48
+ "q50": 1830.172356557723,
49
+ "q75": 2088.9087756789663
50
+ },
51
+ "x>=y": {
52
+ "q25": 1655.6262344708268,
53
+ "q50": 1830.172356557723,
54
+ "q75": 2088.9087756789663
55
+ },
56
+ "x<=y": {
57
+ "q25": 1655.6262344708268,
58
+ "q50": 1830.172356557723,
59
+ "q75": 2088.9087756789663
60
+ },
61
+ "x+y": {
62
+ "q25": 1828.5074110467942,
63
+ "q50": 1974.5484596185097,
64
+ "q75": 2606.3806091903493
65
+ },
66
+ "x-y": {
67
+ "q25": 2567.297889164987,
68
+ "q50": 2764.450908060443,
69
+ "q75": 2965.6867371143035
70
+ },
71
+ "x*y": {
72
+ "q25": 1938.423746030986,
73
+ "q50": 2426.1415206122474,
74
+ "q75": 2827.0604978328874
75
+ },
76
+ "sqrt(x)": {
77
+ "q25": 2796.6202473232133,
78
+ "q50": 3066.6651003148763,
79
+ "q75": 3364.2090685415774
80
+ },
81
+ "x/y": {
82
+ "q25": 3163.277772962583,
83
+ "q50": 3299.2498172624,
84
+ "q75": 3442.890645108403
85
+ },
86
+ "2^x": {
87
+ "q25": 5315.585060615009,
88
+ "q50": 5658.201618089246,
89
+ "q75": 5906.3237367433785
90
+ },
91
+ "log2(x)": {
92
+ "q25": 7495.219774272615,
93
+ "q50": 8732.827433259092,
94
+ "q75": 9181.92753987244
95
+ },
96
+ "x^y": {
97
+ "q25": 13072.297712832518,
98
+ "q50": 13953.353992510196,
99
+ "q75": 14935.083207864303
100
+ }
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,103 @@
1
+ {
2
+ "system_info": {
3
+ "platform_processor": "x86_64",
4
+ "platform_machine": "x86_64",
5
+ "platform_system": "Linux",
6
+ "platform_release": "5.15.0-94-generic",
7
+ "platform_python_version": "3.11.7",
8
+ "platform_python_implementation": "CPython",
9
+ "platform_python_compiler": "GCC 11.2.0",
10
+ "psutil_cpu_count_logical": 12,
11
+ "psutil_cpu_count_physical": 10
12
+ },
13
+ "benchmark_settings": {
14
+ "array_size": 1000,
15
+ "n_runs_total": 30,
16
+ "n_runs_warmup": 10,
17
+ "n_seconds_per_run_target": 0.5
18
+ },
19
+ "results_ns": {
20
+ "baseline": {
21
+ "q25": 235.7368871299203,
22
+ "q50": 239.26947187715905,
23
+ "q75": 250.43910989369024
24
+ },
25
+ "flops": {
26
+ "abs(x)": {
27
+ "q25": 326.23165256790696,
28
+ "q50": 341.8612340923687,
29
+ "q75": 350.5939730837959
30
+ },
31
+ "x>=0": {
32
+ "q25": 345.9860542847383,
33
+ "q50": 358.6503587550384,
34
+ "q75": 375.0537641284386
35
+ },
36
+ "round(x)": {
37
+ "q25": 605.9442359172265,
38
+ "q50": 612.7025683853096,
39
+ "q75": 620.0276949348317
40
+ },
41
+ "-x": {
42
+ "q25": 315.60999507080516,
43
+ "q50": 339.95131526516184,
44
+ "q75": 354.72383671394783
45
+ },
46
+ "x==y": {
47
+ "q25": 346.00513584372237,
48
+ "q50": 357.30622388854283,
49
+ "q75": 381.494968611982
50
+ },
51
+ "x>=y": {
52
+ "q25": 346.00513584372237,
53
+ "q50": 357.30622388854283,
54
+ "q75": 381.494968611982
55
+ },
56
+ "x<=y": {
57
+ "q25": 346.00513584372237,
58
+ "q50": 357.30622388854283,
59
+ "q75": 381.494968611982
60
+ },
61
+ "x+y": {
62
+ "q25": 313.6741648425307,
63
+ "q50": 319.53220110357825,
64
+ "q75": 327.70202468480556
65
+ },
66
+ "x-y": {
67
+ "q25": 311.7566818406692,
68
+ "q50": 336.3151218017174,
69
+ "q75": 348.1148053939487
70
+ },
71
+ "x*y": {
72
+ "q25": 319.8723732623861,
73
+ "q50": 327.4367509736013,
74
+ "q75": 335.91731357456
75
+ },
76
+ "sqrt(x)": {
77
+ "q25": 841.512485126231,
78
+ "q50": 844.3625917757934,
79
+ "q75": 853.6490636271077
80
+ },
81
+ "x/y": {
82
+ "q25": 1045.5432577829022,
83
+ "q50": 1063.5378522257229,
84
+ "q75": 1075.5049646159168
85
+ },
86
+ "2^x": {
87
+ "q25": 2193.125961022153,
88
+ "q50": 2200.297127195724,
89
+ "q75": 2211.858485396869
90
+ },
91
+ "log2(x)": {
92
+ "q25": 4101.653464795643,
93
+ "q50": 4128.668137169114,
94
+ "q75": 4285.959186784487
95
+ },
96
+ "x^y": {
97
+ "q25": 8503.688381994434,
98
+ "q50": 8536.172727211253,
99
+ "q75": 8557.370575449291
100
+ }
101
+ }
102
+ }
103
+ }
File without changes
@@ -0,0 +1,52 @@
1
+ {
2
+ "latencies": {
3
+ "FABS": {
4
+ "min_cycles": 1,
5
+ "max_cycles": 1
6
+ },
7
+ "FCHS": {
8
+ "min_cycles": 1,
9
+ "max_cycles": 1
10
+ },
11
+ "FCOM": {
12
+ "min_cycles": 7,
13
+ "max_cycles": 7
14
+ },
15
+ "FTST": {
16
+ "min_cycles": 7,
17
+ "max_cycles": 7
18
+ },
19
+ "FRNDINT": {
20
+ "min_cycles": 5,
21
+ "max_cycles": 5
22
+ },
23
+ "FADD": {
24
+ "min_cycles": 7,
25
+ "max_cycles": 7
26
+ },
27
+ "FSUB": {
28
+ "min_cycles": 7,
29
+ "max_cycles": 7
30
+ },
31
+ "FMUL": {
32
+ "min_cycles": 7,
33
+ "max_cycles": 7
34
+ },
35
+ "FDIV": {
36
+ "min_cycles": 15,
37
+ "max_cycles": 15
38
+ },
39
+ "FSQRT": {
40
+ "min_cycles": 25,
41
+ "max_cycles": 25
42
+ },
43
+ "F2XM1": {
44
+ "min_cycles": 50,
45
+ "max_cycles": 60
46
+ },
47
+ "FYL2X": {
48
+ "min_cycles": 40,
49
+ "max_cycles": 60
50
+ }
51
+ }
52
+ }