Skip to content

Add AbstractMCMC-based Gibbs combinator#204

Open
singhharsh1708 wants to merge 2 commits into
TuringLang:mainfrom
singhharsh1708:gibbs-interface
Open

Add AbstractMCMC-based Gibbs combinator#204
singhharsh1708 wants to merge 2 commits into
TuringLang:mainfrom
singhharsh1708:gibbs-interface

Conversation

@singhharsh1708
Copy link
Copy Markdown

@singhharsh1708 singhharsh1708 commented May 20, 2026

Add model-agnostic Gibbs combinator

Turing.jl and JuliaBUGS.jl currently each have their own separate Gibbs implementation with no shared code. This PR adds a single Gibbs combinator to AbstractMCMC that any PPL can plug into.

The extension interface is three functions per model type:

condition(model, target_vars, global_values) — return a model conditioned on non-target variables
_init_global_values — initialise the global parameter store from the first component's state
_update_global_values — merge new sampled values back into the global store
Component samplers only need the existing getparams/setparams!! interface.

Turing.jl and JuliaBUGS.jl wiring is in separate PRs.

Copy link
Copy Markdown
Member

@shravanngoswamii shravanngoswamii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Being candid since this targets AbstractMCMC, one of the most depended-on packages in the Turing ecosystem -- a single bad API addition here affects many downstream packages. This PR has both design problems and real correctness/quality bugs. Please settle the interface design first, and fix the bugs listed below before the next review round.

  • Nothing is exported. If this is meant as a public API, export it. If it is not, the docstring should not claim it is.
  • condition will collide with AbstractPPL.condition for any user doing using AbstractMCMC, AbstractPPL.
  • _init_global_values / _update_global_values / _build_gibbs_transition are part of the extension interface that downstream packages must implement, but the leading underscore signals "private." Drop the underscore, or move them to an internal module.
  • initial_params is reused for global_values. Everywhere else in AbstractMCMC, initial_params is a flat Vector{<:Real}. Pick a new kwarg name.
  • The docstring says global_values is "an associative collection mapping identifiers to their current raw values," and then on the first init step you pass nothing. Either fix the doc or fix the call site.
  • GibbsState does not itself implement getparams / setparams!! / getstats. That means it cannot be nested inside another Gibbs, cannot be used by callbacks that expect getparams(state), and breaks the same contract this PR demands of its components.
  • using Turing in tests cannot work: Turing depends on AbstractMCMC, so this is a hard circular dependency. The tests must be written using AbstractMCMC primitives only, plus a small hand-written model and a small sampler that implements the contract.

Comment thread test/gibbs_test.jl
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not included in test/runtests.jl, so you only know this PR "works" because of whatever you ran locally.

Comment thread test/gibbs_test.jl
using Test
using Random
using AbstractMCMC
using Turing
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Project.toml's [extras] / test target not updated

Comment thread src/gibbs.jl

Downstream packages implement this per model type. There is no default.
"""
function condition end
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure condition belongs here? AbstractMCMC's design (https://turinglang.org/AbstractMCMC.jl/stable/design/) is deliberately minimal and PPL-agnostic. condition is a PPL concept and AbstractPPL.condition already exists.

Comment thread src/gibbs.jl
Comment on lines +32 to +33
sampler = Gibbs(@varname(μ) => NUTS(), @varname(σ) => MH())
chain = sample(model, sampler, 1000)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@varname, NUTS, MH, and model are not defined in AbstractMCMC. A reader cannot run this example using only this package. Either rewrite it with AbstractMCMC primitives, or move it to a "Downstream usage" section that names Turing explicitly.

Comment thread src/gibbs.jl
chain = sample(model, sampler, 1000)
```
"""
struct Gibbs{N,S} <: AbstractSampler
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constructor validation is too thin. The docstring says "All model variables must be covered by exactly one group," but the only check is length(varnames) == length(samplers). Overlapping groups, empty groups, and zero pairs all silently produce undefined behaviour. Please validate that the groups are disjoint and non-empty.

@shravanngoswamii
Copy link
Copy Markdown
Member

@singhharsh1708 Please read CONTRIBUTING.md and organization wide IMPORTANT section in organization README: https://github.com/TuringLang

It's fine if you use AI for this but it was a GSoC project meant to learn how to engage in open source softwares and how to understand them and contribute positively. Atleast discuss this with team before implementing.

@shravanngoswamii
Copy link
Copy Markdown
Member

@sunxd3 Can you see if this should be continued here or discussed first?

@singhharsh1708
Copy link
Copy Markdown
Author

@shravanngoswamii You're right — I should have opened a discussion issue first before sending code. I used AI assistance to help implement this, but I understand that for a package this central, the interface design needs to be agreed on with the team before any implementation. I'll close these PRs and open a design discussion first. will that be fine?

@shravanngoswamii
Copy link
Copy Markdown
Member

shravanngoswamii commented May 21, 2026

I'll close these PRs and open a design discussion first. will that be fine?

Yep, @sunxd3 Can you please see how this should be continued...

@sunxd3
Copy link
Copy Markdown
Member

sunxd3 commented May 21, 2026

A constraint is that unless we can find an interface that DynamicPPL can use without (1) performance penalty and (2) support all the inference algorithms (tricky ones are the particle/SMC), it won't get adopted by Turing.

This is not trivial, otherwise Penny (Markus and Tor) would have done it already.

Start by designing is definitely the right approach and one of the first questions to think about is why we need the GibbsContext in Turing.

@shravanngoswamii
Copy link
Copy Markdown
Member

@singhharsh1708 Your approach is correct, you just need to have to some more context of how these are shared and should be designed across the ecosystem. I will not close it. Let's discuss this first in a issue. Feel free to open and wait for response from the team.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants