feat(perception): measure M48S load envelope
This commit is contained in:
@@ -52,7 +52,7 @@ from k1link.perception.reference_graph_runtime import ReferenceGraphRuntimePaths
|
||||
from k1link.perception.rolling_map import RollingLocalObstacleMapProvider
|
||||
from k1link.perception.temporal import BoundedSpatialTemporalProvider
|
||||
|
||||
SCHEMA_VERSION: Final = "missioncore.m48s-reference-graph-shadow-load/v3"
|
||||
SCHEMA_VERSION: Final = "missioncore.m48s-reference-graph-shadow-load/v4"
|
||||
FRAME_EVIDENCE_SCHEMA: Final = "missioncore.m48s-reference-graph-frame-evidence/v1"
|
||||
PIPELINE_TIMING_SCHEMA: Final = "missioncore.m48s-frame-pipeline-timing/v0"
|
||||
GC_POLICY_SCHEMA: Final = "missioncore.cyclic-gc-hot-loop-policy/v0"
|
||||
@@ -63,6 +63,7 @@ AUTHORITY: Final = {
|
||||
"actuation_allowed": False,
|
||||
"navigation_or_safety_accepted": False,
|
||||
}
|
||||
LOAD_PURPOSES: Final = ("production-rate", "reserve-gate", "limit-discovery")
|
||||
|
||||
|
||||
class GpuTelemetry:
|
||||
@@ -359,6 +360,13 @@ def main() -> int:
|
||||
parser.add_argument("--triton-origin", default="http://127.0.0.1:8000")
|
||||
parser.add_argument("--loops", type=int, default=1)
|
||||
parser.add_argument("--maximum-frames", type=int)
|
||||
parser.add_argument("--source-rate-hz", type=float)
|
||||
parser.add_argument("--minimum-delivery-ratio", type=float, default=0.0)
|
||||
parser.add_argument("--minimum-effective-world-state-fps", type=float, default=9.5)
|
||||
parser.add_argument("--maximum-world-state-completion-p95-ms", type=float, default=175.0)
|
||||
parser.add_argument("--load-purpose", choices=LOAD_PURPOSES, default="production-rate")
|
||||
parser.add_argument("--runtime-artifact-sha256", required=True)
|
||||
parser.add_argument("--runner-sha256", required=True)
|
||||
parser.add_argument("--telemetry-interval-seconds", type=float, default=1.0)
|
||||
parser.add_argument("--output", type=Path, required=True)
|
||||
parser.add_argument("--progress", type=Path, required=True)
|
||||
@@ -370,6 +378,21 @@ def main() -> int:
|
||||
raise RuntimeError("maximum frame count must be positive")
|
||||
if arguments.telemetry_interval_seconds <= 0:
|
||||
raise RuntimeError("telemetry interval must be positive")
|
||||
if arguments.source_rate_hz is not None and (
|
||||
not np.isfinite(arguments.source_rate_hz) or arguments.source_rate_hz <= 0
|
||||
):
|
||||
raise RuntimeError("source rate must be positive and finite")
|
||||
if not 0.0 <= arguments.minimum_delivery_ratio <= 1.0:
|
||||
raise RuntimeError("minimum delivery ratio must be between zero and one")
|
||||
if arguments.minimum_effective_world_state_fps <= 0:
|
||||
raise RuntimeError("minimum effective world-state FPS must be positive")
|
||||
if arguments.maximum_world_state_completion_p95_ms <= 0:
|
||||
raise RuntimeError("maximum completion p95 must be positive")
|
||||
for digest in (arguments.runtime_artifact_sha256, arguments.runner_sha256):
|
||||
if len(digest) != 64 or any(character not in "0123456789abcdef" for character in digest):
|
||||
raise RuntimeError("runtime and runner SHA-256 values must be lowercase hex")
|
||||
if _sha256(Path(__file__)) != arguments.runner_sha256:
|
||||
raise RuntimeError("runner SHA-256 changed")
|
||||
output = arguments.output.absolute()
|
||||
progress = arguments.progress.absolute()
|
||||
frame_ledger = arguments.frame_ledger.absolute()
|
||||
@@ -426,6 +449,7 @@ def main() -> int:
|
||||
decode_timing_observer=timing_store.observe_decode,
|
||||
detector_timing_observer=timing_store.observe_detector,
|
||||
maximum_frames=arguments.maximum_frames,
|
||||
source_rate_hz=arguments.source_rate_hz,
|
||||
) as runtime:
|
||||
for stage_id, attribute in (
|
||||
("geometry", "geometry"),
|
||||
@@ -546,7 +570,9 @@ def main() -> int:
|
||||
identity = _identity_metrics(all_deliveries)
|
||||
semantic = _semantic_metrics(all_deliveries, advisories)
|
||||
world_state_fps = delivered / processing_wall_seconds
|
||||
checks = {
|
||||
delivery_ratio = delivered / admitted if admitted else 0.0
|
||||
completion_distribution = _distribution(completion_ages_ms)
|
||||
integrity_checks = {
|
||||
"loop_count_completed": len(loop_documents) == arguments.loops,
|
||||
"graph_stopped_cleanly": all(
|
||||
loop["state"] == GraphState.STOPPED.value for loop in loop_documents
|
||||
@@ -561,10 +587,6 @@ def main() -> int:
|
||||
TerminalOutcomeType.UNAVAILABLE,
|
||||
)
|
||||
),
|
||||
"minimum_world_state_fps": world_state_fps >= 9.5,
|
||||
"maximum_world_state_completion_p95_ms": (
|
||||
_distribution(completion_ages_ms)["p95"] <= 175.0
|
||||
),
|
||||
"bounded_latest_wins_queues": all(value <= 2 for value in queue_high_watermarks.values()),
|
||||
"temporal_identity_reuse_observed": cast(
|
||||
int,
|
||||
@@ -588,6 +610,19 @@ def main() -> int:
|
||||
),
|
||||
"authority_remains_false": all(value is False for value in AUTHORITY.values()),
|
||||
}
|
||||
operating_target_checks = {
|
||||
"minimum_delivery_ratio": delivery_ratio >= arguments.minimum_delivery_ratio,
|
||||
"minimum_world_state_fps": (
|
||||
world_state_fps >= arguments.minimum_effective_world_state_fps
|
||||
),
|
||||
"maximum_world_state_completion_p95_ms": (
|
||||
completion_distribution["p95"]
|
||||
<= arguments.maximum_world_state_completion_p95_ms
|
||||
),
|
||||
}
|
||||
checks = {**integrity_checks, **operating_target_checks}
|
||||
evidence_integrity_gate_passed = all(integrity_checks.values())
|
||||
operating_target_gate_passed = all(operating_target_checks.values())
|
||||
integrated_runtime_gate_passed = all(checks.values())
|
||||
document = {
|
||||
"schema_version": SCHEMA_VERSION,
|
||||
@@ -595,20 +630,28 @@ def main() -> int:
|
||||
"source_id": "RAVNOVES00",
|
||||
"loops": arguments.loops,
|
||||
"maximum_frames_per_loop": arguments.maximum_frames,
|
||||
"requested_rate_hz": arguments.source_rate_hz,
|
||||
"pacing_contract": "wall-clock-scaled-source-timestamps-immutable/v1",
|
||||
},
|
||||
"identity": {
|
||||
"worker_id": "worker-006",
|
||||
"graph_id": "reference-perception-graph/v2",
|
||||
"detector_provider_id": "triton-rf-detr-large-coco-risk-fp16-shadow/v0",
|
||||
"inputs": _input_digests(paths, arguments.detector_profile),
|
||||
"runtime_artifact_sha256": arguments.runtime_artifact_sha256,
|
||||
"runner_sha256": arguments.runner_sha256,
|
||||
},
|
||||
"execution": {
|
||||
"run_mode": GraphRunMode.SOURCE_PACED_LATEST_WINS.value,
|
||||
"load_purpose": arguments.load_purpose,
|
||||
"requested_source_rate_hz": arguments.source_rate_hz,
|
||||
"source_timestamps_preserved": True,
|
||||
"wall_seconds": round(wall_seconds, 6),
|
||||
"source_processing_wall_seconds": round(processing_wall_seconds, 6),
|
||||
"admitted_frames": admitted,
|
||||
"delivered_world_states": delivered,
|
||||
"effective_world_state_fps": round(world_state_fps, 6),
|
||||
"delivery_ratio": round(delivery_ratio, 9),
|
||||
"terminal_outcomes": dict(sorted(accounting.items())),
|
||||
"queue_high_watermarks": queue_high_watermarks,
|
||||
"loops": loop_documents,
|
||||
@@ -624,7 +667,7 @@ def main() -> int:
|
||||
},
|
||||
},
|
||||
"metrics": {
|
||||
"world_state_completion_age_ms": _distribution(completion_ages_ms),
|
||||
"world_state_completion_age_ms": completion_distribution,
|
||||
"local_obstacle_map_output_age_ms": _distribution(map_output_ages_ms),
|
||||
"identity_continuity": identity,
|
||||
"semantic_advisory": semantic,
|
||||
@@ -635,6 +678,19 @@ def main() -> int:
|
||||
"process_peak_rss_after_mib": round(rss_after_kib / 1024.0, 6),
|
||||
},
|
||||
"checks": checks,
|
||||
"integrity_checks": integrity_checks,
|
||||
"operating_target_checks": operating_target_checks,
|
||||
"predeclared_thresholds": {
|
||||
"minimum_delivery_ratio": arguments.minimum_delivery_ratio,
|
||||
"minimum_effective_world_state_fps": (
|
||||
arguments.minimum_effective_world_state_fps
|
||||
),
|
||||
"maximum_world_state_completion_p95_ms": (
|
||||
arguments.maximum_world_state_completion_p95_ms
|
||||
),
|
||||
},
|
||||
"evidence_integrity_gate_passed": evidence_integrity_gate_passed,
|
||||
"operating_target_gate_passed": operating_target_gate_passed,
|
||||
"integrated_runtime_gate_passed": integrated_runtime_gate_passed,
|
||||
"independent_track_identity_quality_evaluated": False,
|
||||
"independent_risk_policy_quality_evaluated": False,
|
||||
@@ -647,7 +703,10 @@ def main() -> int:
|
||||
output.write_bytes(_canonical_json(document) + b"\n")
|
||||
print(output)
|
||||
print(json.dumps(checks, indent=2, sort_keys=True))
|
||||
return 0 if integrated_runtime_gate_passed else 2
|
||||
discovery_completed = (
|
||||
arguments.load_purpose == "limit-discovery" and evidence_integrity_gate_passed
|
||||
)
|
||||
return 0 if integrated_runtime_gate_passed or discovery_completed else 2
|
||||
|
||||
|
||||
def _record_completion_age(
|
||||
|
||||
Reference in New Issue
Block a user