@@ -169,3 +169,47 @@ function jacobian_sparsity(f!, Y, X, args...;
169169 return sparse (sparsity)
170170 end
171171end
172+
173+ function Cassette. overdub (ctx:: SparsityContext ,
174+ f:: typeof (Base. unsafe_copyto!),
175+ X:: Tagged ,
176+ xstart,
177+ Y:: Tagged ,
178+ ystart,
179+ len)
180+ S = ctx. metadata
181+ if ismetatype (Y, ctx, JacInput) && ismetatype (X, ctx, JacOutput)
182+ # Write directly to the output sparsity
183+ val = Cassette. fallback (ctx, f, X, xstart, Y, ystart, len)
184+ for (i, j) in zip (xstart: xstart+ len- 1 , ystart: ystart+ len- 1 )
185+ push! (S, i, j)
186+ end
187+ val
188+ elseif ismetatype (Y, ctx, JacInput)
189+ # Keep around a ProvinanceSet
190+ val = Cassette. fallback (ctx, f, X, xstart, Y, ystart, len)
191+ nometa = Cassette. NoMetaMeta ()
192+ rhs = (i-> Cassette. Meta (pset (i), nometa)). (ystart: ystart+ len- 1 )
193+ X. meta. meta[xstart: xstart+ len- 1 ] .= rhs
194+ val
195+ elseif ismetatype (X, ctx, JacOutput)
196+ val = Cassette. fallback (ctx, f, X, xstart, Y, ystart, len)
197+ for (i, j) in zip (xstart: xstart+ len- 1 , ystart: ystart+ len- 1 )
198+ y = Cassette. @overdub ctx Y[j]
199+ set = metadata (y, ctx)
200+ if set isa ProvinanceSet
201+ push! (S, i, set)
202+ end
203+ end
204+ val
205+ else
206+ val = Cassette. fallback (ctx, f, X, xstart, Y, ystart, len)
207+ for (i, j) in zip (xstart: xstart+ len- 1 , ystart: ystart+ len- 1 )
208+ y = Cassette. @overdub ctx Y[j]
209+ set = metadata (y, ctx)
210+ nometa = Cassette. NoMetaMeta ()
211+ X. meta. meta[i] = Cassette. Meta (set, nometa)
212+ end
213+ val
214+ end
215+ end
0 commit comments