gesvd.hh
Go to the documentation of this file.
1#pragma once
2
3#include <batchlas/export.hh>
4#include <stdexcept>
5#include <optional>
6#include <type_traits>
7#include <vector>
8
14
15#include <batchlas/backend_config.h>
16
18
19namespace batchlas {
20
21// Signature aliases for explicit instantiation; see BATCHLAS_INSTANTIATE in
22// src/util/template-instantiations.hh. Keep in sync with the declarations below.
23namespace sig {
24template <typename T>
25using gesvd_vendor = Event(Queue&,
26 const MatrixView<T, MatrixFormat::Dense>&,
27 Span<typename base_type<T>::type>,
28 const MatrixView<T, MatrixFormat::Dense>&,
29 const MatrixView<T, MatrixFormat::Dense>&,
30 SvdVectors, SvdVectors, Span<std::byte>, Span<int32_t>);
31
32template <typename T>
33using gesvd_vendor_buffer_size = size_t(Queue&,
34 const MatrixView<T, MatrixFormat::Dense>&,
35 Span<typename base_type<T>::type>,
36 const MatrixView<T, MatrixFormat::Dense>&,
37 const MatrixView<T, MatrixFormat::Dense>&,
39
40// The public entry points (src/ops/gesvd/gesvd.cc). `_hermitian` adds the Uplo parameter.
41template <typename T>
42using gesvd = Event(Queue&, const MatrixView<T, MatrixFormat::Dense>&, Span<typename base_type<T>::type>,
43 const MatrixView<T, MatrixFormat::Dense>&, const MatrixView<T, MatrixFormat::Dense>&,
44 SvdVectors, SvdVectors, Span<std::byte>, Span<int32_t>);
45template <typename T>
46using gesvd_hermitian = Event(Queue&, const MatrixView<T, MatrixFormat::Dense>&,
47 Span<typename base_type<T>::type>, const MatrixView<T, MatrixFormat::Dense>&,
48 const MatrixView<T, MatrixFormat::Dense>&, SvdVectors, SvdVectors, Uplo,
49 Span<std::byte>, Span<int32_t>);
50template <typename T>
51using gesvd_buffer_size = size_t(Queue&, const MatrixView<T, MatrixFormat::Dense>&,
52 Span<typename base_type<T>::type>, const MatrixView<T, MatrixFormat::Dense>&,
53 const MatrixView<T, MatrixFormat::Dense>&, SvdVectors, SvdVectors);
54template <typename T>
55using gesvd_buffer_size_hermitian = size_t(Queue&, const MatrixView<T, MatrixFormat::Dense>&,
56 Span<typename base_type<T>::type>,
57 const MatrixView<T, MatrixFormat::Dense>&,
58 const MatrixView<T, MatrixFormat::Dense>&, SvdVectors, SvdVectors,
59 Uplo);
60} // namespace sig
61
62/**
63 * @brief Singular value decomposition of a batch of matrices (LAPACK `?gesvd`).
64 *
65 * Computes \f$ A = U \Sigma V^H \f$ for every m x n batch item, with the
66 * \f$ k = \min(m, n) \f$ singular values in descending order. The kernel family is
67 * the first entry of the nearest row of the device's tuned table
68 * (`tuned/gesvd.<device>.txt`) that can run the call: `jacobi` (one-sided
69 * Jacobi, max(m, n) <= 64, or 32 for `complex<double>` with vectors), `cta`
70 * (max(m, n) <= 32; no `Thin` request that canonicalisation leaves thin),
71 * `blocked` (bidiagonalisation for real input; square Hermitian `Lower` input of
72 * any type runs syev_blocked()), or
73 * `vendor`, the solver library. Complex general input therefore runs `jacobi` or
74 * `vendor`. Pin a family with `BATCHLAS_GESVD_ROUTE`
75 * (e.g. `jacobi`, `vendor`). Asynchronous: returns once the work is enqueued.
76 *
77 * @param ctx queue the work is enqueued on
78 * @param A batch of m x n matrices; overwritten (destroyed)
79 * @param singular_values k real singular values per batch item, packed, descending
80 * @param U left singular vectors: m x m for `SvdVectors::All`, m x k for
81 * `Thin`; unused for `None`
82 * @param Vh \f$ V^H \f$: n x n for `All`, k x n for `Thin`; unused for `None`
83 * @param jobu which columns of `U` to compute
84 * @param jobvh which rows of `Vh` to compute
85 * @param workspace at least gesvd_buffer_size() bytes for the same arguments
86 * @param info per-item convergence status: 0 converged, > 0 LAPACK-like (the
87 * number of off-diagonals that failed to converge, or 1 where the
88 * kernel that ran tracks only the fact of failure). An
89 * EMPTY span means "not requested" and costs nothing;
90 * gesvd_buffer_size() is the same either way.
91 * @return event of the last enqueued kernel
92 * @throws batchlas::workspace_error if the workspace span is smaller than the chosen kernel needs
93 * @throws batchlas::NoRouteError when no native kernel can run the call in a build
94 * without the solver library
95 * @throws batchlas::unsupported if the `vendor` family runs a shape its binding cannot
96 * take: on CUDA (`gesvdjBatched`) max(m, n) > 32, a non-packed batch stride or
97 * a thin request; on ROCm always (no binding). Complex general input above
98 * `jacobi`'s ceiling therefore has no kernel on those backends.
99 * @throws batchlas::convergence_error on NETLIB when an item fails to converge and
100 * `info` is empty (with `info` given, the status is written instead)
101 * @throws std::invalid_argument if `BATCHLAS_GESVD_ROUTE` names a family that is not
102 * compiled or cannot run this call (the words `native` and `vendor` instead
103 * fall back to the tuned choice with a warning)
104 * @see @ref selection_tables, @ref perf_gesvd, @ref design_gesvd,
105 * @ref md_docs_2cpp-api (convergence status)
106 * @ingroup api_svd
107 */
108template <Backend B, typename T>
109BATCHLAS_API Event gesvd(Queue& ctx,
111 Span<typename base_type<T>::type> singular_values,
114 SvdVectors jobu,
115 SvdVectors jobvh,
116 Span<std::byte> workspace,
117 Span<int32_t> info);
118
119/**
120 * @brief gesvd() of square Hermitian input. Other parameters as for the general form.
121 *
122 * The native kernels solve it as an eigenproblem (syev_cta() or syev_blocked()) and read
123 * only the `hermitian_uplo` triangle (`blocked` takes `Lower` only). The `vendor`
124 * family has no triangle argument and reads all of `A`, so keep both triangles valid
125 * wherever that family can be chosen, e.g. `Upper` with n > 32.
126 * @pre `A` is square
127 * @ingroup api_svd
128 */
129template <Backend B, typename T>
130BATCHLAS_API Event gesvd(Queue& ctx,
132 Span<typename base_type<T>::type> singular_values,
135 SvdVectors jobu,
136 SvdVectors jobvh,
137 Uplo hermitian_uplo,
138 Span<std::byte> workspace,
139 Span<int32_t> info);
140
141// Old-arity forwarders, not a defaulted `info`, as in functions/syev.hh: the sig:: alias
142// is a function TYPE and cannot carry a default. Arity plus the Uplo/Span type at
143// parameter 8 keeps all four overloads unambiguous.
144// evidence: docs/design/vendor-independence.md#info-spans-on-syev-gesvd-and-steqr-forwarder-or-default
145/** @brief gesvd() without the convergence status (`info` empty). @ingroup api_svd */
146template <Backend B, typename T>
147inline Event gesvd(Queue& ctx,
149 Span<typename base_type<T>::type> singular_values,
152 SvdVectors jobu,
153 SvdVectors jobvh,
154 Span<std::byte> workspace) {
155 return gesvd<B, T>(ctx, A, singular_values, U, Vh, jobu, jobvh, workspace, Span<int32_t>{});
156}
157
158/** @brief Hermitian gesvd() without the convergence status (`info` empty). @ingroup api_svd */
159template <Backend B, typename T>
160inline Event gesvd(Queue& ctx,
162 Span<typename base_type<T>::type> singular_values,
165 SvdVectors jobu,
166 SvdVectors jobvh,
167 Uplo hermitian_uplo,
168 Span<std::byte> workspace) {
169 return gesvd<B, T>(ctx, A, singular_values, U, Vh, jobu, jobvh, hermitian_uplo, workspace,
170 Span<int32_t>{});
171}
172
173/**
174 * @brief Workspace, in bytes, that gesvd() needs for the same arguments.
175 *
176 * Canonicalises `jobu`/`jobvh` and makes the same kernel choice as the call does, so
177 * the size is for the kernel that will run. `info` does not affect it.
178 * @ingroup api_svd_lowlevel
179 */
180template <Backend B, typename T>
181BATCHLAS_API size_t gesvd_buffer_size(Queue& ctx,
183 Span<typename base_type<T>::type> singular_values,
186 SvdVectors jobu,
187 SvdVectors jobvh);
188
189/** @brief Workspace, in bytes, for the Hermitian gesvd(). @ingroup api_svd_lowlevel */
190template <Backend B, typename T>
191BATCHLAS_API size_t gesvd_buffer_size(Queue& ctx,
193 Span<typename base_type<T>::type> singular_values,
196 SvdVectors jobu,
197 SvdVectors jobvh,
198 Uplo hermitian_uplo);
199
200} // namespace batchlas
201
202namespace batchlas::backend {
203
204// DECLARATION ONLY: each backend wrapper TU (cuSOLVER / rocSOLVER / LAPACKE) defines and
205// instantiates it for its own Backend. A definition here makes theirs a redefinition error.
206// evidence: docs/design/gesvd.md#gesvd-design-vendor-binding-and-dispatch
207// `info_out` (caller's status span, or empty) is defaulted, as in syev_vendor, so
208// sig::gesvd_vendor still names the full nine-parameter signature.
209/**
210 * @brief The vendor solver's SVD (cuSOLVER `gesvdjBatched` or a LAPACKE loop), as
211 * gesvd()'s `vendor` kernel family calls it; same contract as the general gesvd().
212 * @throws batchlas::unsupported on CUDA for max(m, n) > 32, a non-packed batch stride
213 * or `Thin` vectors (`gesvdjBatched` has no `econ` flag); on ROCm always
214 * @throws batchlas::convergence_error on NETLIB for a non-converged item when
215 * `info_out` is empty
216 * @ingroup api_dispatch
217 */
218template <Backend B, typename T>
219BATCHLAS_API Event gesvd_vendor(Queue& ctx,
221 Span<typename base_type<T>::type> singular_values,
224 SvdVectors jobu,
225 SvdVectors jobvh,
226 Span<std::byte> workspace,
227 Span<int32_t> info_out = Span<int32_t>());
228
229/** @brief Workspace, in bytes, for backend::gesvd_vendor(). @ingroup api_dispatch */
230template <Backend B, typename T>
231BATCHLAS_API size_t gesvd_vendor_buffer_size(Queue& ctx,
233 Span<typename base_type<T>::type> singular_values,
236 SvdVectors jobu,
237 SvdVectors jobvh);
238
239} // namespace batchlas::backend
240
241
242namespace batchlas {
243
244// Backend-deducing overloads: `f(ctx, ...)` uses ctx.backend(). See
245// BATCHLAS_DISPATCH_ON_QUEUE in blas/queue-dispatch.hh.
246
247
250
251} // namespace batchlas
Non-owning view of a batch of matrices: the argument type of every entry point.
Definition matrix.hh:485
Enumerations, scalar traits and scalar concepts shared by every public header.
size_t gesvd_vendor_buffer_size(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, Span< typename base_type< T >::type > singular_values, const MatrixView< T, MatrixFormat::Dense > &U, const MatrixView< T, MatrixFormat::Dense > &Vh, SvdVectors jobu, SvdVectors jobvh)
Workspace, in bytes, for backend::gesvd_vendor().
Event gesvd_vendor(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, Span< typename base_type< T >::type > singular_values, const MatrixView< T, MatrixFormat::Dense > &U, const MatrixView< T, MatrixFormat::Dense > &Vh, SvdVectors jobu, SvdVectors jobvh, Span< std::byte > workspace, Span< int32_t > info_out=Span< int32_t >())
The vendor solver's SVD (cuSOLVER gesvdjBatched or a LAPACKE loop), as gesvd()'s vendor kernel family...
Uplo
Which triangle of a symmetric, Hermitian or triangular operand is referenced.
Definition enums.hh:287
SvdVectors
Which singular vectors gesvd computes for one factor (LAPACK jobu / jobvt).
Definition enums.hh:220
size_t gesvd_buffer_size(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, Span< typename base_type< T >::type > singular_values, const MatrixView< T, MatrixFormat::Dense > &U, const MatrixView< T, MatrixFormat::Dense > &Vh, SvdVectors jobu, SvdVectors jobvh)
Workspace, in bytes, that gesvd() needs for the same arguments.
Event gesvd(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, Span< typename base_type< T >::type > singular_values, const MatrixView< T, MatrixFormat::Dense > &U, const MatrixView< T, MatrixFormat::Dense > &Vh, SvdVectors jobu, SvdVectors jobvh, Span< std::byte > workspace, Span< int32_t > info)
Singular value decomposition of a batch of matrices (LAPACK ?gesvd).
The batched containers: Matrix (owning), MatrixView (non-owning), KernelMatrixView (device-side),...
Span(T *, typename Span< T >::size_t) -> Span< T >
Backend deduction from the Queue and the USM pointer check.
#define BATCHLAS_DISPATCH_ON_QUEUE(NAME)
Completion handle of enqueued work, returned by every entry point.
Event()
An empty Event, already complete.
Where BatchLAS work runs: a device, a backend, an ordered SYCL queue and a workspace arena.
Non-owning view of size() contiguous elements of type T.
Definition sycl-span.hh:39
T type
The real type.
Definition enums.hh:30
batchlas::Device, batchlas::Event and batchlas::Queue: where work runs and how it is ordered.
batchlas::Span, the non-owning pointer + length every entry point takes for 1-D data.