Skip to content
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

Use _init_parmas for MCMCThreads and MCMCDistributed too #126

Merged
merged 18 commits into from
Oct 2, 2023

Conversation

torfjelde
Copy link
Member

Fixes #125

@codecov
Copy link

codecov bot commented Sep 13, 2023

Codecov Report

Attention: 1 lines in your changes are missing coverage. Please review.

Comparison is base (d7c549f) 97.37% compared to head (4dbcb3f) 97.37%.
Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #126   +/-   ##
=======================================
  Coverage   97.37%   97.37%           
=======================================
  Files           8        8           
  Lines         305      305           
=======================================
  Hits          297      297           
  Misses          8        8           
Files Coverage Δ
src/sample.jl 96.64% <90.00%> (ø)

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

test/sample.jl Outdated
3,
nchains;
progress=false,
init_params=Iterators.repeated(init_params, nchains + 1),
Copy link
Member Author

Choose a reason for hiding this comment

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

So _first_or_nothing doesn't actually care if there are too many initial parameters 😕

IMO it seems like we want to raise an error in this case since it's otherwise very easy to accidentally do the incorrect thing.

@torfjelde
Copy link
Member Author

So I just removed _first_or_nothing and added a simple check for the length of init_params.

Though this is then a breaking change

src/sample.jl Outdated Show resolved Hide resolved
src/sample.jl Outdated
Comment on lines 317 to 318
# We will use `getindex` later so we need to `collect`.
_init_params = init_params !== nothing ? collect(init_params) : nothing
Copy link
Member

Choose a reason for hiding this comment

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

Can we remove the collect call? It's not generally required and will lead to surprising allocations, e.g., the following cases would work just fine without collect (IIRC the docs even mention FillArrays if you want to specify the same parameters multiple times):

julia> collect(1:10)
10-element Vector{Int64}:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10

julia> collect(Zeros(10))
10-element Vector{Float64}:
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
Suggested change
# We will use `getindex` later so we need to `collect`.
_init_params = init_params !== nothing ? collect(init_params) : nothing

Copy link
Member Author

Choose a reason for hiding this comment

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

So I added it explicitly to cause allocations, but maybe it's not quite the right thing to do. We use getindex further down, and so if init_params is an iterator, e.g. Iterator.repeated, then this will fail unless we do something like collect first.

Copy link
Member Author

Choose a reason for hiding this comment

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

How about we just simplify the process by adding something like:

multiple_init_params(::Nothing, n) = Iterator.repeated(nothing, n)
function multiple_init_params(x, n)
    if length(x) != n
        throw(
            ArgumentError(
                "incorrect number of initial parameters (expected $n, received $(length(x))"
            ),
        )
    end

    return x
end

and then we just do

_init_params = multiple_init_params(init_params, n)

then we can just remove all the subsequent checks for nothing + use zip and avoid the getindex call.

Copy link
Member

Choose a reason for hiding this comment

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

I think we should not generally change nothing to Iterator.repeated. Mainly, because it means we would not dispatch on nothing anymore and hence not use the map/pmap calls with reduced number of arguments anymore. IMO we really want to use these calls with one argument less since generally map, broadcast etc. is more optimized for AbstractArray than generic iterators.

For this reason I'm also not a fan of promoting and using Iterators.repeated. Maybe we should just demand that multiple sets of parameters are always provided as an AbstractVector? If you want something cheap, you can just use e.g. Fill(...) instead of Iterators.repeated - which in contrast to the latter supports the array interface.

Copy link
Member Author

Choose a reason for hiding this comment

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

IMO we really want to use these calls with one argument less since generally map, broadcast etc. is more optimized for AbstractArray than generic iterators.

Good point!

If you want something cheap, you can just use e.g. Fill(...) instead of Iterators.repeated - which in contrast to the latter supports the array interface.

Am happy with this 👍

Copy link
Member

Choose a reason for hiding this comment

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

Could you update the docs (https://turinglang.org/AbstractMCMC.jl/dev/api/#Common-keyword-arguments) accordingly and remove Iterators.repeated there?

Copy link
Member Author

Choose a reason for hiding this comment

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

Will do 👍

@torfjelde
Copy link
Member Author

torfjelde commented Oct 1, 2023

@devmotion given that we're making a breaking change here, should we also throw in the renaming of init_params to initial_params as discussed in #119 ?

Copy link
Member

@devmotion devmotion left a comment

Choose a reason for hiding this comment

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

Looks good. Adding using FillArrays: FillArrays to the tests should fix the test errors.

@torfjelde
Copy link
Member Author

Aight, I'll merge this now, but let's delay the release until #119 has gone through to limit the number of breaking releases 👍

@torfjelde torfjelde merged commit 084f809 into master Oct 2, 2023
28 of 30 checks passed
@delete-merged-branch delete-merged-branch bot deleted the torfjelde/init-params-fix branch October 2, 2023 14:20
@devmotion
Copy link
Member

But the PR here was marked as non-breaking anyway? 🤔 (I saw you already corrected the version bump 👍)

@torfjelde
Copy link
Member Author

torfjelde commented Oct 2, 2023 via email

@devmotion
Copy link
Member

No, minor versions are only breaking < 1.0.0. The next breaking release will be 5.0.0.

@torfjelde
Copy link
Member Author

Ooooooh, crap. I clearly work too much with < 1.0.0 packages 😬

But aight, I'll bump to 5.0.0 then?

@devmotion
Copy link
Member

👍

torfjelde added a commit that referenced this pull request Oct 24, 2023
…-fix"

This reverts commit 084f809, reversing
changes made to caeade2.
torfjelde added a commit that referenced this pull request Oct 24, 2023
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.

Error if init_params has not been specified for all chains
2 participants