Multiprocessing#
Use aspire.Aspire.enable_pool() to run your likelihood (and optionally
prior) in parallel across a multiprocessing.Pool. The helper swaps the
map_fn argument expected by your log-likelihood / log-prior for
pool.map while the context is active, then restores the original methods.
Prepare a map-aware likelihood#
Your likelihood must accept map_fn. A minimal
pattern:
import numpy as np
def _global_log_likelihood(x):
# Expensive likelihood computation for a single sample `x`
return -np.sum(x**2) # Example likelihood
def log_likelihood(samples, map_fn=map):
logl = -np.inf * np.ones(len(samples.x))
if samples.log_prior is None:
raise RuntimeError("log-prior has not been evaluated!")
mask = np.isfinite(samples.log_prior, dtype=bool)
x = np.asarray(samples.x[mask, :], dtype=float)
logl[mask] = np.fromiter(
map_fn(_global_log_likelihood, x),
dtype=float,
)
return logl
Swap in a multiprocessing pool#
Wrap your sampling call inside enable_pool to parallelize the map step:
import multiprocessing as mp
from aspire import Aspire
aspire = Aspire(
log_likelihood=log_likelihood,
log_prior=log_prior, # must also accept map_fn if parallelize_prior=True
dims=4,
parameters=["a", "b", "c", "d"],
)
with mp.Pool() as pool, aspire.enable_pool(pool):
samples, history = aspire.sample_posterior(
sampler="smc",
n_samples=1_000,
return_history=True,
)
Notes#
By default only the likelihood is parallelized; set
aspire.enable_pool(pool, parallelize_prior=True)if your prior also acceptsmap_fn.enable_poolcloses the pool on exit unless you passclose_pool=False.The context manager itself is implemented by
aspire.utils.PoolHandler; if you need finer control (for example, reusing the same pool across multipleAspireinstances) you can instantiate it directly.