Skip to content

Commit fa81895

Browse files
Documentation (#33)
* Add docs, examples and auto deploy * correct url * Minor fixes
1 parent 9f8522f commit fa81895

File tree

18 files changed

+1425
-16
lines changed

18 files changed

+1425
-16
lines changed

.github/workflows/Docs.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Documentation
2+
3+
on:
4+
push:
5+
branches:
6+
# Build the master branch.
7+
- master
8+
tags: '*'
9+
pull_request:
10+
11+
concurrency:
12+
# Skip intermediate builds: always.
13+
# Cancel intermediate builds: only if it is a pull request build.
14+
group: ${{ github.workflow }}-${{ github.ref }}
15+
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
16+
17+
jobs:
18+
docs:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v2
22+
- uses: julia-actions/setup-julia@latest
23+
with:
24+
version: '1'
25+
- name: Install dependencies
26+
run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
27+
- name: Build and deploy
28+
env:
29+
GKSwstype: nul # GR backend issues
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token
31+
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key
32+
JULIA_DEBUG: Documenter # Print `@debug` statements (https://github.com/JuliaDocs/Documenter.jl/issues/955)
33+
run: julia --project=docs/ docs/make.jl
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Doc Preview Cleanup
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
7+
jobs:
8+
doc-preview-cleanup:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout gh-pages branch
12+
uses: actions/checkout@v2
13+
with:
14+
ref: gh-pages
15+
- name: Delete preview and history + push changes
16+
run: |
17+
if [ -d "previews/PR$PRNUM" ]; then
18+
git config user.name "Documenter.jl"
19+
git config user.email "[email protected]"
20+
git rm -rf "previews/PR$PRNUM"
21+
git commit -m "delete preview"
22+
git branch gh-pages-new $(echo "delete history" | git commit-tree HEAD^{tree})
23+
git push --force origin gh-pages-new:gh-pages
24+
fi
25+
env:
26+
PRNUM: ${{ github.event.number }}

.github/workflows/TagBot.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ jobs:
1212
- uses: JuliaRegistries/TagBot@v1
1313
with:
1414
token: ${{ secrets.GITHUB_TOKEN }}
15-
15+
ssh: ${{ secrets.DOCUMENTER_KEY }}

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
*.jl.*.cov
33
*.jl.mem
44
/Manifest.toml
5-
/test/Manifest.toml
5+
/test/Manifest.toml

README.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@
55
[![Coverage](https://coveralls.io/repos/github/TuringLang/AdvancedPS.jl/badge.svg?branch=master)](https://coveralls.io/github/TuringLang/AdvancedPS.jl?branch=master)
66
[![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/invenia/BlueStyle)
77

8+
AdvancedPS provides an efficient implementation of common particle based Monte Carlo samplers using the [AbstractMCMC](https://github.com/TuringLang/AbstractMCMC.jl) interface.
9+
The package also relies on [Libtask](https://github.com/TuringLang/Libtask.jl) for task manipulation.
10+
AdvancedPS is part of the [Turing](https://turing.ml/stable/) ecosystem.
11+
12+
### Installation
13+
14+
Inside the Julia REPL
15+
```julia
16+
julia>] add AdvancedPS
17+
```
18+
19+
### Examples
20+
21+
Detailed examples are available in the [documentation](https://turinglang.github.io/AdvancedPS.jl/stable/)
22+
823
### Reference
924

1025
1. Doucet, Arnaud, and Adam M. Johansen. "A tutorial on particle filtering and smoothing: Fifteen years later." Handbook of nonlinear filtering 12, no. 656-704 (2009): 3.
@@ -21,6 +36,3 @@
2136

2237
7. Del Moral, Pierre, Arnaud Doucet, and Ajay Jasra. "Sequential Monte Carlo samplers." Journal of the Royal Statistical Society: Series B (Statistical Methodology) 68, no. 3 (2006): 411-436.
2338

24-
25-
26-

docs/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/

docs/Project.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[deps]
2+
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3+
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
4+
5+
[compat]
6+
Documenter = "0.27"

docs/literate.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Retrieve name of example and output directory
2+
if length(ARGS) != 2
3+
error("please specify the name of the example and the output directory")
4+
end
5+
const EXAMPLE = ARGS[1]
6+
const OUTDIR = ARGS[2]
7+
8+
# Activate environment
9+
# Note that each example's Project.toml must include Literate as a dependency
10+
using Pkg: Pkg
11+
const EXAMPLEPATH = joinpath(@__DIR__, "..", "examples", EXAMPLE)
12+
Pkg.activate(EXAMPLEPATH)
13+
Pkg.instantiate()
14+
using Literate: Literate
15+
16+
# Convert to markdown and notebook
17+
const SCRIPTJL = joinpath(EXAMPLEPATH, "script.jl")
18+
Literate.markdown(SCRIPTJL, OUTDIR; name=EXAMPLE, documenter=false, execute=true)

docs/make.jl

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#
2+
# With minor changes from https://github.com/JuliaGaussianProcesses/AbstractGPs.jl/docs
3+
#
4+
### Process examples
5+
# Always rerun examples
6+
const EXAMPLES_OUT = joinpath(@__DIR__, "src", "examples")
7+
ispath(EXAMPLES_OUT) && rm(EXAMPLES_OUT; recursive=true)
8+
mkpath(EXAMPLES_OUT)
9+
10+
# Install and precompile all packages
11+
# Workaround for https://github.com/JuliaLang/Pkg.jl/issues/2219
12+
examples = filter!(isdir, readdir(joinpath(@__DIR__, "..", "examples"); join=true))
13+
let script = "using Pkg; Pkg.activate(ARGS[1]); Pkg.instantiate()"
14+
for example in examples
15+
if !success(`$(Base.julia_cmd()) -e $script $example`)
16+
error(
17+
"project environment of example ",
18+
basename(example),
19+
" could not be instantiated",
20+
)
21+
end
22+
end
23+
end
24+
# Run examples asynchronously
25+
processes = let literatejl = joinpath(@__DIR__, "literate.jl")
26+
map(examples) do example
27+
return run(
28+
pipeline(
29+
`$(Base.julia_cmd()) $literatejl $(basename(example)) $EXAMPLES_OUT`;
30+
stdin=devnull,
31+
stdout=devnull,
32+
stderr=stderr,
33+
);
34+
wait=false,
35+
)::Base.Process
36+
end
37+
end
38+
39+
# Check that all examples were run successfully
40+
isempty(processes) || success(processes) || error("some examples were not run successfully")
41+
42+
# Building Documenter
43+
using Documenter
44+
using AdvancedPS
45+
46+
DocMeta.setdocmeta!(AdvancedPS, :DocTestSetup, :(using AdvancedPS); recursive=true)
47+
48+
makedocs(;
49+
sitename="AdvancedPS",
50+
format=Documenter.HTML(),
51+
modules=[AdvancedPS],
52+
pages=[
53+
"Home" => "index.md",
54+
"api.md",
55+
"Examples" => [
56+
"example.md",
57+
map(
58+
(x) -> joinpath("examples", x),
59+
filter!(filename -> endswith(filename, ".md"), readdir(EXAMPLES_OUT)),
60+
)...,
61+
],
62+
],
63+
strict=true,
64+
checkdocs=:exports,
65+
doctestfilters=[
66+
# Older versions will show "0 element Array" instead of "Type[]".
67+
r"(Any\[\]|0-element Array{.+,[0-9]+})",
68+
# Older versions will show "Array{...,1}" instead of "Vector{...}".
69+
r"(Array{.+,\s?1}|Vector{.+})",
70+
# Older versions will show "Array{...,2}" instead of "Matrix{...}".
71+
r"(Array{.+,\s?2}|Matrix{.+})",
72+
],
73+
)
74+
75+
deploydocs(; repo="github.com/TuringLang/AdvancedPS.jl.git", push_preview=true)

docs/src/api.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# API
2+
3+
## Samplers
4+
5+
AdvancedPS introduces a few samplers extending [AbstractMCMC](https://github.com/TuringLang/AbstractMCMC.jl).
6+
The `sample` method expects a custom type that subtypes `AbstractMCMC.AbstractModel`.
7+
The available samplers are listed below:
8+
9+
### SMC
10+
11+
```@docs
12+
AdvancedPS.SMC
13+
```
14+
The SMC sampler populates a set of particles in a [`AdvancedPS.ParticleContainer`](@ref) and performs a [`AdvancedPS.sweep!`](@ref) which
15+
propagates the particles and provides an estimation of the log-evidence
16+
17+
```julia
18+
sampler = SMC(nparticles)
19+
chains = sample(model, sampler)
20+
```
21+
22+
### Particle Gibbs
23+
```@docs
24+
AdvancedPS.PG
25+
```
26+
The Particle Gibbs introduced in [^2] runs a sequence of conditional SMC steps where a pre-selected particle, the reference particle, is replayed and propagated through
27+
the SMC step.
28+
29+
```julia
30+
sampler = PG(nparticles)
31+
chains = sample(model, sampler, nchains)
32+
```
33+
34+
For more detailed examples please refer to the [Examples](@ref) page.
35+
36+
## Resampling
37+
38+
AdvancedPS implements adaptive resampling for both [`AdvancedPS.PG`](@ref) and [`AdvancedPS.SMC`](@ref).
39+
The following resampling schemes are implemented:
40+
```@docs
41+
AdvancedPS.resample_multinomial
42+
AdvancedPS.resample_residual
43+
AdvancedPS.resample_stratified
44+
AdvancedPS.resample_systematic
45+
```
46+
47+
Each of these schemes is wrapped in a [`AdvancedPS.ResampleWithESSThreshold`](@ref) struct to trigger a resampling step whenever the ESS is below a certain threshold.
48+
```@docs
49+
AdvancedPS.ResampleWithESSThreshold
50+
```
51+
52+
## RNG
53+
54+
AdvancedPS replays the individual trajectories instead of storing the intermediate values. This way we can build efficient samplers.
55+
However in order to replay the trajectories we need to reproduce most of the random numbers generated
56+
during the execution of the program while also generating diverging traces after each resampling step.
57+
To solve these two issues AdvancedPS uses counter-based RNG introduced in [^1] and widely used in large parallel systems see
58+
[StochasticDifferentialEquations](https://github.com/SciML/StochasticDiffEq.jl) or [JAX](https://jax.readthedocs.io/en/latest/jax-101/05-random-numbers.html?highlight=random)
59+
for other implementations.
60+
61+
Under the hood AdvancedPS is using [Random123](https://github.com/JuliaRandom/Random123.jl) for the generators.
62+
Using counter-based RNG allows us to split generators thus creating new independent random streams. These generators are also wrapped in a [`AdvancedPS.TracedRNG`](@ref) type.
63+
The `TracedRNG` keeps track of the keys generated at every `split` and can be reset to replay random streams.
64+
65+
66+
```@docs
67+
AdvancedPS.TracedRNG
68+
AdvancedPS.split
69+
AdvancedPS.load_state!
70+
AdvancedPS.save_state!
71+
```
72+
73+
## Internals
74+
### Particle Sweep
75+
76+
```@docs
77+
AdvancedPS.ParticleContainer
78+
AdvancedPS.sweep!
79+
```
80+
81+
[^1]: John K. Salmon, Mark A. Moraes, Ron O. Dror, and David E. Shaw. 2011. Parallel random numbers: as easy as 1, 2, 3. In Proceedings of 2011 International Conference for High Performance Computing, Networking, Storage and Analysis (SC '11). Association for Computing Machinery, New York, NY, USA, Article 16, 1–12. DOI:https://doi.org/10.1145/2063384.2063405
82+
[^2]: Andrieu, Christophe, Arnaud Doucet, and Roman Holenstein. "Particle Markov chain Monte Carlo methods." Journal of the Royal Statistical Society: Series B (Statistical Methodology) 72, no. 3 (2010): 269-342.

0 commit comments

Comments
 (0)