|
TDLS 0.4.0
Tiny Device-callable Linear Solvers
|
Compile-time-shape solver of arrowhead (bordered block-diagonal) systems by static condensation, built on TiledLUpp. More...
#include <cmath>#include <type_traits>#include <utility>#include <tdls/core/macros.hpp>#include <tdls/core/math.hpp>#include <tdls/core/target.hpp>#include <tdls/solvers/arrowhead_lupp/config.hpp>#include <tdls/solvers/arrowhead_lupp/storage_map.hpp>#include <tdls/solvers/tiled_lupp/solver_static.hpp>Go to the source code of this file.
Classes | |
| struct | tdls::detail::ArrowheadStreamedBlock< T, S, B, col, diag > |
| Block k of a streamed solve of ArrowheadLUppSolverStatic (ArrowheadLUppSolverStatic::StreamedBlock): the working arrays of the solver themselves, which the caller fills through the accessors when the solver asks for the block; the factorization and the solve then run in place. Only a save is copied (D_k, and [A_kb | y_k] when the column-major check reads the forward stage), to store a refused block as given. Entries in logical order whatever the layout and the storage. The arrays come uninitialized, or holding another block: the caller writes every entry, zeros included, by assignment. More... | |
| struct | tdls::detail::ArrowheadRecomputedBlock< T, S, B, col, diag > |
| Block k of a recomputed solve (solve_inplace_recomputed, solve_inplace_recomputed_or_tangent): a StreamedBlock, the same accessors, and whether the solver asks for the block again, in its recovery. A provider taking a StreamedBlock& serves too; one taking a RecomputedBlock&, or auto&, reads the flag. The streamed entry points keep the StreamedBlock alone, so that their code is that of a solver without the recomputed ones. More... | |
| struct | tdls::ArrowheadLUppSolverStatic< T, Shape, Config > |
| Arrowhead solver with a compile-time shape. More... | |
Macros | |
| #define | TDLS_ARROW_LUPP_A(idx) |
| Stored entry at index idx of the matrix: contiguous under internal residency, strided otherwise. | |
| #define | TDLS_ARROW_LUPP_Y(i) |
| Entry i of the right-hand side and solution: contiguous under internal residency, strided otherwise. | |
| #define | TDLS_ARROW_LUPP_YW(m, i) |
| Entry i of column m of the right-hand sides and solutions: columns of dimension contiguous entries under internal residency, xcol_stride-strided columns otherwise. The function declares ycols, its number of columns: with one, m is ignored and the macro is TDLS_ARROW_LUPP_Y exactly. | |
| #define | TDLS_ARROW_LUPP_W(e) |
| Entry e of the workspace: contiguous under internal residency, strided otherwise. | |
| #define | TDLS_ARROW_LUPP_F(r, c) |
| Entry (r, c) of the front of the second pass, row-major at the start of the workspace, fcols columns per row. | |
| #define | TDLS_ARROW_LUPP_SIDED(...) |
| Under the side dispatch of nvc++ (TDLS_TARGET_GPU), when the host and the device choose differently (sided), returns the call, the variadic argument, run by the solver of the side of the code: SolverGpu on the device, SolverCpu on the host; nothing elsewhere and in constant expressions. | |
| #define | TDLS_ARROW_LUPP_FOR(i, first, last, ...) |
for (int i = first; i < last; ++i) { body } under the unroll policy of the configuration: the two-branch if constexpr of the other families, the forced-unroll pragma lexically present in the first branch only. The body is the variadic argument. | |
Enumerations | |
| enum class | tdls::detail::ArrowheadStreamedOutcome { solved , tangent , singular } |
| Outcome of ArrowheadLUppSolverStatic::solve_inplace_streamed_or_tangent. More... | |
| enum class | tdls::detail::ArrowheadRecomputedOutcome { solved , tangent , singular , deferred } |
| Outcome of ArrowheadLUppSolverStatic::solve_inplace_recomputed and solve_inplace_recomputed_or_tangent. More... | |
Compile-time-shape solver of arrowhead (bordered block-diagonal) systems by static condensation, built on TiledLUpp.
The system has B border unknowns first, then NB blocks of S unknowns:
[ Abb Ab0 Ab1 ... ] [xb] [yb] [ A0b D0 ] [x0] [y0] [ A1b D1 ] [x1] = [y1] [ ... ... ] [..] [..]
Two blocks never couple. The solver reads only the entries of this pattern: the zeros are never read, so they need not be stored (see storage_map.hpp).
Algorithm. First pass, per block k:
Condensation of an accepted block, per layout:
A refused block costs the second pass, never a failure: the solver succeeds whenever the full matrix is invertible, rounding aside. Like TiledLUpp, the solver does not detect non-finite entries: a block with one fails the pivot check and goes to the second pass, where they spread to the solution. A true return is no proof of a finite solution.
On exit y holds the solution. A holds the recovery data in place of A_kb, and in place of D_k for the refused blocks and, under the row-major layout with the dense coupling and MinFlops, for the accepted ones too; with schur_in_place, the coupled border rows of A hold the Schur complement of the accepted blocks. The other entries are only read. The canonical solves recover nothing and store no recovery data: they write in A only the Schur complement under schur_in_place and, streamed, the refused blocks. Without schur_in_place, a stored A thus comes out unchanged and serves the next columns.
The caller pre-offsets every remote pointer with the system index and passes a runtime stride, as for the other families, or a stride known at compile time as a template argument (see tdls::dynamic_stride); the internal_rhs / internal_work / internal_matrix template booleans declare a caller-local array instead (stride ignored). The workspace holds the front of the second pass: it is touched only when blocks are refused.
Streamed blocks. The *_streamed entry points take the blocks from a provider, called exactly once per block and in order when the solver condenses it, instead of reading them from A: the caller stores only the border, and the provider writes every entry of the block, zeros included, in the working arrays of the solver (StreamedBlock). A refused block is stored as given for the second pass. The arithmetic is that of the stored path, bit for bit when the compiler contracts multiply-adds alike in the two paths (-ffp-contract=off, or –fmad=false for nvcc, guarantees it; GCC with -march=native does not). The streamed path is selected at compile time: the stored entry points keep their signatures and their code. The entry points are noexcept: the provider must not throw.
| #define TDLS_ARROW_LUPP_A | ( | idx | ) |
Stored entry at index idx of the matrix: contiguous under internal residency, strided otherwise.
| #define TDLS_ARROW_LUPP_F | ( | r, | |
| c ) |
Entry (r, c) of the front of the second pass, row-major at the start of the workspace, fcols columns per row.
| #define TDLS_ARROW_LUPP_FOR | ( | i, | |
| first, | |||
| last, | |||
| ... ) |
for (int i = first; i < last; ++i) { body } under the unroll policy of the configuration: the two-branch if constexpr of the other families, the forced-unroll pragma lexically present in the first branch only. The body is the variadic argument.
| #define TDLS_ARROW_LUPP_W | ( | e | ) |
Entry e of the workspace: contiguous under internal residency, strided otherwise.
| #define TDLS_ARROW_LUPP_Y | ( | i | ) |
Entry i of the right-hand side and solution: contiguous under internal residency, strided otherwise.
| #define TDLS_ARROW_LUPP_YW | ( | m, | |
| i ) |
Entry i of column m of the right-hand sides and solutions: columns of dimension contiguous entries under internal residency, xcol_stride-strided columns otherwise. The function declares ycols, its number of columns: with one, m is ignored and the macro is TDLS_ARROW_LUPP_Y exactly.
|
strong |
Outcome of ArrowheadLUppSolverStatic::solve_inplace_recomputed and solve_inplace_recomputed_or_tangent.
|
strong |