discopt.debug.context#

The state snapshot handed to the debugger at each checkpoint.

DebugContext is a superset of discopt.callbacks.CallbackContext: it carries the aggregate tree state that is always available, plus the per-node batch arrays that exist only at the batch-level checkpoints. It is built lazily — only when a debugger is actually attached — so a detached solve pays nothing (see discopt.debug.fire()).

Classes#

DebugContext

Read-mostly view of solver state at a checkpoint.

Module Contents#

class discopt.debug.context.DebugContext#

Read-mostly view of solver state at a checkpoint.

Aggregate fields are always populated. Batch fields (batch_* and result_*) are present only at AFTER_SELECT and later within an iteration; they are None at ITER_START and TERMINATED.

checkpoint: discopt.debug.checkpoints.Checkpoint#
iteration: int#
elapsed: float#
node_count: int#
open_nodes: int#
incumbent_obj: float | None#
best_bound: float#
gap: float | None#
batch_lb: numpy.ndarray | None = None#
batch_ub: numpy.ndarray | None = None#
batch_ids: numpy.ndarray | None = None#
result_lbs: numpy.ndarray | None = None#
result_sols: numpy.ndarray | None = None#
result_feas: numpy.ndarray | None = None#
event: str | None = None#
steer: discopt.debug.steer.DebugSteer | None = None#
model: Any = None#
extra: dict[str, Any]#
property n_batch: int#

Number of nodes in the current batch (0 if no batch is live).

metrics() → dict[str, float]#

Scalar metrics addressable by conditional breakpoints and print.

classmethod build(checkpoint: discopt.debug.checkpoints.Checkpoint, *, tree: Any, model: Any = None, iteration: int = 0, elapsed: float = 0.0, batch_lb: Any = None, batch_ub: Any = None, batch_ids: Any = None, result_lbs: Any = None, result_sols: Any = None, result_feas: Any = None, event: str | None = None, validator: Any = None) → DebugContext#

Construct a context by reading aggregate state from the Rust tree.

Only pure reads (tree.stats() / tree.incumbent()) are performed, so building a context never perturbs the search — a no-op debugger is bound-neutral. validator is the solve loop’s candidate-validation closure (see discopt.debug.steer.Validator); the inject steer is available only at checkpoints that wire one.

classmethod from_rust(state: dict) → DebugContext#

Build a context from the pure-Rust MILP hook’s state dict.

The Rust solve_milp fast-path has no PyTreeManager (so no steer handle — inspection and flow control only), but at the after_select checkpoint the hook marshals the batch’s per-node boxes/ids, so print node <i> / print nodes work here too. The Rust hook carries no final status, so extra["error"] is never set and "on-error" sessions do not trigger on this path (documented in Model.solve).