Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
diagnostics_impl.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace uni20::mplapack::detail
6{
7template <class Adapter, class S>
8std::size_t gelss_impl(std::size_t m, std::size_t n, std::size_t nrhs, std::span<S> a, std::span<S> b,
9 std::span<make_real_t<S>> values, make_real_t<S> const& cutoff, std::size_t& rank, Precision p)
10{
11 auto k = std::min(m, n), rows_b = std::max(m, n);
12 Adapter::check_size(a.size(), m, n);
13 Adapter::check_size(b.size(), rows_b, nrhs);
14 Adapter::check_size(values.size(), k, 1);
15 if (!k) throw std::invalid_argument("packed GELSS requires nonzero dimensions");
16 auto pm = Adapter::integer(m), pn = Adapter::integer(n), prhs = Adapter::integer(nrhs);
17 auto ldb = Adapter::integer(rows_b);
18 typename Adapter::precision_scope scope(p);
19 using P = typename Adapter::template scalar<S>;
20 auto av = Adapter::pack_values(std::span<S const>(a));
21 auto bv = Adapter::pack_values(std::span<S const>(b));
22 // Providers still need a valid address when there are no RHS columns.
23 if (bv.empty()) bv.resize(1);
24 auto threshold = Adapter::pack_values(std::span(&cutoff, 1));
25 std::vector<typename Adapter::real> singular(k), rwork;
26 if constexpr (Complex<S>) rwork.resize(auxiliary_size(k, 5));
27 mplapackint provider_rank = 0;
28 auto info = Adapter::template workspace_info<P>([&](P* work, mplapackint length, mplapackint& code) {
29 if constexpr (Real<S>)
30 Rgelss(pm, pn, prhs, av.data(), pm, bv.data(), ldb, singular.data(), threshold[0], provider_rank, work, length,
31 code);
32 else
33 Cgelss(pm, pn, prhs, av.data(), pm, bv.data(), ldb, singular.data(), threshold[0], provider_rank, work, length,
34 rwork.data(), code);
35 });
36 if (info) return static_cast<std::size_t>(info);
37 rank = static_cast<std::size_t>(provider_rank);
38 Adapter::unpack_values(av, a, p);
39 bv.resize(b.size());
40 Adapter::unpack_values(bv, b, p);
41 Adapter::unpack_values(singular, values, p);
42 return 0;
43}
44
45template <class Adapter, class S>
46make_real_t<S> gecon_impl(std::size_t n, std::span<S const> a, make_real_t<S> const& anorm, char norm, Precision p)
47{
48 Adapter::check_size(a.size(), n, n);
49 if (norm != '1' && norm != 'I') throw std::invalid_argument("condition norm must be one or infinity");
50 auto pn = Adapter::integer(n);
51 typename Adapter::precision_scope scope(p);
52 if (!n) return scalar_at_precision<make_real_t<S>>(1, p);
53 auto av = Adapter::pack_values(a);
54 auto norm_value = Adapter::pack_values(std::span(&anorm, 1));
55 using P = typename Adapter::template scalar<S>;
56 typename Adapter::real rcond;
57 mplapackint info = 0;
58 if constexpr (Real<S>)
59 {
60 std::vector<P> work(auxiliary_size(n, 4));
61 std::vector<mplapackint> iwork(n);
62 Rgecon(&norm, pn, av.data(), pn, norm_value[0], rcond, work.data(), iwork.data(), info);
63 }
64 else
65 {
66 std::vector<P> work(auxiliary_size(n, 2));
67 std::vector<typename Adapter::real> rwork(auxiliary_size(n, 2));
68 Cgecon(&norm, pn, av.data(), pn, norm_value[0], rcond, work.data(), rwork.data(), info);
69 }
70 if (info < 0) throw std::logic_error("MPLAPACK rejected validated GECON arguments");
71 return Adapter::get_value(rcond, p);
72}
73} // namespace uni20::mplapack::detail
Shared packed MPLAPACK decomposition algorithms for compiled scalar adapters.
void info(checked_format_string< Args... > format, Args &&... args)
Emit an informational display message.
Definition display.hpp:393
auto values(Tensor &tensor)
Definition packed_matrix.hpp:29
@ singular
An exactly zero elimination pivot was found.
Definition data_table.cpp:8
mpreal norm(mpcomplex const &z)
Definition mpcomplex.hpp:494