solprop.backends.registry#
Selecting a backend by name, and saying why one is not usable.
docs/dev/backends.md section 1: selection is by name, availability is detected with
importlib.util.find_spec() and never cached. The
errors are two-tier, because the two failures need different answers from the reader: a
name this package has never heard of is a ValueError listing what is usable,
and a known name whose dependencies are missing is an ImportError saying what
to install.
Each backend is one row of BACKENDS, a BackendEntry naming by import
path everything selection reads of it – its constructor, its lockstep runner and its
policy hooks – so nothing here branches on a backend’s name to construct one, and an
optional backend in another distribution registers with one row
(docs/dev/backends.md section 1).
The native backend is a second distribution, solprop-native, built from native/
in this repository and a required dependency; probing availability does not import it.
Automatic selection is that backend, with no fallback (SEP 43). It refuses when the
package is absent or this processor is below the installed build’s CPU baseline, using
the package’s own check (solprop_native._cpu), loaded by path and read from the
same code that refuses the import. Import, compatibility and construction errors remain
visible, and they never trigger different arithmetic.
Module Attributes
The backends this package knows, by name: one row each. |
|
What |
|
What to say about a backend that no longer exists, by the name it had. |
|
The backends that form the far-field statistics of SEP 23. |
|
Where a run must execute: |
Functions
|
Return the names of the backends that can run a precision here and now. |
|
Resolve automatic selection to an installed backend's registry name. |
|
Construct the named backend for a validated problem and its run's request. |
|
Select batch arithmetic without substituting a different backend. |
|
Return why a backend cannot form some of the statistics named, or |
Classes
|
What selection needs of a backend, each object named by its import path. |
- solprop.backends.registry.BACKENDS: Mapping[str, BackendEntry] = {'native': BackendEntry(requires=('solprop_native',), extras=(), factory='solprop_native:NativeBackend', batch=None, install='solprop, or build solprop-native from native/ in the solprop repository', distribution='solprop-native', first_use='solprop.calibration.first_use:ensure', device='solprop_native:build_info', far_field='solprop_native:NativeBackend.far_field_statistics'), 'numpy_ref': BackendEntry(requires=(), extras=(), factory='solprop.backends.numpy_ref:construct', batch='solprop.backends.numpy_ref.batch:lockstep_runner', install=None, distribution=None, first_use=None, device=None, far_field=None)}#
The backends this package knows, by name: one row each.
- class solprop.backends.registry.BackendEntry(requires, extras, factory, batch=None, install=None, distribution=None, first_use=None, device=None, far_field=None)[source]#
Bases:
objectWhat selection needs of a backend, each object named by its import path.
A path is
"module:attribute", the attribute dotted for one inside a class. It is imported only when selection needs it, afterrequireswas found, so listing a backend imports nothing.- Attributes:
- requirestuple of str
Importable module names that must be present. Empty for a backend that needs nothing beyond the package’s own dependencies.
- extrastuple of str
The optional-dependency groups that supply
requires, for the error message.- factorystr
The backend’s constructor, called as
factory(problem, request, *, grid, modes, profiles, options), and withtdse_bindingtoo for a TDSE run, which only the reference is given (select()).- batchstr or None, optional
The reference group’s lockstep runner over loaded members,
batch(owners)(select_batch());Nonefor a backend whose prepared group runs its members itself, as the native group session does (SEP 47 section 6.7).- installstr or None, optional
What to install when
requiresis missing;Nonenamesextras.- distributionstr or None, optional
The distribution that ships the backend, named by the messages of the policies below;
Nonenames the package or the backend instead.- first_usestr or None, optional
Called with no arguments before each construction: the native backend’s first-use calibration (SEP 46);
Nonefor nothing.- devicestr or None, optional
The build’s description,
device(), whosedevice_backend("none"on a CPU build) anddevice_countsay where it runs (REQUIRE_DEVICE_SETTING); the module holding it carries the version.Nonefor a backend that never runs on a device.- far_fieldstr or None, optional
The far-field statistics (SEP 23) the installed backend declares it forms; another is refused by name before construction (
statistics_refusal()).Nonefor a backend that forms every one, or declares nothing to check.
- solprop.backends.registry.FAR_FIELD_BACKENDS: tuple[str, ...] = ('numpy_ref', 'native')#
The backends that form the far-field statistics of SEP 23.
numpy_refalways does; the native backend declares what it forms by its class’sfar_field_statisticsattribute (its row’sfar_field). A statistic it does not declare is refused by name on this side of the seam (statistics_refusal()), before it is built.
- solprop.backends.registry.REMOVED_BACKENDS: Mapping[str, str] = {'mlx': "the experimental mlx backend was retired in SEP 47: use backend='native', the solprop-native package, or, for precision='single', backend='numpy_ref', the reference. Output that records mlx still opens", 'numba_cpu': "the numba_cpu backend was removed in SEP 43: use backend='native', the solprop-native package, or backend='numpy_ref', the reference, which is unthreaded and far slower. Output and snapshots that record numba_cpu still load"}#
What to say about a backend that no longer exists, by the name it had.
- solprop.backends.registry.REQUIRE_DEVICE_SETTING: Final = 'SOLPROP_REQUIRE_DEVICE'#
Where a run must execute:
cuda,hiporany; unset for no requirement.
- solprop.backends.registry.available(precision='double')[source]#
Return the names of the backends that can run a precision here and now.
Detection is by
importlib.util.find_spec(), so nothing is imported and nothing is cached: a backend whose optional dependency is installed while the process runs becomes available without a restart, and initializing a native runtime is never a side effect of asking.- Parameters:
- precision{‘double’, ‘single’}, optional
The arithmetic asked for (SEP 33).
"double", the default, lists every backend;"single"lists those that admit single precision (solprop.translate.precision.SINGLE_PRECISION_BACKENDS).
- Returns:
- tuple of str
The usable names, in the table’s order.
Examples
>>> from solprop.backends.registry import available >>> "numpy_ref" in available() True
- solprop.backends.registry.resolve_name(name='auto')[source]#
Resolve automatic selection to an installed backend’s registry name.
- Parameters:
- namestr, optional
"auto"is"native", and has no fallback: it refuses ifsolprop_nativecan’t be found or this processor doesn’t meet the installed build’s CPU baseline. Other names pass through unchanged, but for a removed backend (REMOVED_BACKENDS).
- Returns:
- str
Concrete selection to store in simulation settings. This uncached probe does not import a backend or initialize a native runtime.
select()validates the name and constructs the backend; failures there never cause a fallback.
- Raises:
- BackendError
If
nameis a removed backend, or"auto"has nothing to select; the message says what to do.
Examples
>>> resolve_name("numpy_ref") 'numpy_ref'
- solprop.backends.registry.select(name, problem, request, *, grid=None, modes=None, profiles=None, tdse_binding=None, options=None)[source]#
Construct the named backend for a validated problem and its run’s request.
The backend receives the request where it is built (SEP 47 section 5.2): it checks the pair (
solprop.translate.problem.validate_run()) and refuses an unsupported combination by name before it allocates, and it lowers the method, the error control, the itinerary, the planes and the statistics once. A session is then started on it with that request, adapted to one run (for_run()).- Parameters:
- namestr
The backend’s registry name, for example
"numpy_ref", or"auto"for the native backend, with no fallback (resolve_name()).- problemsolprop.translate.problem.PropagationProblem
The problem to step.
- requestsolprop.translate.run_request.RunRequest
The run’s policies. The backend validates it with the problem again.
- gridsolprop.grid.TimeGrid, optional
The grid the state lives on. Statistics need it and the kernel contract does not carry it, so it is passed alongside rather than inside the problem.
- modescollections.abc.Sequence, optional
The propagated modes, in state order, for the statistics that need them.
- profilescollections.abc.Mapping, optional
The z-profiles keyed by statistic name, for the profile statistics.
- tdse_bindingsolprop.translate.tdse.TDSEBinding or None, optional
Driver-owned host response binding for a TDSE problem on NumPy.
- optionssolprop.backends.session.ExecutionOptions or None, optional
The run’s execution options, among them an explicit node budget, from which the backend plans its node chunk (SEP 47 section 6.5);
Nonefor the automatic choice.
- Returns:
- Backend
The constructed backend.
- Raises:
- ValueError
If
nameis not a backend this package knows; the message lists what is usable.- BackendError
If
nameis a backend that has been removed, or one that does not form a statistic the problem asks for; the message says what to use instead.- ImportError
If
nameis known but its dependencies are missing; the message says what to install.
Examples
>>> from solprop.backends.registry import BACKENDS >>> sorted(BACKENDS) ['native', 'numpy_ref']
- solprop.backends.registry.select_batch(owners)[source]#
Select batch arithmetic without substituting a different backend.
This is the reference group’s lockstep runner, read from the registry row’s
batch. A backend whose row names none, asnative’s, runs its groups through its own prepared group instead (solprop.backends.sessions.start_group(); SEP 47 section 6.7), and is refused here by name.- Parameters:
- ownerssequence of solprop.backends.protocol.Backend
Compatible, loaded member owners.
- Returns:
- BatchBackend
Common fixed march using the selected backend’s arithmetic.
- Raises:
- BackendError
If the members are not of one backend, or their backend has no lockstep runner (its groups start through
start_group).
- solprop.backends.registry.statistics_refusal(name, names)[source]#
Return why a backend cannot form some of the statistics named, or
None.Asking about a backend whose row declares its far-field statistics (the native backend’s) imports the installed plugin, as selecting it would, to read them.
- Parameters:
- namestr
The resolved backend name.
- namescollections.abc.Sequence of str
The statistics asked for.
- Returns:
- str or None
The refusal, naming the backends that do form them, or
Nonewhen the backend forms every one (or is not installed, which selecting it reports).
Examples
>>> from solprop.backends.registry import statistics_refusal >>> statistics_refusal("numpy_ref", ["energy", "beam_spectrum"]) is None True