-
Notifications
You must be signed in to change notification settings - Fork 36
Fix DynamicPPL / MCMCChains methods #1076
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
Conversation
# T is the element type of the vectors that are the values of `acc.logps`. Usually | ||
# it's LogProbType. | ||
T = eltype(last(fieldtypes(eltype(acc.logps)))) | ||
# Note that in only accumulating LogPrior, we effectively ignore logjac | ||
# (since we want to return log densities that don't depend on the | ||
# linking status of the VarInfo). | ||
subacc = accumulate_assume!!(LogPriorAccumulator{T}(), val, logjac, vn, right) | ||
push!(acc, vn, subacc.logp) | ||
acc.logps[vn] = logpdf(right, val) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if there was some point in going the circuitous route. Just calling logpdf seems much easier
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect this may have been leftover from an earlier iteration of the code, where the whichlogprob
thing was a subaccumulator rather than a Symbol.
# We'll just test one, since `pointwise_logdensities(::Model, ::AbstractVarInfo)` is tested extensively, | ||
# and this is what is used to implement `pointwise_logdensities(::Model, ::Chains)`. This test suite is just | ||
# to ensure that we don't accidentally break the version on `Chains`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this comment is no longer appropriate since the varinfo method is not used to implement the chains method
@test typed_vi[vn_y] == 2.0 | ||
end | ||
|
||
@testset "setval!" begin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these tests are no longer relevant since the corresponding methods are removed
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## breaking #1076 +/- ##
============================================
- Coverage 82.40% 80.98% -1.43%
============================================
Files 42 42
Lines 3791 3765 -26
============================================
- Hits 3124 3049 -75
- Misses 667 716 +49 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
DynamicPPL.jl documentation for PR #1076 is available at: |
ext/DynamicPPLMCMCChainsExt.jl
Outdated
julia> # construct a chain of samples using MCMCChains | ||
chain = Chains(rand(10, 2, 3), [:s, :m]); | ||
julia> loglikelihood(demo_model([1., 2.]), chain); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it intentional that this doctest doesn't check the output at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Frankly, I'm not sure. I just copy-pasted it. Very happy to change it now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the output! Also changed the rand() to some fixed values to avoid making it too fragile.
# T is the element type of the vectors that are the values of `acc.logps`. Usually | ||
# it's LogProbType. | ||
T = eltype(last(fieldtypes(eltype(acc.logps)))) | ||
# Note that in only accumulating LogPrior, we effectively ignore logjac | ||
# (since we want to return log densities that don't depend on the | ||
# linking status of the VarInfo). | ||
subacc = accumulate_assume!!(LogPriorAccumulator{T}(), val, logjac, vn, right) | ||
push!(acc, vn, subacc.logp) | ||
acc.logps[vn] = logpdf(right, val) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect this may have been leftover from an earlier iteration of the code, where the whichlogprob
thing was a subaccumulator rather than a Symbol.
@test !any(Base.Fix1(subsumes, @varname(x)), keys(logpriors_pointwise)) | ||
@test !any(vn in keys(loglikelihoods_pointwise) for vn in vns) | ||
@test all(Base.Fix1(subsumes, @varname(x)), keys(loglikelihoods_pointwise)) | ||
@test all(Symbol(vn) in keys(logjoints_pointwise) for vn in vns) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the point of moving to a Chains
return type, but this does feel like a regression. I can accept that, just mourning it out loud.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally agree 😄. I was mulling keeping the default as Dict, and make Chains output opt-in. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(It's also less breaking.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think long-term Chains feels like the right thing. We could choose to wait until MCMCChains has been improved, so that this would no longer be a regression. I'm quite ambivalent though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it makes a difference (not that I think it should, really), I already implemented pointwise_...
for FlexiChains and they return a FlexiChain: https://github.com/penelopeysm/FlexiChains.jl/blob/66b973e0fb346f3ef6cb51a6caa70324ef9d8f70/ext/FlexiChainsDynamicPPLExt.jl#L237-L254
Co-authored-by: Markus Hauru <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to merge. Happy either way on which one is the default, so change it if you want to.
Thanks! OK, Chains it is then |
This PR:
pointwise_logdensities
family of functions usingInitContext
. NOTE They now return aMCMCChains.Chains
by default rather than an OrderedDict, see Return an AbstractChains object from appliying pointwise_logdensities to Abstractchains? #688 for the motivation -- although OrderedDict output is still supported (I couldn't in good conscience allow it to return a lossyMCMCChains.Chains
without leaving this option available)setval!
methods that were only used for the old implementation (along with corresponding tests)pointwise_logdensities
family, as well aslogjoint
,loglikelihood
andlogprior
, to MCMCChainsExt where they rightfully belong.logjoint
, ... methods insrc/simple_varinfo.jl
Closes #1072
Closes #688
Note, while working on this I discovered more problems.
The entirety of
src/model_utils.jl
is really meant for MCMCChains and should also be banished to the extension (or, in my opinion, removed; but then again I think that MCMCChains should just be removed, so...). The functions there are problematic in the same way thatpointwise_...
were (#1072) but at least they're only for internal use, so there is no reason for them to be overloaded by other types, so unlikely to cause problems in the future.There are also issues with the current implementation of logjoint etc. on
MCMCChains.Chains
, they will only work if the set of varnames is static (i.e. no varying-size / varying-names).Personally I think these remaining issues are comparatively unimportant and can be dealt with another time (or, indeed, never dealt with).