gesv.hh
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @brief Batched general linear solve (gesv) by LU with partial pivoting.
5/// @ingroup api_factorizations
6
7// No vendor ships a batched gesv, so there is no gesv_vendor; the fallback is the
8// routed composition getrf; getrs, and the documented contract is exactly that.
9// evidence: docs/perf/lu.md#the-fused-gesv-tier
10
11#include <batchlas/export.hh>
12#include <cstdint>
13#include <stdexcept>
14#include <string>
15
21
22namespace batchlas {
23
24// Signature aliases for explicit instantiation; see BATCHLAS_INSTANTIATE in
25// src/util/template-instantiations.hh. Keep in sync with the declarations below.
26namespace sig {
27template <typename T>
28using gesv = Event(Queue&,
29 const MatrixView<T, MatrixFormat::Dense>&,
30 const MatrixView<T, MatrixFormat::Dense>&,
31 Span<int64_t>, Span<std::byte>, Span<int32_t>);
32
33template <typename T>
34using gesv_buffer_size = size_t(Queue&,
35 const MatrixView<T, MatrixFormat::Dense>&,
36 const MatrixView<T, MatrixFormat::Dense>&);
37} // namespace sig
38
39/// @brief Validates the arguments of gesv() and gesv_buffer_size().
40///
41/// Checks non-negative extents, a square A, `B.rows() == A.rows()` and equal
42/// batch sizes.
43/// @throws batchlas::invalid_argument if any check fails
44/// @ingroup api_factorizations_lowlevel
45// Stricter than getrs_validate_params on purpose: getrs routes a non-conforming
46// pair to the vendor, but gesv has none, so it would report the wrong cause.
47template <typename T>
50 if (A.rows() < 0 || A.cols() < 0 || B.rows() < 0 || B.cols() < 0) {
52 "GESV: Matrix dimensions cannot be negative (A: rows=" +
53 std::to_string(A.rows()) + ", cols=" + std::to_string(A.cols()) +
54 "; B: rows=" + std::to_string(B.rows()) +
55 ", cols=" + std::to_string(B.cols()) + ")");
56 }
57 if (A.rows() != A.cols()) {
59 "GESV: A must be square, got " + std::to_string(A.rows()) + "x" +
60 std::to_string(A.cols()));
61 }
62 if (A.rows() != B.rows()) {
64 "GESV: B must have A.rows() rows, got " + std::to_string(B.rows()) +
65 " against " + std::to_string(A.rows()));
66 }
67 if (A.batch_size() != B.batch_size()) {
69 "GESV: A and B must share a batch size, got " +
70 std::to_string(A.batch_size()) + " and " + std::to_string(B.batch_size()));
71 }
72}
73
74/// @brief Batched solve of \f$ A X = B \f$ by LU with partial pivoting.
75///
76/// Semantically getrf() followed by getrs() with `Transpose::NoTrans`: on return
77/// A holds L and U as getrf() leaves them, @p pivots the same packed 1-based
78/// interchange list getrf() writes (so the factors can be reused with getrs()
79/// or getri()), B holds X and @p info carries getrf's per-item status. No
80/// vendor library call sits behind this op; it is served by a native fused
81/// tier or by the routed getrf + getrs composition.
82///
83/// Asynchronous: A, B, @p pivots and @p info are readable after the returned
84/// event is waited on.
85/// @tparam Back backend; the backend-deducing overload takes it from `ctx.backend()`
86/// @tparam T scalar type (float, double, std::complex<float>, std::complex<double>)
87/// @param ctx queue the kernels are enqueued on
88/// @param A batch of n x n matrices; overwritten with L and U
89/// @param B batch of n x nrhs right-hand sides; overwritten with X
90/// @param pivots pivot output, `n * batch` entries in getrf()'s format
91/// @param work_space device-accessible scratch of at least gesv_buffer_size() bytes
92/// @param info per-item status as for getrf(): 0 on success, i > 0 if
93/// U(i,i) is exactly zero (that item's X is meaningless).
94/// Empty span = not requested.
95/// @return event of the last enqueued kernel
96/// @throws batchlas::invalid_argument if gesv_validate_params() rejects the call
97/// @throws batchlas::workspace_error if the composed getrf + getrs route is
98/// chosen and @p work_space is shorter than its getrf leg needs
99/// @ingroup api_factorizations
100template <Backend Back, typename T>
101BATCHLAS_API Event gesv(Queue& ctx,
104 Span<int64_t> pivots,
105 Span<std::byte> work_space,
106 Span<int32_t> info);
107
108/// @brief Workspace, in bytes, that gesv() needs for these operands on this queue.
109///
110/// Takes the same operands as the call, so both resolve the same route.
111/// @throws batchlas::invalid_argument if gesv_validate_params() rejects the operands
112/// @ingroup api_factorizations_lowlevel
113template <Backend Back, typename T>
114BATCHLAS_API size_t gesv_buffer_size(Queue& ctx,
117
118/// @brief gesv() without per-item status (`info` not requested).
119/// @ingroup api_factorizations
120// Not a defaulted `info`: the sig:: aliases are function types (see potrf.hh).
121template <Backend Back, typename T>
122inline Event gesv(Queue& ctx,
125 Span<int64_t> pivots,
126 Span<std::byte> work_space) {
127 return gesv<Back, T>(ctx, A, B, pivots, work_space, Span<int32_t>{});
128}
129
130
133
134} // 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 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 gesv_validate_params(const MatrixView< T, MatrixFormat::Dense > &A, const MatrixView< T, MatrixFormat::Dense > &B)
Validates the arguments of gesv() and gesv_buffer_size().
Definition gesv.hh:48
size_t gesv_buffer_size(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, const MatrixView< T, MatrixFormat::Dense > &B)
Workspace, in bytes, that gesv() needs for these operands on this queue.
Event gesv(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &A, const MatrixView< T, MatrixFormat::Dense > &B, Span< int64_t > pivots, Span< std::byte > work_space, Span< int32_t > info)
Batched solve of by LU with partial pivoting.
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
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.