Skip to content

Commit 775a78c

Browse files
committed
using NonlinearSolve works
1 parent 17bb8a8 commit 775a78c

File tree

13 files changed

+101
-127
lines changed

13 files changed

+101
-127
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ NonlinearSolveSymbolicsExt = "Symbolics"
5757
NonlinearSolveZygoteExt = "Zygote"
5858

5959
[compat]
60-
ADTypes = "0.2.6"
60+
ADTypes = "1.1.0"
6161
Aqua = "0.8"
6262
ArrayInterface = "7.9"
6363
BandedMatrices = "1.5"

docs/src/basics/autodiff.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,16 @@
33
## Summary of Finite Differencing Backends
44

55
- [`AutoFiniteDiff`](@ref): Finite differencing, not optimal but always applicable.
6-
- [`AutoSparseFiniteDiff`](@ref): Sparse version of [`AutoFiniteDiff`](@ref).
76

87
## Summary of Forward Mode AD Backends
98

109
- [`AutoForwardDiff`](@ref): The best choice for dense problems.
11-
- [`AutoSparseForwardDiff`](@ref): Sparse version of [`AutoForwardDiff`](@ref).
1210
- [`AutoPolyesterForwardDiff`](@ref): Might be faster than [`AutoForwardDiff`](@ref) for
1311
large problems. Requires `PolyesterForwardDiff.jl` to be installed and loaded.
1412

1513
## Summary of Reverse Mode AD Backends
1614

1715
- [`AutoZygote`](@ref): The fastest choice for non-mutating array-based (BLAS) functions.
18-
- [`AutoSparseZygote`](@ref): Sparse version of [`AutoZygote`](@ref).
1916
- [`AutoEnzyme`](@ref): Uses `Enzyme.jl` Reverse Mode and should be considered
2017
experimental.
2118

@@ -26,37 +23,38 @@
2623

2724
!!! note
2825

29-
The `Sparse` versions of the methods refers to automated sparsity detection. These
26+
The sparse versions of the methods refer to automated sparsity detection. These
3027
methods automatically discover the sparse Jacobian form from the function `f`. Note that
3128
all methods specialize the differentiation on a sparse Jacobian if the sparse Jacobian
3229
is given as `prob.f.jac_prototype` in the `NonlinearFunction` definition, and the
3330
`AutoSparse` here simply refers to whether this `jac_prototype` should be generated
3431
automatically. For more details, see
3532
[SparseDiffTools.jl](https://github.com/JuliaDiff/SparseDiffTools.jl) and
36-
[Sparsity Detection Manual Entry](@ref sparsity-detection).
33+
[Sparsity Detection Manual Entry](@ref sparsity-detection), as well as the
34+
documentation of [ADTypes.jl](https://github.com/SciML/ADTypes.jl).
3735

3836
## API Reference
3937

38+
```@docs
39+
AutoSparse
40+
```
41+
4042
### Finite Differencing Backends
4143

4244
```@docs
4345
AutoFiniteDiff
44-
AutoSparseFiniteDiff
4546
```
4647

4748
### Forward Mode AD Backends
4849

4950
```@docs
5051
AutoForwardDiff
51-
AutoSparseForwardDiff
5252
AutoPolyesterForwardDiff
5353
```
5454

5555
### Reverse Mode AD Backends
5656

5757
```@docs
5858
AutoZygote
59-
AutoSparseZygote
6059
AutoEnzyme
61-
NonlinearSolve.AutoSparseEnzyme
6260
```

docs/src/basics/sparsity_detection.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ refer to the documentation there for more details.
5959
If you constructed a Nonlinear Solver with a sparse AD type, for example
6060

6161
```julia
62-
NewtonRaphson(; autodiff = AutoSparseForwardDiff())
62+
NewtonRaphson(; autodiff = AutoSparse(AutoForwardDiff()))
6363
# OR
64-
TrustRegion(; autodiff = AutoSparseZygote())
64+
TrustRegion(; autodiff = AutoSparse(AutoZygote()))
6565
```
6666

6767
then NonlinearSolve will automatically perform matrix coloring and use sparse

docs/src/tutorials/large_systems.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ include:
128128
In the next section, we will discuss how to declare a sparse Jacobian and how to use
129129
[Symbolics.jl](https://github.com/JuliaSymbolics/Symbolics.jl), to compute exact sparse
130130
jacobians. This is triggered if you pass in a sparse autodiff type such as
131-
`AutoSparseForwardDiff()`. If `Symbolics.jl` is loaded, then the default changes to
131+
`AutoSparse(AutoForwardDiff())`. If `Symbolics.jl` is loaded, then the default changes to
132132
Symbolic Sparsity Detection. See the manual entry on
133133
[Sparsity Detection](@ref sparsity-detection) for more details on the default.
134134

@@ -137,13 +137,13 @@ using BenchmarkTools # for @btime
137137
138138
@btime solve(prob_brusselator_2d, NewtonRaphson());
139139
@btime solve(prob_brusselator_2d,
140-
NewtonRaphson(; autodiff = AutoSparseForwardDiff(; chunksize = 32)));
140+
NewtonRaphson(; autodiff = AutoSparse(AutoForwardDiff(; chunksize = 32))));
141141
@btime solve(prob_brusselator_2d,
142142
NewtonRaphson(;
143-
autodiff = AutoSparseForwardDiff(; chunksize = 32), linsolve = KLUFactorization()));
143+
autodiff = AutoSparse(AutoForwardDiff(; chunksize = 32)), linsolve = KLUFactorization()));
144144
@btime solve(prob_brusselator_2d,
145145
NewtonRaphson(;
146-
autodiff = AutoSparseForwardDiff(; chunksize = 32), linsolve = KrylovJL_GMRES()));
146+
autodiff = AutoSparse(AutoForwardDiff(; chunksize = 32)), linsolve = KrylovJL_GMRES()));
147147
nothing # hide
148148
```
149149

src/NonlinearSolve.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import PrecompileTools: @recompile_invalidations, @compile_workload, @setup_work
2727

2828
import SciMLBase: AbstractNonlinearAlgorithm, JacobianWrapper, AbstractNonlinearProblem,
2929
AbstractSciMLOperator, NLStats, _unwrap_val, has_jac, isinplace
30-
import SparseDiffTools: AbstractSparsityDetection, AutoSparseEnzyme
30+
import SparseDiffTools: AbstractSparsityDetection
3131
import StaticArraysCore: StaticArray, SVector, SArray, MArray, Size, SMatrix, MMatrix
3232
import SymbolicIndexingInterface: SymbolicIndexingInterface, ParameterIndexingProxy,
3333
symbolic_container, parameter_values, state_values,
@@ -36,9 +36,6 @@ end
3636

3737
@reexport using ADTypes, SciMLBase, SimpleNonlinearSolve
3838

39-
const AbstractSparseADType = Union{ADTypes.AbstractSparseFiniteDifferences,
40-
ADTypes.AbstractSparseForwardMode, ADTypes.AbstractSparseReverseMode}
41-
4239
# Type-Inference Friendly Check for Extension Loading
4340
is_extension_loaded(::Val) = false
4441

src/adtypes.jl

Lines changed: 39 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,6 @@ error into the derivative estimates.
2222
"""
2323
AutoFiniteDiff
2424

25-
"""
26-
AutoSparseFiniteDiff()
27-
28-
Sparse Version of [`AutoFiniteDiff`](@ref) that uses
29-
[FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl) and the column color vector of
30-
the Jacobian Matrix to efficiently compute the Sparse Jacobian.
31-
32-
- Supports both inplace and out-of-place functions
33-
"""
34-
AutoSparseFiniteDiff
35-
3625
"""
3726
AutoForwardDiff(; chunksize = nothing, tag = nothing)
3827
AutoForwardDiff{chunksize, tagType}(tag::tagType)
@@ -56,27 +45,6 @@ For type-stability of internal operations, a positive `chunksize` must be provid
5645
"""
5746
AutoForwardDiff
5847

59-
"""
60-
AutoSparseForwardDiff(; chunksize = nothing, tag = nothing)
61-
AutoSparseForwardDiff{chunksize, tagType}(tag::tagType)
62-
63-
Sparse Version of [`AutoForwardDiff`](@ref) that uses
64-
[ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl) and the column color vector of
65-
the Jacobian Matrix to efficiently compute the Sparse Jacobian.
66-
67-
- Supports both inplace and out-of-place functions
68-
69-
For type-stability of internal operations, a positive `chunksize` must be provided.
70-
71-
### Keyword Arguments
72-
73-
- `chunksize`: Count of dual numbers that can be propagated simultaneously. Setting this
74-
number to a high value will lead to slowdowns. Use
75-
[`NonlinearSolve.pickchunksize`](@ref) to get a proper value.
76-
- `tag`: Used to avoid perturbation confusion. If set to `nothing`, we use a custom tag.
77-
"""
78-
AutoSparseForwardDiff
79-
8048
"""
8149
AutoPolyesterForwardDiff(; chunksize = nothing)
8250
@@ -108,20 +76,6 @@ jacobians.
10876
"""
10977
AutoZygote
11078

111-
"""
112-
AutoSparseZygote()
113-
114-
Sparse version of [`AutoZygote`](@ref) that uses
115-
[`Zygote.jl`](https://github.com/FluxML/Zygote.jl) and the row color vector of
116-
the Jacobian Matrix to efficiently compute the Sparse Jacobian.
117-
118-
- Supports only out-of-place functions
119-
120-
This is efficient only for long jacobians or if the maximum value of the row color vector is
121-
significantly lower than the maximum value of the column color vector.
122-
"""
123-
AutoSparseZygote
124-
12579
"""
12680
AutoEnzyme()
12781
@@ -134,15 +88,52 @@ and VJP support is currently not implemented.
13488
AutoEnzyme
13589

13690
"""
137-
AutoSparseEnzyme()
91+
AutoSparse(AutoEnzyme())
13892
13993
Sparse version of [`AutoEnzyme`](@ref) that uses
14094
[Enzyme.jl](https://github.com/EnzymeAD/Enzyme.jl) and the row color vector of
14195
the Jacobian Matrix to efficiently compute the Sparse Jacobian.
14296
14397
- Supports both inplace and out-of-place functions
14498
99+
This is efficient only for long jacobians or if the maximum value of the row color vector is
100+
significantly lower than the maximum value of the column color vector.
101+
102+
AutoSparse(AutoFiniteDiff())
103+
104+
Sparse Version of [`AutoFiniteDiff`](@ref) that uses
105+
[FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl) and the column color vector of
106+
the Jacobian Matrix to efficiently compute the Sparse Jacobian.
107+
108+
- Supports both inplace and out-of-place functions
109+
110+
AutoSparse(AutoForwardDiff(; chunksize = nothing, tag = nothing))
111+
AutoSparse(AutoForwardDiff{chunksize, tagType}(tag::tagType))
112+
113+
Sparse Version of [`AutoForwardDiff`](@ref) that uses
114+
[ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl) and the column color vector of
115+
the Jacobian Matrix to efficiently compute the Sparse Jacobian.
116+
117+
- Supports both inplace and out-of-place functions
118+
119+
For type-stability of internal operations, a positive `chunksize` must be provided.
120+
121+
### Keyword Arguments
122+
123+
- `chunksize`: Count of dual numbers that can be propagated simultaneously. Setting this
124+
number to a high value will lead to slowdowns. Use
125+
[`NonlinearSolve.pickchunksize`](@ref) to get a proper value.
126+
- `tag`: Used to avoid perturbation confusion. If set to `nothing`, we use a custom tag.
127+
128+
AutoSparse(AutoZygote())
129+
130+
Sparse version of [`AutoZygote`](@ref) that uses
131+
[`Zygote.jl`](https://github.com/FluxML/Zygote.jl) and the row color vector of
132+
the Jacobian Matrix to efficiently compute the Sparse Jacobian.
133+
134+
- Supports only out-of-place functions
135+
145136
This is efficient only for long jacobians or if the maximum value of the row color vector is
146137
significantly lower than the maximum value of the column color vector.
147138
"""
148-
AutoSparseEnzyme
139+
AutoSparse

src/algorithms/trust_region.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ function TrustRegion(; concrete_jac = nothing, linsolve = nothing, precs = DEFAU
2626
shrink_factor::Real = 1 // 4, expand_factor::Real = 2 // 1,
2727
max_shrink_times::Int = 32, autodiff = nothing, vjp_autodiff = nothing)
2828
descent = Dogleg(; linsolve, precs)
29-
if autodiff isa
30-
Union{ADTypes.AbstractForwardMode, ADTypes.AbstractFiniteDifferencesMode}
29+
if autodiff !== nothing && ADTypes.mode(autodiff) isa ADTypes.ForwardMode
3130
forward_ad = autodiff
3231
else
3332
forward_ad = nothing
3433
end
35-
if isnothing(vjp_autodiff) && autodiff isa ADTypes.AbstractFiniteDifferencesMode
34+
if isnothing(vjp_autodiff) &&
35+
autodiff isa Union{ADTypes.AutoFiniteDiff, ADTypes.AutoFiniteDifferences}
36+
# TODO: why not just ForwardMode?
3637
vjp_autodiff = autodiff
3738
end
3839
trustregion = GenericTrustRegionScheme(;

src/core/generalized_first_order.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,14 @@ function GeneralizedFirstOrderAlgorithm{concrete_jac, name}(;
5555
descent, linesearch = missing, trustregion = missing,
5656
jacobian_ad = nothing, forward_ad = nothing, reverse_ad = nothing,
5757
max_shrink_times::Int = typemax(Int)) where {concrete_jac, name}
58-
forward_ad = ifelse(forward_ad !== nothing, forward_ad,
59-
ifelse(jacobian_ad isa ADTypes.AbstractForwardMode, jacobian_ad, nothing))
60-
reverse_ad = ifelse(reverse_ad !== nothing, reverse_ad,
61-
ifelse(jacobian_ad isa ADTypes.AbstractReverseMode, jacobian_ad, nothing))
58+
forward_ad = ifelse(forward_ad !== nothing,
59+
forward_ad,
60+
ifelse(jacobian_ad !== nothing && ADTypes.mode(jacobian_ad) isa ADTypes.ForwardMode,
61+
jacobian_ad, nothing))
62+
reverse_ad = ifelse(reverse_ad !== nothing,
63+
reverse_ad,
64+
ifelse(jacobian_ad !== nothing && ADTypes.mode(jacobian_ad) isa ADTypes.ReverseMode,
65+
jacobian_ad, nothing))
6266

6367
if linesearch !== missing && !(linesearch isa AbstractNonlinearSolveLineSearchAlgorithm)
6468
Base.depwarn("Passing in a `LineSearches.jl` algorithm directly is deprecated. \

src/internal/helpers.jl

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,12 @@ function evaluate_f!!(f::NonlinearFunction{iip}, fu, u, p) where {iip}
3030
end
3131

3232
# AutoDiff Selection Functions
33-
function get_concrete_forward_ad(
34-
autodiff::Union{ADTypes.AbstractForwardMode, ADTypes.AbstractFiniteDifferencesMode},
35-
prob, sp::Val{test_sparse} = True, args...; kwargs...) where {test_sparse}
36-
return autodiff
37-
end
3833
function get_concrete_forward_ad(
3934
autodiff::ADTypes.AbstractADType, prob, sp::Val{test_sparse} = True,
4035
args...; check_reverse_mode = true, kwargs...) where {test_sparse}
41-
if check_reverse_mode
42-
@warn "$(autodiff)::$(typeof(autodiff)) is not a \
43-
`Abstract(Forward/FiniteDifferences)Mode`. Use with caution." maxlog=1
36+
# TODO: shouldn't this be `check_forward_mode`?
37+
if !isa(ADTypes.mode(autodiff), ADTypes.ForwardMode) && check_reverse_mode
38+
@warn "$(autodiff)::$(typeof(autodiff)) is not a `ForwardMode`. Use with caution." maxlog=1
4439
end
4540
return autodiff
4641
end
@@ -53,37 +48,28 @@ function get_concrete_forward_ad(
5348
use_sparse_ad = false
5449
end
5550
ad = if !ForwardDiff.can_dual(eltype(prob.u0)) # Use Finite Differencing
56-
use_sparse_ad ? AutoSparseFiniteDiff() : AutoFiniteDiff()
51+
use_sparse_ad ? AutoSparse(AutoFiniteDiff()) : AutoFiniteDiff()
5752
else
58-
(use_sparse_ad ? AutoSparseForwardDiff : AutoForwardDiff)()
53+
use_sparse_ad ? AutoSparse(AutoForwardDiff()) : AutoForwardDiff()
5954
end
6055
return ad
6156
end
6257

6358
function get_concrete_reverse_ad(
64-
autodiff::Union{ADTypes.AbstractReverseMode, ADTypes.AbstractFiniteDifferencesMode},
65-
prob, sp::Val{test_sparse} = True, args...; kwargs...) where {test_sparse}
66-
return autodiff
67-
end
68-
function get_concrete_reverse_ad(autodiff::Union{AutoZygote, AutoSparseZygote}, prob,
69-
sp::Val{test_sparse} = True, args...; kwargs...) where {test_sparse}
70-
if isinplace(prob)
59+
autodiff::ADTypes.AbstractADType, prob, sp::Val{test_sparse} = True,
60+
args...; check_reverse_mode = true, kwargs...) where {test_sparse}
61+
if !isa(ADTypes.mode(autodiff), ADTypes.ReverseMode) && check_reverse_mode
62+
@warn "$(autodiff)::$(typeof(autodiff)) is not a `ReverseMode`. Use with caution." maxlog=1
63+
end
64+
if autodiff <: Union{AutoZygote, AutoSparse{<:AutoZygote}} && isinplace(prob)
7165
@warn "Attempting to use Zygote.jl for inplace problems. Switching to FiniteDiff. \
7266
Sparsity even if present will be ignored for correctness purposes. Set \
7367
the reverse ad option to `nothing` to automatically select the best option \
7468
and exploit sparsity."
7569
return AutoFiniteDiff() # colorvec confusion will occur if we use FiniteDiff
70+
else
71+
return autodiff
7672
end
77-
return autodiff
78-
end
79-
function get_concrete_reverse_ad(
80-
autodiff::ADTypes.AbstractADType, prob, sp::Val{test_sparse} = True,
81-
args...; check_reverse_mode = true, kwargs...) where {test_sparse}
82-
if check_reverse_mode
83-
@warn "$(autodiff)::$(typeof(autodiff)) is not a \
84-
`Abstract(Forward/FiniteDifferences)Mode`. Use with caution." maxlog=1
85-
end
86-
return autodiff
8773
end
8874
function get_concrete_reverse_ad(
8975
autodiff, prob, sp::Val{test_sparse} = True, args...; kwargs...) where {test_sparse}
@@ -94,9 +80,9 @@ function get_concrete_reverse_ad(
9480
use_sparse_ad = false
9581
end
9682
ad = if isinplace(prob) || !is_extension_loaded(Val(:Zygote)) # Use Finite Differencing
97-
use_sparse_ad ? AutoSparseFiniteDiff() : AutoFiniteDiff()
83+
use_sparse_ad ? AutoSparse(AutoFiniteDiff()) : AutoFiniteDiff()
9884
else
99-
use_sparse_ad ? AutoSparseZygote() : AutoZygote()
85+
use_sparse_ad ? AutoSparse(AutoZygote()) : AutoZygote()
10086
end
10187
return ad
10288
end

src/internal/jacobian.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ end
154154

155155
# Sparsity Detection Choices
156156
@inline __sparsity_detection_alg(_, _) = NoSparsityDetection()
157-
@inline function __sparsity_detection_alg(f::NonlinearFunction, ad::AbstractSparseADType)
157+
@inline function __sparsity_detection_alg(f::NonlinearFunction, ad::AutoSparse)
158158
if f.sparsity === nothing
159159
if f.jac_prototype === nothing
160160
if is_extension_loaded(Val(:Symbolics))
@@ -185,7 +185,7 @@ end
185185

186186
if SciMLBase.has_colorvec(f)
187187
return PrecomputedJacobianColorvec(; jac_prototype, f.colorvec,
188-
partition_by_rows = ad isa ADTypes.AbstractSparseReverseMode)
188+
partition_by_rows = (ad isa AutoSparse && ADTypes.mode(ad) isa ADTypes.ReverseMode))
189189
else
190190
return JacPrototypeSparsityDetection(; jac_prototype)
191191
end

0 commit comments

Comments
 (0)