Multi-/named-output submodels silently ignore `where { ... }` options (inline variational constraints)

Open Beginner friendly
#304 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
82/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
julia

Research direction

Start in src/model_macro.jl at get_make_node_function, comparing the single-output path around line 838 with the tuple and NamedTuple paths around lines 860 and 882. Review the existing inline-constraints test in test/plugins/variational_constraints/variational_constraints_tests.jl around line 1135, then add coverage for multi- and named-output calls. Done means both forms honor the where { constraints = ... } option.

Written by the indexing model from the issue text.

Description

Summary

When a composite submodel is invoked with a multi-output ((a, b) ~ sub(...)) or
named-output ((a = x, b = y) ~ sub(...)) left-hand side, the child Context is
constructed without the NodeCreationOptions carried by the where { ... } clause.
As a result, inline where { constraints = ... } (e.g. a MeanField or custom factorization
constraint) is silently ignored for that submodel.

Impact

Silent wrong behaviour: inference runs with a different (unconstrained / different
factorization) recognition distribution than the user requested — no warning is emitted.

Root cause

src/model_macro.jl get_make_node_function:

  • single-output LHS (line 838): Context(__parent_context__, $ms_name, __options__)
  • Tuple LHS (line 860): Context(__parent_context__, $ms_name)
  • NamedTuple LHS (line 882): Context(__parent_context__, $ms_name)

The constraint engine reads inline constraints from that field:

src/plugins/variational_constraints/variational_constraints_engine.jl:1003
inline_constraints = get(context_options(child), :constraints, nothing)

with context_options(context) = something(context.options, EmptyNodeCreationOptions)
(src/graph_engine.jl:668). When context.options === nothing it returns
EmptyNodeCreationOptions, so :constraints is never found.

Repro

using GraphPPL, Distributions
import GraphPPL: @model

@model function two_out(a, b, x)
    a ~ Normal(x, 1.0)
    b ~ Normal(a, 1.0)
end

@model function outer_multi(x)
    (a, b) ~ two_out(x = x) where { constraints = GraphPPL.MeanField() }
end

model = GraphPPL.create_model(outer_multi()) do m, ctx
    x = GraphPPL.datalabel(m, ctx, GraphPPL.NodeCreationOptions(kind=:data), :x, 1.0)
    return (x = x,)
end
ctx = GraphPPL.getcontext(model)
for (fid, child) in GraphPPL.pairs(GraphPPL.children(ctx))
    @show child.options          # => nothing  (single-output equivalent: NodeCreationOptions)
end

The equivalent single-output call honors it (see the existing "inline constraints on
submodel calls" test, test/plugins/variational_constraints/variational_constraints_tests.jl:1135).

Expected

Inline where { constraints = ... } behaves identically for multi-/named-output submodel
calls as for single-output calls.

Suggested fix

Pass __options__ in both multi-output paths (mirroring line 838) plus a regression test.

Dominant language
Julia
Stars
46
Forks
8
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from ReactiveBayes/GraphPPL.jl

All issues in ReactiveBayes/GraphPPL.jl

Similar issues

More Julia issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.