You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/src/opting_out_of_rules.md
+13-13Lines changed: 13 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,13 +2,13 @@
2
2
3
3
It is common to define rules fairly generically.
4
4
Often matching (or exceeding) how generic the matching original primal method is.
5
-
Sometimes this is not the correct behavour.
5
+
Sometimes this is not the correct behaviour.
6
6
Sometimes the AD can do better than this human defined rule.
7
7
If this is generally the case, then we should not have the rule defined at all.
8
8
But if it is only the case for a particular set of types, then we want to opt-out just that one.
9
9
This is done with the [`@opt_out`](@ref) macro.
10
10
11
-
Consider one might have a rrule for `sum` (the following simplified from the one in [ChainRules.jl](https://github.com/JuliaDiff/ChainRules.jl/blob/master/src/rulesets/Base/mapreduce.jl) itself)
11
+
Consider one a `rrule` for `sum` (the following simplified from the one in [ChainRules.jl](https://github.com/JuliaDiff/ChainRules.jl/blob/master/src/rulesets/Base/mapreduce.jl) itself)
That is a fairly reasonable `rrule` for the vast majority of cases.
28
28
29
29
You might have a custom array type for which you could write a faster rule.
30
-
For example, the pullback for summing a`SkewSymmetric` matrix can be optimizes to basically be `Diagonal(fill(ȳ, size(x,1)))`.
30
+
For example, the pullback for summing a[`SkewSymmetric`(anti-symmetric)](https://en.wikipedia.org/wiki/Skew-symmetric_matrix)matrix can be optimized to basically be `Diagonal(fill(ȳ, size(x,1)))`.
31
31
To do that, you can indeed write another more specific [`rrule`](@ref).
32
32
But another case is where the AD system itself would generate a more optimized case.
33
33
34
-
For example, the a [`NamedDimArray`](https://github.com/invenia/NamedDims.jl) is a thin wrapper around some other array type.
35
-
It's sum method is basically just to call `sum` on it's parent.
34
+
For example, the [`NamedDimsArray`](https://github.com/invenia/NamedDims.jl) is a thin wrapper around some other array type.
35
+
Its sum method is basically just to call `sum` on its parent.
36
36
It is entirely conceivable[^1] that the AD system can do better than our `rrule` here.
37
37
For example by avoiding the overhead of [`project`ing](@ref ProjectTo).
38
38
39
-
To opt-out of using the `rrule` and to allow the AD system to do its own thing we use the
40
-
[`@opt_out`](@ref) macro, to say to not use it for sum.
39
+
To opt-out of using the generic `rrule` and to allow the AD system to do its own thing we use the
40
+
[`@opt_out`](@ref) macro, to say to not use it for sum of `NamedDimsArrays`.
41
41
42
42
```julia
43
43
@opt_outrrule(::typeof(sum), ::NamedDimsArray)
@@ -53,11 +53,11 @@ Similar can be done `@opt_out frule`.
53
53
It can also be done passing in a [`RuleConfig`](@ref config).
54
54
55
55
56
-
###How to support this (for AD implementers)
56
+
## How to support this (for AD implementers)
57
57
58
58
We provide two ways to know that a rule has been opted out of.
59
59
60
-
## `rrule` / `frule` returns `nothing`
60
+
###`rrule` / `frule` returns `nothing`
61
61
62
62
`@opt_out` defines a `frule` or `rrule` matching the signature that returns `nothing`.
63
63
@@ -70,12 +70,12 @@ else
70
70
y, pullback = res
71
71
end
72
72
```
73
-
The Julia compiler, will specialize based on inferring the restun type of `rrule`, and so can remove that branch.
73
+
The Julia compiler will specialize based on inferring the return type of `rrule`, and so can remove that branch.
74
74
75
-
## `no_rrule` / `no_frule` has a method
75
+
###`no_rrule` / `no_frule` has a method
76
76
77
77
`@opt_out` also defines a method for [`ChainRulesCore.no_frule`](@ref) or [`ChainRulesCore.no_rrule`](@ref).
78
-
The use of this method doesn't matter, what matters is it's method-table.
78
+
The body of this method doesn't matter, what matters is that it is a method-table.
79
79
A simple thing you can do with this is not support opting out.
80
80
To do this, filter all methods from the `rrule`/`frule` method table that also occur in the `no_frule`/`no_rrule` table.
81
81
This will thus avoid ever hitting an `rrule`/`frule` that returns `nothing` and thus makes your library error.
@@ -89,4 +89,4 @@ and then `invoke` it.
89
89
90
90
91
91
92
-
[^1]: It is also possible, that this is not the case. Benchmark your real uses cases.
92
+
[^1]: It is also possible, that this is not the case. Benchmark your real uses cases.
0 commit comments