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

[Merged by Bors] - Hotfixes after #309 #351

Closed
wants to merge 13 commits into from
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
version:
# - '1.3' # minimum supported version
- '1.3' # minimum supported version
- '1' # current stable version
os:
- ubuntu-latest
Expand Down
3 changes: 3 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ makedocs(;
r"(Array{.+,\s?1}|Vector{.+})",
# Older versions will show "Array{...,2}" instead of "Matrix{...}".
r"(Array{.+,\s?2}|Matrix{.+})",
# Errors from macros sometimes result in `LoadError: LoadError:`
# rather than `LoadError:`, depending on Julia version.
r"ERROR: LoadError: (LoadError:\s)?",
],
)

Expand Down
15 changes: 11 additions & 4 deletions src/submodel_macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -212,17 +212,23 @@ function submodel(prefix_expr, expr, ctx=esc(:__context__))
if prefix_left !== :prefix
error("$(prefix_left) is not a valid kwarg")
end

# The user expects `@submodel ...` to return the
# return-value of the `...`, hence we need to capture
# the return-value and handle it correctly.
@gensym retval

# `prefix=false` => don't prefix, i.e. do nothing to `ctx`.
# `prefix=true` => automatically determine prefix.
# `prefix=...` => use it.
args_assign = getargs_assignment(expr)
return if args_assign === nothing
ctx = prefix_submodel_context(prefix, ctx)
# In this case we only want to get the `__varinfo__`.
quote
$(esc(:__varinfo__)) = last(
$(DynamicPPL._evaluate!!)($(esc(expr)), $(esc(:__varinfo__)), $(ctx))
$retval, $(esc(:__varinfo__)) = $(DynamicPPL._evaluate!!)(
Copy link
Member

@yebai yebai Dec 14, 2021

Choose a reason for hiding this comment

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

I like returning both the retval and varinfo. I was talking with Philip that we should consider enforcing this more systematically. Roughly speaking, we can consider adopting the notation that retval refers to generated quantities and varinfo refers to model parameters. This would help clarify the submodel notation as well, i.e.

  1. x = SubModel will extract retval and assign it to LHS
  2. x ~ SubModel will extract varinfo and assign it to LHS

Following this view, we no longer need to concern ourselves what is the semantics if the returned value retval of SubModel is deterministic in case 2.

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 a bit confused. In both those cases we still have to concern ourselves with the return-value, no? Essentially the difference between = and ~ will be whether we have $retval or varinfo below, right?

Anyways, you're happy with this right? You're just talking about potentially also supporting ~ later?

Copy link
Member

@yebai yebai Dec 14, 2021

Choose a reason for hiding this comment

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

yes, happy with this PR.

I think retval and varinfo provides a clear semantical distinction between = and ~. If we always return both, (e.g. we can return (, varinfo) in case retval is empty), we can extract either retval or varinfo for = or ~.

$(esc(expr)), $(esc(:__varinfo__)), $(ctx)
)
$retval
end
else
L, R = args_assign
Expand All @@ -235,9 +241,10 @@ function submodel(prefix_expr, expr, ctx=esc(:__context__))
)
end
quote
$(esc(L)), $(esc(:__varinfo__)) = $(DynamicPPL._evaluate!!)(
$retval, $(esc(:__varinfo__)) = $(DynamicPPL._evaluate!!)(
$(esc(R)), $(esc(:__varinfo__)), $(ctx)
)
$(esc(L)) = $retval
end
end
end
10 changes: 10 additions & 0 deletions test/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -570,5 +570,15 @@ end

@model demo() = x ~ Normal()
retval, svi = DynamicPPL.evaluate!!(demo(), SimpleVarInfo(), SamplingContext())

# Return-value when using `@submodel`
@model inner() = x ~ Normal()
# Without assignment.
@model outer() = @submodel inner()
@test outer()() isa Real

# With assignment.
@model outer() = @submodel x = inner()
@test outer()() isa Real
end
end
3 changes: 3 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ include("test_util.jl")
r"(Array{.+,\s?1}|Vector{.+})",
# Older versions will show "Array{...,2}" instead of "Matrix{...}".
r"(Array{.+,\s?2}|Matrix{.+})",
# Errors from macros sometimes result in `LoadError: LoadError:`
# rather than `LoadError:`, depending on Julia version.
r"ERROR: LoadError: (LoadError:\s)?",
]
doctest(DynamicPPL; manual=false, doctestfilters=doctestfilters)
end
Expand Down