Skip to content

Commit e82ab12

Browse files
authored
Tests and working pb for CUDA + LQ (#258)
* Tests and working pb for CUDA + LQ * Missing diagview zero?
1 parent 1a1dda3 commit e82ab12

2 files changed

Lines changed: 35 additions & 6 deletions

File tree

src/pullbacks/lq.jl

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,18 @@ function check_and_prepare_lq_cotangents(
3030
ΔL₁₁ = LowerTriangular(view(ΔL, 1:p, 1:p))
3131
ΔL₂₁ = view(ΔL, (p + 1):size(ΔL, 1), 1:p)
3232
ΔL₂₂ = view(ΔL, (p + 1):size(ΔL, 1), (p + 1):minmn)
33-
Δgauge_L = norm(view(ΔL₂₂, lowertriangularind(ΔL₂₂)), Inf)
34-
Δgauge_L = max(Δgauge_L, norm(view(ΔL₂₂, diagind(ΔL₂₂)), Inf))
35-
Δgauge = max(Δgauge, Δgauge_L)
33+
if p < minmn # otherwise ΔL₂₂ is empty
34+
# lowertriangularind generates linear indices
35+
# compute the appropriate offset in ΔL so we aren't
36+
# operating on a view-of-view, which doesn't work
37+
# for GPU arrays
38+
I = lowertriangularind(ΔL₂₂)
39+
lower_inds = view(LinearIndices(ΔL), (p + 1):m, (p + 1):minmn)[I]
40+
ΔL₂₂lower = view(ΔL, lower_inds)
41+
Δgauge_L = norm(ΔL₂₂lower, Inf)
42+
Δgauge_L = max(Δgauge_L, norm(view(ΔL₂₂, diagind(ΔL₂₂)), Inf))
43+
Δgauge = max(Δgauge, Δgauge_L)
44+
end
3645
else
3746
ΔL₁₁ = nothing
3847
ΔL₂₁ = nothing
@@ -145,20 +154,33 @@ Additionally, columns of `ΔL` beyond the rank are zeroed out.
145154
"""
146155
function remove_lq_gauge_dependence!(ΔL, ΔQ, A, L, Q; rank_atol = MatrixAlgebraKit.default_pullback_rank_atol(L))
147156
r = MatrixAlgebraKit.lq_rank(L; rank_atol)
148-
minmn = min(size(A)...)
157+
m, n = size(A)
158+
minmn = min(m, n)
149159
Q₁ = view(Q, 1:r, :)
150160
ΔQ₂ = view(ΔQ, (r + 1):minmn, :)
151161
zero!(ΔQ₂)
152162
ΔQ₃ = view(ΔQ, (minmn + 1):size(ΔQ, 1), :) # extra rows in the case of lq_full
153-
if r == minmn
163+
# use this isempty check here to avoid GPU dispatch errors
164+
# since CUBLAS scal! can't handle an array with stride > 1
165+
# on dimension 1
166+
if r == minmn && !isempty(ΔQ₃)
154167
ΔQ₃Q₁ᴴ = ΔQ₃ * Q₁'
155168
mul!(ΔQ₃, ΔQ₃Q₁ᴴ, Q₁)
156169
else # rank-deficient case, no gauge-invariant information
157170
zero!(ΔQ₃)
158171
end
159172
ΔL₂₂ = view(ΔL, (r + 1):size(ΔL, 1), (r + 1):minmn)
160173
zero!(diagview(ΔL₂₂))
161-
zero!(view(ΔL₂₂, lowertriangularind(ΔL₂₂)))
174+
if r < minmn
175+
# lowertriangularind generates linear indices
176+
# compute the appropriate offset in ΔL so we aren't
177+
# operating on a view-of-view, which doesn't work
178+
# for GPU arrays
179+
I = lowertriangularind(ΔL₂₂)
180+
lower_inds = view(LinearIndices(ΔL), (r + 1):m, (r + 1):minmn)[I]
181+
ΔL₂₂lower = view(ΔL, lower_inds)
182+
zero!(ΔL₂₂lower)
183+
end
162184
return ΔL, ΔQ
163185
end
164186

test/mooncake/lq.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,11 @@ for T in (BLASFloats..., GenericFloats...), n in (17, m, 23)
2020
TestSuite.test_mooncake_lq(AT, (m, m); atol = m * n * TestSuite.precision(T), rtol = m * n * TestSuite.precision(T))
2121
end
2222
end
23+
if T BLASFloats && CUDA.functional()
24+
TestSuite.test_mooncake_lq(CuMatrix{T}, (m, n); atol = m * n * TestSuite.precision(T), rtol = m * n * TestSuite.precision(T))
25+
#=if m == n
26+
AT = Diagonal{T, CuVector{T}}
27+
TestSuite.test_mooncake_lq(AT, (m, m); atol = m * n * TestSuite.precision(T), rtol = m * n * TestSuite.precision(T))
28+
end=# # currently broken
29+
end
2330
end

0 commit comments

Comments
 (0)