Skip to content

Commit 6a8c3c2

Browse files
authored
Merge pull request #662 from JuliaDiff/ox/donot_zero
Define a bunch of zero_tangents that should just NoTangent
2 parents 0385ea8 + a105ba9 commit 6a8c3c2

3 files changed

Lines changed: 31 additions & 4 deletions

File tree

src/tangent_types/abstract_zero.jl

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,6 @@ function zero_tangent end
112112

113113
zero_tangent(x::Number) = zero(x)
114114

115-
zero_tangent(::Type) = NoTangent()
116-
117115
function zero_tangent(x::MutableTangent{P}) where {P}
118116
zb = backing(zero_tangent(backing(x)))
119117
return MutableTangent{P}(zb)
@@ -171,10 +169,25 @@ function zero_tangent(x::Array{P,N}) where {P,N}
171169
return y
172170
end
173171

172+
function zero_tangent(::T) where {K,V,T<:AbstractDict{K,V}}
173+
return Tangent{T}(Dict{K,guess_zero_tangent_type(V)}())
174+
end
175+
174176
# Sad heauristic methods we need because of unassigned values
175177
guess_zero_tangent_type(::Type{T}) where {T<:Number} = T
176178
guess_zero_tangent_type(::Type{T}) where {T<:Integer} = typeof(float(zero(T)))
177179
function guess_zero_tangent_type(::Type{<:Array{T,N}}) where {T,N}
178180
return Array{guess_zero_tangent_type(T),N}
179181
end
180-
guess_zero_tangent_type(T::Type) = Any
182+
guess_zero_tangent_type(T::Type) = Any
183+
184+
# Stuff that conceptually has its own identity regardless of structual implementation and doesn't have a tangent
185+
zero_tangent(::Base.AbstractLogger) = NoTangent()
186+
187+
# Prevent zero_tangent going wild on the internals
188+
zero_tangent(::Type) = NoTangent()
189+
zero_tangent(::Expr) = NoTangent()
190+
zero_tangent(::Core.Compiler.AbstractInterpreter) = NoTangent()
191+
zero_tangent(::Core.Compiler.InstructionStream) = NoTangent()
192+
zero_tangent(::Core.CodeInfo) = NoTangent()
193+
zero_tangent(::Core.MethodInstance) = NoTangent()

src/tangent_types/structural_tangent.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ function Tangent{P}() where {P<:Tuple}
340340
return Tangent{P,typeof(backing)}(backing)
341341
end
342342

343-
function Tangent{P}(d::Dict) where {P<:Dict}
343+
function Tangent{P}(d::Dict) where {P<:AbstractDict}
344344
return Tangent{P,typeof(d)}(d)
345345
end
346346

test/tangent_types/abstract_zero.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,18 @@ end
183183

184184
@test zero_tangent((1.0, 2.0)) == Tangent{Tuple{Float64,Float64}}(0.0, 0.0)
185185

186+
@test ==(
187+
zero_tangent(Dict{Int, Float64}(1 => 2.4)),
188+
Tangent{Dict{Int,Float64}}(Dict{Int, Float64}())
189+
)
190+
if isdefined(Base, :PersistentDict)
191+
@test ==(
192+
zero_tangent(Base.PersistentDict(1 => 2.4)),
193+
Tangent{Base.PersistentDict{Int,Float64}}(Dict{Int, Float64}())
194+
)
195+
end
196+
197+
186198
# Higher order
187199
# StructuralTangents are valid tangents for themselves (just like Numbers)
188200
# and indeed we prefer that, otherwise higher order structural tangents are kinda
@@ -200,6 +212,8 @@ end
200212
@test iszero(zero_tangent(:abc))
201213
@test iszero(zero_tangent("abc"))
202214
@test iszero(zero_tangent(sin))
215+
216+
@test iszero(zero_tangent(:(1 + 1)))
203217
end
204218

205219
@testset "undef elements Vector" begin

0 commit comments

Comments
 (0)