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

For VarInfo, fix merge and allow push!!ing new Symbols #690

Merged
merged 3 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 29 additions & 7 deletions src/varinfo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ function merge_metadata(metadata_left::Metadata, metadata_right::Metadata)
ranges = Vector{UnitRange{Int}}()
vals = T[]
dists = D[]
gids = metadata_right.gids # NOTE: giving precedence to `metadata_right`
gids = Set{Selector}[]
orders = Int[]
flags = Dict{String,BitVector}()
# Initialize the `flags`.
Expand Down Expand Up @@ -520,6 +520,8 @@ function merge_metadata(metadata_left::Metadata, metadata_right::Metadata)
dist_right = getdist(metadata_right, vn)
# Give precedence to `metadata_right`.
push!(dists, dist_right)
gid = metadata_right.gids[getidx(metadata_right, vn)]
push!(gids, gid)
# `orders`: giving precedence to `metadata_right`
push!(orders, getorder(metadata_right, vn))
# `flags`
Expand All @@ -539,6 +541,8 @@ function merge_metadata(metadata_left::Metadata, metadata_right::Metadata)
# `dists`
dist_left = getdist(metadata_left, vn)
push!(dists, dist_left)
gid = metadata_left.gids[getidx(metadata_left, vn)]
push!(gids, gid)
# `orders`
push!(orders, getorder(metadata_left, vn))
# `flags`
Expand All @@ -557,6 +561,8 @@ function merge_metadata(metadata_left::Metadata, metadata_right::Metadata)
# `dists`
dist_right = getdist(metadata_right, vn)
push!(dists, dist_right)
gid = metadata_right.gids[getidx(metadata_right, vn)]
push!(gids, gid)
# `orders`
push!(orders, getorder(metadata_right, vn))
# `flags`
Expand Down Expand Up @@ -1826,14 +1832,31 @@ function BangBang.push!!(
vi::VarInfo, vn::VarName, r, dist::Distribution, gidset::Set{Selector}
)
if vi isa UntypedVarInfo
@assert ~(vn in keys(vi)) "[push!!] attempt to add an exisitng variable $(getsym(vn)) ($(vn)) to VarInfo (keys=$(keys(vi))) with dist=$dist, gid=$gidset"
@assert ~(vn in keys(vi)) "[push!!] attempt to add an existing variable $(getsym(vn)) ($(vn)) to VarInfo (keys=$(keys(vi))) with dist=$dist, gid=$gidset"
elseif vi isa TypedVarInfo
@assert ~(haskey(vi, vn)) "[push!!] attempt to add an exisitng variable $(getsym(vn)) ($(vn)) to TypedVarInfo of syms $(syms(vi)) with dist=$dist, gid=$gidset"
@assert ~(haskey(vi, vn)) "[push!!] attempt to add an existing variable $(getsym(vn)) ($(vn)) to TypedVarInfo of syms $(syms(vi)) with dist=$dist, gid=$gidset"
end

sym = getsym(vn)
if vi isa TypedVarInfo && ~haskey(vi.metadata, sym)
Copy link
Member

Choose a reason for hiding this comment

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

I guess one downside of this ordeal is that it introduces a discrepancy between push!! and push!, the latter which cannot handle new named tuple entries.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm at peace with discrepancies in how ! and !! work, if the !! allows you to do something that can not be done with mutation, but is in line with the semantics of the ! version as well. Said differently, if the only reason ! doesn't do something is because it can not (since it must rely on mutation), then I think it's fine for !! to handle it.

# The NamedTuple doesn't have an entry for this variable, let's add one.
val = tovec(r)
md = Metadata(
Dict(vn => 1),
[vn],
[1:length(val)],
val,
[dist],
[gidset],
[get_num_produce(vi)],
Dict{String,BitVector}("trans" => [false], "del" => [false]),
)
vi = Accessors.@set vi.metadata[sym] = md
else
meta = getmetadata(vi, vn)
push!(meta, vn, r, dist, gidset, get_num_produce(vi))
end

meta = getmetadata(vi, vn)
push!(meta, vn, r, dist, gidset, get_num_produce(vi))

return vi
end

Expand Down Expand Up @@ -1864,7 +1887,6 @@ function Base.push!(meta::Metadata, vn, r, dist, gidset, num_produce)
push!(meta.orders, num_produce)
push!(meta.flags["del"], false)
push!(meta.flags["trans"], false)

return meta
end

Expand Down
25 changes: 25 additions & 0 deletions test/varinfo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,18 @@ DynamicPPL.getspace(::DynamicPPL.Sampler{MySAlg}) = (:s,)
test_varinfo!(vi)
test_varinfo!(empty!!(TypedVarInfo(vi)))
end

@testset "push!! to TypedVarInfo" begin
vn_x = @varname x
vn_y = @varname y
untyped_vi = VarInfo()
untyped_vi = push!!(untyped_vi, vn_x, 1.0, Normal(0, 1), Selector())
typed_vi = TypedVarInfo(untyped_vi)
typed_vi = push!!(typed_vi, vn_y, 2.0, Normal(0, 1), Selector())
@test typed_vi[vn_x] == 1.0
@test typed_vi[vn_y] == 2.0
end

@testset "setgid!" begin
vi = VarInfo(DynamicPPL.Metadata())
meta = vi.metadata
Expand Down Expand Up @@ -694,6 +706,19 @@ DynamicPPL.getspace(::DynamicPPL.Sampler{MySAlg}) = (:s,)
@test varinfo_merged[@varname(x)] == varinfo_right[@varname(x)]
@test DynamicPPL.istrans(varinfo_merged, @varname(x))
end

# The below used to error, testing to avoid regression.
@testset "merge gids" begin
gidset_left = Set([Selector(1)])
vi_left = VarInfo()
vi_left = push!!(vi_left, @varname(x), 1.0, Normal(), gidset_left)
gidset_right = Set([Selector(2)])
vi_right = VarInfo()
vi_right = push!!(vi_right, @varname(y), 2.0, Normal(), gidset_right)
varinfo_merged = merge(vi_left, vi_right)
@test DynamicPPL.getgid(varinfo_merged, @varname(x)) == gidset_left
@test DynamicPPL.getgid(varinfo_merged, @varname(y)) == gidset_right
end
end

@testset "VarInfo with selectors" begin
Expand Down