Backends

The solver is written once in KernelAbstractions.jl. The matrix given to DirectSolver decides the backend: the CSR arrays are wrapped without a copy and every numeric phase runs where they live.

backendinputdense kernels for large frontsstatus
CPU (KernelAbstractions.CPU())SparseMatrixCSC, CSR of VectorsKernelAbstractions kernelstested
CUDA (using CUDA)CuSparseMatrixCSR, CuSparseMatrixCSC, CSR of CuArrayscuBLAS, cuSOLVERtested
AMDGPU (using AMDGPU)ROCSparseMatrixCSR, ROCSparseMatrixCSC, CSR of ROCArraysrocBLAS, rocSOLVERtested (MI300X)
Metal (using Metal)CSR of MtlArraysMetal.jl / KernelAbstractions kernelsFloat32, tested (M4 Max)
oneAPI (using oneAPI)oneSparseMatrixCSR, oneSparseMatrixCSC, CSR of oneArraysoneMKL BLAS, KernelAbstractions kernels for the panel factorizationstested (Intel Data Center GPU Max 1550)

to_backend moves a SparseMatrixCSC to a backend:

using KernelAbstractions
A_dev = to_backend(A, CUDABackend())     # or CPU(), ROCBackend(), …

The kernels follow portability rules that let them run on every backend: 1-D workgroups, @localmem reductions and no warp intrinsics, no atomics in assembly (an atomic-free variant exists for the one atomic kernel, selected by deterministic_mode = 1), and no allocation or host synchronization inside the numeric and solve phases. The symbolic analysis runs on the host. The fused pipeline of FusedSolver is the exception: its dependency counters are Atomix atomics on which workgroups spin, which needs resident workgroups, so it refuses the CPU backend.

Element types are Float32, Float64, ComplexF32 and ComplexF64; index types are Int32 and Int64. Metal currently supports Float32 factors; Apple GPUs do not expose Float64 arithmetic.

On Metal, the default SPD schedule uses narrower regime-C thresholds than the CUDA/ROCm schedule (32 columns and 128 rows), the KernelAbstractions panel GEMM/SYRK/TRSM, and fused level solves for every front. When vendor calls are allowed (not factorization_alg = "algo1"), regime-C Cholesky fronts at least 64 columns wide use offset-aware MPS decomposition objects built when the numeric storage is allocated; the MPS status is folded into info (MPS names no column, so a failure it alone detects is reported at the last column of the front). On an M4 Max, the 90,000-row lap2d_300 warmed refactorization fell from 142 ms to 62 ms while its 5.2 ms solve time was preserved. The narrower SPD thresholds apply only when every schedule option has its default value.

LDLT, LU and uniform batches run every front through the regime-C path (factorization_alg = "algo2", no regime-A subtrees), because the fused kernels bind 32 device buffers and Apple GPUs expose 31. An explicit factorization_alg = "algo1" or explicit subtree_budgets for them raises a NotSupportedError at analysis rather than being replaced.