Setting the Backend#
GWPopulation provides a unified interface to a number of numpy/scipy like APIs.
The backend can be set using gwpopulation.set_backend(backend), where
backend is one of numpy, cupy, jax.
Downstream packages can automatically track the active backend using entry_points.
With this set up, packages can use xp and scs in specified modules.
Additionally, users can provide a full arbitrary scipy object to be used if anything beyond
scipy.special is needed.
An example of how to set numpy, scipy.special, and the toeplitz function
from scipy.linalg via the setup.cfg file is shown below.
Specification using pyproject.toml and setup.py follows slightly
different syntax documentation for which can be found online.
[options.entry_points]
gwpopulation.xp =
mypackage_foo = mypackage.foo
gwpopulation.scs =
mypackage_foo = mypackage.foo
mypackage_bar = mypackage.bar
gwpopulation.other =
mypackage_baz_toeplitz = mypackage.baz:scipy.linalg.toeplitz
Note
Each module that wants to use the GWPopulation backend must be specified independently
for the automatic propagation to work.
If there is a backend that you would like to use that is not currently supported, please open an issue.
Precision#
With jax, 64-bit floats are enabled the first time the backend is set.
For single precision, which can be several times faster on GPUs, especially
those with limited double-precision throughput, use
gwpopulation.set_backend("jax", enable_x64=False).
Arrays keep the precision they were created with, so set it before creating
any arrays.
Densities below about 1e-38 underflow to zero in single precision,
so use it with models that provide a log density (see
Population models). The likelihood and selection functions
form their Monte Carlo sums in log space, and the sampling priors can be given
as ln_prior. A model without a log density still works, but its log
density is -inf wherever the density underflows.