Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion src/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,11 @@ instead:

```jldoctest condition
julia> vnt = @vnt begin
@template m = zeros(2)
m[2] := 1.0
end
VarNamedTuple
└─ m => PartialArray size=(2,) data::DynamicPPL.VarNamedTuples.GrowableArray{Float64, 1}
└─ m => PartialArray size=(2,) data::Vector{Float64}
└─ (2,) => 1.0

julia> m = condition(model, vnt)(); (m[1] != 1.0 && m[2] == 1.0)
Expand Down
2 changes: 2 additions & 0 deletions src/varnamedtuple/getset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ function make_leaf_singleindex(value, coptic::AbstractPPL.Index, template)
# have to make a GrowableArray. No need to use `kw` since make_leaf already errors
# if there are uninterpretable keyword indices.
template_sz = get_maximum_size_from_indices(coptic.ix...)
_warn_growable_array_creation(template_sz)
GrowableArray(Array{pa_eltype}(undef, template_sz))
end
pa_mask = similar(pa_data, Bool)
Expand Down Expand Up @@ -408,6 +409,7 @@ function make_leaf_multiindex(value, coptic::AbstractPPL.Index, template)
else
# No template, or incorrectly typed template
template_sz = get_maximum_size_from_indices(coptic.ix...)
_warn_growable_array_creation(template_sz)
GrowableArray(Array{pa_eltype}(undef, template_sz))
end
pa_mask = similar(pa_data, Bool)
Expand Down
8 changes: 8 additions & 0 deletions src/varnamedtuple/macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ julia> @vnt begin
x[1] := 1.0
y[1, 1] := 2.0
end
┌ Warning: Creating a growable `Base.Array` of dimension 1 to store values. This may not match the actual type or size of the actual `AbstractArray` that will be used inside the DynamicPPL model.
│ If this is not the type or size that you expect, please see: https://turinglang.org/docs/uri/growablearray
└ @ DynamicPPL.VarNamedTuples /path/to/DynamicPPL.jl/src/varnamedtuple/partial_array.jl:823
┌ Warning: Creating a growable `Base.Array` of dimension 2 to store values. This may not match the actual type or size of the actual `AbstractArray` that will be used inside the DynamicPPL model.
│ If this is not the type or size that you expect, please see: https://turinglang.org/docs/uri/growablearray
└ @ DynamicPPL.VarNamedTuples /path/to/DynamicPPL.jl/src/varnamedtuple/partial_array.jl:823
VarNamedTuple
├─ x => PartialArray size=(1,) data::DynamicPPL.VarNamedTuples.GrowableArray{Float64, 1}
│ └─ (1,) => 1.0
Expand Down
30 changes: 24 additions & 6 deletions src/varnamedtuple/partial_array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ Base.getindex(ga::GrowableArray, ix::CartesianIndex) = getindex(ga.data, ix)
# multi-element indexing
Base.getindex(ga::GrowableArray, ix...) = GrowableArray(getindex(ga.data, ix...))
Base.setindex!(ga::GrowableArray, value, ix...) = setindex!(ga.data, value, ix...)
# This function is exported so we can override it!
function AbstractPPL.concretize_top_level(idx::Index, val::GrowableArray)
if any(ix -> ix isa AbstractPPL.DynamicIndex, idx.ix)
_warn_growable_array_extraction()
end
return concretize_top_level(idx, val.data)
end

function throw_kw_error()
throw(
Expand Down Expand Up @@ -399,7 +406,7 @@ function Base.getindex(pa::PartialArray, inds::Vararg{Any}; kw...)
# you index with `x[end]` for example, `inds` is already concretised outside of this
# function.
if any(ind -> ind isa AbstractPPL.DynamicIndex || ind isa Colon, inds)
_warn_growable_array()
_warn_growable_array_extraction()
end
return unwrap_internal_array(val)
else
Expand Down Expand Up @@ -630,7 +637,7 @@ end
function _subset_partialarray(pa::PartialArray, inds::Vararg{Any}; kw...)
if pa.data isa GrowableArray &&
any(ind -> ind isa AbstractPPL.DynamicIndex || ind isa Colon, inds)
_warn_growable_array()
_warn_growable_array_extraction()
end
new_data = view(pa.data, inds...; kw...)
new_mask = view(pa.mask, inds...; kw...)
Expand Down Expand Up @@ -783,7 +790,7 @@ function unwrap_internal_array(pa::PartialArray)

retval = pa.data
if retval isa GrowableArray
_warn_growable_array()
_warn_growable_array_extraction()
end
if eltype(retval) <: ArrayLikeBlock || ArrayLikeBlock <: eltype(retval)
for ind in eachindex(retval)
Expand All @@ -801,12 +808,23 @@ function unwrap_internal_array(pa::PartialArray)
end
unwrap_internal_array(ga::GrowableArray) = ga.data

function _warn_growable_array()
function _warn_growable_array_extraction()
@warn (
"Returning a `Base.Array` with a presumed size based on the indices" *
" used to set values; but this may not be the actual shape or size" *
" used to set values; but this may not be the actual type or size" *
" of the actual `AbstractArray` that was inside the DynamicPPL model." *
" You should inspect the returned result to make sure that it has the" *
" correct value."
" correct value.\n\n" *
"To find out how to avoid this warning, please see: " *
"https://turinglang.org/docs/uri/growablearray"
)
end
function _warn_growable_array_creation(size)
@warn (
"Creating a growable `Base.Array` of dimension $(length(size)) to store" *
" values. This may not match the actual type or size of the actual" *
" `AbstractArray` that will be used inside the DynamicPPL model.\n\n" *
" If this is not the type or size that you expect, please see:" *
" https://turinglang.org/docs/uri/growablearray"
)
end
35 changes: 26 additions & 9 deletions test/varnamedtuple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module VarNamedTupleTests

using Combinatorics: Combinatorics
using OrderedCollections: OrderedDict
using Test: @inferred, @test, @test_throws, @testset, @test_broken
using Test: @inferred, @test, @test_throws, @testset, @test_broken, @test_logs
using DynamicPPL: DynamicPPL, @varname, VarNamedTuple, subset
using DynamicPPL.VarNamedTuples:
PartialArray,
Expand Down Expand Up @@ -643,25 +643,42 @@ Base.size(st::SizedThing) = st.size
end
end

@testset "Warning when setting untemplated values" begin
warnmsg = r"Creating a growable `Base.Array`"
@test_logs (:warn, warnmsg) vnt = setindex!!(
VarNamedTuple(), [1.0, 2.0], @varname(x[1:2])
)
@test_logs (:warn, warnmsg) vnt = setindex!!(
VarNamedTuple(), 1.0, @varname(x[1])
)
@test_logs (:warn, warnmsg) vnt = setindex!!(
VarNamedTuple(), 1.0, @varname(x[2])
)
# This shouldn't warn, because `x` is just the whole vector
@test_logs vnt = setindex!!(VarNamedTuple(), [1.0, 2.0], @varname(x))
# With a template it shouldn't warn
@test_logs vnt = templated_setindex!!(
VarNamedTuple(), 1.0, @varname(x[1]), zeros(2)
)
end

@testset "Warning when trying to extract values" begin
vnt = @vnt begin
x[1] := 1.0
x[2] := 2.0
end
warnmsg = r"Returning a `Base.Array` with"
# These should warn
# These should warn. There are various calls to _warn_growable_array() inside
# the VNT code to handle each of these cases.
@test_logs (:warn, warnmsg) vnt[@varname(x[:][1])]
@test_logs (:warn, warnmsg) vnt[@varname(x[:])]
@test_logs (:warn, warnmsg) vnt[@varname(x)]
# These shouldn't warn
@test_logs (:warn, warnmsg) vnt[@varname(x[begin])]
@test_logs (:warn, warnmsg) vnt[@varname(x[end])]
@test_logs (:warn, warnmsg) vnt[@varname(x[1:end])]
# These shouldn't warn because they are safe
@test_logs vnt[@varname(x[1:2])]
@test_logs vnt[@varname(x[1])]
# The following with DynamicIndex things are broken. They should warn, but
# currently they don't because by the time you try to index into the
# GrowableArray, the indices are already concretised. This can be fixed.
@test_broken false
@test_logs vnt[@varname(x[end])]
@test_logs vnt[@varname(x[1:end])]
end
end

Expand Down