"""Training-contract tests; random synthetic fixtures are not carrier qualification.""" from dataclasses import replace from unittest.mock import patch import pytest import torch from mcss.dynamic.carrier import DynamicSceneCarrier from mcss.dynamic.config import CarrierConfig from mcss.dynamic.types import OnlineObservation, hash_scene_state from mcss.measurements import FixedMeasurementRenderer from mcss.mechanism_pilot.training import common_anchor_measurement_loss from mcss.types import Cameras def observation(frame): pose = torch.eye(4) pose[0, 3] = 2 + frame * 0.025 intrinsics = torch.tensor([[6.0, 0, 3.5], [0, 6.0, 3.5], [0, 0, 1.0]]) return OnlineObservation( "scene", frame, torch.full((3, 8, 8), 0.1 + frame * 0.07), Cameras(intrinsics, pose, (8, 8)), ) @pytest.fixture def batch(): torch.manual_seed(21) carrier = DynamicSceneCarrier(CarrierConfig( feature_dim=4, hidden_dim=4, expansion_dim=8, grid_size=(4, 4, 4), token_count=16 )) query = observation(5).camera return dict( carrier=carrier, first_context=[observation(i) for i in (0, 1, 2)], second_context=[observation(i) for i in (0, 3, 4)], query_frame_ids=[5], query_cameras=Cameras(query.intrinsics[None, None], query.c2w[None, None], (8, 8)), query_rgb=torch.full((1, 1, 3, 8, 8), 0.6), query_depth=torch.full((1, 1, 1, 8, 8), 3.0), renderer=FixedMeasurementRenderer(n_samples=8), split_id="train", ) def test_common_anchor_loss_backpropagates_without_fast_writes(batch): carrier = batch["carrier"] with patch.object(carrier, "materialize", wraps=carrier.materialize) as materialize: result = common_anchor_measurement_loss(**batch) assert materialize.call_count == 2 for call in materialize.call_args_list: fast = call.args[1] assert fast.step == 0 assert torch.count_nonzero(fast.delta_fuse) == 0 assert torch.count_nonzero(fast.delta_complete) == 0 assert materialize.call_args_list[0].args[0] is not materialize.call_args_list[1].args[0] assert materialize.call_args_list[0].args[1] is not materialize.call_args_list[1].args[1] assert torch.equal(result.first_anchor_c2w, result.second_anchor_c2w) assert torch.isfinite(result.loss) result.loss.backward() for name in ("image_encoder.0.weight", "fuse_down.weight", "complete_down.weight"): gradient = dict(carrier.named_parameters())[name].grad assert gradient is not None and torch.isfinite(gradient).all() assert torch.count_nonzero(gradient) > 0 def test_query_camera_and_labels_cannot_change_constructed_states(batch): first = common_anchor_measurement_loss(**batch) query = batch["query_cameras"] moved = query.c2w.clone() moved[..., 0, 3] += 1 second = common_anchor_measurement_loss(**{ **batch, "query_cameras": Cameras(query.intrinsics, moved, query.image_size), "query_rgb": batch["query_rgb"] * 0.5, "query_depth": batch["query_depth"] * 2, }) assert hash_scene_state(first.first_state) == hash_scene_state(second.first_state) assert hash_scene_state(first.second_state) == hash_scene_state(second.second_state) events = [] carrier, renderer = batch["carrier"], batch["renderer"] materialize, render = carrier.materialize, renderer.forward def record_state(*args, **kwargs): events.append("state") return materialize(*args, **kwargs) def record_query(*args, **kwargs): events.append("query") return render(*args, **kwargs) with patch.object(carrier, "materialize", side_effect=record_state): with patch.object(renderer, "forward", side_effect=record_query): common_anchor_measurement_loss(**batch) assert events == ["state", "state", "query", "query"] @pytest.mark.parametrize("component", ["rgb", "pose", "intrinsics"]) def test_anchor_content_mismatch_rejected(batch, component): anchor = batch["second_context"][0] if component == "rgb": changed = replace(anchor, rgb=anchor.rgb + 0.1) else: pose, intrinsics = anchor.camera.c2w.clone(), anchor.camera.intrinsics.clone() if component == "pose": pose[0, 3] += 0.1 else: intrinsics[0, 0] += 1 changed = replace(anchor, camera=Cameras(intrinsics, pose, (8, 8))) batch["second_context"][0] = changed with pytest.raises(ValueError, match="Common anchor"): common_anchor_measurement_loss(**batch) @pytest.mark.parametrize("split", ["dev", "test", "validation", ""]) def test_nontraining_supervision_rejected(batch, split): with pytest.raises(ValueError, match="split_id"): common_anchor_measurement_loss(**{**batch, "split_id": split}) def test_overlap_and_unequal_contexts_rejected(batch): with pytest.raises(ValueError, match="only at the common anchor"): common_anchor_measurement_loss(**{ **batch, "second_context": [observation(i) for i in (0, 2, 4)] }) with pytest.raises(ValueError, match="equal counts"): common_anchor_measurement_loss(**{**batch, "second_context": [observation(0)]}) with pytest.raises(ValueError, match="disjoint"): common_anchor_measurement_loss(**{**batch, "query_frame_ids": [1]}) def test_invalid_depth_is_masked_and_empty_depth_rejected(batch): batch["query_depth"][..., 0, 0] = float("nan") batch["query_depth"][..., 0, 1] = float("inf") result = common_anchor_measurement_loss(**batch) assert torch.isfinite(result.loss) result.loss.backward() assert all(torch.isfinite(p.grad).all() for p in batch["carrier"].parameters() if p.grad is not None) with pytest.raises(ValueError, match="valid metric depth"): common_anchor_measurement_loss(**{ **batch, "query_depth": torch.zeros_like(batch["query_depth"]) })