Parallel Sampling
Octofitter's default sampler (Hamiltonian Monte Carlo) is not easily parallelizable; however, it performs excellently on a single core. Give it a try before assuming you need to sample with multiple cores or nodes.
This guide shows how you can sample from Octofitter models using a cluster. If you just want to sample across multiple cores on the same computer, start julia with multiple threads (julia --threads=auto
) and use octofit_pigeons
.
If your problem is challenging enough to benefit from parallel sampling across multiple nodes in a cluster, you might consider using Pigeons with MPI.
Model Script
Start by creating a script that only loads your data. Instead of building your model at the top-level, create a function that returns a new model. At the end of the script, add some boilerplate shown below. Here is an example:
using Octofitter
using OctofitterRadialVelocity
using PlanetOrbits
using CairoMakie
using PairPlots
using CSV
using DataFrames
using Distributions
# Specify your data as usual
astrom_like = PlanetRelAstromLikelihood(
# Your data here:
(epoch = 50000, ra = -505.7637580573554, dec = -66.92982418533026, σ_ra = 10, σ_dec = 10, cor=0),
(epoch = 50120, ra = -502.570356287689, dec = -37.47217527025044, σ_ra = 10, σ_dec = 10, cor=0),
(epoch = 50240, ra = -498.2089148883798, dec = -7.927548139010479, σ_ra = 10, σ_dec = 10, cor=0),
(epoch = 50360, ra = -492.67768482682357, dec = 21.63557115669823, σ_ra = 10, σ_dec = 10, cor=0),
(epoch = 50480, ra = -485.9770335870402, dec = 51.147204404903704, σ_ra = 10, σ_dec = 10, cor=0),
(epoch = 50600, ra = -478.1095526888573, dec = 80.53589069730698, σ_ra = 10, σ_dec = 10, cor=0),
(epoch = 50720, ra = -469.0801731788123, dec = 109.72870493064629, σ_ra = 10, σ_dec = 10, cor=0),
(epoch = 50840, ra = -458.89628893460525, dec = 138.65128697876773, σ_ra = 10, σ_dec = 10, cor=0),
)
# Copy this boilerplate
struct MyLazyTarget end
using Pigeons
function Pigeons.instantiate_target(flag::MyLazyTarget)
# build your model as usual
@planet b Visual{KepOrbit} begin
a ~ Uniform(0, 100) # AU
e ~ Uniform(0.0, 0.99)
i ~ Sine() # radians
ω ~ UniformCircular()
Ω ~ UniformCircular()
θ ~ UniformCircular()
tp = θ_at_epoch_to_tperi(system,b,50000) # use MJD epoch of your data here!!
end astrom_like
@system Tutoria begin # replace Tutoria with the name of your planetary system
M ~ truncated(Normal(1.2, 0.1), lower=0)
plx ~ truncated(Normal(50.0, 0.02), lower=0)
end b
model = Octofitter.LogDensityModel(Tutoria)
return model
end
Launcher Script
Use this script to launch your MPI job.
Don't submit this script to your cluster. Run it on a login node and it will submit the job for you.
include("distributed-model.jl")
pt = pigeons(
target = Pigeons.LazyTarget(MyLazyTarget()),
record = [traces; round_trip; record_default()],
on = Pigeons.MPIProcesses(
n_mpi_processes = n_chains,
n_threads = 1,
dependencies = [abspath("distributed-model.jl")]
),
# Pass additional flags to the HPC scheduler here
# See here for more details: https://pigeons.run/stable/reference/#Pigeons.MPIProcesses
# add_to_submission = ["#PBS -A my_user_allocation_code"] # pbs
add_to_submission = ["#SBATCH --account=my_user_name"], # slurm
environment_modules: ["intel", "openmpi", "julia"] # HPC modules to load on each worker
)
results = Chains(model, pt)
octocorner(model, results,small=true)