Skip to content
Closed
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: DynamicPPL-CI
name: CI

on:
push:
Expand All @@ -13,13 +13,11 @@ on:
jobs:
test:
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.version == 'nightly' }}
strategy:
matrix:
version:
- '1.3'
- '1'
# - 'nightly'
- '1.3' # minimum supported version
- '1' # current stable version
os:
- ubuntu-latest
- macOS-latest
Expand Down
33 changes: 33 additions & 0 deletions .github/workflows/JuliaNightly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: JuliaNightly

on:
push:
branches:
# This is where pull requests from "bors r+" are built.
- staging
# This is where pull requests from "bors try" are built.
- trying
# Build the master branch.
- master

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
with:
version: 'nightly'
arch: x64
- uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/julia-buildpkg@latest
- uses: julia-actions/julia-runtest@latest
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "DynamicPPL"
uuid = "366bfd00-2699-11ea-058f-f148b4cae6d8"
version = "0.10.5"
version = "0.10.6"

[deps]
AbstractMCMC = "80f14c24-f653-4e6a-9b94-39d6b0f70001"
Expand All @@ -16,6 +16,6 @@ AbstractMCMC = "2"
Bijectors = "0.5.2, 0.6, 0.7, 0.8"
ChainRulesCore = "0.9.7"
Distributions = "0.23.8, 0.24"
MacroTools = "0.5.1"
MacroTools = "0.5.6"
NaturalSort = "1"
julia = "1.3"
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# DynamicPPL.jl

[![Build Status](https://travis-ci.com/TuringLang/DynamicPPL.jl.svg?branch=master)](https://travis-ci.com/TuringLang/DynamicPPL.jl)
[![Build Status](https://github.com/TuringLang/DynamicPPL.jl/workflows/DynamicPPL-CI/badge.svg)](https://github.com/TuringLang/DynamicPPL.jl/actions?query=workflow%3ADynamicPPL-CI+branch%3Amaster)
[![Build Status](https://github.com/TuringLang/DynamicPPL.jl/workflows/CI/badge.svg?branch=master)](https://github.com/TuringLang/DynamicPPL.jl/actions?query=workflow%3ACI+branch%3Amaster)
[![Build Status](https://github.com/TuringLang/DynamicPPL.jl/workflows/JuliaNightly/badge.svg?branch=master)](https://github.com/TuringLang/DynamicPPL.jl/actions?query=workflow%3AJuliaNightly+branch%3Amaster)
[![Coverage Status](https://coveralls.io/repos/github/TuringLang/DynamicPPL.jl/badge.svg?branch=master)](https://coveralls.io/github/TuringLang/DynamicPPL.jl?branch=master)
[![Codecov](https://codecov.io/gh/TuringLang/DynamicPPL.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/TuringLang/DynamicPPL.jl)
[![ColPrac: Contributor's Guide on Collaborative Practices for Community Packages](https://img.shields.io/badge/ColPrac-Contributor's%20Guide-blueviolet)](https://colprac.sciml.ai/)
[![Bors enabled](https://bors.tech/images/badge_small.svg)](https://app.bors.tech/repositories/24589)
Expand Down
20 changes: 13 additions & 7 deletions src/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,20 @@ end
To generate a `Model`, call `model(xvalue)` or `model(xvalue, yvalue)`.
"""
macro model(expr, warn=true)
esc(model(expr, warn))
# include `LineNumberNode` with information about the call site in the
# generated function for easier debugging and interpretation of error messages
esc(model(expr, __source__, warn))
end

function model(expr, warn)
function model(expr, linenumbernode, warn)
modelinfo = build_model_info(expr)

# Generate main body
modelinfo[:body] = generate_mainbody(
modelinfo[:modeldef][:body], modelinfo[:allargs_syms], warn
)

return build_output(modelinfo)
return build_output(modelinfo, linenumbernode)
end

"""
Expand Down Expand Up @@ -301,11 +303,11 @@ hasmissing(T::Type{<:AbstractArray{>:Missing}}) = true
hasmissing(T::Type) = false

"""
build_output(modelinfo)
build_output(modelinfo, linenumbernode)

Builds the output expression.
"""
function build_output(modelinfo)
function build_output(modelinfo, linenumbernode)
## Build the anonymous evaluator from the user-provided model definition.

# Remove the name.
Expand Down Expand Up @@ -340,8 +342,12 @@ function build_output(modelinfo)
# We use a name for the anonymous evaluator that does not conflict with other variables.
modeldef = modelinfo[:modeldef]
@gensym evaluator
modeldef[:body] = quote
$evaluator = $(combinedef_anonymous(evaluatordef))
# We use `MacroTools.@q begin ... end` instead of regular `quote ... end` to ensure
# that no new `LineNumberNode`s are added apart from the reference `linenumbernode`
# to the call site
modeldef[:body] = MacroTools.@q begin
$(linenumbernode)
$evaluator = $(MacroTools.combinedef(evaluatordef))
return $(DynamicPPL.Model)(
$(QuoteNode(modeldef[:name])),
$evaluator,
Expand Down
30 changes: 2 additions & 28 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,6 @@
struct NoDefault end
const NO_DEFAULT = NoDefault()

# FIXME: This is copied from MacroTools and should be removed when a MacroTools release with
# support for anonymous functions is available (> 0.5.5).
function combinedef_anonymous(dict::Dict)
rtype = get(dict, :rtype, nothing)
params = get(dict, :params, [])
wparams = get(dict, :whereparams, [])
body = MacroTools.block(dict[:body])

if isempty(dict[:kwargs])
arg = :($(dict[:args]...),)
else
arg = Expr(:tuple, Expr(:parameters, dict[:kwargs]...), dict[:args]...)
end
if isempty(wparams)
if rtype==nothing
MacroTools.@q($arg -> $body)
else
MacroTools.@q(($arg::$rtype) -> $body)
end
else
if rtype === nothing
MacroTools.@q(($arg where {$(wparams...)}) -> $body)
else
MacroTools.@q(($arg::$rtype where {$(wparams...)}) -> $body)
end
end
end

"""
@addlogprob!(ex)

Expand All @@ -52,6 +24,8 @@ function getargs_dottilde(expr::Expr)
return MacroTools.@match expr begin
(.~)(L_, R_) => (L, R)
(~).(L_, R_) => (L, R)
# Julia 1.6: see https://github.com/TuringLang/Turing.jl/issues/1525
(L_ .~ R_) => (L, R)
x_ => nothing
end
end
Expand Down
40 changes: 20 additions & 20 deletions test/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,30 @@ end
testmodel_comp(1.0, 1.2)

# check if drawing from the prior works
@model function testmodel0(x = missing)
@model function testmodel01(x = missing)
x ~ Normal()
return x
end
f0_mm = testmodel0()
f0_mm = testmodel01()
@test mean(f0_mm() for _ in 1:1000) ≈ 0. atol=0.1

# Test #544
@model function testmodel0(x = missing)
@model function testmodel02(x = missing)
if x === missing
x = Vector{Float64}(undef, 2)
end
x[1] ~ Normal()
x[2] ~ Normal()
return x
end
f0_mm = testmodel0()
f0_mm = testmodel02()
@test all(x -> isapprox(x, 0; atol = 0.1), mean(f0_mm() for _ in 1:1000))

@model function testmodel01(x = missing)
@model function testmodel03(x = missing)
x ~ Bernoulli(0.5)
return x
end
f01_mm = testmodel01()
f01_mm = testmodel03()
@test mean(f01_mm() for _ in 1:1000) ≈ 0.5 atol=0.1

# test if we get the correct return values
Expand Down Expand Up @@ -133,22 +133,22 @@ end
@test_throws ArgumentError btest()

# Test missing input arguments
@model function testmodel(x)
x ~ Bernoulli(0.5)
@model function testmodel_missing1(x)
x ~ Bernoulli(0.5)
return x
end
@test_throws MethodError testmodel()
@test_throws MethodError testmodel_missing1()

# Test missing initialization for vector observation turned parameter
@model function testmodel(x)
x[1] ~ Bernoulli(0.5)
@model function testmodel_missing2(x)
x[1] ~ Bernoulli(0.5)
return x
end
@test_throws MethodError testmodel(missing)()
@test_throws MethodError testmodel_missing2(missing)()

# Test use of internal names
@model function testmodel(x)
x[1] ~  Bernoulli(0.5)
@model function testmodel_missing3(x)
x[1] ~ Bernoulli(0.5)
global varinfo_ = _varinfo
global sampler_ = _sampler
global model_ = _model
Expand All @@ -157,7 +157,7 @@ end
global lp = getlogp(_varinfo)
return x
end
model = testmodel([1.0])
model = testmodel_missing3([1.0])
varinfo = VarInfo(model)
@test getlogp(varinfo) == lp
@test varinfo_ isa AbstractVarInfo
Expand All @@ -167,8 +167,8 @@ end
@test rng_ isa Random.AbstractRNG

# disable warnings
@model function testmodel(x)
x[1] ~  Bernoulli(0.5)
@model function testmodel_missing4(x)
x[1] ~ Bernoulli(0.5)
global varinfo_ = _varinfo
global sampler_ = _sampler
global model_ = _model
Expand All @@ -178,17 +178,17 @@ end
return x
end false
lpold = lp
model = testmodel([1.0])
model = testmodel_missing4([1.0])
varinfo = VarInfo(model)
@test getlogp(varinfo) == lp == lpold

# test DPPL#61
@model function testmodel(z)
@model function testmodel_missing5(z)
m ~ Normal()
z[1:end] ~ MvNormal(fill(m, length(z)), 1.0)
return m
end
model = testmodel(rand(10))
model = testmodel_missing5(rand(10))
@test all(z -> isapprox(z, 0; atol = 0.2), mean(model() for _ in 1:1000))

# test Turing#1464
Expand Down
26 changes: 14 additions & 12 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,20 @@ include("test_util.jl")
include(joinpath("compat", "ad.jl"))
end

@testset "turing" begin
# activate separate test environment
Pkg.activate(DIRECTORY_Turing_tests)
Pkg.develop(PackageSpec(path=DIRECTORY_DynamicPPL))
Pkg.instantiate()

# make sure that the new environment is considered `using` and `import` statements
# (not added automatically on Julia 1.3, see e.g. PR #209)
if !(joinpath(DIRECTORY_Turing_tests, "Project.toml") in Base.load_path())
pushfirst!(LOAD_PATH, DIRECTORY_Turing_tests)
@static if VERSION <= v"1.5.3"
Copy link
Member

Choose a reason for hiding this comment

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

Are we going to remove this flag after Turing is 1.5.3 compatible? Or is Libtask still the hangup here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Turing and Libtask are fine with 1.5.3, only with Julia 1.6 and nightlies Julia segfaults. I am pretty sure it is only due to Libtask, in particular since the model with NUTS in the linked issue runs on Julia 1.6 without any problems.

Copy link
Member

Choose a reason for hiding this comment

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

Okay. Let's revisit this flag when the 1.6 release candidate is out.

@testset "turing" begin
# activate separate test environment
Pkg.activate(DIRECTORY_Turing_tests)
Pkg.develop(PackageSpec(path=DIRECTORY_DynamicPPL))
Pkg.instantiate()

# make sure that the new environment is considered `using` and `import` statements
# (not added automatically on Julia 1.3, see e.g. PR #209)
if !(joinpath(DIRECTORY_Turing_tests, "Project.toml") in Base.load_path())
pushfirst!(LOAD_PATH, DIRECTORY_Turing_tests)
end

include(joinpath("turing", "runtests.jl"))
end

include(joinpath("turing", "runtests.jl"))
end
end
3 changes: 2 additions & 1 deletion test/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
@test getargs_dottilde(:(x ~ Normal(μ, σ))) === nothing
@test getargs_dottilde(:((.~)(x, Normal(μ, σ)))) == (:x, :(Normal(μ, σ)))
@test getargs_dottilde(:((~).(x, Normal(μ, σ)))) == (:x, :(Normal(μ, σ)))
@test getargs_dottilde(:(x .~ Normal(μ, σ))) == (:x, :(Normal(μ, σ)))
@test getargs_dottilde(:(@. x ~ Normal(μ, σ))) === nothing
@test getargs_dottilde(:(@. x ~ Normal(μ, $(Expr(:$, :(sqrt(v))))))) === nothing
@test getargs_dottilde(:(@~ Normal.(μ, σ))) === nothing
Expand All @@ -41,4 +42,4 @@
@test getargs_tilde(:(@. x ~ Normal(μ, $(Expr(:$, :(sqrt(v))))))) === nothing
@test getargs_tilde(:(@~ Normal.(μ, σ))) === nothing
end
end
end