Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions ext/MatrixAlgebraKitCUDAExt/MatrixAlgebraKitCUDAExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -207,14 +207,6 @@ function svd_pullback!(ΔA::AnyCuMatrix, A, USVᴴ, ΔUSVᴴ, ind::AnyCuVector;
return svd_pullback!(ΔA, A, USVᴴ, ΔUSVᴴ, collect(ind); kwargs...)
end

function eigh_pullback!(ΔA::AnyCuMatrix, A, DV, ΔDV, ind::AnyCuVector; kwargs...)
return eigh_pullback!(ΔA, A, DV, ΔDV, collect(ind); kwargs...)
end

function eig_pullback!(ΔA::AnyCuMatrix, A, DV, ΔDV, ind::AnyCuVector; kwargs...)
return eig_pullback!(ΔA, A, DV, ΔDV, collect(ind); kwargs...)
end

# have to override this as methods are missing in GPUArrays for the various
# views of Diagonal of ΔA
function svd_pushforward!(
Expand Down
22 changes: 22 additions & 0 deletions src/common/pullbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,25 @@ iszerotangent(::Nothing) = true

# fallback
_sylvester(A, B, C) = LinearAlgebra.sylvester(A, B, C)

"""
select_indices(r::AbstractRange, ind)

Compute `r[ind]` without iterating over `ind`, so that this also works for an `ind` that
lives on a device.
"""
select_indices(r::AbstractRange, ind) = r[ind]
select_indices(r::AbstractRange, ind::AbstractRange{<:Integer}) = r[ind]
function select_indices(r::AbstractRange, ind::AbstractVector{<:Integer})
checkbounds(r, ind)
return first(r) .+ step(r) .* (ind .- 1)
end

"""
is_leading_index(ind, p::Int)

Check whether `ind` selects the first `p` values in order, i.e. whether `ind == 1:p`, without
iterating over `ind`, so that this also works for an `ind` that lives on a device.
"""
is_leading_index(ind::AbstractRange, p::Int) = ind == 1:p
is_leading_index(ind::AbstractVector, p::Int) = length(ind) == p && all(ind .== 1:p)
9 changes: 4 additions & 5 deletions src/pullbacks/eig.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ function check_and_prepare_eig_cotangents(
)

n, p = size(V)
indD = axes(D, 1)[ind]
indV = axes(V, 2)[ind]
indD = select_indices(axes(D, 1), ind)
indV = select_indices(axes(V, 2), ind)
if !iszerotangent(ΔV)
n == size(ΔV, 1) || throw(DimensionMismatch())
length(indV) == size(ΔV, 2) || throw(DimensionMismatch())
if indV == 1:p
if is_leading_index(indV, p)
ΔV₁ = copy(ΔV)
else
ΔV₁ = zero(V)
Expand Down Expand Up @@ -41,8 +41,7 @@ function check_and_prepare_eig_cotangents(
if !iszerotangent(ΔDmat)
ΔD = diagview(ΔDmat)
length(indD) == length(ΔD) || throw(DimensionMismatch())
# needed to avoid GPUCompiler errors
VᴴAΔV[diagind(VᴴAΔV)[indD]] .+= ΔD
VᴴAΔV[select_indices(diagind(VᴴAΔV), indD)] .+= ΔD
else
ΔD = nothing
end
Expand Down
9 changes: 4 additions & 5 deletions src/pullbacks/eigh.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ function check_and_prepare_eigh_cotangents(
)

n, p = size(V)
indD = axes(D, 1)[ind]
indV = axes(V, 2)[ind]
indD = select_indices(axes(D, 1), ind)
indV = select_indices(axes(V, 2), ind)
if !iszerotangent(ΔV)
n == size(ΔV, 1) || throw(DimensionMismatch())
length(indV) == size(ΔV, 2) || throw(DimensionMismatch())
if indV == 1:p
if is_leading_index(indV, p)
ΔV₁ = copy(ΔV)
else
ΔV₁ = zero(V)
Expand Down Expand Up @@ -42,8 +42,7 @@ function check_and_prepare_eigh_cotangents(
if !iszerotangent(ΔDmat)
ΔD = diagview(ΔDmat)
length(indD) == length(ΔD) || throw(DimensionMismatch())
# needed to avoid GPUCompiler errors
VᴴAΔV[diagind(VᴴAΔV)[indD]] .+= real.(ΔD)
VᴴAΔV[select_indices(diagind(VᴴAΔV), indD)] .+= real.(ΔD)
else
ΔD = nothing
end
Expand Down
Loading