Can't calculate `von_neumann_entropy()` in gpu
zipeilee opened this issue · comments
When calculating the von_neumann_entropy()
of a certain quantum state on the GPU, I often receive CUDA errors like
ERROR: ArgumentError: cannot take the CPU address of a CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}
Stacktrace:
[1] unsafe_convert(#unused#::Type{Ptr{Float32}}, x::CuArray{Float32, 2, CUDA.Mem.DeviceBuffer})
@ CUDA ~/.julia/packages/CUDA/pCcGc/src/array.jl:370
[2] geevx!(balanc::Char, jobvl::Char, jobvr::Char, sense::Char, A::CuArray{Float32, 2, CUDA.Mem.DeviceBuffer})
@ LinearAlgebra.LAPACK ~/packages/julias/julia-1.9/share/julia/stdlib/v1.9/LinearAlgebra/src/lapack.jl:2093
[3] eigvals!(A::CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}; permute::Bool, scale::Bool, sortby::typeof(LinearAlgebra.eigsortby))
@ LinearAlgebra ~/packages/julias/julia-1.9/share/julia/stdlib/v1.9/LinearAlgebra/src/eigen.jl:306
[4] eigvals!(A::CuArray{Float32, 2, CUDA.Mem.DeviceBuffer})
@ LinearAlgebra ~/packages/julias/julia-1.9/share/julia/stdlib/v1.9/LinearAlgebra/src/eigen.jl:304
[5] eigvals(A::CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}; kws::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ LinearAlgebra ~/packages/julias/julia-1.9/share/julia/stdlib/v1.9/LinearAlgebra/src/eigen.jl:339
[6] eigvals(A::CuArray{Float32, 2, CUDA.Mem.DeviceBuffer})
@ LinearAlgebra ~/packages/julias/julia-1.9/share/julia/stdlib/v1.9/LinearAlgebra/src/eigen.jl:339
Then I remind that function von_neumann_entropy()
have a operattion p = max.(eigvals(dm), eps(real(eltype(dm))))
but it seems eigvals()
operation have not been implemented in CUDA.jl.
I wander if there is any way to improve this operation in Yao.jl so that it can run successfully on the GPU, or alternatively, to only load the quantum state onto the CPU when calculating the entropy?
I have tried change the
p = max.(eigvals(dm), eps(real(eltype(dm))))
to
_, l = eigen(dm)
p = max.(l, eps(real(eltype(dm))))
but due to computational precision, the density matrix is not a Hermitian matrix and LinearAlgebra.eigen()
only seems to work for symmetric/hermitian inputs.