20
20
21
21
Tag (:: Nothing , :: Type{V} ) where {V} = nothing
22
22
23
+
23
24
@inline function ≺ (:: Type{Tag{F1,V1}} , :: Type{Tag{F2,V2}} ) where {F1,V1,F2,V2}
24
25
tagcount (Tag{F1,V1}) < tagcount (Tag{F2,V2})
25
26
end
26
27
27
- """
28
- HashTag{Hash}
29
-
30
- HashTag is similar to a Tag, but carries just a small UInt64 hash,
31
- instead of the full type, which makes stacktraces / types easier to
32
- read while still providing good resilience to perturbation confusion.
33
- """
34
- struct HashTag{H}
35
- end
36
-
37
- @generated function tagcount (:: Type{HashTag{H}} ) where {H}
38
- :($ (Threads. atomic_add! (TAGCOUNT, UInt (1 ))))
39
- end
40
-
41
- function HashTag (f:: F , :: Type{V} ) where {F,V}
42
- H = if F <: Tuple
43
- # no easy way to check Jacobian tag used with Hessians as multiple functions may be used
44
- # see checktag(::Type{Tag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT<:Tuple,VT,F,V}
45
- nothing
46
- else
47
- hash (F) ⊻ hash (V)
48
- end
49
- tagcount (HashTag{H}) # trigger generated function
50
- HashTag {H} ()
51
- end
52
-
53
- HashTag (:: Nothing , :: Type{V} ) where {V} = nothing
54
-
55
- @inline function ≺ (:: Type{HashTag{H1}} , :: Type{Tag{F2,V2}} ) where {H1,F2,V2}
56
- tagcount (HashTag{H1}) < tagcount (Tag{F2,V2})
57
- end
58
-
59
- @inline function ≺ (:: Type{Tag{F1,V1}} , :: Type{HashTag{H2}} ) where {F1,V1,H2}
60
- tagcount (Tag{F1,V1}) < tagcount (HashTag{H2})
61
- end
62
-
63
- @inline function ≺ (:: Type{HashTag{H1}} , :: Type{HashTag{H2}} ) where {H1,H2}
64
- tagcount (HashTag{H1}) < tagcount (HashTag{H2})
65
- end
66
-
67
28
struct InvalidTagException{E,O} <: Exception
68
29
end
69
30
@@ -75,22 +36,13 @@ checktag(::Type{Tag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT,VT,F,V} =
75
36
76
37
checktag (:: Type{Tag{F,V}} , f:: F , x:: AbstractArray{V} ) where {F,V} = true
77
38
78
- # HashTag is a smaller tag, that only confirms the hash
79
- function checktag (:: Type{HashTag{HT}} , f:: F , x:: AbstractArray{V} ) where {HT,F,V}
80
- H = hash (F) ⊻ hash (V)
81
- if HT == H || HT === nothing
82
- true
83
- else
84
- throw (InvalidTagException {HashTag{H},HashTag{HT}} ())
85
- end
86
- end
87
-
88
39
# no easy way to check Jacobian tag used with Hessians as multiple functions may be used
89
40
checktag (:: Type{Tag{FT,VT}} , f:: F , x:: AbstractArray{V} ) where {FT<: Tuple ,VT,F,V} = true
90
41
91
42
# custom tag: you're on your own.
92
43
checktag (z, f, x) = true
93
44
45
+
94
46
# #################
95
47
# AbstractConfig #
96
48
# #################
@@ -103,21 +55,6 @@ Base.eltype(cfg::AbstractConfig) = eltype(typeof(cfg))
103
55
104
56
@inline (chunksize (:: AbstractConfig{N} ):: Int ) where {N} = N
105
57
106
- @inline function maketag (f, X; style:: Union{Symbol,Nothing} = nothing )
107
- if style === :hash
108
- return HashTag (f, X)
109
- elseif style === :type
110
- return Tag (f, X)
111
- elseif style === nothing
112
- if VERSION ≥ v " 1.11"
113
- return HashTag (f, X)
114
- else
115
- return Tag (f, X)
116
- end
117
- end
118
- error (" unexpected tag style: $(style) " )
119
- end
120
-
121
58
# ###################
122
59
# DerivativeConfig #
123
60
# ###################
@@ -171,9 +108,9 @@ vector `x`.
171
108
The returned `GradientConfig` instance contains all the work buffers required by
172
109
`ForwardDiff.gradient` and `ForwardDiff.gradient!`.
173
110
174
- If `f` or `tag` is `nothing`, then the returned instance can be used with any target function.
175
- However, this will reduce ForwardDiff's ability to catch and prevent perturbation confusion
176
- (see https://github.com/JuliaDiff/ForwardDiff.jl/issues/83).
111
+ If `f` is `nothing` instead of the actual target function, then the returned instance can
112
+ be used with any target function. However, this will reduce ForwardDiff's ability to catch
113
+ and prevent perturbation confusion (see https://github.com/JuliaDiff/ForwardDiff.jl/issues/83).
177
114
178
115
This constructor does not store/modify `x`.
179
116
"""
@@ -208,9 +145,9 @@ The returned `JacobianConfig` instance contains all the work buffers required by
208
145
`ForwardDiff.jacobian` and `ForwardDiff.jacobian!` when the target function takes the form
209
146
`f(x)`.
210
147
211
- If `f` or `tag` is `nothing`, then the returned instance can be used with any target function.
212
- However, this will reduce ForwardDiff's ability to catch and prevent perturbation confusion
213
- (see https://github.com/JuliaDiff/ForwardDiff.jl/issues/83).
148
+ If `f` is `nothing` instead of the actual target function, then the returned instance can
149
+ be used with any target function. However, this will reduce ForwardDiff's ability to catch
150
+ and prevent perturbation confusion (see https://github.com/JuliaDiff/ForwardDiff.jl/issues/83).
214
151
215
152
This constructor does not store/modify `x`.
216
153
"""
@@ -233,9 +170,9 @@ The returned `JacobianConfig` instance contains all the work buffers required by
233
170
`ForwardDiff.jacobian` and `ForwardDiff.jacobian!` when the target function takes the form
234
171
`f!(y, x)`.
235
172
236
- If `f!` or `tag` is `nothing`, then the returned instance can be used with any target function.
237
- However, this will reduce ForwardDiff's ability to catch and prevent perturbation confusion
238
- (see https://github.com/JuliaDiff/ForwardDiff.jl/issues/83).
173
+ If `f!` is `nothing` instead of the actual target function, then the returned instance can
174
+ be used with any target function. However, this will reduce ForwardDiff's ability to catch
175
+ and prevent perturbation confusion (see https://github.com/JuliaDiff/ForwardDiff.jl/issues/83).
239
176
240
177
This constructor does not store/modify `y` or `x`.
241
178
"""
@@ -275,9 +212,9 @@ configured for the case where the `result` argument is an `AbstractArray`. If
275
212
it is a `DiffResult`, the `HessianConfig` should instead be constructed via
276
213
`ForwardDiff.HessianConfig(f, result, x, chunk)`.
277
214
278
- If `f` or `tag` is `nothing`, then the returned instance can be used with any target function.
279
- However, this will reduce ForwardDiff's ability to catch and prevent perturbation confusion
280
- (see https://github.com/JuliaDiff/ForwardDiff.jl/issues/83).
215
+ If `f` is `nothing` instead of the actual target function, then the returned instance can
216
+ be used with any target function. However, this will reduce ForwardDiff's ability to catch
217
+ and prevent perturbation confusion (see https://github.com/JuliaDiff/ForwardDiff.jl/issues/83).
281
218
282
219
This constructor does not store/modify `x`.
283
220
"""
@@ -299,9 +236,9 @@ type/shape of the input vector `x`.
299
236
The returned `HessianConfig` instance contains all the work buffers required by
300
237
`ForwardDiff.hessian!` for the case where the `result` argument is an `DiffResult`.
301
238
302
- If `f` or `tag` is `nothing`, then the returned instance can be used with any target function.
303
- However, this will reduce ForwardDiff's ability to catch and prevent perturbation confusion
304
- (see https://github.com/JuliaDiff/ForwardDiff.jl/issues/83).
239
+ If `f` is `nothing` instead of the actual target function, then the returned instance can
240
+ be used with any target function. However, this will reduce ForwardDiff's ability to catch
241
+ and prevent perturbation confusion (see https://github.com/JuliaDiff/ForwardDiff.jl/issues/83).
305
242
306
243
This constructor does not store/modify `x`.
307
244
"""
0 commit comments