22# Tag #
33# ######
44
5- struct Tag{F,M} end
5+ struct Tag{F,H} end
6+
7+ # Here, we could've just as easily used `hash`; however, this
8+ # is unsafe/undefined behavior if `hash(::Type{V})` is overloaded
9+ # in a module loaded after ForwardDiff. Thus, we instead use
10+ # `hash(Symbol(V))`, which is somewhat safer since it's far less
11+ # likely that somebody would overwrite the Base definition for
12+ # `Symbol(::DataType)` or `hash(::Symbol)`.
13+ @generated function Tag (:: Type{F} , :: Type{V} ) where {F,V}
14+ H = hash (Symbol (V))
15+ return quote
16+ $ (Expr (:meta , :inline ))
17+ Tag {F,$H} ()
18+ end
19+ end
620
721# ########
822# Chunk #
3751
3852abstract type AbstractConfig{T<: Tag ,N} end
3953
40- struct ConfigMismatchError{F,G,M } <: Exception
54+ struct ConfigMismatchError{F,G,H } <: Exception
4155 f:: F
42- cfg:: AbstractConfig{Tag{G,M }}
56+ cfg:: AbstractConfig{Tag{G,H }}
4357end
4458
4559function Base. showerror {F,G} (io:: IO , e:: ConfigMismatchError{F,G} )
6781function GradientConfig {V,N,F,T} (:: F ,
6882 x:: AbstractArray{V} ,
6983 :: Chunk{N} = Chunk (x),
70- :: T = Tag {F,order(V)} ( ))
84+ :: T = Tag (F, V ))
7185 seeds = construct_seeds (Partials{N,V})
7286 duals = similar (x, Dual{T,V,N})
7387 return GradientConfig {T,V,N,typeof(duals)} (seeds, duals)
8599function JacobianConfig {V,N,F,T} (:: F ,
86100 x:: AbstractArray{V} ,
87101 :: Chunk{N} = Chunk (x),
88- :: T = Tag {F,order(V)} ( ))
102+ :: T = Tag (F, V ))
89103 seeds = construct_seeds (Partials{N,V})
90104 duals = similar (x, Dual{T,V,N})
91105 return JacobianConfig {T,V,N,typeof(duals)} (seeds, duals)
@@ -95,7 +109,7 @@ function JacobianConfig{Y,X,N,F,T}(::F,
95109 y:: AbstractArray{Y} ,
96110 x:: AbstractArray{X} ,
97111 :: Chunk{N} = Chunk (x),
98- :: T = Tag {F,order(X)} ( ))
112+ :: T = Tag (F, X ))
99113 seeds = construct_seeds (Partials{N,X})
100114 yduals = similar (y, Dual{T,Y,N})
101115 xduals = similar (x, Dual{T,X,N})
@@ -107,15 +121,15 @@ end
107121# HessianConfig #
108122# ################
109123
110- struct HessianConfig{T,V,N,D,MJ ,DJ} <: AbstractConfig{T,N}
111- jacobian_config:: JacobianConfig{Tag{Void,MJ },V,N,DJ}
112- gradient_config:: GradientConfig{T,Dual{Tag{Void,MJ },V,N},D}
124+ struct HessianConfig{T,V,N,D,H ,DJ} <: AbstractConfig{T,N}
125+ jacobian_config:: JacobianConfig{Tag{Void,H },V,N,DJ}
126+ gradient_config:: GradientConfig{T,Dual{Tag{Void,H },V,N},D}
113127end
114128
115129function HessianConfig {F,V} (f:: F ,
116130 x:: AbstractArray{V} ,
117131 chunk:: Chunk = Chunk (x),
118- tag:: Tag = Tag {F,order( Dual{Void,V,0})} ( ))
132+ tag:: Tag = Tag (F, Dual{Void,V,0 }))
119133 jacobian_config = JacobianConfig (nothing , x, chunk)
120134 gradient_config = GradientConfig (f, jacobian_config. duals, chunk, tag)
121135 return HessianConfig (jacobian_config, gradient_config)
@@ -125,7 +139,7 @@ function HessianConfig{F,V}(result::DiffResult,
125139 f:: F ,
126140 x:: AbstractArray{V} ,
127141 chunk:: Chunk = Chunk (x),
128- tag:: Tag = Tag {F,order( Dual{Void,V,0})} ( ))
142+ tag:: Tag = Tag (F, Dual{Void,V,0 }))
129143 jacobian_config = JacobianConfig (nothing , DiffBase. gradient (result), x, chunk)
130144 gradient_config = GradientConfig (f, jacobian_config. duals[2 ], chunk, tag)
131145 return HessianConfig (jacobian_config, gradient_config)
0 commit comments