# ChainRules for functions that "destroy their input arguments

**URL:** <https://discourse.julialang.org/t/chainrules-for-functions-that-destroy-their-input-arguments/103857>\
**Category:** Numerics\
**Tags:** autodiff, chainrules\
**Created:** [September 14, 2023, 3:41pm UTC](https://discourse.julialang.org/t/chainrules-for-functions-that-destroy-their-input-arguments/103857 "2023-09-14T15:41:03Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![lkdvos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lkdvos/32/43091_2.png) [@lkdvos](https://discourse.julialang.org/u/lkdvos)\
**Post date:** [September 14, 2023, 3:41pm UTC](https://discourse.julialang.org/t/chainrules-for-functions-that-destroy-their-input-arguments/103857/1 "2023-09-14T15:41:03Z")

</div>

Some functions have the behaviour of using their inputs as workspace, and by doing so their documented behaviour is that they destroy the input. As an example, things like `svd!` work in such fashion.  
While in general, mutating functions are not supported, in this case it might be fair to assume that we can define a rule like (example code):

```julia
function ChainRulesCore.rrule(::typeof(svd!), A)
    U, S, V = svd(A)
    pullback_svd!(dUSV) = pullback_svd(dUSV)
   [...]
end

```

Effectively, this automatically replaces `svd!` with `svd`, which should leave the code around it unaffected.

With this setting in mind, I have two questions:  
Firstly, is there any reason to refrain from doing this? It does feel prone to silent errors that are hard to debug.  
Secondly, for `rrule`s like this, the automatic `test_rrule` from ChainRulesTestUtils will fail, as this assumes that the primal values are left unchanged. I have a local version of `test_mutating_rrule` that circumvents this by explicitly copying these, for which I can file a pull request if wanted.

Any thoughts or comments are greatly appreciated.

I am asking this because I am defining rules for TensorKit, and there are similar rules there.

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [September 16, 2023, 10:31pm UTC](https://discourse.julialang.org/t/chainrules-for-functions-that-destroy-their-input-arguments/103857/2 "2023-09-16T22:31:38Z")

</div>

This sounds fine I think. So long as you are sure that no program tries to use the values written into `A`. Which seems likely if they are officially garbage.

For testing, one way would be to define `rrule(::typeof(svd!∘copy), x) = rrule(svd!, x)` and test that. ChainRules itself has some examples a bit like this, e.g. `collect∘eachslice` fits what CRTU expects (meaning in this case, an array output, even though `eachslice` returned a non-array iterator, on Julia 1.6 or so.)
