Skip to content

RuleMethodError: improve debugging information #366

Closed
@fonsp

Description

@fonsp

Hello! 👋

I was experimenting with error messages in RxInfer, and talking with @Nimrais we found one example where the error message could really improve.

I followed the example from https://reactivebayes.github.io/RxInfer.jl/stable/examples/basic_examples/Bayesian%20Linear%20Regression%20Tutorial/ , but I removed the . broadcasting in the definition of y:

Before:

@model function linear_regression(x, y)
    a ~ Normal(mean = 0.0, variance = 1.0)
    b ~ Normal(mean = 0.0, variance = 100.0)    
    y .~ Normal(mean = a .* x .+ b, variance = 1.0)
end

After:

@model function linear_regression(x, y)
    a ~ Normal(mean = 0.0, variance = 1.0)
    b ~ Normal(mean = 0.0, variance = 100.0)    
    y .~ Normal(mean = a * x + b, variance = 1.0)
end

Error message:

ERROR: RuleMethodError: no method matching rule for the given arguments

Possible fix, define:

@rule typeof(*)(:A, Marginalisation) (m_out::NormalMeanVariance, m_in::PointMass, meta::MatrixCorrectionTools.ReplaceZeroDiagonalEntries{TinyHugeNumbers.TinyNumber}) = begin 
    return ...
end


Stacktrace:
  [1] (::ReactiveMP.MessageMapping{…})(messages::Tuple{…}, marginals::Nothing)
    @ ReactiveMP ~/.julia/packages/ReactiveMP/G3hZ2/src/message.jl:357
  [2] as_message(message::DeferredMessage{…}, cache::Nothing, messages::Tuple{…}, marginals::Nothing)
    @ ReactiveMP ~/.julia/packages/ReactiveMP/G3hZ2/src/message.jl:235
  [3] as_message(message::DeferredMessage{Tuple{…}, Nothing, ReactiveMP.MessageMapping{…}}, cache::Nothing)
    @ ReactiveMP ~/.julia/packages/ReactiveMP/G3hZ2/src/message.jl:231
  [4] as_message(message::DeferredMessage{Tuple{…}, Nothing, ReactiveMP.MessageMapping{…}})
    @ ReactiveMP ~/.julia/packages/ReactiveMP/G3hZ2/src/message.jl:223
  [5] MappingRF
    @ ./reduce.jl:100 [inlined]
  [6] _foldl_impl(op::Base.MappingRF{…}, init::Base._InitialValue, itr::Vector{…})
    @ Base ./reduce.jl:62
  [7] foldl_impl
    @ ./reduce.jl:48 [inlined]
  [8] mapfoldl_impl
    @ ./reduce.jl:44 [inlined]
  [9] mapfoldl
    @ ./reduce.jl:175 [inlined]
 [10] foldl
    @ ./reduce.jl:198 [inlined]
 [11] (::ReactiveMP.var"#15#17"{GenericProd, CompositeFormConstraint{Tuple{…}}})(messages::Vector{AbstractMessage})
    @ ReactiveMP ~/.julia/packages/ReactiveMP/G3hZ2/src/message.jl:149
 [12] (::ReactiveMP.var"#119#120"{ReactiveMP.var"#15#17"{…}})(messages::Vector{AbstractMessage})
    @ ReactiveMP ~/.julia/packages/ReactiveMP/G3hZ2/src/variables/variable.jl:36
 [13] next_received!(wrapper::Rocket.CollectLatestObservableWrapper{…}, data::DeferredMessage{…}, index::CartesianIndex{…})
    @ Rocket ~/.julia/packages/Rocket/LrFUI/src/observable/collected.jl:103
 [14] on_next!
    @ ~/.julia/packages/Rocket/LrFUI/src/observable/collected.jl:93 [inlined]
 [15] scheduled_next!(actor::Rocket.CollectLatestObservableInnerActor{…}, value::DeferredMessage{…}, ::AsapScheduler)
    @ Rocket ~/.julia/packages/Rocket/LrFUI/src/schedulers/asap.jl:23
 [16] on_next!(subject::Subject{…}, data::DeferredMessage{…})
    @ Rocket ~/.julia/packages/Rocket/LrFUI/src/subjects/subject.jl:62
 [17] actor_on_next!
    @ ~/.julia/packages/Rocket/LrFUI/src/actor.jl:250 [inlined]
 [18] next!
    @ ~/.julia/packages/Rocket/LrFUI/src/actor.jl:202 [inlined]
 [19] on_next!
    @ ~/.julia/packages/Rocket/LrFUI/src/subjects/recent.jl:62 [inlined]
 [20] actor_on_next!
    @ ~/.julia/packages/Rocket/LrFUI/src/actor.jl:250 [inlined]
 [21] next!
    @ ~/.julia/packages/Rocket/LrFUI/src/actor.jl:202 [inlined]
 [22] on_next!
    @ ~/.julia/packages/Rocket/LrFUI/src/operators/map.jl:62 [inlined]
 [23] next!
    @ ~/.julia/packages/Rocket/LrFUI/src/actor.jl:206 [inlined]
 [24] next_received!
    @ ~/.julia/packages/Rocket/LrFUI/src/observable/combined.jl:101 [inlined]
 [25] on_next!
    @ ~/.julia/packages/Rocket/LrFUI/src/observable/combined.jl:68 [inlined]
 [26] next!
    @ ~/.julia/packages/Rocket/LrFUI/src/actor.jl:206 [inlined]
 [27] next_received!
    @ ~/.julia/packages/Rocket/LrFUI/src/observable/combined_updates.jl:72 [inlined]
 [28] on_next!
    @ ~/.julia/packages/Rocket/LrFUI/src/observable/combined_updates.jl:34 [inlined]
 [29] scheduled_next!(actor::Rocket.CombineLatestUpdatesInnerActor{…}, value::Message{…}, ::AsapScheduler)
    @ Rocket ~/.julia/packages/Rocket/LrFUI/src/schedulers/asap.jl:23
 [30] on_next!(subject::Subject{Message, AsapScheduler, AsapScheduler}, data::Message{PointMass{Vector{Float64}}, Nothing})
    @ Rocket ~/.julia/packages/Rocket/LrFUI/src/subjects/subject.jl:62
 [31] actor_on_next!(::BaseActorTrait{…}, actor::Subject{…}, data::Message{…})
    @ Rocket ~/.julia/packages/Rocket/LrFUI/src/actor.jl:250
 [32] next!
    @ ~/.julia/packages/Rocket/LrFUI/src/actor.jl:202 [inlined]
 [33] on_next!
    @ ~/.julia/packages/Rocket/LrFUI/src/subjects/recent.jl:62 [inlined]
 [34] actor_on_next!
    @ ~/.julia/packages/Rocket/LrFUI/src/actor.jl:250 [inlined]
 [35] next!
    @ ~/.julia/packages/Rocket/LrFUI/src/actor.jl:202 [inlined]
 [36] update!
    @ ~/.julia/packages/ReactiveMP/G3hZ2/src/variables/data.jl:85 [inlined]
 [37] update!(datavar::DataVariable{Rocket.RecentSubjectInstance{…}, ReactiveMP.MarginalObservable}, data::Vector{Float64})
    @ ReactiveMP ~/.julia/packages/ReactiveMP/G3hZ2/src/variables/data.jl:84
 [38] batch_inference(; model::GraphPPL.ModelGenerator{…}, data::@NamedTuple{…}, initialization::RxInfer.InitSpecification, constraints::Nothing, meta::Nothing, options::Nothing, returnvars::Nothing, predictvars::Nothing, iterations::Int64, free_energy::Bool, free_energy_diagnostics::Tuple{…}, allow_node_contraction::Bool, showprogress::Bool, callbacks::Nothing, addons::Nothing, postprocess::DefaultPostprocess, warn::Bool, catch_exception::Bool)
    @ RxInfer ~/.julia/packages/RxInfer/vPXLG/src/inference/batch.jl:304
 [39] batch_inference
    @ ~/.julia/packages/RxInfer/vPXLG/src/inference/batch.jl:96 [inlined]
 [40] #infer#244
    @ ~/.julia/packages/RxInfer/vPXLG/src/inference/inference.jl:307 [inlined]
 [41] top-level scope
    @ ~/.julia/packages/RxInfer/vPXLG/src/model/plugins/initialization_plugin.jl:225
Some type information was truncated. Use `show(err)` to see complete types.

The information that is missing in the error message is:

  • which rule was applied? (*, currently hidden in the possible fix)
  • what types was it being applied on?
  • where does this happen in the model definition? this could be:
    • what are the variable names that it was applied on? (a and x)
    • the line where it happened (y .~ Normal(mean = a * x + b, variance = 1.0))

(Base.Experimental.register_error_hint might be useful here.)

When you do something similar in base Julia, you get a MethodError, and the error message answers these three questions:

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions