2020
2121Tag (:: Nothing , :: Type{V} ) where {V} = nothing
2222
23+
2324@inline function ≺ (:: Type{Tag{F1,V1}} , :: Type{Tag{F2,V2}} ) where {F1,V1,F2,V2}
2425 tagcount (Tag{F1,V1}) < tagcount (Tag{F2,V2})
2526end
2627
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-
6728struct InvalidTagException{E,O} <: Exception
6829end
6930
@@ -75,22 +36,13 @@ checktag(::Type{Tag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT,VT,F,V} =
7536
7637checktag (:: Type{Tag{F,V}} , f:: F , x:: AbstractArray{V} ) where {F,V} = true
7738
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-
8839# no easy way to check Jacobian tag used with Hessians as multiple functions may be used
8940checktag (:: Type{Tag{FT,VT}} , f:: F , x:: AbstractArray{V} ) where {FT<: Tuple ,VT,F,V} = true
9041
9142# custom tag: you're on your own.
9243checktag (z, f, x) = true
9344
45+
9446# #################
9547# AbstractConfig #
9648# #################
@@ -103,21 +55,6 @@ Base.eltype(cfg::AbstractConfig) = eltype(typeof(cfg))
10355
10456@inline (chunksize (:: AbstractConfig{N} ):: Int ) where {N} = N
10557
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-
12158# ###################
12259# DerivativeConfig #
12360# ###################
@@ -171,9 +108,9 @@ vector `x`.
171108The returned `GradientConfig` instance contains all the work buffers required by
172109`ForwardDiff.gradient` and `ForwardDiff.gradient!`.
173110
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).
177114
178115This constructor does not store/modify `x`.
179116"""
@@ -208,9 +145,9 @@ The returned `JacobianConfig` instance contains all the work buffers required by
208145`ForwardDiff.jacobian` and `ForwardDiff.jacobian!` when the target function takes the form
209146`f(x)`.
210147
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).
214151
215152This constructor does not store/modify `x`.
216153"""
@@ -233,9 +170,9 @@ The returned `JacobianConfig` instance contains all the work buffers required by
233170`ForwardDiff.jacobian` and `ForwardDiff.jacobian!` when the target function takes the form
234171`f!(y, x)`.
235172
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).
239176
240177This constructor does not store/modify `y` or `x`.
241178"""
@@ -275,9 +212,9 @@ configured for the case where the `result` argument is an `AbstractArray`. If
275212it is a `DiffResult`, the `HessianConfig` should instead be constructed via
276213`ForwardDiff.HessianConfig(f, result, x, chunk)`.
277214
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).
281218
282219This constructor does not store/modify `x`.
283220"""
@@ -299,9 +236,9 @@ type/shape of the input vector `x`.
299236The returned `HessianConfig` instance contains all the work buffers required by
300237`ForwardDiff.hessian!` for the case where the `result` argument is an `DiffResult`.
301238
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).
305242
306243This constructor does not store/modify `x`.
307244"""
0 commit comments