Skip to content

Commit d5ecd0b

Browse files
gdalledevmotion
andauthored
Move README content to docstrings & update docs website (#106)
* Move README content to docstrings & update docs website * WIP implementer guide * Add docs preview cleanup workflow * Update docs/src/user_guide.md Co-authored-by: David Widmann <[email protected]> * Update docs/Project.toml Co-authored-by: David Widmann <[email protected]> * Update src/AbstractDifferentiation.jl Co-authored-by: David Widmann <[email protected]> * Update src/AbstractDifferentiation.jl Co-authored-by: David Widmann <[email protected]> * Update src/AbstractDifferentiation.jl Co-authored-by: David Widmann <[email protected]> * Update src/AbstractDifferentiation.jl Co-authored-by: David Widmann <[email protected]> * Update src/AbstractDifferentiation.jl Co-authored-by: David Widmann <[email protected]> * Update src/AbstractDifferentiation.jl Co-authored-by: David Widmann <[email protected]> * Update src/AbstractDifferentiation.jl Co-authored-by: David Widmann <[email protected]> * Update src/AbstractDifferentiation.jl Co-authored-by: David Widmann <[email protected]> * Update src/AbstractDifferentiation.jl Co-authored-by: David Widmann <[email protected]> * Update src/AbstractDifferentiation.jl Co-authored-by: David Widmann <[email protected]> * Update src/AbstractDifferentiation.jl Co-authored-by: David Widmann <[email protected]> * Finish updating docstrings following devmotion's style recos * JuliaFormatter * Fix docs * Add implementer guide * Formatting * Add prefixes --------- Co-authored-by: David Widmann <[email protected]>
1 parent df50a8d commit d5ecd0b

13 files changed

+386
-300
lines changed

.JuliaFormatter.toml

-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
style = "blue"
22
format_markdown = true
3-

.github/workflows/CompatHelper.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ jobs:
1313
env:
1414
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1515
COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }}
16-
run: julia -e 'using CompatHelper; CompatHelper.main()'
16+
run: julia -e 'using CompatHelper; CompatHelper.main(; subdirs=["", "docs"])'
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Doc Preview Cleanup
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
7+
jobs:
8+
doc-preview-cleanup:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: write
12+
steps:
13+
- name: Checkout gh-pages branch
14+
uses: actions/checkout@v3
15+
with:
16+
ref: gh-pages
17+
- name: Delete preview and history + push changes
18+
run: |
19+
if [ -d "previews/PR$PRNUM" ]; then
20+
git config user.name "Documenter.jl"
21+
git config user.email "[email protected]"
22+
git rm -rf "previews/PR$PRNUM"
23+
git commit -m "delete preview"
24+
git branch gh-pages-new $(echo "delete history" | git commit-tree HEAD^{tree})
25+
git push --force origin gh-pages-new:gh-pages
26+
fi
27+
env:
28+
PRNUM: ${{ github.event.number }}

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/Manifest.toml
22
/docs/build
3-
/docs/src/index.md
3+
/docs/src/index.md
4+
/docs/Manifest.toml

README.md

+3-93
Original file line numberDiff line numberDiff line change
@@ -13,100 +13,10 @@ This is a package that implements an abstract interface for differentiation in J
1313

1414
Julia has more (automatic) differentiation packages than you can count on 2 hands. Different packages have different user interfaces. Therefore, having a backend-agnostic interface to request the function value and its gradient for example is necessary to avoid a combinatorial explosion of code when trying to support every differentiation package in Julia in every algorithm package requiring gradients. For higher order derivatives, the situation is even more dire since you can combine any 2 differentiation backends together to create a new higher-order backend.
1515

16-
## Loading `AbstractDifferentiation`
16+
## Getting started
1717

18-
To load `AbstractDifferentiation`, it is recommended to use
19-
20-
```julia
21-
import AbstractDifferentiation as AD
22-
```
23-
24-
With the `AD` alias you can access names inside of `AbstractDifferentiation` using `AD.<>` instead of typing the long name `AbstractDifferentiation`.
25-
26-
## `AbstractDifferentiation` backends
27-
28-
To use `AbstractDifferentiation`, first construct a backend instance `ab::AD.AbstractBackend` using your favorite differentiation package in Julia that supports `AbstractDifferentiation`.
29-
In particular, you may want to use `AD.ReverseRuleConfigBackend(ruleconfig)` for any [ChainRules.jl](https://github.com/JuliaDiff/ChainRules.jl)-compatible reverse mode differentiation package.
30-
31-
The following backends are temporarily made available by `AbstractDifferentiation` as soon as their corresponding package is loaded (thanks to [weak dependencies](https://pkgdocs.julialang.org/dev/creating-packages/#Weak-dependencies) on Julia ≥ 1.9 and [Requires.jl](https://github.com/JuliaPackaging/Requires.jl) on older Julia versions):
32-
33-
- `AD.ForwardDiffBackend()` for [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl)
34-
- `AD.FiniteDifferencesBackend()` for [FiniteDifferences.jl](https://github.com/JuliaDiff/FiniteDifferences.jl)
35-
- `AD.ReverseDiffBackend()` for [ReverseDiff.jl](https://github.com/JuliaDiff/ReverseDiff.jl)
36-
- `AD.TrackerBackend()` for [Tracker.jl](https://github.com/FluxML/Tracker.jl)
37-
- `AD.ZygoteBackend()` for [Zygote.jl](https://github.com/FluxML/Zygote.jl), which is a special case of `AD.ReverseRuleConfigBackend`
38-
39-
In the long term, these backend objects (and many more) will be defined within their respective packages to enforce the `AbstractDifferentiation` interface.
40-
This is already the case for some of them:
41-
42-
- `Diffractor.DiffractorForwardBackend()` for [Diffractor.jl](https://github.com/JuliaDiff/Diffractor.jl) in forward mode
43-
44-
Here's an example:
45-
46-
```julia
47-
julia> import AbstractDifferentiation as AD, Zygote
48-
49-
julia> ab = AD.ZygoteBackend()
50-
AbstractDifferentiation.ReverseRuleConfigBackend{Zygote.ZygoteRuleConfig{Zygote.Context}}(Zygote.ZygoteRuleConfig{Zygote.Context}(Zygote.Context(nothing)))
51-
52-
julia> f(x) = log(sum(exp, x))
53-
f (generic function with 1 method)
54-
55-
julia> AD.gradient(ab, f, rand(10))
56-
([0.07163448353282538, 0.08520350535348796, 0.09675622487503996, 0.1522744408520505, 0.12174662595572318, 0.07996969757526722, 0.07832665607158593, 0.11001685581681672, 0.06691909637037166, 0.1371524135968315],)
57-
```
58-
59-
For higher order derivatives, you can build higher order backends using `AD.HigherOrderBackend`. For instance, let `ab_f` be a forward-mode automatic differentiation backend and let `ab_r` be a reverse-mode automatic differentiation backend. To construct a higher order backend for doing forward-over-reverse-mode automatic differentiation, use `AD.HigherOrderBackend((ab_f, ab_r))`. To construct a higher order backend for doing reverse-over-forward-mode automatic differentiation, use `AD.HigherOrderBackend((ab_r, ab_f))`.
60-
61-
## Backend-agnostic interface
62-
63-
The following list of functions is the officially supported differentiation interface in `AbstractDifferentiation`.
64-
65-
### Derivative/Gradient/Jacobian/Hessian
66-
67-
The following list of functions can be used to request the derivative, gradient, Jacobian or Hessian without the function value.
68-
69-
- `ds = AD.derivative(ab::AD.AbstractBackend, f, xs::Number...)`: computes the derivatives `ds` of `f` wrt the numbers `xs` using the backend `ab`. `ds` is a tuple of derivatives, one for each element in `xs`.
70-
- `gs = AD.gradient(ab::AD.AbstractBackend, f, xs...)`: computes the gradients `gs` of `f` wrt the inputs `xs` using the backend `ab`. `gs` is a tuple of gradients, one for each element in `xs`.
71-
- `js = AD.jacobian(ab::AD.AbstractBackend, f, xs...)`: computes the Jacobians `js` of `f` wrt the inputs `xs` using the backend `ab`. `js` is a tuple of Jacobians, one for each element in `xs`.
72-
- `h = AD.hessian(ab::AD.AbstractBackend, f, x)`: computes the Hessian `h` of `f` wrt the input `x` using the backend `ab`. `hessian` currently only supports a single input.
73-
74-
### Value and Derivative/Gradient/Jacobian/Hessian
75-
76-
The following list of functions can be used to request the function value along with its derivative, gradient, Jacobian or Hessian. You can also request the function value, its gradient and Hessian for single-input functions.
77-
78-
- `(v, ds) = AD.value_and_derivative(ab::AD.AbstractBackend, f, xs::Number...)`: computes the function value `v = f(xs...)` and the derivatives `ds` of `f` wrt the numbers `xs` using the backend `ab`. `ds` is a tuple of derivatives, one for each element in `xs`.
79-
- `(v, gs) = AD.value_and_gradient(ab::AD.AbstractBackend, f, xs...)`: computes the function value `v = f(xs...)` and the gradients `gs` of `f` wrt the inputs `xs` using the backend `ab`. `gs` is a tuple of gradients, one for each element in `xs`.
80-
- `(v, js) = AD.value_and_jacobian(ab::AD.AbstractBackend, f, xs...)`: computes the function value `v = f(xs...)` and the Jacobians `js` of `f` wrt the inputs `xs` using the backend `ab`. `js` is a tuple of Jacobians, one for each element in `xs`.
81-
- `(v, h) = AD.value_and_hessian(ab::AD.AbstractBackend, f, x)`: computes the function value `v = f(x)` and the Hessian `h` of `f` wrt the input `x` using the backend `ab`. `hessian` currently only supports a single input.
82-
- `(v, g, h) = AD.value_gradient_and_hessian(ab::AD.AbstractBackend, f, x)`: computes the function value `v = f(x)` and the gradient `g` and Hessian `h` of `f` wrt the input `x` using the backend `ab`. `hessian` currently only supports a single input.
83-
84-
### Jacobian vector products (aka pushforward)
85-
86-
This operation goes by a few names. Refer to the [ChainRules documentation](https://juliadiff.org/ChainRulesCore.jl/stable/#The-propagators:-pushforward-and-pullback) for more on terminology. For a single input, single output function `f` with a Jacobian `J`, the pushforward operator `pf_f` is equivalent to applying the function `v -> J * v` on a (tangent) vector `v`.
87-
88-
The following functions can be used to request a function that returns the pushforward operator/function. In order to request the pushforward function `pf_f` of a function `f` at the inputs `xs`, you can use either of:
89-
90-
- `pf_f = AD.pushforward_function(ab::AD.AbstractBackend, f, xs...)`: returns the pushforward function `pf_f` of the function `f` at the inputs `xs`. `pf_f` is a function that accepts the tangents `vs` as input which is a tuple of length equal to the length of the tuple `xs`. If `f` has a single input, `pf_f` can also accept a single input instead of a 1-tuple.
91-
- `value_and_pf_f = AD.value_and_pushforward_function(ab::AD.AbstractBackend, f, xs...)`: returns a function `value_and_pf_f` which accepts the tangent `vs` as input which is a tuple of length equal to the length of the tuple `xs`. If `f` has a single input, `value_and_pf_f` can accept a single input instead of a 1-tuple. `value_and_pf_f` returns a 2-tuple, namely the value `f(xs...)` and output of the pushforward operator.
92-
93-
### Vector Jacobian products (aka pullback)
94-
95-
This operation goes by a few names. Refer to the [ChainRules documentation](https://juliadiff.org/ChainRulesCore.jl/stable/#The-propagators:-pushforward-and-pullback) for more on terminology. For a single input, single output function `f` with a Jacobian `J`, the pullback operator `pb_f` is equivalent to applying the function `v -> v' * J` on a (co-tangent) vector `v`.
96-
97-
The following functions can be used to request the pullback operator/function with or without the function value. In order to request the pullback function `pb_f` of a function `f` at the inputs `xs`, you can use either of:
98-
99-
- `pb_f = AD.pullback_function(ab::AD.AbstractBackend, f, xs...)`: returns the pullback function `pb_f` of the function `f` at the inputs `xs`. `pb_f` is a function that accepts the co-tangents `vs` as input which is a tuple of length equal to the number of outputs of `f`. If `f` has a single output, `pb_f` can also accept a single input instead of a 1-tuple.
100-
- `value_and_pb_f = AD.value_and_pullback_function(ab::AD.AbstractBackend, f, xs...)`: computes the function value `v = f(xs...)` and returns a 2-tuple containing the value `v` and a function `pb_f` that accepts the co-tangent `vs` as input, which is a tuple of length equal to the number of outputs of `f`. If `f` has a single output, `pb_f` can accept a single input instead of a 1-tuple.
101-
102-
### Lazy operators
103-
104-
You can also get a struct for the lazy derivative/gradient/Jacobian/Hessian of a function. You can then use the `*` operator to apply the lazy operator on a value or tuple of the correct shape. To get a lazy derivative/gradient/Jacobian/Hessian use any one of:
105-
106-
- `ld = lazy_derivative(ab::AbstractBackend, f, xs::Number...)`: returns an operator `ld` for multiplying by the derivative of `f` at `xs`. You can apply the operator by multiplication e.g. `ld * y` where `y` is a number if `f` has a single input, a tuple of the same length as `xs` if `f` has multiple inputs, or an array of numbers/tuples.
107-
- `lg = lazy_gradient(ab::AbstractBackend, f, xs...)`: returns an operator `lg` for multiplying by the gradient of `f` at `xs`. You can apply the operator by multiplication e.g. `lg * y` where `y` is a number if `f` has a single input or a tuple of the same length as `xs` if `f` has multiple inputs.
108-
- `lh = lazy_hessian(ab::AbstractBackend, f, x)`: returns an operator `lh` for multiplying by the Hessian of the scalar-valued function `f` at `x`. You can apply the operator by multiplication e.g. `lh * y` or `y' * lh` where `y` is a number or a vector of the appropriate length.
109-
- `lj = lazy_jacobian(ab::AbstractBackend, f, xs...)`: returns an operator `lj` for multiplying by the Jacobian of `f` at `xs`. You can apply the operator by multiplication e.g. `lj * y` or `y' * lj` where `y` is a number, vector or tuple of numbers and/or vectors. If `f` has multiple inputs, `y` in `lj * y` should be a tuple. If `f` has multiply outputs, `y` in `y' * lj` should be a tuple. Otherwise, it should be a scalar or a vector of the appropriate length.
18+
- If you are an autodiff user and want to write code in a backend-agnostic way, read the _user guide_ in the docs.
19+
- If you are an autodiff developer and want your backend to implement the interface, read the _implementer guide_ in the docs (still in construction).
11020

11121
## Citing this package
11222

docs/Manifest.toml

-178
This file was deleted.

docs/Project.toml

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
[deps]
22
AbstractDifferentiation = "c29ec348-61ec-40c8-8164-b8c60e9d9f3d"
33
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
4+
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
5+
6+
[compat]
7+
Documenter = "1"
8+
Zygote = "0.6"

docs/make.jl

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
using AbstractDifferentiation
2+
import AbstractDifferentiation as AD
23
using Documenter
34

45
DocMeta.setdocmeta!(
5-
AbstractDifferentiation, :DocTestSetup, :(using AbstractDifferentiation); recursive=true
6+
AbstractDifferentiation,
7+
:DocTestSetup,
8+
:(import AbstractDifferentiation as AD);
9+
recursive=true,
610
)
711

812
generated_path = joinpath(@__DIR__, "src")
@@ -28,15 +32,23 @@ end
2832
makedocs(;
2933
modules=[AbstractDifferentiation],
3034
authors="Mohamed Tarek <[email protected]> and contributors",
31-
repo="https://github.com/JuliaDiff/AbstractDifferentiation.jl/blob/{commit}{path}#{line}",
3235
sitename="AbstractDifferentiation.jl",
3336
format=Documenter.HTML(;
37+
repolink="https://github.com/JuliaDiff/AbstractDifferentiation.jl",
3438
prettyurls=get(ENV, "CI", "false") == "true",
3539
canonical="https://JuliaDiff.github.io/AbstractDifferentiation.jl",
3640
edit_link="master",
3741
assets=String[],
3842
),
39-
pages=["Home" => "index.md", "API reference" => "api.md"],
43+
pages=[
44+
"Home" => "index.md",
45+
"User guide" => "user_guide.md",
46+
"Implementer guide" => "implementer_guide.md",
47+
],
4048
)
4149

42-
deploydocs(; repo="github.com/JuliaDiff/AbstractDifferentiation.jl", devbranch="master")
50+
deploydocs(;
51+
repo="github.com/JuliaDiff/AbstractDifferentiation.jl",
52+
devbranch="master",
53+
push_preview=true,
54+
)

docs/src/api.md

-12
This file was deleted.

0 commit comments

Comments
 (0)