21#if UNI20_HAS_MPLAPACK_FLOAT80
33template <
class CoefficientTensor,
class RhsTensor>
34concept CompatibleLinearSolveTensors =
39template <uni20::RankedTensorView<2> CoefficientTensor, uni20::RankedTensorView<2> RhsTensor>
40void require_linear_solve_shape(CoefficientTensor
const& coefficients, RhsTensor
const& right_hand_sides)
42 ERROR_IF(coefficients.extent(0) != coefficients.extent(1),
"solve requires a square coefficient matrix");
43 ERROR_IF(coefficients.extent(0) != right_hand_sides.extent(0),
44 "solve coefficient and right-hand-side row counts do not agree");
47inline void require_solve_success(SolveInfo
const& info)
51 ERROR_IF(!
info.succeeded(),
"nonfinite result or rejected pivot in solve");
59template <KernelBackendSelector BackendSelector,
class A,
class B>
60 requires detail::CompatibleLinearSolveTensors<A, B>
64 require_precision<tensor_element_t<A>>(
p);
66 detail::require_linear_solve_shape(a, b);
67 detail::require_solve_options(options);
71 detail::dispatch_at_precision<tensor_element_t<A>>(std::forward<BackendSelector>(selector), linear_solve_op{},
p, ad,
73 if (info.succeeded() && a.extent(0) != 0 && b.extent(1) != 0)
75 uni20::detail::record_output_precision(a,
p);
76 uni20::detail::record_output_precision(b,
p);
95template <KernelBackendSelector BackendSelector,
class CoefficientTensor,
class RhsTensor>
96 requires detail::CompatibleLinearSolveTensors<CoefficientTensor, RhsTensor>
98 BackendSelector&& selector, CoefficientTensor&& coefficients, RhsTensor&& right_hand_sides,
101 return solve_inplace_with_info(std::forward<BackendSelector>(selector), std::forward<CoefficientTensor>(coefficients),
102 std::forward<RhsTensor>(right_hand_sides),
110template <
class CoefficientTensor,
class RhsTensor>
111 requires detail::CompatibleLinearSolveTensors<CoefficientTensor, RhsTensor>
113 CoefficientTensor&& coefficients, RhsTensor&& right_hand_sides,
116 auto selector =
select_backend(linear_solve_op{}, coefficients, right_hand_sides);
118 std::forward<RhsTensor>(right_hand_sides), options);
128template <KernelBackendSelector BackendSelector,
class CoefficientTensor,
class RhsTensor>
129 requires detail::CompatibleLinearSolveTensors<CoefficientTensor, RhsTensor>
130void solve_inplace(BackendSelector&& selector, CoefficientTensor&& coefficients, RhsTensor&& right_hand_sides,
131 std::optional<Precision> requested = {})
134 solve_inplace_with_info(std::forward<BackendSelector>(selector), std::forward<CoefficientTensor>(coefficients),
135 std::forward<RhsTensor>(right_hand_sides),
137 detail::require_solve_success(info);
141template <
class CoefficientTensor,
class RhsTensor>
142 requires detail::CompatibleLinearSolveTensors<CoefficientTensor, RhsTensor>
143void solve_inplace(CoefficientTensor&& coefficients, RhsTensor&& right_hand_sides, std::optional<Precision>
p = {})
145 detail::require_linear_solve_shape(coefficients, right_hand_sides);
146 auto selector =
select_backend(linear_solve_op{}, coefficients, right_hand_sides);
147 solve_inplace(selector, std::forward<CoefficientTensor>(coefficients), std::forward<RhsTensor>(right_hand_sides),
p);
153template <KernelBackendSelector BackendSelector, uni20::RankedTensorView<2> CoefficientTensor,
154 uni20::RankedTensorView<2> RhsTensor>
157[[nodiscard]]
auto solve(BackendSelector&& selector, CoefficientTensor
const& coefficients,
158 RhsTensor
const& right_hand_sides, std::optional<Precision> requested = {})
161 require_precision<tensor_element_t<CoefficientTensor>>(
p);
162 detail::require_linear_solve_shape(coefficients, right_hand_sides);
163 auto coefficient_work = uni20::make_tensor<uni20::ColumnMajor>(coefficients);
164 auto solution = uni20::make_tensor<uni20::ColumnMajor>(right_hand_sides);
165 solve_inplace(std::forward<BackendSelector>(selector), coefficient_work, solution,
p);
166 uni20::detail::record_output_precision(solution,
p);
171template <uni20::RankedTensorView<2> CoefficientTensor, uni20::RankedTensorView<2> RhsTensor>
174[[nodiscard]]
auto solve(CoefficientTensor
const& coefficients, RhsTensor
const& right_hand_sides,
175 std::optional<Precision> requested = {})
177 using work_type =
decltype(uni20::make_tensor<uni20::ColumnMajor>(right_hand_sides));
178 auto selector = select_backend_for<work_type, work_type>(linear_solve_op{});
179 return solve(selector, coefficients, right_hand_sides, requested);
183template <
class A,
class B>
184 requires detail::CompatibleLinearSolveTensors<A, B>
Reference CPU backend for dense general linear systems.
LAPACK backend for dense general linear systems.
Exact arithmetic or an explicit binary working precision.
Definition core/precision.hpp:13
MutableTensorView with a specified static rank.
Definition tensor/concepts.hpp:166
Concept for types that are either real or complex.
Definition scalar_concepts.hpp:87
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
void info(checked_format_string< Args... > format, Args &&... args)
Emit an informational display message.
Definition display.hpp:393
Definition linalg/async.hpp:28
auto solve(BackendSelector selector, async::Async< CoefficientTensor > const &coefficients, async::Async< RhsTensor > const &right_hand_sides, std::optional< Precision > p={})
Schedule a preserving dense general solve through an explicit selector.
Definition async/linear_solve.hpp:100
@ nonfinite_input
An input coefficient or RHS component was nonfinite; both workspaces are preserved.
@ singular
An exactly zero elimination pivot was found.
SolveInfo solve_inplace_with_info(BackendSelector &&selector, A &&a, B &&b, Precision p, SolveOptions< make_real_t< tensor_element_t< A > > > const &options={})
Solve in place at an explicit operation precision, independent of workspace defaults.
Definition ops/linear_solve.hpp:61
void solve_inplace(BackendSelector selector, async::Async< CoefficientTensor > &coefficients, async::Async< RhsTensor > &right_hand_sides, std::optional< Precision > p={})
Schedule a destructive dense general solve through an explicit selector.
Definition async/linear_solve.hpp:125
constexpr auto select_backend(Operation const &operation, FirstTensor const &, RestTensors const &...)
Select the default backend list for an operation on Tensor operands.
Definition backend_selector.hpp:252
Definition data_table.cpp:8
constexpr Precision common_default_precision(A const &a, B const &b)
Select a binary operation's default without inspecting element precisions.
Definition tensor/precision.hpp:43
constexpr decltype(auto) mdspec_of(Tensor &tensor) noexcept(noexcept(tensor.mdspec()))
Return a tensor's immediate or descriptor-backed multidimensional metadata.
Definition tensor/concepts.hpp:50
std::remove_cv_t< typename tensor_mdspec_t< T >::element_type > tensor_element_t
Scalar value type exposed by a tensor-level object.
Definition tensor/concepts.hpp:126
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
Concepts for tensor-level objects that resolve mdspan kernel operands.
Backend-dispatched tensor copies and inferred owning materialization.
General-purpose owning tensors with runtime extents.
#define ERROR_IF(cond,...)
Definition trace.hpp:389