Skip to content

Commit 1a1dda3

Browse files
authored
Test QR rules with CUDA (#241)
* Test QR rules with CUDA * Incremental progress on pb * Turn off Diagonal QR tests for CUDA for now * Working QR * Fix another bad R22upper * Typo * Another fix * Remove duplicated comment * Use internal _rdiv * Update comment
1 parent 69a34d7 commit 1a1dda3

2 files changed

Lines changed: 37 additions & 6 deletions

File tree

src/pullbacks/qr.jl

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,18 @@ function check_and_prepare_qr_cotangents(
3131
ΔR₁₁ = UpperTriangular(view(ΔR, 1:p, 1:p))
3232
ΔR₁₂ = view(ΔR, 1:p, (p + 1):n)
3333
ΔR₂₂ = view(ΔR, (p + 1):minmn, (p + 1):n)
34-
Δgauge_R = norm(view(ΔR₂₂, uppertriangularind(ΔR₂₂)), Inf)
35-
Δgauge_R = max(Δgauge_R, norm(view(ΔR₂₂, diagind(ΔR₂₂)), Inf))
36-
Δgauge = max(Δgauge, Δgauge_R)
34+
if p < minmn # otherwise ΔR₂₂ is empty
35+
# uppertriangularind generates linear indices
36+
# compute the appropriate offset in ΔR so we aren't
37+
# operating on a view-of-view, which doesn't work
38+
# for GPU arrays
39+
I = uppertriangularind(ΔR₂₂)
40+
upper_inds = view(LinearIndices(ΔR), (p + 1):minmn, (p + 1):n)[I]
41+
ΔR₂₂upper = view(ΔR, upper_inds)
42+
Δgauge_R = norm(ΔR₂₂upper, Inf)
43+
Δgauge_R = max(Δgauge_R, norm(view(ΔR₂₂, diagind(ΔR₂₂)), Inf))
44+
Δgauge = max(Δgauge, Δgauge_R)
45+
end
3746
else
3847
ΔR₁₁ = nothing
3948
ΔR₁₂ = nothing
@@ -101,7 +110,12 @@ function qr_pullback!(
101110
Md = diagview(M)
102111
Md .= real.(Md)
103112
end
104-
ΔA₁ .+= rdiv!(mul!(ΔQ₁, Q₁, M, +1, 1), R₁₁')
113+
mul!(ΔQ₁, Q₁, M, +1, 1)
114+
# bypass istriu check in LinearAlgebra's toplevel rdiv
115+
# which causes scalar indexing for GPU arrays.
116+
# TODO: revisit this if/when LinearAlgebra becomes more
117+
# sensible.
118+
ΔA₁ .+= LinearAlgebra._rdiv!(ΔQ₁, ΔQ₁, R₁₁')
105119
return ΔA
106120
end
107121

@@ -147,7 +161,8 @@ ambiguity. Additionally, rows of `ΔR` beyond the rank are zeroed out.
147161
"""
148162
function remove_qr_gauge_dependence!(ΔQ, ΔR, A, Q, R; rank_atol = MatrixAlgebraKit.default_pullback_rank_atol(R))
149163
r = MatrixAlgebraKit.qr_rank(R; rank_atol)
150-
minmn = min(size(A)...)
164+
m, n = size(A, 1), size(A, 2)
165+
minmn = min(m, n)
151166
Q₁ = view(Q, :, 1:r)
152167
ΔQ₂ = view(ΔQ, :, (r + 1):minmn)
153168
zero!(ΔQ₂)
@@ -160,7 +175,16 @@ function remove_qr_gauge_dependence!(ΔQ, ΔR, A, Q, R; rank_atol = MatrixAlgebr
160175
end
161176
ΔR₂₂ = view(ΔR, (r + 1):minmn, (r + 1):size(R, 2))
162177
zero!(diagview(ΔR₂₂))
163-
zero!(view(ΔR₂₂, uppertriangularind(ΔR₂₂)))
178+
if r < minmn
179+
# uppertriangularind generates linear indices
180+
# compute the appropriate offset in ΔR so we aren't
181+
# operating on a view-of-view, which doesn't work
182+
# for GPU arrays
183+
I = uppertriangularind(ΔR₂₂)
184+
upper_inds = view(LinearIndices(ΔR), (r + 1):minmn, (r + 1):n)[I]
185+
ΔR₂₂upper = view(ΔR, upper_inds)
186+
zero!(ΔR₂₂upper)
187+
end
164188
return ΔQ, ΔR
165189
end
166190

test/mooncake/qr.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_qr(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_qr(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_qr(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)