flopscope 0.2.0__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 (115) hide show
  1. benchmarks/__init__.py +1 -0
  2. benchmarks/__main__.py +6 -0
  3. benchmarks/_baseline.py +171 -0
  4. benchmarks/_bitwise.py +231 -0
  5. benchmarks/_complex.py +176 -0
  6. benchmarks/_contractions.py +291 -0
  7. benchmarks/_fft.py +198 -0
  8. benchmarks/_impl_urls.py +139 -0
  9. benchmarks/_linalg.py +197 -0
  10. benchmarks/_linalg_delegates.py +407 -0
  11. benchmarks/_metadata.py +141 -0
  12. benchmarks/_misc.py +653 -0
  13. benchmarks/_perf.py +321 -0
  14. benchmarks/_perm_group_calibration.py +175 -0
  15. benchmarks/_pointwise.py +372 -0
  16. benchmarks/_polynomial.py +193 -0
  17. benchmarks/_random.py +209 -0
  18. benchmarks/_reductions.py +136 -0
  19. benchmarks/_sorting.py +289 -0
  20. benchmarks/_stats.py +137 -0
  21. benchmarks/_window.py +92 -0
  22. benchmarks/accumulation/__init__.py +0 -0
  23. benchmarks/accumulation/bench_cost_compute.py +138 -0
  24. benchmarks/dashboard.py +312 -0
  25. benchmarks/runner.py +636 -0
  26. flopscope/__init__.py +273 -0
  27. flopscope/_accumulation/__init__.py +13 -0
  28. flopscope/_accumulation/_bipartite.py +121 -0
  29. flopscope/_accumulation/_burnside.py +51 -0
  30. flopscope/_accumulation/_cache.py +146 -0
  31. flopscope/_accumulation/_components.py +153 -0
  32. flopscope/_accumulation/_cost.py +1414 -0
  33. flopscope/_accumulation/_cost_descriptions.py +63 -0
  34. flopscope/_accumulation/_detection.py +318 -0
  35. flopscope/_accumulation/_ladder.py +191 -0
  36. flopscope/_accumulation/_output_orbit.py +104 -0
  37. flopscope/_accumulation/_partition.py +290 -0
  38. flopscope/_accumulation/_path_info.py +211 -0
  39. flopscope/_accumulation/_public.py +169 -0
  40. flopscope/_accumulation/_reduction.py +310 -0
  41. flopscope/_accumulation/_regimes.py +303 -0
  42. flopscope/_accumulation/_shape.py +33 -0
  43. flopscope/_accumulation/_wreath.py +209 -0
  44. flopscope/_budget.py +1027 -0
  45. flopscope/_config.py +118 -0
  46. flopscope/_counting_ops.py +451 -0
  47. flopscope/_display.py +478 -0
  48. flopscope/_docstrings.py +59 -0
  49. flopscope/_dtypes.py +20 -0
  50. flopscope/_einsum.py +717 -0
  51. flopscope/_errstate.py +25 -0
  52. flopscope/_flops.py +282 -0
  53. flopscope/_free_ops.py +2654 -0
  54. flopscope/_ndarray.py +1126 -0
  55. flopscope/_opt_einsum/LICENSE +21 -0
  56. flopscope/_opt_einsum/NOTICE +59 -0
  57. flopscope/_opt_einsum/__init__.py +209 -0
  58. flopscope/_opt_einsum/_contract.py +1478 -0
  59. flopscope/_opt_einsum/_helpers.py +164 -0
  60. flopscope/_opt_einsum/_hsluv.py +273 -0
  61. flopscope/_opt_einsum/_path_random.py +462 -0
  62. flopscope/_opt_einsum/_paths.py +1653 -0
  63. flopscope/_opt_einsum/_subgraph_symmetry.py +544 -0
  64. flopscope/_opt_einsum/_symmetry.py +140 -0
  65. flopscope/_opt_einsum/_typing.py +37 -0
  66. flopscope/_perm_group.py +717 -0
  67. flopscope/_pointwise.py +2522 -0
  68. flopscope/_polynomial.py +278 -0
  69. flopscope/_registry.py +3216 -0
  70. flopscope/_sorting_ops.py +571 -0
  71. flopscope/_symmetric.py +812 -0
  72. flopscope/_symmetry_transport.py +510 -0
  73. flopscope/_symmetry_utils.py +669 -0
  74. flopscope/_type_info.py +12 -0
  75. flopscope/_unwrap.py +70 -0
  76. flopscope/_validation.py +83 -0
  77. flopscope/_version_check.py +46 -0
  78. flopscope/_weights.py +195 -0
  79. flopscope/_window.py +177 -0
  80. flopscope/accounting.py +565 -0
  81. flopscope/data/default_weights.json +462 -0
  82. flopscope/data/weights.csv +509 -0
  83. flopscope/errors.py +197 -0
  84. flopscope/numpy/__init__.py +878 -0
  85. flopscope/numpy/fft/__init__.py +55 -0
  86. flopscope/numpy/fft/_free.py +51 -0
  87. flopscope/numpy/fft/_transforms.py +695 -0
  88. flopscope/numpy/linalg/__init__.py +105 -0
  89. flopscope/numpy/linalg/_aliases.py +126 -0
  90. flopscope/numpy/linalg/_compound.py +161 -0
  91. flopscope/numpy/linalg/_decompositions.py +353 -0
  92. flopscope/numpy/linalg/_properties.py +533 -0
  93. flopscope/numpy/linalg/_solvers.py +444 -0
  94. flopscope/numpy/linalg/_svd.py +122 -0
  95. flopscope/numpy/random/__init__.py +684 -0
  96. flopscope/numpy/random/_cost_formulas.py +115 -0
  97. flopscope/numpy/random/_counted_classes.py +241 -0
  98. flopscope/numpy/testing/__init__.py +13 -0
  99. flopscope/numpy/typing/__init__.py +30 -0
  100. flopscope/py.typed +0 -0
  101. flopscope/stats/__init__.py +84 -0
  102. flopscope/stats/_base.py +77 -0
  103. flopscope/stats/_cauchy.py +146 -0
  104. flopscope/stats/_erf.py +190 -0
  105. flopscope/stats/_expon.py +146 -0
  106. flopscope/stats/_laplace.py +150 -0
  107. flopscope/stats/_logistic.py +148 -0
  108. flopscope/stats/_lognorm.py +160 -0
  109. flopscope/stats/_ndtri.py +133 -0
  110. flopscope/stats/_norm.py +149 -0
  111. flopscope/stats/_truncnorm.py +186 -0
  112. flopscope/stats/_uniform.py +141 -0
  113. flopscope-0.2.0.dist-info/METADATA +23 -0
  114. flopscope-0.2.0.dist-info/RECORD +115 -0
  115. flopscope-0.2.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,565 @@
1
+ """Public FLOP cost query API.
2
+
3
+ All exported helpers return weighted FLOP costs by default, using the active
4
+ operation multipliers from ``flopscope._weights``. The underlying analytical
5
+ formulas remain available to the runtime in the private modules.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import inspect
11
+ from functools import wraps
12
+
13
+ from flopscope._flops import (
14
+ analytical_pointwise_cost as _analytical_pointwise_cost,
15
+ )
16
+ from flopscope._flops import (
17
+ analytical_reduction_cost as _analytical_reduction_cost,
18
+ )
19
+ from flopscope._flops import (
20
+ einsum_cost as _analytical_einsum_cost,
21
+ )
22
+ from flopscope._flops import (
23
+ svd_cost as _analytical_svd_cost,
24
+ )
25
+ from flopscope._perm_group import SymmetryGroup
26
+ from flopscope._polynomial import (
27
+ poly_cost as _analytical_poly_cost,
28
+ )
29
+ from flopscope._polynomial import (
30
+ polyadd_cost as _analytical_polyadd_cost,
31
+ )
32
+ from flopscope._polynomial import (
33
+ polyder_cost as _analytical_polyder_cost,
34
+ )
35
+ from flopscope._polynomial import (
36
+ polydiv_cost as _analytical_polydiv_cost,
37
+ )
38
+ from flopscope._polynomial import (
39
+ polyfit_cost as _analytical_polyfit_cost,
40
+ )
41
+ from flopscope._polynomial import (
42
+ polyint_cost as _analytical_polyint_cost,
43
+ )
44
+ from flopscope._polynomial import (
45
+ polymul_cost as _analytical_polymul_cost,
46
+ )
47
+ from flopscope._polynomial import (
48
+ polysub_cost as _analytical_polysub_cost,
49
+ )
50
+ from flopscope._polynomial import (
51
+ polyval_cost as _analytical_polyval_cost,
52
+ )
53
+ from flopscope._polynomial import (
54
+ roots_cost as _analytical_roots_cost,
55
+ )
56
+ from flopscope._unwrap import unwrap_cost as _analytical_unwrap_cost
57
+ from flopscope._weights import get_weight
58
+ from flopscope._window import (
59
+ bartlett_cost as _analytical_bartlett_cost,
60
+ )
61
+ from flopscope._window import (
62
+ blackman_cost as _analytical_blackman_cost,
63
+ )
64
+ from flopscope._window import (
65
+ hamming_cost as _analytical_hamming_cost,
66
+ )
67
+ from flopscope._window import (
68
+ hanning_cost as _analytical_hanning_cost,
69
+ )
70
+ from flopscope._window import (
71
+ kaiser_cost as _analytical_kaiser_cost,
72
+ )
73
+ from flopscope.numpy.fft._transforms import (
74
+ fft_cost as _analytical_fft_cost,
75
+ )
76
+ from flopscope.numpy.fft._transforms import (
77
+ fftn_cost as _analytical_fftn_cost,
78
+ )
79
+ from flopscope.numpy.fft._transforms import (
80
+ hfft_cost as _analytical_hfft_cost,
81
+ )
82
+ from flopscope.numpy.fft._transforms import (
83
+ rfft_cost as _analytical_rfft_cost,
84
+ )
85
+ from flopscope.numpy.fft._transforms import (
86
+ rfftn_cost as _analytical_rfftn_cost,
87
+ )
88
+ from flopscope.numpy.linalg._compound import (
89
+ matrix_power_cost as _analytical_matrix_power_cost,
90
+ )
91
+ from flopscope.numpy.linalg._compound import (
92
+ multi_dot_cost as _analytical_multi_dot_cost,
93
+ )
94
+ from flopscope.numpy.linalg._decompositions import (
95
+ cholesky_cost as _analytical_cholesky_cost,
96
+ )
97
+ from flopscope.numpy.linalg._decompositions import (
98
+ eig_cost as _analytical_eig_cost,
99
+ )
100
+ from flopscope.numpy.linalg._decompositions import (
101
+ eigh_cost as _analytical_eigh_cost,
102
+ )
103
+ from flopscope.numpy.linalg._decompositions import (
104
+ eigvals_cost as _analytical_eigvals_cost,
105
+ )
106
+ from flopscope.numpy.linalg._decompositions import (
107
+ eigvalsh_cost as _analytical_eigvalsh_cost,
108
+ )
109
+ from flopscope.numpy.linalg._decompositions import (
110
+ qr_cost as _analytical_qr_cost,
111
+ )
112
+ from flopscope.numpy.linalg._decompositions import (
113
+ svdvals_cost as _analytical_svdvals_cost,
114
+ )
115
+ from flopscope.numpy.linalg._properties import (
116
+ cond_cost as _analytical_cond_cost,
117
+ )
118
+ from flopscope.numpy.linalg._properties import (
119
+ det_cost as _analytical_det_cost,
120
+ )
121
+ from flopscope.numpy.linalg._properties import (
122
+ matrix_norm_cost as _analytical_matrix_norm_cost,
123
+ )
124
+ from flopscope.numpy.linalg._properties import (
125
+ matrix_rank_cost as _analytical_matrix_rank_cost,
126
+ )
127
+ from flopscope.numpy.linalg._properties import (
128
+ norm_cost as _analytical_norm_cost,
129
+ )
130
+ from flopscope.numpy.linalg._properties import (
131
+ slogdet_cost as _analytical_slogdet_cost,
132
+ )
133
+ from flopscope.numpy.linalg._properties import (
134
+ trace_cost as _analytical_trace_cost,
135
+ )
136
+ from flopscope.numpy.linalg._properties import (
137
+ vector_norm_cost as _analytical_vector_norm_cost,
138
+ )
139
+ from flopscope.numpy.linalg._solvers import (
140
+ inv_cost as _analytical_inv_cost,
141
+ )
142
+ from flopscope.numpy.linalg._solvers import (
143
+ lstsq_cost as _analytical_lstsq_cost,
144
+ )
145
+ from flopscope.numpy.linalg._solvers import (
146
+ pinv_cost as _analytical_pinv_cost,
147
+ )
148
+ from flopscope.numpy.linalg._solvers import (
149
+ solve_cost as _analytical_solve_cost,
150
+ )
151
+ from flopscope.numpy.linalg._solvers import (
152
+ tensorinv_cost as _analytical_tensorinv_cost,
153
+ )
154
+ from flopscope.numpy.linalg._solvers import (
155
+ tensorsolve_cost as _analytical_tensorsolve_cost,
156
+ )
157
+
158
+
159
+ def _weight_cost(op_name: str, analytical_cost: int) -> int:
160
+ """Convert an analytical FLOP count into the public weighted estimate.
161
+
162
+ This intentionally mirrors ``BudgetContext.deduct()`` by flooring via
163
+ ``int(...)`` after applying the weight multiplier, so public estimates and
164
+ runtime accounting stay in sync.
165
+ """
166
+ return int(analytical_cost * get_weight(op_name))
167
+
168
+
169
+ def _make_weighted_cost(op_name: str, analytical_fn):
170
+ example = _EXAMPLE_DOCS.get(op_name)
171
+
172
+ @wraps(analytical_fn)
173
+ def wrapper(*args, **kwargs):
174
+ return _weight_cost(op_name, analytical_fn(*args, **kwargs))
175
+
176
+ wrapper.__doc__ = _build_weighted_cost_docstring(
177
+ op_name,
178
+ analytical_fn,
179
+ example=example,
180
+ )
181
+ return wrapper
182
+
183
+
184
+ _EXAMPLE_DOCS = {
185
+ "einsum": """\
186
+ >>> import flopscope as flops
187
+ >>> cost = flops.accounting.einsum_cost(
188
+ ... "ij,jk->ik",
189
+ ... [(8, 16), (16, 4)],
190
+ ... )
191
+ >>> isinstance(cost, int)
192
+ True
193
+ """,
194
+ "linalg.svd": """\
195
+ >>> import flopscope as flops
196
+ >>> cost = flops.accounting.svd_cost(128, 64)
197
+ >>> isinstance(cost, int)
198
+ True
199
+ """,
200
+ }
201
+
202
+
203
+ _PARAMETER_DESCRIPTIONS = {
204
+ "axis": "Axis or axes forwarded to the analytical cost formula.",
205
+ "input_shape": "Shape of the reduction input.",
206
+ "k": "Target rank or number of singular components to estimate.",
207
+ "m": "Number of rows in the input matrix.",
208
+ "n": "Number of columns in the input matrix.",
209
+ "operand_symmetries": "Optional symmetry metadata for each einsum operand.",
210
+ "shape": "Shape of the array passed to the analytical cost formula.",
211
+ "shapes": "Operand shapes in the same order as the einsum operands.",
212
+ "subscripts": "Einstein summation expression that defines the contraction.",
213
+ "symmetry_info": (
214
+ "Optional symmetry metadata used to count only analytically distinct elements."
215
+ ),
216
+ }
217
+
218
+
219
+ def _build_weighted_cost_docstring(
220
+ op_name: str,
221
+ analytical_fn,
222
+ *,
223
+ example: str | None = None,
224
+ ) -> str:
225
+ summary, description, notes = _parse_analytical_doc(analytical_fn.__doc__ or "")
226
+ signature = inspect.signature(analytical_fn)
227
+
228
+ parts = [
229
+ _make_weighted_summary(summary, op_name),
230
+ ]
231
+ if description:
232
+ parts.extend(["", description])
233
+ parts.extend(
234
+ [
235
+ "",
236
+ "Parameters",
237
+ "----------",
238
+ _render_parameters(signature, op_name),
239
+ "",
240
+ "Returns",
241
+ "-------",
242
+ "int",
243
+ " Weighted public cost estimate, floored to match runtime accounting.",
244
+ "",
245
+ "Notes",
246
+ "-----",
247
+ (
248
+ "This helper multiplies the analytical FLOP count by the active "
249
+ "weight from ``flopscope._weights`` and then applies ``int(...)`` "
250
+ "so public estimates match budget deductions."
251
+ ),
252
+ ]
253
+ )
254
+ if notes:
255
+ parts.extend(["", notes])
256
+ if example:
257
+ parts.extend(["", "Examples", "--------", example.rstrip()])
258
+ return "\n".join(parts)
259
+
260
+
261
+ def _make_weighted_summary(summary: str, op_name: str) -> str:
262
+ if summary:
263
+ return summary.replace("FLOP cost", "Weighted FLOP cost", 1)
264
+ return f"Weighted FLOP cost estimate for ``{op_name}``."
265
+
266
+
267
+ def _parse_analytical_doc(doc: str) -> tuple[str, str, str]:
268
+ lines = inspect.cleandoc(doc).splitlines()
269
+ if not lines:
270
+ return "", "", ""
271
+
272
+ summary = ""
273
+ index = 0
274
+ while index < len(lines) and not lines[index].strip():
275
+ index += 1
276
+ if index < len(lines):
277
+ summary = lines[index].strip()
278
+ index += 1
279
+
280
+ while index < len(lines) and not lines[index].strip():
281
+ index += 1
282
+
283
+ description_lines: list[str] = []
284
+ notes_lines: list[str] = []
285
+ current_section: str | None = None
286
+
287
+ while index < len(lines):
288
+ if _is_numpydoc_header(lines, index):
289
+ current_section = lines[index].strip()
290
+ index += 2
291
+ continue
292
+
293
+ line = lines[index]
294
+ if current_section == "Notes":
295
+ notes_lines.append(line)
296
+ elif current_section is None:
297
+ description_lines.append(line)
298
+ index += 1
299
+
300
+ description = "\n".join(description_lines).strip()
301
+ notes = "\n".join(notes_lines).strip()
302
+ return summary, description, notes
303
+
304
+
305
+ def _is_numpydoc_header(lines: list[str], index: int) -> bool:
306
+ if index + 1 >= len(lines):
307
+ return False
308
+ title = lines[index].strip()
309
+ underline = lines[index + 1].strip()
310
+ return bool(title) and underline == "-" * len(title)
311
+
312
+
313
+ def _render_parameters(signature: inspect.Signature, op_name: str) -> str:
314
+ rendered: list[str] = []
315
+ for parameter in signature.parameters.values():
316
+ annotation = _format_annotation(parameter.annotation)
317
+ header = parameter.name
318
+ if annotation:
319
+ header = f"{header} : {annotation}"
320
+ if parameter.default is not inspect.Signature.empty:
321
+ header = f"{header}, optional"
322
+
323
+ description = _PARAMETER_DESCRIPTIONS.get(
324
+ parameter.name,
325
+ f"Argument forwarded to the analytical ``{op_name}`` cost formula.",
326
+ )
327
+ if parameter.default is not inspect.Signature.empty:
328
+ description = f"{description} Defaults to ``{parameter.default!r}``."
329
+ rendered.append(f"{header}\n {description}")
330
+ return "\n\n".join(rendered)
331
+
332
+
333
+ def _format_annotation(annotation) -> str:
334
+ if annotation is inspect.Signature.empty:
335
+ return "object"
336
+ if isinstance(annotation, str):
337
+ return annotation
338
+ return getattr(annotation, "__name__", repr(annotation))
339
+
340
+
341
+ def pointwise_cost(
342
+ op_name: str,
343
+ *,
344
+ shape: tuple[int, ...],
345
+ symmetry: SymmetryGroup | None = None,
346
+ ) -> int:
347
+ """Weighted FLOP cost of a pointwise operation.
348
+
349
+ Parameters
350
+ ----------
351
+ op_name : str
352
+ Operation name used for weight lookup, e.g. ``"exp"`` or ``"add"``.
353
+ shape : tuple of int
354
+ Output shape of the pointwise operation.
355
+ symmetry : SymmetryGroup or None, optional
356
+ If provided, only unique elements are counted analytically before the
357
+ operation weight is applied.
358
+
359
+ Returns
360
+ -------
361
+ int
362
+ Weighted public cost estimate, floored to match runtime accounting.
363
+
364
+ Notes
365
+ -----
366
+ This helper multiplies the analytical pointwise count by the active weight
367
+ for ``op_name`` and then floors with ``int(...)`` to match runtime budget
368
+ accounting.
369
+
370
+ Examples
371
+ --------
372
+ >>> import flopscope as flops
373
+ >>> cost = flops.accounting.pointwise_cost("exp", shape=(2, 3))
374
+ >>> isinstance(cost, int)
375
+ True
376
+ """
377
+ if not isinstance(op_name, str):
378
+ raise TypeError("pointwise_cost() requires op_name as the first argument")
379
+ return _weight_cost(
380
+ op_name,
381
+ _analytical_pointwise_cost(shape, symmetry=symmetry),
382
+ )
383
+
384
+
385
+ def reduction_cost(
386
+ op_name: str,
387
+ *,
388
+ input_shape: tuple[int, ...],
389
+ axis: int | None = None,
390
+ symmetry: SymmetryGroup | None = None,
391
+ ) -> int:
392
+ """Weighted FLOP cost of a reduction operation.
393
+
394
+ Parameters
395
+ ----------
396
+ op_name : str
397
+ Operation name used for weight lookup, e.g. ``"sum"`` or ``"max"``.
398
+ input_shape : tuple of int
399
+ Shape of the reduction input.
400
+ axis : int or None, optional
401
+ Reduction axis. Accepted for API consistency with the analytical helper.
402
+ symmetry : SymmetryGroup or None, optional
403
+ If provided, only unique elements are counted analytically before the
404
+ operation weight is applied.
405
+
406
+ Returns
407
+ -------
408
+ int
409
+ Weighted public cost estimate, floored to match runtime accounting.
410
+
411
+ Notes
412
+ -----
413
+ This helper multiplies the analytical reduction count by the active weight
414
+ for ``op_name`` and then floors with ``int(...)`` to match runtime budget
415
+ accounting.
416
+
417
+ Examples
418
+ --------
419
+ >>> import flopscope as flops
420
+ >>> cost = flops.accounting.reduction_cost(
421
+ ... "sum",
422
+ ... input_shape=(4, 5),
423
+ ... axis=1,
424
+ ... )
425
+ >>> isinstance(cost, int)
426
+ True
427
+ """
428
+ if not isinstance(op_name, str):
429
+ raise TypeError("reduction_cost() requires op_name as the first argument")
430
+ return _weight_cost(
431
+ op_name,
432
+ _analytical_reduction_cost(
433
+ input_shape,
434
+ axis=axis,
435
+ symmetry=symmetry,
436
+ ),
437
+ )
438
+
439
+
440
+ einsum_cost = _make_weighted_cost("einsum", _analytical_einsum_cost)
441
+ svd_cost = _make_weighted_cost("linalg.svd", _analytical_svd_cost)
442
+
443
+ polyval_cost = _make_weighted_cost("polyval", _analytical_polyval_cost)
444
+ polyadd_cost = _make_weighted_cost("polyadd", _analytical_polyadd_cost)
445
+ polysub_cost = _make_weighted_cost("polysub", _analytical_polysub_cost)
446
+ polymul_cost = _make_weighted_cost("polymul", _analytical_polymul_cost)
447
+ polydiv_cost = _make_weighted_cost("polydiv", _analytical_polydiv_cost)
448
+ polyfit_cost = _make_weighted_cost("polyfit", _analytical_polyfit_cost)
449
+ poly_cost = _make_weighted_cost("poly", _analytical_poly_cost)
450
+ roots_cost = _make_weighted_cost("roots", _analytical_roots_cost)
451
+ polyder_cost = _make_weighted_cost("polyder", _analytical_polyder_cost)
452
+ polyint_cost = _make_weighted_cost("polyint", _analytical_polyint_cost)
453
+
454
+ unwrap_cost = _make_weighted_cost("unwrap", _analytical_unwrap_cost)
455
+
456
+ bartlett_cost = _make_weighted_cost("bartlett", _analytical_bartlett_cost)
457
+ blackman_cost = _make_weighted_cost("blackman", _analytical_blackman_cost)
458
+ hamming_cost = _make_weighted_cost("hamming", _analytical_hamming_cost)
459
+ hanning_cost = _make_weighted_cost("hanning", _analytical_hanning_cost)
460
+ kaiser_cost = _make_weighted_cost("kaiser", _analytical_kaiser_cost)
461
+
462
+ fft_cost = _make_weighted_cost("fft.fft", _analytical_fft_cost)
463
+ rfft_cost = _make_weighted_cost("fft.rfft", _analytical_rfft_cost)
464
+ fftn_cost = _make_weighted_cost("fft.fftn", _analytical_fftn_cost)
465
+ rfftn_cost = _make_weighted_cost("fft.rfftn", _analytical_rfftn_cost)
466
+ hfft_cost = _make_weighted_cost("fft.hfft", _analytical_hfft_cost)
467
+
468
+ multi_dot_cost = _make_weighted_cost("linalg.multi_dot", _analytical_multi_dot_cost)
469
+ matrix_power_cost = _make_weighted_cost(
470
+ "linalg.matrix_power",
471
+ _analytical_matrix_power_cost,
472
+ )
473
+
474
+ cholesky_cost = _make_weighted_cost("linalg.cholesky", _analytical_cholesky_cost)
475
+ qr_cost = _make_weighted_cost("linalg.qr", _analytical_qr_cost)
476
+ eig_cost = _make_weighted_cost("linalg.eig", _analytical_eig_cost)
477
+ eigh_cost = _make_weighted_cost("linalg.eigh", _analytical_eigh_cost)
478
+ eigvals_cost = _make_weighted_cost("linalg.eigvals", _analytical_eigvals_cost)
479
+ eigvalsh_cost = _make_weighted_cost("linalg.eigvalsh", _analytical_eigvalsh_cost)
480
+ svdvals_cost = _make_weighted_cost("linalg.svdvals", _analytical_svdvals_cost)
481
+
482
+ trace_cost = _make_weighted_cost("linalg.trace", _analytical_trace_cost)
483
+ det_cost = _make_weighted_cost("linalg.det", _analytical_det_cost)
484
+ slogdet_cost = _make_weighted_cost("linalg.slogdet", _analytical_slogdet_cost)
485
+ norm_cost = _make_weighted_cost("linalg.norm", _analytical_norm_cost)
486
+ vector_norm_cost = _make_weighted_cost(
487
+ "linalg.vector_norm",
488
+ _analytical_vector_norm_cost,
489
+ )
490
+ matrix_norm_cost = _make_weighted_cost(
491
+ "linalg.matrix_norm",
492
+ _analytical_matrix_norm_cost,
493
+ )
494
+ cond_cost = _make_weighted_cost("linalg.cond", _analytical_cond_cost)
495
+ matrix_rank_cost = _make_weighted_cost(
496
+ "linalg.matrix_rank",
497
+ _analytical_matrix_rank_cost,
498
+ )
499
+
500
+ solve_cost = _make_weighted_cost("linalg.solve", _analytical_solve_cost)
501
+ inv_cost = _make_weighted_cost("linalg.inv", _analytical_inv_cost)
502
+ lstsq_cost = _make_weighted_cost("linalg.lstsq", _analytical_lstsq_cost)
503
+ pinv_cost = _make_weighted_cost("linalg.pinv", _analytical_pinv_cost)
504
+ tensorsolve_cost = _make_weighted_cost(
505
+ "linalg.tensorsolve",
506
+ _analytical_tensorsolve_cost,
507
+ )
508
+ tensorinv_cost = _make_weighted_cost("linalg.tensorinv", _analytical_tensorinv_cost)
509
+
510
+ __all__ = [
511
+ # Existing
512
+ "einsum_cost",
513
+ "pointwise_cost",
514
+ "reduction_cost",
515
+ "svd_cost",
516
+ # Linalg
517
+ "cholesky_cost",
518
+ "qr_cost",
519
+ "eig_cost",
520
+ "eigh_cost",
521
+ "eigvals_cost",
522
+ "eigvalsh_cost",
523
+ "svdvals_cost",
524
+ "solve_cost",
525
+ "inv_cost",
526
+ "lstsq_cost",
527
+ "pinv_cost",
528
+ "tensorsolve_cost",
529
+ "tensorinv_cost",
530
+ "trace_cost",
531
+ "det_cost",
532
+ "slogdet_cost",
533
+ "norm_cost",
534
+ "vector_norm_cost",
535
+ "matrix_norm_cost",
536
+ "cond_cost",
537
+ "matrix_rank_cost",
538
+ "multi_dot_cost",
539
+ "matrix_power_cost",
540
+ # FFT
541
+ "fft_cost",
542
+ "rfft_cost",
543
+ "fftn_cost",
544
+ "rfftn_cost",
545
+ "hfft_cost",
546
+ # Polynomial
547
+ "polyval_cost",
548
+ "polyadd_cost",
549
+ "polysub_cost",
550
+ "polymul_cost",
551
+ "polydiv_cost",
552
+ "polyfit_cost",
553
+ "poly_cost",
554
+ "roots_cost",
555
+ "polyder_cost",
556
+ "polyint_cost",
557
+ # Window
558
+ "bartlett_cost",
559
+ "blackman_cost",
560
+ "hamming_cost",
561
+ "hanning_cost",
562
+ "kaiser_cost",
563
+ # Other
564
+ "unwrap_cost",
565
+ ]