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.
- benchmarks/__init__.py +1 -0
- benchmarks/__main__.py +6 -0
- benchmarks/_baseline.py +171 -0
- benchmarks/_bitwise.py +231 -0
- benchmarks/_complex.py +176 -0
- benchmarks/_contractions.py +291 -0
- benchmarks/_fft.py +198 -0
- benchmarks/_impl_urls.py +139 -0
- benchmarks/_linalg.py +197 -0
- benchmarks/_linalg_delegates.py +407 -0
- benchmarks/_metadata.py +141 -0
- benchmarks/_misc.py +653 -0
- benchmarks/_perf.py +321 -0
- benchmarks/_perm_group_calibration.py +175 -0
- benchmarks/_pointwise.py +372 -0
- benchmarks/_polynomial.py +193 -0
- benchmarks/_random.py +209 -0
- benchmarks/_reductions.py +136 -0
- benchmarks/_sorting.py +289 -0
- benchmarks/_stats.py +137 -0
- benchmarks/_window.py +92 -0
- benchmarks/accumulation/__init__.py +0 -0
- benchmarks/accumulation/bench_cost_compute.py +138 -0
- benchmarks/dashboard.py +312 -0
- benchmarks/runner.py +636 -0
- flopscope/__init__.py +273 -0
- flopscope/_accumulation/__init__.py +13 -0
- flopscope/_accumulation/_bipartite.py +121 -0
- flopscope/_accumulation/_burnside.py +51 -0
- flopscope/_accumulation/_cache.py +146 -0
- flopscope/_accumulation/_components.py +153 -0
- flopscope/_accumulation/_cost.py +1414 -0
- flopscope/_accumulation/_cost_descriptions.py +63 -0
- flopscope/_accumulation/_detection.py +318 -0
- flopscope/_accumulation/_ladder.py +191 -0
- flopscope/_accumulation/_output_orbit.py +104 -0
- flopscope/_accumulation/_partition.py +290 -0
- flopscope/_accumulation/_path_info.py +211 -0
- flopscope/_accumulation/_public.py +169 -0
- flopscope/_accumulation/_reduction.py +310 -0
- flopscope/_accumulation/_regimes.py +303 -0
- flopscope/_accumulation/_shape.py +33 -0
- flopscope/_accumulation/_wreath.py +209 -0
- flopscope/_budget.py +1027 -0
- flopscope/_config.py +118 -0
- flopscope/_counting_ops.py +451 -0
- flopscope/_display.py +478 -0
- flopscope/_docstrings.py +59 -0
- flopscope/_dtypes.py +20 -0
- flopscope/_einsum.py +717 -0
- flopscope/_errstate.py +25 -0
- flopscope/_flops.py +282 -0
- flopscope/_free_ops.py +2654 -0
- flopscope/_ndarray.py +1126 -0
- flopscope/_opt_einsum/LICENSE +21 -0
- flopscope/_opt_einsum/NOTICE +59 -0
- flopscope/_opt_einsum/__init__.py +209 -0
- flopscope/_opt_einsum/_contract.py +1478 -0
- flopscope/_opt_einsum/_helpers.py +164 -0
- flopscope/_opt_einsum/_hsluv.py +273 -0
- flopscope/_opt_einsum/_path_random.py +462 -0
- flopscope/_opt_einsum/_paths.py +1653 -0
- flopscope/_opt_einsum/_subgraph_symmetry.py +544 -0
- flopscope/_opt_einsum/_symmetry.py +140 -0
- flopscope/_opt_einsum/_typing.py +37 -0
- flopscope/_perm_group.py +717 -0
- flopscope/_pointwise.py +2522 -0
- flopscope/_polynomial.py +278 -0
- flopscope/_registry.py +3216 -0
- flopscope/_sorting_ops.py +571 -0
- flopscope/_symmetric.py +812 -0
- flopscope/_symmetry_transport.py +510 -0
- flopscope/_symmetry_utils.py +669 -0
- flopscope/_type_info.py +12 -0
- flopscope/_unwrap.py +70 -0
- flopscope/_validation.py +83 -0
- flopscope/_version_check.py +46 -0
- flopscope/_weights.py +195 -0
- flopscope/_window.py +177 -0
- flopscope/accounting.py +565 -0
- flopscope/data/default_weights.json +462 -0
- flopscope/data/weights.csv +509 -0
- flopscope/errors.py +197 -0
- flopscope/numpy/__init__.py +878 -0
- flopscope/numpy/fft/__init__.py +55 -0
- flopscope/numpy/fft/_free.py +51 -0
- flopscope/numpy/fft/_transforms.py +695 -0
- flopscope/numpy/linalg/__init__.py +105 -0
- flopscope/numpy/linalg/_aliases.py +126 -0
- flopscope/numpy/linalg/_compound.py +161 -0
- flopscope/numpy/linalg/_decompositions.py +353 -0
- flopscope/numpy/linalg/_properties.py +533 -0
- flopscope/numpy/linalg/_solvers.py +444 -0
- flopscope/numpy/linalg/_svd.py +122 -0
- flopscope/numpy/random/__init__.py +684 -0
- flopscope/numpy/random/_cost_formulas.py +115 -0
- flopscope/numpy/random/_counted_classes.py +241 -0
- flopscope/numpy/testing/__init__.py +13 -0
- flopscope/numpy/typing/__init__.py +30 -0
- flopscope/py.typed +0 -0
- flopscope/stats/__init__.py +84 -0
- flopscope/stats/_base.py +77 -0
- flopscope/stats/_cauchy.py +146 -0
- flopscope/stats/_erf.py +190 -0
- flopscope/stats/_expon.py +146 -0
- flopscope/stats/_laplace.py +150 -0
- flopscope/stats/_logistic.py +148 -0
- flopscope/stats/_lognorm.py +160 -0
- flopscope/stats/_ndtri.py +133 -0
- flopscope/stats/_norm.py +149 -0
- flopscope/stats/_truncnorm.py +186 -0
- flopscope/stats/_uniform.py +141 -0
- flopscope-0.2.0.dist-info/METADATA +23 -0
- flopscope-0.2.0.dist-info/RECORD +115 -0
- flopscope-0.2.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
# src/flopscope/linalg/_decompositions.py
|
|
2
|
+
"""Matrix decomposition wrappers with FLOP counting.
|
|
3
|
+
|
|
4
|
+
Each operation has a co-located cost function documenting the formula,
|
|
5
|
+
source, and assumptions. Cost functions are pure (shape params) -> int.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import numpy as _np
|
|
11
|
+
from numpy.linalg._linalg import EighResult, EigResult, QRResult
|
|
12
|
+
from numpy.typing import ArrayLike
|
|
13
|
+
|
|
14
|
+
from flopscope._budget import _call_numpy, _counted_wrapper
|
|
15
|
+
from flopscope._docstrings import attach_docstring
|
|
16
|
+
from flopscope._ndarray import FlopscopeArray, _asflopscope, _to_base_ndarray
|
|
17
|
+
from flopscope._validation import require_budget
|
|
18
|
+
from flopscope.numpy.linalg._solvers import _batch_size, _has_zero_dim
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def cholesky_cost(n: int) -> int:
|
|
22
|
+
"""FLOP cost of Cholesky decomposition.
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
n : int
|
|
27
|
+
Matrix dimension.
|
|
28
|
+
|
|
29
|
+
Returns
|
|
30
|
+
-------
|
|
31
|
+
int
|
|
32
|
+
Estimated FLOP count: $n^3$.
|
|
33
|
+
|
|
34
|
+
Notes
|
|
35
|
+
-----
|
|
36
|
+
Simplified cubic cost model for Cholesky decomposition.
|
|
37
|
+
"""
|
|
38
|
+
return max(n**3, 1)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@_counted_wrapper
|
|
42
|
+
def cholesky(a: ArrayLike, /, *, upper: bool = False) -> FlopscopeArray:
|
|
43
|
+
"""Cholesky decomposition with FLOP counting."""
|
|
44
|
+
budget = require_budget()
|
|
45
|
+
inputs_were_whest = isinstance(a, FlopscopeArray)
|
|
46
|
+
if not isinstance(a, _np.ndarray):
|
|
47
|
+
a = _np.asarray(a)
|
|
48
|
+
n = a.shape[-1]
|
|
49
|
+
batch = _batch_size(a.shape)
|
|
50
|
+
cost = cholesky_cost(n) * batch if not _has_zero_dim(a.shape) else 0
|
|
51
|
+
with budget.deduct(
|
|
52
|
+
"linalg.cholesky", flop_cost=cost, subscripts=None, shapes=(a.shape,)
|
|
53
|
+
):
|
|
54
|
+
result = _call_numpy(_np.linalg.cholesky, _to_base_ndarray(a), upper=upper)
|
|
55
|
+
if isinstance(result, _np.ndarray) and inputs_were_whest:
|
|
56
|
+
return _asflopscope(result) # type: ignore[reportReturnType]
|
|
57
|
+
return result # type: ignore[reportReturnType]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
attach_docstring(cholesky, _np.linalg.cholesky, "linalg", r"$n^3$ FLOPs")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def qr_cost(m: int, n: int) -> int:
|
|
64
|
+
r"""FLOP cost of QR decomposition.
|
|
65
|
+
|
|
66
|
+
Parameters
|
|
67
|
+
----------
|
|
68
|
+
m : int
|
|
69
|
+
Number of rows.
|
|
70
|
+
n : int
|
|
71
|
+
Number of columns.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
int
|
|
76
|
+
Estimated FLOP count: $m \cdot n \cdot \min(m, n)$.
|
|
77
|
+
|
|
78
|
+
Notes
|
|
79
|
+
-----
|
|
80
|
+
Simplified cubic cost model for QR decomposition.
|
|
81
|
+
"""
|
|
82
|
+
return max(m * n * min(m, n), 1)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@_counted_wrapper
|
|
86
|
+
def qr(
|
|
87
|
+
a: ArrayLike, mode: str = "reduced"
|
|
88
|
+
) -> tuple[FlopscopeArray, FlopscopeArray] | FlopscopeArray:
|
|
89
|
+
"""QR decomposition with FLOP counting.
|
|
90
|
+
|
|
91
|
+
Returns vary by ``mode``:
|
|
92
|
+
|
|
93
|
+
- ``"reduced"`` (default) / ``"complete"`` → ``QRResult(q, r)``
|
|
94
|
+
- ``"r"`` → ``r`` only
|
|
95
|
+
- ``"raw"`` → 2-tuple ``(h, tau)`` of two ndarrays with mismatched
|
|
96
|
+
shapes (preserved as a tuple rather than collapsed via
|
|
97
|
+
``_asflopscope``, which would otherwise fail with
|
|
98
|
+
``ValueError: ... inhomogeneous shape``)
|
|
99
|
+
"""
|
|
100
|
+
budget = require_budget()
|
|
101
|
+
inputs_were_whest = isinstance(a, FlopscopeArray)
|
|
102
|
+
if not isinstance(a, _np.ndarray):
|
|
103
|
+
a = _np.asarray(a)
|
|
104
|
+
m, n = a.shape[-2], a.shape[-1]
|
|
105
|
+
batch = _batch_size(a.shape)
|
|
106
|
+
cost = qr_cost(m, n) * batch if not _has_zero_dim(a.shape) else 0
|
|
107
|
+
with budget.deduct("linalg.qr", flop_cost=cost, subscripts=None, shapes=(a.shape,)):
|
|
108
|
+
result = _call_numpy(_np.linalg.qr, _to_base_ndarray(a), mode=mode) # type: ignore[reportCallIssue]
|
|
109
|
+
if mode in ("reduced", "complete"):
|
|
110
|
+
q, r = result # type: ignore[reportGeneralTypeIssues]
|
|
111
|
+
if inputs_were_whest:
|
|
112
|
+
return QRResult(_asflopscope(q), _asflopscope(r)) # type: ignore[reportReturnType]
|
|
113
|
+
return QRResult(q, r) # type: ignore[reportReturnType]
|
|
114
|
+
if mode == "raw":
|
|
115
|
+
# ``raw`` returns a (h, tau) tuple of two ndarrays with different
|
|
116
|
+
# shapes — preserve the tuple structure rather than collapsing to
|
|
117
|
+
# a single array via ``_asflopscope``.
|
|
118
|
+
h, tau = result # type: ignore[reportGeneralTypeIssues]
|
|
119
|
+
if inputs_were_whest:
|
|
120
|
+
return _asflopscope(h), _asflopscope(tau) # type: ignore[reportReturnType]
|
|
121
|
+
return h, tau # type: ignore[reportReturnType]
|
|
122
|
+
if inputs_were_whest:
|
|
123
|
+
return _asflopscope(result) # type: ignore[reportArgumentType]
|
|
124
|
+
return result # type: ignore[reportReturnType]
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
attach_docstring(qr, _np.linalg.qr, "linalg", r"$m \cdot n \cdot \min(m,n)$ FLOPs")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def eig_cost(n: int) -> int:
|
|
131
|
+
"""FLOP cost of eigendecomposition.
|
|
132
|
+
|
|
133
|
+
Parameters
|
|
134
|
+
----------
|
|
135
|
+
n : int
|
|
136
|
+
Matrix dimension.
|
|
137
|
+
|
|
138
|
+
Returns
|
|
139
|
+
-------
|
|
140
|
+
int
|
|
141
|
+
Estimated FLOP count: $n^3$.
|
|
142
|
+
|
|
143
|
+
Notes
|
|
144
|
+
-----
|
|
145
|
+
Simplified cubic cost model for eigendecomposition.
|
|
146
|
+
"""
|
|
147
|
+
return max(n**3, 1)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@_counted_wrapper
|
|
151
|
+
def eig(a: ArrayLike) -> tuple[FlopscopeArray, FlopscopeArray]:
|
|
152
|
+
"""Eigendecomposition with FLOP counting."""
|
|
153
|
+
budget = require_budget()
|
|
154
|
+
inputs_were_whest = isinstance(a, FlopscopeArray)
|
|
155
|
+
if not isinstance(a, _np.ndarray):
|
|
156
|
+
a = _np.asarray(a)
|
|
157
|
+
n = a.shape[-1]
|
|
158
|
+
batch = _batch_size(a.shape)
|
|
159
|
+
cost = eig_cost(n) * batch if not _has_zero_dim(a.shape) else 0
|
|
160
|
+
with budget.deduct(
|
|
161
|
+
"linalg.eig", flop_cost=cost, subscripts=None, shapes=(a.shape,)
|
|
162
|
+
):
|
|
163
|
+
result = _call_numpy(_np.linalg.eig, _to_base_ndarray(a))
|
|
164
|
+
if inputs_were_whest:
|
|
165
|
+
return EigResult( # type: ignore[reportReturnType]
|
|
166
|
+
_asflopscope(result.eigenvalues), _asflopscope(result.eigenvectors)
|
|
167
|
+
)
|
|
168
|
+
return result # type: ignore[reportReturnType]
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
attach_docstring(eig, _np.linalg.eig, "linalg", r"$n^3$ FLOPs")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def eigh_cost(n: int) -> int:
|
|
175
|
+
"""FLOP cost of symmetric eigendecomposition.
|
|
176
|
+
|
|
177
|
+
Parameters
|
|
178
|
+
----------
|
|
179
|
+
n : int
|
|
180
|
+
Matrix dimension.
|
|
181
|
+
|
|
182
|
+
Returns
|
|
183
|
+
-------
|
|
184
|
+
int
|
|
185
|
+
Estimated FLOP count: $n^3$.
|
|
186
|
+
|
|
187
|
+
Notes
|
|
188
|
+
-----
|
|
189
|
+
Simplified cubic cost model for symmetric eigendecomposition.
|
|
190
|
+
"""
|
|
191
|
+
return max(n**3, 1)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@_counted_wrapper
|
|
195
|
+
def eigh(a: ArrayLike, UPLO: str = "L") -> tuple[FlopscopeArray, FlopscopeArray]:
|
|
196
|
+
"""Symmetric eigendecomposition with FLOP counting."""
|
|
197
|
+
budget = require_budget()
|
|
198
|
+
inputs_were_whest = isinstance(a, FlopscopeArray)
|
|
199
|
+
if not isinstance(a, _np.ndarray):
|
|
200
|
+
a = _np.asarray(a)
|
|
201
|
+
n = a.shape[-1]
|
|
202
|
+
batch = _batch_size(a.shape)
|
|
203
|
+
cost = eigh_cost(n) * batch if not _has_zero_dim(a.shape) else 0
|
|
204
|
+
with budget.deduct(
|
|
205
|
+
"linalg.eigh", flop_cost=cost, subscripts=None, shapes=(a.shape,)
|
|
206
|
+
):
|
|
207
|
+
result = _call_numpy(_np.linalg.eigh, _to_base_ndarray(a), UPLO=UPLO) # type: ignore[reportCallIssue]
|
|
208
|
+
if inputs_were_whest:
|
|
209
|
+
return EighResult( # type: ignore[reportReturnType]
|
|
210
|
+
_asflopscope(result.eigenvalues), _asflopscope(result.eigenvectors)
|
|
211
|
+
)
|
|
212
|
+
return result # type: ignore[reportReturnType]
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
attach_docstring(eigh, _np.linalg.eigh, "linalg", r"$n^3$ FLOPs")
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def eigvals_cost(n: int) -> int:
|
|
219
|
+
"""FLOP cost of computing eigenvalues.
|
|
220
|
+
|
|
221
|
+
Parameters
|
|
222
|
+
----------
|
|
223
|
+
n : int
|
|
224
|
+
Matrix dimension.
|
|
225
|
+
|
|
226
|
+
Returns
|
|
227
|
+
-------
|
|
228
|
+
int
|
|
229
|
+
Estimated FLOP count: $n^3$.
|
|
230
|
+
|
|
231
|
+
Notes
|
|
232
|
+
-----
|
|
233
|
+
Simplified cubic cost model for eigenvalue computation.
|
|
234
|
+
"""
|
|
235
|
+
return max(n**3, 1)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@_counted_wrapper
|
|
239
|
+
def eigvals(a: ArrayLike) -> FlopscopeArray:
|
|
240
|
+
"""Eigenvalues (nonsymmetric) with FLOP counting."""
|
|
241
|
+
budget = require_budget()
|
|
242
|
+
inputs_were_whest = isinstance(a, FlopscopeArray)
|
|
243
|
+
if not isinstance(a, _np.ndarray):
|
|
244
|
+
a = _np.asarray(a)
|
|
245
|
+
n = a.shape[-1]
|
|
246
|
+
batch = _batch_size(a.shape)
|
|
247
|
+
cost = eigvals_cost(n) * batch if not _has_zero_dim(a.shape) else 0
|
|
248
|
+
with budget.deduct(
|
|
249
|
+
"linalg.eigvals", flop_cost=cost, subscripts=None, shapes=(a.shape,)
|
|
250
|
+
):
|
|
251
|
+
result = _call_numpy(_np.linalg.eigvals, _to_base_ndarray(a))
|
|
252
|
+
if inputs_were_whest:
|
|
253
|
+
return _asflopscope(result) # type: ignore[reportReturnType]
|
|
254
|
+
return result # type: ignore[reportReturnType]
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
attach_docstring(eigvals, _np.linalg.eigvals, "linalg", r"$n^3$ FLOPs")
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def eigvalsh_cost(n: int) -> int:
|
|
261
|
+
"""FLOP cost of computing eigenvalues of a symmetric matrix.
|
|
262
|
+
|
|
263
|
+
Parameters
|
|
264
|
+
----------
|
|
265
|
+
n : int
|
|
266
|
+
Matrix dimension.
|
|
267
|
+
|
|
268
|
+
Returns
|
|
269
|
+
-------
|
|
270
|
+
int
|
|
271
|
+
Estimated FLOP count: $n^3$.
|
|
272
|
+
|
|
273
|
+
Notes
|
|
274
|
+
-----
|
|
275
|
+
Simplified cubic cost model for symmetric eigenvalue computation.
|
|
276
|
+
"""
|
|
277
|
+
return max(n**3, 1)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@_counted_wrapper
|
|
281
|
+
def eigvalsh(a: ArrayLike, UPLO: str = "L") -> FlopscopeArray:
|
|
282
|
+
"""Eigenvalues (symmetric) with FLOP counting."""
|
|
283
|
+
budget = require_budget()
|
|
284
|
+
inputs_were_whest = isinstance(a, FlopscopeArray)
|
|
285
|
+
if not isinstance(a, _np.ndarray):
|
|
286
|
+
a = _np.asarray(a)
|
|
287
|
+
n = a.shape[-1]
|
|
288
|
+
batch = _batch_size(a.shape)
|
|
289
|
+
cost = eigvalsh_cost(n) * batch if not _has_zero_dim(a.shape) else 0
|
|
290
|
+
with budget.deduct(
|
|
291
|
+
"linalg.eigvalsh", flop_cost=cost, subscripts=None, shapes=(a.shape,)
|
|
292
|
+
):
|
|
293
|
+
result = _call_numpy(_np.linalg.eigvalsh, _to_base_ndarray(a), UPLO=UPLO) # type: ignore[reportCallIssue]
|
|
294
|
+
if inputs_were_whest:
|
|
295
|
+
return _asflopscope(result) # type: ignore[reportReturnType]
|
|
296
|
+
return result # type: ignore[reportReturnType]
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
attach_docstring(eigvalsh, _np.linalg.eigvalsh, "linalg", r"$n^3$ FLOPs")
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def svdvals_cost(m: int, n: int, k: int | None = None) -> int:
|
|
303
|
+
"""FLOP cost of computing singular values.
|
|
304
|
+
|
|
305
|
+
Parameters
|
|
306
|
+
----------
|
|
307
|
+
m : int
|
|
308
|
+
Number of rows.
|
|
309
|
+
n : int
|
|
310
|
+
Number of columns.
|
|
311
|
+
k : int or None, optional
|
|
312
|
+
Number of singular values to compute. Defaults to min(m, n).
|
|
313
|
+
|
|
314
|
+
Returns
|
|
315
|
+
-------
|
|
316
|
+
int
|
|
317
|
+
Estimated FLOP count: m * n * k.
|
|
318
|
+
|
|
319
|
+
Notes
|
|
320
|
+
-----
|
|
321
|
+
Source: Golub-Reinsch bidiagonalization. Same cost model as SVD.
|
|
322
|
+
"""
|
|
323
|
+
if k is None:
|
|
324
|
+
k = min(m, n)
|
|
325
|
+
return max(m * n * k, 1)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
@_counted_wrapper
|
|
329
|
+
def svdvals(x: ArrayLike, /, *, k: int | None = None) -> FlopscopeArray:
|
|
330
|
+
"""Singular values with FLOP counting."""
|
|
331
|
+
budget = require_budget()
|
|
332
|
+
inputs_were_whest = isinstance(x, FlopscopeArray)
|
|
333
|
+
if not isinstance(x, _np.ndarray):
|
|
334
|
+
x = _np.asarray(x)
|
|
335
|
+
m, n = x.shape[-2], x.shape[-1]
|
|
336
|
+
batch = _batch_size(x.shape)
|
|
337
|
+
if k is None:
|
|
338
|
+
k = min(m, n)
|
|
339
|
+
if min(m, n) > 0 and not (1 <= k <= min(m, n)):
|
|
340
|
+
raise ValueError(f"k must satisfy 1 <= k <= min(m, n) = {min(m, n)}, got k={k}")
|
|
341
|
+
cost = svdvals_cost(m, n, k) * batch if not _has_zero_dim(x.shape) else 0
|
|
342
|
+
with budget.deduct(
|
|
343
|
+
"linalg.svdvals", flop_cost=cost, subscripts=None, shapes=(x.shape,)
|
|
344
|
+
):
|
|
345
|
+
result = _call_numpy(_np.linalg.svdvals, _to_base_ndarray(x))
|
|
346
|
+
if k < min(m, n):
|
|
347
|
+
result = result[..., :k]
|
|
348
|
+
if inputs_were_whest:
|
|
349
|
+
return _asflopscope(result) # type: ignore[reportReturnType]
|
|
350
|
+
return result # type: ignore[reportReturnType]
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
attach_docstring(svdvals, _np.linalg.svdvals, "linalg", r"$m \cdot n \cdot k$ FLOPs")
|