Householder QR, forming and applying Q, and batched orthogonalisation.
Lower-level functions (algorithm-specific variants, workspace queries, validation and helpers): QR: lower-level API.
Batched Householder QR factorization \( A = Q R \).
For every m x n batch item, as LAPACK ?geqrf: on return the upper triangle (upper trapezoid if m < n) of A holds R, and the part below the diagonal holds the Householder vectors \( v_i \) with an implied unit leading entry. With \( k = \min(m, n) \), \( Q = H_1 H_2 \cdots H_k \), \( H_i = I - \tau_i v_i v_i^H \). Pass A and tau unchanged to orgqr() to form Q or to ormqr() to apply it.
Asynchronous: A and tau are readable after the returned event is waited on.
- Template Parameters
-
| B | backend; the backend-deducing overload takes it from ctx.backend() |
| T | scalar type (float, double, std::complex<float>, std::complex<double>) |
- Parameters
-
| ctx | queue the kernels are enqueued on |
| A | batch of m x n matrices; overwritten with R and the reflectors |
| tau | reflector scalars, k * batch elements; item b's \( \tau_i \) is tau[b * k + i] |
| work_space | device-accessible scratch of at least geqrf_buffer_size() bytes |
- Returns
- event of the last enqueued kernel
- Precondition
- tau.size() >= min(m, n) * A.batch_size() (checked by the option overloads only)
- Exceptions
-
Batched formation of the first n columns of Q from geqrf() output.
As LAPACK ?orgqr / ?ungqr with \( k = n \): A holds, below its diagonal, the reflectors written by geqrf() on an m x n matrix, and on return A holds the m x n matrix \( Q = H_1 H_2 \cdots H_n \) restricted to its first n columns, with orthonormal columns ( \( Q^H Q = I \)).
Asynchronous: A is readable after the returned event is waited on.
- Template Parameters
-
| B | backend; the backend-deducing overload takes it from ctx.backend() |
| T | scalar type (float, double, std::complex<float>, std::complex<double>) |
- Parameters
-
| ctx | queue the kernels are enqueued on |
| A | batch of m x n geqrf() outputs, m >= n; overwritten with Q |
| tau | reflector scalars from geqrf(), n * batch elements |
| workspace | device-accessible scratch of at least orgqr_buffer_size() bytes |
- Returns
- event of the last enqueued kernel
- Precondition
- A.cols() <= A.rows(); not checked by any overload
-
tau.size() >= min(m, n) * batch (checked by the option overloads only)
- Exceptions
-
Batched multiplication by the orthogonal/unitary Q from geqrf().
As LAPACK ?ormqr / ?unmqr. A holds, below its diagonal, the \( k = \min(A_{rows}, A_{cols}) \) reflectors that geqrf() wrote, with \( Q = H_1 \cdots H_k \) of order A.rows(). For every batch item C is overwritten with \( \mathrm{op}(Q)\, C \) (Side::Left) or \( C\, \mathrm{op}(Q) \) (Side::Right), where \( \mathrm{op}(Q) \) is Q for NoTrans and \( Q^H \) for ConjTrans ( \( Q^T \) for real T, where Trans means the same). Q is never formed.
The kernel (the blocked WY apply on a GPU queue, or the vendor library) is chosen per call from the device's tuned table (src/ops/ormqr/ormqr.cc) and can be pinned with BATCHLAS_ORMQR_ROUTE.
Asynchronous: C is readable after the returned event is waited on. On an out-of-order ctx the work runs on an internal in-order queue that first waits for everything already submitted to ctx.
- Template Parameters
-
| B | backend; the backend-deducing overload takes it from ctx.backend() |
| T | scalar type (float, double, std::complex<float>, std::complex<double>) |
- Parameters
-
| ctx | queue the kernels are enqueued on |
| A | batch of geqrf() outputs holding the reflectors; not modified |
| C | batch of matrices to multiply; overwritten with the product |
| side | apply Q from the left or the right |
| trans | apply Q (NoTrans) or its (conjugate) transpose |
| tau | reflector scalars from geqrf(), k * batch elements |
| workspace | device-accessible scratch of at least ormqr_buffer_size() bytes, sized with the same block_size_hint |
| block_size_hint | WY panel width for the blocked kernel; 0 lets the tuning table choose. Clamped to [1, k]; ignored by the vendor kernel. |
- Returns
- event of the last enqueued kernel
- Precondition
- A.rows() == C.rows() for Side::Left, A.rows() == C.cols() for Side::Right, and A and C share a batch size
-
tau.size() >= k * batch (checked by the option overloads)
- Exceptions
-
- See also
- OrmqrOptions