Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
backends/lapack/lq.hpp
Go to the documentation of this file.
1#pragma once
2
9#include "common.hpp"
10
21
22#include <algorithm>
23#include <concepts>
24#include <cstddef>
25#include <type_traits>
26#include <vector>
27
28namespace uni20::linalg
29{
30namespace lapack_detail
31{
32
33template <class LMdspan, class QMdspan, class MatrixMdspan> consteval auto lq_acceptance()
34{
35 using l_scalar = std::remove_cv_t<typename LMdspan::element_type>;
36 using q_scalar = std::remove_cv_t<typename QMdspan::element_type>;
37 using matrix_scalar = std::remove_cv_t<typename MatrixMdspan::element_type>;
38 if constexpr (uni20::LapackScalar<matrix_scalar> && std::same_as<l_scalar, matrix_scalar> &&
39 std::same_as<q_scalar, matrix_scalar> && uni20::DefaultAccessorMdspanLike<MatrixMdspan>)
40 return kernel_types_maybe;
41 else
42 return kernel_types_no;
43}
44
45template <uni20::MutableRankedMdspanLike<2> LMdspan, uni20::MutableRankedMdspanLike<2> QMdspan,
46 uni20::MutableRankedStridedMdspanLike<2> MatrixMdspan>
47KernelAttempt try_lq(LMdspan& l, QMdspan& q, MatrixMdspan& matrix_work)
48{
49 using scalar_type = std::remove_cv_t<typename MatrixMdspan::element_type>;
50 using l_index_type = typename LMdspan::index_type;
51 using q_index_type = typename QMdspan::index_type;
52 using matrix_index_type = typename MatrixMdspan::index_type;
53
54 std::size_t const rows_size = static_cast<std::size_t>(matrix_work.extent(0));
55 std::size_t const cols_size = static_cast<std::size_t>(matrix_work.extent(1));
56 std::size_t const rank_size = std::min(rows_size, cols_size);
57 CHECK_EQUAL(l.extent(0), matrix_work.extent(0));
58 CHECK_EQUAL(static_cast<std::size_t>(l.extent(1)), rank_size);
59 CHECK_EQUAL(static_cast<std::size_t>(q.extent(0)), rank_size);
60 CHECK_EQUAL(q.extent(1), matrix_work.extent(1));
61
62 if (rank_size == 0) return KernelAttempt::success;
63
64 blas_int const rows = uni20::blas::try_blas_int(rows_size);
65 blas_int const cols = uni20::blas::try_blas_int(cols_size);
66 blas_int const rank = uni20::blas::try_blas_int(rank_size);
70
71 auto matrix = uni20::linalg::blas::try_lapack_writable_matrix(matrix_work);
72 if (!matrix) return KernelAttempt::unsupported_layout;
73 CHECK_EQUAL(matrix->rows, rows);
74 CHECK_EQUAL(matrix->cols, cols);
75
76 std::vector<scalar_type> tau(rank_size);
77 scalar_type work_query{};
78 uni20::lapack::gelqf(rows, cols, matrix->data, matrix->leading_dimension, tau.data(), &work_query, -1);
79 blas_int const gelqf_lwork = workspace_size(work_query);
80 std::vector<scalar_type> work(static_cast<std::size_t>(gelqf_lwork));
81 uni20::lapack::gelqf(rows, cols, matrix->data, matrix->leading_dimension, tau.data(), work.data(), gelqf_lwork);
82
83 for (std::size_t row = 0; row < rows_size; ++row)
84 {
85 for (std::size_t column = 0; column < rank_size; ++column)
86 {
87 auto const l_row = static_cast<l_index_type>(row);
88 auto const l_column = static_cast<l_index_type>(column);
89 if (column <= row)
90 {
91 l[l_row, l_column] = matrix_work[static_cast<matrix_index_type>(row), static_cast<matrix_index_type>(column)];
92 }
93 else
94 {
95 l[l_row, l_column] = scalar_type{};
96 }
97 }
98 }
99
100 work_query = scalar_type{};
101 uni20::lapack::orglq(rank, cols, rank, matrix->data, matrix->leading_dimension, tau.data(), &work_query, -1);
102 blas_int const orglq_lwork = workspace_size(work_query);
103 work.resize(static_cast<std::size_t>(orglq_lwork));
104 uni20::lapack::orglq(rank, cols, rank, matrix->data, matrix->leading_dimension, tau.data(), work.data(), orglq_lwork);
105
106 for (std::size_t row = 0; row < rank_size; ++row)
107 {
108 for (std::size_t column = 0; column < cols_size; ++column)
109 {
110 q[static_cast<q_index_type>(row), static_cast<q_index_type>(column)] =
111 matrix_work[static_cast<matrix_index_type>(row), static_cast<matrix_index_type>(column)];
112 }
113 }
115}
116
117} // namespace lapack_detail
118
120template <uni20::MutableRankedMdspecLike<2> LMdspec, uni20::MutableRankedMdspecLike<2> QMdspec,
121 uni20::MutableRankedStridedMdspecLike<2> MatrixMdspec>
124consteval auto kernel_accepts_types(LapackBackend const&, lq_op const&, LMdspec&, QMdspec&, MatrixMdspec&)
125{
129 constexpr auto acceptance = lapack_detail::lq_acceptance<l_span, q_span, matrix_span>();
130 if constexpr (acceptance == KernelTypeAcceptance::no)
131 return kernel_types_no;
132 else
133 return kernel_types_maybe;
134}
135
137template <uni20::MutableRankedMdspecLike<2> LMdspec, uni20::MutableRankedMdspecLike<2> QMdspec,
138 uni20::MutableRankedStridedMdspecLike<2> MatrixMdspec>
141KernelAttempt try_kernel(LapackBackend, lq_op const&, LMdspec& l, QMdspec& q, MatrixMdspec& matrix_work)
142{
144 [](auto& l_span, auto& q_span, auto& matrix_span) { return lapack_detail::try_lq(l_span, q_span, matrix_span); },
145 l, q, matrix_work);
146}
147
148} // namespace uni20::linalg
149
150#if UNI20_HAS_MPLAPACK_MPREAL || UNI20_HAS_MPLAPACK_FLOAT80
152#endif
RAII leases that resolve device descriptors and tensor views to mdspans.
Safe conversion helpers for the configured signed BLAS integer ABI.
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
Logical host adapters for value-converting dense decompositions.
Operation-tag backend dispatch over tensor-view operands.
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
void orglq(blas_int m, blas_int n, blas_int k, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Generate an explicit orthogonal or unitary Q factor from an LQ factorization.
Definition lapack.hpp:569
void gelqf(blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Compute a real or complex dense LQ factorization through the configured LAPACK backend.
Definition lapack.hpp:537
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
blas_int workspace_size(Scalar const &query)
Convert a provider workspace query result to the configured LAPACK integer type.
Definition linalg/backends/lapack/common.hpp:43
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 lq_acceptance()
Definition backends/lapack/lq.hpp:33
KernelAttempt try_lq(LMdspan &l, QMdspan &q, MatrixMdspan &matrix_work)
Definition backends/lapack/lq.hpp:47
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
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
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
Reduced dense real LQ factorization operation tag.
Definition operation_tags.hpp:187
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