Backends
Backends that write the numeric functions of compiled problems: NumPy, Numba, and JAX.
BaseBackend
Bases: BaseConfig[None, LoweredKernelsSpec]
Base of the backends, which turn the kernels of a problem into the numeric functions of its form.
A backend stores its settings in its constructor, prepare() takes nothing, and run(kernels) takes the
LoweredKernelsSpec of a problem, with its form, the size of its state vector, its reductions, and its draws, and
keeps the LoweredFunctionsSpec of the form in functions_. Subclasses implement the hooks _run, _get_name,
the name a problem records, and _get_support, the times, spaces, laws, noise, and orders the backend writes
functions of.
Attributes:
| Name | Type | Description |
|---|---|---|
functions_ |
LoweredFunctionsSpec
|
The numeric functions of the form of the kernels of the last run. |
JaxBackend
Bases: BaseBackend
Backend that writes discrete maps and ordinary differential equations as pure JAX functions.
The functions return new arrays instead of writing into buffers, so JAX traces, compiles, and differentiates them.
Reductions lower to sums, means, and matrix products, and a reduction weighted by a shaped parameter to the product
with its block of the parameter vector reshaped into a matrix. The forward functions in functions_ take and
return NumPy arrays and compute in double precision. Rule, noise, and jump laws, reductions over neighbourhoods,
and laws given as Python callables have no JAX form.
Attributes:
| Name | Type | Description |
|---|---|---|
functions_ |
LoweredFunctionsSpec
|
The forward functions of the form of the kernels of the last run, on NumPy arrays. |
traced_ |
TracedFunction
|
The pure JAX function |
Examples:
>>> from skcomplex.engine.compile import compile_system
>>> from skcomplex.engine.backends import JaxBackend
>>> from skcomplex.core.system import System
>>> from skcomplex.models.biology.common.populations import PopulationElement
>>> problem = compile_system(System(elements=[PopulationElement('a', n=2.0)]), backend=JaxBackend())
>>> problem.backend
'jax'
NumbaBackend(cache_dir=None, parallel=True)
Bases: BaseBackend
Backend that generates fused Numba kernels and compiled stepper loops, cached on disk.
Kinds of laws that contain a plain Python callable fall back to the NumPy functions, and the problem then has no compiled stepper loops.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cache_dir
|
str | Path | None
|
The directory of the generated kernel sources and Numba's cache, or |
None
|
parallel
|
bool
|
Whether member and pair loops over groups of at least 1000 members run in parallel threads. Kernels that the compiled loops of jump processes and discrete maps call once per event always run serially. |
True
|
Examples:
>>> from skcomplex.core.elements import GroupElement
>>> from skcomplex.engine.compile import compile_system
>>> from skcomplex.core.system import System
>>> from skcomplex.models.biology.common.populations import ExponentialGrowthInteraction, PopulationElement
>>> system = System(
... elements=[GroupElement('herds', element=PopulationElement, size=2, values={'n': [1.0, 2.0]})],
... interactions=[ExponentialGrowthInteraction('growth', target='herds', r=3.0)],
... )
>>> problem = compile_system(system, backend=NumbaBackend())
>>> problem.drift(0.0, problem.initial_state, problem.initial_parameters).tolist()
[3.0, 6.0]
Source code in src/skcomplex/engine/backends/_numba.py
167 168 169 | |
NumpyBackend
Bases: BaseBackend
Reference backend that evaluates every kernel with NumPy array operations.
Examples:
>>> from skcomplex.engine.compile import compile_system
>>> from skcomplex.engine.backends import NumpyBackend
>>> from skcomplex.core.system import System
>>> from skcomplex.models.biology.common.populations import PopulationElement
>>> compile_system(System(elements=[PopulationElement('a')]), backend=NumpyBackend()).backend
'numpy'