Comments (6)
Duplicate of #13, or at least #13 (comment) and the following discussion?
from abstractdifferentiation.jl.
BTW, regarding
Why is AD.jacobian so central to AbstractDifferentiation.jl and why does it have to be generated via a macro? Can't it be implemented in a more generic way by making sure pullbacks and pushforward wrappers have consistent output types?
#95 trimmed down the macro, it can only be used anymore to implement the jacobian based on a pushforward_function or a value_and_pullback_function. Support for ReverseDiff and FiniteDifferences is implemented without the macro already, and e.g. ForwardDiff uses the automatically constructed jacobian function only for functions with multiple arguments (the single-argument version just calls ForwardDiff.jacobian
).
from abstractdifferentiation.jl.
To elaborate on this:
What the macro does
As far as I understand, the @primitive
macro is used on pullbacks/pushforwards from individual backends to generate the following AD.jacobian
functions:
Forward-mode AD:
AbstractDifferentiation.jl/src/AbstractDifferentiation.jl
Lines 600 to 634 in 211b675
Reverse-mode AD:
AbstractDifferentiation.jl/src/AbstractDifferentiation.jl
Lines 636 to 663 in 211b675
These functions compute full Jacobians by evaluating the pullbacks/pushforwards on the standard basis (identity_like
).
Fallback behavior
By default, the fallback jacobian
function is empty (maybe this should be replaced by a NotImplementedError
):
As shown in the implementer guide, this jacobian
function is the fallback at the core of most functions exported by AbstractDifferentiation:
Taking reverse-mode AD as an example, the function dependency graph of value_and_pullback_function
would look as follows:
value_and_pullback_function
callsjacobian
jacobian
is an empty function
Now, when a reverse-mode AD backend is loaded, value_and_pullback_function
is defined for the backend and @primitive
is called on it, the function dependency graph is inverted:
value_and_pullback_function
calls the backend- a new generated
jacobian
callsvalue_and_pullback_function
The second behaviour is desired, as we wouldn't want to compute a full Jacobian just to compute a VJP when we can instead evaluate the pullback directly.
The fact that the function dependency graph is flipped was very confusing to me at first. A lot of hidden control flow is added via package extensions and the @primitive
macro, which currently isn't documented in the implementer guide.
Back to the question
Why is AD.jacobian
so central to AbstractDifferentiation.jl and why does it have to be generated via a macro? Can't it be implemented in a more generic way by making sure pullbacks and pushforward wrappers have consistent output types?
The only advantage I currently see is to allow users to
- compute VJPs by constructing a full Jacobian using JVPs
- compute JVPs by constructing a full Jacobian using VJPs
but those sound like things that should usually be avoided.
Why isn't AbstractDifferentiation.jl built around two primitives value_and_pullback_function
and value_and_pushforward
1 and making more liberal use of dispatch on the AbstractReverseMode
and AbstractForwardMode
types?
Footnotes
-
Ideally with in-place mutating variants. ↩
from abstractdifferentiation.jl.
Why is AD.jacobian so central to AbstractDifferentiation.jl
Why isn't AbstractDifferentiation.jl built around twoprimitives value_and_pullback_function
andvalue_and_pushforward
Historical reasons based mainly on the original author have a strong enough understanding of the calculus involved, but not such a strong understanding of autodiff or julia abstractions, IIRC. And the priority being on getting something out that worked and was usable. It should be.
from abstractdifferentiation.jl.
This issue is my fault. Feel free to remove the macro if it makes things simpler.
from abstractdifferentiation.jl.
As I mentioned in #13 (comment) and #123 (comment), I am ok with removing the macro. It is currently a thin wrapper over a pushforward or pullback definition. Feel free to open a PR.
from abstractdifferentiation.jl.
Related Issues (20)
- Define a function for v' J v
- Expose tests through public API in src HOT 2
- Add docs for how to implement API as an AD HOT 2
- API Docs for end-users HOT 5
- `pushforward_function` and `pullback_function` are confused by tuples vs single input
- Only support tuples and not single inputs/outputs HOT 7
- Use DocStringExtensions.jl
- Fix type instabilities HOT 7
- Add JET tests for linting and type instabilities
- AbstractDifferentiation stable docs 404 HOT 1
- Lazy jacobians could implement more of the LinearAlgebra interface
- New version timeline HOT 11
- Inconsistency in value_and_pushforward_function vs value_and_pullback_function outputs HOT 6
- Regression in type inferrability HOT 5
- `value_and_pullback_function` doesn't do what its docstring says HOT 3
- Configurable ForwardDiff tag
- Maybe AbstractDifferentiation should shrink to a collection of names? HOT 1
- Comparison with DifferentiationInterface.jl HOT 2
- Handling of thunks and tangents HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from abstractdifferentiation.jl.