Skip to content

passage-eval API reference

Auto-generated documentation for every public symbol exported by the passage-eval sub-package. The narrative usage guide lives at the passage-eval package page; the formal protocol sits at Evaluation protocol; the confirmatory paired analysis API is described at Paired statistics. This page is the canonical docstring view.


Ordinary-input requests — passage_eval.protocol.contracts

Existing algorithms implement plan(PlanRequest) -> PlanResult. The request contains candidate-visible terrain, endpoints, graph and shared budget; reference labels stay evaluator-owned. See Evaluate your planner for runnable specifications.

GraphSpec(connectivity=8, diagonal_policy='destination_only', pixel_size_m=30.0, obstacle_policy='blocked', coordinate_order='row_col', cost_model='elevation', cost_weight=62.4, rtol=1e-07, atol=1e-06) dataclass

BudgetSpec(wall_time_ms=None, max_expansions=None, max_queue_operations=None, max_live_states=None) dataclass

Cooperative limits, checked again at safe completion.

A Python call cannot be forcibly stopped. The runner retains ownership until it returns, records late/drain time and never admits a late result as success. Counters must be reported when a corresponding work budget is configured.

PlanRequest(sample_id, elevation, obstacles, start, goal, cost_model, cost_weight, graph=None, budget=BudgetSpec(), metadata=dict(), input_tensor=None, deadline_monotonic=None) dataclass

Functions

remaining_wall_ms(*, clock=time.perf_counter)

One admission deadline shared by prediction, repair and fallback.

The runner sets the absolute deadline before copying ordinary inputs. Standalone requests without a runner deadline have no absolute limit; their caller must initialize one before launching a timed procedure.

PlanResult(path, status='ok', stage='primary', work=dict(), stage_work=dict(), precision='unspecified', diagnostics=dict(), stage_spans=dict(), resource_peaks=dict()) dataclass

Candidate terminal output; work totals include all primary/repair/fallback.

stage_work provides subtotals; the runner charges at least their sum, while resource peaks use the maximum. precision must describe actual execution. Unreported precision remains explicitly unspecified. path must own a materialized numeric array or coordinate sequence. The runner synchronizes before snapshotting its bytes; lazy iterators are not admitted because consuming them can introduce work after that boundary.


Complete requests and offline scores

run_requests(planner, requests, *, repeats=1, output_dir=None, manifest=None, clock=time.perf_counter, synchronize=None, quality_repeat_index=0, series='warm')

score_run_artifact(artifact, scenes, *, reference_store=None, require_qualified_reference=True, geographic_blocks=None)

Score every recorded repeat, preserving failures and service deadlines.

Exact references come from an external qualified store (or evaluator-owned manifest.reference_qualification), never from a candidate request. The explicit diagnostic opt-out uses stored labels with a visible unqualified policy; stored cost alone does not establish optimality.

With qualified references, a legal recorded route (any status) whose cost is below c* beyond the graph tolerance raises NegativeRegretHalt: scoring stops for a diagnosis of the reference.

geographic_blocks is the roster_block_table of the roster the run records. When given, it is the only source of cluster_id (provenance sealed_roster_geographic_block for a passage-roster-v2 table that binds the installed block rule, unsealed_roster_geographic_block for a v1 table) and metrics['geographic_blocks'] records its digest; a table with an unplaced task leaves every block unknown, and a table of another roster, or a run that records no roster, is refused. Without it, blocks come from the declared request metadata as before.

compare_artifacts(paths, *, primary_repeat_index=None, bootstrap_resamples=2000, bootstrap_seed=0, confidence=0.95, odd_spec=None, require_identical_limits=False, geographic_blocks=None)

Compare qualified scored runs with exactly identical frozen task identities.

Input paths may be run directories or files inside those directories. Budget, checkpoint and procedure identities may differ; dataset, reference, ordinary input, endpoints, objective, graph and task variant must match by task ID. Quality uses one explicit repeat; latency retains all repeats and failures. Runs with different timing profiles (latency fields) are never compared.

require_identical_limits (opt-in, off by default) also requires every task's budget, the timing boundary and the recorded supervision limits (grace, hard timeout, start-up timeout, restart cap) to be identical, as a comparison on matched budgets needs. The result always reports which of them differ under procedure_limits.

Blocks come, in this order, from geographic_blocks (the roster_block_table of the roster that every compared run records; a table of another roster, or a run without a recorded roster, is refused), from the roster blocks that the roster scorer stored in every score, or from the declared request metadata. Blocks are labelled sealed only for a passage-roster-v2 table that binds the installed block rule.

paired_cluster_bootstrap(a, b, blocks, *, statistic='median', resamples=2000, seed=0, confidence=0.95)

Estimate a contrast and percentile interval over paired whole blocks.

Each draw samples the observed number of blocks with replacement, then concatenates every row in each drawn block. Thus varying cluster sizes retain the task-weighted statistic. One block cannot estimate geographic uncertainty.


Timing profiles, latency censoring and batch bounds

The censoring rule and the re-warm profile are proposals, not sealed rules. The developer guide docs/benchmark/supervised-execution.md in the source checkout (sections 5.G to 5.I, 6.I and 6.J) explains them, including the separate report of validation and recost time and the request limits that strict comparison requires; the evaluation protocol states the proposed censoring rule.

timing

Versioned supervised timing profiles; artifacts written without a profile keep their legacy meaning.

A profile fixes, together, the artifact schema, the timing boundary written in every record, the record field that is compared with the wall budget and used as the latency, and what happens to the warm-up when a worker is restarted inside a measured pass.

supervised_total_v3 (legacy, the default) total_wall_ms = service_wall_ms + validation_recost_ms is compared with the budget and scored, so the supervisor's validation and physical recost count against the candidate (boundary passage-timing-boundary/v3-supervised-ipc-fresh-pass). It stays the default so that existing runs and receipts keep their meaning. The manuscript's timing rule keeps validation and recosting separate, which this profile does not. supervised_service_v1 service_wall_ms is compared and scored. Validation and recost are recorded in validation_recost_ms and kept in total_wall_ms, outside the boundary (passage-timing-boundary/v4-supervised-ipc-service). supervised_service_rewarm_v1 As supervised_service_v1; in addition, a worker restarted inside a warm pass is warmed up again, outside the boundary, before the next measured request, and every record states its warm-up state (passage-timing-boundary/v5-supervised-ipc-service-rewarm). The re-warm policy is a proposal for the protocol, not a sealed rule.

manifest_warmup(manifest)

The warm-up that a run manifest declares, and records as performed, before its timed series.

The series name alone says nothing about a warm-up: both runners call their measured series warm even when no warm-up ran (measure_latency false or latency_warmup zero). This reads the evidence instead.

  • Supervised runs: supervision.timing_policy declares latency_warmup untimed requests per warm pass on inputs disjoint from the roster; each entry of supervision.passes records the warm-up summary of its pass. The warm-up is performed when every pass of the series ran at least one warm-up request.
  • In-process cli runs: the bench_spec declares latency_warmup recorded passes over the roster when measure_latency is true; the CLI runner runs them before its warm series, and the warm artifact does not list them, so a declared warm-up is taken as performed.
  • Any other manifest declares no warm-up.

censored_latency_quantiles(latency_ms, *, status, sample_id, censored=None, series='warm', quantiles=DEFAULT_QUANTILES, min_warm_requests=MIN_WARM_REQUESTS, warmup_complete=None, warmup=None)

Quantiles of every request of one series under the proposed censoring rule (see the module docstring).

censored defaults to the statuses' timeouts; pass :func:latency_censoring with the records' latency_charged_not_measured flags to censor charged latencies as well. warmup_complete takes the re-warm profile's warmup_complete_before_request values, when the records carry them; a None state (no warm-up applied) counts as a request without a complete warm-up. warmup takes the run's warm-up evidence (:func:passage_eval.execution.timing.manifest_warmup); without it the warm-request flag is None.

validation_recost_summary(values, *, inside_latency, quantiles=DEFAULT_QUANTILES)

The supervisor's validation and recost time, reported separately from the scored latency.

The manuscript keeps validation and physical recosting outside the request latency and reports them separately. inside_latency states whether the run's timing profile nevertheless counts this time inside the scored latency (the legacy profile and the in-process runner do). Quantiles are order statistics (inverted_cdf) over the recorded values; a request killed before a reply records zero.

check_batch_plan(plan, limit_ms)

Refuse a batch whose worst-case wall time exceeds limit_ms (a lease or batch timeout).


Top-level package

passage_eval

passage-eval: canonical evaluation contract for the PASSAGE benchmark.

The public API follows the evaluation protocol of the PASSAGE paper:

Primary metrics:
    cost_regret, cost_regret_summary,
    path_assd, path_hausdorff_p95,
    success_rate, obstacle_violation_rate,
    compute_primary_metrics, paired_bootstrap_ci

Statistical discipline:
    DEFAULT_SEEDS, PRIMARY_METRICS, MetricFamily,
    apply_censored_penalty,
    paired_bootstrap_delta, multiseed_paired_bootstrap,
    holm_bonferroni, decide_pairwise,
    BootstrapDelta, HolmBonferroniResult, PairwiseDecision

Approach-agnostic planner interface:
    Planner, PlannerOutput, Scene, score_planner, evaluate_planner

Trustworthiness axes:
    TrustworthinessAxis,
    stability_cv, geographic_generalisation,
    odd_boundary_delta, oracle_relative_efficiency

Per-sample prediction loaders (notebook / reviewer entry-point):
    PerSampleArrays, load_per_sample_npz,
    primary_metrics_from_arrays

Reference classical planners (illustrative, NOT headline):
    AStarPlanner, GreedyToGoalPlanner, RandomPolicyPlanner

Decoder-readiness diagnostics:
    mask_endpoints_in_same_component, boundary_f_score,
    descent_direction_agreement, bellman_residual_reachable,
    local_ordinal_concordance, field_ssi_mae

Inference / deployment footprint:
    benchmark_forward, benchmark_decoder, benchmark_end_to_end,
    astar_expansions_ratio, decoder_recovery_rate

Reproducibility sidecar:
    ReproducibilitySidecar, compute_calibration_decisions_hash

Primary metrics — passage_eval.metrics

The paper's six headline decoded-path metrics, tested together under the Holm–Bonferroni correction.

regret

Cost-regret family.

Per-sample cost regret is

regret_i = (cost_pred_i - cost_oracle_i) / cost_oracle_i

under the same cost model and ODD sample. Headline statistics are the median and the 90-th percentile of the per-sample distribution; the geometric mean and the 95-th percentile are kept as diagnostics.

The mean of cost_pred / cost_oracle is dominated by a long right tail (under the canonical PASSAGE cost models a single obstacle violation yields a 1e6 penalty, which ruins the mean). The robust statistics here are the headline numbers for the paper.

Functions

cost_regret(predicted_costs, oracle_costs, *, eps=1e-12)

Per-sample cost regret. Returns NaN where the oracle cost is non-positive.

Parameters

predicted_costs : array_like, shape (N,) Cost of the decoded predicted path under the cost model. Use np.nan for samples where the decoder failed to produce a path. oracle_costs : array_like, shape (N,) Cost of the exact A* oracle path under the same cost model. eps : float Numerical floor for the denominator.

cost_regret_summary(regret)

Return median / p90 / p95 / mean / geomean of a regret distribution.

The geometric mean is computed on 1 + regret_i and reported as exp(mean(log(1 + r))) - 1; clipped at -1 + 1e-12 to keep the log finite when an unusually-decoded path is sub-zero in regret (which can happen at numerically degenerate corners of the ODD).

geometric

Geometric-fidelity family: ASSD and percentile Hausdorff.

Headline

path_assd : average symmetric surface distance, normalised by the oracle waypoint count, averaged over the batch. path_hausdorff_p95 : 95-th-percentile symmetric Hausdorff, in pixels, without length normalisation.

Diagnostic

path_iou_diagnostic : raw mask-overlap of the rasterised decoded path against the rasterised oracle path. Kept as a diagnostic; never headline.

Per-sample ASSD is normalised by the oracle waypoint count so the metric is commensurate across the seven PASSAGE resolutions (64x64 to 4096x4096).

Functions

path_assd(predicted_paths, oracle_paths)

Per-sample normalised ASSD; nan for empty paths.

Returned array has shape (N,) and units of pixels per unit oracle path length. Aggregate with np.nanmean / np.nanmedian over a batch.

path_hausdorff_p95(predicted_paths, oracle_paths, *, percentile=95.0)

Per-sample symmetric percentile-Hausdorff in pixels.

path_iou_diagnostic(predicted_paths, oracle_paths, grid_shape)

Per-sample raw path-mask IoU on a fixed grid.

Diagnostic only — drift between path_iou and the cost-regret family is what this metric is reported for, not as a promotion signal.

reliability

Reliability and safety guardrails.

Functions

path_status(path, *, start=None, goal=None, obstacles=None)

Return connection, obstacle violation and traversal count for one path.

Invalid coordinates are never rounded or clipped into a valid grid cell. An obstacle crossing is reported separately from start-to-goal connection.

success_rate(predicted_paths, *, starts=None, goals=None)

Fraction of samples whose decoded path connects start to goal.

A path is "successful" iff: (i) it has at least two cells, (ii) consecutive cells are 8-connected, and (iii) when starts and goals are provided, the first / last cells match the prescribed endpoints.

Returns NaN for an empty batch.

obstacle_violation_rate(predicted_paths, obstacles)

Fraction of samples whose decoded path crosses any obstacle pixel.

Each obstacles[i] is an (H, W) boolean array (1 = forbidden). Returns NaN for an empty batch.

obstacle_cells_traversed_per_path(predicted_paths, obstacles)

Mean obstacle-cell traversal count, conditioned on a violation.

Distinguishes 'clipped a corner' (1) from 'drove through the building' (50). Returns NaN if the batch contains no violation.

summary

Aggregation: primary-metric bundle and paired-bootstrap CIs.

Functions

per_sample_metrics(*, predicted_paths, oracle_paths, predicted_costs, oracle_costs, obstacles=None, starts=None, goals=None)

Validated per-sample evidence; censored costs retain failed decodes.

aggregate_primary_metrics(arrays, *, obstacles_available=True)

Aggregate validated per-sample arrays without rerunning inference.

compute_primary_metrics(*, predicted_paths, oracle_paths, predicted_costs, oracle_costs, obstacles=None, starts=None, goals=None)

Six metrics; costs include censored failures, geometry uses valid paths.

Costs passed to this lower-level API must already use the analytic scene model. Use score_planner to recompute them directly from candidate paths.

paired_bootstrap_ci(metric_fn, samples_a, samples_b, *, n_bootstrap=10000, alpha=0.05, seed=0)

Paired-bootstrap CI on the difference of a metric across paired samples.

Both arrays are indexed identically (sample-paired), so the sample-difficulty variance cancels under the resample. metric_fn is applied to each resampled pair and the difference recorded.


Statistical discipline — passage_eval.protocol

Six primary metrics and three declared training seeds. The canonical comparison estimates contrasts of metric aggregates with shared geographic-block draws, then applies Holm–Bonferroni only to separately supplied paired-test p-values. It reports partial evidence when remaining metrics are inconclusive.

discipline

Statistical-discipline primitives for the PASSAGE evaluation protocol.

The cross-family evaluation protocol of the PASSAGE paper declares that every headline number is

(i) a function of the decoded path (Rule 1: common anchor), (ii) computed under a pre-registered set of primary metrics (PRIMARY_METRICS), (iii) aggregated over the seeds DEFAULT_SEEDS = (1234, 2026, 3407), (iv) estimated via shared geographic-block draws of aggregate contrasts, (v) corrected across the primary-metric family by Holm–Bonferroni at family-wise alpha = 0.05, and (vi) reduced to a categorical pairwise decision: Pareto-dominant / Trade-off / Partial evidence / No demonstrated difference.

This module is the canonical implementation of points (iii) - (vi). It is deliberately small and depends only on numpy so a third-party submission can re-derive the headline decision from its per-sample primary-metric arrays without re-running its decoder.

Classes

MetricFamily

Bases: str, Enum

Three primary-metric families declared by the paper.

BootstrapDelta(metric, delta, ci_low, ci_high, n, n_bootstrap, higher_is_better, n_a=None, n_b=None, n_blocks=None, per_seed=None) dataclass

Paired-bootstrap result on a single primary metric.

delta estimates T(A) - T(B). n counts the frozen task roster (summed across seeds for a seed mean); n_a and n_b count each method's finite outcomes. n_bootstrap counts shared draws, not seeds times draws. An undefined draw makes the interval unavailable (NaN).

Attributes
excludes_zero property

True iff zero is outside the CI - i.e. a directional difference.

favours_a property

True iff the directional CI favours method A.

Combines excludes_zero with the higher_is_better flag of the metric: e.g. for cost_regret_median (lower is better), \(\Delta < 0\) means \(A\) is better than \(B\).

Functions
two_sided_p_value(draws=None)

Legacy descriptive tail proxy; not a declared confirmatory test.

When draws (the resampled \(\Delta\) trajectory) is supplied the p-value is the empirical fraction of draws on the wrong side of zero, doubled for two-sided. With no draws available we fall back to a CI-coverage proxy: 2 * Phi(-|delta| / se) where se is approximated from the symmetric 95% CI half-width. Neither proxy specifies a null-resampling test or its assumptions. The canonical comparison requires separately supplied, declared paired-test p-values.

HolmBonferroniResult(metric, p_value, p_adjusted, rejected) dataclass

Per-test outcome of a Holm–Bonferroni correction over a metric family.

PairwiseDecision

Bases: str, Enum

Primary-metric outcomes; no-difference does not establish equivalence.

PrimaryMetricComparison(deltas, holm, decision, votes, inference_status, paired_test, test_assumptions, task_ids, blocks, resampling_seed, alpha) dataclass

Six-metric, three-seed comparison conditional on the fitted procedures.

A Pareto label concerns primary metrics only. Deployment latency and footprint must still be assessed separately before an overall claim. inference_status records availability, not qualification of a caller's declared paired test or scientific eligibility of these inputs.

Functions

apply_censored_penalty(predicted_costs, oracle_costs, *, decoder_succeeded=None, obstacle_violated=None, k_factor=1000000.0)

Return predicted costs with a \(K \gg c^{\star}\) penalty on failed decodes.

The paper defines a censored penalty \(c^{\text{pred}}_i = K\) "on a decode that fails to connect \(s\) to \(g\) or that crosses an obstacle". The canonical PASSAGE penalty value is K = k_factor * oracle_cost with k_factor = 1e6.

Parameters

predicted_costs, oracle_costs : array_like Per-sample costs in matching order. Pass np.nan (or the already-censored sentinel) for samples whose decode failed - this function will rewrite those entries. decoder_succeeded : array_like of bool, optional True iff the canonical decoder produced an \((s\to g)\) path. Mutually consistent with success_rate. obstacle_violated : array_like of bool, optional True iff the decoded path crosses an obstacle pixel. k_factor : float Multiplier on the oracle cost used as the censored penalty.

Returns

np.ndarray of shape (N,) Predicted costs with failed decodes rewritten to k_factor * oracle_cost. Entries with non-finite oracle cost remain non-finite.

paired_bootstrap_delta(per_sample_a, per_sample_b, *, metric='metric', higher_is_better=False, statistic=np.mean, n_bootstrap=10000, alpha=0.05, seed=DEFAULT_SEEDS[0], return_draws=False, blocks=None, nan_policy='raise')

Paired bootstrap on T(A) - T(B), preserving draw order.

Pairs are anchored on the same sample index: the pairing cancels sample-difficulty variance because both methods are evaluated on the same indices. With blocks, each draw samples the observed number of whole geographic blocks with replacement, retaining task weights. Without blocks this lower-level helper uses independent task resampling.

For cost_regret_median and friends pass statistic=np.median. The mean default agrees with the historical mean of paired differences. Nonlinear reductions intentionally use the difference of aggregates.

Parameters

per_sample_a, per_sample_b : array_like, shape (N,) Per-sample metric values, paired by index. statistic : callable Reduction applied separately to each method, including inside draws. n_bootstrap, alpha, seed Bootstrap parameters; alpha = 0.05 is the paper's default. return_draws : bool If True also return the (n_bootstrap,) draw vector for descriptive inspection. Ordinary bootstrap tails alone do not define the valid paired null test required for confirmatory Holm correction. nan_policy : {"raise", "omit"} Missing values raise by default. Explicit omission draws the complete roster first, then reduces each method's finite subset separately. An empty subset in any draw makes its CI unavailable; draws are retained.

multiseed_paired_bootstrap(per_sample_a_by_seed, per_sample_b_by_seed, *, metric='metric', higher_is_better=False, statistic=np.mean, n_bootstrap_per_seed=10000, alpha=0.05, seeds=DEFAULT_SEEDS, return_draws=False, seed=DEFAULT_SEEDS[0], blocks=None, nan_policy='raise')

Average seed contrasts within each shared task/block bootstrap draw.

The result contains B = n_bootstrap_per_seed draws of the seed mean, and per-seed estimates/CIs in per_seed. seed controls geographic resampling; seeds identifies fitted training seeds. This intentionally replaces the historical seed-union mixture of S * B draws.

Inputs are mappings keyed by exactly seeds, or sequences in that order. All arrays must represent the identical ordered task roster. Use compare_primary_metrics to validate explicit task identities and the complete preregistered seed/metric family.

holm_bonferroni(p_values, *, alpha=0.05)

Holm–Bonferroni step-down correction on a family of two-sided p-values.

Implements the standard step-down procedure: order p-values ascending, and reject at step \(k\) iff \(p_{(k)} \leq \alpha / (m - k + 1)\) and every earlier hypothesis was rejected. Returns a per-metric record carrying the original p-value, the Holm-adjusted p-value (\(\min(1, (m - k + 1) p_{(k)})\) with monotonised cumulative max), and the reject decision at family-wise alpha.

The order of the input mapping is ignored; results are returned in the original metric order (Python 3.11+ dicts preserve insertion). A NaN represents an unavailable test: it remains NaN and cannot reject, while still counting in the declared family size. Other values outside [0, 1], including infinities, raise instead of becoming evidence.

decide_pairwise(deltas, holm=None)

Reduce per-metric paired-bootstrap deltas + Holm flags to a verdict.

Each metric independently votes
  • win_a iff delta.favours_a and (if holm provided) the Holm-adjusted decision rejects the null.
  • win_b iff delta.favours_a is False, delta.excludes_zero is True, and Holm rejects.
  • tie otherwise.

Pareto-dominant: every metric votes the same direction. Indistinguishable: no metric votes either way. Trade-off: demonstrated wins in both directions. Partial evidence: demonstrated wins in one direction with inconclusive remaining metrics. This generic helper judges only the supplied family; use compare_primary_metrics for all six preregistered primary metrics.

compare_primary_metrics(per_sample_a_by_seed, per_sample_b_by_seed, *, blocks, n_bootstrap=10000, alpha=0.05, seed=DEFAULT_SEEDS[0], p_values=None, paired_test=None, test_assumptions=None)

Compare all primary metrics on an explicit, frozen three-seed roster.

Each seed supplies task_id, regret, assd, h95, success, obstacle_violation and valid_path arrays in identical task order. Regret must already retain censored failures; reliability uses all tasks. Geometry reduces each method's own successful, obstacle-free subset. The caller is responsible for matching data, operating conditions, work limits and frozen checkpoints; this function never loads or evaluates one.

Geographic blocks are sampled identically for both methods, every seed and every metric. Within each draw, compute each seed's prescribed aggregate contrast and then average the three contrasts. Per-seed CIs and method-specific denominators accompany the seed-mean interval. A geometry draw with an empty subset makes the CI unavailable; no draw is discarded.

Holm uses only the six explicitly supplied p-values from a predeclared paired test of this same block/seed-mean contrast. The test name and its assumptions are required metadata, not automatic evidence of validity. The legacy bootstrap-tail proxy is never used. Without a declared test, estimates/CIs are available but no confirmatory win is returned. NaN tests remain unavailable and retain their place in the six-test family. Claims across more method pairs require a larger prespecified correction family.


Decoder-readiness diagnostics — passage_eval.diagnostics

Checks that a predicted path mask or cost-to-go field is ready for its decoder. They are diagnostics, never headline metrics.

diagnostics

Family-symmetric decoder-readiness diagnostics.

Segmentation diagnostics live in segmentation; regression diagnostics in regression. None of them carries a headline claim.

Functions

boundary_f_score(pred_mask, gt_mask, *, tolerance=1)

F-score of boundary agreement at a tolerance of tolerance pixels.

Standard segmentation-challenge boundary-F at tolerance d is precision = |pred ∩ dilate(gt, d)| / |pred| recall = |gt ∩ dilate(pred, d)| / |gt| F = 2 PR / (P + R) Returns NaN when both masks are empty.

mask_connected_components_total(mask)

Number of 8-connected components of mask > 0.

mask_endpoints_in_same_component(mask, start, goal)

Do start and goal cells share an 8-connected component of mask>0?

bellman_residual_reachable(predicted_field, cost_grid, *, reachable_mask=None, goal=None, eps=1e-12)

Mean per-cell Bellman residual on reachable non-goal cells, normalised.

For each reachable non-goal cell s, residual(s) = | V_hat(s) - min_n ( c(s, n) + V_hat(n) ) | Normalised by mean(|V_hat|) over the reachable subset.

descent_direction_agreement(predicted_field, oracle_field, *, reachable_mask=None, obstacles=None, goal=None)

Fraction of cells where the local 8-argmin of the predicted field matches the oracle. Restricted to reachable, non-goal, non-obstacle cells.

A regression model with descent_direction_agreement = 0.99 produces oracle-equivalent paths under a greedy decoder regardless of MAE.

field_ssi_mae(predicted_field, oracle_field, *, reachable_mask=None, eps=1e-12)

Scale-and-shift-invariant MAE.

Solves for a, b = argmin || a * pred + b - oracle ||_1 via a closed-form least-squares fit, then reports the L1 residual on the fitted scale. Cross-cost-model comparable; invariant to the per-sample V normalisation.

local_ordinal_concordance(predicted_field, oracle_field, *, reachable_mask=None, margin=0.001)

Fraction of neighbour pairs with non-trivial oracle margin where the predicted field ranks them the same as the oracle.

A scale-invariant ordering check that complements MAE: a field can have a low MAE and still rank neighbouring cells in the wrong order, which misleads a descent decoder.


Trustworthiness axes — passage_eval.trustworthiness

Stability across training seeds, geographic generalization, behavior at the edge of the operational design domain (ODD), and latency relative to the exact A\(^{\star}\) oracle on the same device. Each function returns one TrustworthinessAxis record.

trustworthiness

Four trustworthiness axes of the PASSAGE paper.

A planner that is on average accurate can still fail operationally. The PASSAGE protocol re-applies the six primary metrics under four conditions the headline does not capture:

  • stability: coefficient of variation \(\sigma / \mu\) of cost_regret_p90 across the three pre-registered training seeds. Above 25% flags a training-unstable planner.
  • geographic: difference in mean between the geographic hold-out and a matched-marginal random split.
  • odd_boundary: performance at the declared envelope edge (extremal obstacle coverage, super-ellipse exponents, elevation bands).
  • efficiency: same-device latency relative to the A\(^{\star}\) oracle when the comparison is hardware-comparable.

Each module exposes a small, numpy-only function that takes the per-sample arrays produced by the released baselines (see passage_eval.io) and emits a single TrustworthinessAxis row.

Classes

TrustworthinessAxis(name, metric, value, flag=False, n_samples=0, extras=dict()) dataclass

One row of the trustworthiness sub-table.

value is the headline scalar (e.g. CV for stability, difference of means for geographic / ODD-edge, speed-up factor for efficiency). flag is a Boolean trip indicator: True means the axis fires (the planner is unstable, generalises poorly, collapses at the boundary, or is slower than the oracle). Threshold semantics are axis-specific and documented inside each module.

Functions

stability_cv(cost_regret_p90_per_seed, *, cv_threshold=0.25)

Coefficient of variation \(\sigma / \mu\) of the per-seed cost_regret_p90 (axis "Stab").

A planner whose three-seed CR-p90 has a CV above cv_threshold is flagged as training-unstable. The default cv_threshold is 0.25.

geographic_generalisation(holdout_per_sample, matched_random_per_sample, *, metric_name='cost_regret_p90', higher_is_better=False)

Difference in the mean of a primary metric between the geographic hold-out split and a matched-marginal random split (axis "Geo").

Both inputs are per-sample arrays for the same metric. The output value is mean(holdout) - mean(matched_random); higher_is_better sets which sign counts as worse.

The axis fires when the hold-out mean is worse than the matched random mean. The flag uses the sign of the difference only; it is not a significance test.

odd_boundary_delta(metric_per_sample, stratifier_per_sample, *, top_quantile=0.1, metric_name='cost_regret_p90', stratifier_name='obstacle_coverage', higher_is_better=False)

Difference between the top-quantile (boundary) slice and the full-split mean of a primary metric (axis "ODDe").

stratifier_per_sample carries one of the four declared per-sample ODD axes (obstacle coverage, super-ellipse exponent, elevation band, start-goal distance). Samples whose stratifier sits in the top top_quantile are designated the "boundary" slice. The axis value is \(\Delta = \mathrm{mean}(\text{boundary}) - \mathrm{mean}(\text{full})\).

For smaller-is-better metrics, a positive \(\Delta\) means the planner worsens at the envelope edge — the axis fires.

oracle_relative_efficiency(planner_latency_ms_per_sample, oracle_latency_ms_per_sample, *, speedup_threshold=1.0)

Same-device latency ratio between planner and A\(^{\star}\) oracle (axis "Eff").

The axis value is the speed-up \(\mathrm{speedup} = T_{\text{oracle}} / T_{\text{planner}}\).

A speed-up below speedup_threshold = 1.0 means the planner is slower than the oracle that produced its labels — the axis fires.

Inputs may be scalars or arrays; arrays are summarised by their median.


Deployment footprint — passage_eval.deployment

Wall-clock latency, decoder timing, end-to-end percentiles, parameter count, A\(^{\star}\)-expansions ratio, and decoder-recovery rate.

deployment

Deployment-footprint utilities.

Two submodules:

  • throughput: wall-clock benchmarking of the bare neural network forward pass, the canonical decoder, and the end-to-end pipeline (forward + decoder).
  • efficiency: surrogate-acceleration metrics (A*-expansions ratio and decoder-recovery rate).

These figures are reported next to the primary metrics but are not part of the Holm–Bonferroni family.

Functions

astar_expansions_ratio(expansions_pred, expansions_oracle, *, eps=1e-12)

expansions(decoded planner on V_hat) / expansions(plain A* on true cost).

Reported as median, p90 and geometric mean. < 1 means the surrogate accelerates A*; ≈ 1 means no acceleration; > 1 means the surrogate adds search effort.

decoder_recovery_rate(decoder_succeeded, fallback_triggered)

Fraction of samples whose canonical decoder produced a path without triggering the A*-recovery fallback.

This legacy measure excludes only the explicitly reported fallback stage. It does not receive a bounded-repair flag and therefore cannot establish that a successful decoder ran without repair. Use the scored direct_success_rate and repair_rate to distinguish that case.

benchmark_decoder(decoder_fn, inputs, *, name='decoder', n_warmup=1, determinism_flag='bit_exact')

Time the canonical decoder over a fixed batch of model outputs.

The decoder is run once per element of inputs. Latency is the mean per-sample wall-clock, and the percentile breakdown is computed over the per-sample times.

benchmark_end_to_end(model, decoder_fn, inputs, *, name='end_to_end', n_warmup=5, determinism_flag='algorithmically_deterministic', device=None)

Forward + decoder per sample, returning percentile latency.

Each inputs[i] is fed to model and the output to decoder_fn. End-to-end time per sample = forward + decode. Use this to populate the Lat. (ms) column of the headline table. Select a PyTorch device explicitly to benchmark an accelerator.

benchmark_forward(model, *, input_shape, name='forward', n_warmup=5, n_timed=20, determinism_flag='algorithmically_deterministic', device=None, dtype='fp32')

Benchmark the bare forward pass of model on synthetic input.

Parameters

model A torch nn.Module-like callable (or a wrapper exposing network). Plain Python callables also work — they will be treated as bare functions on numpy input when torch is not present. input_shape Shape of one synthetic input batch (e.g. (1, 3, 256, 256)). device PyTorch device. Defaults to CPU. Select CUDA explicitly to use it. dtype "fp32" (default), "fp16" or "bf16".


Reproducibility sidecar — passage_eval.sidecar

Manifest writer and deterministic calibration-decisions hash so every reported number can be mapped back to its dataset version, seeds, calibration decisions, hardware stack, batch size, dtype, and determinism flag.

sidecar

Reproducibility-sidecar manifest.

Every headline row of the PASSAGE results table carries a sidecar JSON manifest pinning, at minimum, the artefacts needed to map a number back to the configuration that produced it:

  • dataset version + content hash
  • seed set and split seed
  • deterministic hash of every calibration-split decision
  • hardware stack label (R1 for a server GPU, R2 for an edge GPU, or any other string)
  • inference batch size and numerical precision
  • determinism flag

This module is deliberately small: a single dataclass, deterministic hashing of arbitrary nested-Python decisions dicts, and JSON read/write. Submitters are expected to fill the dataclass once per headline row and ship the JSON with the predictions.

Classes

ReproducibilitySidecar(method_name, family, dataset_version, dataset_content_hash, operating_point, seeds=(lambda: list(DEFAULT_SEEDS))(), split_seed=0, calibration_decisions_hash='', hardware_stack='R1', batch_size=1, dtype='fp16', determinism_flag='algorithmically_deterministic', container_digest=None, commit_sha=None, notes=None, extra=dict()) dataclass

Sidecar manifest for one headline row.

Required minimum fields follow the reproducibility sidecar of the PASSAGE paper. Extra information goes under extra; the calibration_decisions_hash should be computed via compute_calibration_decisions_hash on the original mapping.

Functions

compute_calibration_decisions_hash(decisions)

Deterministic SHA-256 over a calibration-decisions mapping.

Renders the mapping as canonical JSON (sort_keys=True, separators=(",", ":")) before hashing so two manifests with the same logical content always produce the same hash. Path, set, and tuple values are normalised for serialisation.