Open ChrisRackauckas opened 2 years ago
This isn't just 'an overload missing'; CUSPARSE doesn't support these operations. Only incomplete factorizations for use as a preconditioner. I'm not sure if/how that generalizes (thoughts, @kshyatt?).
oh interesting. If there's a CUDA ILU that would be great as well, and that's okay if it's non-generic. Are those operations wrapped?
Yeah, LU and Cholesky, both here: https://github.com/JuliaGPU/CUDA.jl/blob/master/lib/cusparse/preconditioners.jl
cusolverRF
is able to refactorize the matrix entirely on the GPU, but it requires to compute the initial symbolic factorization on the CPU, and a fixed sparsity pattern.
This is our observation with most of the factorizations implemented in CUSPARSE: they deport seamlessly the factorization to the host, inducing a lot of data transfer if the matrix is large. And that even for QR
: this can be observed with a profiler. To avoid this, NVIDIA provides more coarse grained control to the factorization routines in the header cusolverSp_LOWLEVEL_PREVIEW.h
(undocumented). See for example the code for the Cholesky factorization:
https://github.com/tpn/cuda-samples/blob/master/v8.0/7_CUDALibraries/cuSolverSp_LowlevelCholesky/cuSolverSp_LowlevelCholesky.cpp
cusolverRF is able to refactorize the matrix entirely on the GPU, but it requires to compute the initial symbolic factorization on the CPU, and a fixed sparsity pattern.
That would be fine for us. We can just specialize that in LinearSolve.jl. That would be relatively straightforward to do, if we have the right functionality to call cusolverRF
@maleadt do you have an example of how to use the SparseChar
?
Set it to 'O'
for one-based arrays (i.e. sparse arrays created in Julia).
@ChrisRackauckas we tried to wrap cusolverRF
in CUDA.jl in #828 , but the PR is a bit stalled now (it's on me).
We are currently using a custom wrapper for cusolverRF
, where we use our own functions for the triangular solves, using SpSV/SpSM
(the functions sv!/sm!
wrapped in CUSPARSE.jl just allocate too much memory for our use case, leading to unexpected crashes).
I almost got this all working in https://github.com/SciML/OrdinaryDiffEq.jl/issues/1566#issuecomment-1059890002, but the last step is the ldiv!
action which is missing on the CuSparseMatrixCSR
. It's hard to make an MWE because ilu02!
throws a zero pivot error on the random cases 😓, so that comment has the matrix that would be needed to see it. But I'm essentially trying to figure out how to make it act just like lu(A) \ ...
.
MWE:
Now if you factorize you get CPU fallbacks: