Skip to content

Commit 648bd87

Browse files
authored
Merge pull request #204 from ReactiveBayes/dev-4.0.0
GraphPPL version 4.0.0
2 parents fca0b4b + c6ee51a commit 648bd87

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+17631
-1796
lines changed

.JuliaFormatter.toml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
style = "blue"
2+
indent = 4
3+
margin = 140
4+
always_for_in = true
5+
whitespace_typedefs = true
6+
whitespace_ops_in_indices = true
7+
remove_extra_newlines = true
8+
import_to_using = false
9+
pipe_to_function_call = false
10+
short_to_long_function_def = false
11+
long_to_short_function_def = false
12+
always_use_return = false
13+
whitespace_in_kwargs = true
14+
annotate_untyped_fields_with_any = false
15+
format_docstrings = false
16+
conditional_to_if = true
17+
trailing_comma = false
18+
indent_submodule = false
19+
align_assignment = true
20+
align_struct_field = true
21+
align_conditional = true
22+
align_pair_arrow = true
23+
align_matrix = false
24+
join_lines_based_on_source = false
25+
separate_kwargs_with_semicolon = false
26+
surround_whereop_typeparameters = true

.github/codecov.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ignore:
2+
- "src/old/"
3+
- "ext/"

.github/workflows/CompatHelper.yml

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,45 @@
11
name: CompatHelper
22
on:
33
schedule:
4-
- cron: '00 00 * * *'
4+
- cron: 0 0 * * *
55
workflow_dispatch:
6+
permissions:
7+
contents: write
8+
pull-requests: write
69
jobs:
710
CompatHelper:
811
runs-on: ubuntu-latest
912
steps:
10-
- name: Pkg.add("CompatHelper")
11-
run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
12-
- name: CompatHelper.main()
13+
- name: Check if Julia is already available in the PATH
14+
id: julia_in_path
15+
run: which julia
16+
continue-on-error: true
17+
- name: Install Julia, but only if it is not already available in the PATH
18+
uses: julia-actions/setup-julia@v1
19+
with:
20+
version: '1'
21+
arch: ${{ runner.arch }}
22+
if: steps.julia_in_path.outcome != 'success'
23+
- name: "Add the General registry via Git"
24+
run: |
25+
import Pkg
26+
ENV["JULIA_PKG_SERVER"] = ""
27+
Pkg.Registry.add("General")
28+
shell: julia --color=yes {0}
29+
- name: "Install CompatHelper"
30+
run: |
31+
import Pkg
32+
name = "CompatHelper"
33+
uuid = "aa819f21-2bde-4658-8897-bab36330d9b7"
34+
version = "3"
35+
Pkg.add(; name, uuid, version)
36+
shell: julia --color=yes {0}
37+
- name: "Run CompatHelper"
38+
run: |
39+
import CompatHelper
40+
CompatHelper.main()
41+
shell: julia --color=yes {0}
1342
env:
1443
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15-
COMPATHELPER_PRIV: ${{ secrets.COMPATHELPER_PRIV }} # optional
16-
run: julia -e 'using CompatHelper; CompatHelper.main()'
44+
COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }}
45+
# COMPATHELPER_PRIV: ${{ secrets.COMPATHELPER_PRIV }}

.github/workflows/ci.yml

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,8 @@ jobs:
1919
fail-fast: false
2020
matrix:
2121
version:
22-
- '1.6'
23-
- '1.7'
24-
- '1.8'
25-
- '1.9'
2622
- '1.10'
23+
- 'nightly'
2724
os:
2825
- ubuntu-latest
2926
arch:
@@ -36,27 +33,22 @@ jobs:
3633
with:
3734
version: ${{ matrix.version }}
3835
arch: ${{ matrix.arch }}
39-
- uses: actions/cache@v1
36+
- uses: julia-actions/cache@v1
37+
- uses: julia-actions/julia-buildpkg@v1
38+
- uses: julia-actions/julia-runtest@v1
39+
- uses: julia-actions/julia-processcoverage@v1
40+
- uses: codecov/codecov-action@v3
4041
env:
41-
cache-name: cache-artifacts
42-
with:
43-
path: ~/.julia/artifacts
44-
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
45-
restore-keys: |
46-
${{ runner.os }}-test-${{ env.cache-name }}-
47-
${{ runner.os }}-test-
48-
${{ runner.os }}-
49-
- uses: julia-actions/julia-buildpkg@latest
50-
- uses: julia-actions/julia-runtest@latest
42+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
5143
docs:
5244
name: Documentation
5345
runs-on: ubuntu-latest
5446
needs: test
5547
steps:
5648
- uses: actions/checkout@v2
5749
- uses: julia-actions/setup-julia@latest
58-
with:
59-
version: '1.10'
50+
- uses: julia-actions/cache@v1
51+
- uses: julia-actions/julia-buildpkg@v1
6052
- name: Install dependencies
6153
run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
6254
- name: Build and deploy

.gitignore

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ demo/*wip.ipynb
3333
demo/*.jl
3434

3535
.idea
36-
.vscode
36+
.vscode/
37+
3738

3839
**/*.aux
3940
**/*.log
@@ -46,5 +47,10 @@ Coverage.ipynb
4647

4748
**/.DS_Store
4849

50+
benchmark/tune.json
51+
benchmark_*md
52+
4953
examples/*Compiled
5054
statprof
55+
profile.pb.gz
56+
.swp

Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
scripts_init:
2+
julia --startup-file=no --project=scripts/ -e 'using Pkg; Pkg.instantiate(); Pkg.update(); Pkg.precompile();'
3+
4+
project_init:
5+
julia --startup-file=no --project=. -e 'using Pkg; Pkg.instantiate(); Pkg.update(); Pkg.precompile();'
6+
7+
lint: scripts_init ## Code formating check
8+
julia --startup-file=no --project=scripts/ scripts/format.jl
9+
10+
format: scripts_init ## Code formating run
11+
julia --startup-file=no --project=scripts/ scripts/format.jl --overwrite
12+
13+
bench: ## Run benchmark, use `make bench branch=...` to test against a specific branch
14+
julia --startup-file=no --project=scripts/ scripts/bench.jl $(branch)
15+
16+
doc_init:
17+
julia --project=docs -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate();'
18+
19+
docs: doc_init ## Generate documentation
20+
julia --project=docs/ docs/make.jl

Project.toml

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,48 @@
11
name = "GraphPPL"
22
uuid = "b3f8163a-e979-4e85-b43e-1f63d8c8b42c"
3-
authors = ["Dmitry Bagaev <bvdmitri@gmail.com>"]
4-
version = "3.1.0"
3+
authors = ["Wouter Nuijten <wouternuijten@gmail.com>", "Dmitry Bagaev <bvdmitri@gmail.com>"]
4+
version = "4.0.0"
55

66
[deps]
7+
BitSetTuples = "0f2f92aa-23a3-4d05-b791-88071d064721"
8+
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
9+
Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4"
710
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
11+
MetaGraphsNext = "fa8bd995-216d-47f1-8a91-f3b68fbeb377"
12+
NamedTupleTools = "d9ec5142-1e00-5aa0-9d6a-321866360f50"
13+
Static = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
14+
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
815
TupleTools = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6"
16+
Unrolled = "9602ed7d-8fef-5bc8-8597-8f21381861e8"
17+
18+
[weakdeps]
19+
Cairo = "159f3aea-2a34-519c-b102-8c37f9878175"
20+
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
21+
GraphPlot = "a2cc645c-3eea-5389-862e-a155d0052231"
22+
23+
[extensions]
24+
GraphPPLDistributionsExt = "Distributions"
25+
GraphPPLPlottingExt = ["Cairo", "GraphPlot"]
926

1027
[compat]
11-
MacroTools = "0.5.6"
12-
TupleTools = "1.2.0"
28+
BitSetTuples = "1.1"
29+
Cairo = "1.0"
30+
DataStructures = "0.18"
31+
Dictionaries = "0.4"
32+
Distributions = "0.25"
33+
Documenter = "1.0"
34+
GraphPlot = "0.5"
35+
MacroTools = "0.5"
36+
MetaGraphsNext = "0.6, 0.7"
37+
NamedTupleTools = "0.14"
38+
Static = "0.8"
39+
StaticArrays = "1.6"
40+
TupleTools = "1.4"
41+
Unrolled = "0.1"
1342
julia = "1.6"
1443

1544
[extras]
1645
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
17-
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1846

1947
[targets]
20-
test = ["Test", "Documenter"]
48+
test = ["Documenter"]

README.md

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,46 @@
1313
[ci-img]: https://github.com/reactivebayes/GraphPPL.jl/actions/workflows/ci.yml/badge.svg?branch=master
1414
[ci-url]: https://github.com/reactivebayes/GraphPPL.jl/actions
1515

16-
GraphPPL.jl is a probabilistic programming language focused on probabilistic graphical models. This repository is aimed for advanced users, please refer to the [ReactiveMP.jl](https://github.com/reactivebayes/ReactiveMP.jl) repository for more comprehensive and self-contained documentation and usages examples.
16+
GraphPPL.jl is a probabilistic programming language focused on probabilistic graphical models. GraphPPL.jl materializes a probabilistic model as a factor graph and provides a set of tools for model specification. GraphPPL.jl is a part of the [RxInfer](https://rxinfer.ml) ecosystem, but it does not explicitly depend on any inference backend. GraphPPL exports a high-level DSL for model specification and allows users to append arbitrary information to nodes in the model. This information can be used by inference backends to perform inference on the model.
17+
18+
## Installation
19+
20+
To install GraphPPL.jl, you can use the Julia package manager. From the Julia REPL, type `]` to enter the Pkg REPL mode and run:
21+
22+
```julia
23+
pkg> add GraphPPL
24+
```
25+
26+
# Model Specification in GraphPPL
27+
28+
GraphPPL.jl provides a high-level DSL for model specification. The DSL is based on the [Julia's](https://julialang.org) macro system and allows users to specify probabilistic models in a concise and intuitive way. The DSL is based on the following principles:
29+
30+
- **Model specification should read as a Julia program**. GraphPPL.jl introduces the `~` syntax for model specification.
31+
- **Any GraphPPL model is a valid submodel**. GraphPPL.jl allows users to specify models as a composition of submodels. This allows users to reuse models and specify complex models in a modular way.
32+
- **Model specification should be extensible**. GraphPPL.jl allows users to extend the DSL with custom model specification procedures. This allows developers of inference backend to inject desired behavior to the model specification process.
33+
34+
To achieve tihs, GraphPPL.jl specifies a protocol for the `@model` macro:
35+
```julia
36+
@model function beta_bernoulli(x)
37+
θ ~ Beta(1, 1)
38+
for i in eachindex(x)
39+
x[i] ~ Bernoulli(θ)
40+
end
41+
end
42+
```
1743

1844
# Inference Backend
1945

20-
GraphPPL.jl does not export any Bayesian inference backend. It provides a simple DSL parser, model generation, constraints specification and meta specification helpers. To run inference on
21-
generated models user needs to have a Bayesian inference backend with GraphPPL.jl support (e.g. [ReactiveMP.jl](https://github.com/reactivebayes/ReactiveMP.jl)).
46+
GraphPPL.jl does not export any Bayesian inference backend. It provides a complex DSL parser, model generation, constraints specification and meta specification helpers. To run inference on
47+
generated models a user needs to have a Bayesian inference backend with GraphPPL.jl support (e.g. [RxInfer.jl](https://rxinfer.ml)).
48+
49+
# Documentation
50+
51+
For more information about GraphPPL.jl please refer to the [documentation](https://biaslab.github.io/GraphPPL.jl/stable).
52+
53+
> [!NOTE]
54+
> `GraphPPL.jl` API has been changed in version `4.0.0`. See [Migration Guide](https://reactivebayes.github.io/GraphPPL.jl/stable/) for more details.
55+
2256

2357
# License
2458

benchmark/benchmarks.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using BenchmarkTools
2+
3+
const SUITE = BenchmarkGroup()
4+
5+
include("graph_engine.jl")
6+
include("model_creation.jl")
7+
8+
SUITE["graph_engine"] = benchmark_graph_engine()
9+
SUITE["model_creation"] = benchmark_model_creation()

benchmark/graph_engine.jl

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using BenchmarkTools
2+
using GraphPPL
3+
4+
function benchmark_graph_engine()
5+
SUITE = BenchmarkGroup(["graph_creation"])
6+
7+
# Benchmark how long it takes to create a model structure
8+
SUITE["create_model"] = @benchmarkable GraphPPL.Model(identity, GraphPPL.PluginsCollection(), GraphPPL.DefaultBackend()) evals = 1
9+
10+
# Benchmark how long it takes to get the context of a model
11+
SUITE["getcontext"] = @benchmarkable GraphPPL.getcontext(model) evals = 1 setup = begin
12+
model = GraphPPL.Model(identity, GraphPPL.PluginsCollection(), GraphPPL.DefaultBackend())
13+
end
14+
15+
# Benchmark how long it takes to create a factor node
16+
SUITE["factor_node_creation"] = benchmark_factor_node_creation()
17+
18+
# Benchmark how long it takes to get or create a variable node
19+
SUITE["variable_node_creation"] = benchmark_variable_node_creation()
20+
21+
return SUITE
22+
end
23+
24+
# Benchmark how long it takes to create a factor node
25+
function benchmark_factor_node_creation()
26+
SUITE = BenchmarkGroup()
27+
28+
# This SUITE benchmarks how long it takes to create a factor node `$f` with `n` variables as input
29+
for f in (sum,), n in Int.(exp10.(0:4))
30+
SUITE["make_node! (n inputs)", f, n] = @benchmarkable GraphPPL.make_node!(model, ctx, $f, y, (in = x,)) evals =
31+
1 setup = begin
32+
model = GraphPPL.Model(identity, GraphPPL.PluginsCollection(), GraphPPL.DefaultBackend())
33+
ctx = GraphPPL.getcontext(model)
34+
y = GraphPPL.getorcreate!(model, ctx, :y, nothing)
35+
foreach(1:($n)) do i
36+
GraphPPL.getorcreate!(model, ctx, :x, i)
37+
end
38+
x = GraphPPL.getorcreate!(model, ctx, :x, 1)
39+
end
40+
end
41+
42+
# This SUITE benchmarks how long it takes to create `n` factor nodes with the same variable as input
43+
for f in (sum,), n in Int.(exp10.(0:4))
44+
SUITE["make_node! (n nodes)", f, n] = @benchmarkable foreach(
45+
_ -> GraphPPL.make_node!(model, ctx, $f, y, (in = x,)), 1:($n)
46+
) evals = 1 setup = begin
47+
model = GraphPPL.Model(identity, GraphPPL.PluginsCollection(), GraphPPL.DefaultBackend())
48+
ctx = GraphPPL.getcontext(model)
49+
y = GraphPPL.getorcreate!(model, ctx, :y, nothing)
50+
x = GraphPPL.getorcreate!(model, ctx, :x, nothing)
51+
end
52+
end
53+
54+
return SUITE
55+
end
56+
57+
function benchmark_variable_node_creation()
58+
SUITE = BenchmarkGroup()
59+
60+
# This SUITE benchmarks how long it takes to create a single variable node
61+
SUITE["getorcreate! (individual)"] = @benchmarkable GraphPPL.getorcreate!(model, ctx, :x, nothing) evals = 1 setup =
62+
begin
63+
model = GraphPPL.Model(identity, GraphPPL.PluginsCollection(), GraphPPL.DefaultBackend())
64+
ctx = GraphPPL.getcontext(model)
65+
end
66+
67+
# This SUITE benchmarks how long it takes to add `n` individual variable nodes
68+
for n in Int.(exp10.(0:4))
69+
SUITE["getorcreate! (n individual)", n] = @benchmarkable foreach(
70+
_ -> GraphPPL.getorcreate!(model, ctx, :x, nothing), 1:($n)
71+
) evals = 1 setup = begin
72+
model = GraphPPL.Model(identity, GraphPPL.PluginsCollection(), GraphPPL.DefaultBackend())
73+
ctx = GraphPPL.getcontext(model)
74+
end
75+
end
76+
77+
# THIS SUITE benchmarks how long it takes to add vector based bariables of size `n`
78+
for n in Int.(exp10.(0:4))
79+
SUITE["getorcreate! (n vector)", n] = @benchmarkable foreach(
80+
i -> GraphPPL.getorcreate!(model, ctx, :x, i), 1:($n)
81+
) evals = 1 setup = begin
82+
model = GraphPPL.Model(identity, GraphPPL.PluginsCollection(), GraphPPL.DefaultBackend())
83+
ctx = GraphPPL.getcontext(model)
84+
end
85+
end
86+
87+
return SUITE
88+
end

0 commit comments

Comments
 (0)