trsm.hh
Go to the documentation of this file.
1#pragma once
2
3#include <batchlas/export.hh>
4#include <stdexcept>
5#include <string>
6#include <algorithm>
7
12
13namespace batchlas {
14
15// Signature aliases for explicit instantiation; see BATCHLAS_INSTANTIATE in
16// src/util/template-instantiations.hh. Keep in sync with the declarations below.
17namespace sig {
18template <typename T>
19using trsm = Event(Queue&,
20 const MatrixView<T, MatrixFormat::Dense>&,
21 const MatrixView<T, MatrixFormat::Dense>&,
22 T, Side, Uplo, Transpose, Diag);
23
24// NOT an alias for sig::trsm: the vendor signature puts alpha last.
25template <typename T>
26using trsm_vendor = Event(Queue&,
27 const MatrixView<T,MatrixFormat::Dense>&,
28 const MatrixView<T,MatrixFormat::Dense>&,
29 Side,
30 Uplo,
32 Diag,
33 T);
34} // namespace sig
35
36
37/// @brief Host-side argument check that trsm runs on every backend before kernel selection.
38///
39/// With m = `B.rows()` and n = `B.cols()`, requires m, n >= 0; valid enum values
40/// for `side`, `uplo`, `transA` and `diag`; `A` square of order m (Left) or n
41/// (Right) with `A.ld()` >= max(1, order); `B.ld()` >= max(1, m); and `A` and `B`
42/// with the same batch size. Reads only the views' shape metadata, never their data.
43/// @param A triangular operand
44/// @param B right-hand sides
45/// @param side Side::Left or Side::Right
46/// @param uplo Uplo::Lower or Uplo::Upper
47/// @param transA NoTrans, Trans or ConjTrans
48/// @param diag Diag::NonUnit or Diag::Unit
49/// @throws batchlas::invalid_argument naming the first violated requirement
50/// @ingroup api_blas3_lowlevel
51template <typename T>
55 Side side,
56 Uplo uplo,
57 Transpose transA,
58 Diag diag) {
59 int m = B.rows(), n = B.cols();
60 int lda = A.ld(), ldb = B.ld();
61
62 if (m < 0 || n < 0) {
63 throw batchlas::invalid_argument("TRSM: Matrix dimensions cannot be negative (m=" + std::to_string(m) +
64 ", n=" + std::to_string(n) + ")");
65 }
66
67 if (transA != Transpose::NoTrans && transA != Transpose::Trans && transA != Transpose::ConjTrans) {
68 throw batchlas::invalid_argument("TRSM: Invalid transpose operation: " + std::to_string(static_cast<int>(transA)));
69 }
70 if (uplo != Uplo::Lower && uplo != Uplo::Upper) {
71 throw batchlas::invalid_argument("TRSM: Invalid uplo parameter: " + std::to_string(static_cast<int>(uplo)));
72 }
73 if (side != Side::Left && side != Side::Right) {
74 throw batchlas::invalid_argument("TRSM: Invalid side parameter: " + std::to_string(static_cast<int>(side)));
75 }
76 if (diag != Diag::NonUnit && diag != Diag::Unit) {
77 throw batchlas::invalid_argument("TRSM: Invalid diag parameter: " + std::to_string(static_cast<int>(diag)));
78 }
79
80 if (side == Side::Left) {
81 if (A.rows() != m || A.cols() != m) {
82 throw batchlas::invalid_argument("TRSM: For left side, A must be square matrix of size m x m. Got " +
83 std::to_string(A.rows()) + "x" + std::to_string(A.cols()) +
84 " instead of " + std::to_string(m) + "x" + std::to_string(m));
85 }
86 if (lda < std::max(1, m)) {
87 throw batchlas::invalid_argument("TRSM: lda must be >= max(1, m). Got lda=" +
88 std::to_string(lda) + ", m=" + std::to_string(m));
89 }
90 } else {
91 if (A.rows() != n || A.cols() != n) {
92 throw batchlas::invalid_argument("TRSM: For right side, A must be square matrix of size n x n. Got " +
93 std::to_string(A.rows()) + "x" + std::to_string(A.cols()) +
94 " instead of " + std::to_string(n) + "x" + std::to_string(n));
95 }
96 if (lda < std::max(1, n)) {
97 throw batchlas::invalid_argument("TRSM: lda must be >= max(1, n). Got lda=" +
98 std::to_string(lda) + ", n=" + std::to_string(n));
99 }
100 }
101
102 if (ldb < std::max(1, m)) {
103 throw batchlas::invalid_argument("TRSM: ldb must be >= max(1, m). Got ldb=" +
104 std::to_string(ldb) + ", m=" + std::to_string(m));
105 }
106 // Every kernel walks one batch count over both operands; a mismatch indexes past one.
107 if (A.batch_size() != B.batch_size()) {
108 throw batchlas::invalid_argument("TRSM: A and B must have the same batch size. Got " +
109 std::to_string(A.batch_size()) + " and " +
110 std::to_string(B.batch_size()));
111 }
112}
113
114// alpha sits right after the matrices, as in trmm; it used to come last.
115// evidence: docs/cpp-api.md#trsm-alpha-moved-next-to-the-matrices
116/// @brief Batched triangular solve with multiple right-hand sides, in place.
117///
118/// For every batch item solves
119/// \f[ \mathrm{op}(A) \, X = \alpha B \quad (\texttt{Side::Left}), \qquad
120/// X \, \mathrm{op}(A) = \alpha B \quad (\texttt{Side::Right}) \f]
121/// and overwrites `B` with \f$X\f$. `A` is triangular (`uplo`), unit or
122/// non-unit diagonal (`diag`), and \f$\mathrm{op}(A)\f$ is one of
123/// \f$A, A^T, A^H\f$. `B` is m x n; `A` is m x m (Left) or n x n (Right).
124/// No singularity check is made: a zero on a non-unit diagonal gives Inf/NaN.
125///
126/// Also callable as `trsm(ctx, A, B, TrsmOptions<T>{...})`, with owning
127/// `Matrix` arguments, and without `Back` (taken from `ctx.backend()`).
128///
129/// @tparam Back backend the call is compiled for; must match `ctx`'s device
130/// @tparam T scalar type: `float`, `double`, `std::complex<float>` or `std::complex<double>`
131/// @param ctx queue the work is enqueued on
132/// @param A batch of triangular matrices; only the `uplo` triangle is read
133/// @param B batch of m x n right-hand sides; overwritten with the solution
134/// @param alpha scale of the right-hand side
135/// @param side whether op(A) is applied from the left or the right
136/// @param uplo which triangle of `A` holds the data
137/// @param transA op() applied to `A`
138/// @param diag whether `A` has an implicit unit diagonal
139/// @return event of the last enqueued kernel; `B` holds \f$X\f$ once it completes
140/// @throws batchlas::invalid_argument from trsm_validate_params (bad shape, `ld`,
141/// enum value, or `A` and `B` batch sizes that differ), before anything
142/// is enqueued
143/// @throws batchlas::NoRouteError in a build without the vendor BLAS for `Back`
144/// when no native kernel can run the shape
145/// @note On `Backend::NETLIB`, `alpha == 0` still reads `B`, so a NaN in `B`
146/// survives (known defect 5, @ref md_docs_2design_2known-defects).
147/// @see trmm, TrsmOptions, @ref perf_trsm, @ref md_docs_2cpp-api
148/// @ingroup api_blas3
149template <Backend Back, typename T>
150BATCHLAS_API Event trsm(Queue& ctx,
153 T alpha,
154 Side side,
155 Uplo uplo,
156 Transpose transA,
157 Diag diag);
158
159// Tombstones for the old order; both spellings need one.
160// evidence: docs/cpp-api.md#trsm-alpha-moved-next-to-the-matrices
161/// @brief Deleted: the old argument order with `alpha` last. Pass `alpha` right
162/// after `B`.
163/// @ingroup api_blas3
164template <Backend Back, typename T>
168 Side, Uplo, Transpose, Diag, T) = delete;
169
170} // namespace batchlas
171
172
173namespace batchlas::backend {
174
175// Declaration only: each vendor wrapper TU defines and instantiates it for its
176// own Backend; the public trsm is defined in src/ops/trsm/trsm.cc, so dropping a
177// vendor library drops only this path. evidence: docs/design/vendor-independence.md#the-entry-point-facade
178/// @brief Vendor-library implementation of trsm (cuBLAS, rocBLAS, host BLAS).
179///
180/// Not an entry point: batchlas::trsm calls it after validation, when kernel
181/// selection picks the Vendor family. Same semantics as batchlas::trsm, but
182/// `alpha` is the last argument.
183/// @ingroup api_dispatch
184template <Backend Back, typename T>
185BATCHLAS_API Event trsm_vendor(Queue& ctx,
188 Side side,
189 Uplo uplo,
190 Transpose transA,
191 Diag diag,
192 T alpha);
193
194} // namespace batchlas::backend
195
196namespace batchlas {
197
198// Owning-argument (`f(ctx, Matrix, ...)`) and backend-deducing (`f(ctx, ...)`)
199// overloads; see blas/queue-dispatch.hh.
200
201
203
204} // namespace batchlas
Non-owning view of a batch of matrices: the argument type of every entry point.
Definition matrix.hh:485
int rows() const
Rows per item (the capacity on a heterogeneous batch).
Definition matrix.hh:605
int cols() const
Columns per item (the capacity on a heterogeneous batch).
Definition matrix.hh:611
int ld() const
Leading dimension: element distance between columns.
Definition matrix.hh:818
int batch_size() const
Number of batch items.
Definition matrix.hh:603
The call violates the API contract.
Definition error.hh:77
Enumerations, scalar traits and scalar concepts shared by every public header.
void trsm_validate_params(const MatrixView< T, MatrixFormat::Dense > &A, const MatrixView< T, MatrixFormat::Dense > &B, Side side, Uplo uplo, Transpose transA, Diag diag)
Host-side argument check that trsm runs on every backend before kernel selection.
Definition trsm.hh:52
Event trsm(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, const MatrixView< T, MatrixFormat::Dense > &B, T alpha, Side side, Uplo uplo, Transpose transA, Diag diag)
Batched triangular solve with multiple right-hand sides, in place.
Event trsm_vendor(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, const MatrixView< T, MatrixFormat::Dense > &B, Side side, Uplo uplo, Transpose transA, Diag diag, T alpha)
Vendor-library implementation of trsm (cuBLAS, rocBLAS, host BLAS).
Transpose
The operator op() applied to an operand: op(A) = A, A^T or A^H.
Definition enums.hh:171
Diag
Whether a triangular operand's diagonal is read or assumed to be one.
Definition enums.hh:303
Uplo
Which triangle of a symmetric, Hermitian or triangular operand is referenced.
Definition enums.hh:287
Side
Side on which a special operand multiplies: op(A) * B or B * op(A).
Definition enums.hh:319
@ Trans
op(A) = A^T.
Definition enums.hh:173
@ NoTrans
op(A) = A.
Definition enums.hh:172
@ ConjTrans
op(A) = A^H (the same as Trans for real scalars).
Definition enums.hh:174
@ Unit
The diagonal is taken as 1 and not read.
Definition enums.hh:305
@ NonUnit
The stored diagonal is used.
Definition enums.hh:304
@ Upper
The upper triangle (i <= j).
Definition enums.hh:288
@ Lower
The lower triangle (i >= j).
Definition enums.hh:289
@ Right
The special operand is on the right.
Definition enums.hh:321
@ Left
The special operand is on the left.
Definition enums.hh:320
The batched containers: Matrix (owning), MatrixView (non-owning), KernelMatrixView (device-side),...
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.
batchlas::Device, batchlas::Event and batchlas::Queue: where work runs and how it is ordered.