ormqr.hh
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @brief Batched application of Q from geqrf reflectors (ormqr/unmqr) and its workspace query.
5/// @ingroup api_qr
6
7#include <batchlas/export.hh>
8#include <algorithm>
9#include <optional>
10#include <stdexcept>
11#include <type_traits>
12#include <complex>
13
19
21
23
24namespace batchlas {
25
26// Signature aliases for explicit instantiation; see BATCHLAS_INSTANTIATE in
27// src/util/template-instantiations.hh. Keep in sync with the declarations below.
28namespace sig {
29template <typename T>
30using ormqr = Event(Queue&,
31 const MatrixView<T, MatrixFormat::Dense>&,
32 const MatrixView<T, MatrixFormat::Dense>&,
34 int32_t);
35
36template <typename T>
37using ormqr_buffer_size = size_t(Queue&,
38 const MatrixView<T, MatrixFormat::Dense>&,
39 const MatrixView<T, MatrixFormat::Dense>&,
41 int32_t);
42
43// The vendor signatures deliberately drop the block-size hint (a WY panel width
44// means nothing to a vendor kernel), so they are spelled out, not aliased.
45template <typename T>
46using ormqr_vendor = Event(Queue&,
47 const MatrixView<T, MatrixFormat::Dense>&,
48 const MatrixView<T, MatrixFormat::Dense>&,
50
51template <typename T>
52using ormqr_vendor_buffer_size = size_t(Queue&,
53 const MatrixView<T, MatrixFormat::Dense>&,
54 const MatrixView<T, MatrixFormat::Dense>&,
56} // namespace sig
57
58
59/// @brief Batched multiplication by the orthogonal/unitary Q from geqrf().
60///
61/// As LAPACK `?ormqr` / `?unmqr`. A holds, below its diagonal, the
62/// \f$ k = \min(A_{rows}, A_{cols}) \f$ reflectors that geqrf() wrote, with
63/// \f$ Q = H_1 \cdots H_k \f$ of order `A.rows()`. For every batch item C is
64/// overwritten with
65/// \f$ \mathrm{op}(Q)\, C \f$ (`Side::Left`) or \f$ C\, \mathrm{op}(Q) \f$
66/// (`Side::Right`), where \f$ \mathrm{op}(Q) \f$ is Q for `NoTrans` and
67/// \f$ Q^H \f$ for `ConjTrans` (\f$ Q^T \f$ for real T, where `Trans` means the
68/// same). Q is never formed.
69///
70/// The kernel (the blocked WY apply on a GPU queue, or the vendor library) is
71/// chosen per call from the device's tuned table (src/ops/ormqr/ormqr.cc) and
72/// can be pinned with `BATCHLAS_ORMQR_ROUTE`.
73///
74/// Asynchronous: C is readable after the returned event is waited on. On an
75/// out-of-order @p ctx the work runs on an internal in-order queue that first
76/// waits for everything already submitted to @p ctx.
77/// @tparam B backend; the backend-deducing overload takes it from `ctx.backend()`
78/// @tparam T scalar type (float, double, std::complex<float>, std::complex<double>)
79/// @param ctx queue the kernels are enqueued on
80/// @param A batch of geqrf() outputs holding the reflectors; not modified
81/// @param C batch of matrices to multiply; overwritten with the product
82/// @param side apply Q from the left or the right
83/// @param trans apply Q (`NoTrans`) or its (conjugate) transpose
84/// @param tau reflector scalars from geqrf(), `k * batch` elements
85/// @param workspace device-accessible scratch of at least ormqr_buffer_size() bytes,
86/// sized with the same @p block_size_hint
87/// @param block_size_hint WY panel width for the blocked kernel; 0 lets the tuning
88/// table choose. Clamped to [1, k]; ignored by the vendor kernel.
89/// @return event of the last enqueued kernel
90/// @pre `A.rows() == C.rows()` for `Side::Left`, `A.rows() == C.cols()` for
91/// `Side::Right`, and A and C share a batch size
92/// @pre `tau.size() >= k * batch` (checked by the option overloads)
93/// @throws batchlas::workspace_error if @p workspace is smaller than the chosen kernel needs
94/// @throws batchlas::invalid_argument for `Transpose::Trans` with complex T (use
95/// `ConjTrans`), and on non-conforming operands (blocked kernel)
96/// @throws batchlas::NoRouteError if no native kernel can run (e.g. a CPU queue) and
97/// the vendor library was not built in
98/// @see OrmqrOptions
99/// @ingroup api_qr
100// Defined in src/ops/ormqr/ormqr.cc, which picks the kernel (flat selection).
101template <Backend B, typename T>
102BATCHLAS_API Event ormqr(Queue& ctx,
105 Side side,
106 Transpose trans,
107 Span<T> tau,
108 Span<std::byte> workspace,
109 int32_t block_size_hint = 0);
110
111/// @brief Workspace, in bytes, that ormqr() needs for these operands on this queue.
112///
113/// Makes the same kernel choice and block width as ormqr() from the same inputs, so
114/// the result is valid for a call with the same arguments and @p block_size_hint.
115/// `evidence: docs/perf/qr.md#ormqr-one-route-resolution-for-the-call-and-its-size-query`
116/// @ingroup api_qr_lowlevel
117template <Backend B, typename T>
118BATCHLAS_API size_t ormqr_buffer_size(Queue& ctx,
121 Side side,
122 Transpose trans,
123 Span<T> tau,
124 int32_t block_size_hint = 0);
125
126} // namespace batchlas
127
128namespace batchlas::backend {
129
130/// @brief Vendor arm of ormqr() (cuSOLVER / rocSOLVER / LAPACKE); not for direct use.
131/// @ingroup api_dispatch
132template <Backend B, typename T>
133BATCHLAS_API Event ormqr_vendor(Queue& ctx,
136 Side side,
137 Transpose trans,
138 Span<T> tau,
139 Span<std::byte> workspace);
140
141/// @brief Workspace query of the vendor arm of ormqr().
142/// @ingroup api_dispatch
143template <Backend B, typename T>
144BATCHLAS_API size_t ormqr_vendor_buffer_size(Queue& ctx,
147 Side side,
148 Transpose trans,
149 Span<T> tau);
150
151} // namespace batchlas::backend
152
153
154namespace batchlas {
155
156// Owning-container and backend-deducing overloads; see blas/queue-dispatch.hh.
157
160
161} // 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.
Event ormqr_vendor(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, const MatrixView< T, MatrixFormat::Dense > &C, Side side, Transpose trans, Span< T > tau, Span< std::byte > workspace)
Vendor arm of ormqr() (cuSOLVER / rocSOLVER / LAPACKE); not for direct use.
size_t ormqr_vendor_buffer_size(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, const MatrixView< T, MatrixFormat::Dense > &C, Side side, Transpose trans, Span< T > tau)
Workspace query of the vendor arm of ormqr().
Transpose
The operator op() applied to an operand: op(A) = A, A^T or A^H.
Definition enums.hh:171
Side
Side on which a special operand multiplies: op(A) * B or B * op(A).
Definition enums.hh:319
size_t ormqr_buffer_size(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, const MatrixView< T, MatrixFormat::Dense > &C, Side side, Transpose trans, Span< T > tau, int32_t block_size_hint=0)
Workspace, in bytes, that ormqr() needs for these operands on this queue.
Event ormqr(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, const MatrixView< T, MatrixFormat::Dense > &C, Side side, Transpose trans, Span< T > tau, Span< std::byte > workspace, int32_t block_size_hint=0)
Batched multiplication by the orthogonal/unitary Q from geqrf().
The batched containers: Matrix (owning), MatrixView (non-owning), KernelMatrixView (device-side),...
Span(T *, typename Span< T >::size_t) -> Span< T >
Blocked (WY) application of Q from geqrf reflectors.
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
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.
Tuning constants, bucketed by problem order n, with runtime BATCHLAS_TUNE_* overrides.