feat(perception): add bounded full-graph streaming and latency pilots

This commit is contained in:
DCCONSTRUCTIONS
2026-09-02 00:59:48 +03:00
parent 4e04d06191
commit bfe6ef4c77
17 changed files with 2267 additions and 0 deletions
@@ -0,0 +1,17 @@
# Stage-1 disposable ABI/process-isolation probe, NOT a released full profile.
# Before building, verify both local base tags against the IDs in the report.
FROM ndc/mission-core-installed-lab-v1-ddrnet-step:439127908dba AS goose
FROM ndc/mission-core-m49-t3-travel:20260826 AS travel
COPY baseline_tgs.cpp /tmp/baseline_tgs.cpp
RUN g++ -std=c++17 -O3 -DNDEBUG -pthread \
-I/opt/travel/src/TRAVEL/cpp/travel/core -I/usr/include/eigen3 \
/tmp/baseline_tgs.cpp -o /tmp/stage1-tgs
FROM nvcr.io/nvidia/tritonserver:26.06-py3
COPY --from=goose /opt/conda /opt/conda
COPY --from=travel /tmp/stage1-tgs /usr/local/bin/stage1-tgs
LABEL com.nodedc.product="mission-core" \
com.nodedc.stack="observatory" \
com.nodedc.role="stage1-dependency-probe" \
com.nodedc.managed-by="codex-local"
ENTRYPOINT ["/bin/bash"]
@@ -0,0 +1,40 @@
# Bounded stage-1 common-graph pilot, NOT the stage-2 standalone release.
# Verify local base tags against the recorded image IDs before build.
FROM ndc/mission-core-installed-lab-v1-ddrnet-step:439127908dba AS ddr
FROM ndc/mission-core-m49-t3-travel:20260826 AS tgs
COPY pilot_tgs.cpp /tmp/pilot_tgs.cpp
RUN g++ -std=c++17 -O3 -DNDEBUG -pthread \
-I/opt/travel/src/TRAVEL/cpp/travel/core -I/usr/include/eigen3 \
/tmp/pilot_tgs.cpp -o /tmp/pilot-tgs
FROM nvcr.io/nvidia/tritonserver:26.06-py3 AS pilot
COPY --from=ddr /opt/conda /opt/conda
# Exact version from repository uv.lock; only the CPU supervisor needs this.
RUN python3 -m pip install --no-cache-dir --only-binary=:all: pillow==12.3.0
COPY --from=tgs /tmp/pilot-tgs /usr/local/bin/pilot-tgs
COPY source-code.tar.gz /tmp/source-code.tar.gz
RUN mkdir /code && tar --no-same-owner -xzf /tmp/source-code.tar.gz -C /code \
&& mkdir -p /models/rf_detr_large_native_kb4/1 /root/sg_logs
COPY *.py /probe/
COPY run_goose_vegetation_benchmark.py /probe/run_goose_vegetation_benchmark.py
COPY rfdetr-config.pbtxt /models/rf_detr_large_native_kb4/config.pbtxt
ENV PYTHONPATH=/code/src \
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 \
MPLCONFIGDIR=/tmp/matplotlib
LABEL com.nodedc.product="mission-core" com.nodedc.stack="observatory" \
com.nodedc.role="stage1-joint-pilot" com.nodedc.managed-by="codex-local"
ENTRYPOINT ["python3", "-B", "/probe/run_joint_pilot.py"]
# Bounded local fallback for a daemon with missing compressed registry blobs.
# Uses only already-built files; no new registry access or credential change.
# This overlay is a diagnostic pilot, NEVER a standalone image release.
FROM scratch AS pilot-assets
COPY --from=pilot /probe /probe
COPY --from=pilot /code /code
COPY --from=pilot /models /models
COPY --from=pilot /usr/local/bin/pilot-tgs /bin/pilot-tgs
COPY --from=pilot /usr/local/lib/python3.12/dist-packages/PIL /python/PIL
COPY --from=pilot /usr/local/lib/python3.12/dist-packages/pillow.libs /python/pillow.libs
# Default docker build remains a runnable image, not the diagnostic overlay.
FROM pilot AS joint-pilot
@@ -0,0 +1,127 @@
#!/usr/bin/env python3
"""Bounded component baseline, NOT full-profile or transport qualification.
Run only in the pinned installed DDRNet image on an exclusive Worker. The
existing video is decoded incrementally; it is not copied, hashed end-to-end,
cached as PNGs or fully decoded before the first measured frame.
"""
from __future__ import annotations
import argparse
import hashlib
import importlib.machinery
import importlib.util
import json
import signal
import statistics
import time
from datetime import datetime, timezone
from pathlib import Path
def digest(path: Path) -> str:
result = hashlib.sha256()
with path.open("rb") as stream:
for chunk in iter(lambda: stream.read(1024 * 1024), b""):
result.update(chunk)
return result.hexdigest()
def distribution(values: list[float]) -> dict[str, float]:
ordered = sorted(values)
return {
"mean": statistics.fmean(ordered),
"p50": ordered[int((len(ordered) - 1) * 0.50)],
"p95": ordered[int((len(ordered) - 1) * 0.95)],
"p99": ordered[int((len(ordered) - 1) * 0.99)],
"maximum": max(ordered),
}
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--video", type=Path, required=True)
parser.add_argument("--runner", type=Path, required=True)
parser.add_argument("--checkpoint", type=Path, required=True)
parser.add_argument("--samples", type=int, default=64, choices=range(8, 129))
parser.add_argument("--warmup", type=int, default=8, choices=range(1, 17))
args = parser.parse_args()
signal.alarm(180)
started = time.monotonic_ns()
utc = datetime.now(timezone.utc).isoformat()
runner = args.runner
checkpoint = args.checkpoint
expected_checkpoint = "b99c2838051bcd7b092fd3970aa62a77d5c0bbb809c9b9afb2ff4b0ebdaa4ee6"
if digest(checkpoint) != expected_checkpoint:
raise RuntimeError("checkpoint identity changed")
if digest(runner) != "b18ad60f277eea69a240a28f290611b94627fb9707faf1bb3e6e22102dad67c1":
raise RuntimeError("reused runner identity changed")
loader = importlib.machinery.SourceFileLoader("goose_baseline_runner", str(runner))
spec = importlib.util.spec_from_loader(loader.name, loader)
if spec is None:
raise RuntimeError("runner is unavailable")
module = importlib.util.module_from_spec(spec)
loader.exec_module(module)
import cv2
import torch
from PIL import Image
capture = cv2.VideoCapture(str(args.video))
try:
ok, bgr = capture.read()
if not ok or bgr is None or bgr.shape != (600, 800, 3):
raise RuntimeError("first native KB4 frame unavailable")
tensor, _ = module.preprocess(Image.fromarray(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)))
model, name, _ = module.load_model("ddrnet", checkpoint)
for _ in range(args.warmup):
module.infer(model, tensor)
warm_ns = time.monotonic_ns()
torch.cuda.reset_peak_memory_stats()
rows = []
mask_digest = hashlib.sha256()
for sequence in range(args.samples):
begin = time.monotonic_ns()
ok, bgr = capture.read()
decoded = time.monotonic_ns()
if not ok or bgr is None or bgr.shape != (600, 800, 3):
raise RuntimeError("bounded source ended or changed shape")
tensor, _ = module.preprocess(Image.fromarray(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)))
preprocessed = time.monotonic_ns()
mask, forward_ms = module.infer(model, tensor)
completed = time.monotonic_ns()
mask_digest.update(mask.tobytes())
rows.append({
"sequence": sequence + 1,
"decode_ms": (decoded - begin) / 1e6,
"preprocess_ms": (preprocessed - decoded) / 1e6,
"h2d_forward_post_d2h_ms": (completed - preprocessed) / 1e6,
"forward_post_ms": forward_ms,
"component_total_ms": (completed - begin) / 1e6,
})
result = {
"schema_version": "missioncore.perception-component-baseline/v1",
"component": "ddrnet", "started_utc": utc,
"started_monotonic_ns": started, "finished_monotonic_ns": time.monotonic_ns(),
"checkpoint_sha256": expected_checkpoint, "runner_sha256": digest(runner),
"model": name, "torch": torch.__version__, "cuda": torch.version.cuda,
"gpu": torch.cuda.get_device_name(0), "precision": "existing-fp32",
"samples": args.samples, "warmup_iterations": args.warmup,
"load_first_decode_warmup_seconds": (warm_ns - started) / 1e9,
"source_whole_file_copied_or_hashed": False,
"source_frames_decoded": args.samples + 1,
"source_paced": False, "full_profile_qualified": False,
"mask_sequence_sha256": mask_digest.hexdigest(),
"peak_allocated_vram_mib": torch.cuda.max_memory_allocated() / 1048576,
"peak_reserved_vram_mib": torch.cuda.max_memory_reserved() / 1048576,
"timing_ms": {key: distribution([row[key] for row in rows]) for key in rows[0]
if key != "sequence"},
"frames": rows,
}
print("STAGE1_RESULT=" + json.dumps(result, sort_keys=True), flush=True)
finally:
capture.release()
if __name__ == "__main__":
main()
@@ -0,0 +1,32 @@
"""CPU component probe using synthetic, explicitly stationary geometry only."""
import json
import time
import numpy as np
from k1link.compute.lidar_local_surface_shadow import (
K1LocalSurfaceShadowEstimator,
K1LocalSurfaceShadowInput,
)
random = np.random.default_rng(20260901)
estimator = K1LocalSurfaceShadowEstimator()
rows = []
for index in range(64):
xy = random.uniform(-8, 8, (4000, 2))
z = random.normal(0, 0.015, (4000, 1))
z[3800:] += 1.0
value = K1LocalSurfaceShadowInput(
frame_index=index, source_frame_index=index, session_seconds=index / 10,
pose_binding_age_ms=0, points_map=np.column_stack((xy, z)),
position_map=np.zeros(3), published_monotonic_ns=time.monotonic_ns(),
)
started = time.monotonic_ns()
result = estimator.process(value)
rows.append({"sequence": index, "wall_ms": (time.monotonic_ns() - started) / 1e6,
"state": result.state})
print(json.dumps({"schema_version": "missioncore.perception-component-baseline/v1",
"component": "online-local-surface", "synthetic": True,
"points_per_frame": 4000, "frames": rows,
"full_profile_qualified": False}, sort_keys=True))
@@ -0,0 +1,61 @@
// Component-only CPU measurement on 64 existing prepared rolling clouds.
// Does NOT measure source decoding, rolling input preparation, costmap or transport.
#include <chrono>
#include <cmath>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include "travel/point_types.hpp"
#include "travel/tgs.hpp"
struct QuietLibraryOutput {
std::ostringstream buffer;
std::streambuf* previous;
QuietLibraryOutput() : previous(std::cout.rdbuf(buffer.rdbuf())) {}
~QuietLibraryOutput() { std::cout.rdbuf(previous); }
};
int main(int argc, char** argv) {
if (argc != 2) return 2;
using Clock = std::chrono::steady_clock;
try {
std::cout << "sequence,points,ground,nonground,wall_ms,algorithm_ms\n";
for (int index = 0; index < 64; ++index) {
std::ostringstream path;
path << argv[1] << '/' << std::setw(6) << std::setfill('0') << index << ".bin";
std::ifstream file(path.str(), std::ios::binary);
if (!file) throw std::runtime_error("bounded cloud unavailable");
travel::PointCloud<PointXYZILID> input;
float row[4];
while (file.read(reinterpret_cast<char*>(row), sizeof(row))) {
if (input.size() >= 500000) throw std::runtime_error("cloud exceeds point budget");
PointXYZILID point{};
point.x = row[0]; point.y = row[1]; point.z = row[2]; point.intensity = row[3];
if (!std::isfinite(point.x) || !std::isfinite(point.y) || !std::isfinite(point.z))
throw std::runtime_error("nonfinite cloud");
input.emplace_back(point);
}
if (file.gcount() || input.empty()) throw std::runtime_error("invalid cloud bytes");
const auto start = Clock::now();
travel::PointCloud<PointXYZILID> ground, nonground;
double algorithm_seconds = 0;
{
QuietLibraryOutput quiet;
travel::TravelGroundSeg<PointXYZILID> tgs;
tgs.setParams(80.0, 1.0, 8.0, 3, 5, 10, 0.5, 0.125, 0.3, 0.940,
200.0, 0.03, 0.1, 1.0, true, false);
tgs.estimateGround(input, ground, nonground, algorithm_seconds);
}
const auto end = Clock::now();
const auto wall = std::chrono::duration<double, std::milli>(end - start).count();
std::cout << index << ',' << input.size() << ',' << ground.size() << ','
<< nonground.size() << ',' << wall << ',' << algorithm_seconds * 1000 << '\n';
}
} catch (const std::exception& error) {
std::cerr << error.what() << '\n';
return 1;
}
}
@@ -0,0 +1,138 @@
"""Measured FP32 DDRNet execution; preserves sigmoid and first-index ties.
An experimental memory-layout variant, not a new weight/precision/label model.
Python 3.9 compatible. GPU calls remain serialized by the owning supervisor.
"""
import time
def layout_scores(scores, layout):
if layout == "reference":
return scores, 1
if layout == "channels-last":
return scores.permute(0, 2, 3, 1).contiguous(), 3
raise ValueError("unknown DDRNet postprocess layout")
class DdrnetRuntime:
def __init__(self, model, logits_from_output, layout, execution="eager"):
import torch
if layout not in ("reference", "channels-last"):
raise ValueError("unknown DDRNet postprocess layout")
if execution not in ("eager", "cuda-graph"):
raise ValueError("unknown DDRNet execution mode")
self.torch = torch
self.model = model
self.logits_from_output = logits_from_output
self.layout = layout
self.execution = execution
self.graph = None
self.events = [torch.cuda.Event(enable_timing=True) for _ in range(5)]
def validate_ties(self):
torch = self.torch
# Sigmoid saturates 100 and 101 to the same score. Argmax(logits)
# would change the original label; the layout optimization must not.
logits = torch.tensor(
[
[100.0, 0.0, -100.0, 4.0],
[101.0, 0.0, -99.0, 4.0],
[-100.0, 0.0, 3.0, 0.0],
[-9.0, 0.0, -9.0, 0.0],
],
dtype=torch.float32,
device="cuda",
).reshape(1, 4, 2, 2)
scores = torch.sigmoid(logits)
reference = torch.argmax(scores, dim=1)
changed, dimension = layout_scores(scores, "channels-last")
candidate = torch.argmax(changed, dim=dimension)
valid = bool(torch.equal(reference, candidate) and reference[0, 0, 0].item() == 0)
if not valid:
raise RuntimeError("DDRNet layout changed saturated/tied-score labels")
return valid
def infer(self, tensor):
if self.execution == "cuda-graph":
return self.infer_graph(tensor)
torch = self.torch
h2d_started = time.perf_counter_ns()
tensor = tensor.cuda(non_blocking=True)
torch.cuda.synchronize()
started = time.perf_counter_ns()
with torch.inference_mode():
self.events[0].record()
logits = self.logits_from_output(self.model(tensor))
self.events[1].record()
scores = torch.sigmoid(logits)
self.events[2].record()
scores, dimension = layout_scores(scores, self.layout)
self.events[3].record()
prediction = torch.argmax(scores, dim=dimension)
self.events[4].record()
torch.cuda.synchronize()
predicted = time.perf_counter_ns()
mask = prediction[0].to(device="cpu", dtype=torch.uint8).numpy()
copied = time.perf_counter_ns()
names = ("model_gpu_ms", "sigmoid_gpu_ms", "layout_gpu_ms", "argmax_gpu_ms")
stages = {
name: self.events[i].elapsed_time(self.events[i + 1]) for i, name in enumerate(names)
}
stages.update(
h2d_sync_wall_ms=(started - h2d_started) / 1e6,
d2h_wall_ms=(copied - predicted) / 1e6,
forward_post_wall_ms=(predicted - started) / 1e6,
)
return mask, (predicted - started) / 1e6, stages
def _compute(self, tensor):
logits = self.logits_from_output(self.model(tensor))
scores, dimension = layout_scores(self.torch.sigmoid(logits), self.layout)
return self.torch.argmax(scores, dim=dimension)
def _capture(self, tensor):
torch = self.torch
# Capture only fixed-shape DDRNet work, never source reads, RF-DETR,
# host decisions, or another profile. Capture is local to this GPU/run.
self.static_input = tensor.cuda().clone()
stream = torch.cuda.Stream()
stream.wait_stream(torch.cuda.current_stream())
with torch.cuda.stream(stream), torch.inference_mode():
for _ in range(3):
self._compute(self.static_input)
torch.cuda.current_stream().wait_stream(stream)
torch.cuda.synchronize()
self.graph = torch.cuda.CUDAGraph()
with torch.cuda.graph(self.graph), torch.inference_mode():
self.static_prediction = self._compute(self.static_input)
torch.cuda.synchronize()
def infer_graph(self, tensor):
torch = self.torch
if self.graph is None:
self._capture(tensor)
if tensor.shape != self.static_input.shape or tensor.dtype != self.static_input.dtype:
raise ValueError("DDRNet CUDA graph input shape/dtype changed")
h2d_started = time.perf_counter_ns()
self.static_input.copy_(tensor, non_blocking=True)
torch.cuda.synchronize()
started = time.perf_counter_ns()
self.events[0].record()
self.graph.replay()
self.events[1].record()
torch.cuda.synchronize()
predicted = time.perf_counter_ns()
mask = self.static_prediction[0].to(device="cpu", dtype=torch.uint8).numpy()
copied = time.perf_counter_ns()
return (
mask,
(predicted - started) / 1e6,
{
"cuda_graph_gpu_ms": self.events[0].elapsed_time(self.events[1]),
"h2d_sync_wall_ms": (started - h2d_started) / 1e6,
"d2h_wall_ms": (copied - predicted) / 1e6,
"forward_post_wall_ms": (predicted - started) / 1e6,
},
)
@@ -0,0 +1,451 @@
"""Joint-pilot wiring of existing algorithms to current, causal source data.
Experiment adapter only: no installed LAB or product registry mutation.
Historical profile files supply algorithm parameters, never derived evidence.
"""
from __future__ import annotations
import csv
import hashlib
import importlib.util
import struct
import sys
import time
import zipfile
from collections import Counter, OrderedDict
from dataclasses import asdict
from pathlib import Path
import numpy as np
from pilot_ipc import exact
from k1link.compute.lidar_local_surface_shadow import (
K1LocalSurfaceShadowEstimator,
K1LocalSurfaceShadowInput,
)
from k1link.perception.contracts import (
ClockBasis,
LocalObstacleMap,
ModalityOutcome,
ModalityStatus,
SourceAccounting,
SourceEnvelope,
TemporalState,
TimestampBundle,
)
from k1link.perception.detector import NativeRfDetrShadowDetectorProvider
from k1link.perception.geometry import (
GeometryFrame,
Ravnoves00GeometryAssociationProvider,
load_geometry_profile,
)
from k1link.perception.geometry_math import (
Kb4ProjectionProfile,
project_map_points_kb4,
quaternion_xyzw_to_rotation_matrix,
)
from k1link.perception.motion import ClassIndependentMotionEstimator
from k1link.perception.providers import SourcePacket
from k1link.perception.rf_detr_native_object_detector import TritonNativeRfDetrHttpInferenceBackend
from k1link.perception.rolling_map import RollingLocalObstacleMapProvider, load_rolling_map_profile
from k1link.perception.temporal import BoundedSpatialTemporalProvider, load_temporal_motion_profile
from k1link.perception.threat import (
DualEvidenceReplayThreatProvider,
ReplayBodyFrame,
load_replay_threat_profile,
)
from k1link.perception.yolox_object_detector import load_valid_fov_mask
def module_from_file(name, path):
spec = importlib.util.spec_from_file_location(name, path)
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
spec.loader.exec_module(module)
return module
def calibration(path):
# Read only the three small static arrays, never the archive's point data.
with zipfile.ZipFile(path) as archive:
arrays = {}
for name in ("intrinsic_fx_fy_cx_cy", "distortion_kb4", "t_camera_from_lidar"):
if archive.getinfo(name + ".npy").file_size > 4096:
raise ValueError("calibration exceeds metadata budget")
with archive.open(name + ".npy") as stream:
arrays[name] = np.lib.format.read_array(stream, allow_pickle=False)
return Kb4ProjectionProfile(
800,
600,
tuple(arrays["intrinsic_fx_fy_cx_cy"]),
tuple(arrays["distortion_kb4"]),
arrays["t_camera_from_lidar"],
)
def grid_indices(point_cells, grid):
"""Exact equivalent of per-point tuple/dict lookup, including holes."""
grid_xy = grid[:, :2].astype(np.int64)
lower = grid_xy.min(axis=0)
shape = grid_xy.max(axis=0) - lower + 1
lookup = np.full(tuple(shape), -1, np.int64)
offset = grid_xy - lower
lookup[offset[:, 0], offset[:, 1]] = np.arange(len(grid))
relative = point_cells - lower
inside = np.all((relative >= 0) & (relative < shape), axis=1)
result = np.full(len(point_cells), -1, np.int64)
result[inside] = lookup[relative[inside, 0], relative[inside, 1]]
return result
class CurrentStore:
"""One current frame, no NPZ store, historical lookup or future trajectory."""
def __init__(self, profile):
self.profile = profile
self.current = None
self.pose = None
self.body = None
self.frame_id = None
self.body_history = OrderedDict()
def frame(self, packet):
if packet.envelope.frame_id != self.frame_id:
raise ValueError("online geometry frame identity mismatch")
return self.current
def current_points(self, packet):
frame = self.frame(packet)
return frame.points_map if frame is not None and frame.surface_valid else None
def pose_values_for_frame(self, frame_id):
if frame_id != self.frame_id:
raise ValueError("past/future pose lookup forbidden")
return self.pose
def body_frame_for_frame(self, frame_id):
if frame_id > self.frame_id:
raise ValueError("future body lookup forbidden")
return self.body_history.get(frame_id)
def remember_body(self):
self.body_history[self.frame_id] = self.body
while len(self.body_history) > 64:
self.body_history.popitem(last=False)
def current_body(frame, surface):
if (
not surface.valid
or surface.sensor_height_m is None
or abs(surface.sensor_height_m - 1.25) > 0.45
or surface.slope_deg is None
or surface.slope_deg > 10.0
):
return None
rotation = quaternion_xyzw_to_rotation_matrix(frame.sensor_orientation_xyzw)
forward = rotation @ frame.projection.t_camera_from_lidar[2, :3]
forward[2] = 0
norm = np.linalg.norm(forward)
normal = np.asarray(surface.plane_coefficients_map[:3])
if norm < 1e-9 or abs(normal[2]) < 1e-6:
return None
forward /= norm
up = np.array([0.0, 0.0, 1.0])
left = np.cross(up, forward)
origin = frame.sensor_position_map - up * (surface.sensor_height_m / abs(normal[2]))
basis = np.column_stack((forward, left, up))
return ReplayBodyFrame(
f"frame-{frame.frame_index:06d}",
tuple(origin),
tuple(tuple(row) for row in basis),
surface.sensor_height_m,
surface.slope_deg,
"causal-camera-forward-simulation",
0.0,
)
class JointGraph:
def __init__(self, code_root, tgs, *, mask_path, mapping_path, calibration_pack):
root = Path(code_root)
config = root / "config/perception"
self.projection = calibration(calibration_pack)
self.surface = K1LocalSurfaceShadowEstimator()
self.store = CurrentStore(load_geometry_profile(config / "m4-geometry-association-v1.json"))
self.geometry = Ravnoves00GeometryAssociationProvider(store=self.store)
temporal_profile = load_temporal_motion_profile(config / "m4-temporal-motion-v1.json")
self.temporal = BoundedSpatialTemporalProvider(
point_resolver=self.store, profile=temporal_profile
)
self.motion = ClassIndependentMotionEstimator(profile=temporal_profile)
self.rolling = RollingLocalObstacleMapProvider(
pose_resolver=self.store,
profile=load_rolling_map_profile(config / "m4-rolling-local-map-v1.json"),
)
self.threat = DualEvidenceReplayThreatProvider(
body_frame_resolver=self.store,
profile=load_replay_threat_profile(config / "m4-replay-threat-v3.json"),
)
self.backend = TritonNativeRfDetrHttpInferenceBackend(
"http://127.0.0.1:8000", timeout_seconds=5
)
self.detector = NativeRfDetrShadowDetectorProvider(
mask=load_valid_fov_mask(Path(mask_path)), backend=self.backend
)
self.tgs = tgs
scripts = root / "experiments/perception/worker/m49_t3_travel"
sys.path.insert(0, str(scripts))
from build_tgs_fail_closed_evidence import costmap_grid
from build_tgs_full_shadow_evidence import rasterize
self.rasterize = rasterize
self.grid = costmap_grid(12.0, 0.45)
self.cell_lookup = {(int(row[0]), int(row[1])): i for i, row in enumerate(self.grid)}
policy_module = module_from_file(
"pilot_vegetation_policy", root / "src/k1link/laboratory/vegetation_mission_policy.py"
)
self.policy = policy_module.load_vegetation_mission_policy(
config / "lab-v1-vegetation-mission-policy-v1.json", repository_root=root
)
mapping = policy_module.load_vegetation_provider_label_map(
config / "lab-v1-vegetation-provider-label-map-v1.json", policy=self.policy
)
if (
hashlib.sha256(Path(mapping_path).read_bytes()).hexdigest()
!= "88ae319ba5a3877dd3ae0773f693a6a5fdc283934140de9dfaff029108aefd7f"
):
raise ValueError("GOOSE class mapping changed")
with Path(mapping_path).open(encoding="utf-8-sig", newline="") as stream:
labels = {int(row["label_key"]): row["class_name"] for row in csv.DictReader(stream)}
if set(labels) != set(range(64)):
raise ValueError("GOOSE mapping incomplete")
material_names = ["unknown", *self.policy["material_classes"]]
provider_map = mapping["providers"]["goose-fine-64"]["labels"]
self.material_names = material_names
self.material_lut = np.asarray(
[material_names.index(provider_map.get(labels[i], "unknown")) for i in range(64)]
)
self.action_lut = np.full(
(len(material_names), 4), 2, np.uint8
) # 0=ALLOW,1=HIGH_COST,2=NO_GO
for i, material in enumerate(material_names):
decision = policy_module.resolve_terrain_policy(
self.policy,
preset_id="rural",
material_class=None if material == "unknown" else material,
evidence_state="SUPPORTED_GROUND",
)
self.action_lut[i, 1] = {"ALLOW": 0, "HIGH_COST": 1, "NO_GO": 2}[
decision.effective_action
]
# Pilot intent: ONLY coarse hard_surface can be an ALLOW candidate.
# This additional conservative interlock cannot weaken legacy rules.
if material != "hard_surface":
self.action_lut[i, :] = 2
def packet(self, bundle):
available = bundle["available"]
status = ModalityStatus(
available,
ModalityOutcome.AVAILABLE if available else ModalityOutcome.UNAVAILABLE,
"causal-source-bound" if available else "no-fresh-past-cloud-or-pose",
)
env = SourceEnvelope(
source_id="RAVNOVES00",
session_id="20260720T065719Z_viewer_live",
frame_id=f"frame-{bundle['sequence']:06d}",
sequence=bundle["sequence"],
timestamps=TimestampBundle(
utc_ns=bundle["utc_ns"],
monotonic_ns=bundle["time_ns"],
source_ns=bundle["source_ns"],
clock_basis=ClockBasis.RECORDED_HOST,
),
source_age_ns=0,
binding_reason="past-only-source-arrival",
calibration_id="camera-1-kb4-05f3ad9b",
representation_id=self.rolling.profile.representation_id,
image=ModalityStatus(True, ModalityOutcome.AVAILABLE, "current-camera"),
registered_point_increment=status,
pose=status,
)
return SourcePacket(
env,
bundle["image"],
bundle["points"] if available else None,
bundle["pose"] if available else None,
)
def process(self, bundle, segmentation, *, proposals=None, detector_ms=None):
packet = self.packet(bundle)
timing = {}
if proposals is None:
begin = time.monotonic_ns()
proposals = self.detector.detect(packet)
detector_ms = (time.monotonic_ns() - begin) / 1e6
timing["detector_ms"] = detector_ms
self.store.frame_id = packet.envelope.frame_id
self.store.current = self.store.pose = self.store.body = None
surface = None
begin = time.monotonic_ns()
if bundle["available"]:
position, quaternion = bundle["pose"]
surface = self.surface.process(
K1LocalSurfaceShadowInput(
frame_index=bundle["sequence"],
source_frame_index=bundle["sequence"],
session_seconds=bundle["source_ns"] / 1e9,
pose_binding_age_ms=bundle["binding_age_ms"],
points_map=bundle["points"],
position_map=position,
published_monotonic_ns=bundle["due_ns"],
)
)
self.store.current = GeometryFrame(
bundle["sequence"],
bundle["points"],
surface.point_class,
position,
quaternion,
self.projection,
surface.valid,
)
self.store.pose = (tuple(position), tuple(quaternion))
self.store.body = current_body(self.store.current, surface)
self.store.remember_body()
timing["online_surface_ms"] = (time.monotonic_ns() - begin) / 1e6
begin = time.monotonic_ns()
observations = self.geometry.associate(packet, proposals)
timing["association_ms"] = (time.monotonic_ns() - begin) / 1e6
begin = time.monotonic_ns()
temporal = self.temporal.update(packet, observations)
moving = self.motion.estimate(packet, temporal)
retained = self.rolling.update(packet, moving)
current = tuple(item for item in moving if item.state is TemporalState.CURRENT)
unknown = tuple(item for item in moving if item.state is not TemporalState.CURRENT)
associated = {
pid
for item in observations
if item.metric_geometry is not None
for pid in item.proposal_ids
}
scene_map = LocalObstacleMap(
"RAVNOVES00",
"20260720T065719Z_viewer_live",
packet.envelope.frame_id,
"stage1-joint-online-pilot/v1",
time.monotonic_ns(),
max(0, time.monotonic_ns() - bundle["due_ns"]),
(*current, *retained),
unknown,
tuple(p for p in proposals if p.proposal_id not in associated),
SourceAccounting(1, 1, 0, 0),
)
threats = self.threat.assess(scene_map)
timing["motion_rolling_threat_ms"] = (time.monotonic_ns() - begin) / 1e6
begin = time.monotonic_ns()
costmap, actions, material, tgs_counts = self.costmap(bundle, segmentation, scene_map)
timing["tgs_costmap_policy_ms"] = (time.monotonic_ns() - begin) / 1e6
return {
"timing_ms": timing,
"surface_state": surface.state if surface else "unavailable",
"segmentation_sha256": hashlib.sha256(segmentation.tobytes()).hexdigest(),
"proposals": [asdict(x) for x in proposals],
"observations": [asdict(x) for x in observations],
"tracks": [asdict(x) for x in moving],
"threats": [asdict(x) for x in threats],
"tgs_counts": tgs_counts,
"costmap_states": costmap.tolist(),
"costmap_material": material.tolist(),
"policy_actions": actions.tolist(),
"policy_counts": {
key: int(np.count_nonzero(actions == value))
for key, value in (("ALLOW_candidate", 0), ("HIGH_COST", 1), ("NO_GO", 2))
},
"range_estimator": {
"detected": "median-camera-z",
"geometry_only": "nearest-euclidean-sensor",
},
"commands_enabled": False,
"actuation_allowed": False,
}
def costmap(self, bundle, mask, obstacle_map):
count = len(self.grid)
material = np.zeros(count, np.int32)
if not bundle["available"]:
return (
np.zeros(count, np.uint8),
np.full(count, 2, np.uint8),
material,
{"unavailable": True},
)
position, quaternion = bundle["pose"]
points = bundle["rolling_points"]
stamps = bundle["rolling_times"]
local = points - position
keep = np.sum(local[:, :2] ** 2, axis=1) <= 144.0
local, points, stamps = local[keep], points[keep], stamps[keep]
if not 0 < len(local) <= 64000:
raise ValueError("TGS rolling input outside pilot bound")
native = np.column_stack((local, np.zeros(len(local)))).astype("<f4")
self.tgs.stdin.write(struct.pack("<I", len(local)) + native.tobytes())
self.tgs.stdin.flush()
n, algorithm_ms = struct.unpack("<Id", exact(self.tgs.stdout, 12))
if n != len(local):
raise ValueError("TGS point accounting changed")
states = np.frombuffer(exact(self.tgs.stdout, n), np.uint8)
if np.any((states < 1) | (states > 3)):
raise ValueError("TGS returned invalid state")
cells, _ = self.rasterize(native[:, :3], states, self.grid, 0.45)
point_cells = np.floor(local[:, :2] / 0.45).astype(np.int32)
ids = grid_indices(point_cells, self.grid)
valid = ids >= 0
last_seen = np.full(count, -1, np.int64)
np.maximum.at(last_seen, ids[valid], stamps[valid])
stale = (last_seen >= 0) & (bundle["time_ns"] - last_seen > 250_000_000)
cells[stale & (cells != 2)] = 3
projected = project_map_points_kb4(
points,
position_map_xyz=position,
orientation_map_from_lidar_xyzw=quaternion,
profile=self.projection,
)
uv = projected.pixels_xy
crop = (uv[:, 0] >= 100) & (uv[:, 0] < 700) & (uv[:, 1] >= 0) & (uv[:, 1] < 600)
point_ids = projected.source_indices[crop]
uv = uv[crop]
labels = mask[
(uv[:, 1] * 512 / 600).astype(int), ((uv[:, 0] - 100) * 512 / 600).astype(int)
]
votes = np.zeros((count, len(self.material_names)), np.int32)
cell_ids = ids[point_ids]
good = (cell_ids >= 0) & (states[point_ids] == 1)
np.add.at(votes, (cell_ids[good], self.material_lut[labels[good]]), 1)
material = votes.argmax(axis=1).astype(np.int32)
# Current and retained geometry can only add a prohibition, never clear TGS.
for obstacle in (*obstacle_map.occupied, *obstacle_map.unknown):
for cell in obstacle.cells:
xy = (
np.asarray((cell.x, cell.y)) + 0.5
) * self.temporal.config.voxel_size_m - position[:2]
index = self.cell_lookup.get(tuple(np.floor(xy / 0.45).astype(int)))
if index is not None:
cells[index] = 2
actions = self.action_lut[material, cells]
return (
cells,
actions,
material,
{
"points": n,
"algorithm_ms": algorithm_ms,
"ground": int(np.count_nonzero(states == 1)),
"occupied": int(np.count_nonzero(states == 2)),
"rejected": int(np.count_nonzero(states == 3)),
"stale_cells": int(np.count_nonzero(stale)),
"state_counts": dict(Counter(int(x) for x in cells)),
},
)
@@ -0,0 +1,41 @@
"""Bounded local probe RPC, compatible with Python 3.9 and 3.12."""
from __future__ import annotations
import json
import struct
MAX_PAYLOAD = 16 * 1024 * 1024
def exact(stream, size):
if not 0 <= size <= MAX_PAYLOAD:
raise ValueError("IPC read exceeds budget")
chunks = bytearray()
while len(chunks) < size:
part = stream.read(size - len(chunks))
if not part:
raise EOFError("truncated IPC message")
chunks.extend(part)
return bytes(chunks)
def receive(stream):
length = struct.unpack("<I", exact(stream, 4))[0]
if not 1 <= length <= 65536:
raise ValueError("IPC header exceeds budget")
header = json.loads(exact(stream, length))
size = header.pop("payload_bytes")
if type(size) is not int:
raise ValueError("invalid IPC byte count")
return header, exact(stream, size)
def send(stream, header, payload=b""):
if len(payload) > MAX_PAYLOAD:
raise ValueError("IPC payload exceeds budget")
raw = json.dumps({**header, "payload_bytes": len(payload)}, allow_nan=False).encode()
if len(raw) > 65536:
raise ValueError("IPC header exceeds budget")
stream.write(struct.pack("<I", len(raw)) + raw + payload)
stream.flush()
@@ -0,0 +1,110 @@
"""Persistent decode OR DDRNet child; never loads an alternative model."""
from __future__ import annotations
import argparse
import importlib.util
import os
import sys
import time
from pathlib import Path
from baseline_ddrnet import digest
from pilot_ddrnet_runtime import DdrnetRuntime
from pilot_ipc import receive, send
def main():
parser = argparse.ArgumentParser()
parser.add_argument("mode", choices=("camera", "ddrnet"))
parser.add_argument("--video", default="/source.mp4")
parser.add_argument("--runner", default="/probe/run_goose_vegetation_benchmark.py")
parser.add_argument("--checkpoint", default="/checkpoint.pth")
parser.add_argument(
"--ddrnet-layout", choices=("reference", "channels-last"), default="reference"
)
parser.add_argument("--ddrnet-execution", choices=("eager", "cuda-graph"), default="eager")
args = parser.parse_args()
output = os.fdopen(os.dup(sys.stdout.fileno()), "wb", buffering=0)
os.dup2(sys.stderr.fileno(), sys.stdout.fileno())
import cv2
import numpy as np
started = time.monotonic_ns()
capture = None
if args.mode == "camera":
capture = cv2.VideoCapture(args.video)
if not capture.isOpened():
raise RuntimeError("camera decoder unavailable")
else:
if digest(Path(args.checkpoint)) != (
"b99c2838051bcd7b092fd3970aa62a77d5c0bbb809c9b9afb2ff4b0ebdaa4ee6"
):
raise RuntimeError("DDRNet checkpoint changed")
if digest(Path(args.runner)) != (
"b18ad60f277eea69a240a28f290611b94627fb9707faf1bb3e6e22102dad67c1"
):
raise RuntimeError("DDRNet preprocessing runner changed")
spec = importlib.util.spec_from_file_location("pinned_goose_runner", args.runner)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
import torch
from PIL import Image
model, _, _ = module.load_model("ddrnet", Path(args.checkpoint))
runtime = DdrnetRuntime(
model, module.logits_from_output, args.ddrnet_layout, args.ddrnet_execution
)
runtime.validate_ties()
warm, _ = module.preprocess(Image.fromarray(np.zeros((600, 800, 3), np.uint8)))
for _ in range(8):
runtime.infer(warm)
torch.cuda.reset_peak_memory_stats()
send(
output,
{
"ready": args.mode,
"warmup_ms": (time.monotonic_ns() - started) / 1e6,
"postprocess_layout": args.ddrnet_layout if args.mode == "ddrnet" else None,
"postprocess_tie_check": args.mode == "ddrnet",
"execution_mode": args.ddrnet_execution if args.mode == "ddrnet" else None,
},
)
try:
while True:
header, payload = receive(sys.stdin.buffer)
if header.get("op") == "stop":
return
begin = time.monotonic_ns()
if args.mode == "camera":
if header != {"op": "next"} or payload:
raise ValueError("invalid decoder operation")
ok, bgr = capture.read()
if not ok or bgr is None or bgr.shape != (600, 800, 3):
raise RuntimeError("camera ended or changed shape")
send(output, {"decode_ms": (time.monotonic_ns() - begin) / 1e6}, bgr.tobytes())
else:
if header != {"op": "infer"} or len(payload) != 600 * 800 * 3:
raise ValueError("invalid DDRNet observation")
bgr = np.frombuffer(payload, np.uint8).reshape(600, 800, 3)
tensor, _ = module.preprocess(Image.fromarray(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)))
preprocess_ms = (time.monotonic_ns() - begin) / 1e6
mask, forward_ms, stages = runtime.infer(tensor)
stages["preprocess_wall_ms"] = preprocess_ms
send(
output,
{
"component_ms": (time.monotonic_ns() - begin) / 1e6,
"forward_ms": forward_ms,
"stages_ms": stages,
"postprocess_layout": args.ddrnet_layout,
},
mask.astype(np.uint8).tobytes(),
)
finally:
if capture is not None:
capture.release()
if __name__ == "__main__":
main()
@@ -0,0 +1,69 @@
"""CPU-only preflight: metadata, one increment, TGS identity and graph wiring."""
import json
import struct
import subprocess
from pathlib import Path
import numpy as np
from pilot_graph import JointGraph
from pilot_ipc import exact
from pilot_source import SensorArchive, camera_events
archive = SensorArchive(Path("/sensor-source.npz"))
try:
point = next(archive.points())
pose = next(archive.poses())
camera = next(camera_events("/camera-index.jsonl", 1))
print(
json.dumps(
{
"first_point": point.time_ns,
"first_pose": pose.time_ns,
"first_camera": camera.time_ns,
"point_shape": point.value[0].shape,
"reads": archive.counters(),
}
),
flush=True,
)
finally:
archive.close()
process = subprocess.Popen(
["/usr/local/bin/pilot-tgs"], stdin=subprocess.PIPE, stdout=subprocess.PIPE
)
try:
grid = np.array(
[(x, y, -1.25, 0) for x in np.linspace(-8, 8, 24) for y in np.linspace(-8, 8, 24)],
dtype="<f4",
)
process.stdin.write(struct.pack("<I", len(grid)) + grid.tobytes())
process.stdin.flush()
n, ms = struct.unpack("<Id", exact(process.stdout, 12))
states = np.frombuffer(exact(process.stdout, n), np.uint8)
assert n == len(grid) and np.all((states >= 1) & (states <= 3))
graph = JointGraph(
"/code",
process,
mask_path="/valid-fov.png",
mapping_path="/goose.csv",
calibration_pack="/calibration.npz",
)
assert np.count_nonzero(graph.action_lut == 0) == 1
assert graph.action_lut[graph.material_names.index("hard_surface"), 1] == 0
graph.backend.close()
print(
json.dumps(
{
"graph_initialized": True,
"tgs_identity_accounted": n,
"tgs_ms": ms,
"cells": len(graph.grid),
}
),
flush=True,
)
finally:
process.stdin.write(struct.pack("<I", 0))
process.stdin.flush()
process.wait(timeout=5)
@@ -0,0 +1,74 @@
"""One producer, one graph, bounded pending queue and active payload accounting."""
from collections import deque
from threading import Condition
class Mailbox:
def __init__(self, capacity=2, byte_limit=16 * 1024 * 1024):
self.capacity = capacity
self.byte_limit = byte_limit
self.condition = Condition()
self.pending = deque()
self.bytes = 0
self.peak_bytes = 0
self.peak_pending = 0
self.external_pending = 0
self.dropped = []
self.done = False
self.error = None
def put(self, bundle):
size = bundle["payload_bytes"]
with self.condition:
while self.pending and (
len(self.pending) + self.external_pending >= self.capacity
or self.bytes + size > self.byte_limit
):
old = self.pending.popleft()
self.bytes -= old["payload_bytes"]
self.dropped.append({"sequence": old["sequence"], "reason": "pending-overflow"})
if len(self.pending) + self.external_pending >= self.capacity:
self.dropped.append({"sequence": bundle["sequence"], "reason": "pending-overflow"})
return
if self.bytes + size > self.byte_limit:
self.dropped.append({"sequence": bundle["sequence"], "reason": "byte-budget"})
return
self.pending.append(bundle)
self.bytes += size
self.peak_bytes = max(self.peak_bytes, self.bytes)
self.peak_pending = max(self.peak_pending, len(self.pending) + self.external_pending)
self.condition.notify_all()
def reserve_completed(self):
"""A finished GPU result shares the SAME pending budget as ingress."""
with self.condition:
if self.external_pending:
raise ValueError("only one completed GPU slot is permitted")
while len(self.pending) + 1 > self.capacity:
old = self.pending.popleft()
self.bytes -= old["payload_bytes"]
self.dropped.append({"sequence": old["sequence"], "reason": "handoff-overflow"})
self.external_pending = 1
self.peak_pending = max(self.peak_pending, len(self.pending) + 1)
def take_completed(self):
with self.condition:
if self.external_pending != 1:
raise ValueError("completed GPU slot accounting mismatch")
self.external_pending = 0
def take(self):
with self.condition:
self.condition.wait_for(lambda: self.pending or self.done)
return self.pending.popleft() if self.pending else None
def release(self, bundle):
with self.condition:
self.bytes -= bundle["payload_bytes"]
def finish(self, error=None):
with self.condition:
self.done = True
self.error = error
self.condition.notify_all()
@@ -0,0 +1,61 @@
"""One serial GPU stage can overlap one chronological CPU fusion stage.
No GPU model concurrency. Ingress and completed-GPU results share two pending
slots. Active payloads remain in the shared mailbox byte budget.
"""
import queue
import threading
import traceback
class GpuStage:
def __init__(self, mailbox, compute, stop):
self.mailbox = mailbox
self.compute = compute
self.stop = stop
self.output = queue.Queue(maxsize=1)
# Reserve the output slot BEFORE starting another GPU call. Otherwise a
# blocked put would hide a third pending frame outside the two queues.
self.output_slot = threading.Semaphore(1)
self.finished = threading.Event()
self.error = None
self.peak_pending = 0
self.thread = threading.Thread(target=self._run, daemon=True)
self.thread.start()
def _run(self):
try:
while not self.stop.is_set():
if not self.output_slot.acquire(timeout=0.05):
continue
bundle = self.mailbox.take()
if bundle is None:
break
result = self.compute(bundle)
self.mailbox.reserve_completed()
self.output.put_nowait((bundle, result))
self.peak_pending = max(self.peak_pending, self.output.qsize())
except Exception:
self.error = traceback.format_exc()
finally:
self.finished.set()
def take(self):
while True:
try:
result = self.output.get(timeout=0.05)
self.mailbox.take_completed()
self.output_slot.release()
return result
except queue.Empty:
if self.finished.is_set():
if self.error:
raise RuntimeError(self.error) from None
return None
def close(self):
self.stop.set()
self.mailbox.finish(self.mailbox.error)
self.thread.join(timeout=2)
return not self.thread.is_alive()
@@ -0,0 +1,154 @@
"""Incremental existing normalized sensor archive; no NPZ materialization.
Only original capture clocks/points/pose are read. No camera-indexed E10
nearest-neighbor association, surface NPZ, masks, TGS outputs or threat ledger.
One-row lookahead belongs to the source reader, never to perception providers.
"""
from __future__ import annotations
import heapq
import json
import math
import zipfile
from dataclasses import dataclass
from pathlib import Path
import numpy as np
class NpyRows:
def __init__(self, archive, name, *, columns=(), dtype=None):
self.stream = archive.open(name + ".npy")
version = np.lib.format.read_magic(self.stream)
if version == (1, 0):
shape, fortran, actual = np.lib.format.read_array_header_1_0(self.stream)
elif version == (2, 0):
shape, fortran, actual = np.lib.format.read_array_header_2_0(self.stream)
else:
raise ValueError("unsupported bounded NPY header")
if fortran or actual.hasobject or tuple(shape[1:]) != columns:
raise ValueError("sensor archive layout changed")
if dtype is not None and actual != np.dtype(dtype):
raise ValueError("sensor archive dtype changed")
self.count = shape[0]
self.columns = columns
self.dtype = actual
self.row_bytes = actual.itemsize * math.prod(columns)
self.position = 0
self.bytes_read = 0
def take(self, count=1):
size = count * self.row_bytes
if count < 0 or self.position + count > self.count or size > 8 * 1024 * 1024:
raise ValueError("sensor row exceeds source budget")
raw = self.stream.read(size)
if len(raw) != size:
raise EOFError("truncated sensor array")
self.position += count
self.bytes_read += size
return np.frombuffer(raw, self.dtype).reshape((count, *self.columns))
@dataclass(frozen=True)
class SensorEvent:
time_ns: int
channel: str
sequence: int
value: object
class SensorArchive:
def __init__(self, path: Path):
self.archive = zipfile.ZipFile(path)
self.readers = {}
def rows(self, name, **kwargs):
reader = NpyRows(self.archive, name, **kwargs)
self.readers[name] = reader
return reader
def points(self):
times = self.rows("point_received_monotonic_ns", dtype="<i8")
seqs = self.rows("point_capture_sequence", dtype="<i8")
offsets = self.rows("point_offsets", dtype="<i8")
xyz = self.rows("point_xyz_map", columns=(3,), dtype="<f8")
intensity = self.rows("point_intensity", dtype="u1")
begin = int(offsets.take()[0])
if begin != 0:
raise ValueError("point offsets do not start at zero")
previous = -1
for _ in range(times.count):
stamp = int(times.take()[0])
sequence = int(seqs.take()[0])
end = int(offsets.take()[0])
if stamp < previous or not 0 <= end - begin <= 50000:
raise ValueError("point clock/size outside source bounds")
points = xyz.take(end - begin)
intensities = intensity.take(end - begin)
if not np.isfinite(points).all():
raise ValueError("nonfinite source cloud")
yield SensorEvent(stamp, "points", sequence, (points, intensities))
begin, previous = end, stamp
def poses(self):
times = self.rows("pose_received_monotonic_ns", dtype="<i8")
seqs = self.rows("pose_capture_sequence", dtype="<i8")
positions = self.rows("pose_positions_map", columns=(3,), dtype="<f8")
quats = self.rows("pose_quaternions_map_from_lidar", columns=(4,), dtype="<f8")
previous = -1
for _ in range(times.count):
stamp = int(times.take()[0])
if stamp < previous:
raise ValueError("pose clock moved backwards")
position, quaternion = positions.take()[0], quats.take()[0]
if (
not np.isfinite(position).all()
or not np.isfinite(quaternion).all()
or abs(float(np.linalg.norm(quaternion)) - 1.0) > 0.01
):
raise ValueError("invalid source pose")
yield SensorEvent(stamp, "pose", int(seqs.take()[0]), (position, quaternion))
previous = stamp
def counters(self):
return {
name: {"rows_read": r.position, "bytes_read": r.bytes_read, "source_rows": r.count}
for name, r in self.readers.items()
}
def close(self):
for reader in self.readers.values():
reader.stream.close()
self.archive.close()
def camera_events(path, limit):
previous = -1
with Path(path).open("rb") as stream:
for index in range(limit):
raw = stream.readline(65537)
if not raw or len(raw) > 65536:
raise ValueError("camera index is truncated or unbounded")
row = json.loads(raw)
if (
row.get("schema_version") != "missioncore.camera-recording-index/v1"
or row.get("kind") != "media"
or row.get("sequence") != index + 1
):
raise ValueError("camera source identity/order changed")
stamp = row["host_monotonic_ns"]
if type(stamp) is not int or stamp <= previous:
raise ValueError("camera source clock is not increasing")
yield SensorEvent(stamp, "camera", index, row)
previous = stamp
def merged_events(archive, camera_index, limit):
# Stable per-channel order; a tie admits sensor data before the camera.
return heapq.merge(
archive.poses(),
archive.points(),
camera_events(camera_index, limit),
key=lambda event: event.time_ns,
)
@@ -0,0 +1,62 @@
// Persistent bounded TGS adapter. stdin: uint32 count + XYZ-intensity float32.
// Original point identity survives segmentation in PointXYZILID::id (<=64000).
// stdout: uint32 count + double algorithm_ms + uint8 state per input point.
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <stdexcept>
#include <unistd.h>
#include <vector>
#include "travel/point_types.hpp"
#include "travel/tgs.hpp"
int main() {
FILE* protocol = fdopen(dup(STDOUT_FILENO), "wb");
dup2(STDERR_FILENO, STDOUT_FILENO); // TGS diagnostics cannot corrupt RPC.
try {
std::uint32_t count;
while (std::fread(&count, sizeof(count), 1, stdin) == 1) {
if (count == 0) break;
if (count > 64000) throw std::runtime_error("TGS point budget exceeded");
std::vector<float> data(static_cast<std::size_t>(count) * 4);
if (std::fread(data.data(), sizeof(float), data.size(), stdin) != data.size())
throw std::runtime_error("truncated TGS observation");
travel::PointCloud<PointXYZILID> input, ground, nonground;
input.reserve(count);
for (std::uint32_t index = 0; index < count; ++index) {
PointXYZILID p{};
p.x = data[index*4]; p.y = data[index*4+1]; p.z = data[index*4+2];
p.intensity = data[index*4+3]; p.id = static_cast<std::uint16_t>(index);
if (!std::isfinite(p.x) || !std::isfinite(p.y) || !std::isfinite(p.z))
throw std::runtime_error("nonfinite TGS input");
input.push_back(p);
}
double seconds = 0;
travel::TravelGroundSeg<PointXYZILID> tgs;
tgs.setParams(80.0, 1.0, 8.0, 3, 5, 10, 0.5, 0.125, 0.3, 0.940,
200.0, 0.03, 0.1, 1.0, true, false);
tgs.estimateGround(input, ground, nonground, seconds);
std::vector<std::uint8_t> states(count, 3); // Rejected != unobserved/free.
for (const auto& p : ground.points) {
if (p.id >= count || states[p.id] != 3)
throw std::runtime_error("TGS ground identity collision");
states[p.id] = 1;
}
for (const auto& p : nonground.points) {
if (p.id >= count || states[p.id] != 3)
throw std::runtime_error("TGS nonground identity collision");
states[p.id] = 2;
}
const double ms = seconds * 1000.0;
if (std::fwrite(&count, sizeof(count), 1, protocol) != 1 ||
std::fwrite(&ms, sizeof(ms), 1, protocol) != 1 ||
std::fwrite(states.data(), 1, count, protocol) != count)
throw std::runtime_error("TGS result transport failed");
std::fflush(protocol);
}
std::fclose(protocol);
} catch (const std::exception& e) {
std::fprintf(stderr, "TGS pilot: %s\n", e.what());
return 1;
}
}
@@ -0,0 +1,9 @@
name: "rf_detr_large_native_kb4"
platform: "tensorrt_plan"
max_batch_size: 0
input [{ name: "raw_kb4_bgr" data_type: TYPE_UINT8 dims: [1,600,800,3] }]
output [
{ name: "dets" data_type: TYPE_FP16 dims: [1,300,4] },
{ name: "labels" data_type: TYPE_FP16 dims: [1,300,91] }
]
instance_group [{ count: 1 kind: KIND_GPU gpus: [0] }]
@@ -0,0 +1,605 @@
"""Bounded source-paced Worker pilot, not an installed or qualified profile.
Only persistent DDRNet and RF-DETR share the GPU; inference is serialized.
Source is paced independently of the graph, using original host arrival times.
The in-container collector is measured; network to Mission Core is NOT measured.
"""
from __future__ import annotations
import argparse
import hashlib
import http.client
import json
import math
import os
import signal
import subprocess
import threading
import time
import traceback
from collections import Counter, deque
from dataclasses import asdict
from datetime import UTC, datetime
from pathlib import Path
import numpy as np
from pilot_ipc import receive, send
from pilot_queue import Mailbox
from pilot_scheduler import GpuStage
from pilot_source import SensorArchive, camera_events, merged_events
def distribution(values):
if not values:
return None
values = sorted(values)
return {
"count": len(values),
"mean": sum(values) / len(values),
"min": values[0],
"p50": values[math.ceil(len(values) * 0.5) - 1],
"p95": values[math.ceil(len(values) * 0.95) - 1],
"p99": values[math.ceil(len(values) * 0.99) - 1],
"max": values[-1],
}
def payload_size(bundle):
return (
sum(bundle[key].nbytes for key in ("image", "points", "rolling_points", "rolling_times"))
+ 4096
)
def produce(args, decoder, mailbox, stop, report):
archive = SensorArchive(Path(args.sensor_archive))
first_camera = next(camera_events(args.camera_index, args.frames)).time_ns
source_zero = first_camera - 500_000_000
wall_zero = time.monotonic_ns() + 50_000_000
report.update(
source_zero_ns=source_zero,
wall_zero_ns=wall_zero,
first_camera_source_ns=first_camera,
source_clock_speed=1.0,
source_eof_required=False,
full_source_prepass=False,
)
pose = None
rolling = deque()
fresh = []
arrivals = Counter()
release_lags = []
skipped_prefix = Counter()
try:
for event in merged_events(archive, args.camera_index, args.frames):
if stop.is_set():
break
if event.time_ns < source_zero:
skipped_prefix[event.channel] += 1
continue
due = wall_zero + event.time_ns - source_zero
if stop.wait(max(0.0, (due - time.monotonic_ns()) / 1e9)):
break
arrived = time.monotonic_ns()
release_lags.append(max(0, arrived - due) / 1e6)
arrivals[event.channel] += 1
while rolling and event.time_ns - rolling[0].time_ns > 1_000_000_000:
rolling.popleft()
if event.channel == "pose":
pose = event
continue
if event.channel == "points":
rolling.append(event)
fresh.append(event)
if sum(len(e.value[0]) for e in rolling) > 64000:
raise ValueError("raw rolling cloud exceeds bounded 64000-point window")
continue
# Decoder reads ONE frame after its original due time, never full-decodes.
decode_start = time.monotonic_ns()
send(decoder.stdin, {"op": "next"})
decoded, raw = receive(decoder.stdout)
image = np.frombuffer(raw, np.uint8).reshape(600, 800, 3)
points = np.concatenate([e.value[0] for e in fresh]) if fresh else np.empty((0, 3))
rolling_points = (
np.concatenate([e.value[0] for e in rolling]) if rolling else np.empty((0, 3))
)
rolling_times = (
np.concatenate([np.full(len(e.value[0]), e.time_ns, np.int64) for e in rolling])
if rolling
else np.empty(0, np.int64)
)
pose_age = event.time_ns - pose.time_ns if pose else None
point_age = event.time_ns - fresh[-1].time_ns if fresh else None
oldest_age = event.time_ns - fresh[0].time_ns if fresh else None
binding_age = (
max(abs(e.time_ns - pose.time_ns) for e in fresh) if fresh and pose else None
)
available = bool(
len(points)
and pose
and 0 <= pose_age <= 100_000_000
and 0 <= point_age <= 100_000_000
and oldest_age <= 250_000_000
and binding_age <= 100_000_000
)
bundle = {
"sequence": event.sequence,
"time_ns": event.time_ns,
"source_ns": event.time_ns - source_zero,
"due_ns": due,
"utc_ns": event.value["host_epoch_ns"],
"image": image,
"points": points,
"rolling_points": rolling_points,
"rolling_times": rolling_times,
"pose": pose.value if pose else None,
"available": available,
"binding_age_ms": binding_age / 1e6 if binding_age is not None else None,
"lineage": {
"camera_index_sequence": event.value["sequence"],
"camera_host_monotonic_ns": event.time_ns,
"pose_sequence": pose.sequence if pose else None,
"pose_host_monotonic_ns": pose.time_ns if pose else None,
"point_increments": [
{
"sequence": e.sequence,
"host_monotonic_ns": e.time_ns,
"points": len(e.value[0]),
}
for e in fresh
],
"pose_age_ms": pose_age / 1e6 if pose_age is not None else None,
"newest_point_age_ms": point_age / 1e6 if point_age is not None else None,
"oldest_point_age_ms": oldest_age / 1e6 if oldest_age is not None else None,
},
"source_release_lag_ms": max(0, arrived - due) / 1e6,
"decode_ms": decoded["decode_ms"],
"decode_rpc_ms": (time.monotonic_ns() - decode_start) / 1e6,
"enqueued_ns": time.monotonic_ns(),
}
bundle["payload_bytes"] = payload_size(bundle)
mailbox.put(bundle)
fresh = []
report["last_camera_due_ns"] = due
if arrivals["camera"] >= args.frames:
break
except Exception:
mailbox.finish(traceback.format_exc())
finally:
report.update(
arrivals=dict(arrivals),
skipped_prefix=dict(skipped_prefix),
release_lag_ms=distribution(release_lags),
incremental_reads=archive.counters(),
window_end_monotonic_ns=time.monotonic_ns(),
)
archive.close()
mailbox.finish(mailbox.error)
def telemetry(stop, samples):
while not stop.is_set():
sample = {"monotonic_ns": time.monotonic_ns()}
try:
result = subprocess.run(
[
"nvidia-smi",
"--query-gpu=memory.used,utilization.gpu",
"--format=csv,noheader,nounits",
],
capture_output=True,
text=True,
timeout=2,
check=True,
)
mem, util = result.stdout.strip().split(",")
sample.update(gpu_used_mib=int(mem), gpu_utilization=int(util))
sample["cgroup_memory_mib"] = (
int(Path("/sys/fs/cgroup/memory.current").read_text()) / 1048576
)
sample["cpu_stat"] = {
key: int(value)
for key, value in (
line.split()
for line in Path("/sys/fs/cgroup/cpu.stat").read_text().splitlines()
)
}
except Exception as error:
sample["error"] = str(error)
samples.append(sample)
stop.wait(0.5)
def wait_triton(process, seconds=90):
deadline = time.monotonic() + seconds
while time.monotonic() < deadline:
if process.poll() is not None:
raise RuntimeError("Triton exited during initialization")
connection = http.client.HTTPConnection("127.0.0.1", 8000, timeout=1)
try:
connection.request("GET", "/v2/models/rf_detr_large_native_kb4/ready")
if connection.getresponse().status == 200:
return
except OSError:
pass
finally:
connection.close()
time.sleep(0.1)
raise TimeoutError("Triton initialization exceeded budget")
def run(args):
output = Path(args.output)
output.mkdir(parents=True, exist_ok=False)
started = time.monotonic_ns()
report = {
"schema_version": "missioncore.stage1-joint-pilot/v1",
"run_id": args.run_id,
"started_utc": datetime.now(UTC).isoformat(),
"started_monotonic_ns": started,
"requested_frames": args.frames,
"profile": "K1 Perception — DDRNet-39 + RF-DETR + TGS",
"scope": "one-container-worker-graph-to-local-collector",
"external_transport_measured": False,
"standalone_release": False,
"authority": {"commands_enabled": False, "actuation_allowed": False},
"effective_policy": "hard-surface-only-plus-geometry-TGS-stale-no-go",
"body_frame": "causal-camera-forward-simulation; no future trajectory",
"clock_quality": "original host arrival best effort; not hardware synchronization",
"ddrnet_postprocess_layout": args.ddrnet_layout,
"ddrnet_execution": args.ddrnet_execution,
"schedule": args.schedule,
}
children, logs, results, samples = [], [], [], []
stop = threading.Event()
mailbox = Mailbox(capacity=2)
source_report = {}
producer = monitor = graph = gpu_stage = None
def child(name, command, env=None):
log = (output / (name + ".log")).open("wb")
logs.append(log)
process = subprocess.Popen(
command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=log,
env=env,
start_new_session=True,
)
children.append(process)
return process
def timeout_handler(signum, frame):
raise TimeoutError("joint pilot wall-clock watchdog fired")
previous = signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(240)
try:
triton = child(
"triton",
[
"tritonserver",
"--model-repository=/models",
"--model-control-mode=explicit",
"--load-model=rf_detr_large_native_kb4",
"--allow-grpc=false",
"--allow-metrics=false",
"--http-address=127.0.0.1",
"--pinned-memory-pool-byte-size=16777216",
"--cuda-memory-pool-byte-size=0:16777216",
],
)
# Triton logs stdout too: drain directly to the same bounded-run log.
threading.Thread(target=lambda: drain(triton.stdout, logs[0]), daemon=True).start()
wait_triton(triton)
python = "/opt/conda/envs/goose/bin/python"
ddr = child(
"ddrnet",
[
python,
"-B",
"/probe/pilot_model.py",
"ddrnet",
"--ddrnet-layout",
args.ddrnet_layout,
"--ddrnet-execution",
args.ddrnet_execution,
],
{**os.environ, "PYTHONPATH": "/probe"},
)
report["ddrnet_ready"], _ = receive(ddr.stdout)
decoder = child(
"decoder",
[python, "-B", "/probe/pilot_model.py", "camera"],
{**os.environ, "PYTHONPATH": "/probe", "CUDA_VISIBLE_DEVICES": ""},
)
report["decoder_ready"], _ = receive(decoder.stdout)
tgs = child("tgs", ["/usr/local/bin/pilot-tgs"])
from pilot_graph import JointGraph
graph = JointGraph(
"/code",
tgs,
mask_path="/valid-fov.png",
mapping_path="/goose.csv",
calibration_pack="/calibration.npz",
)
report["rfdetr_warmup"] = asdict(graph.detector.warm_up())
report["warmup_ms"] = (time.monotonic_ns() - started) / 1e6
report["costmap_grid"] = graph.grid.tolist()
report["material_names"] = graph.material_names
def compute_gpu(bundle):
begin = time.monotonic_ns()
send(ddr.stdin, {"op": "infer"}, bundle["image"].tobytes())
ddr_result, raw = receive(ddr.stdout)
mask = np.frombuffer(raw, np.uint8).reshape(512, 512)
ddr_done = time.monotonic_ns()
proposals = graph.detector.detect(graph.packet(bundle))
gpu_done = time.monotonic_ns()
return begin, ddr_done, gpu_done, ddr_result, mask, proposals
monitor = threading.Thread(target=telemetry, args=(stop, samples), daemon=True)
monitor.start()
producer = threading.Thread(
target=produce, args=(args, decoder, mailbox, stop, source_report), daemon=True
)
producer.start()
if args.schedule == "overlap-cpu":
gpu_stage = GpuStage(mailbox, compute_gpu, stop)
with (output / "scenes.jsonl").open("wb") as sink:
while True:
if gpu_stage:
item = gpu_stage.take()
if item is None:
break
bundle, computed = item
else:
bundle = mailbox.take()
if bundle is None:
break
computed = compute_gpu(bundle)
begin, ddr_done, gpu_done, ddr_result, mask, proposals = computed
cpu_started = time.monotonic_ns()
scene = graph.process(
bundle,
mask,
proposals=proposals,
detector_ms=(gpu_done - ddr_done) / 1e6,
)
# Late evidence remains inspectable but cannot authorize terrain.
scene["oldest_required_input_age_ms"] = (
time.monotonic_ns() - bundle["due_ns"]
) / 1e6 + max(
bundle["lineage"]["pose_age_ms"] or 0,
bundle["lineage"]["oldest_point_age_ms"] or 0,
)
scene["stale_at_publication"] = scene["oldest_required_input_age_ms"] > 250
if scene["stale_at_publication"]:
scene["policy_actions"] = [2] * len(scene["policy_actions"])
scene["policy_counts"] = {
"ALLOW_candidate": 0,
"HIGH_COST": 0,
"NO_GO": len(scene["policy_actions"]),
}
scene.update(
sequence=bundle["sequence"],
lineage=bundle["lineage"],
available=bundle["available"],
original_source_ns=bundle["time_ns"],
)
encoded = json.dumps(scene, allow_nan=False, separators=(",", ":")).encode()
if len(encoded) > 1024 * 1024:
raise ValueError("scene exceeds bounded collector message budget")
# Actual bounded local receiver parse. Durable export excluded below.
received = json.loads(encoded)
if received["sequence"] != bundle["sequence"]:
raise ValueError("collector identity mismatch")
finished = time.monotonic_ns()
timing = {
**scene["timing_ms"],
**{"ddrnet_" + key: value for key, value in ddr_result["stages_ms"].items()},
"ddrnet_rpc_ms": (ddr_done - begin) / 1e6,
"ddrnet_component_ms": ddr_result["component_ms"],
"ddrnet_forward_ms": ddr_result["forward_ms"],
"decode_ms": bundle["decode_ms"],
"decode_rpc_ms": bundle["decode_rpc_ms"],
"source_release_lag_ms": bundle["source_release_lag_ms"],
"queue_wait_ms": (begin - bundle["enqueued_ns"]) / 1e6,
"gpu_to_cpu_queue_wait_ms": (cpu_started - gpu_done) / 1e6,
"cpu_tail_to_receiver_ms": (finished - cpu_started) / 1e6,
"compute_to_receiver_ms": (finished - begin) / 1e6,
"source_due_to_receiver_ms": (finished - bundle["due_ns"]) / 1e6,
}
result = {
"sequence": bundle["sequence"],
"finished_monotonic_ns": finished,
"timing_ms": timing,
"available": bundle["available"],
"surface_state": scene["surface_state"],
"proposal_count": len(scene["proposals"]),
"observation_count": len(scene["observations"]),
"track_count": len(scene["tracks"]),
"metric_count": sum(
x["metric_geometry"] is not None for x in scene["observations"]
),
"tgs_counts": scene["tgs_counts"],
"policy_counts": scene["policy_counts"],
"scene_bytes": len(encoded),
"scene_sha256": hashlib.sha256(encoded).hexdigest(),
}
results.append(result)
mailbox.release(bundle)
sink.write(encoded + b"\n")
if len(results) == 1:
report["reads_at_first_result"] = {
"results": 1,
"source_eof_reached": False,
"source_end_window_reached": mailbox.done,
}
if len(results) % 16 == 0:
print(
json.dumps(
{
"completed": len(results),
"last_sequence": bundle["sequence"],
"last_age_ms": timing["source_due_to_receiver_ms"],
"drops": len(mailbox.dropped),
}
),
flush=True,
)
if mailbox.error:
raise RuntimeError(mailbox.error)
report["execution_complete"] = True
except Exception:
report["execution_complete"] = False
report["error"] = traceback.format_exc()
print(report["error"], flush=True)
finally:
signal.alarm(0)
signal.signal(signal.SIGALRM, previous)
stop.set()
shutdown_start = time.monotonic_ns()
for process in reversed(children):
if process.poll() is None:
os.killpg(process.pid, signal.SIGTERM)
deadline = time.monotonic() + 4
for process in reversed(children):
try:
process.wait(timeout=max(0.01, deadline - time.monotonic()))
except subprocess.TimeoutExpired:
os.killpg(process.pid, signal.SIGKILL)
process.wait(timeout=1)
if producer:
producer.join(timeout=2)
if monitor:
monitor.join(timeout=2)
report["gpu_stage_stopped"] = gpu_stage.close() if gpu_stage else True
if graph:
graph.backend.close()
for log in logs:
log.close()
report["stop_ms"] = (time.monotonic_ns() - shutdown_start) / 1e6
report["children_stopped"] = all(p.poll() is not None for p in children)
report["source"] = source_report
report["frames"] = results
report["telemetry"] = samples
report["queue"] = {
"capacity": mailbox.capacity,
"gpu_completed_capacity": 1 if gpu_stage else 0,
"completed_shares_pending_limit": bool(gpu_stage),
"global_pending_limit": 2,
"gpu_peak_pending": gpu_stage.peak_pending if gpu_stage else 0,
"byte_limit": mailbox.byte_limit,
"peak_pending": mailbox.peak_pending,
"peak_bytes": mailbox.peak_bytes,
"drops": mailbox.dropped,
"residual_bytes": mailbox.bytes,
"residual_completed": mailbox.external_pending,
}
report["distributions_ms"] = (
{
key: distribution([r["timing_ms"][key] for r in results])
for key in results[0]["timing_ms"]
}
if results
else {}
)
camera_count = source_report.get("arrivals", {}).get("camera", 0)
report["accounting"] = {
"released": camera_count,
"completed": len(results),
"dropped": len(mailbox.dropped),
"unaccounted": camera_count - len(results) - len(mailbox.dropped),
}
latency = report["distributions_ms"].get("source_due_to_receiver_ms")
queue_lags = [
r["timing_ms"]["queue_wait_ms"] + r["timing_ms"]["gpu_to_cpu_queue_wait_ms"]
for r in results
]
growth = (
max(
0.0,
sum(queue_lags[-8:]) / len(queue_lags[-8:]) - sum(queue_lags[:8]) / len(queue_lags[:8]),
)
if queue_lags
else None
)
report["backlog_growth_ms"] = growth
report["backlog_growth_basis"] = "ingress-plus-completed-GPU-wait-last8-minus-first8"
first_ms = (
((results[0]["finished_monotonic_ns"] - source_report["wall_zero_ns"]) / 1e6)
if results
else None
)
report["first_result_from_stream_start_ms"] = first_ms
report["gates"] = {
"execution": report["execution_complete"],
"zero_drops_complete_accounting": camera_count == args.frames == len(results)
and not mailbox.dropped,
"worker_p95_p99_125ms": bool(latency and latency["p95"] <= 125 and latency["p99"] <= 125),
"source_release_lag_25ms": bool(
source_report.get("release_lag_ms") and source_report["release_lag_ms"]["max"] <= 25
),
"backlog_growth_25ms": growth is not None and growth <= 25,
"first_result_1s": first_ms is not None and first_ms <= 1000,
"warmup_120s": report.get("warmup_ms", math.inf) <= 120000,
"stop_5s": report["stop_ms"] <= 5000
and report["children_stopped"]
and report["gpu_stage_stopped"],
"vram_22000MiB": bool(samples)
and max(s.get("gpu_used_mib", 99999) for s in samples) <= 22000,
"container_memory_8192MiB": bool(samples)
and max(s.get("cgroup_memory_mib", 99999) for s in samples) <= 8192,
"all_modalities_fresh": len(results) == args.frames
and all(r["available"] for r in results),
"network_end_to_end_qualified": False,
}
report["profile_realtime_qualified"] = False
(output / "report.json").write_text(json.dumps(report, indent=2, allow_nan=False) + "\n")
print(
json.dumps(
{
key: report[key]
for key in (
"run_id",
"execution_complete",
"accounting",
"gates",
"distributions_ms",
)
}
),
flush=True,
)
return 0 if report["execution_complete"] else 1
def drain(stream, sink):
while True:
raw = stream.read(4096)
if not raw:
break
sink.write(raw)
sink.flush()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--frames", type=int, default=128)
parser.add_argument("--run-id", required=True)
parser.add_argument("--output", required=True)
parser.add_argument("--sensor-archive", default="/sensor-source.npz")
parser.add_argument("--camera-index", default="/camera-index.jsonl")
parser.add_argument(
"--ddrnet-layout", choices=("reference", "channels-last"), default="reference"
)
parser.add_argument("--ddrnet-execution", choices=("eager", "cuda-graph"), default="eager")
parser.add_argument("--schedule", choices=("serial", "overlap-cpu"), default="serial")
args = parser.parse_args()
if not 1 <= args.frames <= 256:
parser.error("pilot window must be 1..256 frames")
raise SystemExit(run(args))
+216
View File
@@ -0,0 +1,216 @@
"""Small synthetic checks only; model/real-source runs belong on Worker 006."""
import importlib
import io
import json
import threading
import zipfile
from pathlib import Path
import numpy as np
import pytest
@pytest.fixture
def pilot(monkeypatch):
root = Path(__file__).resolve().parents[1]
monkeypatch.syspath_prepend(
str(root / "experiments/perception/worker/streaming_profile_stage1")
)
return lambda name: importlib.import_module(name)
def test_pending_overflow_is_explicit_and_does_not_evict_active(pilot):
queue = pilot("pilot_queue").Mailbox(capacity=2, byte_limit=100)
def make(sequence):
return {"sequence": sequence, "payload_bytes": 10}
queue.put(make(0))
active = queue.take()
for sequence in (1, 2, 3):
queue.put(make(sequence))
assert queue.dropped == [{"sequence": 1, "reason": "pending-overflow"}]
assert queue.bytes == 30
assert queue.peak_pending == 2
queue.release(active)
assert queue.take()["sequence"] == 2
assert queue.take()["sequence"] == 3
def test_active_bytes_count_towards_memory_limit(pilot):
queue = pilot("pilot_queue").Mailbox(byte_limit=20)
queue.put({"sequence": 0, "payload_bytes": 20})
active = queue.take()
queue.put({"sequence": 1, "payload_bytes": 1})
assert queue.dropped == [{"sequence": 1, "reason": "byte-budget"}]
assert queue.peak_bytes == 20
queue.release(active)
queue.finish()
assert queue.take() is None
def test_numpy_member_is_read_incrementally_and_bounded(pilot):
data = io.BytesIO()
np.savez_compressed(data, points=np.arange(300, dtype="<f8").reshape(100, 3))
data.seek(0)
with zipfile.ZipFile(data) as archive:
rows = pilot("pilot_source").NpyRows(archive, "points", columns=(3,), dtype="<f8")
np.testing.assert_array_equal(rows.take(2), np.arange(6).reshape(2, 3))
assert rows.count == 100 and rows.position == 2 and rows.bytes_read == 48
with pytest.raises(ValueError, match="budget"):
rows.take(99)
def test_original_camera_clock_not_fixed_frame_rate(pilot, tmp_path):
path = tmp_path / "camera.jsonl"
stamps = [123000, 127777, 987654]
rows = [
{
"schema_version": "missioncore.camera-recording-index/v1",
"kind": "media",
"sequence": i + 1,
"host_monotonic_ns": stamp,
}
for i, stamp in enumerate(stamps)
]
path.write_text("\n".join(json.dumps(row) for row in rows))
events = list(pilot("pilot_source").camera_events(path, 2))
assert [e.time_ns for e in events] == stamps[:2]
assert [e.sequence for e in events] == [0, 1]
def test_ipc_preserves_binary_and_rejects_oversized_header(pilot):
ipc = pilot("pilot_ipc")
stream = io.BytesIO()
ipc.send(stream, {"op": "infer"}, b"\x00\xff")
stream.seek(0)
assert ipc.receive(stream) == ({"op": "infer"}, b"\x00\xff")
with pytest.raises(ValueError, match="header"):
ipc.receive(io.BytesIO((65537).to_bytes(4, "little")))
def test_nearest_rank_tail_metrics_keep_outlier(pilot):
metrics = pilot("run_joint_pilot").distribution([1] * 99 + [200])
assert metrics["p99"] == 1
assert metrics["max"] == 200
assert pilot("run_joint_pilot").distribution([1, 200])["p99"] == 200
def test_body_history_is_bounded_and_never_reads_future(pilot):
store = pilot("pilot_graph").CurrentStore(None)
for index in range(100):
store.frame_id = f"frame-{index:06d}"
store.body = index
store.remember_body()
assert len(store.body_history) == 64
assert store.body_frame_for_frame("frame-000098") == 98
assert store.body_frame_for_frame("frame-000000") is None
with pytest.raises(ValueError, match="future"):
store.body_frame_for_frame("frame-000100")
def test_vectorized_grid_lookup_preserves_exact_cells_and_holes(pilot):
grid = np.asarray([[-2, -1], [0, 0], [2, 1]])
points = np.asarray([[x, y] for x in range(-5, 6) for y in range(-5, 6)])
lookup = {tuple(row): i for i, row in enumerate(grid)}
expected = np.asarray([lookup.get(tuple(row), -1) for row in points])
np.testing.assert_array_equal(pilot("pilot_graph").grid_indices(points, grid), expected)
def test_ddrnet_layout_preserves_class_order_and_ties(pilot):
class Scores:
def __init__(self, array):
self.array = array
def permute(self, *axes):
return Scores(self.array.transpose(axes))
def contiguous(self):
return Scores(np.ascontiguousarray(self.array))
# Include saturated/equal probabilities: first class must win every tie.
scores = Scores(np.array([[[[1.0, 0.5]], [[1.0, 0.5]], [[0.0, 0.9]], [[1.0, 0.9]]]]))
function = pilot("pilot_ddrnet_runtime").layout_scores
reference, reference_dim = function(scores, "reference")
candidate, candidate_dim = function(scores, "channels-last")
np.testing.assert_array_equal(
reference.array.argmax(axis=reference_dim), candidate.array.argmax(axis=candidate_dim)
)
np.testing.assert_array_equal(candidate.array.argmax(axis=candidate_dim), [[[0, 2]]])
assert candidate.array.flags.c_contiguous
with pytest.raises(ValueError, match="unknown"):
function(scores, "silent-change")
def test_gpu_stage_preserves_order_and_reserves_bounded_output_before_compute(pilot):
mailbox = pilot("pilot_queue").Mailbox(capacity=2, byte_limit=30)
started = [threading.Event(), threading.Event()]
stop = threading.Event()
def compute(bundle):
started[bundle["sequence"]].set()
return bundle["sequence"] * 10
stage = pilot("pilot_scheduler").GpuStage(mailbox, compute, stop)
try:
mailbox.put({"sequence": 0, "payload_bytes": 10})
assert started[0].wait(1)
mailbox.put({"sequence": 1, "payload_bytes": 10})
mailbox.finish()
assert not started[1].wait(0.05) # No hidden completed third slot.
assert mailbox.bytes == 20 # GPU completion cannot release CPU-owned input.
first, result = stage.take()
assert (first["sequence"], result) == (0, 0)
assert started[1].wait(1)
second, result = stage.take()
assert (second["sequence"], result) == (1, 10)
assert mailbox.bytes == 20
mailbox.release(first)
mailbox.release(second)
assert stage.take() is None
assert mailbox.bytes == 0 and not mailbox.dropped
assert stage.peak_pending <= 1
finally:
assert stage.close()
def test_gpu_stage_propagates_failure_and_stops_waiting_for_input(pilot):
mailbox = pilot("pilot_queue").Mailbox(capacity=1)
def compute(bundle):
raise ValueError("synthetic GPU failure")
stage = pilot("pilot_scheduler").GpuStage(mailbox, compute, threading.Event())
mailbox.put({"sequence": 0, "payload_bytes": 10})
try:
with pytest.raises(RuntimeError, match="synthetic GPU failure"):
stage.take()
finally:
assert stage.close()
waiting = pilot("pilot_scheduler").GpuStage(
pilot("pilot_queue").Mailbox(capacity=1), compute, threading.Event()
)
assert waiting.close()
def test_completed_gpu_and_ingress_share_two_pending_slots(pilot):
mailbox = pilot("pilot_queue").Mailbox(capacity=2, byte_limit=100)
mailbox.put({"sequence": 0, "payload_bytes": 10})
active = mailbox.take()
for sequence in (1, 2):
mailbox.put({"sequence": sequence, "payload_bytes": 10})
mailbox.reserve_completed()
assert mailbox.dropped == [{"sequence": 1, "reason": "handoff-overflow"}]
assert mailbox.external_pending + len(mailbox.pending) == 2
mailbox.put({"sequence": 3, "payload_bytes": 10})
assert mailbox.dropped[-1] == {"sequence": 2, "reason": "pending-overflow"}
assert mailbox.peak_pending == 2 and mailbox.bytes == 20
mailbox.take_completed()
mailbox.release(active)
last = mailbox.take()
assert last["sequence"] == 3
mailbox.release(last)
assert mailbox.bytes == 0
with pytest.raises(ValueError, match="accounting"):
mailbox.take_completed()