counted-float 0.9.5__tar.gz → 0.9.7__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.
Files changed (101) hide show
  1. counted_float-0.9.7/PKG-INFO +637 -0
  2. counted_float-0.9.7/README.md +616 -0
  3. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/__init__.py +1 -11
  4. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/_cli.py +3 -2
  5. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/benchmarking/__init__.py +2 -2
  6. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/benchmarking/flops/__init__.py +1 -1
  7. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/benchmarking/flops/_flops_benchmark_suite.py +3 -3
  8. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/benchmarking/micro/_micro_benchmark.py +8 -4
  9. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/counting/_builtin_data.py +16 -13
  10. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/counting/config/_defaults.py +13 -8
  11. counted_float-0.9.7/counted_float/_core/models/__init__.py +9 -0
  12. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/models/_flop_weights.py +20 -8
  13. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/models/_flops_benchmark_meta_data.py +6 -4
  14. counted_float-0.9.5/counted_float/_core/models/_flops_benchmark_result_v2.py → counted_float-0.9.7/counted_float/_core/models/_flops_benchmark_result.py +1 -1
  15. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/models/_instruction_latencies.py +36 -47
  16. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/utils/__init__.py +2 -0
  17. counted_float-0.9.7/counted_float/_core/utils/_cpu_freq.py +46 -0
  18. counted_float-0.9.7/counted_float/_core/utils/_latency.py +3 -0
  19. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/utils/_missing_data.py +5 -1
  20. counted_float-0.9.7/counted_float/_core/utils/_rounding.py +66 -0
  21. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/benchmarking/__init__.py +2 -2
  22. counted_float-0.9.7/counted_float/data/arm/v8_x/benchmarks/apple_m3_max_mbp16.json +196 -0
  23. counted_float-0.9.7/counted_float/data/arm/v8_x/benchmarks/apple_m3_mba15.json +196 -0
  24. counted_float-0.9.7/counted_float/data/arm/v8_x/benchmarks/ec2_m6g_xlarge_graviton_2_neoverse_n1.json +196 -0
  25. counted_float-0.9.7/counted_float/data/arm/v8_x/benchmarks/ec2_m7g_xlarge_graviton_3_neoverse_v1.json +196 -0
  26. counted_float-0.9.7/counted_float/data/arm/v8_x/benchmarks/gh_apple_m1.json +196 -0
  27. counted_float-0.9.7/counted_float/data/arm/v9_0/benchmarks/ec2_m8g_xlarge_graviton_4_neoverse_v2.json +196 -0
  28. counted_float-0.9.7/counted_float/data/arm/v9_0/benchmarks/gh_azure_cobalt_100_neoverse_n2.json +196 -0
  29. counted_float-0.9.7/counted_float/data/arm/v9_2/benchmarks/apple_m4_pro_mbp16.json +196 -0
  30. counted_float-0.9.7/counted_float/data/x86/amd/2017_zen1/benchmark_ryzen_1700x.json +196 -0
  31. counted_float-0.9.7/counted_float/data/x86/amd/2020_zen3/benchmark_gh_amd_epyc_7763_linux.json +196 -0
  32. counted_float-0.9.7/counted_float/data/x86/amd/2020_zen3/benchmark_gh_amd_epyc_7763_windows.json +196 -0
  33. counted_float-0.9.7/counted_float/data/x86/amd/2022_zen4/benchmark_ec2_m7a_xlarge_zen4.json +196 -0
  34. counted_float-0.9.7/counted_float/data/x86/amd/2024_zen5/benchmark_ec2_m8a_xlarge_zen5.json +196 -0
  35. counted_float-0.9.7/counted_float/data/x86/intel/2017_coffee_lake_gen_8/benchmark_gh_intel_i7_8700B_macos.json +196 -0
  36. counted_float-0.9.7/counted_float/data/x86/intel/2017_coffee_lake_gen_8/benchmark_intel_i7_8550U_windows.json +196 -0
  37. counted_float-0.9.7/counted_float/data/x86/intel/2019_sunny_cove_gen_10/benchmark_ec2_m6i_xlarge_ice_lake.json +196 -0
  38. counted_float-0.9.7/counted_float/data/x86/intel/2021_golden_cove_gen_12/benchmark_ec2_m7i_xlarge_sapphire_rapids.json +196 -0
  39. counted_float-0.9.7/counted_float/data/x86/intel/2022_raptor_cove_gen_13_14/benchmark_ec2_i7i_xlarge_emerald_rapids.json +196 -0
  40. counted_float-0.9.7/counted_float/data/x86/intel/2023_redwood_cove_ultra_1/benchmark_ec2_m8i_xlarge_granite_rapids.json +196 -0
  41. {counted_float-0.9.5 → counted_float-0.9.7}/pyproject.toml +1 -1
  42. counted_float-0.9.5/PKG-INFO +0 -608
  43. counted_float-0.9.5/README.md +0 -587
  44. counted_float-0.9.5/counted_float/_core/models/__init__.py +0 -18
  45. counted_float-0.9.5/counted_float/_core/models/_flops_benchmark_result_v1.py +0 -42
  46. counted_float-0.9.5/counted_float/_core/utils/_latency.py +0 -3
  47. counted_float-0.9.5/counted_float/data/arm/v8_x/benchmarks/m3_max_macbook_pro_16.json +0 -106
  48. counted_float-0.9.5/counted_float/data/arm/v8_x/benchmarks/m3_max_macbook_pro_16_v2.json +0 -196
  49. counted_float-0.9.5/counted_float/data/x86/amd/2017_zen1/benchmark_ryzen_1700x.json +0 -106
  50. counted_float-0.9.5/counted_float/data/x86/intel/2021_golden_cove_gen_12/benchmark_core_i7_1265u.json +0 -106
  51. {counted_float-0.9.5 → counted_float-0.9.7}/.gitignore +0 -0
  52. {counted_float-0.9.5 → counted_float-0.9.7}/LICENSE +0 -0
  53. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/__init__.py +0 -0
  54. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/benchmarking/flops/_array_generator.py +0 -0
  55. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/benchmarking/flops/_flops_micro_benchmark.py +0 -0
  56. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/benchmarking/micro/__init__.py +0 -0
  57. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/compatibility/__init__.py +0 -0
  58. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/compatibility/_numba.py +0 -0
  59. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/counting/__init__.py +0 -0
  60. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/counting/_context_managers.py +0 -0
  61. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/counting/_counted_float.py +0 -0
  62. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/counting/_global_counter.py +0 -0
  63. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/counting/config/__init__.py +0 -0
  64. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/counting/config/_config.py +0 -0
  65. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/models/_base.py +0 -0
  66. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/models/_flop_counts.py +0 -0
  67. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/models/_flop_type.py +0 -0
  68. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/models/_flops_benchmark_type.py +0 -0
  69. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/models/_micro_benchmark_result.py +0 -0
  70. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/utils/_formatting.py +0 -0
  71. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/utils/_geo_mean.py +0 -0
  72. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/_core/utils/_timer.py +0 -0
  73. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/config/__init__.py +0 -0
  74. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/arm/v8_x/specs/arm_v8_cortex_a76.json +0 -0
  75. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/arm/v8_x/specs/arm_v9_cortex_x1.json +0 -0
  76. /counted_float-0.9.5/counted_float/data/arm/v8_x/specs/arm_v9_cortex_n1.json → /counted_float-0.9.7/counted_float/data/arm/v8_x/specs/arm_v9_neoverse_n1.json +0 -0
  77. /counted_float-0.9.5/counted_float/data/arm/v8_x/specs/arm_v9_cortex_v1.json → /counted_float-0.9.7/counted_float/data/arm/v8_x/specs/arm_v9_neoverse_v1.json +0 -0
  78. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/arm/v9_0/specs/arm_v9_cortex_x2.json +0 -0
  79. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/arm/v9_0/specs/arm_v9_cortex_x3.json +0 -0
  80. /counted_float-0.9.5/counted_float/data/arm/v9_0/specs/arm_v9_cortex_n2.json → /counted_float-0.9.7/counted_float/data/arm/v9_0/specs/arm_v9_neoverse_n2.json +0 -0
  81. /counted_float-0.9.5/counted_float/data/arm/v9_0/specs/arm_v9_cortex_v2.json → /counted_float-0.9.7/counted_float/data/arm/v9_0/specs/arm_v9_neoverse_v2.json +0 -0
  82. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/arm/v9_2/specs/arm_v9_cortex_x4.json +0 -0
  83. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/arm/v9_2/specs/arm_v9_cortex_x925.json +0 -0
  84. /counted_float-0.9.5/counted_float/data/arm/v9_2/specs/arm_v9_cortex_v3.json → /counted_float-0.9.7/counted_float/data/arm/v9_2/specs/arm_v9_neoverse_v3.json +0 -0
  85. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/amd/2017_zen1/analysis_uops_info_zen1+.json +0 -0
  86. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/amd/2020_zen3/analysis_agner_fog_r7_5800x.json +0 -0
  87. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/amd/2020_zen3/analysis_uops_info_zen3.json +0 -0
  88. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/amd/2022_zen4/analysis_agner_fog_r9_7900x.json +0 -0
  89. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/amd/2022_zen4/analysis_uops_info_zen4.json +0 -0
  90. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/amd/2022_zen4/specs_amd.json +0 -0
  91. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/amd/2024_zen5/analysis_agner_fog_r7_9800x3d.json +0 -0
  92. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/amd/2024_zen5/specs_amd.json +0 -0
  93. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/intel/2017_coffee_lake_gen_8/analysis_agner_fog_coffee_lake.json +0 -0
  94. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/intel/2017_coffee_lake_gen_8/analysis_uops_info_coffee_lake.json +0 -0
  95. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/intel/2019_sunny_cove_gen_10/analysis_agner_fog_ice_lake.json +0 -0
  96. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/intel/2019_sunny_cove_gen_10/analysis_uops_info_ice_lake.json +0 -0
  97. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/intel/2019_sunny_cove_gen_10/analysis_uops_info_tiger_lake.json +0 -0
  98. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/intel/2021_golden_cove_gen_12/analysis_uops_info_alder_lake_p.json +0 -0
  99. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/intel/2021_golden_cove_gen_12/specs_intel.json +0 -0
  100. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/intel/2022_raptor_cove_gen_13_14/specs_intel.json +0 -0
  101. {counted_float-0.9.5 → counted_float-0.9.7}/counted_float/data/x86/intel/2023_redwood_cove_ultra_1/specs_intel.json +0 -0
@@ -0,0 +1,637 @@
1
+ Metadata-Version: 2.4
2
+ Name: counted-float
3
+ Version: 0.9.7
4
+ Summary: Count floating-point operations in Python code & benchmark relative flop costs.
5
+ Project-URL: Source, https://github.com/bertpl/counted-float
6
+ Project-URL: ChangeLog, https://github.com/bertpl/counted-float/blob/develop/CHANGELOG.md
7
+ Project-URL: Issues, https://github.com/bertpl/counted-float/issues
8
+ Project-URL: Roadmap, https://github.com/bertpl/counted-float/milestones
9
+ License-File: LICENSE
10
+ Requires-Python: >=3.11
11
+ Requires-Dist: numpy>=1.20
12
+ Requires-Dist: psutil>=5.0
13
+ Requires-Dist: py-cpuinfo>=9.0.0
14
+ Requires-Dist: pydantic>=2.0.0
15
+ Requires-Dist: rich>=13.0.0
16
+ Provides-Extra: cli
17
+ Requires-Dist: click>=8.0.0; extra == 'cli'
18
+ Provides-Extra: numba
19
+ Requires-Dist: numba>=0.50; extra == 'numba'
20
+ Description-Content-Type: text/markdown
21
+
22
+ <!--START_SECTION:images-->
23
+ ![shields.io-python-versions](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue)
24
+ ![genbadge-test-count](https://bertpl.github.io/counted-float/version_artifacts/v0.9.7/badge-test-count.svg)
25
+ ![genbadge-test-coverage](https://bertpl.github.io/counted-float/version_artifacts/v0.9.7/badge-coverage.svg)
26
+ ![counted_float logo](https://bertpl.github.io/counted-float/version_artifacts/v0.9.7/splash.webp)
27
+ <!--END_SECTION:images-->
28
+
29
+ # counted-float
30
+
31
+ This Python package provides functionality for...
32
+ - **counting floating point operations** (FLOPs) of numerical algorithms implemented in plain Python, optionally weighted by their relative cost of execution
33
+ - **running benchmarks** to estimate the relative cost of executing various floating-point operations (requires `numba` optional dependency for achieving accurate results)
34
+
35
+ The target application area is evaluation of research prototypes of numerical algorithms where (weighted) flop counting can be
36
+ useful for estimating total computational cost, in cases where benchmarking a compiled version (C, Rust, ...) is not
37
+ feasible or desirable.
38
+
39
+ Flop weights are computed using a highly curated dataset spanning a wide range of modern CPUs:
40
+ - 19 benchmarks, 16 spec sheets, 12 third party measurements (Agner Fog, uops.info)
41
+ - covering x86 (Intel, AMD) and ARM (Apple, AWS, Azure) architectures
42
+
43
+ # 1. Installation
44
+
45
+ Use you favorite package manager such as `uv` or `pip`:
46
+
47
+ ```
48
+ pip install counted-float # install without numba optional dependency
49
+ pip install counted-float[numba] # install with numba optional dependency
50
+ ```
51
+ Numba is optional due to its relatively large size (40-50MB, including llvmlite), but without it, benchmarks will
52
+ not be reliable (but will still run, but not in jit-compiled form).
53
+
54
+ NOTE: the `cli` optional dependency is only useful when installing the code as a tool using e.g. `uv` or `pipx` (see below)
55
+
56
+ # 2. Counting Flops
57
+
58
+ ## 2.1. CountedFloat class
59
+
60
+ In order to instrument all floating point operations with counting functionality,
61
+ the `CountedFloat` class was implemented, which is a drop-in replacement for the built-in `float` type.
62
+ The `CountedFloat` class is a subclass of `float` and is "contagious", meaning that it will automatically
63
+ ensure results of math operations where at least one operand is a `CountedFloat` will also be a `CountedFloat`.
64
+ This way we ensure flop counting is a 'closed system'.
65
+
66
+ On top of this, we monkey-patch the `math` module to ensure that all math operations
67
+ that require counting (`sqrt`, `log2`, `pow`, ...) are also instrumented.
68
+
69
+ **Example 1**:
70
+
71
+ ```python
72
+ from counted_float import CountedFloat
73
+
74
+ cf = CountedFloat(1.3)
75
+ f = 2.8
76
+
77
+ result = cf + f # result = CountedFloat(4.1)
78
+
79
+ is_float_1 = isinstance(cf, float) # True
80
+ is_float_2 = isinstance(result, float) # True
81
+ ```
82
+
83
+ **Example 2**:
84
+
85
+ ```python
86
+ import math
87
+ from counted_float import CountedFloat
88
+
89
+ cf1 = CountedFloat(0.81)
90
+
91
+ s = math.sqrt(cf1) # s = CountedFloat(0.9)
92
+ is_float = isinstance(s, float) # True
93
+ ```
94
+
95
+ ## 2.2. FLOP counting context managers
96
+
97
+ Once we use the `CountedFloat` class, we can use the available context managers to count the number of
98
+ flops performed by `CountedFloat` objects.
99
+
100
+ **Example 1**: _basic usage_
101
+ ```python
102
+ from counted_float import CountedFloat, FlopCountingContext
103
+
104
+ cf1 = CountedFloat(1.73)
105
+ cf2 = CountedFloat(2.94)
106
+
107
+ with FlopCountingContext() as ctx:
108
+ _ = cf1 * cf2
109
+ _ = cf1 + cf2
110
+
111
+ counts = ctx.flop_counts() # {FlopType.MUL: 1, FlopType.ADD: 1}
112
+ counts.total_count() # 2
113
+ ```
114
+
115
+ **Example 2**: _pause counting 1_
116
+
117
+ ```python
118
+ from counted_float import CountedFloat, FlopCountingContext
119
+
120
+ cf1 = CountedFloat(1.73)
121
+ cf2 = CountedFloat(2.94)
122
+
123
+ with FlopCountingContext() as ctx:
124
+ _ = cf1 * cf2
125
+ ctx.pause()
126
+ _ = cf1 + cf2 # will be executed but not counted
127
+ ctx.resume()
128
+ _ = cf1 - cf2
129
+
130
+ counts = ctx.flop_counts() # {FlopType.MUL: 1, FlopType.SUB: 1}
131
+ counts.total_count() # 2
132
+ ```
133
+
134
+ **Example 3**: _pause counting 2_
135
+
136
+ ```python
137
+ from counted_float import CountedFloat, FlopCountingContext, PauseFlopCounting
138
+
139
+ cf1 = CountedFloat(1.73)
140
+ cf2 = CountedFloat(2.94)
141
+
142
+ with FlopCountingContext() as ctx:
143
+ _ = cf1 * cf2
144
+ with PauseFlopCounting():
145
+ _ = cf1 + cf2 # will be executed but not counted
146
+ _ = cf1 - cf2
147
+
148
+ counts = ctx.flop_counts() # {FlopType.MUL: 1, FlopType.SUB: 1}
149
+ counts.total_count() # 2
150
+ ```
151
+
152
+ ## 2.3. Weighted FLOP counting
153
+
154
+ The `counted_float` package contains a set of default, built-in FLOP weights, based on both empirical measurements
155
+ and theoretical estimates of the relative cost of different floating point operations.
156
+
157
+ See [fpu_data_sources.md](https://github.com/bertpl/counted-float/tree/develop/docs/analysis_methodology.md) for
158
+ rationale behind choice of data sources and methodology.
159
+
160
+ ```
161
+ >>> from counted_float.config import get_active_flop_weights
162
+ >>> get_active_flop_weights().show()
163
+
164
+ {
165
+ FlopType.MINUS [-x] : 0.45000
166
+ FlopType.ABS [abs(x)] : 0.70000
167
+ FlopType.ADD [x+y] : 1.00000
168
+ FlopType.COMP [x<=y] : 1.00000
169
+ FlopType.SUB [x-y] : 1.00000
170
+ FlopType.MUL [x*y] : 1.40000
171
+ FlopType.RND [round] : 1.80000
172
+ FlopType.F2I [float->int] : 2.00000
173
+ FlopType.I2F [int->float] : 2.00000
174
+ FlopType.DIV [x/y] : 5.50000
175
+ FlopType.SQRT [sqrt(x)] : 7.50000
176
+ FlopType.EXP2 [2^x] : 16.00000
177
+ FlopType.EXP [e^x] : 18.00000
178
+ FlopType.LOG [log(x)] : 20.00000
179
+ FlopType.LOG2 [log2(x)] : 22.00000
180
+ FlopType.EXP10 [10^x] : 24.00000
181
+ FlopType.LOG10 [log10(x)] : 24.00000
182
+ FlopType.COS [cos(x)] : 30.00000
183
+ FlopType.SIN [sin(x)] : 30.00000
184
+ FlopType.POW [x^y] : 40.00000
185
+ FlopType.TAN [tan(x)] : 40.00000
186
+ FlopType.CBRT [cbrt(x)] : 45.00000
187
+ }
188
+ ```
189
+ Note that these weights are rounded up to the ~10% closest semi-round number, reflecting a balance between accuracy and readability,
190
+ while conveying the message that these weights should be used as approximations only. See further down for the different rounding modes.
191
+
192
+ These weights will be used by default when extracting total weighted flop costs:
193
+
194
+ ```python
195
+ import math
196
+ from counted_float import CountedFloat, FlopCountingContext
197
+
198
+
199
+ cf1 = CountedFloat(1.73)
200
+ cf2 = CountedFloat(2.94)
201
+
202
+ with FlopCountingContext() as ctx:
203
+ _ = cf1 + cf2
204
+ _ = cf1 ** cf2
205
+ _ = math.log2(cf2)
206
+
207
+ flop_counts = ctx.flop_counts()
208
+ total_cost = flop_counts.total_weighted_cost() # 1 + 40 + 22 = 63
209
+ ```
210
+ Note that the `total_weighted_cost` method will use the default flop weights as returned by `get_flop_weights()`. This can be
211
+ overridden by either configuring different flop weights (see next section) or by setting the `weights` argument of the `total_weighted_cost()` method.
212
+
213
+
214
+ ## 2.4. Configuring FLOP weights
215
+
216
+ We showed earlier that the `get_flop_weights()` function returns the default FLOP weights. We can change this by
217
+ using the `set_flop_weights()` function, which takes a `FlopWeights` object as an argument. This way we can configure
218
+ flop weights that might be obtained using benchmarks run on the target hardware (see later sections).
219
+
220
+ ```python
221
+ from counted_float.config import set_active_flop_weights
222
+ from counted_float import FlopWeights
223
+
224
+ set_active_flop_weights(weights=FlopWeights(...)) # insert own weights here
225
+ ```
226
+ ## 2.5. Inspecting built-in data
227
+
228
+ ### 2.5.1. Default, pre-aggregated flop weights
229
+
230
+ Built-in flop weights can be inspected using the following functions:
231
+
232
+ ```python
233
+ from counted_float.config import get_default_consensus_flop_weights
234
+
235
+ >>> get_default_consensus_flop_weights(rounding_mode=None).show()
236
+
237
+ {
238
+ FlopType.MINUS [-x] : 0.46773
239
+ FlopType.ABS [abs(x)] : 0.70012
240
+ FlopType.COMP [x<=y] : 0.96923
241
+ FlopType.SUB [x-y] : 0.99846
242
+ FlopType.ADD [x+y] : 1.00000
243
+ FlopType.MUL [x*y] : 1.39950
244
+ FlopType.RND [round] : 1.77232
245
+ FlopType.F2I [float->int] : 1.91485
246
+ FlopType.I2F [int->float] : 1.92200
247
+ FlopType.DIV [x/y] : 5.53105
248
+ FlopType.SQRT [sqrt(x)] : 7.35657
249
+ FlopType.EXP2 [2^x] : 15.85687
250
+ FlopType.EXP [e^x] : 17.51909
251
+ FlopType.LOG [log(x)] : 19.00419
252
+ FlopType.LOG2 [log2(x)] : 22.38002
253
+ FlopType.EXP10 [10^x] : 23.02693
254
+ FlopType.LOG10 [log10(x)] : 24.65718
255
+ FlopType.SIN [sin(x)] : 30.40612
256
+ FlopType.COS [cos(x)] : 31.39434
257
+ FlopType.POW [x^y] : 41.81031
258
+ FlopType.TAN [tan(x)] : 42.15636
259
+ FlopType.CBRT [cbrt(x)] : 44.32376
260
+ }
261
+ ```
262
+ There are 3 rounding modes:
263
+ - `None` -> no rounding
264
+ - `"nearest_int"` -> round up/down to nearest integer, with a minimum of 1
265
+ - `"10%"` -> round to nearest semi-round number within ~10% (default)
266
+
267
+
268
+ The default weights that are configured out-of-the-box in the package are the integer-rounded `consensus` weights.
269
+
270
+ ### 2.5.2. Custom-aggregated flop weights
271
+
272
+ We can retrieve built-in flop weights in a more fine-grained manner, by custom filtering and the aggregating them with
273
+ the geometric mean.
274
+
275
+ ```python
276
+ from counted_float.config import get_builtin_flop_weights
277
+
278
+ >>> get_builtin_flop_weights(key_filter="arm").show()
279
+
280
+ {
281
+ FlopType.COMP [x<=y] : 0.65000
282
+ FlopType.MINUS [-x] : 0.90000
283
+ FlopType.ADD [x+y] : 1.00000
284
+ FlopType.SUB [x-y] : 1.00000
285
+ FlopType.ABS [abs(x)] : 1.10000
286
+ FlopType.F2I [float->int] : 1.50000
287
+ FlopType.MUL [x*y] : 1.50000
288
+ FlopType.I2F [int->float] : 1.60000
289
+ FlopType.RND [round] : 1.60000
290
+ FlopType.DIV [x/y] : 6.00000
291
+ FlopType.SQRT [sqrt(x)] : 7.50000
292
+ FlopType.EXP2 [2^x] : 16.00000
293
+ FlopType.EXP [e^x] : 18.00000
294
+ FlopType.LOG [log(x)] : 20.00000
295
+ FlopType.LOG2 [log2(x)] : 20.00000
296
+ FlopType.EXP10 [10^x] : 24.00000
297
+ FlopType.LOG10 [log10(x)] : 24.00000
298
+ FlopType.COS [cos(x)] : 33.00000
299
+ FlopType.SIN [sin(x)] : 33.00000
300
+ FlopType.POW [x^y] : 40.00000
301
+ FlopType.CBRT [cbrt(x)] : 45.00000
302
+ FlopType.TAN [tan(x)] : 45.00000
303
+ }
304
+ ```
305
+
306
+ # 3. Benchmarking
307
+
308
+ If the package is installed with the optional `numba` dependency, it provides the ability to micro-benchmark
309
+ floating point operations as follows:
310
+
311
+ ```
312
+ >>> from counted_float.benchmarking import run_flops_benchmark
313
+ >>> results = run_flops_benchmark()
314
+
315
+ Running FLOPS benchmarks using counted-float 0.9.5 ...
316
+ (Expected duration: ~87.8 seconds)
317
+
318
+ baseline : wwwwwwwwwwwwwww......................... [ 74.43 ns ± 2.6% | 302 cpu cycles ± 2.6% ] / 1000 iterations
319
+ add : wwwwwwwwwwwwwww......................... [ 662.35 ns ± 0.2% | 2.69K cpu cycles ± 0.2% ] / 1000 iterations
320
+ add_minus : wwwwwwwwwwwwwww......................... [ 1.23 µs ± 0.2% | 4.98K cpu cycles ± 0.2% ] / 1000 iterations
321
+ add_abs : wwwwwwwwwwwwwww......................... [ 1.23 µs ± 0.4% | 4.99K cpu cycles ± 0.4% ] / 1000 iterations
322
+ add_add : wwwwwwwwwwwwwww......................... [ 1.29 µs ± 0.2% | 5.23K cpu cycles ± 0.2% ] / 1000 iterations
323
+ add_sub : wwwwwwwwwwwwwww......................... [ 1.29 µs ± 0.2% | 5.23K cpu cycles ± 0.2% ] / 1000 iterations
324
+ add_round : wwwwwwwwwwwwwww......................... [ 1.44 µs ± 0.1% | 5.84K cpu cycles ± 0.1% ] / 1000 iterations
325
+ add_sqrt : wwwwwwwwwwwwwww......................... [ 3.96 µs ± 0.2% | 16.1K cpu cycles ± 0.2% ] / 1000 iterations
326
+ add_cbrt : wwwwwwwwwwwwwww......................... [ 25.42 µs ± 0.2% | 103K cpu cycles ± 0.2% ] / 1000 iterations
327
+ add_log : wwwwwwwwwwwwwww......................... [ 11.69 µs ± 0.3% | 47.4K cpu cycles ± 0.3% ] / 1000 iterations
328
+ add_log_exp : wwwwwwwwwwwwwww......................... [ 22.57 µs ± 0.1% | 91.5K cpu cycles ± 0.1% ] / 1000 iterations
329
+ add_log2 : wwwwwwwwwwwwwww......................... [ 12.00 µs ± 0.2% | 48.7K cpu cycles ± 0.2% ] / 1000 iterations
330
+ add_log2_exp2 : wwwwwwwwwwwwwww......................... [ 22.48 µs ± 0.2% | 91.2K cpu cycles ± 0.2% ] / 1000 iterations
331
+ add_log10 : wwwwwwwwwwwwwww......................... [ 11.50 µs ± 0.2% | 46.6K cpu cycles ± 0.2% ] / 1000 iterations
332
+ add_log10_exp10 : wwwwwwwwwwwwwww......................... [ 24.68 µs ± 0.2% | 100K cpu cycles ± 0.2% ] / 1000 iterations
333
+ add_sin : wwwwwwwwwwwwwww......................... [ 18.64 µs ± 0.3% | 75.6K cpu cycles ± 0.3% ] / 1000 iterations
334
+ add_cos : wwwwwwwwwwwwwww......................... [ 18.92 µs ± 0.3% | 76.7K cpu cycles ± 0.3% ] / 1000 iterations
335
+ add_tan : wwwwwwwwwwwwwww......................... [ 20.91 µs ± 0.2% | 84.8K cpu cycles ± 0.2% ] / 1000 iterations
336
+ pow : wwwwwwwwwwwwwww......................... [ 24.12 µs ± 0.3% | 97.8K cpu cycles ± 0.3% ] / 1000 iterations
337
+ pow_pow : wwwwwwwwwwwwwww......................... [ 48.15 µs ± 0.2% | 195K cpu cycles ± 0.2% ] / 1000 iterations
338
+ sub : wwwwwwwwwwwwwww......................... [ 661.55 ns ± 0.2% | 2.68K cpu cycles ± 0.2% ] / 1000 iterations
339
+ sub_sub : wwwwwwwwwwwwwww......................... [ 1.29 µs ± 0.2% | 5.24K cpu cycles ± 0.2% ] / 1000 iterations
340
+ mul : wwwwwwwwwwwwwww......................... [ 961.78 ns ± 0.2% | 3.90K cpu cycles ± 0.2% ] / 1000 iterations
341
+ mul_mul : wwwwwwwwwwwwwww......................... [ 1.92 µs ± 0.2% | 7.78K cpu cycles ± 0.2% ] / 1000 iterations
342
+ div : wwwwwwwwwwwwwww......................... [ 2.45 µs ± 0.2% | 9.92K cpu cycles ± 0.2% ] / 1000 iterations
343
+ div_div : wwwwwwwwwwwwwww......................... [ 5.00 µs ± 0.2% | 20.3K cpu cycles ± 0.2% ] / 1000 iterations
344
+ lte_addsub : wwwwwwwwwwwwwww......................... [ 1.71 µs ± 0.2% | 6.94K cpu cycles ± 0.2% ] / 1000 iterations
345
+
346
+ >>> results.flop_weights().show()
347
+
348
+ {
349
+ FlopType.ABS [abs(x)] : 0.89904
350
+ FlopType.MINUS [-x] : 0.90935
351
+ FlopType.SUB [x-y] : 0.99676
352
+ FlopType.ADD [x+y] : 1.00000
353
+ FlopType.RND [round] : 1.24397
354
+ FlopType.MUL [x*y] : 1.55516
355
+ FlopType.COMP [x<=y] : 1.69018
356
+ FlopType.DIV [x/y] : 4.12333
357
+ FlopType.SQRT [sqrt(x)] : 5.42419
358
+ FlopType.EXP2 [2^x] : 16.95266
359
+ FlopType.LOG10 [log10(x)] : 17.60079
360
+ FlopType.EXP [e^x] : 17.76250
361
+ FlopType.LOG [log(x)] : 17.86149
362
+ FlopType.LOG2 [log2(x)] : 18.42380
363
+ FlopType.EXP10 [10^x] : 21.50729
364
+ FlopType.SIN [sin(x)] : 29.31571
365
+ FlopType.COS [cos(x)] : 29.56218
366
+ FlopType.TAN [tan(x)] : 32.88570
367
+ FlopType.POW [x^y] : 39.35018
368
+ FlopType.CBRT [cbrt(x)] : 40.16857
369
+ FlopType.F2I [float->int] : nan
370
+ FlopType.I2F [int->float] : nan
371
+ }
372
+ ```
373
+
374
+ ## 4. Installing the package as a command-line tool
375
+
376
+ An alternative way of using (parts) of the functionality is installing the package as a stand-alone command-line tool
377
+ using `uv` or `pipx`:
378
+
379
+ ```
380
+ uv tool install git+https://github.com/bertpl/counted-float@main[numba,cli] # latest official release
381
+ uv tool install git+https://github.com/bertpl/counted-float@develop[numba,cli] # or latest develop version
382
+ ```
383
+ This installs the `counted_float` command-line tool, which can be used to e.g. run flops benchmarks.
384
+
385
+ ## 4.1. Running benchmarks
386
+
387
+ ```
388
+ counted_float benchmark
389
+ ```
390
+ after which the results will be shown as .json.
391
+
392
+ ## 4.2. Show built-in data
393
+
394
+ ```
395
+ [~] counted_float show-data
396
+ MINUS ABS COMP SUB ADD MUL RND F2I I2F DIV SQRT EXP2 EXP LOG LOG2 EXP10 LOG10 SIN COS POW TAN CBRT
397
+ ALL 0.47 0.70 0.97 1.00 1.00 1.40 1.77 1.91 1.92 5.53 7.36 15.86 17.52 19.00 22.38 23.03 24.66 30.41 31.39 41.81 42.16 44.32
398
+ ├─arm 0.89 1.05 0.64 1.01 1.00 1.50 1.61 1.49 1.59 6.15 7.60 15.98 18.57 19.60 20.86 23.30 24.26 32.32 34.08 42.28 42.85 44.97
399
+ │ ├─v8_x 0.83 1.00 0.67 1.01 1.00 1.48 1.50 1.56 1.91 5.90 7.42 15.45 17.86 19.06 20.80 22.92 22.90 32.43 33.47 41.19 42.99 44.71
400
+ │ │ ├─benchmarks 0.70 1.01 0.45 1.01 1.00 1.46 1.50 / / 4.65 6.68 13.93 16.10 17.18 18.75 20.66 20.65 29.23 30.17 37.13 38.76 40.30
401
+ │ │ │ ├─apple_m3_max_mbp16 0.90 0.90 1.64 1.00 1.00 1.40 1.25 / / 4.00 5.28 16.69 17.42 17.59 18.15 21.06 17.31 28.77 29.17 37.93 39.04 39.48
402
+ │ │ │ ├─apple_m3_mba15 0.90 0.90 1.68 1.00 1.00 1.53 1.24 / / 4.06 5.27 16.68 17.43 17.56 18.09 21.07 17.29 28.63 29.06 38.46 32.32 39.43
403
+ │ │ │ ├─ec2_m6g_xlarge_graviton_2_neoverse_n1 0.46 1.47 0.38 1.00 1.00 1.38 2.01 / / 5.42 8.76 10.21 14.17 15.98 17.91 22.65 25.25 28.68 29.63 33.95 41.90 40.25
404
+ │ │ │ ├─ec2_m7g_xlarge_graviton_3_neoverse_v1 0.51 1.00 0.01 1.00 1.00 1.50 1.99 / / 6.03 9.58 11.89 14.81 17.49 19.20 19.09 27.67 30.26 31.49 36.85 42.45 40.96
405
+ │ │ │ └─gh_apple_m1 0.86 0.86 1.73 1.06 1.00 1.48 1.22 / / 4.07 5.70 15.50 16.98 17.33 20.52 19.61 17.95 29.86 31.59 38.67 38.97 41.44
406
+ │ │ └─specs 1.00 1.00 1.00 1.00 1.00 1.50 1.50 1.73 2.12 7.50 8.25 / / / / / / / / / / /
407
+ │ │ ├─arm_v8_cortex_a76 1.00 1.00 1.00 1.00 1.00 1.50 1.50 2.00 3.00 7.50 8.50 / / / / / / / / / / /
408
+ │ │ ├─arm_v9_cortex_x1 1.00 1.00 1.00 1.00 1.00 1.50 1.50 1.50 1.50 7.50 8.00 / / / / / / / / / / /
409
+ │ │ ├─arm_v9_neoverse_n1 1.00 1.00 1.00 1.00 1.00 1.50 1.50 2.00 3.00 7.50 8.50 / / / / / / / / / / /
410
+ │ │ └─arm_v9_neoverse_v1 1.00 1.00 1.00 1.00 1.00 1.50 1.50 1.50 1.50 7.50 8.00 / / / / / / / / / / /
411
+ │ ├─v9_0 0.74 1.00 0.25 1.00 1.00 1.51 1.80 1.27 1.27 6.78 8.83 14.32 17.90 20.66 22.09 24.04 32.41 35.53 37.31 44.86 52.70 48.30
412
+ │ │ ├─benchmarks 0.54 1.00 0.06 1.00 1.00 1.52 2.16 / / 6.14 9.75 12.12 15.15 17.49 18.70 20.35 27.44 30.08 31.59 37.98 44.62 40.89
413
+ │ │ │ ├─ec2_m8g_xlarge_graviton_4_neoverse_v2 0.52 1.00 0.01 1.00 1.00 1.50 2.05 / / 6.04 9.49 12.66 14.40 17.66 18.54 19.86 27.12 28.76 30.11 36.90 42.70 38.65
414
+ │ │ │ └─gh_azure_cobalt_100_neoverse_n2 0.57 1.00 0.33 1.00 1.00 1.53 2.28 / / 6.23 10.02 11.61 15.94 17.33 18.87 20.85 27.76 31.46 33.15 39.09 46.62 43.26
415
+ │ │ └─specs 1.00 1.00 1.00 1.00 1.00 1.50 1.50 1.50 1.50 7.50 8.00 / / / / / / / / / / /
416
+ │ │ ├─arm_v9_cortex_x2 1.00 1.00 1.00 1.00 1.00 1.50 1.50 1.50 1.50 7.50 8.00 / / / / / / / / / / /
417
+ │ │ ├─arm_v9_cortex_x3 1.00 1.00 1.00 1.00 1.00 1.50 1.50 1.50 1.50 7.50 8.00 / / / / / / / / / / /
418
+ │ │ ├─arm_v9_neoverse_n2 1.00 1.00 1.00 1.00 1.00 1.50 1.50 1.50 1.50 7.50 8.00 / / / / / / / / / / /
419
+ │ │ └─arm_v9_neoverse_v2 1.00 1.00 1.00 1.00 1.00 1.50 1.50 1.50 1.50 7.50 8.00 / / / / / / / / / / /
420
+ │ └─v9_2 1.16 1.16 1.55 1.02 1.00 1.51 1.55 1.66 1.66 5.80 6.70 18.44 20.04 19.11 19.75 22.96 19.23 29.29 31.69 40.89 34.73 42.11
421
+ │ ├─benchmarks 1.35 1.35 2.40 1.03 1.00 1.51 1.84 / / 5.32 7.10 20.38 22.15 21.13 21.83 25.38 21.25 32.38 35.03 45.20 38.39 46.55
422
+ │ │ └─apple_m4_pro_mbp16 1.35 1.35 2.40 1.03 1.00 1.51 1.84 / / 5.32 7.10 20.38 22.15 21.13 21.83 25.38 21.25 32.38 35.03 45.20 38.39 46.55
423
+ │ └─specs 1.00 1.00 1.00 1.00 1.00 1.50 1.31 1.50 1.50 6.33 6.33 / / / / / / / / / / /
424
+ │ ├─arm_v9_cortex_x4 1.00 1.00 1.00 1.00 1.00 1.50 1.50 1.50 1.50 6.50 6.50 / / / / / / / / / / /
425
+ │ ├─arm_v9_cortex_x925 1.00 1.00 1.00 1.00 1.00 1.50 1.00 1.50 1.50 6.00 6.00 / / / / / / / / / / /
426
+ │ └─arm_v9_neoverse_v3 1.00 1.00 1.00 1.00 1.00 1.50 1.50 1.50 1.50 6.50 6.50 / / / / / / / / / / /
427
+ └─x86 0.24 0.47 1.47 0.99 1.00 1.31 1.95 2.47 2.32 4.98 7.12 15.74 16.52 18.43 24.01 22.76 25.06 28.61 28.92 41.35 41.47 43.69
428
+ ├─amd 0.29 0.43 1.51 0.99 1.00 1.19 1.21 2.42 2.54 4.74 7.39 18.48 16.73 18.23 24.93 24.05 24.46 28.42 28.69 42.99 40.87 45.73
429
+ │ ├─2017_zen1 0.34 0.34 1.16 1.00 1.00 1.29 1.34 3.07 3.07 4.18 6.44 63.95 19.71 17.05 32.24 43.83 18.79 30.58 30.27 57.99 39.24 66.55
430
+ │ │ ├─analysis_uops_info_zen1+ 0.33 0.33 2.33 1.00 1.00 1.33 1.33 3.33 3.33 4.33 6.67 / / / / / / / / / / /
431
+ │ │ └─benchmark_ryzen_1700x 0.35 0.35 0.58 1.01 1.00 1.24 1.34 / / 4.03 6.23 58.90 18.16 15.70 29.69 40.37 17.30 28.16 27.88 53.41 36.14 61.29
432
+ │ ├─2020_zen3 0.18 0.34 1.16 1.00 1.00 1.03 1.00 2.15 2.33 4.36 6.76 11.76 15.94 17.09 22.60 19.44 21.26 24.19 24.21 38.36 38.26 39.30
433
+ │ │ ├─analysis_agner_fog_r7_5800x 0.33 0.33 1.67 1.00 1.00 / 1.00 2.00 2.33 4.50 6.67 / / / / / / / / / / /
434
+ │ │ ├─analysis_uops_info_zen3 0.33 0.33 2.33 1.00 1.00 1.00 1.00 3.00 3.00 4.33 6.67 / / / / / / / / / / /
435
+ │ │ ├─benchmark_gh_amd_epyc_7763_linux 0.10 0.34 0.68 1.00 1.00 1.00 1.00 / / 4.31 6.86 10.35 11.79 15.35 14.36 14.53 22.21 22.45 22.86 30.57 33.34 31.25
436
+ │ │ └─benchmark_gh_amd_epyc_7763_windows 0.10 0.34 0.68 1.00 1.00 1.00 1.00 / / 4.28 6.86 10.32 16.65 14.70 27.48 20.08 15.72 20.14 19.82 37.19 33.92 38.17
437
+ │ ├─2022_zen4 0.23 0.33 1.34 0.99 1.00 1.01 1.00 1.92 1.85 4.37 6.90 11.20 12.97 17.81 21.31 16.47 26.04 25.08 25.55 33.51 37.44 34.67
438
+ │ │ ├─analysis_agner_fog_r9_7900x 0.33 0.33 1.33 1.00 1.00 / 1.00 2.00 2.00 4.33 7.00 / / / / / / / / / / /
439
+ │ │ ├─analysis_uops_info_zen4 0.33 0.33 2.33 1.00 1.00 1.00 1.00 3.00 2.67 4.33 7.00 / / / / / / / / / / /
440
+ │ │ ├─benchmark_ec2_m7a_xlarge_zen4 0.07 0.33 1.57 0.97 1.00 0.98 0.99 / / 4.49 6.95 9.97 11.55 15.86 18.98 14.66 23.19 22.34 22.75 29.84 33.34 30.87
441
+ │ │ └─specs_amd 0.33 0.33 0.67 1.00 1.00 1.00 1.00 1.33 1.33 4.33 6.67 / / / / / / / / / / /
442
+ │ └─2024_zen5 0.47 0.91 2.87 0.97 1.00 1.51 1.62 2.69 3.14 6.37 9.89 13.84 19.21 21.29 24.85 23.87 34.44 35.17 36.16 45.83 49.62 48.23
443
+ │ ├─analysis_agner_fog_r7_9800x3d 1.00 1.00 3.00 1.00 1.00 / 1.50 3.00 3.50 6.50 10.00 / / / / / / / / / / /
444
+ │ ├─benchmark_ec2_m8a_xlarge_zen5 0.21 1.53 2.95 0.91 1.00 1.36 1.87 / / 6.12 9.69 13.33 18.50 20.50 23.94 22.98 33.17 33.87 34.83 44.14 47.79 46.45
445
+ │ └─specs_amd 0.50 0.50 / 1.00 1.00 1.50 1.50 / / 6.50 10.00 / / / / / / / / / / /
446
+ └─intel 0.21 0.50 1.43 0.99 1.00 1.44 3.13 2.51 2.12 5.22 6.86 13.40 16.32 18.63 23.13 21.53 25.68 28.79 29.16 39.77 42.08 41.74
447
+ ├─2017_coffee_lake_gen_8 0.14 0.40 1.30 0.98 1.00 1.03 1.99 1.66 1.66 3.54 4.56 10.44 16.58 12.62 19.41 21.85 13.05 20.81 20.80 33.18 28.66 36.32
448
+ │ ├─analysis_agner_fog_coffee_lake 0.25 0.25 / 1.00 1.00 1.00 2.00 1.50 1.50 3.50 4.00 / / / / / / / / / / /
449
+ │ ├─analysis_uops_info_coffee_lake 0.25 0.25 0.75 1.00 1.00 1.00 2.00 1.75 1.75 3.75 4.75 / / / / / / / / / / /
450
+ │ ├─benchmark_gh_intel_i7_8550U_windows 0.08 0.44 1.69 1.01 1.00 1.01 2.00 / / 3.15 4.79 7.02 15.44 11.99 30.07 21.33 13.00 17.80 17.21 32.36 28.09 35.06
451
+ │ └─benchmark_gh_intel_i7_8700B_macos 0.08 0.91 1.77 0.92 1.00 1.10 1.97 / / 3.78 4.77 16.30 18.68 13.93 13.15 23.47 13.74 25.51 26.38 35.70 30.68 39.48
452
+ ├─2019_sunny_cove_gen_10 0.16 0.29 0.78 0.98 1.00 0.99 1.97 1.63 1.63 3.62 4.51 12.52 9.62 14.29 17.52 13.66 20.63 19.62 20.22 29.29 30.32 29.53
453
+ │ ├─analysis_agner_fog_ice_lake 0.25 0.25 0.50 1.00 1.00 / 2.00 1.50 1.50 3.50 4.00 / / / / / / / / / / /
454
+ │ ├─analysis_uops_info_ice_lake 0.25 0.25 0.75 1.00 1.00 1.00 2.00 1.75 1.75 3.75 4.75 / / / / / / / / / / /
455
+ │ ├─analysis_uops_info_tiger_lake 0.25 0.25 0.75 1.00 1.00 1.00 2.00 1.75 1.75 3.75 4.75 / / / / / / / / / / /
456
+ │ └─benchmark_ec2_m6i_xlarge_ice_lake 0.04 0.44 1.30 0.91 1.00 1.00 1.89 / / 3.50 4.60 11.82 9.08 13.49 16.55 12.90 19.48 18.52 19.09 27.65 28.63 27.88
457
+ ├─2021_golden_cove_gen_12 0.28 0.55 1.56 0.99 1.00 1.74 3.77 3.02 2.55 6.20 8.22 14.56 17.86 21.33 24.92 23.36 31.87 33.78 34.10 42.83 49.32 45.31
458
+ │ ├─analysis_uops_info_alder_lake_p 0.33 0.33 1.00 1.00 1.00 1.33 2.67 2.33 2.33 5.00 6.33 / / / / / / / / / / /
459
+ │ ├─benchmark_ec2_m7i_xlarge_sapphire_rapids 0.13 0.99 2.52 0.98 1.00 1.99 5.03 / / 6.80 9.74 16.28 19.97 23.84 27.86 26.11 35.63 37.76 38.12 47.88 55.14 50.65
460
+ │ └─specs_intel 0.50 0.50 1.50 1.00 1.00 2.00 4.00 3.50 2.50 7.00 9.00 / / / / / / / / / / /
461
+ ├─2022_raptor_cove_gen_13_14 0.26 0.71 1.96 1.00 1.00 2.00 4.51 3.55 2.53 7.00 9.49 15.73 19.93 24.00 28.64 26.02 35.73 37.86 38.33 49.02 55.79 51.16
462
+ │ ├─benchmark_ec2_i7i_xlarge_emerald_rapids 0.13 1.00 2.55 1.00 1.00 2.00 5.08 / / 7.00 10.00 15.95 20.20 24.33 29.03 26.37 36.21 38.37 38.85 49.69 56.55 51.86
463
+ │ └─specs_intel 0.50 0.50 1.50 1.00 1.00 2.00 4.00 3.50 2.50 7.00 9.00 / / / / / / / / / / /
464
+ └─2023_redwood_cove_ultra_1 0.24 0.71 1.95 0.99 1.00 1.73 4.51 3.46 2.47 6.97 9.47 14.44 20.41 24.32 27.29 25.53 36.40 37.92 38.32 48.75 55.19 50.95
465
+ ├─benchmark_ec2_m8i_xlarge_granite_rapids 0.12 1.01 2.53 0.98 1.00 1.50 5.09 / / 6.94 9.96 14.28 20.19 24.06 26.99 25.26 36.01 37.51 37.91 48.22 54.60 50.40
466
+ └─specs_intel 0.50 0.50 1.50 1.00 1.00 2.00 4.00 3.50 2.50 7.00 9.00 / / / / / / / / / / /
467
+
468
+ ```
469
+
470
+ # 5. Known limitations
471
+
472
+ - currently any non-Python-built-in math operations are not counted (e.g. `numpy`)
473
+ - not all Python built-in math operations are counted (e.g. `log`, `log10`, `exp`, `exp10`)
474
+ - flop weights should be taken with a grain of salt and should only provide relative ballpark estimates w.r.t computational complexity. Production implementations in a compiled language could have vastly differing performance depending on cpu cache sizes, branch prediction misses, compiler optimizations using vector operations (AVX etc...), etc...
475
+
476
+ # Appendix A - Flop counting / analysis details
477
+
478
+ This appendix provides detailed information about how each floating-point operation (FLOP) type is counted and analyzed in the `counted-float` package. For each flop type, you will find:
479
+ - Relevant scalar instructions for ARM (v8+) and x86 (SSE2+)
480
+ - Python operations that are counted for this flop type
481
+ - Python operations that are *not* counted for this flop type
482
+
483
+ ## Flop Types
484
+
485
+ ### FlopType.ABS (`abs(x)`)
486
+ - Relevant CPU instructions
487
+ - **ARM:** `FABS`
488
+ - **x86:** `ANDPD`
489
+ - **Counted Python operations:** `abs(x)` where `x` is a `CountedFloat`
490
+ - **Not counted:** `numpy.abs`, complex abs, abs on non-CountedFloat
491
+
492
+ ### FlopType.MINUS (`-x`)
493
+ - Relevant CPU instructions
494
+ - **ARM:** `FNEG`
495
+ - **x86:** `XORPD`
496
+ - **Counted Python operations:** Unary minus (`-x`) for `CountedFloat`
497
+ - **Not counted:** Negation on non-CountedFloat, numpy negation
498
+
499
+ ### FlopType.COMP (`x<=y`, `x>y`, `x==y`, `x==0.0`, ...)
500
+ - Relevant CPU instructions
501
+ - **ARM:** `FCMP`
502
+ - **x86:** `(U)COMISD`
503
+ - **Counted Python operations:** `x == y`, `x != y`, `x <= y`, ... and `min(x,y)`, `max(x,y)` for `CountedFloat`
504
+ - **Not counted:** Comparisons on non-CountedFloat, numpy comparisons
505
+
506
+ ### FlopType.RND (`round`)
507
+ - Relevant CPU instructions
508
+ - **ARM:** `FRINT`
509
+ - **x86:** `ROUNDSD`
510
+ - **Counted Python operations:** `round(x, 0)` for `CountedFloat` (returns float)
511
+ - **Not counted:** `numpy.round`, rounding with decimals, rounding on non-CountedFloat
512
+
513
+ ### FlopType.F2I (`float->int`)
514
+ - Relevant CPU instructions
515
+ - **ARM:** `FCVTZS`
516
+ - **x86:** `CVTSD2SI`
517
+ - **Counted Python operations:** `int(x)`, `math.floor(x)`, `math.ceil(x)`, `math.trunc(x)`, `round(x)` for `CountedFloat` (returns int)
518
+ - **Not counted:** Conversions on non-CountedFloat, numpy conversions
519
+
520
+ ### FlopType.I2F (`int->float`)
521
+ - Relevant CPU instructions
522
+ - **ARM:** `SCVTF`
523
+ - **x86:** `CVTSI2SD`
524
+ - **Counted Python operations:** Construction of `CountedFloat` from int, any binary operation where one operand is an int and the other a `CountedFloat` (e.g., `x + 3`, `3 * x`, etc.)
525
+ - **Not counted:** `float(n)`, unitary operations (e.g. `math.sqrt` on integers -> convert to `CountedFloat` first)
526
+
527
+ ### FlopType.ADD (`x+y`)
528
+ - Relevant CPU instructions
529
+ - **ARM:** `FADD`
530
+ - **x86:** `ADDSD`
531
+ - **Counted Python operations:** `x + y` or `y + x` for `CountedFloat`
532
+ - **Not counted:** Addition on non-CountedFloat, numpy addition
533
+
534
+ ### FlopType.SUB (`x-y`)
535
+ - Relevant CPU instructions
536
+ - **ARM:** `FSUB`
537
+ - **x86:** `SUBSD`
538
+ - **Counted Python operations:** `x - y` or `y - x` for `CountedFloat`
539
+ - **Not counted:** Subtraction on non-CountedFloat, numpy subtraction
540
+
541
+ ### FlopType.MUL (`x*y`)
542
+ - Relevant CPU instructions
543
+ - **ARM:** `FMUL`
544
+ - **x86:** `MULSD`
545
+ - **Counted Python operations:** `x * y` or `y * x` for `CountedFloat`
546
+ - **Not counted:** Multiplication on non-CountedFloat, numpy multiplication
547
+
548
+ ### FlopType.DIV (`x/y`)
549
+ - Relevant CPU instructions
550
+ - **ARM:** `FDIV`
551
+ - **x86:** `DIVSD`
552
+ - **Counted Python operations:** `x / y` or `y / x` for `CountedFloat`
553
+ - **Not counted:** Division on non-CountedFloat, numpy division
554
+
555
+ ### FlopType.SQRT (`sqrt(x)`)
556
+ - Relevant CPU instructions
557
+ - **ARM:** `FSQRT`
558
+ - **x86:** `SQRTSD`
559
+ - **Counted Python operations:** `math.sqrt(x)` for `CountedFloat`
560
+ - **Not counted:** `numpy.sqrt`, sqrt on non-CountedFloat
561
+
562
+ ### FlopType.CBRT (`cbrt(x)`)
563
+ - Relevant CPU instructions
564
+ - **ARM:** (software)
565
+ - **x86:** (software)
566
+ - **Counted Python operations:** `math.cbrt(x)` for `CountedFloat`
567
+ - **Not counted:** `numpy.cbrt`, cbrt on non-CountedFloat
568
+
569
+ ### FlopType.EXP (`e^x`)
570
+ - Relevant CPU instructions
571
+ - **ARM:** (software)
572
+ - **x86:** (software)
573
+ - **Counted Python operations:** `math.exp(x)` for `CountedFloat`
574
+ - **Not counted:** `math.exp(x)` on non-CountedFloat, `numpy.exp`, `math.expm1`, `math.e ** x`
575
+
576
+ ### FlopType.EXP2 (`2^x`)
577
+ - Relevant CPU instructions
578
+ - **ARM:** (software)
579
+ - **x86:** (software)
580
+ - **Counted Python operations:** `2 ** x`, `pow(2, x)` or `math.exp2(x)` for `CountedFloat`
581
+ - **Not counted:** `exp2` on non-CountedFloat, `numpy.exp2`
582
+
583
+ ### FlopType.EXP10 (`10^x`)
584
+ - Relevant CPU instructions
585
+ - **ARM:** (software)
586
+ - **x86:** (software)
587
+ - **Counted Python operations:** `10 ** x`, `pow(10, x)` for `CountedFloat`
588
+ - **Not counted:** `10 ** x` on non-CountedFloat
589
+
590
+ ### FlopType.LOG (`log(x)`)
591
+ - Relevant CPU instructions
592
+ - **ARM:** (software)
593
+ - **x86:** (software)
594
+ - **Counted Python operations:** `math.log(x)` for `CountedFloat`
595
+ - **Not counted:** `numpy.log`, log on non-CountedFloat
596
+
597
+ ### FlopType.LOG2 (`log2(x)`)
598
+ - Relevant CPU instructions
599
+ - **ARM:** (software)
600
+ - **x86:** (software)
601
+ - **Counted Python operations:** `math.log2(x)` for `CountedFloat`
602
+ - **Not counted:** `numpy.log2`, log2 on non-CountedFloat
603
+
604
+ ### FlopType.LOG10 (`log10(x)`)
605
+ - Relevant CPU instructions
606
+ - **ARM:** (software)
607
+ - **x86:** (software)
608
+ - **Counted Python operations:** `math.log10(x)` for `CountedFloat`
609
+ - **Not counted:** `numpy.log10`, log10 on non-CountedFloat
610
+
611
+ ### FlopType.POW (`x^y`)
612
+ - Relevant CPU instructions
613
+ - **ARM:** (software)
614
+ - **x86:** (software)
615
+ - **Counted Python operations:** `x ** y`, `pow(x, y)` for `CountedFloat`
616
+ - **Not counted:** `pow` on non-CountedFloat, `numpy.pow`
617
+
618
+ ### FlopType.SIN (`sin(x)`)
619
+ - Relevant CPU instructions
620
+ - **ARM:** (software)
621
+ - **x86:** (software)
622
+ - **Counted Python operations:** `math.sin(x)` for `CountedFloat`
623
+ - **Not counted:** `sin` on non-CountedFloat, `numpy.sin`
624
+
625
+ ### FlopType.COS (`cos(x)`)
626
+ - Relevant CPU instructions
627
+ - **ARM:** (software)
628
+ - **x86:** (software)
629
+ - **Counted Python operations:** `math.cos(x)` for `CountedFloat`
630
+ - **Not counted:** `cos` on non-CountedFloat, `numpy.cos`
631
+
632
+ ### FlopType.TAN (`tan(x)`)
633
+ - Relevant CPU instructions
634
+ - **ARM:** (software)
635
+ - **x86:** (software)
636
+ - **Counted Python operations:** `math.tan(x)` for `CountedFloat`
637
+ - **Not counted:** `tan` on non-CountedFloat, `numpy.tan