counted-float 0.9.6__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 (92) hide show
  1. {counted_float-0.9.6 → counted_float-0.9.7}/PKG-INFO +98 -90
  2. {counted_float-0.9.6 → counted_float-0.9.7}/README.md +97 -89
  3. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/counting/_builtin_data.py +12 -7
  4. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/counting/config/_defaults.py +13 -8
  5. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/models/_flop_weights.py +20 -8
  6. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/utils/__init__.py +1 -0
  7. counted_float-0.9.7/counted_float/_core/utils/_rounding.py +66 -0
  8. {counted_float-0.9.6 → counted_float-0.9.7}/pyproject.toml +1 -1
  9. {counted_float-0.9.6 → counted_float-0.9.7}/.gitignore +0 -0
  10. {counted_float-0.9.6 → counted_float-0.9.7}/LICENSE +0 -0
  11. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/__init__.py +0 -0
  12. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/__init__.py +0 -0
  13. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/_cli.py +0 -0
  14. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/benchmarking/__init__.py +0 -0
  15. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/benchmarking/flops/__init__.py +0 -0
  16. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/benchmarking/flops/_array_generator.py +0 -0
  17. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/benchmarking/flops/_flops_benchmark_suite.py +0 -0
  18. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/benchmarking/flops/_flops_micro_benchmark.py +0 -0
  19. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/benchmarking/micro/__init__.py +0 -0
  20. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/benchmarking/micro/_micro_benchmark.py +0 -0
  21. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/compatibility/__init__.py +0 -0
  22. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/compatibility/_numba.py +0 -0
  23. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/counting/__init__.py +0 -0
  24. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/counting/_context_managers.py +0 -0
  25. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/counting/_counted_float.py +0 -0
  26. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/counting/_global_counter.py +0 -0
  27. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/counting/config/__init__.py +0 -0
  28. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/counting/config/_config.py +0 -0
  29. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/models/__init__.py +0 -0
  30. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/models/_base.py +0 -0
  31. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/models/_flop_counts.py +0 -0
  32. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/models/_flop_type.py +0 -0
  33. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/models/_flops_benchmark_meta_data.py +0 -0
  34. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/models/_flops_benchmark_result.py +0 -0
  35. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/models/_flops_benchmark_type.py +0 -0
  36. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/models/_instruction_latencies.py +0 -0
  37. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/models/_micro_benchmark_result.py +0 -0
  38. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/utils/_cpu_freq.py +0 -0
  39. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/utils/_formatting.py +0 -0
  40. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/utils/_geo_mean.py +0 -0
  41. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/utils/_latency.py +0 -0
  42. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/utils/_missing_data.py +0 -0
  43. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/_core/utils/_timer.py +0 -0
  44. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/benchmarking/__init__.py +0 -0
  45. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/config/__init__.py +0 -0
  46. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v8_x/benchmarks/apple_m3_max_mbp16.json +0 -0
  47. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v8_x/benchmarks/apple_m3_mba15.json +0 -0
  48. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v8_x/benchmarks/ec2_m6g_xlarge_graviton_2_neoverse_n1.json +0 -0
  49. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v8_x/benchmarks/ec2_m7g_xlarge_graviton_3_neoverse_v1.json +0 -0
  50. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v8_x/benchmarks/gh_apple_m1.json +0 -0
  51. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v8_x/specs/arm_v8_cortex_a76.json +0 -0
  52. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v8_x/specs/arm_v9_cortex_x1.json +0 -0
  53. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v8_x/specs/arm_v9_neoverse_n1.json +0 -0
  54. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v8_x/specs/arm_v9_neoverse_v1.json +0 -0
  55. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v9_0/benchmarks/ec2_m8g_xlarge_graviton_4_neoverse_v2.json +0 -0
  56. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v9_0/benchmarks/gh_azure_cobalt_100_neoverse_n2.json +0 -0
  57. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v9_0/specs/arm_v9_cortex_x2.json +0 -0
  58. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v9_0/specs/arm_v9_cortex_x3.json +0 -0
  59. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v9_0/specs/arm_v9_neoverse_n2.json +0 -0
  60. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v9_0/specs/arm_v9_neoverse_v2.json +0 -0
  61. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v9_2/benchmarks/apple_m4_pro_mbp16.json +0 -0
  62. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v9_2/specs/arm_v9_cortex_x4.json +0 -0
  63. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v9_2/specs/arm_v9_cortex_x925.json +0 -0
  64. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/arm/v9_2/specs/arm_v9_neoverse_v3.json +0 -0
  65. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2017_zen1/analysis_uops_info_zen1+.json +0 -0
  66. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2017_zen1/benchmark_ryzen_1700x.json +0 -0
  67. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2020_zen3/analysis_agner_fog_r7_5800x.json +0 -0
  68. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2020_zen3/analysis_uops_info_zen3.json +0 -0
  69. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2020_zen3/benchmark_gh_amd_epyc_7763_linux.json +0 -0
  70. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2020_zen3/benchmark_gh_amd_epyc_7763_windows.json +0 -0
  71. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2022_zen4/analysis_agner_fog_r9_7900x.json +0 -0
  72. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2022_zen4/analysis_uops_info_zen4.json +0 -0
  73. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2022_zen4/benchmark_ec2_m7a_xlarge_zen4.json +0 -0
  74. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2022_zen4/specs_amd.json +0 -0
  75. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2024_zen5/analysis_agner_fog_r7_9800x3d.json +0 -0
  76. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2024_zen5/benchmark_ec2_m8a_xlarge_zen5.json +0 -0
  77. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/amd/2024_zen5/specs_amd.json +0 -0
  78. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2017_coffee_lake_gen_8/analysis_agner_fog_coffee_lake.json +0 -0
  79. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2017_coffee_lake_gen_8/analysis_uops_info_coffee_lake.json +0 -0
  80. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2017_coffee_lake_gen_8/benchmark_gh_intel_i7_8700B_macos.json +0 -0
  81. /counted_float-0.9.6/counted_float/data/x86/intel/2017_coffee_lake_gen_8/benchmark_gh_intel_i7_8550U_windows.json → /counted_float-0.9.7/counted_float/data/x86/intel/2017_coffee_lake_gen_8/benchmark_intel_i7_8550U_windows.json +0 -0
  82. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2019_sunny_cove_gen_10/analysis_agner_fog_ice_lake.json +0 -0
  83. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2019_sunny_cove_gen_10/analysis_uops_info_ice_lake.json +0 -0
  84. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2019_sunny_cove_gen_10/analysis_uops_info_tiger_lake.json +0 -0
  85. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2019_sunny_cove_gen_10/benchmark_ec2_m6i_xlarge_ice_lake.json +0 -0
  86. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2021_golden_cove_gen_12/analysis_uops_info_alder_lake_p.json +0 -0
  87. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2021_golden_cove_gen_12/benchmark_ec2_m7i_xlarge_sapphire_rapids.json +0 -0
  88. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2021_golden_cove_gen_12/specs_intel.json +0 -0
  89. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2022_raptor_cove_gen_13_14/benchmark_ec2_i7i_xlarge_emerald_rapids.json +0 -0
  90. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2022_raptor_cove_gen_13_14/specs_intel.json +0 -0
  91. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2023_redwood_cove_ultra_1/benchmark_ec2_m8i_xlarge_granite_rapids.json +0 -0
  92. {counted_float-0.9.6 → counted_float-0.9.7}/counted_float/data/x86/intel/2023_redwood_cove_ultra_1/specs_intel.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: counted-float
3
- Version: 0.9.6
3
+ Version: 0.9.7
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
6
  Project-URL: ChangeLog, https://github.com/bertpl/counted-float/blob/develop/CHANGELOG.md
@@ -21,9 +21,9 @@ Description-Content-Type: text/markdown
21
21
 
22
22
  <!--START_SECTION:images-->
23
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.6/badge-test-count.svg)
25
- ![genbadge-test-coverage](https://bertpl.github.io/counted-float/version_artifacts/v0.9.6/badge-coverage.svg)
26
- ![counted_float logo](https://bertpl.github.io/counted-float/version_artifacts/v0.9.6/splash.webp)
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
27
  <!--END_SECTION:images-->
28
28
 
29
29
  # counted-float
@@ -162,30 +162,33 @@ rationale behind choice of data sources and methodology.
162
162
  >>> get_active_flop_weights().show()
163
163
 
164
164
  {
165
- FlopType.ABS [abs(x)] : 1
166
- FlopType.MINUS [-x] : 1
167
- FlopType.COMP [x<=y] : 1
168
- FlopType.RND [round] : 2
169
- FlopType.F2I [float->int] : 2
170
- FlopType.I2F [int->float] : 2
171
- FlopType.ADD [x+y] : 1
172
- FlopType.SUB [x-y] : 1
173
- FlopType.MUL [x*y] : 1
174
- FlopType.DIV [x/y] : 5
175
- FlopType.SQRT [sqrt(x)] : 6
176
- FlopType.CBRT [cbrt(x)] : 42
177
- FlopType.EXP [e^x] : 19
178
- FlopType.EXP2 [2^x] : 29
179
- FlopType.EXP10 [10^x] : 23
180
- FlopType.LOG [log(x)] : 19
181
- FlopType.LOG2 [log2(x)] : 24
182
- FlopType.LOG10 [log10(x)] : 19
183
- FlopType.POW [x^y] : 62
184
- FlopType.SIN [sin(x)] : 32
185
- FlopType.COS [cos(x)] : 31
186
- FlopType.TAN [tan(x)] : 34
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
187
  }
188
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
+
189
192
  These weights will be used by default when extracting total weighted flop costs:
190
193
 
191
194
  ```python
@@ -202,7 +205,7 @@ with FlopCountingContext() as ctx:
202
205
  _ = math.log2(cf2)
203
206
 
204
207
  flop_counts = ctx.flop_counts()
205
- total_cost = flop_counts.total_weighted_cost() # 1 + 62 + 24 = 87
208
+ total_cost = flop_counts.total_weighted_cost() # 1 + 40 + 22 = 63
206
209
  ```
207
210
  Note that the `total_weighted_cost` method will use the default flop weights as returned by `get_flop_weights()`. This can be
208
211
  overridden by either configuring different flop weights (see next section) or by setting the `weights` argument of the `total_weighted_cost()` method.
@@ -229,33 +232,38 @@ Built-in flop weights can be inspected using the following functions:
229
232
  ```python
230
233
  from counted_float.config import get_default_consensus_flop_weights
231
234
 
232
- >>> get_default_consensus_flop_weights(rounded=False).show()
235
+ >>> get_default_consensus_flop_weights(rounding_mode=None).show()
233
236
 
234
237
  {
235
- FlopType.ABS [abs(x)] : 0.63673
236
- FlopType.MINUS [-x] : 0.64396
237
- FlopType.COMP [x<=y] : 1.20756
238
- FlopType.RND [round] : 1.54041
239
- FlopType.F2I [float->int] : 1.99099
240
- FlopType.I2F [int->float] : 1.84601
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
241
242
  FlopType.ADD [x+y] : 1.00000
242
- FlopType.SUB [x-y] : 1.00586
243
- FlopType.MUL [x*y] : 1.37238
244
- FlopType.DIV [x/y] : 5.07465
245
- FlopType.SQRT [sqrt(x)] : 5.90559
246
- FlopType.CBRT [cbrt(x)] : 42.39375
247
- FlopType.EXP [e^x] : 18.58228
248
- FlopType.EXP2 [2^x] : 28.88672
249
- FlopType.EXP10 [10^x] : 22.86839
250
- FlopType.LOG [log(x)] : 18.89135
251
- FlopType.LOG2 [log2(x)] : 24.34792
252
- FlopType.LOG10 [log10(x)] : 18.55085
253
- FlopType.POW [x^y] : 61.79155
254
- FlopType.SIN [sin(x)] : 31.91490
255
- FlopType.COS [cos(x)] : 30.79295
256
- FlopType.TAN [tan(x)] : 34.37970
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
257
260
  }
258
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
+
259
267
 
260
268
  The default weights that are configured out-of-the-box in the package are the integer-rounded `consensus` weights.
261
269
 
@@ -270,28 +278,28 @@ from counted_float.config import get_builtin_flop_weights
270
278
  >>> get_builtin_flop_weights(key_filter="arm").show()
271
279
 
272
280
  {
273
- FlopType.ABS [abs(x)] : 0.97313
274
- FlopType.MINUS [-x] : 0.99098
275
- FlopType.COMP [x<=y] : 1.03987
276
- FlopType.RND [round] : 1.35111
277
- FlopType.F2I [float->int] : 1.52648
278
- FlopType.I2F [int->float] : 1.63320
281
+ FlopType.COMP [x<=y] : 0.65000
282
+ FlopType.MINUS [-x] : 0.90000
279
283
  FlopType.ADD [x+y] : 1.00000
280
- FlopType.SUB [x-y] : 1.00058
281
- FlopType.MUL [x*y] : 1.44952
282
- FlopType.DIV [x/y] : 5.00897
283
- FlopType.SQRT [sqrt(x)] : 5.15597
284
- FlopType.CBRT [cbrt(x)] : 39.30448
285
- FlopType.EXP [e^x] : 17.22817
286
- FlopType.EXP2 [2^x] : 15.82232
287
- FlopType.EXP10 [10^x] : 21.20195
288
- FlopType.LOG [log(x)] : 17.51472
289
- FlopType.LOG2 [log2(x)] : 18.32529
290
- FlopType.LOG10 [log10(x)] : 17.19903
291
- FlopType.POW [x^y] : 47.63289
292
- FlopType.SIN [sin(x)] : 29.58923
293
- FlopType.COS [cos(x)] : 28.54904
294
- FlopType.TAN [tan(x)] : 31.87442
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
295
303
  }
296
304
  ```
297
305
 
@@ -335,29 +343,29 @@ div : wwwwwwwwwwwwwww.........................
335
343
  div_div : wwwwwwwwwwwwwww......................... [ 5.00 µs ± 0.2% | 20.3K cpu cycles ± 0.2% ] / 1000 iterations
336
344
  lte_addsub : wwwwwwwwwwwwwww......................... [ 1.71 µs ± 0.2% | 6.94K cpu cycles ± 0.2% ] / 1000 iterations
337
345
 
338
- >>> results.flop_weights.show()
346
+ >>> results.flop_weights().show()
339
347
 
340
348
  {
341
- FlopType.ABS [abs(x)] : 0.90556
342
- FlopType.MINUS [-x] : 0.90089
343
- FlopType.COMP [x<=y] : 1.67297
344
- FlopType.RND [round] : 1.24118
349
+ FlopType.ABS [abs(x)] : 0.89904
350
+ FlopType.MINUS [-x] : 0.90935
351
+ FlopType.SUB [x-y] : 0.99676
345
352
  FlopType.ADD [x+y] : 1.00000
346
- FlopType.SUB [x-y] : 0.99928
347
- FlopType.MUL [x*y] : 1.52656
348
- FlopType.DIV [x/y] : 4.06589
349
- FlopType.SQRT [sqrt(x)] : 5.26487
350
- FlopType.CBRT [cbrt(x)] : 39.49190
351
- FlopType.EXP [e^x] : 17.34508
352
- FlopType.EXP2 [2^x] : 16.70475
353
- FlopType.EXP10 [10^x] : 21.03351
354
- FlopType.LOG [log(x)] : 17.59412
355
- FlopType.LOG2 [log2(x)] : 18.08932
356
- FlopType.LOG10 [log10(x)] : 17.27955
357
- FlopType.POW [x^y] : 38.32044
358
- FlopType.SIN [sin(x)] : 28.67006
359
- FlopType.COS [cos(x)] : 29.11818
360
- FlopType.TAN [tan(x)] : 32.28703
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
361
369
  FlopType.F2I [float->int] : nan
362
370
  FlopType.I2F [int->float] : nan
363
371
  }
@@ -1,8 +1,8 @@
1
1
  <!--START_SECTION:images-->
2
2
  ![shields.io-python-versions](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue)
3
- ![genbadge-test-count](https://bertpl.github.io/counted-float/version_artifacts/v0.9.6/badge-test-count.svg)
4
- ![genbadge-test-coverage](https://bertpl.github.io/counted-float/version_artifacts/v0.9.6/badge-coverage.svg)
5
- ![counted_float logo](https://bertpl.github.io/counted-float/version_artifacts/v0.9.6/splash.webp)
3
+ ![genbadge-test-count](https://bertpl.github.io/counted-float/version_artifacts/v0.9.7/badge-test-count.svg)
4
+ ![genbadge-test-coverage](https://bertpl.github.io/counted-float/version_artifacts/v0.9.7/badge-coverage.svg)
5
+ ![counted_float logo](https://bertpl.github.io/counted-float/version_artifacts/v0.9.7/splash.webp)
6
6
  <!--END_SECTION:images-->
7
7
 
8
8
  # counted-float
@@ -141,30 +141,33 @@ rationale behind choice of data sources and methodology.
141
141
  >>> get_active_flop_weights().show()
142
142
 
143
143
  {
144
- FlopType.ABS [abs(x)] : 1
145
- FlopType.MINUS [-x] : 1
146
- FlopType.COMP [x<=y] : 1
147
- FlopType.RND [round] : 2
148
- FlopType.F2I [float->int] : 2
149
- FlopType.I2F [int->float] : 2
150
- FlopType.ADD [x+y] : 1
151
- FlopType.SUB [x-y] : 1
152
- FlopType.MUL [x*y] : 1
153
- FlopType.DIV [x/y] : 5
154
- FlopType.SQRT [sqrt(x)] : 6
155
- FlopType.CBRT [cbrt(x)] : 42
156
- FlopType.EXP [e^x] : 19
157
- FlopType.EXP2 [2^x] : 29
158
- FlopType.EXP10 [10^x] : 23
159
- FlopType.LOG [log(x)] : 19
160
- FlopType.LOG2 [log2(x)] : 24
161
- FlopType.LOG10 [log10(x)] : 19
162
- FlopType.POW [x^y] : 62
163
- FlopType.SIN [sin(x)] : 32
164
- FlopType.COS [cos(x)] : 31
165
- FlopType.TAN [tan(x)] : 34
144
+ FlopType.MINUS [-x] : 0.45000
145
+ FlopType.ABS [abs(x)] : 0.70000
146
+ FlopType.ADD [x+y] : 1.00000
147
+ FlopType.COMP [x<=y] : 1.00000
148
+ FlopType.SUB [x-y] : 1.00000
149
+ FlopType.MUL [x*y] : 1.40000
150
+ FlopType.RND [round] : 1.80000
151
+ FlopType.F2I [float->int] : 2.00000
152
+ FlopType.I2F [int->float] : 2.00000
153
+ FlopType.DIV [x/y] : 5.50000
154
+ FlopType.SQRT [sqrt(x)] : 7.50000
155
+ FlopType.EXP2 [2^x] : 16.00000
156
+ FlopType.EXP [e^x] : 18.00000
157
+ FlopType.LOG [log(x)] : 20.00000
158
+ FlopType.LOG2 [log2(x)] : 22.00000
159
+ FlopType.EXP10 [10^x] : 24.00000
160
+ FlopType.LOG10 [log10(x)] : 24.00000
161
+ FlopType.COS [cos(x)] : 30.00000
162
+ FlopType.SIN [sin(x)] : 30.00000
163
+ FlopType.POW [x^y] : 40.00000
164
+ FlopType.TAN [tan(x)] : 40.00000
165
+ FlopType.CBRT [cbrt(x)] : 45.00000
166
166
  }
167
167
  ```
168
+ Note that these weights are rounded up to the ~10% closest semi-round number, reflecting a balance between accuracy and readability,
169
+ while conveying the message that these weights should be used as approximations only. See further down for the different rounding modes.
170
+
168
171
  These weights will be used by default when extracting total weighted flop costs:
169
172
 
170
173
  ```python
@@ -181,7 +184,7 @@ with FlopCountingContext() as ctx:
181
184
  _ = math.log2(cf2)
182
185
 
183
186
  flop_counts = ctx.flop_counts()
184
- total_cost = flop_counts.total_weighted_cost() # 1 + 62 + 24 = 87
187
+ total_cost = flop_counts.total_weighted_cost() # 1 + 40 + 22 = 63
185
188
  ```
186
189
  Note that the `total_weighted_cost` method will use the default flop weights as returned by `get_flop_weights()`. This can be
187
190
  overridden by either configuring different flop weights (see next section) or by setting the `weights` argument of the `total_weighted_cost()` method.
@@ -208,33 +211,38 @@ Built-in flop weights can be inspected using the following functions:
208
211
  ```python
209
212
  from counted_float.config import get_default_consensus_flop_weights
210
213
 
211
- >>> get_default_consensus_flop_weights(rounded=False).show()
214
+ >>> get_default_consensus_flop_weights(rounding_mode=None).show()
212
215
 
213
216
  {
214
- FlopType.ABS [abs(x)] : 0.63673
215
- FlopType.MINUS [-x] : 0.64396
216
- FlopType.COMP [x<=y] : 1.20756
217
- FlopType.RND [round] : 1.54041
218
- FlopType.F2I [float->int] : 1.99099
219
- FlopType.I2F [int->float] : 1.84601
217
+ FlopType.MINUS [-x] : 0.46773
218
+ FlopType.ABS [abs(x)] : 0.70012
219
+ FlopType.COMP [x<=y] : 0.96923
220
+ FlopType.SUB [x-y] : 0.99846
220
221
  FlopType.ADD [x+y] : 1.00000
221
- FlopType.SUB [x-y] : 1.00586
222
- FlopType.MUL [x*y] : 1.37238
223
- FlopType.DIV [x/y] : 5.07465
224
- FlopType.SQRT [sqrt(x)] : 5.90559
225
- FlopType.CBRT [cbrt(x)] : 42.39375
226
- FlopType.EXP [e^x] : 18.58228
227
- FlopType.EXP2 [2^x] : 28.88672
228
- FlopType.EXP10 [10^x] : 22.86839
229
- FlopType.LOG [log(x)] : 18.89135
230
- FlopType.LOG2 [log2(x)] : 24.34792
231
- FlopType.LOG10 [log10(x)] : 18.55085
232
- FlopType.POW [x^y] : 61.79155
233
- FlopType.SIN [sin(x)] : 31.91490
234
- FlopType.COS [cos(x)] : 30.79295
235
- FlopType.TAN [tan(x)] : 34.37970
222
+ FlopType.MUL [x*y] : 1.39950
223
+ FlopType.RND [round] : 1.77232
224
+ FlopType.F2I [float->int] : 1.91485
225
+ FlopType.I2F [int->float] : 1.92200
226
+ FlopType.DIV [x/y] : 5.53105
227
+ FlopType.SQRT [sqrt(x)] : 7.35657
228
+ FlopType.EXP2 [2^x] : 15.85687
229
+ FlopType.EXP [e^x] : 17.51909
230
+ FlopType.LOG [log(x)] : 19.00419
231
+ FlopType.LOG2 [log2(x)] : 22.38002
232
+ FlopType.EXP10 [10^x] : 23.02693
233
+ FlopType.LOG10 [log10(x)] : 24.65718
234
+ FlopType.SIN [sin(x)] : 30.40612
235
+ FlopType.COS [cos(x)] : 31.39434
236
+ FlopType.POW [x^y] : 41.81031
237
+ FlopType.TAN [tan(x)] : 42.15636
238
+ FlopType.CBRT [cbrt(x)] : 44.32376
236
239
  }
237
240
  ```
241
+ There are 3 rounding modes:
242
+ - `None` -> no rounding
243
+ - `"nearest_int"` -> round up/down to nearest integer, with a minimum of 1
244
+ - `"10%"` -> round to nearest semi-round number within ~10% (default)
245
+
238
246
 
239
247
  The default weights that are configured out-of-the-box in the package are the integer-rounded `consensus` weights.
240
248
 
@@ -249,28 +257,28 @@ from counted_float.config import get_builtin_flop_weights
249
257
  >>> get_builtin_flop_weights(key_filter="arm").show()
250
258
 
251
259
  {
252
- FlopType.ABS [abs(x)] : 0.97313
253
- FlopType.MINUS [-x] : 0.99098
254
- FlopType.COMP [x<=y] : 1.03987
255
- FlopType.RND [round] : 1.35111
256
- FlopType.F2I [float->int] : 1.52648
257
- FlopType.I2F [int->float] : 1.63320
260
+ FlopType.COMP [x<=y] : 0.65000
261
+ FlopType.MINUS [-x] : 0.90000
258
262
  FlopType.ADD [x+y] : 1.00000
259
- FlopType.SUB [x-y] : 1.00058
260
- FlopType.MUL [x*y] : 1.44952
261
- FlopType.DIV [x/y] : 5.00897
262
- FlopType.SQRT [sqrt(x)] : 5.15597
263
- FlopType.CBRT [cbrt(x)] : 39.30448
264
- FlopType.EXP [e^x] : 17.22817
265
- FlopType.EXP2 [2^x] : 15.82232
266
- FlopType.EXP10 [10^x] : 21.20195
267
- FlopType.LOG [log(x)] : 17.51472
268
- FlopType.LOG2 [log2(x)] : 18.32529
269
- FlopType.LOG10 [log10(x)] : 17.19903
270
- FlopType.POW [x^y] : 47.63289
271
- FlopType.SIN [sin(x)] : 29.58923
272
- FlopType.COS [cos(x)] : 28.54904
273
- FlopType.TAN [tan(x)] : 31.87442
263
+ FlopType.SUB [x-y] : 1.00000
264
+ FlopType.ABS [abs(x)] : 1.10000
265
+ FlopType.F2I [float->int] : 1.50000
266
+ FlopType.MUL [x*y] : 1.50000
267
+ FlopType.I2F [int->float] : 1.60000
268
+ FlopType.RND [round] : 1.60000
269
+ FlopType.DIV [x/y] : 6.00000
270
+ FlopType.SQRT [sqrt(x)] : 7.50000
271
+ FlopType.EXP2 [2^x] : 16.00000
272
+ FlopType.EXP [e^x] : 18.00000
273
+ FlopType.LOG [log(x)] : 20.00000
274
+ FlopType.LOG2 [log2(x)] : 20.00000
275
+ FlopType.EXP10 [10^x] : 24.00000
276
+ FlopType.LOG10 [log10(x)] : 24.00000
277
+ FlopType.COS [cos(x)] : 33.00000
278
+ FlopType.SIN [sin(x)] : 33.00000
279
+ FlopType.POW [x^y] : 40.00000
280
+ FlopType.CBRT [cbrt(x)] : 45.00000
281
+ FlopType.TAN [tan(x)] : 45.00000
274
282
  }
275
283
  ```
276
284
 
@@ -314,29 +322,29 @@ div : wwwwwwwwwwwwwww.........................
314
322
  div_div : wwwwwwwwwwwwwww......................... [ 5.00 µs ± 0.2% | 20.3K cpu cycles ± 0.2% ] / 1000 iterations
315
323
  lte_addsub : wwwwwwwwwwwwwww......................... [ 1.71 µs ± 0.2% | 6.94K cpu cycles ± 0.2% ] / 1000 iterations
316
324
 
317
- >>> results.flop_weights.show()
325
+ >>> results.flop_weights().show()
318
326
 
319
327
  {
320
- FlopType.ABS [abs(x)] : 0.90556
321
- FlopType.MINUS [-x] : 0.90089
322
- FlopType.COMP [x<=y] : 1.67297
323
- FlopType.RND [round] : 1.24118
328
+ FlopType.ABS [abs(x)] : 0.89904
329
+ FlopType.MINUS [-x] : 0.90935
330
+ FlopType.SUB [x-y] : 0.99676
324
331
  FlopType.ADD [x+y] : 1.00000
325
- FlopType.SUB [x-y] : 0.99928
326
- FlopType.MUL [x*y] : 1.52656
327
- FlopType.DIV [x/y] : 4.06589
328
- FlopType.SQRT [sqrt(x)] : 5.26487
329
- FlopType.CBRT [cbrt(x)] : 39.49190
330
- FlopType.EXP [e^x] : 17.34508
331
- FlopType.EXP2 [2^x] : 16.70475
332
- FlopType.EXP10 [10^x] : 21.03351
333
- FlopType.LOG [log(x)] : 17.59412
334
- FlopType.LOG2 [log2(x)] : 18.08932
335
- FlopType.LOG10 [log10(x)] : 17.27955
336
- FlopType.POW [x^y] : 38.32044
337
- FlopType.SIN [sin(x)] : 28.67006
338
- FlopType.COS [cos(x)] : 29.11818
339
- FlopType.TAN [tan(x)] : 32.28703
332
+ FlopType.RND [round] : 1.24397
333
+ FlopType.MUL [x*y] : 1.55516
334
+ FlopType.COMP [x<=y] : 1.69018
335
+ FlopType.DIV [x/y] : 4.12333
336
+ FlopType.SQRT [sqrt(x)] : 5.42419
337
+ FlopType.EXP2 [2^x] : 16.95266
338
+ FlopType.LOG10 [log10(x)] : 17.60079
339
+ FlopType.EXP [e^x] : 17.76250
340
+ FlopType.LOG [log(x)] : 17.86149
341
+ FlopType.LOG2 [log2(x)] : 18.42380
342
+ FlopType.EXP10 [10^x] : 21.50729
343
+ FlopType.SIN [sin(x)] : 29.31571
344
+ FlopType.COS [cos(x)] : 29.56218
345
+ FlopType.TAN [tan(x)] : 32.88570
346
+ FlopType.POW [x^y] : 39.35018
347
+ FlopType.CBRT [cbrt(x)] : 40.16857
340
348
  FlopType.F2I [float->int] : nan
341
349
  FlopType.I2F [int->float] : nan
342
350
  }
@@ -271,14 +271,19 @@ class FlopWeightsTreeView:
271
271
  else:
272
272
  line += f"{w:.2f}".rjust(col_width)
273
273
 
274
- if not is_leaf:
275
- txt_clr = "bold white"
276
- h = hex(max(16, int(100 * (max_indent - indent) / max_indent)))[-2:]
277
- bg_clr = f"#{h}{h}{h}"
274
+ if is_leaf:
275
+ # no special styling
276
+ console.print(line, highlight=False)
278
277
  else:
279
- txt_clr = "white"
280
- bg_clr = f"black"
281
- console.print(line, style=f"{txt_clr} on {bg_clr}", highlight=False)
278
+ # highlight as bold and with a colored background
279
+ style_tag = [
280
+ "[bold on #888888]", # indent 0
281
+ "[bold on #5555dd]", # indent 1
282
+ "[bold on #55dd55]", # indent 2
283
+ "[bold on #ee7777]", # indent 3+
284
+ ][min(indent, 3)]
285
+ line = line[: 3 * indent] + style_tag + line[3 * indent :] + "[/]"
286
+ console.print(line, highlight=False)
282
287
 
283
288
  print()
284
289
 
@@ -1,31 +1,36 @@
1
1
  from functools import cache
2
+ from typing import Literal
2
3
 
3
4
  from counted_float._core.counting._builtin_data import BuiltInData
4
5
  from counted_float._core.models import FlopWeights
5
6
 
6
7
 
7
8
  @cache
8
- def get_default_consensus_flop_weights(rounded: bool = True) -> FlopWeights:
9
+ def get_default_consensus_flop_weights(rounding_mode: None | Literal["nearest_int", "10%"] = "10%") -> FlopWeights:
9
10
  """
10
11
  Get the default CONSENSUS flop weights.
11
12
  Computed as the geo-mean of the unrounded empirical and theoretical weights, rounded to the nearest integer.
12
13
  """
13
- weights = BuiltInData.get_flop_weights(key_filter="")
14
- if rounded:
15
- return weights.round()
16
- else:
17
- return weights
14
+ return get_builtin_flop_weights(key_filter="", rounding_mode=rounding_mode)
18
15
 
19
16
 
20
17
  @cache
21
- def get_builtin_flop_weights(key_filter: str = "") -> FlopWeights:
18
+ def get_builtin_flop_weights(
19
+ key_filter: str = "",
20
+ rounding_mode: None | Literal["nearest_int", "10%"] = "10%",
21
+ ) -> FlopWeights:
22
22
  """
23
23
  Get built-in flop weights estimated from built-in benchmark results and/or instruction latency analyses.
24
24
 
25
25
  :param key_filter: (str, default="") If non-empty, only include entries whose keys contain this substring.
26
26
  E.g. "benchmarks" to only include benchmark results, or "x86" to only include
27
27
  x86-related flop weights.
28
+ :param rounding_mode: (str, default="10%") rounding mode (None, "nearest_int", "10%").
28
29
  :return: A FlopWeights instance computed as the (hierarchical) geo-mean of all matching built-in data.
29
30
  :raises ValueError: If no built-in data matches the given key_filter.
30
31
  """
31
- return BuiltInData.get_flop_weights(key_filter=key_filter)
32
+ weights = BuiltInData.get_flop_weights(key_filter=key_filter)
33
+ if rounding_mode is not None:
34
+ return weights.round(mode=rounding_mode)
35
+ else:
36
+ return weights
@@ -1,12 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import math
4
- from typing import Iterable
4
+ from typing import Iterable, Literal
5
5
 
6
6
  import numpy as np
7
7
  from pydantic import field_serializer, field_validator
8
8
 
9
- from counted_float._core.utils import geo_mean, impute_missing_data
9
+ from counted_float._core.utils import geo_mean, impute_missing_data, round_number
10
10
 
11
11
  from ._base import MyBaseModel
12
12
  from ._flop_type import FlopType
@@ -18,11 +18,23 @@ class FlopWeights(MyBaseModel):
18
18
  # -------------------------------------------------------------------------
19
19
  # Helpers
20
20
  # -------------------------------------------------------------------------
21
- def round(self) -> FlopWeights:
22
- """Round all weights to the nearest integer, with minimum of 1."""
23
- return FlopWeights(
24
- weights={k: math.nan if math.isnan(v) else max(1, round(v)) for k, v in self.weights.items()},
25
- )
21
+ def round(self, mode: Literal["nearest_int", "10%"] = "10%") -> FlopWeights:
22
+ """
23
+ Round all weights according to specified mode:
24
+ - "10%" (default) : round to nearest round number with ~10% accuracy and max. 2 significant non-0 digits
25
+ (e.g. 1.234 -> 1.2, 12.34 -> 12, 123.4 -> 120)
26
+ - "nearest_int" : round to nearest int with minimum of 1
27
+ """
28
+ if mode == "nearest_int":
29
+ return FlopWeights(
30
+ weights={k: math.nan if math.isnan(v) else max(1, round(v)) for k, v in self.weights.items()},
31
+ )
32
+ else:
33
+ return FlopWeights(
34
+ weights={
35
+ k: math.nan if math.isnan(v) else round_number(v, mode="10%") for k, v in self.weights.items()
36
+ },
37
+ )
26
38
 
27
39
  def has_missing_data(self) -> bool:
28
40
  """Check if any flop type has missing data (i.e. weight is NaN)."""
@@ -55,7 +67,7 @@ class FlopWeights(MyBaseModel):
55
67
  # -------------------------------------------------------------------------
56
68
  def show(self):
57
69
  print("{")
58
- for k, v in self.weights.items():
70
+ for k, v in sorted(self.weights.items(), key=lambda kv: (kv[1], kv[0].long_name())):
59
71
  if isinstance(v, float):
60
72
  print(f" {k.long_name()}".ljust(40) + f": {v:9.5f}")
61
73
  else:
@@ -3,4 +3,5 @@ from ._formatting import format_latency, format_time_duration
3
3
  from ._geo_mean import geo_mean
4
4
  from ._latency import convert_nsecs_to_cycles
5
5
  from ._missing_data import impute_missing_data
6
+ from ._rounding import round_number
6
7
  from ._timer import Timer
@@ -0,0 +1,66 @@
1
+ import math
2
+ from typing import Literal
3
+
4
+ # Values below are used in the "10%" rounding mode and are chosen such...
5
+ # - they span the range [1.0, 10.0] end-to-end
6
+ # - they have ±10% increments
7
+ # - deltas are monotonically increasing and are multiples of 0.1
8
+ # - all integers are included (2.0, 3.0, ..., 9.0)
9
+ __ALLOWED_10PERC_ROUNDING_VALUES = [
10
+ 1.0,
11
+ 1.1, # +0.1
12
+ 1.2, # +0.1
13
+ 1.3, # +0.1
14
+ 1.4, # +0.1
15
+ 1.5, # +0.1
16
+ 1.6, # +0.1
17
+ 1.8, # +0.2
18
+ 2.0, # +0.2
19
+ 2.2, # +0.2
20
+ 2.4, # +0.2
21
+ 2.7, # +0.3
22
+ 3.0, # +0.3
23
+ 3.3, # +0.3
24
+ 3.6, # +0.3
25
+ 4.0, # +0.4
26
+ 4.5, # +0.5
27
+ 5.0, # +0.5
28
+ 5.5, # +0.5
29
+ 6.0, # +0.5
30
+ 6.5, # +0.5
31
+ 7.0, # +0.5
32
+ 7.5, # +0.5
33
+ 8.0, # +0.5
34
+ 9.0, # +1.0
35
+ 10.0, # +1.0
36
+ ]
37
+
38
+
39
+ def round_number(value: float, mode: None | Literal["nearest_int", "10%"]) -> float:
40
+ """
41
+ Round a floating point number according to the specified mode:
42
+ None -> no rounding, value is returned as is
43
+ "nearest_int" -> round to nearest integer
44
+ "10%" -> round to nearest n*10^m with n in __ALLOWED_10PERC_ROUNDING_VALUES
45
+ """
46
+ match mode:
47
+ case "nearest_int":
48
+ return round(value, 0)
49
+ case "10%":
50
+ if value == 0:
51
+ return 0
52
+ elif value < 0:
53
+ return -round_number(-value, mode)
54
+ elif 1.0 <= value <= 10.0:
55
+ return _round_to_log_nearest(value, __ALLOWED_10PERC_ROUNDING_VALUES)
56
+ else:
57
+ scale = 10 ** math.floor(math.log10(value))
58
+ return scale * round_number(value / scale, mode)
59
+ case _:
60
+ return value
61
+
62
+
63
+ def _round_to_log_nearest(value: float, candidate_value: list[float]) -> float:
64
+ """Return candidate_value that is log-closest to value, assuming all are >0."""
65
+ log_value = math.log(value)
66
+ return min(candidate_value, key=lambda cand: abs(math.log(cand) - log_value))
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "counted-float"
3
- version = "0.9.6"
3
+ version = "0.9.7"
4
4
  description = "Count floating-point operations in Python code & benchmark relative flop costs."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
File without changes
File without changes