mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-23 09:51:14 +00:00
[AZ-527] Consolidate _assert_engine_output_dim into c2-internal helper
Closes cumulative review batches 49-51 Finding F1 (Medium / Maintainability) -- the 7-way duplication of _assert_engine_output_dim across c2_vpr secondary VPR strategy modules. Add c2-internal helper assert_engine_output_dim(inference_runtime, handle, preprocessor, descriptor_dim, *, output_key='embedding', input_key='input') in src/gps_denied_onboard/components/c2_vpr/ _engine_dim_assertion.py. The helper runs a zero-init dry-run inference at preprocessor.input_shape() and asserts the engine output dict carries (1, descriptor_dim) under output_key. Raises gps_denied_onboard.config.schema.ConfigError on mismatch (preserving the prior error envelope and message wording byte-identically). Migrate 7 strategy modules (ultra_vpr, net_vlad, mega_loc, mix_vpr, sela_vpr, eigen_places, salad) to import the helper and delete the local _assert_engine_output_dim definitions + their inline 'AZ-527 (planned)' comments. NetVLAD is the only call site that overrides output_key='vlad_descriptor'; the other 6 explicitly pass output_key=_OUTPUT_KEY + input_key=_ENGINE_INPUT_KEY (matching helper defaults but documenting strategy contract at the call site). Add tests/unit/c2_vpr/test_az527_engine_dim_assertion.py (14 tests, AAA pattern, Protocol-conforming fakes) covering AC-1..AC-4: helper signature; wrong shape raises ConfigError naming both dims; missing output key raises ConfigError naming the missing key; AST-walk regression guard for stray definitions outside the helper module (modeled on AZ-526's test_ac4_az526_no_module_level_iso_ts_from_clock_outside_helper); import-grep regression guard verifying all 7 strategy modules import the helper. AC-5 (existing AZ-337/338/339/340 AC-6 sub-tests pass unmodified) is exercised transitively: c2_vpr/ full directory 230/230 PASS, no test file modified outside the new test_az527_*. AC-6 (AZ-270 + AZ-507 layer lints) verified by tests/unit/test_az270_compose_root.py 8/8 PASS. Code-review verdict: PASS (zero findings). Ruff clean. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -59,6 +59,9 @@ from gps_denied_onboard._types.inference import (
|
||||
)
|
||||
from gps_denied_onboard._types.vpr import VprQuery, VprResult
|
||||
from gps_denied_onboard.clock import Clock
|
||||
from gps_denied_onboard.components.c2_vpr._engine_dim_assertion import (
|
||||
assert_engine_output_dim,
|
||||
)
|
||||
from gps_denied_onboard.components.c2_vpr._faiss_bridge import FaissBridge
|
||||
from gps_denied_onboard.components.c2_vpr._preprocessor_mega_loc import (
|
||||
MegaLocBackbonePreprocessor,
|
||||
@@ -393,7 +396,14 @@ def create(
|
||||
clock=clock,
|
||||
)
|
||||
|
||||
_assert_engine_output_dim(inference_runtime, handle, preprocessor)
|
||||
assert_engine_output_dim(
|
||||
inference_runtime,
|
||||
handle,
|
||||
preprocessor,
|
||||
DESCRIPTOR_DIM,
|
||||
output_key=_OUTPUT_KEY,
|
||||
input_key=_ENGINE_INPUT_KEY,
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"C2 VPR strategy ready",
|
||||
@@ -421,31 +431,3 @@ def create(
|
||||
)
|
||||
|
||||
|
||||
def _assert_engine_output_dim(
|
||||
inference_runtime: InferenceRuntimeCut,
|
||||
handle: EngineHandle,
|
||||
preprocessor: MegaLocBackbonePreprocessor,
|
||||
) -> None:
|
||||
# The 4-way duplication of this helper (ultra_vpr / net_vlad /
|
||||
# mega_loc / mix_vpr) will be consolidated by AZ-527 (hygiene
|
||||
# PBI sized in parallel with AZ-339 land). The duplication is
|
||||
# intentional for now: extracting earlier would expand AZ-339's
|
||||
# scope past the two new strategies.
|
||||
h, w = preprocessor.input_shape()
|
||||
probe = np.zeros((1, 3, h, w), dtype=np.float16)
|
||||
outputs = inference_runtime.infer(handle, {_ENGINE_INPUT_KEY: probe})
|
||||
if _OUTPUT_KEY not in outputs:
|
||||
raise ConfigError(
|
||||
f"engine output shape mismatch: {_OUTPUT_KEY!r} key absent; "
|
||||
f"got keys {sorted(outputs.keys())!r}"
|
||||
)
|
||||
actual = np.asarray(outputs[_OUTPUT_KEY])
|
||||
if (
|
||||
actual.ndim != 2
|
||||
or actual.shape[0] != 1
|
||||
or actual.shape[1] != DESCRIPTOR_DIM
|
||||
):
|
||||
raise ConfigError(
|
||||
f"engine output shape mismatch: expected (1, {DESCRIPTOR_DIM}), "
|
||||
f"got {tuple(actual.shape)}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user