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)
oneAPI, MetalCSR of device arraysKernelAbstractions kernelsplanned extensions

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.

Element types are Float32, Float64, ComplexF32 and ComplexF64; index types are Int32 and Int64.