Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
backends/lapack/lu.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <uni20/config.hpp>
4#if UNI20_HAS_MPLAPACK_MPREAL
5#include "lu_mpfr.hpp"
6#endif
7
8#include "linear_solve.hpp"
10
11namespace uni20::linalg
12{
14template <MutableRankedStridedMdspecLike<2> A>
15 requires HostWritableMdspec<A> && LapackScalar<typename A::value_type> &&
16 DefaultAccessorMdspanLike<host_write_mdspan_t<A>>
23
25template <MutableRankedStridedMdspecLike<2> A>
28KernelAttempt try_kernel(LapackBackend, lu_factor_op const&, A& a, std::span<std::size_t> pivots,
31{
32 detail::require_lu_shape(a, pivots.size());
33 detail::require_solve_options(options);
34 auto n = uni20::blas::try_blas_int(a.extent(0));
36 if (n == 0)
37 {
38 if (norms) *norms = {};
39 info = {};
41 }
42 auto access = acquire_host_write_access_sync(a);
43 auto s = access.mdspan();
44 auto matrix = blas::try_lapack_writable_matrix(s);
45 if (!matrix) return KernelAttempt::unsupported_layout;
46 std::vector<blas_int> provider_pivots(pivots.size());
47 info = {};
48 if (!detail::solve_matrix_is_finite(s))
49 {
50 info.status = SolveStatus::nonfinite_input;
52 }
53 detail::capture_lu_norms(s, norms, make_real_t<typename A::value_type>{});
54 auto scale = detail::lu_input_scale(s, make_real_t<typename A::value_type>{});
55 auto code = uni20::lapack::unchecked::getrf(n, n, matrix->data, matrix->leading_dimension, provider_pivots.data());
56 uni20::lapack::detail::check_invalid_argument("getrf", code);
57 for (std::size_t k = 0; k < pivots.size(); ++k)
58 pivots[k] = std::size_t(provider_pivots[k] - 1);
59 if (!detail::solve_matrix_is_finite(s))
61 else if (code > 0)
62 info = {.status = SolveStatus::singular, .pivot = std::size_t(code - 1)};
63 else
64 detail::check_lu_diagonal(s, scale, options.relative_pivot_tolerance, info);
66}
67
69template <RankedStridedMdspecLike<2> A, MutableRankedStridedMdspecLike<2> B>
71 std::same_as<typename A::value_type, typename B::value_type> &&
73consteval auto kernel_accepts_types(LapackBackend, lu_solve_op const&, A&, std::span<std::size_t const>, B&, SolveInfo&)
74{
75 return kernel_types_maybe;
76}
77
80template <RankedStridedMdspecLike<2> A, MutableRankedStridedMdspecLike<2> B>
82 std::same_as<typename A::value_type, typename B::value_type> &&
84KernelAttempt try_kernel(LapackBackend, lu_solve_op const&, A& a, std::span<std::size_t const> pivots, B& b,
85 SolveInfo& info)
86{
87 detail::require_lu_solve_shape(a, pivots, b);
88 auto n = uni20::blas::try_blas_int(a.extent(0));
89 auto nrhs = uni20::blas::try_blas_int(b.extent(1));
92 if (n == 0 || nrhs == 0)
93 {
94 info = {};
96 }
99 auto as = aa.mdspan();
100 auto bs = ba.mdspan();
101 auto matrix = blas::try_blas_readable_matrix(as);
103 if (!matrix || matrix->transform != blas::MatrixTransform::normal || !rhs) return KernelAttempt::unsupported_layout;
104 std::vector<blas_int> provider_pivots(pivots.size());
105 for (std::size_t k = 0; k < pivots.size(); ++k)
106 provider_pivots[k] = blas_int(pivots[k] + 1);
107 info = {};
108 if (!detail::solve_matrix_is_finite(bs))
109 {
110 info.status = SolveStatus::nonfinite_input;
112 }
113 // GETRS's factor argument is input-only. The legacy provider declaration
114 // lacks const; this cast is confined to that boundary, under a read lease.
115 using S = typename A::value_type;
116 uni20::lapack::getrs('N', n, nrhs, const_cast<S*>(matrix->data), matrix->leading_dimension, provider_pivots.data(),
117 rhs->data, rhs->leading_dimension);
118 if (!detail::solve_matrix_is_finite(bs)) info.status = SolveStatus::nonfinite_result;
120}
121} // namespace uni20::linalg
An mdspan-like type whose accessor is stdex::default_accessor.
Definition mdspan/concepts.hpp:501
Mdspec metadata supporting host read acquisition.
Definition access.hpp:688
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
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
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_blas_readable_matrix(Mdspan const &span) -> std::optional< BlasReadableMatrix< std::remove_cv_t< typename Mdspan::element_type >, typename Mdspan::data_handle_type > >
Try to lower an mdspan directly to a readable provider operand.
Definition mdspan_matrix.hpp:272
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
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
@ nonfinite_input
An input coefficient or RHS component was nonfinite; both workspaces are preserved.
@ singular
An exactly zero elimination pivot was found.
@ nonfinite_result
A factor, solution, reduction, or required magnitude became nonfinite.
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
auto acquire_host_read_access_sync(Mdspan const &mdspan)
Acquire a directly host-accessible read-only mdspan.
Definition access.hpp:616
auto acquire_host_write_access_sync(Mdspan &mdspan)
Acquire a directly host-accessible writable mdspan.
Definition access.hpp:626
Destructive-workspace and value-producing dense general solves.
Backend family for configured dense LAPACK kernels, including MPLAPACK scalar adapters.
Definition backend_selector.hpp:20
Original matrix norms after conversion to factor precision.
Definition lu_info.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
Fixed-output packed LU factorization with zero-based row-swap pivots.
Definition operation_tags.hpp:165
Solve using read-only packed LU factors, overwriting an existing RHS.
Definition operation_tags.hpp:171
Multiply one element value by a retained scalar factor.
Definition elementwise_functions.hpp:68