diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index bef7d2a36..071b3c413 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-03-20T22:09:28","documenter_version":"1.3.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-03-21T07:04:06","documenter_version":"1.3.0"}} \ No newline at end of file diff --git a/dev/api/index.html b/dev/api/index.html index 034dc838e..5e77b735e 100644 --- a/dev/api/index.html +++ b/dev/api/index.html @@ -1,26 +1,26 @@ -API reference · DifferentiationInterface.jl

API reference

DifferentiationInterface.DifferentiationInterfaceModule
DifferentiationInterface

An interface to various automatic differentiation backends in Julia.

Exports

source

Derivative

Multiderivative

DifferentiationInterface.value_and_multiderivative!Method
value_and_multiderivative!(multider, backend, f, x, [extras]) -> (y, multider)
-value_and_multiderivative!(y, multider, backend, f!, x, [extras]) -> (y, multider)

Compute the primal value y = f(x) and the (array-valued) derivative multider = f'(x) of a scalar-to-array function, overwriting multider.

source

Gradient

Jacobian

DifferentiationInterface.jacobian!Method
jacobian!(jac, backend, f, x, [extras]) -> jac

Compute the Jacobian matrix jac = ∂f(x) of an array-to-array function, overwriting jac.

Notes

Regardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.

source
DifferentiationInterface.jacobianMethod
jacobian(backend, f, x, [extras]) -> jac

Compute the Jacobian matrix jac = ∂f(x) of an array-to-array function.

Notes

Regardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.

source
DifferentiationInterface.value_and_jacobian!Method
value_and_jacobian!(jac, backend, f, x, [extras]) -> (y, jac)
-value_and_jacobian!(y, jac, backend, f!, x, [extras]) -> (y, jac)

Compute the primal value y = f(x) and the Jacobian matrix jac = ∂f(x) of an array-to-array function, overwriting jac.

Notes

Regardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.

source
DifferentiationInterface.value_and_jacobianMethod
value_and_jacobian(backend, f, x, [extras]) -> (y, jac)

Compute the primal value y = f(x) and the Jacobian matrix jac = ∂f(x) of an array-to-array function.

Notes

Regardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.

source

Second derivative

Hessian

DifferentiationInterface.hessian!Method
hessian!(hess, backend, f, x, [extras]) -> hess

Compute the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting hess.

Notes

Regardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.

source
DifferentiationInterface.hessianMethod
hessian(backend, f, x, [extras]) -> hess

Compute the Hessian hess = ∇²f(x) of an array-to-scalar function.

Notes

Regardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.

source
DifferentiationInterface.value_gradient_and_hessian!Method
value_gradient_and_hessian!(grad, hess, backend, f, x, [extras]) -> (y, grad, hess)

Compute the primal value y = f(x), the gradient grad = ∇f(x) and the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting grad and hess.

Notes

Regardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.

source
DifferentiationInterface.value_gradient_and_hessianMethod
value_gradient_and_hessian(backend, f, x, [extras]) -> (y, grad, hess)

Compute the primal value y = f(x), the gradient grad = ∇f(x) and the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting grad and hess.

Notes

Regardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.

source

Pushforward (JVP)

DifferentiationInterface.value_and_pushforward!Method
value_and_pushforward!(dy, backend, f, x, dx, [extras]) -> (y, dy)
-value_and_pushforward!(y, dy, backend, f!, x, dx, [extras]) -> (y, dy)

Compute the primal value y = f(x) and the Jacobian-vector product dy = ∂f(x) * dx, overwriting dy if possible.

Interface requirement

This is the only required implementation for a forward mode backend.

source

Pullback (JVP)

DifferentiationInterface.value_and_pullback!Method
value_and_pullback!(dx, backend, f, x, dy, [extras]) -> (y, dx)
-value_and_pullback!(y, dx, backend, f!, x, dy, [extras]) -> (y, dx)

Compute the primal value y = f(x) and the vector-Jacobian product dx = ∂f(x)' * dy, overwriting dx if possible.

Interface requirement

This is the only required implementation for a reverse mode backend.

source

Hessian-vector product (HVP)

Preparation

Backend queries

Internals

This is not part of the public API.

DifferentiationInterface.basisarrayMethod
basisarray(backend, a::AbstractArray, i::CartesianIndex)

Construct the i-th stardard basis array in the vector space of a with element type eltype(a).

Note

If an AD backend benefits from a more specialized basis array implementation, this function can be extended on the backend type.

source
DifferentiationInterface.modeFunction
mode(backend)

Return the AD mode of a backend in a statically predictable way.

This function must be overloaded for backends that support both forward and reverse.

We classify finite differences as a forward mode.

source

Testing

This is not part of the public API.

DifferentiationInterface.DifferentiationTest.BenchmarkDataType
BenchmarkData

Fields

  • backend::Vector

  • operator::Vector

  • func::Vector

  • mutating::Vector

  • input_type::Vector

  • output_type::Vector

  • input_size::Vector

  • output_size::Vector

  • samples::Vector

  • time::Vector

  • bytes::Vector

  • allocs::Vector

  • compile_fraction::Vector

  • gc_fraction::Vector

  • evals::Vector

source
DifferentiationInterface.DifferentiationTest.ScenarioType
Scenario

Store a testing scenario composed of a function and its input + output + tangents.

Fields

  • f::Any: function

  • mutating::Bool: mutation

  • x::Union{Number, AbstractArray}: input

  • y::Union{Number, AbstractArray}: output

  • dx::Union{Number, AbstractArray}: pushforward seed

  • dy::Union{Number, AbstractArray}: pullback seed

source
DifferentiationInterface.DifferentiationTest.test_operatorsFunction
test_operators(
+API reference · DifferentiationInterface.jl

API reference

DifferentiationInterface.DifferentiationInterfaceModule
DifferentiationInterface

An interface to various automatic differentiation backends in Julia.

Exports

source

Derivative

Multiderivative

DifferentiationInterface.value_and_multiderivative!Method
value_and_multiderivative!(multider, backend, f, x, [extras]) -> (y, multider)
+value_and_multiderivative!(y, multider, backend, f!, x, [extras]) -> (y, multider)

Compute the primal value y = f(x) and the (array-valued) derivative multider = f'(x) of a scalar-to-array function, overwriting multider.

source

Gradient

Jacobian

DifferentiationInterface.jacobian!Method
jacobian!(jac, backend, f, x, [extras]) -> jac

Compute the Jacobian matrix jac = ∂f(x) of an array-to-array function, overwriting jac.

Notes

Regardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.

source
DifferentiationInterface.jacobianMethod
jacobian(backend, f, x, [extras]) -> jac

Compute the Jacobian matrix jac = ∂f(x) of an array-to-array function.

Notes

Regardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.

source
DifferentiationInterface.value_and_jacobian!Method
value_and_jacobian!(jac, backend, f, x, [extras]) -> (y, jac)
+value_and_jacobian!(y, jac, backend, f!, x, [extras]) -> (y, jac)

Compute the primal value y = f(x) and the Jacobian matrix jac = ∂f(x) of an array-to-array function, overwriting jac.

Notes

Regardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.

source
DifferentiationInterface.value_and_jacobianMethod
value_and_jacobian(backend, f, x, [extras]) -> (y, jac)

Compute the primal value y = f(x) and the Jacobian matrix jac = ∂f(x) of an array-to-array function.

Notes

Regardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.

source

Second derivative

Hessian

DifferentiationInterface.hessian!Method
hessian!(hess, backend, f, x, [extras]) -> hess

Compute the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting hess.

Notes

Regardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.

source
DifferentiationInterface.hessianMethod
hessian(backend, f, x, [extras]) -> hess

Compute the Hessian hess = ∇²f(x) of an array-to-scalar function.

Notes

Regardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.

source
DifferentiationInterface.value_gradient_and_hessian!Method
value_gradient_and_hessian!(grad, hess, backend, f, x, [extras]) -> (y, grad, hess)

Compute the primal value y = f(x), the gradient grad = ∇f(x) and the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting grad and hess.

Notes

Regardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.

source
DifferentiationInterface.value_gradient_and_hessianMethod
value_gradient_and_hessian(backend, f, x, [extras]) -> (y, grad, hess)

Compute the primal value y = f(x), the gradient grad = ∇f(x) and the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting grad and hess.

Notes

Regardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.

source

Pushforward (JVP)

DifferentiationInterface.value_and_pushforward!Method
value_and_pushforward!(dy, backend, f, x, dx, [extras]) -> (y, dy)
+value_and_pushforward!(y, dy, backend, f!, x, dx, [extras]) -> (y, dy)

Compute the primal value y = f(x) and the Jacobian-vector product dy = ∂f(x) * dx, overwriting dy if possible.

Interface requirement

This is the only required implementation for a forward mode backend.

source

Pullback (JVP)

DifferentiationInterface.value_and_pullback!Method
value_and_pullback!(dx, backend, f, x, dy, [extras]) -> (y, dx)
+value_and_pullback!(y, dx, backend, f!, x, dy, [extras]) -> (y, dx)

Compute the primal value y = f(x) and the vector-Jacobian product dx = ∂f(x)' * dy, overwriting dx if possible.

Interface requirement

This is the only required implementation for a reverse mode backend.

source

Hessian-vector product (HVP)

Preparation

Backend queries

Internals

This is not part of the public API.

DifferentiationInterface.basisarrayMethod
basisarray(backend, a::AbstractArray, i::CartesianIndex)

Construct the i-th stardard basis array in the vector space of a with element type eltype(a).

Note

If an AD backend benefits from a more specialized basis array implementation, this function can be extended on the backend type.

source
DifferentiationInterface.modeFunction
mode(backend)

Return the AD mode of a backend in a statically predictable way.

This function must be overloaded for backends that support both forward and reverse.

We classify finite differences as a forward mode.

source

Testing

This is not part of the public API.

DifferentiationInterface.DifferentiationTest.BenchmarkDataType
BenchmarkData

Fields

  • backend::Vector

  • operator::Vector

  • func::Vector

  • mutating::Vector

  • input_type::Vector

  • output_type::Vector

  • input_size::Vector

  • output_size::Vector

  • samples::Vector

  • time::Vector

  • bytes::Vector

  • allocs::Vector

  • compile_fraction::Vector

  • gc_fraction::Vector

  • evals::Vector

source
DifferentiationInterface.DifferentiationTest.ScenarioType
Scenario

Store a testing scenario composed of a function and its input + output + tangents.

Fields

  • f::Any: function

  • mutating::Bool: mutation

  • x::Union{Number, AbstractArray}: input

  • y::Union{Number, AbstractArray}: output

  • dx::Union{Number, AbstractArray}: pushforward seed

  • dy::Union{Number, AbstractArray}: pullback seed

source
DifferentiationInterface.DifferentiationTest.test_operatorsFunction
test_operators(
     backends, [operators, scenarios];
     correctness, type_stability, benchmark, allocations,
     input_type, output_type,
     first_order, second_order, allocating, mutating,
     excluded,
-)

Cross-test a list of backends for a list of operators on a list of scenarios.

Return nothing, except when benchmark=true.

Default arguments

  • operators: defaults to all of them
  • scenarios: defaults to a set of default scenarios

Keyword arguments

  • correctness=true: whether to compare the differentiation results with those given by ForwardDiff.jl
  • type_stability=true: whether to check type stability with JET.jl
  • call_count=false: whether to check that the function is called the right number of times
  • benchmark=false: whether to run and return a benchmark suite with Chairmarks.jl
  • allocations=false: whether to check that the benchmarks are allocation-free
  • input_type=Any: restrict scenario inputs to subtypes of this
  • output_type=Any: restrict scenario outputs to subtypes of this
  • first_order=true: consider first order operators
  • second_order=true: consider second order operators
  • allocating=true: consider operators for allocating functions
  • mutating=true: consider operators for mutating functions
  • excluded=Symbol[]: list of excluded operators
source
DifferentiationInterface.DifferentiationTest.test_operatorsMethod
test_operators(
+)

Cross-test a list of backends for a list of operators on a list of scenarios.

Return nothing, except when benchmark=true.

Default arguments

  • operators: defaults to all of them
  • scenarios: defaults to a set of default scenarios

Keyword arguments

  • correctness=true: whether to compare the differentiation results with those given by ForwardDiff.jl
  • type_stability=true: whether to check type stability with JET.jl
  • call_count=false: whether to check that the function is called the right number of times
  • benchmark=false: whether to run and return a benchmark suite with Chairmarks.jl
  • allocations=false: whether to check that the benchmarks are allocation-free
  • input_type=Any: restrict scenario inputs to subtypes of this
  • output_type=Any: restrict scenario outputs to subtypes of this
  • first_order=true: consider first order operators
  • second_order=true: consider second order operators
  • allocating=true: consider operators for allocating functions
  • mutating=true: consider operators for mutating functions
  • excluded=Symbol[]: list of excluded operators
source
+
diff --git a/dev/backends/index.html b/dev/backends/index.html index c468243ec..257c0ceba 100644 --- a/dev/backends/index.html +++ b/dev/backends/index.html @@ -1,6 +1,6 @@ Backends · DifferentiationInterface.jl

Backends

Types

Most backend choices are defined by ADTypes.jl.

Warning

Only the backends listed here are supported by DifferentiationInterface.jl, even though ADTypes.jl defines more.

ADTypes.AutoEnzymeType
AutoEnzyme(Enzyme.Forward)
-AutoEnzyme(Enzyme.Reverse)

Construct a forward or reverse mode AutoEnzyme backend.

source
AutoEnzyme{M}

Chooses Enzyme.jl.

Fields

  • mode::M = nothing
source

We also provide a few of our own:

DifferentiationInterface.SecondOrderType
SecondOrder

Combination of two backends for second-order differentiation.

Fields

  • inner::ADTypes.AbstractADType: backend for the inner differentiation

  • outer::ADTypes.AbstractADType: backend for the outer differentiation

source

Availability

You can use available to verify whether a given backend is loaded, like we did below:

Backendavailable
Diffractor (forward)
Enzyme (forward)
Enzyme (reverse)
FastDifferentiation (symbolic)
FiniteDiff (forward)
ForwardDiff (forward)
PolyesterForwardDiff (forward)
ReverseDiff (reverse)
Tracker (reverse)
Zygote (reverse)
+AutoEnzyme(Enzyme.Reverse)

Construct a forward or reverse mode AutoEnzyme backend.

source
AutoEnzyme{M}

Chooses Enzyme.jl.

Fields

  • mode::M = nothing
source

We also provide a few of our own:

DifferentiationInterface.SecondOrderType
SecondOrder

Combination of two backends for second-order differentiation.

Fields

  • inner::ADTypes.AbstractADType: backend for the inner differentiation

  • outer::ADTypes.AbstractADType: backend for the outer differentiation

source

Availability

You can use available to verify whether a given backend is loaded, like we did below:

Backendavailable
Diffractor (forward)
Enzyme (forward)
Enzyme (reverse)
FastDifferentiation (symbolic)
FiniteDiff (forward)
ForwardDiff (forward)
PolyesterForwardDiff (forward)
ReverseDiff (reverse)
Tracker (reverse)
Zygote (reverse)

Mutation support

All backends are compatible with allocating functions f(x) = y. Only some are compatible with mutating functions f!(y, x) = nothing. You can use supports_mutation to check that feature, like we did below:

Backendmutation
Diffractor (forward)
Enzyme (forward)
Enzyme (reverse)
FastDifferentiation (symbolic)
FiniteDiff (forward)
ForwardDiff (forward)
PolyesterForwardDiff (forward)
ReverseDiff (reverse)
Tracker (reverse)
Zygote (reverse)

Second order

For second-order differentiation, you can either

In Hessian computations, the most efficient combination is often forward-over-reverse, i.e. SecondOrder(reverse_backend, forward_backend).

Info

Many backend combinations will fail for second order. Some because of our implementation, and some because the outer backend cannot differentiate through code generated by the inner backend.

You can use supports_hessian to find working combinations, like we did below:

Inner \ OuterDiffractor (forward)Enzyme (forward)Enzyme (reverse)FastDifferentiation (symbolic)FiniteDiff (forward)ForwardDiff (forward)PolyesterForwardDiff (forward)ReverseDiff (reverse)Tracker (reverse)Zygote (reverse)
Diffractor (forward)
Enzyme (forward)
Enzyme (reverse)
FastDifferentiation (symbolic)
FiniteDiff (forward)
ForwardDiff (forward)
PolyesterForwardDiff (forward)
ReverseDiff (reverse)
Tracker (reverse)
Zygote (reverse)

Package extensions

Backend-specific extension content is not part of the public API.

+
diff --git a/dev/developer/index.html b/dev/developer/index.html index b22c5cae5..1fbde51fe 100644 --- a/dev/developer/index.html +++ b/dev/developer/index.html @@ -116,4 +116,4 @@ startOnLoad: true, theme: "neutral" }); - + diff --git a/dev/getting_started/index.html b/dev/getting_started/index.html index 1bdeb8721..e1e3ad740 100644 --- a/dev/getting_started/index.html +++ b/dev/getting_started/index.html @@ -4,4 +4,4 @@ startOnLoad: true, theme: "neutral" }); - + diff --git a/dev/index.html b/dev/index.html index b5f744e07..cc4651cce 100644 --- a/dev/index.html +++ b/dev/index.html @@ -20,4 +20,4 @@ startOnLoad: true, theme: "neutral" }); - + diff --git a/dev/objects.inv b/dev/objects.inv index 8de003247..6b6c7d2de 100644 Binary files a/dev/objects.inv and b/dev/objects.inv differ diff --git a/dev/search_index.js b/dev/search_index.js index d020a3ed3..177d28d66 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"api/","page":"API reference","title":"API reference","text":"CurrentModule = DifferentiationInterface\nCollapsedDocStrings = true","category":"page"},{"location":"api/#API-reference","page":"API reference","title":"API reference","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"DifferentiationInterface","category":"page"},{"location":"api/#DifferentiationInterface.DifferentiationInterface","page":"API reference","title":"DifferentiationInterface.DifferentiationInterface","text":"DifferentiationInterface\n\nAn interface to various automatic differentiation backends in Julia.\n\nExports\n\nAutoFastDifferentiation\nSecondOrder\navailable\nderivative\ngradient\ngradient!\ngradient_and_hessian_vector_product\ngradient_and_hessian_vector_product!\nhessian\nhessian!\nhessian_vector_product\nhessian_vector_product!\njacobian\njacobian!\nmultiderivative\nmultiderivative!\nprepare_derivative\nprepare_gradient\nprepare_hessian\nprepare_hessian_vector_product\nprepare_jacobian\nprepare_multiderivative\nprepare_pullback\nprepare_pushforward\nprepare_second_derivative\npullback\npullback!\npushforward\npushforward!\nsecond_derivative\nsupports_hessian\nsupports_mutation\nvalue_and_derivative\nvalue_and_gradient\nvalue_and_gradient!\nvalue_and_jacobian\nvalue_and_jacobian!\nvalue_and_multiderivative\nvalue_and_multiderivative!\nvalue_and_pullback\nvalue_and_pullback!\nvalue_and_pushforward\nvalue_and_pushforward!\nvalue_derivative_and_second_derivative\nvalue_gradient_and_hessian\nvalue_gradient_and_hessian!\n\n\n\n\n\n","category":"module"},{"location":"api/#Derivative","page":"API reference","title":"Derivative","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"src/derivative.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.derivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.derivative","text":"derivative(backend, f, x, [extras]) -> der\n\nCompute the derivative der = f'(x) of a scalar-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_derivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_derivative","text":"value_and_derivative(backend, f, x, [extras]) -> (y, der)\n\nCompute the primal value y = f(x) and the derivative der = f'(x) of a scalar-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#Multiderivative","page":"API reference","title":"Multiderivative","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"multiderivative.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.multiderivative!-Union{Tuple{F}, Tuple{AbstractArray, ADTypes.AbstractADType, F, Number}, Tuple{AbstractArray, ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.multiderivative!","text":"multiderivative!(multider, backend, f, x, [extras]) -> multider\n\nCompute the (array-valued) derivative multider = f'(x) of a scalar-to-array function, overwriting multider.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.multiderivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.multiderivative","text":"multiderivative(backend, f, x, [extras]) -> multider\n\nCompute the (array-valued) derivative multider = f'(x) of a scalar-to-array function.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_multiderivative!-Union{Tuple{F}, Tuple{AbstractArray, ADTypes.AbstractADType, F, Number}, Tuple{AbstractArray, ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_multiderivative!","text":"value_and_multiderivative!(multider, backend, f, x, [extras]) -> (y, multider)\nvalue_and_multiderivative!(y, multider, backend, f!, x, [extras]) -> (y, multider)\n\nCompute the primal value y = f(x) and the (array-valued) derivative multider = f'(x) of a scalar-to-array function, overwriting multider.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_multiderivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_multiderivative","text":"value_and_multiderivative(backend, f, x, [extras]) -> (y, multider)\n\nCompute the primal value y = f(x) and the (array-valued) derivative multider = f'(x) of a scalar-to-array function.\n\n\n\n\n\n","category":"method"},{"location":"api/#Gradient","page":"API reference","title":"Gradient","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"gradient.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.gradient!-Union{Tuple{F}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.gradient!","text":"gradient!(grad, backend, f, x, [extras]) -> grad\n\nCompute the gradient grad = ∇f(x) of an array-to-scalar function, overwriting grad.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.gradient-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.gradient","text":"gradient(backend, f, x, [extras]) -> grad\n\nCompute the gradient grad = ∇f(x) of an array-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_gradient!-Union{Tuple{F}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_gradient!","text":"value_and_gradient!(grad, backend, f, x, [extras]) -> (y, grad)\n\nCompute the primal value y = f(x) and the gradient grad = ∇f(x) of an array-to-scalar function, overwriting grad.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_gradient-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_gradient","text":"value_and_gradient(backend, f, x, [extras]) -> (y, grad)\n\nCompute the primal value y = f(x) and the gradient grad = ∇f(x) of an array-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#Jacobian","page":"API reference","title":"Jacobian","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"jacobian.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.jacobian!-Union{Tuple{F}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.jacobian!","text":"jacobian!(jac, backend, f, x, [extras]) -> jac\n\nCompute the Jacobian matrix jac = ∂f(x) of an array-to-array function, overwriting jac.\n\nNotes\n\nRegardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.jacobian-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.jacobian","text":"jacobian(backend, f, x, [extras]) -> jac\n\nCompute the Jacobian matrix jac = ∂f(x) of an array-to-array function.\n\nNotes\n\nRegardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_jacobian!-Union{Tuple{F}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_jacobian!","text":"value_and_jacobian!(jac, backend, f, x, [extras]) -> (y, jac)\nvalue_and_jacobian!(y, jac, backend, f!, x, [extras]) -> (y, jac)\n\nCompute the primal value y = f(x) and the Jacobian matrix jac = ∂f(x) of an array-to-array function, overwriting jac.\n\nNotes\n\nRegardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_jacobian-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_jacobian","text":"value_and_jacobian(backend, f, x, [extras]) -> (y, jac)\n\nCompute the primal value y = f(x) and the Jacobian matrix jac = ∂f(x) of an array-to-array function.\n\nNotes\n\nRegardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#Second-derivative","page":"API reference","title":"Second derivative","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"second_derivative.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.second_derivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.second_derivative","text":"second_derivative(backend, f, x, [extras]) -> derder\n\nCompute the second derivative derder = f''(x) of a scalar-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_derivative_and_second_derivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_derivative_and_second_derivative","text":"value_derivative_and_second_derivative(backend, f, x, [extras]) -> (y, der, derder)\n\nCompute the primal value y = f(x), the derivative der = f'(x) and the second derivative derder = f''(x) of a scalar-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#Hessian","page":"API reference","title":"Hessian","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"hessian.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.hessian!-Union{Tuple{F}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.hessian!","text":"hessian!(hess, backend, f, x, [extras]) -> hess\n\nCompute the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting hess.\n\nNotes\n\nRegardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.hessian-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.hessian","text":"hessian(backend, f, x, [extras]) -> hess\n\nCompute the Hessian hess = ∇²f(x) of an array-to-scalar function.\n\nNotes\n\nRegardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_gradient_and_hessian!-Union{Tuple{F}, Tuple{AbstractArray, AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractArray, AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_gradient_and_hessian!","text":"value_gradient_and_hessian!(grad, hess, backend, f, x, [extras]) -> (y, grad, hess)\n\nCompute the primal value y = f(x), the gradient grad = ∇f(x) and the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting grad and hess.\n\nNotes\n\nRegardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_gradient_and_hessian-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_gradient_and_hessian","text":"value_gradient_and_hessian(backend, f, x, [extras]) -> (y, grad, hess)\n\nCompute the primal value y = f(x), the gradient grad = ∇f(x) and the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting grad and hess.\n\nNotes\n\nRegardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#Pushforward-(JVP)","page":"API reference","title":"Pushforward (JVP)","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"pushforward.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.pushforward!-Union{Tuple{F}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.pushforward!","text":"pushforward!(dy, backend, f, x, dx, [extras]) -> dy\n\nCompute the Jacobian-vector product dy = ∂f(x) * dx, overwriting dy if possible.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.pushforward-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Any, Any}, Tuple{ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.pushforward","text":"pushforward(backend, f, x, dx, [extras]) -> dy\n\nCompute the Jacobian-vector product dy = ∂f(x) * dx.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_pushforward!-Union{Tuple{F}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_pushforward!","text":"value_and_pushforward!(dy, backend, f, x, dx, [extras]) -> (y, dy)\nvalue_and_pushforward!(y, dy, backend, f!, x, dx, [extras]) -> (y, dy)\n\nCompute the primal value y = f(x) and the Jacobian-vector product dy = ∂f(x) * dx, overwriting dy if possible.\n\ninfo: Interface requirement\nThis is the only required implementation for a forward mode backend.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_pushforward-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Any, Any}, Tuple{ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_pushforward","text":"value_and_pushforward(backend, f, x, dx, [extras]) -> (y, dy)\n\nCompute the primal value y = f(x) and the Jacobian-vector product dy = ∂f(x) * dx.\n\n\n\n\n\n","category":"method"},{"location":"api/#Pullback-(JVP)","page":"API reference","title":"Pullback (JVP)","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"pullback.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.pullback!-Union{Tuple{F}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.pullback!","text":"pullback!(dx, backend, f, x, dy, [extras]) -> dx\n\nCompute the vector-Jacobian product dx = ∂f(x)' * dy, overwriting dx if possible.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.pullback-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Any, Any}, Tuple{ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.pullback","text":"pullback(backend, f, x, dy, [extras]) -> dx\n\nCompute the vector-Jacobian product dx = ∂f(x)' * dy.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_pullback!-Union{Tuple{F}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_pullback!","text":"value_and_pullback!(dx, backend, f, x, dy, [extras]) -> (y, dx)\nvalue_and_pullback!(y, dx, backend, f!, x, dy, [extras]) -> (y, dx)\n\nCompute the primal value y = f(x) and the vector-Jacobian product dx = ∂f(x)' * dy, overwriting dx if possible.\n\ninfo: Interface requirement\nThis is the only required implementation for a reverse mode backend.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_pullback-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Any, Any}, Tuple{ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_pullback","text":"value_and_pullback(backend, f, x, dy, [extras]) -> (y, dx)\n\nCompute the primal value y = f(x) and the vector-Jacobian product dx = ∂f(x)' * dy.\n\n\n\n\n\n","category":"method"},{"location":"api/#Hessian-vector-product-(HVP)","page":"API reference","title":"Hessian-vector product (HVP)","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"hessian_vector_product.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.gradient_and_hessian_vector_product!-Union{Tuple{F}, Tuple{AbstractArray, AbstractArray, ADTypes.AbstractADType, F, AbstractArray, AbstractArray}, Tuple{AbstractArray, AbstractArray, ADTypes.AbstractADType, F, AbstractArray, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.gradient_and_hessian_vector_product!","text":"gradient_and_hessian_vector_product!(grad, backend, hvp, backend, f, x, v, [extras]) -> (grad, hvp)\n\nCompute the gradient grad = ∇f(x) and the Hessian-vector product hvp = ∇²f(x) * v of an array-to-scalar function, overwriting grad and hvp.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.gradient_and_hessian_vector_product-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.gradient_and_hessian_vector_product","text":"gradient_and_hessian_vector_product(backend, f, x, v, [extras]) -> (grad, hvp)\n\nCompute the gradient grad = ∇f(x) and the Hessian-vector product hvp = ∇²f(x) * v of an array-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.hessian_vector_product!-Union{Tuple{F}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray, AbstractArray}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.hessian_vector_product!","text":"hessian_vector_product!(hvp, backend, f, x, v, [extras]) -> hvp\n\nCompute the Hessian-vector product hvp = ∇²f(x) * v of an array-to-scalar function, overwriting hvp.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.hessian_vector_product-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.hessian_vector_product","text":"hessian_vector_product(backend, f, x, v, [extras]) -> hvp\n\nCompute the Hessian-vector product hvp = ∇²f(x) * v of an array-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#Preparation","page":"API reference","title":"Preparation","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"prepare.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.prepare_derivative-Tuple{ADTypes.AbstractADType, Any, Number}","page":"API reference","title":"DifferentiationInterface.prepare_derivative","text":"prepare_derivative(backend, f, x) -> extras\n\nCreate an extras object that can be given to derivative operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_gradient-Tuple{ADTypes.AbstractADType, Any, AbstractArray}","page":"API reference","title":"DifferentiationInterface.prepare_gradient","text":"prepare_gradient(backend, f, x) -> extras\n\nCreate an extras object that can be given to gradient operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_hessian-Tuple{ADTypes.AbstractADType, Any, AbstractArray}","page":"API reference","title":"DifferentiationInterface.prepare_hessian","text":"prepare_hessian(backend, f, x) -> extras\n\nCreate an extras object that can be given to Hessian operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_hessian_vector_product-Tuple{ADTypes.AbstractADType, Any, AbstractArray}","page":"API reference","title":"DifferentiationInterface.prepare_hessian_vector_product","text":"prepare_hessian_vector_product(backend, f, x) -> extras\n\nCreate an extras object that can be given to Hessian-vector product operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_jacobian-Tuple{ADTypes.AbstractADType, Any, AbstractArray}","page":"API reference","title":"DifferentiationInterface.prepare_jacobian","text":"prepare_jacobian(backend, f, x) -> extras\nprepare_jacobian(backend, f!, x, y) -> extras\n\nCreate an extras object that can be given to Jacobian operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_multiderivative-Tuple{ADTypes.AbstractADType, Any, Number}","page":"API reference","title":"DifferentiationInterface.prepare_multiderivative","text":"prepare_multiderivative(backend, f, x) -> extras\nprepare_multiderivative(backend, f!, x, y) -> extras\n\nCreate an extras object that can be given to multiderivative operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_pullback-Tuple{ADTypes.AbstractADType, Any, Any}","page":"API reference","title":"DifferentiationInterface.prepare_pullback","text":"prepare_pullback(backend, f, x) -> extras\nprepare_pullback(backend, f!, x, y) -> extras\n\nCreate an extras object that can be given to pullback operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_pushforward-Tuple{ADTypes.AbstractADType, Any, Any}","page":"API reference","title":"DifferentiationInterface.prepare_pushforward","text":"prepare_pushforward(backend, f, x) -> extras\nprepare_pushforward(backend, f!, x, y) -> extras\n\nCreate an extras object that can be given to pushforward operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_second_derivative-Tuple{ADTypes.AbstractADType, Any, Number}","page":"API reference","title":"DifferentiationInterface.prepare_second_derivative","text":"prepare_second_derivative(backend, f, x) -> extras\n\nCreate an extras object that can be given to second derivative operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#Backend-queries","page":"API reference","title":"Backend queries","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"backends.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.available-Tuple{ADTypes.AbstractADType}","page":"API reference","title":"DifferentiationInterface.available","text":"available(backend)\n\nCheck whether backend is available by trying a scalar-to-scalar derivative. Might take a while due to compilation time.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.supports_hessian-Tuple{ADTypes.AbstractADType}","page":"API reference","title":"DifferentiationInterface.supports_hessian","text":"supports_hessian(backend)\n\nCheck whether backend supports second order differentiation by trying a hessian. Might take a while due to compilation time.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.supports_mutation-Tuple{ADTypes.AbstractADType}","page":"API reference","title":"DifferentiationInterface.supports_mutation","text":"supports_mutation(backend)\n\nCheck whether backend supports differentiation of mutating functions by trying a jacobian. Might take a while due to compilation time.\n\n\n\n\n\n","category":"method"},{"location":"api/#Internals","page":"API reference","title":"Internals","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"This is not part of the public API.","category":"page"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPublic = false","category":"page"},{"location":"api/#DifferentiationInterface.AutoZeroForward","page":"API reference","title":"DifferentiationInterface.AutoZeroForward","text":"AutoZeroForward <: ADTypes.AbstractForwardMode\n\nTrivial backend that sets all derivatives to zero. Used in testing and benchmarking.\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.AutoZeroReverse","page":"API reference","title":"DifferentiationInterface.AutoZeroReverse","text":"AutoZeroReverse <: ADTypes.AbstractReverseMode\n\nTrivial backend that sets all derivatives to zero. Used in testing and benchmarking.\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.ForwardMode","page":"API reference","title":"DifferentiationInterface.ForwardMode","text":"ForwardMode\n\nTrait identifying forward mode (and finite differences) first-order AD backends.\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.MutationNotSupported","page":"API reference","title":"DifferentiationInterface.MutationNotSupported","text":"MutationNotSupported\n\nTrait identifying backends that do not support mutating functions f!(y, x).\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.MutationSupported","page":"API reference","title":"DifferentiationInterface.MutationSupported","text":"MutationSupported\n\nTrait identifying backends that support mutating functions f!(y, x).\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.ReverseMode","page":"API reference","title":"DifferentiationInterface.ReverseMode","text":"ReverseMode\n\nTrait identifying reverse mode first-order AD backends.\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.SymbolicMode","page":"API reference","title":"DifferentiationInterface.SymbolicMode","text":"SymbolicMode\n\nTrait identifying symbolic first-order AD backends. Their fallback structure is different from the rest.\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.basisarray-Tuple{ADTypes.AbstractADType, AbstractArray, Any}","page":"API reference","title":"DifferentiationInterface.basisarray","text":"basisarray(backend, a::AbstractArray, i::CartesianIndex)\n\nConstruct the i-th stardard basis array in the vector space of a with element type eltype(a).\n\nNote\n\nIf an AD backend benefits from a more specialized basis array implementation, this function can be extended on the backend type.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.mode","page":"API reference","title":"DifferentiationInterface.mode","text":"mode(backend)\n\nReturn the AD mode of a backend in a statically predictable way.\n\nThis function must be overloaded for backends that support both forward and reverse.\n\nWe classify finite differences as a forward mode.\n\n\n\n\n\n","category":"function"},{"location":"api/#DifferentiationInterface.mutation_behavior-Tuple{ADTypes.AbstractADType}","page":"API reference","title":"DifferentiationInterface.mutation_behavior","text":"mutation_behavior(backend)\n\nReturn the mutation behavior of a backend in a statically predictable way.\n\nNote\n\nThis is different from supports_mutation, which performs an actual call to jacobian!.\n\n\n\n\n\n","category":"method"},{"location":"api/#Testing","page":"API reference","title":"Testing","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"This is not part of the public API.","category":"page"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationTest]","category":"page"},{"location":"api/#DifferentiationInterface.DifferentiationTest","page":"API reference","title":"DifferentiationInterface.DifferentiationTest","text":"DifferentiationInterface.DifferentiationTest\n\nTesting utilities for DifferentiationInterface.\n\n\n\n\n\n","category":"module"},{"location":"api/#DifferentiationInterface.DifferentiationTest.BenchmarkData","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.BenchmarkData","text":"BenchmarkData\n\nFields\n\nbackend::Vector\noperator::Vector\nfunc::Vector\nmutating::Vector\ninput_type::Vector\noutput_type::Vector\ninput_size::Vector\noutput_size::Vector\nsamples::Vector\ntime::Vector\nbytes::Vector\nallocs::Vector\ncompile_fraction::Vector\ngc_fraction::Vector\nevals::Vector\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.DifferentiationTest.Scenario","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.Scenario","text":"Scenario\n\nStore a testing scenario composed of a function and its input + output + tangents.\n\nFields\n\nf::Any: function\nmutating::Bool: mutation\nx::Union{Number, AbstractArray}: input\ny::Union{Number, AbstractArray}: output\ndx::Union{Number, AbstractArray}: pushforward seed\ndy::Union{Number, AbstractArray}: pullback seed\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.DifferentiationTest.backend_string-Tuple{ADTypes.AbstractADType}","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.backend_string","text":"backend_string(backend)\n\nReturn a shorter string than the full object printing from ADTypes.jl. Might be ambiguous.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.DifferentiationTest.test_operators","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.test_operators","text":"test_operators(\n backends, [operators, scenarios];\n correctness, type_stability, benchmark, allocations,\n input_type, output_type,\n first_order, second_order, allocating, mutating,\n excluded,\n)\n\nCross-test a list of backends for a list of operators on a list of scenarios.\n\nReturn nothing, except when benchmark=true.\n\nDefault arguments\n\noperators: defaults to all of them\nscenarios: defaults to a set of default scenarios\n\nKeyword arguments\n\ncorrectness=true: whether to compare the differentiation results with those given by ForwardDiff.jl\ntype_stability=true: whether to check type stability with JET.jl\ncall_count=false: whether to check that the function is called the right number of times\nbenchmark=false: whether to run and return a benchmark suite with Chairmarks.jl\nallocations=false: whether to check that the benchmarks are allocation-free\ninput_type=Any: restrict scenario inputs to subtypes of this\noutput_type=Any: restrict scenario outputs to subtypes of this\nfirst_order=true: consider first order operators\nsecond_order=true: consider second order operators\nallocating=true: consider operators for allocating functions\nmutating=true: consider operators for mutating functions\nexcluded=Symbol[]: list of excluded operators\n\n\n\n\n\n","category":"function"},{"location":"api/#DifferentiationInterface.DifferentiationTest.test_operators-Tuple{ADTypes.AbstractADType, Vararg{Any}}","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.test_operators","text":"test_operators(\n backend::ADTypes.AbstractADType,\n args...;\n kwargs...\n) -> Union{Nothing, BenchmarkData}\n\n\nShortcut for a single backend.\n\n\n\n\n\n","category":"method"},{"location":"api/","page":"API reference","title":"API reference","text":"","category":"page"},{"location":"getting_started/#Getting-started","page":"Getting started","title":"Getting started","text":"","category":"section"},{"location":"getting_started/#operators","page":"Getting started","title":"Operators","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Depending on the type of input and output, differentiation operators can have various names. Most backends have custom implementations, which we reuse if possible.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"We choose the following terminology for the operators we provide:","category":"page"},{"location":"getting_started/#First-order-differentiation","page":"Getting started","title":"First order differentiation","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":" scalar output array output\nscalar input derivative multiderivative\narray input gradient jacobian","category":"page"},{"location":"getting_started/#Second-order-differentiation","page":"Getting started","title":"Second order differentiation","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":" scalar output array output\nscalar input second_derivative not implemented\narray input hessian not implemented","category":"page"},{"location":"getting_started/#Variants","page":"Getting started","title":"Variants","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Whenever it makes sense, four variants of the same operator are defined:","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Operator allocating mutating allocating with primal mutating with primal\nDerivative derivative N/A value_and_derivative N/A\nMultiderivative multiderivative multiderivative! value_and_multiderivative value_and_multiderivative!\nGradient gradient gradient! value_and_gradient value_and_gradient!\nJacobian jacobian jacobian! value_and_jacobian value_and_jacobian!\nSecond derivative second_derivative N/A value_derivative_and_second_derivative N/A\nHessian hessian hessian! value_gradient_and_hessian value_gradient_and_hessian!","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Note that scalar outputs can't be mutated, which is why derivative and second_derivative do not have mutating variants.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"For advanced users, lower-level operators are also exposed:","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Operator allocating mutating allocating with primal mutating with primal\nPushforward (JVP) pushforward pushforward! value_and_pushforward value_and_pushforward!\nPullback (VJP) pullback pullback! value_and_pullback value_and_pullback!\nHessian-vector product (HVP) hessian_vector_product hessian_vector_product! gradient_and_hessian_vector_product gradient_and_hessian_vector_product!","category":"page"},{"location":"getting_started/#Preparation","page":"Getting started","title":"Preparation","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"In many cases, automatic differentiation can be accelerated if the function has been run at least once (e.g. to record a tape) and if some cache objects are provided. This is a backend-specific procedure, but we expose a common syntax to achieve it.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Operator preparation function\nDerivative prepare_derivative\nMultiderivative prepare_multiderivative\nGradient prepare_gradient\nJacobian prepare_jacobian\nSecond derivative prepare_second_derivative\nHessian prepare_hessian\nPushforward (JVP) prepare_pushforward\nPullback (VJP) prepare_pullback\nHessian-vector product (HVP) prepare_hessian_vector_product","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"If you run prepare_operator(backend, f, x), it will create an object called extras containing the necessary information to speed up operator and its variants. This information is specific to backend and f, as well as the type and size of the input x, but it should work with different values of x.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"You can then call operator(backend, f, similar_x, extras), which should be faster than operator(backend, f, similar_x). This is especially worth it if you plan to call operator several times in similar settings: you can think of it as a warm up.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"By default, all the preparation functions return nothing. We do not make any guarantees on their implementation for each backend, or on the performance gains that can be expected.","category":"page"},{"location":"getting_started/#Mutating-functions","page":"Getting started","title":"Mutating functions","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"In addition to allocating functions f(x) = y, some backends also support mutating functions f!(y, x) = nothing whenever the output is an array. Beware that the function f! must return nothing!. Since f! operates in-place and the primal is computed every time, only four operators are defined:","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Operator mutating with primal\nMultiderivative value_and_multiderivative!\nJacobian value_and_jacobian!\nPushforward (JVP) value_and_pushforward!\nPullback (VJP) value_and_pullback!","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Furthermore, the preparation function takes an additional argument: prepare_operator(backend, f!, x, y).","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Check out the list of backends that support mutating functions.","category":"page"},{"location":"getting_started/#Multiple-inputs/outputs","page":"Getting started","title":"Multiple inputs/outputs","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Restricting the API to one input and one output has many coding advantages, but it is not very flexible. If you need more than that, use ComponentArrays.jl to wrap several objects inside a single ComponentVector.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"","category":"page"},{"location":"developer/#For-AD-developers","page":"For AD developers","title":"For AD developers","text":"","category":"section"},{"location":"developer/#Backend-requirements","page":"For AD developers","title":"Backend requirements","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"Every operator can be implemented from either of these two primitives:","category":"page"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"the pushforward (in forward mode), computing a Jacobian-vector product\nthe pullback (in reverse mode), computing a vector-Jacobian product","category":"page"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"The only requirement for a backend is therefore to implement either value_and_pushforward! or value_and_pullback!, from which the rest of the operators can be deduced. We provide a standard series of fallbacks, but we leave it to each backend to redefine as many of the utilities as necessary to achieve optimal performance.","category":"page"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"Every backend we support corresponds to a package extension of DifferentiationInterface.jl (located in the ext subfolder). Advanced users are welcome to code more backends and submit pull requests!","category":"page"},{"location":"developer/#Fallback-call-structure","page":"For AD developers","title":"Fallback call structure","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"note: Edge labels\nNon-labeled edges in the following graphs correspond to single function calls.Edge labels correspond to the amount of function calls when applying operators to a function f mathbbR^n rightarrow mathbbR^m.","category":"page"},{"location":"developer/#Forward-mode,-allocating-functions","page":"For AD developers","title":"Forward mode, allocating functions","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"flowchart LR\n subgraph Derivative\n value_and_derivative\n derivative\n end\n\n value_and_derivative --> value_and_pushforward\n derivative --> pushforward\n \n subgraph Multiderivative\n value_and_multiderivative!\n value_and_multiderivative\n multiderivative!\n multiderivative\n end\n\n value_and_multiderivative! --> value_and_pushforward!\n value_and_multiderivative --> value_and_pushforward\n multiderivative! --> pushforward!\n multiderivative --> pushforward\n\n subgraph Gradient\n value_and_gradient --> value_and_gradient!\n gradient! --> value_and_gradient!\n gradient --> value_and_gradient\n end\n\n value_and_gradient! --> |n|pushforward\n\n subgraph Jacobian\n value_and_jacobian --> value_and_jacobian!\n jacobian! --> value_and_jacobian!\n jacobian --> value_and_jacobian\n end\n\n value_and_jacobian! --> |n|pushforward!\n\n subgraph Pushforward\n value_and_pushforward --> value_and_pushforward!\n pushforward! --> value_and_pushforward!\n pushforward --> value_and_pushforward\n end","category":"page"},{"location":"developer/#Forward-mode,-mutating-functions","page":"For AD developers","title":"Forward mode, mutating functions","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"flowchart LR\n subgraph Multiderivative\n value_and_multiderivative!\n end\n\n value_and_multiderivative! --> value_and_pushforward!\n\n subgraph Jacobian\n value_and_jacobian!\n end\n\n value_and_jacobian! --> |n|value_and_pushforward!\n\n subgraph Pushforward\n value_and_pushforward!\n end","category":"page"},{"location":"developer/#Reverse-mode,-allocating-functions","page":"For AD developers","title":"Reverse mode, allocating functions","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"flowchart LR\n subgraph Derivative\n value_and_derivative\n derivative\n end\n\n value_and_derivative --> value_and_pullback\n derivative --> pullback\n \n subgraph Multiderivative\n value_and_multiderivative --> value_and_multiderivative!\n multiderivative! --> value_and_multiderivative!\n multiderivative --> value_and_multiderivative\n end\n\n value_and_multiderivative! --> |m|pullback\n\n subgraph Gradient\n value_and_gradient!\n value_and_gradient\n gradient!\n gradient \n end\n\n value_and_gradient! --> value_and_pullback!\n value_and_gradient --> value_and_pullback\n gradient! --> pullback!\n gradient --> pullback\n\n subgraph Jacobian\n value_and_jacobian --> value_and_jacobian!\n jacobian! --> value_and_jacobian!\n jacobian --> value_and_jacobian\n end\n\n value_and_jacobian! --> |m|pullback!\n\n subgraph Pullback\n value_and_pullback --> value_and_pullback!\n pullback! --> value_and_pullback!\n pullback --> value_and_pullback\n end","category":"page"},{"location":"developer/#Reverse-mode,-mutating-functions","page":"For AD developers","title":"Reverse mode, mutating functions","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"flowchart LR\n subgraph Multiderivative\n value_and_multiderivative!\n end\n\n value_and_multiderivative! --> |m|value_and_pullback!\n\n subgraph Jacobian\n value_and_jacobian!\n end\n\n value_and_jacobian! --> |m|value_and_pullback!\n\n subgraph Pullback\n value_and_pullback!\n end","category":"page"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"CollapsedDocStrings = true","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"using ADTypes, DifferentiationInterface\nusing DifferentiationInterface.DifferentiationTest: backend_string\nimport Markdown\nimport Chairmarks, DataFrames\nimport Enzyme, FastDifferentiation, FiniteDiff, ForwardDiff, PolyesterForwardDiff, ReverseDiff, Tracker, Zygote\n\nfunction all_backends()\n return [\n AutoDiffractor(),\n AutoEnzyme(Enzyme.Forward),\n AutoEnzyme(Enzyme.Reverse),\n AutoFastDifferentiation(),\n AutoFiniteDiff(),\n AutoForwardDiff(),\n AutoPolyesterForwardDiff(; chunksize=2),\n AutoReverseDiff(),\n AutoTracker(),\n AutoZygote(),\n ]\nend","category":"page"},{"location":"backends/#Backends","page":"Backends","title":"Backends","text":"","category":"section"},{"location":"backends/#Types","page":"Backends","title":"Types","text":"","category":"section"},{"location":"backends/","page":"Backends","title":"Backends","text":"Most backend choices are defined by ADTypes.jl.","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"warning: Warning\nOnly the backends listed here are supported by DifferentiationInterface.jl, even though ADTypes.jl defines more.","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"AutoChainRules\nAutoDiffractor\nAutoEnzyme\nAutoForwardDiff\nAutoForwardDiff()\nAutoFiniteDiff\nAutoPolyesterForwardDiff\nAutoPolyesterForwardDiff()\nAutoReverseDiff\nAutoTracker\nAutoZygote","category":"page"},{"location":"backends/#ADTypes.AutoChainRules","page":"Backends","title":"ADTypes.AutoChainRules","text":"AutoChainRules{RC}\n\nChooses any AD library based on ChainRulesCore.jl, given an appropriate RuleConfig object.\n\nFields\n\nruleconfig::RC\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoDiffractor","page":"Backends","title":"ADTypes.AutoDiffractor","text":"AutoDiffractor\n\nChooses Diffractor.jl.\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoEnzyme","page":"Backends","title":"ADTypes.AutoEnzyme","text":"AutoEnzyme(Enzyme.Forward)\nAutoEnzyme(Enzyme.Reverse)\n\nConstruct a forward or reverse mode AutoEnzyme backend.\n\n\n\n\n\nAutoEnzyme{M}\n\nChooses Enzyme.jl.\n\nFields\n\nmode::M = nothing\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoForwardDiff","page":"Backends","title":"ADTypes.AutoForwardDiff","text":"AutoForwardDiff{chunksize,T}\n\nChooses ForwardDiff.jl.\n\nFields\n\ntag::T\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoForwardDiff-Tuple{}","page":"Backends","title":"ADTypes.AutoForwardDiff","text":"AutoForwardDiff(; chunksize = nothing, tag = nothing)\n\nConstructor.\n\n\n\n\n\n","category":"method"},{"location":"backends/#ADTypes.AutoFiniteDiff","page":"Backends","title":"ADTypes.AutoFiniteDiff","text":"AutoFiniteDiff{T1,T2,T3}\n\nChooses FiniteDiff.jl.\n\nFields\n\nfdtype::T1 = Val(:forward)\nfdjtype::T2 = fdtype\nfdhtype::T3 = Val(:hcentral)\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoPolyesterForwardDiff","page":"Backends","title":"ADTypes.AutoPolyesterForwardDiff","text":"AutoPolyesterForwardDiff{chunksize}\n\nChooses PolyesterForwardDiff.jl.\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoPolyesterForwardDiff-Tuple{}","page":"Backends","title":"ADTypes.AutoPolyesterForwardDiff","text":"AutoPolyesterForwardDiff(; chunksize = nothing)\n\nConstructor.\n\n\n\n\n\n","category":"method"},{"location":"backends/#ADTypes.AutoReverseDiff","page":"Backends","title":"ADTypes.AutoReverseDiff","text":"AutoReverseDiff\n\nChooses ReverseDiff.jl.\n\nFields\n\ncompile::Bool = false\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoTracker","page":"Backends","title":"ADTypes.AutoTracker","text":"AutoTracker\n\nChooses Tracker.jl.\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoZygote","page":"Backends","title":"ADTypes.AutoZygote","text":"AutoZygote\n\nChooses Zygote.jl.\n\n\n\n\n\n","category":"type"},{"location":"backends/","page":"Backends","title":"Backends","text":"We also provide a few of our own:","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"AutoFastDifferentiation\nSecondOrder","category":"page"},{"location":"backends/#DifferentiationInterface.AutoFastDifferentiation","page":"Backends","title":"DifferentiationInterface.AutoFastDifferentiation","text":"AutoFastDifferentiation\n\nChooses FastDifferentiation.jl.\n\n\n\n\n\n","category":"type"},{"location":"backends/#DifferentiationInterface.SecondOrder","page":"Backends","title":"DifferentiationInterface.SecondOrder","text":"SecondOrder\n\nCombination of two backends for second-order differentiation.\n\nFields\n\ninner::ADTypes.AbstractADType: backend for the inner differentiation\nouter::ADTypes.AbstractADType: backend for the outer differentiation\n\n\n\n\n\n","category":"type"},{"location":"backends/#Availability","page":"Backends","title":"Availability","text":"","category":"section"},{"location":"backends/","page":"Backends","title":"Backends","text":"You can use available to verify whether a given backend is loaded, like we did below:","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"header = \"| Backend | available |\" # hide\nsubheader = \"|---|---|\" # hide\nrows = map(all_backends()) do backend # hide\n \"| `$(backend_string(backend))` | $(available(backend) ? '✓' : '✗') |\" # hide\nend # hide\nMarkdown.parse(join(vcat(header, subheader, rows...), \"\\n\")) # hide","category":"page"},{"location":"backends/#backend_mutation_behavior","page":"Backends","title":"Mutation support","text":"","category":"section"},{"location":"backends/","page":"Backends","title":"Backends","text":"All backends are compatible with allocating functions f(x) = y. Only some are compatible with mutating functions f!(y, x) = nothing. You can use supports_mutation to check that feature, like we did below:","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"header = \"| Backend | mutation |\" # hide\nsubheader = \"|---|---|\" # hide\nrows = map(all_backends()) do backend # hide\n \"| `$(backend_string(backend))` | $(supports_mutation(backend) ? '✓' : '✗') |\" # hide\nend # hide\nMarkdown.parse(join(vcat(header, subheader, rows...), \"\\n\")) # hide","category":"page"},{"location":"backends/#Second-order","page":"Backends","title":"Second order","text":"","category":"section"},{"location":"backends/","page":"Backends","title":"Backends","text":"For second-order differentiation, you can either","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"combine a pair (backend_inner, backend_outer) of inner and outer backends into a SecondOrder object\nuse a single backend backend, which amounts to backend_inner = backend_outer = backend","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"In Hessian computations, the most efficient combination is often forward-over-reverse, i.e. SecondOrder(reverse_backend, forward_backend).","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"info: Info\nMany backend combinations will fail for second order. Some because of our implementation, and some because the outer backend cannot differentiate through code generated by the inner backend.","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"You can use supports_hessian to find working combinations, like we did below:","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"header = \"| Inner \\\\ Outer |\" # hide\nsubheader = \"|---|\" # hide\nfor bo in all_backends() # hide\n global header *= \" $(backend_string(bo)) |\" # hide\n global subheader *= \"---|\" # hide\nend # hide\nrows = map(all_backends()) do bi # hide\n @info \"Generating hessian row for $(backend_string(bi))\" # hide\n row = \"| $(backend_string(bi)) |\" # hide\n for bo in all_backends() # hide\n row *= \" $(supports_hessian(SecondOrder(bi, bo)) ? '✓' : '✗') |\" # hide\n end # hide\n row # hide\nend # hide\nMarkdown.parse(join(vcat(header, subheader, rows...), \"\\n\") * \"\\n\") # hide","category":"page"},{"location":"backends/#Package-extensions","page":"Backends","title":"Package extensions","text":"","category":"section"},{"location":"backends/","page":"Backends","title":"Backends","text":"CurrentModule = DifferentiationInterface","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"Backend-specific extension content is not part of the public API.","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"Modules = [\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceChainRulesCoreExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceDiffractorExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceEnzymeExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceFastDifferentiationExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceFiniteDiffExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceForwardDiffExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfacePolyesterForwardDiffExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceReverseDiffExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceTrackerExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceZygoteExt)\n]\nFilter = t -> !(t <: ADTypes.AbstractADType)","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"","category":"page"},{"location":"","page":"Home","title":"Home","text":"EditURL = \"https://github.com/gdalle/DifferentiationInterface.jl/blob/main/README.md\"","category":"page"},{"location":"#DifferentiationInterface","page":"Home","title":"DifferentiationInterface","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"(Image: Dev) (Image: Build Status) (Image: Coverage) (Image: Code Style: Blue)","category":"page"},{"location":"","page":"Home","title":"Home","text":"An interface to various automatic differentiation backends in Julia.","category":"page"},{"location":"#Goal","page":"Home","title":"Goal","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This package provides a backend-agnostic syntax to differentiate functions of the following types:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Allocating: f(x) = y where x and y can be real numbers or abstract arrays\nMutating: f!(y, x) = nothing where y is an abstract array and x can be a real number or an abstract array","category":"page"},{"location":"#Compatibility","page":"Home","title":"Compatibility","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"We support some of the backends defined by ADTypes.jl:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Backend Object\nChainRulesCore.jl AutoChainRules(ruleconfig)\nDiffractor.jl AutoDiffractor()\nEnzyme.jl AutoEnzyme(Enzyme.Forward) or AutoEnzyme(Enzyme.Reverse)\nFiniteDiff.jl AutoFiniteDiff()\nForwardDiff.jl AutoForwardDiff()\nPolyesterForwardDiff.jl AutoPolyesterForwardDiff(; chunksize)\nReverseDiff.jl AutoReverseDiff()\nTracker.jl AutoTracker()\nZygote.jl AutoZygote()","category":"page"},{"location":"","page":"Home","title":"Home","text":"We also provide additional backends:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Backend Object\nFastDifferentiation.jl AutoFastDifferentiation()","category":"page"},{"location":"#Example","page":"Home","title":"Example","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Setup:","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> import ADTypes, ForwardDiff\n\njulia> using DifferentiationInterface\n\njulia> backend = ADTypes.AutoForwardDiff();\n\njulia> f(x) = sum(abs2, x);","category":"page"},{"location":"","page":"Home","title":"Home","text":"Out-of-place gradient:","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> value_and_gradient(backend, f, [1., 2., 3.])\n(14.0, [2.0, 4.0, 6.0])","category":"page"},{"location":"","page":"Home","title":"Home","text":"In-place gradient:","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> grad = zeros(3);\n\njulia> value_and_gradient!(grad, backend, f, [1., 2., 3.])\n(14.0, [2.0, 4.0, 6.0])\n\njulia> grad\n3-element Vector{Float64}:\n 2.0\n 4.0\n 6.0","category":"page"},{"location":"#Related-packages","page":"Home","title":"Related packages","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"AbstractDifferentiation.jl is the original inspiration for DifferentiationInterface.jl.\nAutoDiffOperators.jl is an attempt to bridge ADTypes.jl with AbstractDifferentiation.jl.","category":"page"},{"location":"#Roadmap","page":"Home","title":"Roadmap","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Goals for future releases:","category":"page"},{"location":"","page":"Home","title":"Home","text":"optimize performance for each backend\ndefine user-facing functions to test and benchmark backends against each other","category":"page"},{"location":"","page":"Home","title":"Home","text":"","category":"page"}] +[{"location":"api/","page":"API reference","title":"API reference","text":"CurrentModule = DifferentiationInterface\nCollapsedDocStrings = true","category":"page"},{"location":"api/#API-reference","page":"API reference","title":"API reference","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"DifferentiationInterface","category":"page"},{"location":"api/#DifferentiationInterface.DifferentiationInterface","page":"API reference","title":"DifferentiationInterface.DifferentiationInterface","text":"DifferentiationInterface\n\nAn interface to various automatic differentiation backends in Julia.\n\nExports\n\nAutoFastDifferentiation\nSecondOrder\navailable\nderivative\ngradient\ngradient!\ngradient_and_hessian_vector_product\ngradient_and_hessian_vector_product!\nhessian\nhessian!\nhessian_vector_product\nhessian_vector_product!\njacobian\njacobian!\nmultiderivative\nmultiderivative!\nprepare_derivative\nprepare_gradient\nprepare_hessian\nprepare_hessian_vector_product\nprepare_jacobian\nprepare_multiderivative\nprepare_pullback\nprepare_pushforward\nprepare_second_derivative\npullback\npullback!\npushforward\npushforward!\nsecond_derivative\nsupports_hessian\nsupports_mutation\nvalue_and_derivative\nvalue_and_gradient\nvalue_and_gradient!\nvalue_and_jacobian\nvalue_and_jacobian!\nvalue_and_multiderivative\nvalue_and_multiderivative!\nvalue_and_pullback\nvalue_and_pullback!\nvalue_and_pushforward\nvalue_and_pushforward!\nvalue_derivative_and_second_derivative\nvalue_gradient_and_hessian\nvalue_gradient_and_hessian!\n\n\n\n\n\n","category":"module"},{"location":"api/#Derivative","page":"API reference","title":"Derivative","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"src/derivative.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.derivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.derivative","text":"derivative(backend, f, x, [extras]) -> der\n\nCompute the derivative der = f'(x) of a scalar-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_derivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_derivative","text":"value_and_derivative(backend, f, x, [extras]) -> (y, der)\n\nCompute the primal value y = f(x) and the derivative der = f'(x) of a scalar-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#Multiderivative","page":"API reference","title":"Multiderivative","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"multiderivative.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.multiderivative!-Union{Tuple{F}, Tuple{AbstractArray, ADTypes.AbstractADType, F, Number}, Tuple{AbstractArray, ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.multiderivative!","text":"multiderivative!(multider, backend, f, x, [extras]) -> multider\n\nCompute the (array-valued) derivative multider = f'(x) of a scalar-to-array function, overwriting multider.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.multiderivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.multiderivative","text":"multiderivative(backend, f, x, [extras]) -> multider\n\nCompute the (array-valued) derivative multider = f'(x) of a scalar-to-array function.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_multiderivative!-Union{Tuple{F}, Tuple{AbstractArray, ADTypes.AbstractADType, F, Number}, Tuple{AbstractArray, ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_multiderivative!","text":"value_and_multiderivative!(multider, backend, f, x, [extras]) -> (y, multider)\nvalue_and_multiderivative!(y, multider, backend, f!, x, [extras]) -> (y, multider)\n\nCompute the primal value y = f(x) and the (array-valued) derivative multider = f'(x) of a scalar-to-array function, overwriting multider.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_multiderivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_multiderivative","text":"value_and_multiderivative(backend, f, x, [extras]) -> (y, multider)\n\nCompute the primal value y = f(x) and the (array-valued) derivative multider = f'(x) of a scalar-to-array function.\n\n\n\n\n\n","category":"method"},{"location":"api/#Gradient","page":"API reference","title":"Gradient","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"gradient.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.gradient!-Union{Tuple{F}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.gradient!","text":"gradient!(grad, backend, f, x, [extras]) -> grad\n\nCompute the gradient grad = ∇f(x) of an array-to-scalar function, overwriting grad.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.gradient-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.gradient","text":"gradient(backend, f, x, [extras]) -> grad\n\nCompute the gradient grad = ∇f(x) of an array-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_gradient!-Union{Tuple{F}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_gradient!","text":"value_and_gradient!(grad, backend, f, x, [extras]) -> (y, grad)\n\nCompute the primal value y = f(x) and the gradient grad = ∇f(x) of an array-to-scalar function, overwriting grad.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_gradient-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_gradient","text":"value_and_gradient(backend, f, x, [extras]) -> (y, grad)\n\nCompute the primal value y = f(x) and the gradient grad = ∇f(x) of an array-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#Jacobian","page":"API reference","title":"Jacobian","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"jacobian.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.jacobian!-Union{Tuple{F}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.jacobian!","text":"jacobian!(jac, backend, f, x, [extras]) -> jac\n\nCompute the Jacobian matrix jac = ∂f(x) of an array-to-array function, overwriting jac.\n\nNotes\n\nRegardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.jacobian-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.jacobian","text":"jacobian(backend, f, x, [extras]) -> jac\n\nCompute the Jacobian matrix jac = ∂f(x) of an array-to-array function.\n\nNotes\n\nRegardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_jacobian!-Union{Tuple{F}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_jacobian!","text":"value_and_jacobian!(jac, backend, f, x, [extras]) -> (y, jac)\nvalue_and_jacobian!(y, jac, backend, f!, x, [extras]) -> (y, jac)\n\nCompute the primal value y = f(x) and the Jacobian matrix jac = ∂f(x) of an array-to-array function, overwriting jac.\n\nNotes\n\nRegardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_jacobian-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_jacobian","text":"value_and_jacobian(backend, f, x, [extras]) -> (y, jac)\n\nCompute the primal value y = f(x) and the Jacobian matrix jac = ∂f(x) of an array-to-array function.\n\nNotes\n\nRegardless of the shape of x and y, if x has length n and y has length m, then jac is expected to be a m × n matrix. This function acts as if the input and output had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#Second-derivative","page":"API reference","title":"Second derivative","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"second_derivative.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.second_derivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.second_derivative","text":"second_derivative(backend, f, x, [extras]) -> derder\n\nCompute the second derivative derder = f''(x) of a scalar-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_derivative_and_second_derivative-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Number}, Tuple{ADTypes.AbstractADType, F, Number, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_derivative_and_second_derivative","text":"value_derivative_and_second_derivative(backend, f, x, [extras]) -> (y, der, derder)\n\nCompute the primal value y = f(x), the derivative der = f'(x) and the second derivative derder = f''(x) of a scalar-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#Hessian","page":"API reference","title":"Hessian","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"hessian.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.hessian!-Union{Tuple{F}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.hessian!","text":"hessian!(hess, backend, f, x, [extras]) -> hess\n\nCompute the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting hess.\n\nNotes\n\nRegardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.hessian-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.hessian","text":"hessian(backend, f, x, [extras]) -> hess\n\nCompute the Hessian hess = ∇²f(x) of an array-to-scalar function.\n\nNotes\n\nRegardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_gradient_and_hessian!-Union{Tuple{F}, Tuple{AbstractArray, AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray}, Tuple{AbstractArray, AbstractMatrix, ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_gradient_and_hessian!","text":"value_gradient_and_hessian!(grad, hess, backend, f, x, [extras]) -> (y, grad, hess)\n\nCompute the primal value y = f(x), the gradient grad = ∇f(x) and the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting grad and hess.\n\nNotes\n\nRegardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_gradient_and_hessian-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_gradient_and_hessian","text":"value_gradient_and_hessian(backend, f, x, [extras]) -> (y, grad, hess)\n\nCompute the primal value y = f(x), the gradient grad = ∇f(x) and the Hessian hess = ∇²f(x) of an array-to-scalar function, overwriting grad and hess.\n\nNotes\n\nRegardless of the shape of x, if x has length n, then hess is expected to be a n × n matrix. This function acts as if the input had been flattened with vec.\n\n\n\n\n\n","category":"method"},{"location":"api/#Pushforward-(JVP)","page":"API reference","title":"Pushforward (JVP)","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"pushforward.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.pushforward!-Union{Tuple{F}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.pushforward!","text":"pushforward!(dy, backend, f, x, dx, [extras]) -> dy\n\nCompute the Jacobian-vector product dy = ∂f(x) * dx, overwriting dy if possible.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.pushforward-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Any, Any}, Tuple{ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.pushforward","text":"pushforward(backend, f, x, dx, [extras]) -> dy\n\nCompute the Jacobian-vector product dy = ∂f(x) * dx.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_pushforward!-Union{Tuple{F}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_pushforward!","text":"value_and_pushforward!(dy, backend, f, x, dx, [extras]) -> (y, dy)\nvalue_and_pushforward!(y, dy, backend, f!, x, dx, [extras]) -> (y, dy)\n\nCompute the primal value y = f(x) and the Jacobian-vector product dy = ∂f(x) * dx, overwriting dy if possible.\n\ninfo: Interface requirement\nThis is the only required implementation for a forward mode backend.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_pushforward-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Any, Any}, Tuple{ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_pushforward","text":"value_and_pushforward(backend, f, x, dx, [extras]) -> (y, dy)\n\nCompute the primal value y = f(x) and the Jacobian-vector product dy = ∂f(x) * dx.\n\n\n\n\n\n","category":"method"},{"location":"api/#Pullback-(JVP)","page":"API reference","title":"Pullback (JVP)","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"pullback.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.pullback!-Union{Tuple{F}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.pullback!","text":"pullback!(dx, backend, f, x, dy, [extras]) -> dx\n\nCompute the vector-Jacobian product dx = ∂f(x)' * dy, overwriting dx if possible.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.pullback-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Any, Any}, Tuple{ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.pullback","text":"pullback(backend, f, x, dy, [extras]) -> dx\n\nCompute the vector-Jacobian product dx = ∂f(x)' * dy.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_pullback!-Union{Tuple{F}, Tuple{Any, ADTypes.AbstractADType, F, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_pullback!","text":"value_and_pullback!(dx, backend, f, x, dy, [extras]) -> (y, dx)\nvalue_and_pullback!(y, dx, backend, f!, x, dy, [extras]) -> (y, dx)\n\nCompute the primal value y = f(x) and the vector-Jacobian product dx = ∂f(x)' * dy, overwriting dx if possible.\n\ninfo: Interface requirement\nThis is the only required implementation for a reverse mode backend.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.value_and_pullback-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, Any, Any}, Tuple{ADTypes.AbstractADType, F, Any, Any, Any}} where F","page":"API reference","title":"DifferentiationInterface.value_and_pullback","text":"value_and_pullback(backend, f, x, dy, [extras]) -> (y, dx)\n\nCompute the primal value y = f(x) and the vector-Jacobian product dx = ∂f(x)' * dy.\n\n\n\n\n\n","category":"method"},{"location":"api/#Hessian-vector-product-(HVP)","page":"API reference","title":"Hessian-vector product (HVP)","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"hessian_vector_product.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.gradient_and_hessian_vector_product!-Union{Tuple{F}, Tuple{AbstractArray, AbstractArray, ADTypes.AbstractADType, F, AbstractArray, AbstractArray}, Tuple{AbstractArray, AbstractArray, ADTypes.AbstractADType, F, AbstractArray, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.gradient_and_hessian_vector_product!","text":"gradient_and_hessian_vector_product!(grad, backend, hvp, backend, f, x, v, [extras]) -> (grad, hvp)\n\nCompute the gradient grad = ∇f(x) and the Hessian-vector product hvp = ∇²f(x) * v of an array-to-scalar function, overwriting grad and hvp.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.gradient_and_hessian_vector_product-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.gradient_and_hessian_vector_product","text":"gradient_and_hessian_vector_product(backend, f, x, v, [extras]) -> (grad, hvp)\n\nCompute the gradient grad = ∇f(x) and the Hessian-vector product hvp = ∇²f(x) * v of an array-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.hessian_vector_product!-Union{Tuple{F}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray, AbstractArray}, Tuple{AbstractArray, ADTypes.AbstractADType, F, AbstractArray, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.hessian_vector_product!","text":"hessian_vector_product!(hvp, backend, f, x, v, [extras]) -> hvp\n\nCompute the Hessian-vector product hvp = ∇²f(x) * v of an array-to-scalar function, overwriting hvp.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.hessian_vector_product-Union{Tuple{F}, Tuple{ADTypes.AbstractADType, F, AbstractArray, AbstractArray}, Tuple{ADTypes.AbstractADType, F, AbstractArray, AbstractArray, Any}} where F","page":"API reference","title":"DifferentiationInterface.hessian_vector_product","text":"hessian_vector_product(backend, f, x, v, [extras]) -> hvp\n\nCompute the Hessian-vector product hvp = ∇²f(x) * v of an array-to-scalar function.\n\n\n\n\n\n","category":"method"},{"location":"api/#Preparation","page":"API reference","title":"Preparation","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"prepare.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.prepare_derivative-Tuple{ADTypes.AbstractADType, Any, Number}","page":"API reference","title":"DifferentiationInterface.prepare_derivative","text":"prepare_derivative(backend, f, x) -> extras\n\nCreate an extras object that can be given to derivative operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_gradient-Tuple{ADTypes.AbstractADType, Any, AbstractArray}","page":"API reference","title":"DifferentiationInterface.prepare_gradient","text":"prepare_gradient(backend, f, x) -> extras\n\nCreate an extras object that can be given to gradient operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_hessian-Tuple{ADTypes.AbstractADType, Any, AbstractArray}","page":"API reference","title":"DifferentiationInterface.prepare_hessian","text":"prepare_hessian(backend, f, x) -> extras\n\nCreate an extras object that can be given to Hessian operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_hessian_vector_product-Tuple{ADTypes.AbstractADType, Any, AbstractArray}","page":"API reference","title":"DifferentiationInterface.prepare_hessian_vector_product","text":"prepare_hessian_vector_product(backend, f, x) -> extras\n\nCreate an extras object that can be given to Hessian-vector product operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_jacobian-Tuple{ADTypes.AbstractADType, Any, AbstractArray}","page":"API reference","title":"DifferentiationInterface.prepare_jacobian","text":"prepare_jacobian(backend, f, x) -> extras\nprepare_jacobian(backend, f!, x, y) -> extras\n\nCreate an extras object that can be given to Jacobian operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_multiderivative-Tuple{ADTypes.AbstractADType, Any, Number}","page":"API reference","title":"DifferentiationInterface.prepare_multiderivative","text":"prepare_multiderivative(backend, f, x) -> extras\nprepare_multiderivative(backend, f!, x, y) -> extras\n\nCreate an extras object that can be given to multiderivative operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_pullback-Tuple{ADTypes.AbstractADType, Any, Any}","page":"API reference","title":"DifferentiationInterface.prepare_pullback","text":"prepare_pullback(backend, f, x) -> extras\nprepare_pullback(backend, f!, x, y) -> extras\n\nCreate an extras object that can be given to pullback operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_pushforward-Tuple{ADTypes.AbstractADType, Any, Any}","page":"API reference","title":"DifferentiationInterface.prepare_pushforward","text":"prepare_pushforward(backend, f, x) -> extras\nprepare_pushforward(backend, f!, x, y) -> extras\n\nCreate an extras object that can be given to pushforward operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.prepare_second_derivative-Tuple{ADTypes.AbstractADType, Any, Number}","page":"API reference","title":"DifferentiationInterface.prepare_second_derivative","text":"prepare_second_derivative(backend, f, x) -> extras\n\nCreate an extras object that can be given to second derivative operators.\n\n\n\n\n\n","category":"method"},{"location":"api/#Backend-queries","page":"API reference","title":"Backend queries","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPages = [\"backends.jl\"]","category":"page"},{"location":"api/#DifferentiationInterface.available-Tuple{ADTypes.AbstractADType}","page":"API reference","title":"DifferentiationInterface.available","text":"available(backend)\n\nCheck whether backend is available by trying a scalar-to-scalar derivative. Might take a while due to compilation time.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.supports_hessian-Tuple{ADTypes.AbstractADType}","page":"API reference","title":"DifferentiationInterface.supports_hessian","text":"supports_hessian(backend)\n\nCheck whether backend supports second order differentiation by trying a hessian. Might take a while due to compilation time.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.supports_mutation-Tuple{ADTypes.AbstractADType}","page":"API reference","title":"DifferentiationInterface.supports_mutation","text":"supports_mutation(backend)\n\nCheck whether backend supports differentiation of mutating functions by trying a jacobian. Might take a while due to compilation time.\n\n\n\n\n\n","category":"method"},{"location":"api/#Internals","page":"API reference","title":"Internals","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"This is not part of the public API.","category":"page"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationInterface]\nPublic = false","category":"page"},{"location":"api/#DifferentiationInterface.ForwardMode","page":"API reference","title":"DifferentiationInterface.ForwardMode","text":"ForwardMode\n\nTrait identifying forward mode (and finite differences) first-order AD backends.\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.MutationNotSupported","page":"API reference","title":"DifferentiationInterface.MutationNotSupported","text":"MutationNotSupported\n\nTrait identifying backends that do not support mutating functions f!(y, x).\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.MutationSupported","page":"API reference","title":"DifferentiationInterface.MutationSupported","text":"MutationSupported\n\nTrait identifying backends that support mutating functions f!(y, x).\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.ReverseMode","page":"API reference","title":"DifferentiationInterface.ReverseMode","text":"ReverseMode\n\nTrait identifying reverse mode first-order AD backends.\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.SymbolicMode","page":"API reference","title":"DifferentiationInterface.SymbolicMode","text":"SymbolicMode\n\nTrait identifying symbolic first-order AD backends. Their fallback structure is different from the rest.\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.basisarray-Tuple{ADTypes.AbstractADType, AbstractArray, Any}","page":"API reference","title":"DifferentiationInterface.basisarray","text":"basisarray(backend, a::AbstractArray, i::CartesianIndex)\n\nConstruct the i-th stardard basis array in the vector space of a with element type eltype(a).\n\nNote\n\nIf an AD backend benefits from a more specialized basis array implementation, this function can be extended on the backend type.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.mode","page":"API reference","title":"DifferentiationInterface.mode","text":"mode(backend)\n\nReturn the AD mode of a backend in a statically predictable way.\n\nThis function must be overloaded for backends that support both forward and reverse.\n\nWe classify finite differences as a forward mode.\n\n\n\n\n\n","category":"function"},{"location":"api/#DifferentiationInterface.mutation_behavior-Tuple{ADTypes.AbstractADType}","page":"API reference","title":"DifferentiationInterface.mutation_behavior","text":"mutation_behavior(backend)\n\nReturn the mutation behavior of a backend in a statically predictable way.\n\nNote\n\nThis is different from supports_mutation, which performs an actual call to jacobian!.\n\n\n\n\n\n","category":"method"},{"location":"api/#Testing","page":"API reference","title":"Testing","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"This is not part of the public API.","category":"page"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [DifferentiationTest]","category":"page"},{"location":"api/#DifferentiationInterface.DifferentiationTest","page":"API reference","title":"DifferentiationInterface.DifferentiationTest","text":"DifferentiationInterface.DifferentiationTest\n\nTesting utilities for DifferentiationInterface.\n\n\n\n\n\n","category":"module"},{"location":"api/#DifferentiationInterface.DifferentiationTest.AutoZeroForward","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.AutoZeroForward","text":"AutoZeroForward <: ADTypes.AbstractForwardMode\n\nTrivial backend that sets all derivatives to zero. Used in testing and benchmarking.\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.DifferentiationTest.AutoZeroReverse","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.AutoZeroReverse","text":"AutoZeroReverse <: ADTypes.AbstractReverseMode\n\nTrivial backend that sets all derivatives to zero. Used in testing and benchmarking.\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.DifferentiationTest.BenchmarkData","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.BenchmarkData","text":"BenchmarkData\n\nFields\n\nbackend::Vector\noperator::Vector\nfunc::Vector\nmutating::Vector\ninput_type::Vector\noutput_type::Vector\ninput_size::Vector\noutput_size::Vector\nsamples::Vector\ntime::Vector\nbytes::Vector\nallocs::Vector\ncompile_fraction::Vector\ngc_fraction::Vector\nevals::Vector\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.DifferentiationTest.Scenario","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.Scenario","text":"Scenario\n\nStore a testing scenario composed of a function and its input + output + tangents.\n\nFields\n\nf::Any: function\nmutating::Bool: mutation\nx::Union{Number, AbstractArray}: input\ny::Union{Number, AbstractArray}: output\ndx::Union{Number, AbstractArray}: pushforward seed\ndy::Union{Number, AbstractArray}: pullback seed\n\n\n\n\n\n","category":"type"},{"location":"api/#DifferentiationInterface.DifferentiationTest.backend_string-Tuple{ADTypes.AbstractADType}","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.backend_string","text":"backend_string(backend)\n\nReturn a shorter string than the full object printing from ADTypes.jl. Might be ambiguous.\n\n\n\n\n\n","category":"method"},{"location":"api/#DifferentiationInterface.DifferentiationTest.test_operators","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.test_operators","text":"test_operators(\n backends, [operators, scenarios];\n correctness, type_stability, benchmark, allocations,\n input_type, output_type,\n first_order, second_order, allocating, mutating,\n excluded,\n)\n\nCross-test a list of backends for a list of operators on a list of scenarios.\n\nReturn nothing, except when benchmark=true.\n\nDefault arguments\n\noperators: defaults to all of them\nscenarios: defaults to a set of default scenarios\n\nKeyword arguments\n\ncorrectness=true: whether to compare the differentiation results with those given by ForwardDiff.jl\ntype_stability=true: whether to check type stability with JET.jl\ncall_count=false: whether to check that the function is called the right number of times\nbenchmark=false: whether to run and return a benchmark suite with Chairmarks.jl\nallocations=false: whether to check that the benchmarks are allocation-free\ninput_type=Any: restrict scenario inputs to subtypes of this\noutput_type=Any: restrict scenario outputs to subtypes of this\nfirst_order=true: consider first order operators\nsecond_order=true: consider second order operators\nallocating=true: consider operators for allocating functions\nmutating=true: consider operators for mutating functions\nexcluded=Symbol[]: list of excluded operators\n\n\n\n\n\n","category":"function"},{"location":"api/#DifferentiationInterface.DifferentiationTest.test_operators-Tuple{ADTypes.AbstractADType, Vararg{Any}}","page":"API reference","title":"DifferentiationInterface.DifferentiationTest.test_operators","text":"test_operators(\n backend::ADTypes.AbstractADType,\n args...;\n kwargs...\n) -> Union{Nothing, BenchmarkData}\n\n\nShortcut for a single backend.\n\n\n\n\n\n","category":"method"},{"location":"api/","page":"API reference","title":"API reference","text":"","category":"page"},{"location":"getting_started/#Getting-started","page":"Getting started","title":"Getting started","text":"","category":"section"},{"location":"getting_started/#operators","page":"Getting started","title":"Operators","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Depending on the type of input and output, differentiation operators can have various names. Most backends have custom implementations, which we reuse if possible.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"We choose the following terminology for the operators we provide:","category":"page"},{"location":"getting_started/#First-order-differentiation","page":"Getting started","title":"First order differentiation","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":" scalar output array output\nscalar input derivative multiderivative\narray input gradient jacobian","category":"page"},{"location":"getting_started/#Second-order-differentiation","page":"Getting started","title":"Second order differentiation","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":" scalar output array output\nscalar input second_derivative not implemented\narray input hessian not implemented","category":"page"},{"location":"getting_started/#Variants","page":"Getting started","title":"Variants","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Whenever it makes sense, four variants of the same operator are defined:","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Operator allocating mutating allocating with primal mutating with primal\nDerivative derivative N/A value_and_derivative N/A\nMultiderivative multiderivative multiderivative! value_and_multiderivative value_and_multiderivative!\nGradient gradient gradient! value_and_gradient value_and_gradient!\nJacobian jacobian jacobian! value_and_jacobian value_and_jacobian!\nSecond derivative second_derivative N/A value_derivative_and_second_derivative N/A\nHessian hessian hessian! value_gradient_and_hessian value_gradient_and_hessian!","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Note that scalar outputs can't be mutated, which is why derivative and second_derivative do not have mutating variants.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"For advanced users, lower-level operators are also exposed:","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Operator allocating mutating allocating with primal mutating with primal\nPushforward (JVP) pushforward pushforward! value_and_pushforward value_and_pushforward!\nPullback (VJP) pullback pullback! value_and_pullback value_and_pullback!\nHessian-vector product (HVP) hessian_vector_product hessian_vector_product! gradient_and_hessian_vector_product gradient_and_hessian_vector_product!","category":"page"},{"location":"getting_started/#Preparation","page":"Getting started","title":"Preparation","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"In many cases, automatic differentiation can be accelerated if the function has been run at least once (e.g. to record a tape) and if some cache objects are provided. This is a backend-specific procedure, but we expose a common syntax to achieve it.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Operator preparation function\nDerivative prepare_derivative\nMultiderivative prepare_multiderivative\nGradient prepare_gradient\nJacobian prepare_jacobian\nSecond derivative prepare_second_derivative\nHessian prepare_hessian\nPushforward (JVP) prepare_pushforward\nPullback (VJP) prepare_pullback\nHessian-vector product (HVP) prepare_hessian_vector_product","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"If you run prepare_operator(backend, f, x), it will create an object called extras containing the necessary information to speed up operator and its variants. This information is specific to backend and f, as well as the type and size of the input x, but it should work with different values of x.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"You can then call operator(backend, f, similar_x, extras), which should be faster than operator(backend, f, similar_x). This is especially worth it if you plan to call operator several times in similar settings: you can think of it as a warm up.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"By default, all the preparation functions return nothing. We do not make any guarantees on their implementation for each backend, or on the performance gains that can be expected.","category":"page"},{"location":"getting_started/#Mutating-functions","page":"Getting started","title":"Mutating functions","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"In addition to allocating functions f(x) = y, some backends also support mutating functions f!(y, x) = nothing whenever the output is an array. Beware that the function f! must return nothing!. Since f! operates in-place and the primal is computed every time, only four operators are defined:","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Operator mutating with primal\nMultiderivative value_and_multiderivative!\nJacobian value_and_jacobian!\nPushforward (JVP) value_and_pushforward!\nPullback (VJP) value_and_pullback!","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Furthermore, the preparation function takes an additional argument: prepare_operator(backend, f!, x, y).","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Check out the list of backends that support mutating functions.","category":"page"},{"location":"getting_started/#Multiple-inputs/outputs","page":"Getting started","title":"Multiple inputs/outputs","text":"","category":"section"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"Restricting the API to one input and one output has many coding advantages, but it is not very flexible. If you need more than that, use ComponentArrays.jl to wrap several objects inside a single ComponentVector.","category":"page"},{"location":"getting_started/","page":"Getting started","title":"Getting started","text":"","category":"page"},{"location":"developer/#For-AD-developers","page":"For AD developers","title":"For AD developers","text":"","category":"section"},{"location":"developer/#Backend-requirements","page":"For AD developers","title":"Backend requirements","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"Every operator can be implemented from either of these two primitives:","category":"page"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"the pushforward (in forward mode), computing a Jacobian-vector product\nthe pullback (in reverse mode), computing a vector-Jacobian product","category":"page"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"The only requirement for a backend is therefore to implement either value_and_pushforward! or value_and_pullback!, from which the rest of the operators can be deduced. We provide a standard series of fallbacks, but we leave it to each backend to redefine as many of the utilities as necessary to achieve optimal performance.","category":"page"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"Every backend we support corresponds to a package extension of DifferentiationInterface.jl (located in the ext subfolder). Advanced users are welcome to code more backends and submit pull requests!","category":"page"},{"location":"developer/#Fallback-call-structure","page":"For AD developers","title":"Fallback call structure","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"note: Edge labels\nNon-labeled edges in the following graphs correspond to single function calls.Edge labels correspond to the amount of function calls when applying operators to a function f mathbbR^n rightarrow mathbbR^m.","category":"page"},{"location":"developer/#Forward-mode,-allocating-functions","page":"For AD developers","title":"Forward mode, allocating functions","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"flowchart LR\n subgraph Derivative\n value_and_derivative\n derivative\n end\n\n value_and_derivative --> value_and_pushforward\n derivative --> pushforward\n \n subgraph Multiderivative\n value_and_multiderivative!\n value_and_multiderivative\n multiderivative!\n multiderivative\n end\n\n value_and_multiderivative! --> value_and_pushforward!\n value_and_multiderivative --> value_and_pushforward\n multiderivative! --> pushforward!\n multiderivative --> pushforward\n\n subgraph Gradient\n value_and_gradient --> value_and_gradient!\n gradient! --> value_and_gradient!\n gradient --> value_and_gradient\n end\n\n value_and_gradient! --> |n|pushforward\n\n subgraph Jacobian\n value_and_jacobian --> value_and_jacobian!\n jacobian! --> value_and_jacobian!\n jacobian --> value_and_jacobian\n end\n\n value_and_jacobian! --> |n|pushforward!\n\n subgraph Pushforward\n value_and_pushforward --> value_and_pushforward!\n pushforward! --> value_and_pushforward!\n pushforward --> value_and_pushforward\n end","category":"page"},{"location":"developer/#Forward-mode,-mutating-functions","page":"For AD developers","title":"Forward mode, mutating functions","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"flowchart LR\n subgraph Multiderivative\n value_and_multiderivative!\n end\n\n value_and_multiderivative! --> value_and_pushforward!\n\n subgraph Jacobian\n value_and_jacobian!\n end\n\n value_and_jacobian! --> |n|value_and_pushforward!\n\n subgraph Pushforward\n value_and_pushforward!\n end","category":"page"},{"location":"developer/#Reverse-mode,-allocating-functions","page":"For AD developers","title":"Reverse mode, allocating functions","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"flowchart LR\n subgraph Derivative\n value_and_derivative\n derivative\n end\n\n value_and_derivative --> value_and_pullback\n derivative --> pullback\n \n subgraph Multiderivative\n value_and_multiderivative --> value_and_multiderivative!\n multiderivative! --> value_and_multiderivative!\n multiderivative --> value_and_multiderivative\n end\n\n value_and_multiderivative! --> |m|pullback\n\n subgraph Gradient\n value_and_gradient!\n value_and_gradient\n gradient!\n gradient \n end\n\n value_and_gradient! --> value_and_pullback!\n value_and_gradient --> value_and_pullback\n gradient! --> pullback!\n gradient --> pullback\n\n subgraph Jacobian\n value_and_jacobian --> value_and_jacobian!\n jacobian! --> value_and_jacobian!\n jacobian --> value_and_jacobian\n end\n\n value_and_jacobian! --> |m|pullback!\n\n subgraph Pullback\n value_and_pullback --> value_and_pullback!\n pullback! --> value_and_pullback!\n pullback --> value_and_pullback\n end","category":"page"},{"location":"developer/#Reverse-mode,-mutating-functions","page":"For AD developers","title":"Reverse mode, mutating functions","text":"","category":"section"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"flowchart LR\n subgraph Multiderivative\n value_and_multiderivative!\n end\n\n value_and_multiderivative! --> |m|value_and_pullback!\n\n subgraph Jacobian\n value_and_jacobian!\n end\n\n value_and_jacobian! --> |m|value_and_pullback!\n\n subgraph Pullback\n value_and_pullback!\n end","category":"page"},{"location":"developer/","page":"For AD developers","title":"For AD developers","text":"","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"CollapsedDocStrings = true","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"using ADTypes, DifferentiationInterface\nusing DifferentiationInterface.DifferentiationTest: backend_string\nimport Markdown\nimport Chairmarks, DataFrames\nimport Enzyme, FastDifferentiation, FiniteDiff, ForwardDiff, PolyesterForwardDiff, ReverseDiff, Tracker, Zygote\n\nfunction all_backends()\n return [\n AutoDiffractor(),\n AutoEnzyme(Enzyme.Forward),\n AutoEnzyme(Enzyme.Reverse),\n AutoFastDifferentiation(),\n AutoFiniteDiff(),\n AutoForwardDiff(),\n AutoPolyesterForwardDiff(; chunksize=2),\n AutoReverseDiff(),\n AutoTracker(),\n AutoZygote(),\n ]\nend","category":"page"},{"location":"backends/#Backends","page":"Backends","title":"Backends","text":"","category":"section"},{"location":"backends/#Types","page":"Backends","title":"Types","text":"","category":"section"},{"location":"backends/","page":"Backends","title":"Backends","text":"Most backend choices are defined by ADTypes.jl.","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"warning: Warning\nOnly the backends listed here are supported by DifferentiationInterface.jl, even though ADTypes.jl defines more.","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"AutoChainRules\nAutoDiffractor\nAutoEnzyme\nAutoForwardDiff\nAutoForwardDiff()\nAutoFiniteDiff\nAutoPolyesterForwardDiff\nAutoPolyesterForwardDiff()\nAutoReverseDiff\nAutoTracker\nAutoZygote","category":"page"},{"location":"backends/#ADTypes.AutoChainRules","page":"Backends","title":"ADTypes.AutoChainRules","text":"AutoChainRules{RC}\n\nChooses any AD library based on ChainRulesCore.jl, given an appropriate RuleConfig object.\n\nFields\n\nruleconfig::RC\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoDiffractor","page":"Backends","title":"ADTypes.AutoDiffractor","text":"AutoDiffractor\n\nChooses Diffractor.jl.\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoEnzyme","page":"Backends","title":"ADTypes.AutoEnzyme","text":"AutoEnzyme(Enzyme.Forward)\nAutoEnzyme(Enzyme.Reverse)\n\nConstruct a forward or reverse mode AutoEnzyme backend.\n\n\n\n\n\nAutoEnzyme{M}\n\nChooses Enzyme.jl.\n\nFields\n\nmode::M = nothing\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoForwardDiff","page":"Backends","title":"ADTypes.AutoForwardDiff","text":"AutoForwardDiff{chunksize,T}\n\nChooses ForwardDiff.jl.\n\nFields\n\ntag::T\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoForwardDiff-Tuple{}","page":"Backends","title":"ADTypes.AutoForwardDiff","text":"AutoForwardDiff(; chunksize = nothing, tag = nothing)\n\nConstructor.\n\n\n\n\n\n","category":"method"},{"location":"backends/#ADTypes.AutoFiniteDiff","page":"Backends","title":"ADTypes.AutoFiniteDiff","text":"AutoFiniteDiff{T1,T2,T3}\n\nChooses FiniteDiff.jl.\n\nFields\n\nfdtype::T1 = Val(:forward)\nfdjtype::T2 = fdtype\nfdhtype::T3 = Val(:hcentral)\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoPolyesterForwardDiff","page":"Backends","title":"ADTypes.AutoPolyesterForwardDiff","text":"AutoPolyesterForwardDiff{chunksize}\n\nChooses PolyesterForwardDiff.jl.\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoPolyesterForwardDiff-Tuple{}","page":"Backends","title":"ADTypes.AutoPolyesterForwardDiff","text":"AutoPolyesterForwardDiff(; chunksize = nothing)\n\nConstructor.\n\n\n\n\n\n","category":"method"},{"location":"backends/#ADTypes.AutoReverseDiff","page":"Backends","title":"ADTypes.AutoReverseDiff","text":"AutoReverseDiff\n\nChooses ReverseDiff.jl.\n\nFields\n\ncompile::Bool = false\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoTracker","page":"Backends","title":"ADTypes.AutoTracker","text":"AutoTracker\n\nChooses Tracker.jl.\n\n\n\n\n\n","category":"type"},{"location":"backends/#ADTypes.AutoZygote","page":"Backends","title":"ADTypes.AutoZygote","text":"AutoZygote\n\nChooses Zygote.jl.\n\n\n\n\n\n","category":"type"},{"location":"backends/","page":"Backends","title":"Backends","text":"We also provide a few of our own:","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"AutoFastDifferentiation\nSecondOrder","category":"page"},{"location":"backends/#DifferentiationInterface.AutoFastDifferentiation","page":"Backends","title":"DifferentiationInterface.AutoFastDifferentiation","text":"AutoFastDifferentiation\n\nChooses FastDifferentiation.jl.\n\n\n\n\n\n","category":"type"},{"location":"backends/#DifferentiationInterface.SecondOrder","page":"Backends","title":"DifferentiationInterface.SecondOrder","text":"SecondOrder\n\nCombination of two backends for second-order differentiation.\n\nFields\n\ninner::ADTypes.AbstractADType: backend for the inner differentiation\nouter::ADTypes.AbstractADType: backend for the outer differentiation\n\n\n\n\n\n","category":"type"},{"location":"backends/#Availability","page":"Backends","title":"Availability","text":"","category":"section"},{"location":"backends/","page":"Backends","title":"Backends","text":"You can use available to verify whether a given backend is loaded, like we did below:","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"header = \"| Backend | available |\" # hide\nsubheader = \"|---|---|\" # hide\nrows = map(all_backends()) do backend # hide\n \"| `$(backend_string(backend))` | $(available(backend) ? '✓' : '✗') |\" # hide\nend # hide\nMarkdown.parse(join(vcat(header, subheader, rows...), \"\\n\")) # hide","category":"page"},{"location":"backends/#backend_mutation_behavior","page":"Backends","title":"Mutation support","text":"","category":"section"},{"location":"backends/","page":"Backends","title":"Backends","text":"All backends are compatible with allocating functions f(x) = y. Only some are compatible with mutating functions f!(y, x) = nothing. You can use supports_mutation to check that feature, like we did below:","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"header = \"| Backend | mutation |\" # hide\nsubheader = \"|---|---|\" # hide\nrows = map(all_backends()) do backend # hide\n \"| `$(backend_string(backend))` | $(supports_mutation(backend) ? '✓' : '✗') |\" # hide\nend # hide\nMarkdown.parse(join(vcat(header, subheader, rows...), \"\\n\")) # hide","category":"page"},{"location":"backends/#Second-order","page":"Backends","title":"Second order","text":"","category":"section"},{"location":"backends/","page":"Backends","title":"Backends","text":"For second-order differentiation, you can either","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"combine a pair (backend_inner, backend_outer) of inner and outer backends into a SecondOrder object\nuse a single backend backend, which amounts to backend_inner = backend_outer = backend","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"In Hessian computations, the most efficient combination is often forward-over-reverse, i.e. SecondOrder(reverse_backend, forward_backend).","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"info: Info\nMany backend combinations will fail for second order. Some because of our implementation, and some because the outer backend cannot differentiate through code generated by the inner backend.","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"You can use supports_hessian to find working combinations, like we did below:","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"header = \"| Inner \\\\ Outer |\" # hide\nsubheader = \"|---|\" # hide\nfor bo in all_backends() # hide\n global header *= \" $(backend_string(bo)) |\" # hide\n global subheader *= \"---|\" # hide\nend # hide\nrows = map(all_backends()) do bi # hide\n @info \"Generating hessian row for $(backend_string(bi))\" # hide\n row = \"| $(backend_string(bi)) |\" # hide\n for bo in all_backends() # hide\n row *= \" $(supports_hessian(SecondOrder(bi, bo)) ? '✓' : '✗') |\" # hide\n end # hide\n row # hide\nend # hide\nMarkdown.parse(join(vcat(header, subheader, rows...), \"\\n\") * \"\\n\") # hide","category":"page"},{"location":"backends/#Package-extensions","page":"Backends","title":"Package extensions","text":"","category":"section"},{"location":"backends/","page":"Backends","title":"Backends","text":"CurrentModule = DifferentiationInterface","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"Backend-specific extension content is not part of the public API.","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"Modules = [\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceChainRulesCoreExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceDiffractorExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceEnzymeExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceFastDifferentiationExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceFiniteDiffExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceForwardDiffExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfacePolyesterForwardDiffExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceReverseDiffExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceTrackerExt),\n Base.get_extension(DifferentiationInterface, :DifferentiationInterfaceZygoteExt)\n]\nFilter = t -> !(t <: ADTypes.AbstractADType)","category":"page"},{"location":"backends/","page":"Backends","title":"Backends","text":"","category":"page"},{"location":"","page":"Home","title":"Home","text":"EditURL = \"https://github.com/gdalle/DifferentiationInterface.jl/blob/main/README.md\"","category":"page"},{"location":"#DifferentiationInterface","page":"Home","title":"DifferentiationInterface","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"(Image: Dev) (Image: Build Status) (Image: Coverage) (Image: Code Style: Blue)","category":"page"},{"location":"","page":"Home","title":"Home","text":"An interface to various automatic differentiation backends in Julia.","category":"page"},{"location":"#Goal","page":"Home","title":"Goal","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This package provides a backend-agnostic syntax to differentiate functions of the following types:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Allocating: f(x) = y where x and y can be real numbers or abstract arrays\nMutating: f!(y, x) = nothing where y is an abstract array and x can be a real number or an abstract array","category":"page"},{"location":"#Compatibility","page":"Home","title":"Compatibility","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"We support some of the backends defined by ADTypes.jl:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Backend Object\nChainRulesCore.jl AutoChainRules(ruleconfig)\nDiffractor.jl AutoDiffractor()\nEnzyme.jl AutoEnzyme(Enzyme.Forward) or AutoEnzyme(Enzyme.Reverse)\nFiniteDiff.jl AutoFiniteDiff()\nForwardDiff.jl AutoForwardDiff()\nPolyesterForwardDiff.jl AutoPolyesterForwardDiff(; chunksize)\nReverseDiff.jl AutoReverseDiff()\nTracker.jl AutoTracker()\nZygote.jl AutoZygote()","category":"page"},{"location":"","page":"Home","title":"Home","text":"We also provide additional backends:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Backend Object\nFastDifferentiation.jl AutoFastDifferentiation()","category":"page"},{"location":"#Example","page":"Home","title":"Example","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Setup:","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> import ADTypes, ForwardDiff\n\njulia> using DifferentiationInterface\n\njulia> backend = ADTypes.AutoForwardDiff();\n\njulia> f(x) = sum(abs2, x);","category":"page"},{"location":"","page":"Home","title":"Home","text":"Out-of-place gradient:","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> value_and_gradient(backend, f, [1., 2., 3.])\n(14.0, [2.0, 4.0, 6.0])","category":"page"},{"location":"","page":"Home","title":"Home","text":"In-place gradient:","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> grad = zeros(3);\n\njulia> value_and_gradient!(grad, backend, f, [1., 2., 3.])\n(14.0, [2.0, 4.0, 6.0])\n\njulia> grad\n3-element Vector{Float64}:\n 2.0\n 4.0\n 6.0","category":"page"},{"location":"#Related-packages","page":"Home","title":"Related packages","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"AbstractDifferentiation.jl is the original inspiration for DifferentiationInterface.jl.\nAutoDiffOperators.jl is an attempt to bridge ADTypes.jl with AbstractDifferentiation.jl.","category":"page"},{"location":"#Roadmap","page":"Home","title":"Roadmap","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Goals for future releases:","category":"page"},{"location":"","page":"Home","title":"Home","text":"optimize performance for each backend\ndefine user-facing functions to test and benchmark backends against each other","category":"page"},{"location":"","page":"Home","title":"Home","text":"","category":"page"}] }