TDLS 0.4.0
Tiny Device-callable Linear Solvers
Loading...
Searching...
No Matches
solver_dynamic.hpp File Reference

Runtime-size variant of the TiledLUpp solver. More...

#include <tdls/core/math.hpp>
#include <tdls/core/target.hpp>
#include <type_traits>
#include <tdls/solvers/tiled_lupp/config.hpp>
Include dependency graph for solver_dynamic.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  tdls::TiledLUppSolverDynamic< T, Config >
 Runtime-size tiled dense LU factorization with logical partial pivoting and out-of-tile pivot recovery, solving one n x n system per call. More...
 

Macros

#define TDLS_LUPP_DYN_A(r, c)
 Strided element (r, c) of S, the stored matrix read row-major (A or A^T, see the file documentation).
 
#define TDLS_LUPP_DYN_PIV(i)
 Strided pivot entry i.
 
#define TDLS_LUPP_DYN_X(i)
 Strided entry i of the solution vector.
 
#define TDLS_LUPP_DYN_B(i)
 Strided entry i of the right-hand side.
 
#define TDLS_LUPP_DYN_XW(w, i)
 Strided entry i of column w of a multi right-hand-side block.
 
#define TDLS_LUPP_DYN_BW(w, i)
 Strided entry i of column w of a multi right-hand-side block of b, addressed exactly as TDLS_LUPP_DYN_XW (b and x share both strides).
 
#define TDLS_LUPP_DYN_Y(i)
 Strided entry i of the fused right-hand side of solve_inplace.
 

Detailed Description

Runtime-size variant of the TiledLUpp solver.

Author
Tristan Chenaille

Same algorithm as TiledLUppSolverStatic (solver_static.hpp): tiled LU with logical partial pivoting, in-tile threshold pivoting, out-of-tile recovery, reciprocal-diagonal factored format, right- and left-looking schedules. The difference is that the system dimension n is a runtime function parameter instead of a template parameter. Only the tile size (Config.tile_size) stays compile-time: register tiles keep a fixed tile_size x tile_size footprint, while all loop bounds over tiles and inside partial tiles are runtime values.

Deliberate differences with the compile-time solver:

  • No unroll pragma anywhere: with runtime bounds nothing can be register-resident by full unrolling, so the unroll_loops knob of TiledLUppConfig is ignored.
  • No internal_rhs / internal_piv / internal_matrix booleans: without unrolling, the internal residency mode degenerates into "external with stride 1", so every array is plain pointer + stride. The predicated register gathers/swaps of the static TiledLUpp solver become direct indexed accesses or in-place cycle walks (same values, simpler code).
  • substitute_inplace dispatches at runtime (warp-uniform: n is the same for every lane): a 64-bit visited bitmask up to n = 64, a cycle-leader scan beyond: zero extra storage and no ceiling on n.

For equal shapes (same n, tile_size, schedule, TiledLUppConfig thresholds), results are bitwise identical to the compile-time solver: the arithmetic sequence is the same, only addressing and loop mechanics differ. A compiler that contracts multiplications and additions into fused multiply-adds differently in the two (GCC with -march=native does) changes the last bits. -ffp-contract=off (–fmad=false for nvcc) keeps them identical.

Every entry point passes its dimensions through detail::runtime_dimension first: nvcc miscompiles this solver for Blackwell GPUs (sm_100 and later) when a dimension known at compile time propagates into its loops (issue #16), and the solver is meant to run on runtime dimensions anyway. Nothing changes elsewhere.

The compile-time solver is the performance path; this variant is the flexibility path (dimensions unknown at compile time, fast builds).

The matrix layout follows Config.layout, exactly as in the compile-time solver. The solver factors S, the stored matrix read row-major: S = A under the row-major layout, S = A^T under the column-major one. The column-major solve runs through the transposed factors: U^T z = b, L^T w = z, then x = P^T w (see solver_static.hpp).

Preconditions: n >= 1. tile_size may exceed n (the grid is then a single partial tile). The flat element index (for the matrix, n*n) must stay below 2^31; element offsets, index times stride, are computed in 64-bit arithmetic.

Macro Definition Documentation

◆ TDLS_LUPP_DYN_A

#define TDLS_LUPP_DYN_A ( r,
c )
Value:
A[TDLS_STRIDED((r) * n + (c), A_stride)]
#define TDLS_STRIDED(i, s)
Offset of entry i of a strided object, i times stride s, in 64-bit arithmetic (std::size_t); i and s ...
Definition macros.hpp:206

Strided element (r, c) of S, the stored matrix read row-major (A or A^T, see the file documentation).

◆ TDLS_LUPP_DYN_B

#define TDLS_LUPP_DYN_B ( i)
Value:
b[TDLS_STRIDED(i, rhs_stride)]

Strided entry i of the right-hand side.

◆ TDLS_LUPP_DYN_BW

#define TDLS_LUPP_DYN_BW ( w,
i )
Value:
b[TDLS_STRIDED(i, rhs_stride) + TDLS_STRIDED_WIDE(w, xcol_stride)]
#define TDLS_STRIDED_WIDE(i, s)
Offset of entry i of a strided object, i times stride s, for a 64-bit stride s (std::size_t); i is a ...
Definition macros.hpp:227

Strided entry i of column w of a multi right-hand-side block of b, addressed exactly as TDLS_LUPP_DYN_XW (b and x share both strides).

◆ TDLS_LUPP_DYN_PIV

#define TDLS_LUPP_DYN_PIV ( i)
Value:
piv[TDLS_STRIDED(i, piv_stride)]

Strided pivot entry i.

◆ TDLS_LUPP_DYN_X

#define TDLS_LUPP_DYN_X ( i)
Value:
x[TDLS_STRIDED(i, rhs_stride)]

Strided entry i of the solution vector.

◆ TDLS_LUPP_DYN_XW

#define TDLS_LUPP_DYN_XW ( w,
i )
Value:
x[TDLS_STRIDED(i, rhs_stride) + TDLS_STRIDED_WIDE(w, xcol_stride)]

Strided entry i of column w of a multi right-hand-side block.

◆ TDLS_LUPP_DYN_Y

#define TDLS_LUPP_DYN_Y ( i)
Value:
y[TDLS_STRIDED(i, rhs_stride)]

Strided entry i of the fused right-hand side of solve_inplace.