@@ -9,18 +9,110 @@ abstract type AbstractSparsityDetection <: AbstractMaybeSparsityDetection end
9
9
10
10
struct NoSparsityDetection <: AbstractMaybeSparsityDetection end
11
11
12
+ """
13
+ SymbolicsSparsityDetection(; alg = GreedyD1Color())
14
+
15
+ Use Symbolics to compute the sparsity pattern of the Jacobian. This requires `Symbolics.jl`
16
+ to be explicitly loaded.
17
+
18
+ ## Keyword Arguments
19
+
20
+ - `alg`: The algorithm used for computing the matrix colors
21
+
22
+ See Also: [JacPrototypeSparsityDetection](@ref), [PrecomputedJacobianColorvec](@ref)
23
+ """
12
24
Base. @kwdef struct SymbolicsSparsityDetection{A <: ArrayInterface.ColoringAlgorithm } < :
13
25
AbstractSparsityDetection
14
26
alg:: A = GreedyD1Color ()
15
27
end
16
28
29
+ """
30
+ JacPrototypeSparsityDetection(; jac_prototype, alg = GreedyD1Color())
31
+
32
+ Use a pre-specified `jac_prototype` to compute the matrix colors of the Jacobian.
33
+
34
+ ## Keyword Arguments
35
+
36
+ - `jac_prototype`: The prototype Jacobian used for computing the matrix colors
37
+ - `alg`: The algorithm used for computing the matrix colors
38
+
39
+ See Also: [SymbolicsSparsityDetection](@ref), [PrecomputedJacobianColorvec](@ref)
40
+ """
17
41
Base. @kwdef struct JacPrototypeSparsityDetection{
18
- J, A <: ArrayInterface.ColoringAlgorithm ,
19
- } <: AbstractSparsityDetection
42
+ J, A <: ArrayInterface.ColoringAlgorithm } <: AbstractSparsityDetection
20
43
jac_prototype:: J
21
44
alg:: A = GreedyD1Color ()
22
45
end
23
46
47
+ """
48
+ PrecomputedJacobianColorvec(jac_prototype, row_colorvec, col_colorvec)
49
+
50
+ Use a pre-specified `colorvec` which can be directly used for sparse differentiation. Based
51
+ on whether a reverse mode or forward mode or finite differences is used, the corresponding
52
+ `row_colorvec` or `col_colorvec` is used. Atmost one of them can be set to `nothing`.
53
+
54
+ ## Arguments
55
+
56
+ - `jac_prototype`: The prototype Jacobian used for computing structural nonzeros
57
+ - `row_colorvec`: The row colorvec of the Jacobian
58
+ - `col_colorvec`: The column colorvec of the Jacobian
59
+
60
+ See Also: [SymbolicsSparsityDetection](@ref), [JacPrototypeSparsityDetection](@ref)
61
+ """
62
+ struct PrecomputedJacobianColorvec{J, RC, CC} <: AbstractSparsityDetection
63
+ jac_prototype:: J
64
+ row_colorvec:: RC
65
+ col_colorvec:: CC
66
+ end
67
+
68
+ """
69
+ PrecomputedJacobianColorvec(; jac_prototype, partition_by_rows::Bool = false,
70
+ colorvec = missing, row_colorvec = missing, col_colorvec = missing)
71
+
72
+ Use a pre-specified `colorvec` which can be directly used for sparse differentiation. Based
73
+ on whether a reverse mode or forward mode or finite differences is used, the corresponding
74
+ `row_colorvec` or `col_colorvec` is used. Atmost one of them can be set to `nothing`.
75
+
76
+ ## Keyword Arguments
77
+
78
+ - `jac_prototype`: The prototype Jacobian used for computing structural nonzeros
79
+ - `partition_by_rows`: Whether to partition the Jacobian by rows or columns (row
80
+ partitioning is used for reverse mode AD)
81
+ - `colorvec`: The colorvec of the Jacobian. If `partition_by_rows` is `true` then this
82
+ is the row colorvec, otherwise it is the column colorvec
83
+ - `row_colorvec`: The row colorvec of the Jacobian
84
+ - `col_colorvec`: The column colorvec of the Jacobian
85
+
86
+ See Also: [SymbolicsSparsityDetection](@ref), [JacPrototypeSparsityDetection](@ref)
87
+ """
88
+ function PrecomputedJacobianColorvec (; jac_prototype, partition_by_rows:: Bool = false ,
89
+ colorvec = missing , row_colorvec = missing , col_colorvec = missing )
90
+ if colorvec === missing
91
+ @assert row_colorvec != = missing || col_colorvec != = missing " Either `colorvec` or `row_colorvec` and `col_colorvec` must be specified!"
92
+ row_colorvec = row_colorvec === missing ? nothing : row_colorvec
93
+ col_colorvec = col_colorvec === missing ? nothing : col_colorvec
94
+ return PrecomputedJacobianColorvec (jac_prototype, row_colorvec, col_colorvec)
95
+ else
96
+ @assert row_colorvec === missing && col_colorvec === missing " Specifying `colorvec` is incompatible with specifying `row_colorvec` or `col_colorvec`!"
97
+ row_colorvec = partition_by_rows ? colorvec : nothing
98
+ col_colorvec = partition_by_rows ? nothing : colorvec
99
+ return PrecomputedJacobianColorvec (jac_prototype, row_colorvec, col_colorvec)
100
+ end
101
+ end
102
+
103
+ function _get_colorvec (alg:: PrecomputedJacobianColorvec , ad)
104
+ cvec = alg. col_colorvec
105
+ @assert cvec!= = nothing " `col_colorvec` is nothing, but Forward Mode AD or Finite Differences is being used!"
106
+ return cvec
107
+ end
108
+
109
+ function _get_colorvec (alg:: PrecomputedJacobianColorvec , :: AbstractReverseMode )
110
+ cvec = alg. row_colorvec
111
+ @assert cvec!= = nothing " `row_colorvec` is nothing, but Reverse Mode AD is being used!"
112
+ return cvec
113
+ end
114
+
115
+ # No one should be using this currently
24
116
Base. @kwdef struct AutoSparsityDetection{A <: ArrayInterface.ColoringAlgorithm } < :
25
117
AbstractSparsityDetection
26
118
alg:: A = GreedyD1Color ()
@@ -41,7 +133,8 @@ Inplace update the matrix `J` with the Jacobian of `f` at `x` using the AD backe
41
133
function sparse_jacobian! end
42
134
43
135
"""
44
- sparse_jacobian_cache(ad::AbstractADType, sd::AbstractSparsityDetection, f, x; fx=nothing)
136
+ sparse_jacobian_cache(ad::AbstractADType, sd::AbstractSparsityDetection, f, x;
137
+ fx=nothing)
45
138
sparse_jacobian_cache(ad::AbstractADType, sd::AbstractSparsityDetection, f!, fx, x)
46
139
47
140
Takes the underlying AD backend `ad`, sparsity detection algorithm `sd`, function `f`,
@@ -67,7 +160,7 @@ with the same cache to compute the jacobian.
67
160
function sparse_jacobian (ad:: AbstractADType , sd:: AbstractMaybeSparsityDetection , args... ;
68
161
kwargs... )
69
162
cache = sparse_jacobian_cache (ad, sd, args... ; kwargs... )
70
- J = __init_𝒥 (cache)
163
+ J = init_jacobian (cache)
71
164
return sparse_jacobian! (J, ad, cache, args... )
72
165
end
73
166
@@ -80,7 +173,7 @@ Jacobian at every function call
80
173
"""
81
174
function sparse_jacobian (ad:: AbstractADType , cache:: AbstractMaybeSparseJacobianCache ,
82
175
args... )
83
- J = __init_𝒥 (cache)
176
+ J = init_jacobian (cache)
84
177
return sparse_jacobian! (J, ad, cache, args... )
85
178
end
86
179
@@ -106,7 +199,20 @@ function __gradient end
106
199
function __gradient! end
107
200
function __jacobian! end
108
201
109
- function __init_𝒥 end
202
+ """
203
+ init_jacobian(cache::AbstractMaybeSparseJacobianCache)
204
+
205
+ Initialize the Jacobian based on the cache. Uses sparse jacobians if possible.
206
+
207
+ !!! note
208
+ This function doesn't alias the provided jacobian prototype. It always initializes a
209
+ fresh jacobian that can be mutated without any side effects.
210
+ """
211
+ function init_jacobian end
212
+
213
+ # Never thought this was a useful function externally, but I ended up using it in quite a
214
+ # few places. Keeping this till I remove uses of those.
215
+ const __init_𝒥 = init_jacobian
110
216
111
217
# Misc Functions
112
218
__chunksize (:: AutoSparseForwardDiff{C} ) where {C} = C
@@ -123,12 +229,12 @@ end
123
229
return :(nothing )
124
230
end
125
231
126
- function __init_𝒥 (c:: AbstractMaybeSparseJacobianCache )
232
+ function init_jacobian (c:: AbstractMaybeSparseJacobianCache )
127
233
T = promote_type (eltype (c. fx), eltype (c. x))
128
- return __init_𝒥 (__getfield (c, Val (:jac_prototype )), T, c. fx, c. x)
234
+ return init_jacobian (__getfield (c, Val (:jac_prototype )), T, c. fx, c. x)
129
235
end
130
- __init_𝒥 (:: Nothing , :: Type{T} , fx, x) where {T} = similar (fx, T, length (fx), length (x))
131
- __init_𝒥 (J, :: Type{T} , _, _) where {T} = similar (J, T, size (J, 1 ), size (J, 2 ))
236
+ init_jacobian (:: Nothing , :: Type{T} , fx, x) where {T} = similar (fx, T, length (fx), length (x))
237
+ init_jacobian (J, :: Type{T} , _, _) where {T} = similar (J, T, size (J, 1 ), size (J, 2 ))
132
238
133
239
__maybe_copy_x (_, x) = x
134
240
__maybe_copy_x (_, :: Nothing ) = nothing
0 commit comments