Skip to content

v0.10 #305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft

v0.10 #305

wants to merge 19 commits into from

Conversation

sunxd3
Copy link
Member

@sunxd3 sunxd3 commented May 28, 2025

This is to address #296. The changes required from current main branch will be substantial.

The current approach is that I'll gradually merge PR into v0.10 branch. And eventually make a non-squash merge.

I am not entirely clear about the code change that are required, so I might flip-flop on ideas and design, but I'll make the motivation and changes clear.

I will likely to move fast and not request a lot of reviews, and sometimes code changes will break some tests, but their corresponding test will pass. And before merging , all tests will pass.

TODO: disabling experimental test for now, revive later.

sunxd3 and others added 2 commits May 28, 2025 15:52
Introduce improved functions and tests.

This PR is purely additive, no old code is removed - this will be done
later.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
Contributor

JuliaBUGS.jl documentation for PR #305 is available at:
https://TuringLang.github.io/JuliaBUGS.jl/previews/PR305/

@coveralls
Copy link

coveralls commented May 28, 2025

Pull Request Test Coverage Report for Build 15559296011

Details

  • 650 of 722 (90.03%) changed or added relevant lines in 17 files are covered.
  • 285 unchanged lines in 5 files lost coverage.
  • Overall coverage decreased (-7.8%) to 75.696%

Changes Missing Coverage Covered Lines Changed/Added Lines %
ext/JuliaBUGSGraphMakieExt.jl 0 1 0.0%
ext/JuliaBUGSGraphPlotExt.jl 0 1 0.0%
src/model/bugsmodel.jl 161 162 99.38%
src/model/evaluation.jl 79 80 98.75%
src/source_gen.jl 0 1 0.0%
src/graphs.jl 58 60 96.67%
src/gibbs.jl 81 85 95.29%
src/model/abstractppl.jl 148 154 96.1%
ext/JuliaBUGSMCMCChainsExt.jl 16 27 59.26%
src/model/utils.jl 45 56 80.36%
Files with Coverage Reduction New Missed Lines %
src/parser/bugs_macro.jl 1 78.18%
src/compiler_pass.jl 6 93.61%
src/experimental/ProbabilisticGraphicalModels/conditioning.jl 31 0.0%
src/experimental/ProbabilisticGraphicalModels/functions.jl 70 0.0%
src/experimental/ProbabilisticGraphicalModels/bayesian_network.jl 177 0.0%
Totals Coverage Status
Change from base Build 15511201412: -7.8%
Covered Lines: 2121
Relevant Lines: 2802

💛 - Coveralls

sunxd3 and others added 2 commits May 29, 2025 09:00
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
The scope of `interface.jl` is unclear—it contains a set of
miscellaneous functions defined for models, but it's hard to see why
they differ from `condition` and `evaluation`.


Update: merged `interface.jl` into `model.jl` to balance code per file
and keep related code together.

---------

Co-authored-by: Xianda Sun <[email protected]>
Co-authored-by: Xianda Sun <[email protected]>
@yebai
Copy link
Member

yebai commented May 30, 2025

I forgot in #307: src/logdensityprogram.jl can also be moved to src/model/logdensityproblem.jl.

sunxd3 and others added 9 commits June 2, 2025 11:23
1. `FlattenedGraphNodeData` is renamed to `GraphEvaluationData`. 
2. `parameter` field of `BUGSModel` is moved inside
`GraphEvaluationData` and named `sorted_parameters` for better
understanding.

(1) is purely for ease of understanding. 
(2) is motivated by eliminating an implicit invariant where `parameters`
are assumed to be order-consistent with `sorted_nodes` field of
`FlattenedGraphNodeData`, not explicit by construction.
Address #252

The old `condition` does two things at once: it creates a `BUGSModel`
that contains a subset of the original variables and also mark variables
to be conditioned on as `observed`. This was partially motivated by
trying to make BUGS' `Gibbs` algorithm looks like Turing.jl's while make
use the advantage of the graph.

But this is ultimately a badly thought-out interface. This PR implements
`condition` and `decondition` to be like DynamicPPL's, i.e., it only
sets variables from model parameters to observations.

I also took the chance to properly refactored the code to better handle
more types of arguments and added some docstrings.
This fix some issues following the file restructuring.

It's debatable `source_generation.jl` file should be moved to `model`
folder. I left it as is.

There is an error message removed. It is tricky - I think expose the raw
error to user is probably a better idea, and we can improve the error
message if it's required.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
make `/test` mimic `/src` structure-wise.

one redundant test is removed, others was just moved around, some files
are renamed.

CI are split into parallel runs.

`experimental` and some hmc tests are failing and I am going to ignore
them for now.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
There is a subtle incoherence when doing conditioning - the conditioned
model inherent the base model's generated log density function.

This PR addresses this and checks that the source gen works correctly
for conditioned models.
# Gibbs Sampler Refactor

This PR refactors the Gibbs sampler internals to fix correctness issues
and improve performance.

## What Changed

### 1. Fixed MHFromPrior Bug (#250)
- MHFromPrior now correctly samples from the posterior (not the prior)
- Made MHFromPrior a proper `AbstractMCMC.AbstractSampler` that can be
used standalone
- Added `sample_all=false` to avoid resampling observed data

### 2. Performance Improvements
- **Smart copying**: Only copy mutable parts of evaluation environments
(5-35x faster)
- **Direct state usage**: Gibbs now works directly with evaluation
environments
- Benchmark: 10-20x speedup for typical models with large datasets

### 3. Sampler Map Verification
- Added automatic verification that all parameters are covered exactly
once
- Supports variable subsuming (e.g., `x` covers `x[1]`, `x[2]`, etc.)
- Clear error messages for missing or duplicate parameters

### 4. AD Backend Selection
- New `WithGradient` wrapper to specify AD backend per sampler:
  ```julia
  sampler_map = OrderedDict(
      @varname(μ) => WithGradient(HMC(0.1, 10), :ForwardDiff),
      @varname(σ) => WithGradient(NUTS(), :ReverseDiff)  # default
  )
  ```
- Backward compatible - unwrapped samplers default to ReverseDiff

### 5. Better State Management
- Gibbs maintains sub-sampler states across iterations (preserves
HMC/NUTS adaptation)
- Parameter names preserved in chains (no more `:param_1`, `:param_2`)
- Proper `bundle_samples` implementations for all samplers

## Testing
- All existing tests pass
- Added ~80 new tests covering correctness, performance, and edge cases
- Verified against analytical posteriors (Normal-Normal, linear
regression)
- Mixed discrete/continuous parameter models tested

## Backward Compatibility
- Public API unchanged
- Existing Gibbs code continues to work
- Only internal state structure changed

## Performance Example
For a model with 30 data points and mixed continuous/discrete
parameters:

<details>
<summary>model</summary>

```julia
model_def = @bugs begin
    # Continuous parameters
    μ ~ Normal(0, 10)
    log_σ ~ Normal(0, 1)
    σ = exp(log_σ)
    
    # Discrete parameter
    k ~ Categorical(p[:])
    
    # Likelihood
    for i in 1:N
        y[i] ~ Normal(μ + k * 0.5, σ)
    end
end

# Generate data
Random.seed!(123)
N = 30
p_data = [0.3, 0.4, 0.3]
y_data = randn(N) .+ 1.5

model = compile(model_def, (; N=N, p=p_data, y=y_data))
```

</details>

the per-sample time and total memory comparison is

| Configuration | main | This PR |
|--------------|------|---------|
| Mixed (HMC + MHFromPrior) | 37.5ms / 10.9GB | **2.12ms / 0.9GB** |
| All MHFromPrior | 36.3ms / 9.8GB | **0.164ms / 0.05GB** |

## Files Changed
- Core refactor: `src/gibbs.jl`, `src/mh_from_prior.jl`
- Extensions updated: `ext/JuliaBUGS*Ext.jl`
- Model improvements: `src/model/*.jl`
- New tests: `test/gibbs.jl`, `test/mh_from_prior.jl`

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@sunxd3
Copy link
Member Author

sunxd3 commented Jun 9, 2025

The state of this PR:
submodel operation is not implemented, the fundamental reason for this is that source generation for a submodel is not trivial. Currently for models that we can generate log density computation for, we can also generate log density computation for the conditioned model.

The most technical challenging part of this PR is complete.

some better implemented and tested graph related code was added in
#304.

this PR removed the old code and refactor the tests.
@TuringLang TuringLang deleted a comment from github-actions bot Jun 10, 2025
@TuringLang TuringLang deleted a comment from github-actions bot Jun 12, 2025
Thanks @sunxd3! I've rebased the changes onto sunxd/v0.10 as requested
and opened this new PR accordingly. Totally understand the ongoing
breaking changes — happy to adjust anything here to better align with
the direction of the branch. Let me know if there's anything you'd like
revised or if it makes sense to hold off until things stabilize a bit
more.
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.

4 participants