MLKernels.jl
MLKernels.jl copied to clipboard
Using GPU to accelerate the eigen decomposition in the psuedo-inverse calculation in nystrom.jl
Here is my implementation:
using CuArrays, CUDAnative, LinearAlgebra, MLKernel
function make_symmetric(A::Mat, uplo::Char='U') where {T<:AbstractFloat, Vec<:AbstractVector{T}, Mat<:AbstractMatrix{T}}
return LinearAlgebra.copytri!(A |> Matrix{T}, uplo)
end
function nystrom_inv_gpu!(A::Mat) where {T<:AbstractFloat, Vec<:AbstractVector{T}, Mat<:AbstractMatrix{T}}
A = cu(A)
vals, vectors = CuArrays.CUSOLVER.syevd!('V', 'U', A)
tol = eps(T)*size(A,1)
max_eig = maximum(vals)
# for i in eachindex(vals)
# vals[i] = abs(vals[i]) <= max_eig * tol ? zero(T) : one(T) / sqrt(vals[i])
# end
predicate = one(T) .* (vals .>= max_eig * tol)
vals .= predicate .* CUDAnative.rsqrt.(vals .^ predicate)
QD = CuArrays.CUBLAS.dgmm!('R', vectors, vals, vectors)
W = CuArrays.CUBLAS.syrk('U', 'N', QD)
return make_symmetric(W)
end
Hi @changhe3
Unfortunately I'm not planning on maintaining this library anymore due to other commitments (it's been that way for a while) and I will be archiving the repo. There's another library that is the go-forward solution... I would open up an issue related to the Nystrom factorization over there:
https://github.com/theogf/KernelFunctions.jl
Great work though!