Obsidian uses Markov Chain Monte Carlo methods to sample from the probability distribution defined by the world model. All code related to MCMC are in a separate namespace stateline
.
Obsidian implements a tempered random-walk Metropolis-Hastings Markov Chain sampler. However, because the likelihood function in an inversion problem is expensive to evaluate (need to simulate sensor forward models), we delegate the task of evaluating MCMC states to the workers (implemented in the shard
tool). This allows Obsidian to evaluate many MCMC states in parallel by submitting state evaluation jobs to a cluster of workers simultaneously, and retrieving the results one by one.
A key concept of the Obsidian MCMC module is an asynchronous policy (async policy for short), which dictates how states can be evaluated asynchronously (out of order). As mentioned in the previous section, to take advantage of the worker cluster, the MCMC sampler must be able to send jobs in batch to the workers, and retrieve them back one by one. So any class implementing the asynchronous policy interface must have the following method signatures:
For an example of an async policy, see GeoAsyncPolicy, which is used in the geophysical inversion. Note that this async policy also performs multiplexing, which splits up the job it receives in submit()
into several smaller sub-tasks, one for each sensor type. It then recombines the results of these sub-tasks together to compute a joint likelihood in retrieve()
.
The main interface for running MCMC simulations is the Sampler class. The overall process of the MCMC simulation is briefly outlined below:
Note that the networking aspects involved in distributing tasks to workers is completely abstracted away by the async policy.
The storage of states in the MCMC are handled in the ChainArray class. A ChainArray holds the samples of all the chains that are used in the MCMC simulation. It gives each chain a unique ID to make it easier to iterate through chains and refer to specific chains. The IDs are given as follows:
The term stack is used to refer to a sequence of chains with an increasing temperature ladder. Stacks are independent from each other, and are basically copies of each other, but exploring different parts of the search space (they do eventually have different temperatures and step sizes due to the adaption steps performed by the MCMC).
The most recent samples in the chain array are stored in memory for fast retrieval. However, as the number of samples get large, the chain array has to flush old samples to disk to make room for newer samples. Obsidian implements fault-tolerant persistence for its MCMC, so the simulation can be interrupted and recovered later (and can be resumed). Note that only the coldest chains are stored to disk.
Other tools in the Obsidian toolset such as pickaxe
read from the database in order to extract MCMC samples.