Solver
SparseDirectSolver — Module
SparseDirectSolverPortable sparse direct solver (LLᵀ/LLᴴ, LDLᵀ/LDLᴴ, LDU) for GPUs on KernelAbstractions.jl, with the parameter names and phases of CUDSS.jl. See PLAN.md for the design.
SparseDirectSolver.AbstractDirectSolver — Type
AbstractDirectSolver{T, INT} <: LinearAlgebra.Factorization{T}Supertype of the solvers of SparseDirectSolver.jl (≅ AbstractCudssSolver).
SparseDirectSolver.DirectSolver — Type
DirectSolver{T, INT, M, B, SY, NU, WS, RF, MS} <: AbstractDirectSolver{T, INT}Sparse direct solver handle (≅ CudssSolver), PLAN §3.1–§3.2.
DirectSolver(A::CSR, structure::String, view::Char; index = A.index)
DirectSolver(rowptr, colval, nzval, structure::String, view::Char; index = 'O')
DirectSolver(A::SparseMatrixCSC, structure::String, view::Char; index = 'O')
DirectSolver(A::CuSparseMatrixCSR, structure, view; index = 'O') # CUDA extension
DirectSolver(A::CuSparseMatrixCSC, structure, view; index = 'O') # CUDA extensionstructure is "G", "S", "H", "SPD" or "HPD" and view is 'L', 'U' or 'F' (the triangle of the matrix that is read; 'F' reads the lower triangle of a symmetric or Hermitian structure, and for "G" the view is ignored and every stored entry is read, as in cuDSS), as in CUDSS.jl; index ('O'/'Z') is the base of the row pointers and column indices. The CSR arrays are wrapped without copies and live on a KernelAbstractions backend (the solver's backend), except for a SparseMatrixCSC, which is converted to host CSR arrays once. A CSC matrix (CuSparseMatrixCSC, or a CSR with transposed = true, e.g. from csr_of_transpose) is read as the CSR of its transpose with the view flipped ('L' ↔ 'U'); for complex Hermitian matrices that transpose is the conjugate, and the solve phases conjugate the right-hand side and the solution (as for solve_mode, see solve_conjugated).
Implemented at this point: structures "SPD" (real T), "HPD", "S" (LDLᵀ; complex symmetric for complex T), "H" (LDLᴴ) and "G" (LU on the symmetric pattern of A + Aᵀ with row pivoting inside the fully-summed block of each front, P_r P A Pᵀ = L D U; any view, ignored), single matrices and uniform batches (see below), the phases "reordering", "symbolic_factorization", "analysis", "factorization", "refactorization", "solve", "solve_fwd_perm", "solve_fwd", "solve_diag", "solve_bwd", "solve_bwd_perm" and "solve_refinement" (execute!), and the Schur complement mode with "solve_fwd_schur" and "solve_bwd_schur" (below).
Uniform batch (PLAN §1.6, §3.5, ≅ CUDSS.jl's uniform batch): nbatch matrices with the pattern of rowptr/colval and values nzval, either a vector of nbatch · nnz entries (member after member) or an nnz × nbatch matrix; nbatch is deduced from the values (length(nzval) ÷ length(colval)), and "ubatch_size" must be 0 (deduced) or equal to it. One analysis serves every member; each member has its own factor, "info", "inertia", "npivots" and "pivot_stats" (vectors over the members). Right-hand sides and solutions hold nrhs columns per member, member after member: a strided vector of n · nrhs · nbatch entries, an n × (nrhs · nbatch) matrix, an n × nrhs × nbatch array or a MatrixDescriptor with nbatch. "ubatch_index" (0-based member, -1 = all) and "ubatch_mask" (one 0/1 flag per member) restrict the factorization and solve phases to a subset of the members: the other members' factors and solutions are left untouched. "pivot_sign" and the other options apply to every member; the 2×2 pivot pairs of "S"/"H" ("pivot_pairs") come from the first member's values.
Fields: A (the current CSR, re-pointed by update!), structure, view (as given), options (Options, set through setparam!), backend, nbatch, fresh_factorization (true until the first "factorization" after an analysis; the LinearAlgebra layer then switches cholesky! to "refactorization"), info (the "info" data parameter), the analysis (ordering, host host_symbolic, device symbolic), the numeric storage numeric, the solve workspace, the refinement storage refinement (allocated by the first solve that refines) and ir_steps (the "ir_n_steps" data parameter: refinement steps of the last solve, -1 before one) and schur (the SchurState of an analysis with schur_mode = 1, else nothing), host_matching (the host Matching of matching_alg ≠ "default", else nothing), analysis_colval (the column indices the analysis runs on: those of (Dr A Dc)[:, q] for "G" with matching, else host_colval) and matching (the device MatchingState, or nothing).
Matching and scaling (PLAN §1.3, M9, "matching_alg" = "algo1"–"algo6" before the analysis; compute_matching, from the first batch member's values): "G" factors M = (Dr A Dc)[:, q], whose diagonal holds the matched entries (job 5: |mᵢᵢ| = 1 ≥ |mᵢⱼ|), and the symmetric structures factor D A D (same inertia as A; for "S"/"H" with "algo5"/"algo6" the 2×2 pivot pairs come from the cycles of the matching, matching_pairs; jobs 1–4 have no scaling and keep the pairs of "pivot_pairs" without matching). The solve phases apply the permutation and the scalings ("solve_fwd_perm": Dr, "solve_bwd_perm": Dc Q, as in cuDSS) and refinement measures the residual of A itself; "diag" and the pivot statistics are those of the scaled matrix. Not with the Schur complement mode.
Schur complement mode (PLAN §3.6, ≅ CUDSS.jl's Schur complement): with "schur_mode" = 1 and "user_schur_indices" (n flags 0/1) set before the analysis, the flagged rows and columns are ordered last and the factorization stops before them: getparam(solver, "schur_shape") and getparam(solver, "schur_matrix") export S = A₂₂ − A₂₁ A₁₁⁻¹ A₁₂ (2 = the flagged block), and the solve phases are "solve_fwd_schur", "solve_diag" and "solve_bwd_schur" (see execute!). Single matrices only.
SparseDirectSolver.execute! — Function
execute!(phase::String, solver::DirectSolver, X, B; asynchronous = true) -> nothingExecute phase on solver (≅ cudss(phase, solver, x, b)), PLAN §1.2:
"reordering": fill-reducing ordering on the host (reordering_alg,user_perm, …);"symbolic_factorization": supernodes, schedule, layout and device maps; allocates the numeric storage and the solve workspace (needs"reordering");"analysis": both;"factorization": numeric factorization with the current values of the matrix (needs the analysis); sets"info"(0or, for"SPD"/"HPD", the original column of the first non-positive pivot; LDLᵀ/LDLᴴ and LU perturb tiny pivots instead and report0, see"npivots", except for an exactly zero pivot withpivot_epsilon = 0, whose original column they report) and clearsfresh_factorization;"refactorization": the same with the analysis and storage reused,"info"reset first (needs a previous"factorization");"solve":X = op(A)⁻¹ B(solve_mode0:A, 1:Aᵀ, 2:Aᴴ), followed byir_n_stepssteps of iterative refinement; the sub-phases"solve_fwd_perm"(permuteBinto the workspace),"solve_fwd"(forward sweep),"solve_diag"(D⁻¹of LDLᵀ/LDLᴴ, the identity for Cholesky),"solve_bwd"(backward sweep),"solve_bwd_perm"(inverse permutation intoX) and"solve_refinement"(refineXin place,refine!) do the same in six calls with the sameX,B(bitwise equal to"solve").
X and B are only read by the solve phases (pass anything, e.g. nothing, to the others): vectors, n × nrhs matrices, strided vectors or MatrixDescriptors (row-major when transposed) on the solver's backend; X === B is allowed in every phase but "solve_refinement" (it needs the original B; "solve" keeps a copy of B when they alias). A failed factorization does not throw (as in cuDSS): check getparam(solver, "info"); solving with it gives garbage.
Refinement (PLAN §2.5): each step computes the residual R = B - op(A) X with the solver's current matrix values (KA SpMV over the full pattern), and, when ir_tol > 0, stops once ‖Rₖ‖₂ ≤ ir_tol ‖Bₖ‖₂ for every right-hand side k (this costs one host synchronization per step; ir_tol = 0, the default, never stops early and never synchronizes), then adds the correction op(A)⁻¹ R. The steps performed are the data parameter "ir_n_steps" (getparam). With ir_mode = "fgmres" (needs using Krylov, else NotSupportedError) the refinement is FGMRES on the correction system, right-preconditioned by the factorization (fgmres_refine!): at most ir_n_steps iterations (one SpMV and one solve each, as a plain step), stopping once every relative residual is below ir_tol (ir_tol = 0: all ir_n_steps iterations); "ir_n_steps" then reports the FGMRES iterations.
The flag "user_host_interrupt" (a Threads.Atomic{Bool}, setparam!) is polled at the start of the analysis phases, between the launch groups of the factorization and between refinement steps: when set, the phase raises InterruptedError. An interrupted factorization leaves the solver analyzed (the next phase must be "factorization"); an interrupted refinement leaves the last completed iterate in X and reports the steps completed in "ir_n_steps".
Schur complement mode (schur_mode = 1 at the analysis, PLAN §3.6, as in the CUDSS.jl docs): "factorization"/"refactorization" factor A₁₁ (the rows and columns outside "user_schur_indices") and assemble the Schur complement S (getparam "schur_matrix"). The solve phases then read B and write X (X === B allowed), with intermediate vectors in factor order, where the last ns entries are the Schur block in increasing original order:
"solve_fwd_schur"(permutation and forward sweep): the lastnsentries ofXare the condensed right-hand sidebₛ = b₂ − A₂₁ A₁₁⁻¹ b₁;"solve_diag":D⁻¹of LDLᵀ/LDLᴴ on the factored part (the identity on the Schur block, and for Cholesky and LU, whose diagonal is applied by"solve_bwd_schur"as in cuDSS);"solve_bwd_schur"(backward sweep and inverse permutation): with the solutionx₂ofS x₂ = bₛin the lastnsentries ofB,Xis the solution ofA x = b.
solve_mode 1/2 solve with Aᵀ/Aᴴ (condensed system Sᵀ/Sᴴ); the other solve phases raise NotSupportedError in Schur mode, and the Schur phases without it FactorizationError. Unknown phase strings raise ArgumentError. Executing a phase before the phases it depends on raises FactorizationError. With asynchronous = false the backend is synchronized before returning (KernelAbstractions.synchronize). Phase summaries are logged (see SparseDirectSolver.set_log_level!).
SparseDirectSolver.analyze! — Function
analyze!(solver, X = nothing, B = nothing; asynchronous = true) -> solverexecute!("analysis", solver, X, B; asynchronous).
SparseDirectSolver.factorize! — Function
factorize!(numeric, symbolic, nzval; impl = :auto, opts = Options()) -> info::IntStructures "S"/"H": factorize_ldlt! with the pivoting options opts (impl selects its regime-C GEMMs); structure "G": factorize_lu! (impl is not used). Both return info (nonzero only for a zero pivot with pivot_epsilon = 0). Structures "SPD"/"HPD": multifrontal Cholesky P A Pᵀ = L Lᴴ on the device: nzval are the stored values of A (same pattern, view and index base as the analysis) on the backend of numeric, and symbolic has its maps on that backend (adapt(backend, symbolic, INT)). For every launch group of the schedule, in order: a regime-A group (budget class) is one factorize_subtrees! launch (one workgroup per subtree: its fronts assembled, factored and extend-added in local memory, panels and the root's contribution block written to global memory); a regime-B group (width class W ≤ 64) is one factorize_fronts_b! launch (fused assembly, F11 Cholesky in local memory, trsm, syrk/herk into the front's contribution block); a regime-C group is one launch each of zero_fronts!, scatter_A! and extend_add! over its fronts, then per front potrf_info!, trsm! and herk!/syrk! (into the workspace, then pack_add! into its packed contribution block) through the dense interface (impl is passed on: :auto, :generic, :vendor, :ka, resolved once per call; :auto means :ka when the analysis used factorization_alg = "algo1", no vendor calls). Then cholesky_stats! and one read of the reduced status.
Returns info = 0 on success, else the original column of the smallest non-positive pivot of the factor (as ref_factorize!); fronts above a failed one hold garbage. Uniform batch (numeric.nbatch > 1, PLAN §3.5): the active members of numeric (set_members!) are factorized by the same launches with the batch index as one more grid dimension (nzval holds the values of every member, member after member), a regime-C front by strided-batched potrf/trsm/gemm over each run of consecutive members (vendor potrf/trsm on the member pointers built at allocation; per member with impl = :generic); the return value is the first nonzero member info (see member_info! for all of them). opts.user_host_interrupt is polled before every launch group (a host read): when set, InterruptedError is raised and the factor is incomplete. Structure "SPD" (real) or "HPD". Nothing is allocated on the device; the panels are bitwise reproducible for a fixed impl and backend (regimes A and B are deterministic by construction).
factorize!(solver, X = nothing, B = nothing; asynchronous = true) -> solverexecute!("factorization", solver, X, B; asynchronous).
SparseDirectSolver.refactorize! — Function
refactorize!(solver, X = nothing, B = nothing; asynchronous = true) -> solverexecute!("refactorization", solver, X, B; asynchronous).
SparseDirectSolver.solve! — Function
solve!(solver, X, B; asynchronous = true) -> Xexecute!("solve", solver, X, B; asynchronous).
SparseDirectSolver.update! — Function
update!(desc::MatrixDescriptor, x::AbstractArray) -> descPoint desc at x without copying (≅ cudss_update(matrix, x)). x must hold nrows * ncols * nbatch entries of type T: either as a strided vector, or with the descriptor's shape ((nrows, ncols), (ncols, nrows) when transposed, plus a trailing nbatch dimension for 3-D arrays; a uniform batch also accepts the nrows × (ncols nbatch) matrix with the same memory, e.g. n × nbatch for MatrixDescriptor(T, n; nbatch), as CUDSS.jl). Anything else throws InvalidValueError.
update!(solver::DirectSolver, A)
update!(solver::DirectSolver, rowptr, colval, nzval)Point solver at new matrix data without copying (≅ cudss_update): a CSR of the same type, a SparseMatrixCSC (converted on the host), a CuSparseMatrixCSR/CuSparseMatrixCSC (CUDA extension), or raw CSR arrays (with the index base and orientation of the solver's matrix). The sparsity pattern must be the one of the analysis (only the sizes are checked, as in cuDSS); new values are used by the next "factorization" or "refactorization". Raises InvalidValueError for a different size, number of stored entries, index base, orientation or array type.
update!(solver::DirectSolver, A::CuSparseMatrixCSR)
update!(solver::DirectSolver, A::CuSparseMatrixCSC)Point solver at the arrays of A (≅ cudss_update(solver, A)), see update!.
update!(solver::DirectSolver, A::ROCSparseMatrixCSR)
update!(solver::DirectSolver, A::ROCSparseMatrixCSC)Point solver at the arrays of A, see update!.
Parameters
SparseDirectSolver.setparam! — Method
setparam!(solver::DirectSolver, name::String, value)Set a configuration or user-input data parameter of solver (≅ cudss_set): everything setparam!(::Options, …) accepts, stored in solver.options and used by the next phase that reads it, plus the data parameter "info" (an integer, or for a uniform batch an integer for every member or a vector of nbatch integers; CUDSS.jl resets it before a refactorization). Uniform batch: "ubatch_size" (0 or the batch size), "ubatch_index" (0-based member, -1 = all) and "ubatch_mask" (nbatch flags 0/1, or nothing) select the members of the next phases; the index and the mask are checked against the batch size when a phase runs. "pivot_sign" (PLAN §1.7: a vector of n entries in (-1, 0, 1), host or device, or nothing) is checked against the size of the matrix; the next "factorization"/"refactorization" copies it to the device; it steers the perturbation of LDLᵀ/LDLᴴ only and is ignored for "G" (LU perturbs with the sign of the pivot) and the Cholesky structures. Setting "ir_n_steps" (the number of refinement steps requested) makes getparam report that value again until the next solve. "schur_matrix" (Schur complement mode, after "reordering"/"analysis") registers the destination that getparam(solver, "schur_matrix") fills (≅ cudss_set(solver, "schur_matrix", S) then cudss_get): a dense ns × ns matrix on the solver's backend (or a MatrixDescriptor holding one), a CSR (or a backend CSR matrix, e.g. CuSparseMatrixCSR) with ns + 1 row pointers and room for exactly the entries of the exported pattern, or a tuple (csr, view) with view 'L', 'U' or 'F' (the default) to export one triangle; nothing unregisters it. Computed data parameters ("lu_nnz", "diag", "perm_row", …) cannot be set (ArgumentError): read them with getparam or getparam!, which replaces cuDSS's set-buffer-then-get protocol.
SparseDirectSolver.getparam — Method
getparam(solver::DirectSolver, name::String)Value of a parameter of solver (≅ cudss_get). Configuration and user-input parameters come from solver.options (getparam(::Options, …)). The data parameters computed by the solver:
| name | value | available after |
|---|---|---|
"info" | Int: 0, or the original column (1-based) of the first failed pivot (Cholesky: non-positive; LDLᵀ/LDLᴴ and LU: exactly zero with pivot_epsilon = 0, the other tiny pivots are perturbed) | always |
"ubatch_mask" | the "ubatch_mask" set (or nothing) | always |
"ir_n_steps" | Int: refinement steps performed by the last "solve"/"solve_refinement" (≤ the configured ir_n_steps, fewer when ir_tol stopped early); the configured value before the first solve and after setparam!(solver, "ir_n_steps", k) | always |
"lu_nnz" | Int64: nonzeros of L (diagonal included, amalgamation zeros excluded) | analysis |
"flops" | Float64: factorization flops of the stored panels | analysis |
"nsuperpanels" | Int: supernodes after amalgamation | analysis |
"memory_estimates" | Vector{Int64} (16 entries, see memory_estimates) | analysis |
"perm_reorder_row", "perm_reorder_col" | Vector{Int}: the fill-reducing permutation, 1-based (perm[k] = original index of the k-th pivot) | reordering |
"perm_row", "perm_col" | Vector{Int}: the final permutation of the factor (= the reordering for Cholesky and LDLᵀ/LDLᴴ); LU ("G") after a factorization: perm_row[k] is the original row of factor row k (the reordering composed with the local row interchanges of batch member 1), perm_col the reordering (with matching: composed with the matching, perm_matching[reordering]), so A[perm_row, perm_col] = L D U (with matching Dr[perm_row] A[perm_row, perm_col] Dc[perm_col] = L D U, the scalings Dr, Dc of "scale_row"/"scale_col" as diagonal matrices in the original numbering). For a CSC input (CuSparseMatrixCSC, csr_of_transpose) A is the stored CSR matrix, the transpose of the matrix given | analysis |
"perm_matching" | Vector{Int}: the matching permutation (Matching): row i is matched to column perm_matching[i] ("G": A[:, perm_matching] has the matched entries on its diagonal; symmetric structures: only its cycles are used, for the 2×2 pivot pairs) | reordering (matching_alg ≠ "default") |
"scale_row", "scale_col" | Vector{real(T)}: the row and column scaling factors Dr, Dc of the factored matrix, in the original numbering (ones for "algo1"–"algo4"; equal for the symmetric structures) | reordering (matching_alg ≠ "default") |
"diag" | vector of T on the solver's backend: the diagonal of L (Cholesky), of D (LDLᵀ/LDLᴴ; for a 2×2 block its two diagonal entries) or of D in L D U (LU, = the diagonal of U in L U) in factor order; Schur complement mode: 1 on the (unfactored) Schur block | factorization |
"npivots" | INT: perturbed pivots (LDLᵀ/LDLᴴ, LU; 0 for Cholesky); valid when "info" is 0 (after a failed front the counts of the fronts above it are stale) | factorization |
"inertia" | Tuple{INT, INT}: (npos, nneg) of D (after perturbation, so the inertia of A + E; read it with "npivots"); (0, 0) for complex symmetric "S" and for "G"; Cholesky: (number of positive pivots, 0); valid when "info" is 0, as "npivots" | factorization |
"pivot_stats" | NamedTuple (npos, nneg, nzero, nperturbed, n2x2) of Int64 (PLAN §1.7); in Schur complement mode "npivots", "inertia" and "pivot_stats" count the factored block A₁₁ only; valid when "info" is 0, as "npivots" | factorization |
"schur_shape" | (nrows, ncols, nnz) of Int64: the size ns of the Schur complement and the nonzeros of its symbolic pattern (schur_pattern); for the symmetric structures one triangle with the diagonal (as the sparse export of one triangle) | analysis (schur_mode = 1) |
"schur_matrix" | the Schur complement S = A₂₂ − A₂₁ A₁₁⁻¹ A₁₂ of the rows and columns of "user_schur_indices" (in their increasing order), written into the destination registered with setparam! and returned; without one, a new dense ns × ns matrix on the solver's backend. Symmetric structures: a dense destination gets the full matrix, a sparse one the triangle of its view | factorization (schur_mode = 1) |
Uniform batch (nbatch > 1): "info", "npivots", "inertia" and "pivot_stats" are vectors with one entry per batch member, "diag" is the n · nbatch vector of the members' diagonals one after the other; the analysis outputs are shared by the members. A factorization restricted by "ubatch_index"/"ubatch_mask" updates the active members only: the others keep the "info", "npivots", "inertia" and "pivot_stats" of their last factorization. "perm_row" of an LU batch is batch member 1's row order, by design: cuDSS returns the vector outputs of a uniform batch ("diag") for member 1 only and does not implement "perm_row" at all (cuDSS 0.8). "diag" is the deliberate exception and returns every member.
The pivot statistics are reduced on the device (reduce_stats!) and copied to the host when read (one synchronization). The reordering permutation after "reordering" alone is the ordering algorithm's; "symbolic_factorization" composes it with the supernodal renumbering, and from then on both permutations are the one the factor uses. Data parameters of later tasks ("nd_partition_tree", "hybrid_device_memory_min") raise NotSupportedError; reading one before the phase that computes it raises FactorizationError, and the matching outputs without matching InvalidValueError.
SparseDirectSolver.getparam! — Function
getparam!(buffer, solver::DirectSolver, name::String) -> bufferWrite the vector-valued data parameter name ("perm_reorder_row", "perm_reorder_col", "perm_row", "perm_col", "diag", "memory_estimates", "user_perm") of getparam into buffer, a host or device vector of the right length (converted to its element type), without the C-style set-buffer-then-get protocol of CUDSS.jl. "schur_matrix": buffer is any destination setparam! accepts for it (dense matrix, CSR, (csr, view)), filled without registering it.
SparseDirectSolver.Options — Type
Options(; kwargs...)Every configuration parameter of PLAN §1.3 and §1.7 plus the user-provided data parameters (user_perm, user_schur_indices, user_nd_partition_tree, user_host_interrupt, ubatch_mask, pivot_sign), in typed fields with the defaults below. Keyword arguments are applied through setparam!, so Options(ir_n_steps = 2) validates like setparam!(opts, "ir_n_steps", 2).
| Field | Default | Meaning of the default |
|---|---|---|
reordering_alg | REORDERING_DEFAULT | automatic AMD/ND choice: flops + 1e8 × supernodal schedule depth, every backend |
factorization_alg | FACTORIZATION_DEFAULT | automatic regime choice |
solve_alg | SOLVE_DEFAULT | level-batched sweeps |
matching_alg | MATCHING_NONE | no matching |
solve_mode | 0 | solve with A (1: Aᵀ, 2: Aᴴ) |
ir_n_steps | 0 | no refinement (cuDSS parity) |
ir_tol | 0.0 | no early exit |
pivot_type | PIVOT_AUTO | Bunch–Kaufman for S/H, none for SPD/HPD |
pivot_threshold | 0.01 | pivot acceptance threshold; with pivot_pairs = "default" also the partner threshold of the 2×2 pairs chosen at analysis (a value set after "analysis" changes the in-front test, not the pairs already chosen) |
pivot_epsilon | nothing | default_pivot_epsilon(T); LDLᵀ/LDLᴴ/LU static pivot perturbation, and on the Cholesky path (issue #127) the threshold: a pivot in [0, pivot_epsilon] is raised to it (negative or NaN still fails the front); 0 disables |
pivot_epsilon_alg | PIVOT_EPSILON_DEFAULT | |
max_lu_nnz | -1 | no limit (any negative value) |
hybrid_memory_mode | 0 | device memory only |
hybrid_device_memory_limit | 0 | automatic |
use_cuda_register_memory | 1 | pinned host memory allowed |
host_nthreads | 0 | Threads.nthreads() |
hybrid_execute_mode | 0 | device execution only |
nd_nlevels | 10 | minimum nested-dissection levels |
ubatch_size | 0 | deduced from the matrix values (1 for a single matrix) |
ubatch_index | -1 | all batch members |
use_superpanels | 1 | supernode amalgamation on |
schur_mode | 0 | off |
deterministic_mode | 0 | atomic forward solve allowed |
nd_ubfactor | -1 | ordering library default |
nd_nseps | -1 | ordering library default (1 separator per split) |
nd_seed | -1 | ordering library default |
ir_mode | IR_PLAIN | plain iterative refinement |
factor_precision | nothing | factors in the input precision |
amalgamation | (max_width = 32, zero_fraction = 0.25, min_width = 8) | |
schedule | SCHEDULE_AUTO | |
pivot_pairs | PIVOT_PAIRS_DEFAULT | 2×2 pivot pairs in the analysis of "S"/"H" (structurally zero pivots; "all": every candidate; with matching "algo5"/"algo6": from the cycles of the matching); decided from the values present at analysis: an all-zero nzval gives no pairs, an undefined one arbitrary pairs |
pivot_pair_tolerance | 1e-6 (PIVOT_PAIR_TOLERANCE) | relative diagonal size below which a row is a 2×2 candidate |
regime_c_width | 64 | fronts wider than this go to regime C (vendor dense calls) |
regime_c_rows | 512 | fronts with more rows than this go to regime C |
subtree_budgets | [16384, 32768, 49152] | regime A local-memory budgets in bytes (kernel classes of 8 to 64 KiB); the defaults are clamped to the backend's local memory per workgroup, an explicit budget above it is an InvalidValueError; empty disables regime A |
subtree_parallelism | 4096 | a regime-A subtree does at most 1/subtree_parallelism of the factorization flops (0: no limit) |
subtree_max_fronts | 0 | a regime-A subtree has at most this many fronts (0: no limit); the serial walk of a subtree is its workgroup's critical path |
memory_budget | -1 | update-stack bytes per level chunk (negative: no limit, no chunking) |
user_perm, user_schur_indices, user_nd_partition_tree, ubatch_mask, pivot_sign | nothing | not provided |
user_host_interrupt | nothing | not provided |
Vectors are stored as host copies; user_host_interrupt is stored by reference because it is polled while a phase runs.
The last five rows are analysis tuning knobs of the schedule (PLAN §2.3 step 5, TASKS T07). They are not cuDSS parameter strings, so setparam! does not know them; set them with Options(; regime_c_width = 128) (validated) or by assigning the field.
SparseDirectSolver.setparam! — Method
setparam!(opts::Options, name::String, value)Set the configuration or user-input data parameter name (a CUDSS.jl name from CONFIG_PARAMETERS/DATA_PARAMETERS or a name from EXTRA_PARAMETERS) after validating value.
Accepted values:
- algorithms (
"reordering_alg","factorization_alg","solve_alg","matching_alg","pivot_epsilon_alg"):"default","algoN"or the integerN; "pivot_type":'A','N','D','L','B'('C'/'R'raiseNotSupportedError); LDLᵀ/LDLᴴ:'A','B','L'Bunch–Kaufman,'D'1×1 only,'N'none; LU ("G",lu_pivoting):'A','B','L'in-block threshold row pivoting,'N','D'diagonal pivots;- integer and flag parameters: an
Integerin the documented range; "ir_tol","pivot_threshold","pivot_epsilon": a finite real≥ 0(nothingresets"pivot_epsilon"todefault_pivot_epsilon);"ir_mode":"ir"or"fgmres";"schedule":"auto","subtree+level","syncfree";"pivot_pairs"(beyond cuDSS):"default"(for"S"/"H", a row with a zero or negligible diagonal whose pivot would be structurally zero is ordered together with a 2×2 pivot partner, seezero_pivot_pairs!),"all"(every such row, seepivot_pairs; about 2×nnz(L)on KKT systems) or"none"; ignored for the other structures, withuser_permand with the natural ordering; withmatching_alg = "algo5"/"algo6"the pairs come from the cycles of the scaled symmetric matching instead (matching_pairs). Pairs are decided from the values present at"analysis"(the first batch member): an all-zeronzvalgives no pairs and an undefined one arbitrary pairs, so run"analysis"after the first assembly of the matrix (MadNLP: after the first KKT assembly);"all"reads the values as well (its candidates and partners come from them);"pivot_threshold"also shapes the ordering withpivot_pairs = "default": partners are accepted at analysis down topivot_threshold · maxₖ |aᵢₖ|(zero_pivot_pairs!); a value set after"analysis"changes the in-front pivot test but not the pairs already chosen;"pivot_pair_tolerance"(beyond cuDSS): a finite real≥ 0, the relative diagonal sizeτbelow which a row is a 2×2 candidate (|aᵢᵢ| ≤ τ maxⱼ≠ᵢ |aᵢⱼ|, on the scaled matrix with matching; defaultPIVOT_PAIR_TOLERANCE);"factor_precision":Float32,Float64ornothing;"amalgamation": aNamedTuplewith any ofmax_width,zero_fraction,min_width;"user_perm","user_nd_partition_tree": an integer vector (host or device), ornothing;"user_schur_indices","ubatch_mask": a vector of 0/1 flags, ornothing;"pivot_sign": a vector with entries in(-1, 0, 1), ornothing;"user_host_interrupt": aThreads.Atomic{Bool}, ornothing.
Unknown names raise ArgumentError; values of the wrong type or range raise InvalidValueError; "device_count" ≠ 1, "device_indices", "comm_device", "comm_host" and global pivoting raise NotSupportedError. Parameters computed by a solver ("lu_nnz", "inertia", …) cannot be set (ArgumentError). The hybrid-mode parameters are stored but have no effect yet; a non-default value warns once. reordering_alg = "algo1"/"algo2" (COLAMD-based orderings with global pivoting) is accepted and warns once that the symmetric-pattern path is used.
SparseDirectSolver.getparam — Method
getparam(opts::Options, name::String)Value of the configuration or user-input data parameter name, in the form setparam! accepts: algorithm and mode strings ("algo3", "fgmres"), Char for "pivot_type", Int/Float64 for numbers, a copy of stored vectors, nothing for unset optional values ("pivot_epsilon", "factor_precision", user vectors). "device_count" is always 1.
Unknown names raise ArgumentError, as do data parameters computed by a solver (query those on the solver). "device_indices", "comm_device" and "comm_host" raise NotSupportedError.
SparseDirectSolver.CONFIG_PARAMETERS — Constant
CONFIG_PARAMETERSThe configuration parameter names of CUDSS.jl (CUDSS_CONFIG_PARAMETERS), verbatim.
SparseDirectSolver.DATA_PARAMETERS — Constant
DATA_PARAMETERSThe data parameter names of CUDSS.jl (CUDSS_DATA_PARAMETERS), verbatim.
SparseDirectSolver.CUDSS08_DATA_PARAMETERS — Constant
CUDSS08_DATA_PARAMETERScuDSS 0.8 data parameters that CUDSS.jl does not list in DATA_PARAMETERS (PLAN §1.4): "ir_n_steps" (refinement steps performed; the configuration parameter of the same name is the number requested), "ubatch_mask" and "flops".
SparseDirectSolver.EXTRA_PARAMETERS — Constant
EXTRA_PARAMETERSParameters beyond cuDSS (PLAN §1.7): the data parameters "pivot_sign" (input) and "pivot_stats" (output), and the configuration parameters "ir_mode", "factor_precision", "amalgamation", "schedule", "pivot_pairs" and "pivot_pair_tolerance".
SparseDirectSolver.default_pivot_epsilon — Function
default_pivot_epsilon(T) -> Float64Default pivot_epsilon for element type T, as in cuDSS: 1e-5 for Float32/ComplexF32, 1e-13 for Float64/ComplexF64.
SparseDirectSolver.set_log_level! — Function
SparseDirectSolver.set_log_level!(level) -> IntSet the verbosity of the solver's log messages: 0/"none" (default; the messages are @debug records), 1/"info" (phase summaries: analysis, factorization, refinement steps performed, as @info), 2/"debug" (also the relative residual of every refinement step). The initial value comes from the environment variable SDS_LOG_LEVEL. Returns the previous level.
Errors
SparseDirectSolver.SparseDirectSolverError — Type
SparseDirectSolverError <: ExceptionAbstract supertype of the exceptions raised by SparseDirectSolver.jl.
SparseDirectSolver.NotSupportedError — Type
NotSupportedError(msg)A parameter, value or feature that SparseDirectSolver.jl does not provide (for example "device_count" > 1, or global pivoting pivot_type = 'C').
SparseDirectSolver.InvalidValueError — Type
InvalidValueError(msg)A value of the wrong type or outside the admissible range for a parameter, structure, view, index base or phase.
SparseDirectSolver.FactorizationError — Type
FactorizationError(info, msg = "")A factorization that could not be completed, or a phase called out of order. info follows the "info" data parameter: k > 0 is the first failed pivot (1-based, original numbering); for uniform batches it is a vector with one entry per member.
SparseDirectSolver.InterruptedError — Type
InterruptedError(msg = "interrupted through "user_host_interrupt"")Raised when the "user_host_interrupt" flag is set while a phase runs. The solver stays usable: the phase can be executed again once the flag is cleared.