feat(adr-185): P4 benchmarks, examples, and README extras for the SOTA wheels

ADR-185 §4.2 pytest-benchmark micro-benchmarks + runnable examples +
README extras table for the aether/meridian/mat bindings.

- python/bench/test_bench_{aether,meridian,mat}.py — follow the existing
  test_bench_vitals.py pattern (skipped by default; --benchmark-only).
- python/examples/{reid_from_csi,cross_room_calibrate,mat_triage}.py —
  typed, runnable, mypy --strict clean.
- python/README.md — SOTA extras table + example links.

Measured on a RELEASE wheel (maturin develop --release --features sota),
reference machine per ADR-117 §10:
  AETHER embed()          mean ~150 us/window   (target <2 ms)   PASS
    batch scaling 1/8/64: 140 / 1091 / 8509 us  (linear, no O(n^2)) PASS
  MERIDIAN normalize()    mean ~2.2 us/frame     (target <200 us) PASS
  MERIDIAN encode()       mean ~6.9 us           (target <200 us) PASS
  MAT ingest+scan_once()  mean ~40 ms/256-frame  (< 500 ms interval) PASS

Acceptance self-verification (ADR-185 §6), all run just now:
  §6.1 default wheel 279 KB (<=5 MB); build_features has no p6-* feature  PASS
  §6.2 pytest tests/test_aether.py    9/9   PASS
  §6.3 pytest tests/test_meridian.py  13/13 PASS
  §6.4 pytest tests/test_mat.py       7/7   PASS
  §6.5 benchmarks meet all targets (above)                                PASS
  §6.6 parity harness: 3/3 SHA golden gates green (cargo test --features
       sota, 6/6); CI *wiring* as a release gate is out of python/ scope  PARTIAL
  §6.7 SOTA accuracy bars on labeled fixtures: NOT met (no labeled
       fixtures / trained models available; parity proves path-equality,
       not accuracy)                                                       OPEN
  §6.8 .pyi stubs present for all three; mypy --strict on the 3 examples   PASS
  §6.9 base wheel `import wifi_densepose.{aether,meridian,mat}` raises a
       clear ImportError naming the extra                                  PASS
  No regression: 76 pre-existing tests pass on the default wheel.

Status NOT flipped to Accepted: §6.7 (accuracy bars) is unmet, §6.6 CI
wiring is pending, and the per-extra wheel-size hoists (sensing-server /
train / mat leaf crates) remain follow-ups. docs/adr/ is owned by another
agent this session, so the ADR ledger edit is deferred to that owner.
This commit is contained in:
ruv
2026-07-21 17:03:49 -07:00
parent 1c9727f9cf
commit 0f405213d3
7 changed files with 273 additions and 0 deletions
+23
View File
@@ -43,6 +43,29 @@ pip install "wifi-densepose[client]" # + WebSocket/MQTT clients
Wheels are published for Linux (x86_64, aarch64), macOS (x86_64, arm64), and
Windows (amd64).
### SOTA extras (ADR-185)
Three optional subsystems bind the Rust SOTA modules as compiled-feature
wheels. Each raises a clear `ImportError` if you import it without the extra:
| Extra | Module | What it adds |
|-------|--------|--------------|
| `[aether]` | `wifi_densepose.aether` | Contrastive CSI embeddings / re-identification (ADR-024) — `EmbeddingExtractor`, `cosine_similarity`, `info_nce_loss` |
| `[meridian]` | `wifi_densepose.meridian` | Cross-environment domain generalization (ADR-027) — `HardwareNormalizer`, `GeometryEncoder`, `RapidAdaptation`, `CrossDomainEvaluator` |
| `[mat]` | `wifi_densepose.mat` | Mass-Casualty Assessment disaster-survivor detection + START triage — `DisasterResponse`, `Survivor`, `TriageStatus` |
| `[sota]` | all three | Convenience superset |
```bash
pip install "wifi-densepose[aether]" # re-identification embeddings
pip install "wifi-densepose[meridian]" # cross-room calibration
pip install "wifi-densepose[mat]" # disaster triage
pip install "wifi-densepose[sota]" # all three
```
Runnable examples: [`examples/reid_from_csi.py`](examples/reid_from_csi.py),
[`examples/cross_room_calibrate.py`](examples/cross_room_calibrate.py),
[`examples/mat_triage.py`](examples/mat_triage.py).
## Usage
### Extract breathing rate from a CSI stream
+44
View File
@@ -0,0 +1,44 @@
"""ADR-185 §4.2 — AETHER embed() micro-benchmarks.
Target (release build, ADR-024 §2.8 FP32 <1 ms with headroom): steady-state
`embed()` < 2 ms/window, and batched `embed()` scales roughly linearly (no
accidental O(n²)).
Run with:
pytest python/bench/test_bench_aether.py --benchmark-only
Skipped by default (they live in `bench/`, outside `testpaths`). Timing
targets are validated on a RELEASE wheel (`maturin develop --release
--features sota`); a debug wheel will be several× slower.
"""
from __future__ import annotations
import math
import pytest
from wifi_densepose import aether
def _window(frames: int = 8, subc: int = 56) -> list[list[float]]:
return [[math.sin(0.1 * t + 0.03 * k) for k in range(subc)] for t in range(frames)]
def _extractor() -> aether.EmbeddingExtractor:
return aether.EmbeddingExtractor(n_subcarriers=56, config=aether.AetherConfig())
def test_embed_per_window(benchmark) -> None:
ext = _extractor()
window = _window()
out = benchmark(lambda: ext.embed(window))
assert len(out) == 128
@pytest.mark.parametrize("batch", [1, 8, 64])
def test_embed_batch_scaling(benchmark, batch: int) -> None:
ext = _extractor()
windows = [_window() for _ in range(batch)]
out = benchmark(lambda: [ext.embed(w) for w in windows])
assert len(out) == batch
+44
View File
@@ -0,0 +1,44 @@
"""ADR-185 §4.2 — MAT scan micro-benchmark.
Measures the cost of one full ingest + `scan_once()` cycle over the
committed 256-frame CSI stream. The per-cycle cost should stay comfortably
below the configured scan interval (default 500 ms) so the binding is not
the bottleneck.
Run with:
pytest python/bench/test_bench_mat.py --benchmark-only
Validated on a RELEASE wheel; a debug wheel will be several× slower.
"""
from __future__ import annotations
import json
from pathlib import Path
from wifi_densepose import mat
_FIXTURE = Path(__file__).resolve().parents[1] / "tests" / "golden" / "mat_input.json"
def _stream() -> list[dict]:
return json.loads(_FIXTURE.read_text())["stream"]
def test_scan_cycle_cost(benchmark) -> None:
stream = _stream()
def _run() -> int:
cfg = mat.DisasterConfig(
mat.DisasterType.Earthquake, sensitivity=0.9, confidence_threshold=0.1
)
resp = mat.DisasterResponse(cfg)
resp.initialize_event(0.0, 0.0, "bench")
resp.add_zone(mat.ScanZone.rectangle("Zone A", 0.0, 0.0, 50.0, 30.0))
for frame in stream:
resp.push_csi_data(frame["amplitude"], frame["phase"])
resp.scan_once()
return len(resp.survivors())
survivors = benchmark(_run)
assert survivors == 1
+29
View File
@@ -0,0 +1,29 @@
"""ADR-185 §4.2 — MERIDIAN micro-benchmarks.
Targets (release build, ADR-027 §4.1/§4.3 ×2 headroom): `normalize()`
< 200 µs/frame, `encode()` < 200 µs.
Run with:
pytest python/bench/test_bench_meridian.py --benchmark-only
Validated on a RELEASE wheel; a debug wheel will be several× slower.
"""
from __future__ import annotations
from wifi_densepose import meridian as mer
def test_normalize_per_frame(benchmark) -> None:
norm = mer.HardwareNormalizer()
amp = [10.0 + 0.05 * k for k in range(64)]
phase = [0.01 * k for k in range(64)]
out = benchmark(lambda: norm.normalize(amp, phase, mer.HardwareType.Esp32S3))
assert len(out.amplitude) == 56
def test_geometry_encode(benchmark) -> None:
enc = mer.GeometryEncoder(mer.MeridianGeometryConfig())
aps = [[0.0, 0.0, 2.5], [5.0, 0.0, 2.5], [0.0, 4.0, 2.5]]
out = benchmark(lambda: enc.encode(aps))
assert len(out) == 64
+45
View File
@@ -0,0 +1,45 @@
"""MERIDIAN cross-room calibration (ADR-185 P2, `[meridian]` extra).
Hardware-invariant CSI normalization, AP-geometry encoding, and few-shot
rapid adaptation — the tch-free domain-generalization path.
pip install wifi-densepose[meridian]
python examples/cross_room_calibrate.py
"""
from __future__ import annotations
import math
from wifi_densepose.meridian import (
GeometryEncoder,
HardwareNormalizer,
HardwareType,
MeridianGeometryConfig,
RapidAdaptation,
)
def main() -> None:
# 1. Normalize a 64-subcarrier ESP32 frame to the canonical 56-tone grid.
norm = HardwareNormalizer()
amp = [10.0 + 0.05 * k for k in range(64)]
phase = [0.01 * k for k in range(64)]
frame = norm.normalize(amp, phase, HardwareType.detect(64))
print(f"canonical subcarriers: {len(frame.amplitude)} (hw={frame.hardware_type})")
# 2. Encode AP positions into a permutation-invariant geometry embedding.
enc = GeometryEncoder(MeridianGeometryConfig())
geometry = enc.encode([[0.0, 0.0, 2.5], [5.0, 0.0, 2.5], [0.0, 4.0, 2.5]])
print(f"geometry embedding dim: {len(geometry)}")
# 3. Few-shot rapid adaptation over a handful of unlabeled frames.
ra = RapidAdaptation(min_calibration_frames=10, lora_rank=4)
for i in range(12):
ra.push_frame([math.sin(0.1 * i + 0.05 * d) for d in range(16)])
result = ra.adapt()
print(f"adapted over {result.frames_used} frames, final_loss={result.final_loss:.4f}")
if __name__ == "__main__":
main()
+49
View File
@@ -0,0 +1,49 @@
"""MAT disaster-survivor triage from CSI (ADR-185 P3, `[mat]` extra).
Ingest a CSI stream, run one detection cycle, and list detected survivors
by START triage class.
pip install wifi-densepose[mat]
python examples/mat_triage.py
Note: the stream here is synthetic (breathing-modulated) — it demonstrates
the API and pipeline, not validated detection accuracy on real rubble.
"""
from __future__ import annotations
import math
from collections.abc import Iterator
from wifi_densepose.mat import DisasterConfig, DisasterResponse, DisasterType, ScanZone
def breathing_stream(
frames: int = 256, subc: int = 56, fs: float = 20.0
) -> Iterator[tuple[list[float], list[float]]]:
for t in range(frames):
tt = t / fs
breath = 2.0 * math.sin(2 * math.pi * 0.3 * tt)
amp = [10.0 + 0.05 * k + breath for k in range(subc)]
phase = [0.01 * k + 0.1 * math.sin(2 * math.pi * 0.3 * tt) for k in range(subc)]
yield amp, phase
def main() -> None:
cfg = DisasterConfig(DisasterType.Earthquake, sensitivity=0.9, confidence_threshold=0.1)
resp = DisasterResponse(cfg)
resp.initialize_event(0.0, 0.0, "Collapsed Building A")
resp.add_zone(ScanZone.rectangle("North Wing", 0.0, 0.0, 50.0, 30.0))
for amp, phase in breathing_stream():
resp.push_csi_data(amp, phase)
resp.scan_once()
survivors = resp.survivors()
print(f"detected {len(survivors)} survivor(s)")
for s in survivors:
print(f" {s.id[:8]} triage={s.triage_status} confidence={s.confidence:.3f}")
if __name__ == "__main__":
main()
+39
View File
@@ -0,0 +1,39 @@
"""AETHER re-identification from CSI (ADR-185 P1, `[aether]` extra).
Compute 128-dim contrastive embeddings for CSI windows and score them by
cosine similarity — the primitive behind room fingerprinting and person
re-identification.
pip install wifi-densepose[aether]
python examples/reid_from_csi.py
"""
from __future__ import annotations
import math
from wifi_densepose.aether import AetherConfig, EmbeddingExtractor, cosine_similarity
def make_window(phase_shift: float, frames: int = 8, subc: int = 56) -> list[list[float]]:
"""A synthetic CSI window; `phase_shift` stands in for a different scene."""
return [
[math.sin(0.1 * t + 0.03 * k + phase_shift) for k in range(subc)]
for t in range(frames)
]
def main() -> None:
ext = EmbeddingExtractor(n_subcarriers=56, config=AetherConfig())
same_a = ext.embed(make_window(0.0))
same_b = ext.embed(make_window(0.0)) # same scene
other = ext.embed(make_window(1.5)) # different scene
print(f"embedding dim: {len(same_a)}")
print(f"same-scene similarity: {cosine_similarity(same_a, same_b):.4f}")
print(f"cross-scene similarity: {cosine_similarity(same_a, other):.4f}")
if __name__ == "__main__":
main()