31namespace lapack_detail
33template <
class Operation>
35 std::same_as<std::remove_cvref_t<Operation>, singular_values_op> ||
36 std::same_as<std::remove_cvref_t<Operation>, svd_left_op> ||
37 std::same_as<std::remove_cvref_t<Operation>, svd_right_op> || std::same_as<std::remove_cvref_t<Operation>, svd_op>;
48 PANIC(
"invalid SvdVectorExtent", std::to_underlying(extent));
51template <
class MatrixMdspan>
void set_identity(MatrixMdspan&& matrix)
53 using scalar_type = std::remove_cv_t<typename std::remove_cvref_t<MatrixMdspan>::element_type>;
54 for (std::size_t
row = 0; row < static_cast<std::size_t>(matrix.extent(0)); ++
row)
56 for (std::size_t column = 0; column < static_cast<std::size_t>(matrix.extent(1)); ++column)
65 using matrix_scalar = std::remove_cv_t<typename MatrixMdspan::element_type>;
66 using singular_value_scalar = std::remove_cv_t<typename SingularValueMdspan::element_type>;
68 std::same_as<singular_value_scalar, uni20::make_real_t<matrix_scalar>> &&
74 using matrix_scalar = std::remove_cv_t<typename MatrixMdspan::element_type>;
75 using factor_scalar = std::remove_cv_t<typename FactorMdspan::element_type>;
79template <uni20::LapackScalar Scalar,
class MatrixHandle,
class ValueHandle>
83 Scalar* left, blas_int left_leading_dimension,
Scalar* right, blas_int right_leading_dimension)
90 left, left_leading_dimension, right, right_leading_dimension, &work_query, -1);
92 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
94 left, left_leading_dimension, right, right_leading_dimension, work.data(), lwork);
103 std::vector<real_type> rwork(std::max<std::size_t>(1, *rwork_size), real_type{});
105 left, left_leading_dimension, right, right_leading_dimension, &work_query, -1, rwork.data());
107 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
109 left, left_leading_dimension, right, right_leading_dimension, work.data(), lwork,
115template <
class SingularValueMdspan,
class MatrixMdspan>
117 MatrixMdspan&& matrix_work)
119 using matrix_scalar = std::remove_cv_t<typename std::remove_cvref_t<MatrixMdspan>::element_type>;
120 std::size_t
const rows =
static_cast<std::size_t
>(matrix_work.extent(0));
121 std::size_t
const cols =
static_cast<std::size_t
>(matrix_work.extent(1));
122 std::size_t
const rank = std::min(rows, cols);
131 if (!matrix || !values)
142 return run_gesvd(jobu, jobvt, rank, *matrix, *values,
static_cast<matrix_scalar*
>(matrix->data), 1,
143 static_cast<matrix_scalar*
>(matrix->data), 1);
147namespace lapack_detail
150template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
151 uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
153 std::type_identity<MatrixMdspan>)
155 if constexpr (lapack_detail::svd_base_types_supported<SingularValueMdspan, MatrixMdspan>())
166template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
167 uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
174template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
175 uni20::MutableRankedStr
idedMdspanLike<2> LeftMdspan, uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
177 std::type_identity<LeftMdspan>, std::type_identity<MatrixMdspan>)
179 if constexpr (lapack_detail::svd_base_types_supported<SingularValueMdspan, MatrixMdspan>() &&
180 lapack_detail::svd_factor_types_supported<LeftMdspan, MatrixMdspan>())
191template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
192 uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
194 std::type_identity<MatrixMdspan>)
196 if constexpr (lapack_detail::svd_base_types_supported<SingularValueMdspan, MatrixMdspan>())
207template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
208 uni20::MutableRankedStr
idedMdspanLike<2> LeftMdspan, uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
210 MatrixMdspan& matrix_work)
213 using matrix_scalar = std::remove_cv_t<typename std::remove_cvref_t<MatrixMdspan>::element_type>;
214 std::size_t
const rows =
static_cast<std::size_t
>(matrix_work.extent(0));
215 std::size_t
const cols =
static_cast<std::size_t
>(matrix_work.extent(1));
216 std::size_t
const rank = std::min(rows, cols);
219 CHECK_EQUAL(
static_cast<std::size_t
>(left_singular_vectors.extent(0)), rows);
220 CHECK_EQUAL(
static_cast<std::size_t
>(left_singular_vectors.extent(1)), left_cols);
230 if (!matrix || !values || !left)
244 return run_gesvd(
svd_job(op.
left),
'N', rank, *matrix, *values, left->data, left->leading_dimension,
245 static_cast<matrix_scalar*
>(matrix->data), 1);
249template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
250 uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
259template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
260 uni20::MutableRankedStr
idedMdspanLike<2> RightAdjo
intMdspan,
261 uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
263 std::type_identity<RightAdjointMdspan>, std::type_identity<MatrixMdspan>)
265 if constexpr (lapack_detail::svd_base_types_supported<SingularValueMdspan, MatrixMdspan>() &&
266 lapack_detail::svd_factor_types_supported<RightAdjointMdspan, MatrixMdspan>())
277template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
278 uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
280 std::type_identity<MatrixMdspan>)
282 if constexpr (lapack_detail::svd_base_types_supported<SingularValueMdspan, MatrixMdspan>())
293template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
294 uni20::MutableRankedStr
idedMdspanLike<2> RightAdjo
intMdspan,
295 uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
297 RightAdjointMdspan& right_singular_vectors_adjoint, MatrixMdspan& matrix_work)
300 using matrix_scalar = std::remove_cv_t<typename std::remove_cvref_t<MatrixMdspan>::element_type>;
301 std::size_t
const rows =
static_cast<std::size_t
>(matrix_work.extent(0));
302 std::size_t
const cols =
static_cast<std::size_t
>(matrix_work.extent(1));
303 std::size_t
const rank = std::min(rows, cols);
306 CHECK_EQUAL(
static_cast<std::size_t
>(right_singular_vectors_adjoint.extent(0)), right_rows);
307 CHECK_EQUAL(
static_cast<std::size_t
>(right_singular_vectors_adjoint.extent(1)), cols);
317 if (!matrix || !values || !right)
331 return run_gesvd(
'N',
svd_job(op.
right), rank, *matrix, *values,
static_cast<matrix_scalar*
>(matrix->data), 1,
332 right->data, right->leading_dimension);
336template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
337 uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
349consteval auto svd_acceptance(
svd_op const&, std::type_identity<SingularValueMdspan>, std::type_identity<LeftMdspan>,
350 std::type_identity<RightAdjointMdspan>, std::type_identity<MatrixMdspan>)
352 if constexpr (lapack_detail::svd_base_types_supported<SingularValueMdspan, MatrixMdspan>() &&
353 lapack_detail::svd_factor_types_supported<LeftMdspan, MatrixMdspan>() &&
354 lapack_detail::svd_factor_types_supported<RightAdjointMdspan, MatrixMdspan>())
365template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
366 uni20::MutableRankedStr
idedMdspanLike<2> OtherFactorMdspan,
367 uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
369 std::type_identity<OtherFactorMdspan>, std::type_identity<MatrixMdspan>)
371 if constexpr (lapack_detail::svd_base_types_supported<SingularValueMdspan, MatrixMdspan>() &&
372 lapack_detail::svd_factor_types_supported<OtherFactorMdspan, MatrixMdspan>())
390 RightAdjointMdspan& right_singular_vectors_adjoint, MatrixMdspan& matrix_work)
393 std::size_t
const rows =
static_cast<std::size_t
>(matrix_work.extent(0));
394 std::size_t
const cols =
static_cast<std::size_t
>(matrix_work.extent(1));
395 std::size_t
const rank = std::min(rows, cols);
400 CHECK_EQUAL(
static_cast<std::size_t
>(left_singular_vectors.extent(0)), rows);
401 CHECK_EQUAL(
static_cast<std::size_t
>(left_singular_vectors.extent(1)), left_cols);
402 CHECK_EQUAL(
static_cast<std::size_t
>(right_singular_vectors_adjoint.extent(0)), right_rows);
403 CHECK_EQUAL(
static_cast<std::size_t
>(right_singular_vectors_adjoint.extent(1)), cols);
415 if (!matrix || !values || !left || !right)
435 right->data, right->leading_dimension);
439template <uni20::MutableRankedStr
idedMdspanLike<1> SingularValueMdspan,
440 uni20::MutableRankedStr
idedMdspanLike<2> OtherFactorMdspan,
441 uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan>
443 MatrixMdspan& matrix_work)
445 using matrix_scalar = std::remove_cv_t<typename std::remove_cvref_t<MatrixMdspan>::element_type>;
446 std::size_t
const rows =
static_cast<std::size_t
>(matrix_work.extent(0));
447 std::size_t
const cols =
static_cast<std::size_t
>(matrix_work.extent(1));
448 std::size_t
const rank = std::min(rows, cols);
458 CHECK_EQUAL(
static_cast<std::size_t
>(other_factor.extent(0)), right_rows);
459 CHECK_EQUAL(
static_cast<std::size_t
>(other_factor.extent(1)), cols);
468 CHECK_EQUAL(
static_cast<std::size_t
>(other_factor.extent(0)), rows);
469 CHECK_EQUAL(
static_cast<std::size_t
>(other_factor.extent(1)), left_cols);
483 if (!matrix || !values || !other)
495 matrix_scalar* left =
static_cast<matrix_scalar*
>(matrix->data);
496 blas_int left_leading_dimension = 1;
497 matrix_scalar* right =
static_cast<matrix_scalar*
>(matrix->data);
498 blas_int right_leading_dimension = 1;
503 right_leading_dimension = other->leading_dimension;
509 left_leading_dimension = other->leading_dimension;
511 return run_gesvd(jobu, jobvt, rank, *matrix, *values, left, left_leading_dimension, right, right_leading_dimension);
523 constexpr auto acceptance =
545#if UNI20_HAS_MPLAPACK_MPREAL || UNI20_HAS_MPLAPACK_FLOAT80
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
Real scalar types supported by the configured raw-pointer LAPACK wrappers.
Definition scalar_concepts.hpp:115
Concept for scalar types with a configured dense LAPACK backend.
Definition scalar_concepts.hpp:147
A mutable strided mdspan-like type with a specified static rank.
Definition mdspan/concepts.hpp:532
Mutable mdspec-like type whose mapping is always strided.
Definition mdspan/concepts.hpp:440
Concept for numeric scalar types (integer, real, or complex).
Definition scalar_concepts.hpp:81
Definition backends/lapack/svd.hpp:34
Logical host adapters for value-converting dense decompositions.
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.
Lower mdspan matrix views to provider-ready BLAS operands.
Lower rank-one mdspan 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 gesvd(char jobu, char jobvt, blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *s, Scalar *u, blas_int ldu, Scalar *vt, blas_int ldvt, Scalar *work, blas_int lwork)
Compute a real dense singular value decomposition.
Definition lapack.hpp:1186
auto try_lapack_writable_vector(Mdspan const &span) -> std::optional< BlasWritableVector< std::remove_cv_t< typename Mdspan::element_type >, typename Mdspan::data_handle_type > >
Try to lower an mdspan to the contiguous writable vector shape expected by LAPACK.
Definition mdspan_vector.hpp:130
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
consteval auto svd_acceptance(singular_values_op const &, std::type_identity< SingularValueMdspan >, std::type_identity< MatrixMdspan >)
Report compile-time eligibility for resolved LAPACK singular values.
Definition backends/lapack/svd.hpp:152
KernelAttempt try_svd(singular_values_op const &, SingularValueMdspan &singular_values, MatrixMdspan &matrix_work)
Compute exact singular values through LAPACK gesvd.
Definition backends/lapack/svd.hpp:168
KernelAttempt try_singular_values_kernel(char jobu, char jobvt, SingularValueMdspan &&singular_values, MatrixMdspan &&matrix_work)
Definition backends/lapack/svd.hpp:116
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
void set_identity(MatrixMdspan &&matrix)
Definition backends/lapack/svd.hpp:51
consteval bool svd_factor_types_supported()
Definition backends/lapack/svd.hpp:72
consteval bool svd_base_types_supported()
Definition backends/lapack/svd.hpp:63
KernelAttempt run_gesvd(char jobu, char jobvt, std::size_t rank, uni20::linalg::blas::BlasWritableMatrix< Scalar, MatrixHandle > const &matrix, uni20::linalg::blas::BlasWritableVector< uni20::make_real_t< Scalar >, ValueHandle > const &values, Scalar *left, blas_int left_leading_dimension, Scalar *right, blas_int right_leading_dimension)
Definition backends/lapack/svd.hpp:80
char svd_job(SvdVectorExtent extent)
Definition backends/lapack/svd.hpp:39
constexpr std::optional< std::size_t > try_size_product(std::size_t left, std::size_t right) noexcept
Multiply allocation extents without wrapping std::size_t.
Definition linalg/backends/lapack/common.hpp:69
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
SvdVectorExtent
Extent policy for one side of an exact singular value decomposition.
Definition operation_tags.hpp:248
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 singular_values(BackendSelector selector, async::Async< MatrixTensor > const &matrix, std::optional< Precision > requested={})
Schedule preserving exact singular values through an explicit selector.
Definition async/svd.hpp:416
Backend family for configured dense LAPACK kernels, including MPLAPACK scalar adapters.
Definition backend_selector.hpp:20
Writable matrix shape as seen by a BLAS/LAPACK provider.
Definition blas_matrix.hpp:119
blas_int rows
Definition blas_matrix.hpp:121
blas_int leading_dimension
Definition blas_matrix.hpp:123
Handle data
Definition blas_matrix.hpp:120
blas_int cols
Definition blas_matrix.hpp:122
Writable vector shape as seen by a BLAS provider.
Definition blas_vector.hpp:16
Exact dense singular-values-only operation tag.
Definition operation_tags.hpp:270
Exact dense left singular-vector operation tag.
Definition operation_tags.hpp:276
SvdVectorExtent left
Definition operation_tags.hpp:278
bool overwrite_input
Definition operation_tags.hpp:279
Exact dense singular value decomposition operation tag.
Definition operation_tags.hpp:292
SvdVectorExtent left
Definition operation_tags.hpp:294
SvdVectorExtent right
Definition operation_tags.hpp:295
SvdOverwrite overwrite
Definition operation_tags.hpp:296
Exact dense right singular-vector operation tag.
Definition operation_tags.hpp:284
SvdVectorExtent right
Definition operation_tags.hpp:286
bool overwrite_input
Definition operation_tags.hpp:287
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(cond,...)
Definition trace.hpp:299
#define PANIC(...)
Definition trace.hpp:382
#define CHECK_EQUAL(a, b,...)
Definition trace.hpp:309