Index
Pigeons.explorer
Pigeons.log_potential
Pigeons.log_potentials
Pigeons.pair_swapper
Pigeons.path
Pigeons.recorder
Pigeons.recorder_builder
Pigeons.recorders
Pigeons.registered_online_types
Pigeons.replicas
Pigeons.state
Pigeons.swap_graph
Pigeons.swap_graphs
Pigeons.target
Pigeons.tempering
Pigeons.variational
Pigeons.AAPS
Pigeons.Augmentation
Pigeons.AutoMALA
Pigeons.BlangTarget
Pigeons.BufferedAD
Pigeons.ChildProcess
Pigeons.Compose
Pigeons.DiagonalPreconditioner
Pigeons.DistributionLogPotential
Pigeons.EntangledReplicas
Pigeons.Entangler
Pigeons.FromCheckpoint
Pigeons.GaussianReference
Pigeons.IdentityPreconditioner
Pigeons.Indexer
Pigeons.Indexer
Pigeons.Inputs
Pigeons.InterpolatedAD
Pigeons.InterpolatedLogPotential
Pigeons.InterpolatingPath
Pigeons.Iterators
Pigeons.LazyTarget
Pigeons.LoadBalance
Pigeons.LogPotentialExtractor
Pigeons.MALA
Pigeons.MPIProcesses
Pigeons.MPISettings
Pigeons.Mix
Pigeons.MixDiagonalPreconditioner
Pigeons.NonReversiblePT
Pigeons.NonReversiblePT
Pigeons.OddEven
Pigeons.OnlineStateRecorder
Pigeons.PT
Pigeons.PT
Pigeons.PT
Pigeons.PermutedDistributedArray
Pigeons.Preconditioner
Pigeons.Replica
Pigeons.Result
Pigeons.RoundTripRecorder
Pigeons.SampleArray
Pigeons.ScaledPrecisionNormalPath
Pigeons.ScaledPrecisionNormalPath
Pigeons.Schedule
Pigeons.Shared
Pigeons.Shared
Pigeons.SliceSampler
Pigeons.StabilizedPT
Pigeons.StabilizedPT
Pigeons.StanLogPotential
Pigeons.StanState
Pigeons.StreamState
Pigeons.StreamTarget
Pigeons.Submission
Pigeons.SwapStat
Pigeons.TestSwapper
Pigeons.ThisProcess
Pigeons.ToyExplorer
Pigeons.TuringLogPotential
Pigeons.VariationalOddEven
Pigeons._transformed_online
Pigeons.aaps!
Pigeons.activate_variational
Pigeons.ad_buffers
Pigeons.adapt
Pigeons.adapt_explorer
Pigeons.adapt_tempering
Pigeons.all_reduce_deterministically
Pigeons.all_reports
Pigeons.allocation_extrema
Pigeons.analytic_cumulativebarrier
Pigeons.blang_ising
Pigeons.blang_ising
Pigeons.blang_sitka
Pigeons.blang_sitka
Pigeons.buffers
Pigeons.check_against_serial
Pigeons.communicate!
Pigeons.communication_barriers
Pigeons.communicator
Pigeons.continuous_variables
Pigeons.continuous_variables
Pigeons.create_entangled_replicas
Pigeons.create_explorer
Pigeons.create_pair_swapper
Pigeons.create_path
Pigeons.create_path
Pigeons.create_recorders
Pigeons.create_recorders
Pigeons.create_reference_log_potential
Pigeons.create_replica_indexer
Pigeons.create_replicas
Pigeons.create_swap_graph
Pigeons.create_tempering
Pigeons.create_vector_replicas
Pigeons.default_explorer
Pigeons.default_reference
Pigeons.deo
Pigeons.deserialize_immutables!
Pigeons.discrete_variables
Pigeons.discretize
Pigeons.disk
Pigeons.energy_ac1
Pigeons.energy_ac1s
Pigeons.energy_ac1s
Pigeons.entangler
Pigeons.equally_spaced_schedule
Pigeons.explore!
Pigeons.explore!
Pigeons.explorer_acceptance_pr
Pigeons.explorer_n_steps
Pigeons.explorer_recorder_builders
Pigeons.explorer_step
Pigeons.extract_sample
Pigeons.find_global_index
Pigeons.find_local_index
Pigeons.find_log_potential
Pigeons.find_process
Pigeons.flush_immutables!
Pigeons.forward_sample_condition_and_explore
Pigeons.forward_sample_condition_and_explore
Pigeons.get_buffer
Pigeons.get_buffer
Pigeons.get_sample
Pigeons.get_sample
Pigeons.get_statistic
Pigeons.get_tape_compilation_strategy
Pigeons.global_barrier
Pigeons.index_process
Pigeons.informal_doc
Pigeons.initialization
Pigeons.initialization
Pigeons.interpolate
Pigeons.invariance_test
Pigeons.is_finished
Pigeons.is_reference
Pigeons.is_target
Pigeons.json
Pigeons.kill_child_processes
Pigeons.kill_job
Pigeons.last_round_max_allocation
Pigeons.last_round_max_time
Pigeons.latest_checkpoint_folder
Pigeons.load
Pigeons.load
Pigeons.locals
Pigeons.log_sum_ratio
Pigeons.log_unnormalized_ratio
Pigeons.log_unnormalized_ratio
Pigeons.mpi_active
Pigeons.my_global_indices
Pigeons.my_load
Pigeons.n_chains
Pigeons.n_chains
Pigeons.n_round_trips
Pigeons.n_round_trips
Pigeons.n_tempered_restarts
Pigeons.n_tempered_restarts
Pigeons.next_exec_folder
Pigeons.online
Pigeons.only_one_process
Pigeons.optimal_schedule
Pigeons.partner_chain
Pigeons.permuted_get
Pigeons.permuted_set!
Pigeons.pigeons
Pigeons.pigeons
Pigeons.pigeons
Pigeons.pigeons
Pigeons.pigeons
Pigeons.process_sample
Pigeons.process_sample
Pigeons.process_sample
Pigeons.providers
Pigeons.queue_status
Pigeons.queue_status
Pigeons.record!
Pigeons.record!
Pigeons.record!
Pigeons.record_default
Pigeons.record_if_requested!
Pigeons.record_online
Pigeons.record_swap_stats!
Pigeons.record_swap_stats!
Pigeons.recorded_continuous_variables
Pigeons.recorder_values
Pigeons.recursive_equal
Pigeons.reduce_deterministically
Pigeons.reduce_recorders!
Pigeons.register_online_type
Pigeons.rejections
Pigeons.report!
Pigeons.reversibility_rate
Pigeons.round_trip
Pigeons.run_checks
Pigeons.run_one_round!
Pigeons.safelink
Pigeons.sample_array
Pigeons.sample_iid!
Pigeons.sample_names
Pigeons.sample_segment!
Pigeons.serialize_immutables
Pigeons.set_tape_compilation_strategy!
Pigeons.setup_blang
Pigeons.setup_mpi
Pigeons.setup_mpi
Pigeons.setup_mpi_compute_canada
Pigeons.setup_mpi_sockeye
Pigeons.single_process_load
Pigeons.sort_includes!
Pigeons.split_slice
Pigeons.step!
Pigeons.stepping_stone
Pigeons.stepping_stone_pair
Pigeons.swap!
Pigeons.swap!
Pigeons.swap!
Pigeons.swap_acceptance_pr
Pigeons.swap_decision
Pigeons.swap_decision
Pigeons.swap_stat
Pigeons.swap_stat
Pigeons.tempering_recorder_builders
Pigeons.timing_extrema
Pigeons.toy_mvn_target
Pigeons.toy_stan_target
Pigeons.toy_turing_unid_target
Pigeons.traces
Pigeons.transmit
Pigeons.transmit!
Pigeons.update_reference!
Pigeons.update_state!
Pigeons.variable
Pigeons.variational_deo
Pigeons.variational_recorder_builders
Pigeons.watch
Pigeons.write_checkpoint
RecipesBase.apply_recipe
RecipesBase.apply_recipe
Statistics.mean
Statistics.var
Pigeons.@abstract
Pigeons.@auto
Pigeons.@informal
Pigeons.@record_if_requested!
Types and functions
Pigeons.registered_online_types
— ConstantOnlineStat
types to be computed when the [online()
] recorder is enabled.
Pigeons.AAPS
— TypeThe Apogee to Apogee Path Sampler (AAPS) by Sherlock et al. (2022).
AAPS is a simple alternative to the No U-Turn Sampler (NUTS). It serves a similar purpose as NUTS: the method should be robust to its choice of tuning parameters when compared to standard HMC. For a given starting position and momentum (x, v), AAPS explores both forward and backward trajectories. The trajectories are divided into segments, with segments being separated by apogees (local maxima) in the energy landscape of -log pi(x). The tuning parameter K
defines the number of segments to explore.
Pigeons.Augmentation
— TypeA state augmentation used by explorers. Internally, it hijacks the recorders machinery to store (usually volatile) data in a Replica. This helps with writing allocation-light code by pre-allocating objects inside the Augmentation, while avoiding race-conditions between replicas. For an application, see buffers
.
contents
: The payload. Can benothing
for efficiency purposes.
serialize
: When it is volatile, i.e. can be reconstructed on the fly and is only stored for efficiency purpose, it is not worth serializing it
Pigeons.AutoMALA
— TypeThe Metropolis-Adjusted Langevin Algorithm with automatic step size selection.
Briefly, at each iteration, the step size is exponentially shrunk or grown until the acceptance rate is in a reasonable range. A reversibility check ensures that the move is reversible with respect to the target. The process is started at step_size
, which at the end of each round is set to the average exponent used across all chains.
The number of steps per exploration is set to base_n_refresh * ceil(Int, dim^exponent_n_refresh)
.
At each round, an empirical diagonal marginal standard deviation matrix is estimated. At each step, a random interpolation between the identity and the estimated standard deviation is used to condition the problem.
In normal circumstance, there should not be a need for tuning, however the following optional keyword parameters are available:
base_n_refresh
: The base number of steps (equivalently, momentum refreshments) between swaps. This base number gets multiplied byceil(Int, dim^(exponent_n_refresh))
.
exponent_n_refresh
: Used to scale the increase in number of refreshment with dimensionality.
default_autodiff_backend
: The default backend to use for autodiff. See https://github.com/tpapp/LogDensityProblemsAD.jl#backendsCertain targets may ignore it, e.g. if a manual differential is offered or when calling an external program such as Stan.
For tape-based AD backends like ReverseDiff, compilation can be controlled using
Pigeons.set_tape_compilation_strategy!
.
step_size
: Starting point for the automatic step size algorithm. Gets updated automatically between each round.
preconditioner
: A strategy for building a preconditioner.
estimated_target_std_deviations
: This gets updated after first iteration; initiallynothing
in which case an identity mass matrix is used.
Reference: Biron-Lattes, M., Surjanovic, N., Syed, S., Campbell, T., & Bouchard-Côté, A.. (2024). autoMALA: Locally adaptive Metropolis-adjusted Langevin algorithm. Proceedings of The 27th International Conference on Artificial Intelligence and Statistics, in Proceedings of Machine Learning Research 238:4600-4608.
Pigeons.BlangTarget
— TypeA StreamTarget
delegating exploration to Blang worker processes.
using Pigeons
Pigeons.setup_blang("blangDemos", "UBC-Stat-ML") # pre-compile the blang models in the github repo UBC-Stat-ML/blangDemos
pigeons(target = Pigeons.blang_ising());
Type Pigeons.blang
followed by tab to find other examples.
Pigeons.BufferedAD
— TypeHolds a buffer for in-place auto-differentiation. For example, used by stan log potentials.
Fields:
enclosed
: A struct satisfying theLogDensityProblems
informal interface.buffer
: The buffer used for in-place gradient computation.logd_buffer
: A buffer for logdensity eval.err_buffer
: A buffer to hold error flags.
Pigeons.ChildProcess
— TypeFlag to run to a new julia process. Useful e.g. to dynamically control the number of threads to use or to use MPI on a single machine.
Fields:
n_threads
: The number of threads to provide in the child julia process, the same as the current process by default.
dependencies
: Julia modules (if of typeModule
) or paths to include (if of typeString
) needed by the child process.
n_local_mpi_processes
: If greater than one, run the code locally over MPI using that many MPI processes. In most cases, this is useful only for debugging purpose, as multi-threading should typically perform better. This could also potentially be useful if using a third-party target distribution which somehow does not support multi-threading.
wait
: If wait is false, the process runs asynchronously. When wait is false, the process' I/O streams are directed to devnull.
mpiexec_args
: Extra arguments passed to mpiexec.
Pigeons.Compose
— TypeA deterministic composition of two explorers. E.g. Compose(SliceSampler(), AutoMALA())
Pigeons.DiagonalPreconditioner
— TypeConstructs a diagonal preconditioner using the estimated precisions of the samples from the previous round.
Pigeons.DistributionLogPotential
— TypeProvides a reference type for Pigeons based on an encapsulated Distribution type.
dist
: The encapsulated distribution.
Pigeons.EntangledReplicas
— TypeAn implementation of replicas
for distributed PT. Contains:
locals
: The subset of replicas hosted in this process
chain_to_replica_global_indices
: A specialized distributed array that maps chain indices to replica indices (global indices). This corresponds to the mapping $\boldsymbol{j}$ in line 2 of Algorithm 5 in Syed et al, 2021.
Pigeons.Entangler
— TypeAssume all the MPI processes linked by this communicator will all call the key operations listed below the same number of times in their lifetime, at logically related occasions (e.g. a set number of times per iteration for algorithms running the same number of iterations). We call these 'occasions' a micro-iteration.
This datastructure keeps track internally of appropriate unique tags to coordinate the communication between MPI processes without having to do any explicit synchronization.
This struct contains:
communicator
: An MPIComm
object (or nothing if a single process is involved).
load
: How a set of tasks or "global indices" are distributed across processes.
current_received_bits
: An internal datastructure used during MPI calls.
n_transmits
: The current micro-iteration. Do not rely on it to count logical steps as it is reset to zero aftertransmit_counter_bound
micor-iterations to avoid underflows to negative tags which cause MPI to crash.
transmit_counter_bound
: Calculated from MPI.tagub and nglobal_indices to ensure MPI tags stay valid (i.e. do not overflow into negative values).
The key operations supported:
transmit()
andtransmit!()
: encapsulates pairwise communications in which each MPI process is holding aVector
, the elements of which are to be permuted across the processes.all_reduce_deterministically
andreduce_deterministically
, to perform MPI collective reduction while maintaining the Parallelism Invariance property.
Pigeons.FromCheckpoint
— TypeFlag create_replicas
(and related functions) that replicas should be loaded from a checkpoint. Fields:
checkpoint_folder
Pigeons.GaussianReference
— TypeA Gaussian mean-field variational reference (i.e., with a diagonal covariance matrix).
Pigeons.IdentityPreconditioner
— TypeUses the identity as preconditioner. Equivalent to no preconditioning.
Pigeons.Indexer
— TypeA bijection between integers and some type T
. T
is assumed to have consistent hash
and ==
. The two sides of the bijection can be obtained with the fields:
i2t
: AVector
mapping integers to objects t of typeT
.
t2i
: ADict
mapping objects t of typeT
to integers.
Pigeons.Indexer
— MethodIndexer(i2t)
Create an Indexer
with the given Int
to T
mapping.
Pigeons.Inputs
— TypeA Base.@kwdef
struct used to create Parallel Tempering algorithms.
Fields (see source file for default values):
target
: The target distribution.seed
: The master random seed.n_rounds
: The number of rounds to run.n_chains
: The number of chains to use (but see alson_chains_variational
).n_chains_variational
: The number of chains to use for a variational leg of parallel tempering. The default value is zero. If the variational argument is not specified, this argument does nothing. Otherwise, a value of zero corresponds to basic single-leg variational parallel tempering, where the number of chains is taken from then_chains
argument. A positive value yields "stabilized" two-leg variational parallel tempering. In that case, the number of chains for the prior-reference leg is taken fromn_chains
, and the number of chains for the variational leg is taken from this argument. See https://arxiv.org/abs/2206.00080
reference
: The reference distribution (e.g. a prior), or if nothing and a fixed reference is needed (i.e. variational inference is disabled or two-legged variational inference is used), thendefault_reference()
will be called to automatically determine the reference based on the type of the target.variational
: The variational reference family, or nothing to disable variational inference.checkpoint
: Whether a checkpoint should be written to disk at the end of each round.
record
: Determine what should be stored from the simulation. A Vector with elements of typerecorder_builder
.
checked_round
: The round index whererun_checks()
will be performed. Set to 0 to skip these checks.
multithreaded
: If multithreaded explorers should be allowed. False by default since it incurs an overhead.
explorer
: Theexplorer
to use, or if nothing, will usedefault_explorer()
to automatically determine the explorer based on the type of the target.
extractor
: Passed toextract_sample
andsample_names
to determine how samples should be extracted fortraces
.The value
nothing
signals default behaviour. UseLogPotentialExtractor
to extract only the log potential.
show_report
: Show sampling report?
Pigeons.InterpolatedAD
— TypeThe target and reference may used different autodiff frameworks; provided both are non-allocating, this allows autodiff of InterpolatedLogPotential
's to also be non-allocating. For example, this is useful when the target is a stan log potential and the reference is a variational distribution with a hand-crafted, also allocation-free differentiation.
Fields:
enclosed
: The enclosedInterpolatedLogPotential
.ref_ad
: The result ofLogDensityProblemsAD.ADgradient()
on the reference, often aBufferedAD
.
target_ad
: The same asref_ad
but with the target.
buffer
: An extra buffer to combine the two distribution endpoints gradients.
Pigeons.InterpolatedLogPotential
— TypeA log_potential
obtained by evaluation of a path
at a point beta in the closed interval $[0, 1]$.
Pigeons.InterpolatingPath
— MethodInterpolatingPath(ref, target)
Given a reference log_potential
and a target log_potential
, return a path
interpolating between them.
By default, the interpolator
is a LinearInterpolator
, i.e. standard annealing.
Pigeons.Iterators
— TypeIterators used in Parallel Tempering. Stored in a struct so that recorder
's can access it when outputting sample statistics.
Fields:
round
: Index of the Parallel Tempering adaptation round, as defined in Algorithm 4 of Syed et al., 2021. Set to zero when when pigeons() not yet started.
scan
: Number of (exploration, communication) pairs performed so far, corresponds to $n$ in Algorithm 1 of Syed et al., 2021. Round $i$ typically performs $2^i$ scans. Set to zero when runoneround!() is not yet started.
Pigeons.LazyTarget
— TypeUse when a target contains information that cannot be serialized, e.g. FFT plans (https://discourse.julialang.org/t/distributing-a-function-that-uses-fftw/69564) so that the target is constructed just in time by each MPI node.
# in a script.jl:
struct MyTargetFlag end
import Pigeons.instantiate_target
Pigeons.instantiate_target(flag::MyTargetFlag) = toy_mvn_target(1)
# to run
pigeons(target = Pigeons.LazyTarget(MyTargetFlag()), on = ChildProcess(dependencies = ["script.jl"]))
Pigeons.LoadBalance
— TypeSplit a list of indices across processes. These indices are denoted $1, 2, .., N$. They are usually some kind of task, for example in the context of parallel tempering, two kinds of tasks arise:
- in
replicas.state
, task $i$ consists in keeping track of the state of replica $i$. - in
replicas.chain_to_replica_global_indices
, task $i$ consists in storing which replica index corresponds to chain $i$.
One such task index is called a global_index
.
LoadBalance splits the global indices among n_processes
. LoadBalance is constructed so that the difference in the number of global indices a process is responsible of (its "load") is at most one.
A LoadBalance
contains:
my_process_index
: A unique index for this process. We use 1-indexed, i.e. hide MPI's 0-indexed ranks.
n_processes
: Total number of processes involved.
n_global_indices
: The total number of global indices shared between all the processes.
The set {1, 2, .., load()
} is called a set of local indices. A local index indexes a slice in {1, 2, ..., n_global_indices
}. Collectively over the n_processes
, these slices form a partition of the global indices.
Key functions to utilize a LoadBalance struct:
Pigeons.LogPotentialExtractor
— TypeSignal that only the log potential should be recorded into traces
. See pt.inputs.extractor
.
Pigeons.MALA
— TypeThe Metropolis-Adjusted Langevin Algorithm (MALA).
MALA is based on an approximation to overdamped Langevin dynamics followed by a Metropolis-Hastings correction to ensure that we target the correct distribution.
This round-based version of MALA allows for the use of a preconditioner, which is updated after every PT tuning round. This setting can also be turned off by specifying the type of preconditioner to use. However, MALA will not automatically adjust the step size. For such functionality, use autoMALA.
As for autoMALA, the number of steps per exploration is base_n_refresh * ceil(Int, dim^exponent_n_refresh)
.
Pigeons.MPIProcesses
— TypeFlag to run on MPI. Before using, you have to call once setup_mpi
.
Fields:
n_threads
: The number of threads per MPI process, 1 by default.
walltime
: The walltime limit, 00:30:00 by default (i.e., 30 minutes).
n_mpi_processes
: The number of MPI processes, 2 by default.
memory
: The memory allocated to each MPI process, 8gb by default.
dependencies
: Julia modules (if of typeModule
) or paths to include (if of typeString
) needed by the child process.
mpiexec_args
: Extra arguments passed to mpiexec.
Pigeons.MPISettings
— TypeGlobal settings needed for MPI job submission:
submission_system
: E.g.::pbs
,:slurm
, etcUse
Pigeons.supported_submission_systems()
to see the list of available options.
add_to_submission
: Add lines to the submission scripts.E.g. used in UBC Sockeye for custom allocation code via
add_to_submission = ["#PBS -A my_user_allocation_code"]
or in Compute Canada (optional if member of only one account, see https://docs.alliancecan.ca/wiki/Running_jobs):
add_to_submission = ["#SBATCH --account=my_user_name"]
`
environment_modules
: "Envirnonment modules" to load (not to be confused with Julia modules). Runmodule avail
in the HPC login node to see what is available on your HPC. For example:["git", "gcc", "intel-mkl", "openmpi"]
on Sockeye, and["intel", "openmpi", "julia"]
on Compute Canada
library_name
: In most case, leave empty as MPIPreferences.usesystembinary() will autodetect, but if it does not, the path to libmpi.so can be specified this way, e.g. this is needed on compute Canada clusters (as they are not setting that environment variable correctly) where it needs to be set to "/cvmfs/soft.computecanada.ca/easybuild/software/2020/avx2/Compiler/intel2020/openmpi/4.0.3/lib/libmpi" (notice the .so is not included).
Pigeons.Mix
— TypeRandomly alternate between different explorers.
explorers
: A tuple consisting of exploration kernels
Pigeons.MixDiagonalPreconditioner
— TypeSimilar to DiagonalPreconditioner
but the actual preconditioner used at each iteration is a random mixture of the identity and the adapted diagonal matrix. This helps with targets featuring distantly separated modes, which induces average standard deviations that are much higher than the ones within each mode. Even in the family of Gaussian targets, Hird & Livingstone (2023) identify cases where a fixed diagonal preconditioner performs worse than using no preconditioner at all. We use a zero-one-inflated Uniform(0,1) distribution for the mixing proportion in order to make the preconditioner robust to extreme mismatch of scales (see the automala paper for more details).
p0
: Proportion of zerosp1
: Proportion of ones
Pigeons.NonReversiblePT
— TypeVariables needed for the non-reversible Parallel Tempering described in Syed et al., 2021:
path
: Thepath
.schedule
: TheSchedule
.log_potentials
: Thelog_potentials
.swap_graphs
: Theswap_graphs
.communication_barriers
: The communication barriers computed bycommunication_barriers()
at the same time as this tempering was created; or nothing before adaptation, i.e. before the first call toadapt_tempering
.
Pigeons.NonReversiblePT
— MethodNonReversiblePT(inputs)
The adaptive non-reversible Parallel Tempering described in Syed et al., 2021.
Pigeons.OddEven
— TypeProvides a swap_graph
.
Pigeons.OnlineStateRecorder
— TypeSee online()
.
Pigeons.PT
— TypeStorage involved in PT algorithms:
inputs
: The user-providedInputs
that determine the execution of a PT algorithm.
replicas
: Thereplicas
held by this machine.
shared
: Information shared across all machines, updated between rounds.
exec_folder
: Either a path to a folder shared by all processes, which is used to save information to disk (checkpoints, samples etc); or nothing if a completely in-memory algorithm is used.
Pigeons.PT
— MethodPT(source_exec_folder; round, exec_folder)
Create a PT
struct from a saved checkpoint. The input source_exec_folder
should point to a folder of the form results/all/[exec_folder]
.
The checkpoint carries all the information stored in a PT
struct. It is possible for an MPI-based execution to load a checkpoint written by a single-process execution and vice versa.
A new unique folder will be created with symlinks to the source one, so that e.g. running more rounds of PT will results in a new space-efficient checkpoint containing all the information for the new run.
Pigeons.PT
— MethodPT(inputs; exec_folder)
Create a PT struct from provided Inputs
. Optionally, provide a specific exec_folder
path (AbstractString
), if not one will be created via next_exec_folder()
.
Pigeons.PermutedDistributedArray
— TypeA distributed array making special assumptions on how it will be accessed and written to. The indices of this distributed array correspond to the notion of "global indices" defined in LoadBalance
. Several MPI processes cooperate, each processing storing data for a slice of this distributed array.
We make the following assumptions:
Each MPI process will set/get entries the same number of times in their lifetime, at logically related episodes (e.g. a set number of times per iteration for algorithms running the same number of iterations). These episodes are called micro-iterations as in
Entangler
, which this datastructure is built on.Moreover, at each time all processes perform a get or a set, we assume that each global index is manipulated by exactly one process (i.e. an implicit permutation of the global indices).
We use these assumptions to achieve read/write costs that are near-constant in the number of machines participating.
This struct contains:
local_data
: The slice of the distributed array maintained by this MPI process.
entangler
: AnEntangler
used to coordinate communication.
The operations supported are:
Pigeons.Preconditioner
— TypeAn abstract type for preconditioners. See IdentityPreconditioner
, DiagonalPreconditioner
, and MixDiagonalPreconditioner
.
Pigeons.Replica
— TypeOne of the $N$ components that forms the state maintained by a PT algorithm. A Replica contains:
state
: Configuration in the state space.chain
: The index of the distribution currently associated with this replica, modified during swaps.
rng
: Random operations involving this state should use only this random number generator.
recorders
: Records statistics. Each replica carries its own for thread safety/distribution; then they are reduced at end of each round.
replica_index
: A global id associated with this replica.
Pigeons.Result
— TypeA link to an execution folder able to deserialize type T via a string constructor.
Pigeons.RoundTripRecorder
— TypeSee round_trip()
.
Pigeons.SampleArray
— Typestruct SampleArray{T, PT} <: AbstractArray{T, 1}
Array convience wrapper for traces
reduced recorder. We require a PT
object, and the chain
number which specifies the chain index (has to be a target chain) you wish to extract.
This should not be called directly and the user should instead look at get_sample
.
Pigeons.ScaledPrecisionNormalPath
— TypeA path
of zero-mean normals for testing; contains:
precision0
: Precision parameter of the reference.precision1
: Precision parameter of the target.dim
: Dimensionality.
Pigeons.ScaledPrecisionNormalPath
— MethodScaledPrecisionNormalPath(dim)
Toy Multivariate Normal (MVN) path of distributions for testing: see section I.4.1 in Syed et al 2021.
Pigeons.Schedule
— TypeA partition of $[0, 1]$ encoded by monotonically increasing grid points starting at zero and ending at one.
Pigeons.Shared
— TypeInformation shared by all processes involved in a round of distributed parallel tempering. This is updated between rounds but only read during a round.
Fields:
iterators
: SeeIterators
.
tempering
: Seetempering
.
explorer
: Seeexplorer
.
reports
: Named tuple of DataFrame's
Only one instance maintained per process.
Pigeons.Shared
— MethodShared(inputs)
Create a Shared
struct based on an Inputs
. Uses create_tempering()
and create_explorer()
.
Pigeons.SliceSampler
— TypeSlice sampler based on Neal, 2003.
Fields:
w
: Initial slice size.p
: Slices are no larger than 2^p * wn_passes
: Number of passes through all variables per exploration step.max_iter
: Maximum number of interations inside shrink_slice! before erroring out
Pigeons.StabilizedPT
— TypeStabilized Variational Parallel Tempering as described in Surjanovic et al., 2022.
Fields:
fixed_leg
: The fixed leg of stabilized PT. Contains apath
,Schedule
,log_potentials
, andcommunication_barriers
.swap_graphs
is also included but is overwritten by this struct'sswap_graphs
.
variational_leg
: The variational leg of stabilized PT.swap_graphs
: Aswap_graphs
spanning both legs.log_potentials
: Thelog_potentials
.indexer
: AnIndexer
mapping between global indices and leg-specific indices.
Pigeons.StabilizedPT
— MethodStabilizedPT(inputs)
Parallel tempering with a variational reference described in Surjanovic et al., 2022.
Pigeons.StanLogPotential
— TypeUses BridgeStan
to perform efficient ccall
loglikelihood and allcoation-free gradient calls to a Stan model.
To work with Pigeons BridgeStan
needs to be imported into the current session.
Pigeons.StanState
— TypeA state for stan target. Holds a vector in BridgeStan's unconstrained parameterization.
Pigeons.StreamState
— TypeStates used in the replicas when a stream target is used.
Pigeons.StreamTarget
— TypeA target
based on running worker processes, one for each replica, each communicating with Pigeons using standard streams. These worker processes can be implemented in an arbitrary programming language.
StreamTarget
implements log_potential
and explorer
by invoking worker processes via standard stream communication. The standard stream is less efficient than alternatives such as protobuff, but it has the advantage of being supported by nearly all programming languages in existence. Also in many practical cases, since the worker process is invoked only three times per chain per iteration, it is unlikely to be the bottleneck (overhead is in the order of 0.1ms).
The worker process should be able to reply to commands of the following forms (one command per line):
log_potential(0.6)
in the worker'sstdin
to which it should return a response of the formresponse(-124.23)
in itsstdout
, providing in this example the joint log density atbeta = 0.6
;call_sampler!(0.4)
signaling that one round of local exploration should be performed atbeta = 0.4
, after which the worker should signal it is done withresponse()
.
Pigeons.Submission
— TypeSpecifies where to submit a task.
Pigeons.SwapStat
— TypeDefault statistics exchanged by a pair of chains in the process of proposing a swap:
log_ratio
uniform
See swap_stat()
Pigeons.TestSwapper
— TypeFor testing/benchmarking purposes, a simple pair_swapper
where all swaps have equal acceptance probability.
Could also be used to warm-start swap connections during exploration phase by setting that constant probability to zero.
Pigeons.ThisProcess
— TypeFlag to ask to run a function within the current process.
Pigeons.ToyExplorer
— TypeToy explorer
for toy paths where each log_potential
supports i.i.d. sampling via rand!(rng, x, log_potential)
.
Pigeons.TuringLogPotential
— TypeUses DynamicPPL
i.e. Turing
's backend to construct the log density.
To work with Pigeons DynamicPPL
or Turing
needs to be imported into the current session.
model
: ADynamicPPL.Model
.
context
: EitherDynamicPPL.DefaultContext
for evaluating the full joint, orDynamicPPL.PriorContext
for evaluating only the prior.
dimension
: The total number of scalar values observed in a single random sample frommodel
. It is used by theLogDensityProblems
andLogDensityProblemsAD
interfaces when a gradient-based sampler is used as explorer in models with static computational graphs.Warning Explorers targeting models with dynamic computational graphs should not depend on the value of this field.
Pigeons.VariationalOddEven
— TypeProvides a swap_graph
.
Pigeons._transformed_online
— MethodOnline statistics on potentially transformed samples for the target chain. For example, if a gradient-based method is used, the target is often transformed to be defined on an unconstrained space. This is used internally by explorer
's for adaptation purposes (in particular, pre-conditioning and variational references).
Pigeons.aaps!
— MethodMain function for AAPS. Note that this implementation uses scheme (1) from the AAPS paper, which results in an acceptance probability of one.
Pigeons.activate_variational
— Methodactivate_variational(variational, iterators)
Choose on which rounds/scans to activate the variational reference.
Pigeons.ad_buffers
— Methodad_buffers()
An Augmentation
for Pigeons.BufferedAD
.
Pigeons.adapt
— Methodadapt(pt, reduced_recorders)
Call adapt_tempering()
followed by adapt_explorer
.
Pigeons.adapt_explorer
— Methodadapt_explorer(
explorer,
reduced_recorders,
current_pt,
new_tempering
)
Called between successive rounds (run_one_round!
).
By default, return the explorer without further adaptation.
Pigeons.adapt_tempering
— Methodadapt_tempering(
tempering,
reduced_recorders,
iterators,
variational,
state
)
Called between successive rounds (run_one_round!
).
Given a tempering
and reduced recorders
return an updated tempering
.
Pigeons.all_reduce_deterministically
— Methodall_reduce_deterministically(operation, source_data, e)
Same as reduce_deterministically()
except that the result at the root of the tree is then broadcast to all machines so that the output of all_reduce_deterministically()
is the root of the reduction tree for all MPI processes involved.
Pigeons.all_reports
— Methodall_reports()
The iterim diagnostics computed and printed to standard out at the end of every iteration (this can be disabled using show_report = false
).
Pigeons.allocation_extrema
— MethodAllocations informations.
Pigeons.analytic_cumulativebarrier
— Methodanalytic_cumulativebarrier(path)
Known cumulative barrier used for testing, from Predescu et al., 2003.
Pigeons.blang_ising
— Methodblang_ising(model_options)
Two-dimensional Ising model.
For more information:
using Pigeons
Pigeons.setup_blang("blangDemos")
run(Pigeons.blang_ising(`--help`).command);
E.g., use arguments `model.N` to set the size
of the grid.
Pigeons.blang_ising
— Methodblang_ising()
15x15 Ising model.
Pigeons.blang_sitka
— Methodblang_sitka(model_options)
Model for phylogenetic inference from single-cell copy-number alteration from Salehi et al., 2020.
For more information:
using Pigeons
Pigeons.setup_blang("nowellpack")
run(Pigeons.blang_sitka(`--help`).command);
Pigeons.blang_sitka
— Methodblang_sitka()
Default options for infering a posterior distribution on phylogenetic trees for the 535 triple negative breast cancer dataset in Salehi et al., 2020.
Pigeons.buffers
— Methodbuffers()
buffers()
A buffering system used internally by explorers in Pigeons.
Pigeons.check_against_serial
— Methodcheck_against_serial(pt)
Run a separate, fully serial version of the PT algorithm, and compare the checkpoint files to ensure the two produce exactly the same output.
Pigeons.communicate!
— Methodcommunicate!(pt)
Use create_pair_swapper()
and create_swap_graph
to construct the inputs needed for swap!
.
Pigeons.communication_barriers
— Methodcommunication_barriers(intensity, schedule)
Compute the local communication barrier and cumulative barrier functions from the intensity
rates (i.e. rejection rates in the context of Parallel Tempering) and the current annealing schedule
. The estimation of the barriers is based on Fritsch-Carlson monotonic interpolation.
Returns a NamedTuple
with fields:
localbarrier
cumulativebarrier
globalbarrier
Pigeons.communicator
— Methodcommunicator(replicas)
Return the replicas
's MPI.Comm
or nothing
if no MPI needed
Pigeons.continuous_variables
— Methodcontinuous_variables(state)
The names (each a Symbol
) of the continuous variables in the given state
.
Pigeons.continuous_variables
— Methodcontinuous_variables(pt)
Pigeons.create_entangled_replicas
— MethodPigeons.create_explorer
— Methodcreate_explorer(inputs)
Given an Inputs
object, either use inputs.explorer
, of if it is equal to nothing
dispatch on default_explorer(inputs.target)
to construct the explorer associated with the input target distribution.
Pigeons.create_pair_swapper
— Methodcreate_pair_swapper(tempering, target)
Given a tempering
and a target
, create a pair_swapper
.
If omitted, by default will return the standard Metropolis-Hastings accept-reject.
Pigeons.create_path
— Methodcreate_path(target, inputs)
Create a path
, by default linking the given target
to the refence provided by create_reference_log_potential()
.
For this default to work, the target should conform both target
and log_potential
.
Pigeons.create_path
— Methodcreate_path(target, inputs)
In this case, the target is already a path
, so return it.
Pigeons.create_recorders
— Methodcreate_recorders(recorder_builders)
Create a recorders
from an iterable with element type recorder_builder
.
Pigeons.create_recorders
— MethodPigeons.create_reference_log_potential
— Methodcreate_reference_log_potential(inputs)
Given an Inputs
object, either use inputs.reference
, of if it is equal to nothing
dispatch on default_reference(inputs.target)
to construct the reference log_potential
associated with the input target distribution.
Pigeons.create_replica_indexer
— Methodcreate_replica_indexer(n_chains_fixed, n_chains_var)
Create an Indexer
for stabilized variational PT. Given a chain number, return a tuple indicating the relative chain number within a leg of PT and the leg in which it is located. Given a tuple, return the global chain number.
Pigeons.create_replicas
— Functioncreate_replicas(inputs, shared)
create_replicas(inputs, shared, source)
Create replicas
, detecting automatically if MPI is needed.
Argument source
is either nothing, when creating new states, or FromCheckpoint
to load from a saved checkpoint.
Pigeons.create_swap_graph
— Methodcreate_swap_graph(swap_graphs, shared)
Given a swap_graphs
and Shared
, return the swap_graph
for the current iteration.
Pigeons.create_tempering
— Methodcreate_tempering(inputs)
Build the tempering
needed for communicate!()
.
Pigeons.create_vector_replicas
— Methodcreate_vector_replicas(inputs, shared, source)
Create replicas
when distributed computing is not needed.
See create_replicas
.
Pigeons.default_explorer
— Methoddefault_explorer(target)
The default explorer
for the given target
.
It can be overwritten by the argument explorer
in pigeons()
.
By default, a SliceSampler
.
Pigeons.default_reference
— Methoddefault_reference(target)
Create a default reference distribution, by returning a log_potential
.
The returned object will get passed to sample_iid!()
at the "hot chains" of the Parallel Tempering algorithm.
It can be overwritten by the argument reference
in pigeons()
.
Pigeons.deo
— Methoddeo(n_chains)
Implements the Deterministic Even Odd (DEO) scheme proposed in Okabe, 2001 and analyzed in Syed et al., 2021.
Pigeons.deserialize_immutables!
— Methoddeserialize_immutables!(filename)
See Immutable
's.
Pigeons.discrete_variables
— Methoddiscrete_variables(state)
The names (each a Symbol
) of the discrete (Int) variables in the given state.
Pigeons.discretize
— Methoddiscretize(path, betas)
Create log_potentials
from a path
by interpolating the path at each grid point specified in the Schedule
.
Pigeons.disk
— MethodSave the full trace for the target chain to disk.
The disk
recorders are safe to use in a multi-threaded and/or distributed context as each replica uses its own file.
To post-process files in the correct order, use process_sample
.
Pigeons.energy_ac1
— MethodAuto-correlation before and after an exploration step, grouped by chain.
Pigeons.energy_ac1s
— Functionenergy_ac1s(reduced_recorders)
energy_ac1s(reduced_recorders, skip_reference)
energy_ac1s(reduced_recorders, skip_reference, pt)
Pigeons.energy_ac1s
— Functionenergy_ac1s(pt)
energy_ac1s(pt, skip_reference)
Auto-correlations between energy before and after an exploration step, for each chain. Organized as a Vector
where component i corresponds to chain i.
It is often useful to skip the reference chain, for two reasons, first, exploration should be iid there, second, if the prior is flat the auto-correlation of the energy will be NaN for the reference.
Pigeons.entangler
— Methodentangler(replicas)
Return the replicas
's Entangler
(possibly a no-communication Entangler if a single process is involved)
Pigeons.equally_spaced_schedule
— Methodequally_spaced_schedule(n_chains)
Create a Schedule
with n_chains
equally spaced grid points.
Pigeons.explore!
— Methodexplore!(pt, explorer, multithreaded)
The @threads
macro brings a large overhead even when Threads.nthreads == 1
, so a separate method is used for the single thread mode.
Pigeons.explore!
— Methodexplore!(pt, explorer, multithreaded_flag)
Call sample_iid!
or step!()
on each chain (depending if it is a reference or not respectively).
Uses @threads
to parallelize across threads. This is safe by the contract described in sample_iid!()
and step!()
.
Pigeons.explorer_acceptance_pr
— MethodAverage MH swap acceptance probabilities for explorers.
Pigeons.explorer_n_steps
— MethodNumber of steps used by explorers.
Pigeons.explorer_recorder_builders
— Methodexplorer_recorder_builders(explorer)
What information is needed to perform adapt_explorer
? Answer this by specifying an iterator containing recorder_builder
's. Return []
if none are needed (default behaviour).
Pigeons.explorer_step
— Methodexplorer_step(rng, target, explorer, init_state)
Utility for taking a single step of an explorer
under a given target
and initial state init_state
. Returns the modified state.
Note that taking more than a single step can be achieved in many Pigeons explorers by modifying their arguments for number of passes or refreshements. For example, SliceSampler
takes an n_passes::Int
argument, while AutoMALA
takes the base_n_refresh::Int
argument.
Pigeons.extract_sample
— Methodextract_sample(state, log_potential, extractor)
Extract a sample for postprocessing. By default, calls copy()
but many overloads are defined for different kinds of states.
Typically, this will be a flattened vector (i.e. concatenation of all variables, with discrete ones converted to Float64) ready for post-processing.
The corresponding un-normalized log density might be appended at the very end.
If the state is transformed (e.g. for HMC), this will create a fresh vector with an un-transformed (i.e. original parameterization) state in it.
The argument extractor
is passed from the Inputs
.
Pigeons.find_global_index
— Methodfind_global_index(lb, local_idx)
Find the global index corresponding to the given local_index
.
Pigeons.find_local_index
— Methodfind_local_index(lb, global_idx)
Find the local index corresponding to the given global_index
. Assumes the given global_index
is one of this process'.
Pigeons.find_log_potential
— Methodfind_log_potential(replica, tempering, shared)
Find the log_potential
for the chain the replica is at, based on the tempering
and Shared
objects.
Pigeons.find_process
— Methodfind_process(lb, global_idx)
Find the process id (1-indexed) responsible for the given global_idx
.
Pigeons.flush_immutables!
— Methodflush_immutables!()
See Immutable
's.
Pigeons.forward_sample_condition_and_explore
— FunctionThe workhorse under invariance_test
. It starts with a full forward pass for the probabilistic model underlying target
, thats simulates latent variables and observations. Then a modified model is created that conditions the original model on the observations produced. Finally, the function takes a step using the explorer targetting the conditioned model and the final state is returned. The exploration can be optionally disabled by passing run_explorer=false
, in which case the initial simulated state is returned.
Pigeons.forward_sample_condition_and_explore
— Methodforward_sample_condition_and_explore(
target,
explorer,
rng;
run_explorer
)
Implementation for ScaledPrecisionNormalPath
. Since this toy model allows direct iid sampling from the target, conditioning is not necessary.
Pigeons.get_buffer
— Methodget_buffer(a, key, args)
Return a Pigeons.BufferedAD
if it exists in the Augmentation
. Otherwise it constructs one and then stores it to avoid reconstructing it in the future.
This implementation is not type stable (the value type of the Dict
is not concrete). However, the runtime dispatch cost incurred should be more than compensated by the ability to avoid reconstructing AD objects at each exploration step.
Pigeons.get_buffer
— Methodget_buffer(a, key, dims)
Return an array in the buffer. Allocating only the first time; after that, the buffer is recycled and stored in the Replica's recorders.
Pigeons.get_sample
— Functionget_sample(pt)
get_sample(pt, chain)
The chain
option can be omitted and by default the first chain targetting the distribution of interest will be used (in many cases, there will be only one, in variational cases, two).
Pigeons.get_sample
— Methodget_sample(pt, chain, scan)
Pigeons.get_statistic
— Methodget_statistic(pt, variable_name, t)
Pigeons.get_tape_compilation_strategy
— Methodget_tape_compilation_strategy()
Get the current Pigeons-wide tape compilation strategy for tape-based AD backends. Currently this is only used for ReverseDiff.
Pigeons.global_barrier
— Methodglobal_barrier(pt)
The global communication barrier. If the PT algorithm has both a fixed and variational references, return the barrier to the fixed one.
Pigeons.index_process
— MethodFull index process stored in memory.
Pigeons.informal_doc
— Methodinformal_doc(doc_dir, mod)
Generate informal interface documentation, e.g.:
makedocs(;
...
pages=[
"Home" => "index.md",
"Interfaces" => informal_doc(@__DIR__, MyModuleName),
...
]
)
Pigeons.initialization
— Methodinitialization(target, rng, replica_index)
Create a fresh state used to populate the states at the beginning of the first round of Parallel Tempering.
Pigeons.initialization
— Methodinitialization(target, rng, replica_index)
Return StreamState
by following these steps:
- create a
Cmd
that uses the providedrng
to set the random seed properly, as well as target-specific configurations provided bytarget
. - Create
StreamState
from theCmd
created in step 1 and return it.
Pigeons.interpolate
— Methodinterpolate(path, beta)
Returns the log_potential
at point beta
in the path
.
Pigeons.invariance_test
— FunctionRun an invariance test of explorer
on the provided target
. Corresponds to a modified Geweke test where the simulated data is kept fixed.
References
Bouchard-Côté, A., Chern, K., Cubranic, D., Hosseini, S., Hume, J., Lepur, M., Ouyang, Z., & Sgarbi, G. (2022). Blang: Bayesian Declarative Modeling of General Data Structures and Inference via Algorithms Based on Distribution Continua. Journal of Statistical Software, 103(11), 1–98.
Geweke, J. (2004). Getting It Right: Joint Distribution Tests of Posterior Simulators. Journal of the American Statistical Association, 99(467), 799–804.
Pigeons.is_finished
— Methodis_finished(checkpoint_folder, inputs)
Is the provided path to a checkpoint folder complete? I.e. check in the .signal subfolder that all MPI processes have signaled that they are done.
Pigeons.is_reference
— Methodis_reference(swap_graph, chain)
For a given swap_graph
and input chain
index, is the current chain a reference distribution?
Pigeons.is_target
— Methodis_target(swap_graph, chain)
For a given swap_graph
and input chain
index, is the current chain a target distribution?
Pigeons.json
— Methodjson(; variables...)
Create a JSON string based on the scalar or array variables provided.
Pigeons.kill_child_processes
— Methodkill_child_processes(pt)
Dispose of the child processes associated with the pt's StreamState
's
Pigeons.kill_job
— Methodkill_job(result)
Instruct the scheduler to cancel or kill a job.
Pigeons.last_round_max_allocation
— MethodMaximum bytes allocated (over the MPI process) to compute the last Parallel Tempering round.
Pigeons.last_round_max_time
— MethodMaximum time (over the MPI process) to compute the last Parallel Tempering round.
Pigeons.latest_checkpoint_folder
— Methodlatest_checkpoint_folder(exec_folder)
Pigeons.load
— Methodload(replicas)
Return the replicas
's LoadBalance
(possibly single_process_load
)
Pigeons.load
— Methodload(replicas)
load(result)
Load the result in memory.
Pigeons.locals
— Methodlocals(replicas)
Return the replica's that are stored in this machine
Pigeons.log_sum_ratio
— MethodLog of the sum of density ratios between neighbour chains, used to compute stepping stone estimators of lognormalization contants.
Pigeons.log_unnormalized_ratio
— Methodlog_unnormalized_ratio(
log_potentials,
numerator,
denominator,
state
)
Assumes the input log_potentials
is a vector where each element is a log_potential
.
This default implementation is sufficient in most cases, but in less standard scenarios, e.g. where the state space is infinite dimensional, this can be overridden.
Pigeons.log_unnormalized_ratio
— Methodlog_unnormalized_ratio(
log_potentials,
numerator,
denominator,
state
)
The argument numerator
selects one distribution $\pi_i$ from the collection log_potentials
, and similarly denominator
selects $\pi_j$. Let $x$ denote the input state
. The ratio:
\[f(x) = \frac{\text{d}\pi_i}{\text{d}\pi_j}(x)\]
may only be known up to a normalization constant which can depend on $i$ and $j$ but not $x$, $g(x) = C_{i,j} f(x)$.
This function should return $\log g$ evaluated at state
.
Pigeons.mpi_active
— Methodmpi_active()
A flag is set by launch scripts (see ChildProcess.jl) to indicate if this process is a child MPI process under an mpiexec. Otherwise, that flag is false by default.
This function retrieves the value of that flag.
Pigeons.my_global_indices
— Methodmy_global_indices(lb)
The slice of lb.global_indices
this process is reponsible for.
Pigeons.my_load
— Methodmy_load(lb)
Return the number of indices (task) this process is responsible for.
Pigeons.n_chains
— Methodn_chains(log_potentials)
The number of chains in the log_potentials
.
Pigeons.n_chains
— MethodExtract the number of Parallel Tempering chains from Inputs
.
Pigeons.n_round_trips
— Methodn_round_trips(reduced_recorders)
Pigeons.n_round_trips
— Methodn_round_trips(pt)
Pigeons.n_tempered_restarts
— Methodn_tempered_restarts(reduced_recorders)
Pigeons.n_tempered_restarts
— Methodn_tempered_restarts(pt)
Pigeons.next_exec_folder
— MethodReturn a unique subfolder of results/all/
, making sure the unique folder and its parents are created. It will also create a soft symlink to it called results/latest
`
Pigeons.online
— MethodOnline statistics on the target chain. The samples are processed in the original model parameterization.
Pigeons.only_one_process
— Methodonly_one_process(task, pt)
A task that should be ran on only one of the processes. Using the do .. end
syntax, this can be used as:
only_one_process(pt) do
...
end
Pigeons.optimal_schedule
— Methodoptimal_schedule(
intensity,
old_schedule,
new_schedule_n_chains
)
Return an optimal Schedule
based on statistics from a previous round.
Pigeons.partner_chain
— Methodpartner_chain(swap_graph, chain)
For a given swap_graph
and input chain
index, what chain will it interact with at the current iteration? Convention: if a chain is not interacting, return its index.
Pigeons.permuted_get
— Methodpermuted_get(p, indices)
Retreive the values for the given indices
, using MPI communication when needed.
We make the following assumptions:
length(indices) == my_load(p.entangler.load)
- the
indices
across all participating processes form a permutation of the global indices.
Pigeons.permuted_set!
— Methodpermuted_set!(p, indices, new_values)
Set the values for the given indices
to the given new_values
, using MPI communication when needed.
We make the same assumptions as in permuted_get()
.
Pigeons.pigeons
— Methodpigeons(pt_arguments, new_process)
Run Parallel Tempering in a new process. See ChildProcess
.
Pigeons.pigeons
— Methodpigeons(pt_arguments, mpi_submission)
Pigeons.pigeons
— Methodpigeons(pt_arguments; on)
pt_arguments
can be either an Inputs
, to start a new Parallel Tempering algorithm, or a string pointing to an execution to resume.
Pigeons.pigeons
— Methodpigeons(pt)
Run (a generalization of) Parallel Tempering.
This will call several rounds of run_one_round!()
, performing adaptation between each round via adapt()
.
This will also call report!()
, write_checkpoint()
, and run_checks()
between rounds.
Pigeons.pigeons
— Methodpigeons(; on, args...)
Passes the args...
to Inputs
and start a new Parallel Tempering algorithm with that inputs.
Pigeons.process_sample
— Functionprocess_sample(processor, pt)
process_sample(processor, pt, round)
Pigeons.process_sample
— Functionprocess_sample(processor, pt)
process_sample(processor, pt, round)
Pigeons.process_sample
— Methodprocess_sample(processor, exec_folder, round)
Process samples that were saved to disk using the disk
recorder, at the given round
.
Each sample is passed to the processor
function, by calling processor(chain_index, scan_index, sample)
where chain_index
is the index of the target chain (in classical parallel tempering, there is only one chain at target temperature, so in that case it can be ignored, but it will be non-trivial in e.g. stabilized variational parallel tempering), scan_index
is the iteration index within the round, starting at 1, and sample is the deserialized sample.
This iterates over the samples in increasing order, looping over chain_index
in the outer loop and scan_index
in the inner loop.
Pigeons.providers
— Methodproviders(mod, name)
Provides a Set{Expr}
containing all the providers of the given name in the given module.
Pigeons.queue_status
— Methodqueue_status(result)
Display the queue status for one MPI job.
Pigeons.queue_status
— Methodqueue_status()
Display the queue status for all the user's jobs.
Pigeons.record!
— Methodrecord!(recorder, value)
Add value
to the statistics accumulated by recorder
.
Pigeons.record!
— Methodrecord!(recorder, value)
Forwards to OnlineStats' fit!
.
Pigeons.record!
— Methodrecord!(recorder, value)
Given a value
, a pair (a, b)
, and a Dict{K, Vector{V}}
backed recorder
, append b
to the vector corresponding to a
, inserting an empty vector into the dictionary first if needed.
Pigeons.record_default
— MethodSet of recorders with no measurable impact on performance.
Pigeons.record_if_requested!
— Methodrecord_if_requested!(recorders, recorder_key, value)
If the recorders
contains the given recorder_key
, send the value
to the recorder
corresponding to the recorder_key
. Otherwise, do nothing.
When value
is costly or may cause allocation, use @record_if_requested!()
instead.
Pigeons.record_online
— MethodSet of constant memory recorders.
Pigeons.record_swap_stats!
— Methodrecord_swap_stats!(
pair_swapper,
recorders,
chain1,
stat1,
chain2,
stat2
)
Given a pair_swapper
, a recorders
, the provided chain indices, and the sufficient statistics computed by swap_stat()
, record statistics.
To avoid accumulating twice the same statistic with (chain1, chain2) and (chain2, chain2), swap!()
only calls this for the pair with chain1 < chain2.
Pigeons.record_swap_stats!
— Methodrecord_swap_stats!(
swapper,
recorder,
chain1,
stat1,
chain2,
stat2
)
See TestSwapper
.
Pigeons.recorded_continuous_variables
— Methodrecorded_continuous_variables(state)
Pigeons.recorder_values
— Methodrecorder_values(pt, recorder_name)
Returns a generator for the values of a recorder of type OnlineStatsBase.GroupBy
.
Pigeons.recursive_equal
— Methodrecursive_equal(a, b)
Recursively check equality between two objects by comparing their fields. By default calls ==
but for certain types we dispatch a custom method. This is necessary because for some mutable structs (and even immutable ones with mutable fields) ==
actually dispatches ===
. The latter is too strict for the purpose of checking that two checkpoints are equal.
If you are using custom struct and encounter a failed correctness check, you may need to provide a special equality check for this type. In most cases it will be enough to overload recursive_equal
as follows
Pigeons.recursive_equal(a::MyType, b::MyType) = Pigeons._recursive_equal(a,b)
For examples of more specific checks, refer to the code of PigeonsBridgeStanExt
.
Pigeons.reduce_deterministically
— Methodreduce_deterministically(operation, source_data, e)
Perform a binary reduction of the source_data
, using MPI when needed.
Consider the binary tree with leaves given by the global indices specified in e.load
and stored in the different MPI processes' input source_data
vectors. At each node of the tree, a reduction is performed using operation
, i.e. by calling operation(left_child, right_child)
. When, and only when a branch of the tree crosses from one MPI process to another one, MPI communication is used to transmit the intermediate reduction.
At the end, for process 1, reduce_deterministically()
will return the root of the binary tree, and for the other processes, reduce_deterministically()
will return nothing
.
Note that even when the operation
is only approximately associative (typical situation for floating point reductions), the output of this function is invariant to the number of MPI processes involved (hence the terminology 'deterministically'). This contrasts to direct use of MPI collective communications where the leaves are MPI processes and hence will give slightly different outputs given different numbers of MPI processes. In the context of randomized algorithms, these minor differences are then amplified.
In contrast to transmit!()
, we do not assume isbitstype(T) == true
and use serialization when messages are transmitted over MPI.
Pigeons.reduce_recorders!
— Methodreduce_recorders!(pt, replicas)
Perform a reduction across all the replicas' individual recorders, using Base.merge()
on each individual recorder
held. Returns a recorders
with all the information merged.
Will reset the replicas' recorders at the same time using Base.empty!()
.
Since this uses all_reduce_deterministically
, the output is identical, no matter how many MPI processes are used, even when the reduction involves only approximately associative Base.merge()
operations (e.g. most floating point ones).
Pigeons.register_online_type
— Methodregister_online_type(type)
Register an additional OnlineStat
sub-types to be computed when the [online()
] recorder is enabled.
The provided type should have a zero-argument constructor.
Pigeons.rejections
— MethodSimilar to above except that instead of the number of chains, provide the full vector of chain indices. Note that chain_indices
starts at the reference and ends at the chain one before the target.
Pigeons.report!
— Methodreport!(pt, prev_header)
Report summary information on the progress of pigeons()
.
Pigeons.reversibility_rate
— Methodreversibility_rate()
Records the success rate for the AutoMALA
reversibility check.
Pigeons.round_trip
— MethodRestart and round-trip counts.
Pigeons.run_checks
— MethodPerform checks to detect software defects. Unable via field checked_round
in Inputs
Pigeons.run_one_round!
— Methodrun_one_round!(pt)
From a PT
object, run one round of a generalized version of Algorithm 1 in Syed et al., 2021.
Alternates between communicate!()
, which consists of any pairwise communicating moves and [explore!()
], which consists of moves independent to each chain.
Concrete specification of how to communicate and explore are specified by the field of type Shared
contained in the provided PT
.
Pigeons.safelink
— Methodsafelink(target, link)
Work around two issues with symlink():
- naively calling symlink() when there are relative paths leads to broken links
- on windows, one needs admin permission to do symlinks, so print a helpful error message in that case
Pigeons.sample_array
— Methodsample_array(pt)
Copy the target chain(s) samples into an array with axes: iteration x variable x target chain
. For example, with StabilizedPT
there are two target chains. By default, there is only one chain produced.
See extract_sample()
for information how the variables are flattened, and use sample_names()
to obtain string names for the flattened variables.
The combination of this function and sample_names()
is useful for creating MCMCChains which can then be used to obtain summary statistics, diagnostics, create trace plots, and pair plots (via PairPlots).
Pigeons.sample_iid!
— Methodsample_iid!(reference_log_potential, replica, shared)
Perform i.i.d. sampling on the given Replica
during its visit to the referencelogpotential created by create_reference_log_potential()
.
Optional but recommended for e.g. jumping modes in multi-modal problems.
Pigeons.sample_names
— Methodsample_names(state, log_potential, extractor)
A list of string labels for the flattened vectors returned by extract_sample()
.
The key :log_density
is used when the un-normalized log density is included.
Pigeons.sample_segment!
— MethodSample a segment of the trajectory until an apogee is reached.
Pigeons.serialize_immutables
— Methodserialize_immutables(filename)
See Immutable
's.
Pigeons.set_tape_compilation_strategy!
— Methodset_tape_compilation_strategy!(compile)
Set the Pigeons-wide tape compilation strategy for tape-based AD backends. Currently this is only used for ReverseDiff.
Pigeons.setup_blang
— Functionsetup_blang(repo_name)
setup_blang(repo_name, organization)
Download the github repo with the given repo_name
and organization
in ~.pigeons, and compile the blang code.
Pigeons.setup_mpi
— Methodsetup_mpi(settings)
Run this function once before running MPI jobs. This should be done on the head node of a compute cluster. The setting are permanently saved. See MPISettings
.
Pigeons.setup_mpi
— Methodsetup_mpi(; args...)
Look first at the list of clusters that have "presets" available, by typing Pigeons.setup_mpi_
and then tab. These are the most straightforward to use.
If presets are not available, use setup_mpi()
. To see the documentation of the arguments of setup_mpi()
, see MPISettings
(i.e. args...
are passed to the constructor of MPISettings
).
Pull requests to Pigeons/src/submission/presets.jl
are welcome if you would like to add a new "preset" functions of the form Pigeons.setup_mpi_...()
.
Pigeons.setup_mpi_compute_canada
— Methodsetup_mpi_compute_canada()
Compute Canada clusters.
Pigeons.setup_mpi_sockeye
— Methodsetup_mpi_sockeye(my_user_allocation_code)
UBC Sockeye cluster.
Pigeons.single_process_load
— Methodsingle_process_load(n_global_indices)
A load balance with only one process.
Pigeons.sort_includes!
— Methodsort_includes!(main)
Heuristic to automate the process of sorting include()
's.
Topological sorting of the source files under src (excluding main
) is attempted, if successful, print the include string to copy and paste to the main file, otherwise, print the detected loops.
Internally, this function will:
- Construct a graph where the vertices are the .jl files under src, excluding the provided
main
file (i.e. where the module is defined and the includes will sit in). - Each file starting with a capital letter is assumed to contain a struct with the same name as the file after removal of the .jl suffix. Similarly, files starting with
@
are assumed to contain a macro with the similarly obtained name. - Each source file is inspected to see if the above struct and macro strings are detected. This defines edges in the graph. (known limitation: this includes spurious edges when e.g. the string occurs in a comment).
Pigeons.split_slice
— Methodsplit_slice(slice, rng)
From one splittable random object, one can conceptualize an infinite list of splittable random objects. Return a slice from this infinite list.
Pigeons.step!
— Methodstep!(explorer, replica, shared)
Perform a transition on the given Replica
invariant with respect to the distribution of the replica's chain.
The input explorer
and Shared
should only be read, not written to.
See also find_log_potential
.
Pigeons.stepping_stone
— Methodstepping_stone(pt)
Let Z1 denote the normalization constant of the target, and Z0, of the reference, this function approximates log(Z1/Z2) using the stepping stone estimator computed on the parallel tempering output.
Pigeons.stepping_stone_pair
— Methodstepping_stone_pair(pt)
Return a pair, one such that its exponential is unbiased under Assumptions (A1-2) in Syed et al., 2021 for $Z$ and the other, for $1/Z$. Both are consistent in the number of MCMC iterations without these strong assumptions.
Pigeons.swap!
— Methodswap!(pair_swapper, replicas, swap_graph)
For each pair of chains encoded in swap_graph
, use pair_swapper
to decide if the pair will swap or not, and write the changes in-place into replicas
(i.e. exchanging the Replica
's chain
fields for those that swapped.)
Pigeons.swap!
— Methodswap!(pair_swapper, replicas, swap_graph)
Entangled MPI swap!
implementation.
This implementation is designed to support distributed PT with the following guarantees
- The running time is independent of the size of the state space ('swapping annealing parameters rather than states')
- The output is identical no matter how many MPI processes are used. In particular, this means that we can check correctness by comparing to the serial, single-process version.
- Scalability to 1000s of processes communicating over MPI (see details below).
- The same function can be used when a single process is used and MPI is not available.
- Flexibility to extend PT to e.g. networks of targets and general paths.
Running time analysis:
Let $N$ denote the number of chains, $P$, the number of processes, and $K = \text{ceil}(N/P)$, the maximum number of chains held by one process. Assuming the running time is dominated by communication latency and a constant time for the latency of each peer-to-peer communication, the theoretical running time is $O(K)$. In practice, latency will grow as a function of $P$, but empirically, this growth appears to be slow enough that for say $P = N =$ a few 1000s, swapping will not be the computational bottleneck.
Pigeons.swap!
— Methodswap!(pair_swapper, replicas, swap_graph)
Single process, non-allocating swap!
implementation.
Pigeons.swap_acceptance_pr
— MethodAverage MH swap acceptance probabilities for each pairs of interacting chains.
Pigeons.swap_decision
— Methodswap_decision(pair_swapper, chain1, stat1, chain2, stat2)
Given a pair_swapper
, a recorders
, the provided chain indices, and the sufficient statistics computed by swap_stat()
, make a swap decision.
By default, this is done as follows:
- compute the standard swap acceptance probability
min(1, exp(stat1.log_ratio + stat2.log_ratio))
- make sure the two chains share the same uniform by picking the uniform from the chain with the smallest chain index
- swap if the shared uniform is smaller than the swap acceptance probability.
Pigeons.swap_decision
— Methodswap_decision(swapper, chain1, stat1, chain2, stat2)
See TestSwapper
.
Pigeons.swap_stat
— Methodswap_stat(pair_swapper, replica, partner_chain)
By default, two sufficient statistics are computed and stored in the SwapStat
struct:
- The result of calling
log_unnormalized_ratio()
onpair_swapper
- A uniform number to coordinate the swap decision.
This can be extended by dispatching on other pair_swapper
types, with the constraint that the returned sufficient statistics should satisfy isbitstype()
.
Pigeons.swap_stat
— Methodswap_stat(swapper, replica, partner_chain)
See TestSwapper
.
Pigeons.tempering_recorder_builders
— Methodtempering_recorder_builders(tempering)
What information is needed to perform adapt_tempering
? Answer this by specifying an iterator containing recorder_builder
's. Return []
if none are needed.
Pigeons.timing_extrema
— MethodTiming informations.
Pigeons.toy_mvn_target
— Methodtoy_mvn_target(dim)
A toy multi-variate normal (mvn) target distribution used for testing. Uses a specialized path, ScaledPrecisionNormalPath
, such that i.i.d. sampling is possible at all chains (via ToyExplorer
).
Pigeons.toy_stan_target
— FunctionA multivariate normal implemented in Stan for testing/benchmarking.
Pigeons.toy_turing_unid_target
— FunctionA toy Turing model used for testing (unidentifiable 2-dim params for a bernoulli).
Pigeons.traces
— MethodSave the full trace for the target chain in memory. Call copy() on each state on the target chain. Index them by the (chain index, scan index).
Pigeons.transmit!
— Methodtransmit!(
e,
source_data,
to_global_indices,
write_received_data_here
)
Use MPI point-to-point communication to permute the contents of source_data
across MPI processes, writing the permuted data into write_received_data_here
. The permutation is specified by the load balance in the input argument e
as well as the argument to_global_indices
.
More precisely, assume the Vectors source_data
, to_global_indices
, and write_received_data_here
are all of the length specified in my_load(e.load)
.
For each i
, source_data[i]
is sent to MPI process p = find_process(e.load, g)
, where g = to_global_indices[i]
and written into this p
's write_received_data_here[j]
, where j = find_local_index(e.load, g)
See Entangler's comments regarding the requirement that all machines call transmit() the same number of times and at logically related intervals.
Additionally, at each micro-iteration, we assume that {to_global_indices_p : p ranges over the different processes}
forms a partition of {1, ..., e.load.n_global_indices}
If ran in single-process mode, this 'partition property' is checked; if ran in multi-process, opportunistic checks will be made, namely when several entries in to_global_indices
lie in the same process, but systematic checks are not made for performance reasons.
We also assume isbitstype(T) == true
.
Pigeons.transmit
— Methodtransmit(e, source_data, to_global_indices)
The same as transmit!()
but instead of writing the result to an input argument, provide the result as a returned Vector
.
Pigeons.update_reference!
— Methodupdate_reference!(reduced_recorders, variational, state)
Update the variational reference and the annealing path. Returns the new annealing path.
Pigeons.update_state!
— Methodupdate_state!(state, name, index, value)
Update the state's entry at symbol name
and index
with value
.
Pigeons.variable
— Methodvariable(state, name)
The storage within the state
of the variable of the given name, typically an Array
.
Pigeons.variational_deo
— Methodvariational_deo(n_chains_fixed, n_chains_var)
Implements the Deterministic Even Odd (DEO) scheme but with two references (one fixed and one variational) as in Surjanovic et al., 2022.
Pigeons.variational_recorder_builders
— Methodvariational_recorder_builders(variational)
Specify the recorder builders for this variational reference family.
Pigeons.watch
— Methodwatch(result; machine, last, interactive)
Print the queue status as well as the standard out and error streams (merged) for the given machine
.
Note: when using control-c on interactive = true, julia tends to crash as of version 1.8.
Pigeons.write_checkpoint
— Methodwrite_checkpoint(pt)
If pt.inputs.checkpoint == true
, save a checkpoint under [pt.exec_folder]/[unique folder]/round=[x]/checkpoint
.
By default, pt.exec_folder
is results/all/[unique folder]
.
In an MPI context, each MPI process will write its local replicas, while only one of the MPI processes will write the Shared
and reduced recorders
data. Moreover, only one MPI process will write once at the first round the Inputs
data.
In cases where the sampled model contains large immutable data, consider using Immutable
's to save disk space (Immutables will be written only by one MPI process at the first round).
RecipesBase.apply_recipe
— Methodusing Pigeons
using Plots
pt = pigeons(
target = toy_mvn_target(1),
record = [index_process],
n_rounds = 5)
plot(pt.reduced_recorders.index_process)
RecipesBase.apply_recipe
— Methodusing Pigeons
using Plots
pt = pigeons(target = toy_mvn_target(1))
plot(pt.shared.tempering.communication_barriers.localbarrier)
Statistics.mean
— Functionmean(pt)
mean(pt, variable_name)
the online statistics are computed on the result of calling extract_sample()
.
Statistics.var
— Functionvar(pt)
var(pt, variable_name)
Pigeons.@abstract
— Macromy_fct() = @abstract()
Define an abstract function (i.e. which gives an error message if calling it is attempted).
Pigeons.@auto
— MacroBased on ConcreteStruct.jl, but (1) with a more descriptive name and (2) outputs elided type information (ConcreteStruct.jl has this feature but does not seem to work at the moment).
Pigeons.@informal
— Macro@informal name begin ... end
Document an informal interface with provided name
, and functions specified in a begin .. end
block.
@informal
will spit back the contents of the begin .. end
block so this macro can be essentially ignored at first read.
When building documentation, this allows us to use the function informal_doc()
to automatically document the informal interface.
Pigeons.@record_if_requested!
— Macro@record_if_requested!(recorders, recorder_key, value)
Same behaviour as record_if_requested!
but only evaluate value
when the recorder is present.