@@ -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
106120end
107121
@@ -147,7 +161,8 @@ ambiguity. Additionally, rows of `ΔR` beyond the rank are zeroed out.
147161"""
148162function 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
165189end
166190
0 commit comments