Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
backends/lapack/linear_solve.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <uni20/config.hpp>
4#if UNI20_HAS_MPLAPACK_MPREAL
6#endif
7
14#include "common.hpp"
15
25
26#include <concepts>
27#include <cstddef>
28#include <type_traits>
29#include <vector>
30
31namespace uni20::linalg
32{
33namespace lapack_detail
34{
35
36template <class CoefficientMdspan, class RhsMdspan> consteval auto linear_solve_acceptance()
37{
38 using coefficient_scalar = std::remove_cv_t<typename CoefficientMdspan::element_type>;
39 using rhs_scalar = std::remove_cv_t<typename RhsMdspan::element_type>;
40 if constexpr (uni20::LapackScalar<coefficient_scalar> && std::same_as<coefficient_scalar, rhs_scalar> &&
42 return kernel_types_maybe;
43 else
44 return kernel_types_no;
45}
46
47template <uni20::MutableRankedStridedMdspanLike<2> CoefficientMdspan,
48 uni20::MutableRankedStridedMdspanLike<2> RhsMdspan>
49KernelAttempt try_linear_solve(CoefficientMdspan& coefficients, RhsMdspan& right_hand_sides, SolveInfo& info,
51{
52 CHECK_EQUAL(coefficients.extent(0), coefficients.extent(1));
53 CHECK_EQUAL(coefficients.extent(0), right_hand_sides.extent(0));
54 std::size_t const order_size = static_cast<std::size_t>(coefficients.extent(0));
55 std::size_t const rhs_count_size = static_cast<std::size_t>(right_hand_sides.extent(1));
56 // Direct mdspan dispatch bypasses the Tensor frontend's option validation.
57 detail::require_solve_options(options);
58 if (order_size == 0 || rhs_count_size == 0)
59 {
60 info = {};
62 }
63
64 blas_int const order = uni20::blas::try_blas_int(order_size);
65 blas_int const rhs_count = uni20::blas::try_blas_int(rhs_count_size);
68
69 auto coefficient_matrix = uni20::linalg::blas::try_lapack_writable_matrix(coefficients);
70 auto rhs_matrix = uni20::linalg::blas::try_lapack_writable_matrix(right_hand_sides);
71 if (!coefficient_matrix || !rhs_matrix) return KernelAttempt::unsupported_layout;
72
73 CHECK_EQUAL(coefficient_matrix->rows, order);
74 CHECK_EQUAL(coefficient_matrix->cols, order);
75 CHECK_EQUAL(rhs_matrix->rows, order);
76 CHECK_EQUAL(rhs_matrix->cols, rhs_count);
77
78 std::vector<blas_int> pivots(order_size);
79 using scalar_type = typename CoefficientMdspan::value_type;
80 using real_type = uni20::make_real_t<scalar_type>;
81 real_type scale{};
82 if (!detail::prepare_linear_solve(coefficients, right_hand_sides, scale, info)) return KernelAttempt::success;
83
84 auto const provider_info = uni20::lapack::unchecked::getrf(order, order, coefficient_matrix->data,
85 coefficient_matrix->leading_dimension, pivots.data());
86 uni20::lapack::detail::check_invalid_argument("getrf", provider_info);
87 if (!detail::solve_matrix_is_finite(coefficients))
88 {
91 }
92 if (provider_info > 0)
93 {
94 info = {.status = SolveStatus::singular, .pivot = static_cast<std::size_t>(provider_info - 1)};
96 }
97 using std::abs;
98 for (typename CoefficientMdspan::index_type k = 0; k < coefficients.extent(0); ++k)
99 if (!detail::check_solve_pivot(real_type(abs(coefficients[k, k])), scale, options, std::size_t(k), info))
101
102 uni20::lapack::getrs('N', order, rhs_count, coefficient_matrix->data, coefficient_matrix->leading_dimension,
103 pivots.data(), rhs_matrix->data, rhs_matrix->leading_dimension);
104 if (!detail::solve_matrix_is_finite(right_hand_sides)) info.status = SolveStatus::nonfinite_result;
106}
107
108} // namespace lapack_detail
109
111template <uni20::MutableRankedStridedMdspecLike<2> CoefficientMdspec,
112 uni20::MutableRankedStridedMdspecLike<2> RhsMdspec>
115consteval auto kernel_accepts_types(LapackBackend const&, linear_solve_op const&, CoefficientMdspec&, RhsMdspec&,
116 SolveInfo&,
118{
119 using coefficient_span = uni20::host_write_mdspan_t<CoefficientMdspec>;
121 constexpr auto acceptance = lapack_detail::linear_solve_acceptance<coefficient_span, rhs_span>();
122 if constexpr (acceptance == KernelTypeAcceptance::no)
123 return kernel_types_no;
124 else
125 return kernel_types_maybe;
126}
127
129template <uni20::MutableRankedStridedMdspecLike<2> CoefficientMdspec,
130 uni20::MutableRankedStridedMdspecLike<2> RhsMdspec>
133KernelAttempt try_kernel(LapackBackend, linear_solve_op const&, CoefficientMdspec& coefficients,
134 RhsMdspec& right_hand_sides, SolveInfo& info,
136{
138 [&](auto& coefficient_span, auto& rhs_span) {
139 return lapack_detail::try_linear_solve(coefficient_span, rhs_span, info, options);
140 },
141 coefficients, right_hand_sides);
142}
143
144} // namespace uni20::linalg
RAII leases that resolve device descriptors and tensor views to mdspans.
An mdspan-like type whose accessor is stdex::default_accessor.
Definition mdspan/concepts.hpp:501
Mutable mdspec metadata supporting host write acquisition.
Definition access.hpp:694
Concept for scalar types with a configured dense LAPACK backend.
Definition scalar_concepts.hpp:147
Operation-tag backend dispatch over tensor-view operands.
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
Checked LAPACK wrappers over provider-specific unchecked overloads.
Shared helpers for LAPACK operation-tag backend adapters.
Mdspan concept and accessor extensions for Uni20.
Lower mdspan matrix views to provider-ready BLAS operands.
constexpr blas_int try_blas_int(Value value) noexcept
Convert a non-negative integer to blas_int, or return the negative invalid sentinel.
Definition blas_int.hpp:28
constexpr bool is_valid_blas_int(blas_int value) noexcept
Return whether a non-throwing BLAS integer conversion succeeded.
Definition blas_int.hpp:25
blas_int getrf(blas_int m, blas_int n, uni20::float128 *a, blas_int lda, blas_int *ipiv)
Definition mplapack/general.hpp:85
void getrs(char trans, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, blas_int const *ipiv, Scalar *b, blas_int ldb)
Solve using an existing real dense general LU factorization.
Definition lapack.hpp:418
auto try_lapack_writable_matrix(Mdspan const &span) -> std::optional< BlasWritableMatrix< std::remove_cv_t< typename Mdspan::element_type >, typename Mdspan::data_handle_type > >
Try to lower an mdspan to the strict column-major shape expected by LAPACK.
Definition mdspan_matrix.hpp:285
KernelAttempt try_linear_solve(CoefficientMdspan &coefficients, RhsMdspan &right_hand_sides, SolveInfo &info, SolveOptions< uni20::make_real_t< typename CoefficientMdspan::value_type > > const &options)
Definition backends/lapack/linear_solve.hpp:49
KernelAttempt with_host_write_mdspans(Function &&function, Mdspecs &... mdspecs)
Invoke a LAPACK attempt with host-writable mdspans under simultaneous leases.
Definition linalg/backends/lapack/common.hpp:29
consteval auto linear_solve_acceptance()
Definition backends/lapack/linear_solve.hpp:36
Definition linalg/async.hpp:28
KernelAttempt try_kernel(BlasBackend, gemm_op const &, C &c, S const &alpha, A &a, B &b, S const &beta)
Pack logical host values and execute GEMM through value-preserving provider conversion.
Definition linalg/backends/blas/binary80.hpp:30
KernelAttempt
Result of one runtime kernel backend attempt.
Definition kernel_attempt.hpp:27
@ singular
An exactly zero elimination pivot was found.
@ nonfinite_result
A factor, solution, reduction, or required magnitude became nonfinite.
constexpr KernelAcceptance< KernelTypeAcceptance::no > kernel_types_no
Report that a backend rejects the argument types.
Definition dispatch_error.hpp:34
consteval auto kernel_accepts_types(BlasBackend, gemm_op const &, C &, S const &, A &, B &, S const &)
Accept host-readable native binary80 operands, including transforming accessors.
Definition linalg/backends/blas/binary80.hpp:19
constexpr KernelAcceptance< KernelTypeAcceptance::maybe > kernel_types_maybe
Report that runtime operand values determine backend acceptance.
Definition dispatch_error.hpp:37
constexpr auto abs(basic_half_int< T > value) -> basic_half_int< T >
Return the absolute value of a half-integer.
Definition half_int.hpp:431
std::remove_cvref_t< decltype(std::declval< detail::host_write_mdspan_lease_t< Mdspec > & >().mdspan())> host_write_mdspan_t
Writable mdspan type resolved by host descriptor acquisition.
Definition access.hpp:684
Backend-independent operation values used with normalized kernel operands.
Backend family for configured dense LAPACK kernels, including MPLAPACK scalar adapters.
Definition backend_selector.hpp:20
Diagnostics written by a completed numerical attempt, independent of dispatch.
Definition solve_info.hpp:41
Real-scalar pivot policy for a square linear solve.
Definition solve_info.hpp:62
Destructive dense general linear-system solve operation tag.
Definition operation_tags.hpp:155
Multiply one element value by a retained scalar factor.
Definition elementwise_functions.hpp:68
Trait to extract the scalar type from a type T.
Definition scalar_traits.hpp:93
Concepts for tensor-level objects that resolve mdspan kernel operands.
#define CHECK_EQUAL(a, b,...)
Definition trace.hpp:309