SupernodalMatrix API

For supernodal Cholesky factorizations, SupernodalMatrix stores the output of selinv. This subtype of AbstractMatrix allows for a more efficient memory access tailored to supernodal representations.

While you can just use it like a regular AbstractMatrix (i.e. you can get its size and index into it as you would expect), you might be interested in more specialized methods.

Fields and construction

SelectedInversion.SupernodalMatrixType
SupernodalMatrix{Tr, Sym, Dep}

Represents a sparse block lower triangular matrix with a supernodal layout. A supernode is a set of contiguous columns with identical sparsity pattern below the triangular block at the top. For each supernode, the corresponding nonzero entries are stored in a dense chunk. This enables us to use BLAS for operations on these chunks, so we combine the strengths of sparse and dense matrices.

Type parameters

  • Tr::Bool: Whether chunks are stored transposed (first axis = columns).
  • Sym::Bool: Whether to enforce symmetry when accessing entries.
  • Dep::Bool: Whether to apply an inverse permutation before accessing entries.

Fields

  • N::Int: Number of rows
  • M::Int: Number of columns
  • n_super::Int: Number of supernodes
  • super_to_col::Vector{Int}: Start/end column of each supernode. Length n_super + 1.
  • col_to_super::Vector{Int}: Maps each column to its supernode index. Length M.
  • super_to_vals::Vector{Int}: Start/end indices of each supernode into vals. Length n_super + 1.
  • super_to_rows::Vector{Int}: Start/end indices of each supernode into rows. Length n_super + 1.
  • vals::Vector{Float64}: Nonzero values.
  • rows::Vector{Int}: Row indices. CAREFUL: These are zero-indexed!
  • max_super_rows::Int: Maximum number of rows below the triangular block in a supernode chunk.
  • invperm::Vector{Int}: Permutation to apply before accessing entries when Dep == true.
source
SelectedInversion.SupernodalMatrixMethod
SupernodalMatrix(
    F::SparseArrays.CHOLMOD.Factor;
    transpose_chunks = false,
    symmetric_access = false,
    depermuted_access = false,
)

Construct a SupernodalMatrix from a supernodal Cholesky factorization.

Keyword arguments are explained in the SupernodalMatrix docstring.

source

Methods

SelectedInversion.get_rowsFunction
get_rows(S::SupernodalMatrix, sup_idx::Int)

Get the row indices corresponding to supernode sup_idx. CAREFUL: These are zero-indexed!

source
SelectedInversion.get_row_col_idcsFunction
get_row_col_idcs(S::SupernodalMatrix, sup_idx::Int)

Get the row and column indices corresponding to supernode sup_idx. Both sets of indices are one-indexed.

source
SelectedInversion.get_SjFunction
get_Sj(S::SupernodalMatrix, sup_idx::Int)

Get the row indices below the triangular block of supernode sup_idx. CAREFUL: These are zero-indexed!

source
SelectedInversion.partition_SjFunction
partition_Sj(S::SupernodalMatrix, Sj)

Partition the output of get_Sj into contiguous subsets where each subset is fully contained in one supernode.

source
SelectedInversion.get_chunkFunction
get_chunk(S::SupernodalMatrix, sup_idx::Int)

Get the dense chunk corresponding to supernode sup_idx. Includes the triangular block at the top.

source
SelectedInversion.get_split_chunkFunction
get_split_chunk(S::SupernodalMatrix, sup_idx::Int)

Get the chunk corresponding to supernode sup_idx, split into the diagonal / lower triangular block at the top, and the remaining block below it.

source

Selected-inverse extraction

Read the selected inverse at a given sparse pattern B straight from the supernodal blocks, without materializing the full sparse(selinv(F).Z). For repeated extraction with a fixed pattern (e.g. across refactorizations of the same symbolic factor), precompute a plan with selinv_extract_setup and reuse it via the allocation-free selinv_extract!(dest, S, plan).

SelectedInversion.selinv_extractFunction
selinv_extract(S::SupernodalMatrix, B::SparseMatrixCSC)

Return a SparseMatrixCSC with exactly B's sparsity pattern whose values are S's selected-inverse values at those positions. Equivalent to sparse(S) masked to B's pattern, but computed without materializing sparse(S).

Positions of B that fall outside S's stored selected-inverse pattern (the Cholesky-factor fill) are retained with value 0.0, so the result's pattern is identical to B's. B is assumed to have sorted row indices (the standard SparseMatrixCSC invariant).

For repeated extraction with a fixed pattern across refactorizations, cache a plan with selinv_extract_setup and use the allocation-free selinv_extract!(dest, S, plan).

source
selinv_extract(Z::AbstractMatrix, B::SparseMatrixCSC)

Generic fallback for simplicial selected inverses; see the SupernodalMatrix method for semantics. Lets callers use one interface regardless of whether the factor produced a supernodal or simplicial selected inverse.

source
SelectedInversion.selinv_extract!Function
selinv_extract!(dest::SparseMatrixCSC, S::SupernodalMatrix, plan::Vector{Int})

Fill dest.nzval from S.vals using a plan from selinv_extract_setup. dest must carry the same pattern (and nonzero order) as the B used to build plan. This is O(nnz(dest)) and allocation-free, so it can be reused across refactorizations of the same symbolic factor.

source
selinv_extract!(dest::SparseMatrixCSC, S::SupernodalMatrix, B::SparseMatrixCSC)

Fill dest.nzval with S's values at B's pattern. dest must already carry B's pattern (same colptr/rowval). For repeated extraction with a fixed pattern, cache a plan via selinv_extract_setup and use the plan method instead.

source
selinv_extract!(dest::SparseMatrixCSC, Z::AbstractMatrix, B::SparseMatrixCSC)

Generic fallback used for simplicial selected inverses, where selinv(F).Z is a Symmetric{<:Any, <:SparseMatrixCSC} (or a plain SparseMatrixCSC when depermuted) rather than a SupernodalMatrix. Reads Z[i, j] at B's pattern via ordinary indexing. dest must carry B's pattern.

source
SelectedInversion.selinv_extract_setupFunction
selinv_extract_setup(S::SupernodalMatrix, B::SparseMatrixCSC)

Precompute a reuse plan::Vector{Int} for streaming S's values onto B's pattern.

plan has one entry per structural nonzero of B (in B's original-frame CSC order): plan[t] is the 1-based index into S.vals that supplies that entry, or 0 when the entry lies outside S's stored selected-inverse pattern (so it reads as 0.0). Any depermutation is baked into plan, so the in-place fill needs no permutation at call time.

The supernodal structure is invariant across refactorizations of the same symbolic factor (only S.vals changes), so a plan built once can be reused by selinv_extract!(dest, S, plan) for every later refactorization with zero allocation. dest must carry B's pattern (e.g. selinv_extract(S, B) or a copy of B) so that its nonzero order matches plan.

source