Skip to content

TypelessZero convert ambiguity with ForwardDiff dual numbers #153

Description

@THargreaves

TypelessZero has an ambiguous convert method when ForwardDiff dual numbers are involved. This occurs when trying to AD through a full particle filter pass (e.g. what happens when you initialise MH with an adtype since Turing v0.43.3.

MethodError: convert(::Type{ForwardDiff.Dual{T, V, N}}, ::GeneralisedFilters.TypelessZero) is ambiguous.

Candidates:
  convert(::Type{ForwardDiff.Dual{T, V, N}}, x::Number) where {T, V, N}
    @ ForwardDiff
  convert(::Type{T}, ::GeneralisedFilters.TypelessZero) where T<:Number
    @ GeneralisedFilters .../containers.jl:17

Context

This surfaces when using GeneralisedFilters inside a Turing model and running PMMH via Turing.externalsampler. As of Turing v0.43.3, parameter initialisation was unified between HMC and external samplers — external samplers now call logdensity_and_gradient during initialisation by default. This causes ForwardDiff dual numbers to flow through the filter even for gradient-free samplers, hitting the ambiguity.

Workaround

Ideally we would just do,

Turing.externalsampler(RobustAdaptiveMetropolis(; S=S); adtype=nothing)

but ExternalSampler forces a ADTypes.AbstractADType rather than an optional Nothing. This might be something that needs fixing upstream.

For now I'm just going to use Mooncake.

Fix

I think we can add a more specific convert method in containers.jl to resolve the ambiguity.

Base.convert(
    ::Type{ForwardDiff.Dual{T,V,N}}, ::TypelessZero
) where {T,V,N} = zero(ForwardDiff.Dual{T,V,N})

Though I question if this suggests there is a more fundamental structural issue so didn't want to jump in too quickly.

@charlesknipp would appreciate your thoughts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions