caching
get_solve_batched_cache_path(symbolic_problem: SymbolicProblem, settings: Any, algorithm: Any, solver: Any, discretizer: Any, B: int, param_axes: Dict[str, Optional[int]], cache_dir: Optional[Path] = None) -> Path
¶
Cache path for the exported :meth:Problem.solve_batched artifact.
The vmapped SCP loop closes over far more than the symbolic problem does, so
caching it on :func:get_solver_cache_paths' key would silently deserialize
a stale artifact whenever any of the extra closed-over state changes — a
wrong-answer bug, not a cache miss. This assembler extends
:func:hash_symbolic_problem (dynamics, constraints, boundary-condition
types, parameter shapes) with everything additionally baked into the loop:
- the convex backend class and its
solver_args(viasolver._hash_into), - the algorithm + autotuner + initial penalty weights (via
algorithm._hash_into), - the discretizer scheme (via
discretizer._hash_into), - the state/control scaling matrices
inv_S_x/inv_S_u(settings- derived, not covered by any subsystem hash), - the fixed batch size
B(the artifact is exported at oneB), - the per-parameter batch axes
param_axes— the shared/batched split is baked into thejax.vmapprogram, so an artifact traced for one split must never be loaded for another, and - the JAX version (exported artifacts are not guaranteed to survive an incompatible jax bump — the worst failure mode is deserializing one).
The convergence thresholds and iteration cap are deliberately absent:
they ride the AlgorithmState pytree as runtime inputs, so one artifact
serves every tolerance and max_iters setting.
Each runtime object contributes through its own _hash_into — the same
two-tier split the symbolic layer uses — so a new field that changes the
artifact is hashed next to where it lives, never reached into from here.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
symbolic_problem
|
SymbolicProblem
|
The preprocessed :class: |
required |
settings
|
Any
|
Problem :class: |
required |
algorithm
|
Any
|
The SCP algorithm (and its autotuner / weights). |
required |
solver
|
Any
|
The convex subproblem backend. |
required |
discretizer
|
Any
|
The dynamics discretizer. |
required |
B
|
int
|
Fixed batch size the artifact is exported at. |
required |
param_axes
|
Dict[str, Optional[int]]
|
Per-parameter |
required |
cache_dir
|
Optional[Path]
|
Override for the cache directory. |
None
|
Returns:
| Type | Description |
|---|---|
Path
|
Path to the |
Source code in openscvx/utils/caching.py
get_solver_cache_paths(symbolic_problem: SymbolicProblem, dt: float, total_time: float, cache_dir: Optional[Path] = None, byof: Optional[ByofSpec] = None) -> Tuple[Path, Path]
¶
Generate cache file paths using symbolic AST hashing.
This function computes a hash based on the symbolic structure of the problem, which is more stable than hashing lowered JAX code. Two problems with the same mathematical structure will produce the same hash, regardless of variable names.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
symbolic_problem
|
SymbolicProblem
|
The preprocessed SymbolicProblem |
required |
dt
|
float
|
Time step for propagation |
required |
total_time
|
float
|
Total simulation time |
required |
cache_dir
|
Optional[Path]
|
Directory to store cached solvers. If None, uses the default
cache directory (see :func: |
None
|
byof
|
Optional[ByofSpec]
|
Optional ByofSpec containing raw JAX functions. If provided, function bytecode is included in the hash. |
None
|
Returns:
| Type | Description |
|---|---|
Tuple[Path, Path]
|
Tuple of (discretization_solver_path, propagation_solver_path) |
Source code in openscvx/utils/caching.py
hash_value_into(hasher: hashlib._Hash, value: Any) -> None
¶
Fold a scalar / array / None into hasher deterministically.
Shared by the _hash_into methods of the runtime objects the
solve_batched artifact closes over — the convex backend, the
algorithm/autotuner, the discretizer — and by
:func:get_solve_batched_cache_path for the scaling matrices. Mirrors the
symbolic _hash_into protocol's byte-level updates so the same value
always contributes the same bytes (arrays by shape + dtype + contents,
everything else by repr).
Source code in openscvx/utils/caching.py
load_or_compile_discretization_solver(discretization_solver: callable, cache_file: Path, params: Dict[str, Any], n_discretization_nodes: int, n_states: int, n_controls: int, save_compiled: bool = False, name: str = 'continuous', debug: bool = False) -> callable
¶
Load discretization solver from cache or compile and cache it.
The no-disk path (save_compiled=False, the default) returns a plain
jax.jit callable, which has a vmap batching rule and so composes
with jax.vmap(problem.solve) in the JAX-pure solve work. The disk-cached
path (save_compiled=True) returns a jax.export wrapper that
serializes to disk but, because call_exported has no vmap rule,
cannot be combined with jax.vmap(problem.solve).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discretization_solver
|
callable
|
The solver function to compile |
required |
cache_file
|
Path
|
Path to cache file |
required |
params
|
Dict[str, Any]
|
Parameters dictionary |
required |
n_discretization_nodes
|
int
|
Number of discretization nodes |
required |
n_states
|
int
|
Number of state variables |
required |
n_controls
|
int
|
Number of control variables |
required |
save_compiled
|
bool
|
Whether to save/load compiled solvers to/from disk
( |
False
|
debug
|
bool
|
Whether in debug mode (skip compilation) |
False
|
Returns:
| Type | Description |
|---|---|
callable
|
Compiled discretization solver — a |
callable
|
|
Source code in openscvx/utils/caching.py
load_or_compile_propagation_solver(propagation_solver: callable, cache_file: Path, params: Dict[str, Any], n_states_prop: int, n_controls: int, max_tau_len: int, save_compiled: bool = False, debug: bool = False) -> callable
¶
Load propagation solver from cache or compile and cache it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
propagation_solver
|
callable
|
The solver function to compile |
required |
cache_file
|
Path
|
Path to cache file |
required |
params
|
Dict[str, Any]
|
Parameters dictionary |
required |
n_states_prop
|
int
|
Number of propagation state variables |
required |
n_controls
|
int
|
Number of control variables |
required |
max_tau_len
|
int
|
Maximum tau length for propagation |
required |
save_compiled
|
bool
|
Whether to save/load compiled solvers |
False
|
Returns:
| Type | Description |
|---|---|
callable
|
Compiled propagation solver |
Source code in openscvx/utils/caching.py
load_or_export_solve_batched(batched_fn: callable, cache_file: Path, sample_state: Any, sample_params: Dict[str, Any]) -> Any
¶
Load the exported batched solve from disk, or export and cache it.
Mirrors :func:load_or_compile_discretization_solver but at whole-loop
granularity: the single artifact is the entire vmapped SCP loop exported
at a fixed batch size, not a per-solver piece. On a cache hit the artifact
is deserialized with no XLA compile; on a miss the loop is exported against
the sample batched :class:~openscvx.algorithms.state.AlgorithmState and
parameters, serialized, and returned.
Unlike the per-solver solvers — whose call_exported has no vmap rule
and so cannot be folded into an outer vmap — this artifact already has
the batch baked in, so it is the one exportable form of a batched solve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
batched_fn
|
callable
|
The |
required |
cache_file
|
Path
|
Path from :func: |
required |
sample_state
|
Any
|
A batched |
required |
sample_params
|
Dict[str, Any]
|
Problem parameters dict; supplies shapes/dtypes. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A |
Source code in openscvx/utils/caching.py
prime_propagation_solver(propagation_solver: callable, params: Dict[str, Any], settings: Any) -> None
¶
Prime the propagation solver with a test call to ensure it works.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
propagation_solver
|
callable
|
Compiled propagation solver |
required |
params
|
Dict[str, Any]
|
Parameters dictionary |
required |
settings
|
Any
|
Settings configuration object |
required |