Skip to content

Commit c542c2f

Browse files
oxinaboxmzgubic
andcommitted
Apply suggestions from code review
Co-authored-by: Miha Zgubic <[email protected]>
1 parent 8fa0ecb commit c542c2f

File tree

3 files changed

+22
-22
lines changed

3 files changed

+22
-22
lines changed

docs/src/opting_out_of_rules.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
It is common to define rules fairly generically.
44
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.
66
Sometimes the AD can do better than this human defined rule.
77
If this is generally the case, then we should not have the rule defined at all.
88
But if it is only the case for a particular set of types, then we want to opt-out just that one.
99
This is done with the [`@opt_out`](@ref) macro.
1010

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)
1212
```julia
1313
function rrule(::typeof(sum), x::AbstractArray{<:Number}; dims=:)
1414
y = sum(x; dims=dims)
@@ -27,17 +27,17 @@ end
2727
That is a fairly reasonable `rrule` for the vast majority of cases.
2828

2929
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)))`.
3131
To do that, you can indeed write another more specific [`rrule`](@ref).
3232
But another case is where the AD system itself would generate a more optimized case.
3333

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.
3636
It is entirely conceivable[^1] that the AD system can do better than our `rrule` here.
3737
For example by avoiding the overhead of [`project`ing](@ref ProjectTo).
3838

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`.
4141

4242
```julia
4343
@opt_out rrule(::typeof(sum), ::NamedDimsArray)
@@ -53,11 +53,11 @@ Similar can be done `@opt_out frule`.
5353
It can also be done passing in a [`RuleConfig`](@ref config).
5454

5555

56-
### How to support this (for AD implementers)
56+
## How to support this (for AD implementers)
5757

5858
We provide two ways to know that a rule has been opted out of.
5959

60-
## `rrule` / `frule` returns `nothing`
60+
### `rrule` / `frule` returns `nothing`
6161

6262
`@opt_out` defines a `frule` or `rrule` matching the signature that returns `nothing`.
6363

@@ -70,12 +70,12 @@ else
7070
y, pullback = res
7171
end
7272
```
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.
7474

75-
## `no_rrule` / `no_frule` has a method
75+
### `no_rrule` / `no_frule` has a method
7676

7777
`@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.
7979
A simple thing you can do with this is not support opting out.
8080
To do this, filter all methods from the `rrule`/`frule` method table that also occur in the `no_frule`/`no_rrule` table.
8181
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.
8989

9090

9191

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.

src/rule_definition_tools.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -405,13 +405,13 @@ end
405405
@opt_out frule([config], _, f, args...)
406406
@opt_out rrule([config], f, args...)
407407
408-
This allows you to opt-out of a `frule` or `rrule` by providing a more specific method,
409-
that says to use the AD system, to solver it.
408+
This allows you to opt-out of an `frule` or an `rrule` by providing a more specific method,
409+
that says to use the AD system to differentiate it.
410410
411411
For example, consider some function `foo(x::AbtractArray)`.
412-
In general, you know a efficicent and generic way to implement it's `rrule`.
412+
In general, you know an efficient and generic way to implement its `rrule`.
413413
You do so, (likely making use of [`ProjectTo`](@ref)).
414-
But it actually turns out that for some `FancyArray` type it is better to let the AD do it's
414+
But it actually turns out that for some `FancyArray` type it is better to let the AD do its
415415
thing.
416416
417417
Then you would write something like:
@@ -424,7 +424,7 @@ end
424424
@opt_out rrule(::typeof(foo), ::FancyArray)
425425
```
426426
427-
This will generate a [`rrule`](@ref) that returns `nothing`,
427+
This will generate an [`rrule`](@ref) that returns `nothing`,
428428
and will also add a similar entry to [`ChainRulesCore.no_rrule`](@ref).
429429
430430
Similar applies for [`frule`](@ref) and [`ChainRulesCore.no_frule`](@ref)

src/rules.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ We use it as a way to store a collection of type-tuples in its method-table.
152152
If something has this defined, it means that it must having a must also have a `rrule`,
153153
that returns `nothing`.
154154
155-
### Machanics
156-
note: when this says methods `==` or `<:` it actually means:
157-
`parameters(m.sig)[2:end]` rather than the method object `m` itself.
155+
### Mechanics
156+
note: when the text below says methods `==` or `<:` it actually means:
157+
`parameters(m.sig)[2:end]` (i.e. the signature type tuple) rather than the method object `m` itself.
158158
159159
To decide if should opt-out using this mechanism.
160160
- find the most specific method of `rrule`
@@ -187,4 +187,4 @@ $(replace(NO_RRULE_DOC, "rrule"=>"frule"))
187187
See also [`ChainRulesCore.no_rrule`](@ref).
188188
"""
189189
function no_frule end
190-
no_frule(ȧrgs, f, ::Vararg{Any}) = nothing
190+
no_frule(ȧrgs, f, ::Vararg{Any}) = nothing

0 commit comments

Comments
 (0)