gdalle / DifferentiationInterface.jl

An interface to various automatic differentiation backends in Julia.
https://gdalle.github.io/DifferentiationInterface.jl/DifferentiationInterface
MIT License
166 stars 13 forks source link

Generality #6

Closed gdalle closed 6 months ago

gdalle commented 8 months ago
adrhill commented 7 months ago

(1) Mutating pushforwards & pullbacks

These are at the core of DifferentiationInterface. Each backend needs to implement either a pushforward!, pullback! or both.

(1.1) Mutation of tangent

pushforward!(dy, backend, f, x, dx) -> (y, dy)
pullback!(dx, backend, f, x, dy) -> (y, dx)

(1.2) Mutation of primal and tangent

pushforward!(y, dy, backend, f!, x, dx) -> (y, dy)
pullback!(y, dx, backend, f!, x, dy) -> (y, dx)

(2) Allocating tangents

These are "obtained for free" using (1) as a fallback.

pushforward(backend, f, x, dx) -> (y, dy)
pullback(backend, f, x, dy) -> (y, dx)

The call order can be reversed ((1) calling (2)) in case mutation is not supported.

(3) Pullback closures

These look like a duplicate of (1), but are central to reverse-mode AD systems like Zygote to avoid redundant forward passes. However, they are seemingly irrelevant to Enzyme, which DifferentiationInterface wants to fully support.

pullback_function(backend, f, x, dy) -> (y, f_pb)

(4) Jacobian

Jacobians are "obtained for free" using (1) and (2) as fallbacks.
For $f: \mathbb{R}^n \rightarrow \mathbb{R}^m$ the corresponding $m\times n$ Jacobian can be constructed column-wise via $n$ calls to pushforward or row-wise via $m$ calls to pullback

(5) Gradient

Gradients are a special case of the Jacobian for $m=1$ and require $n$ calls to pushforward or one call to pullback

adrhill commented 7 months ago

Regarding (3), it looks like Enzyme supports "reverse pass punctions" via ReverseModeSplit and autodiff_deferred_thunk / autodiff_thunk.

CC @wsmoses

adrhill commented 6 months ago

I think this can largely be considered closed by #23 and should be replaced by more specific issues.