feat(train): TrainingConfig subcarrier-layout presets + real MmFiDataset loader test (audit #4/#6/#7)#537
Merged
Conversation
…set loader test Closes the remaining doable items from the 2026-05-11 training-pipeline audit: #6 (CSI format default = 56-sc / 1 NIC) + #7 (multi-band 168-sc mesh not in config): new `TrainingConfig::for_subcarriers(native, target)` plus named presets `mmfi()` (114→56), `ht40_192()` (≈192-sc ESP32 HT40 → 56) and `multiband_168()` (168-sc ADR-078 multi-band mesh → 56). Non-MM-Fi CSI shapes are now first-class instead of requiring manual `native_subcarriers` / `num_subcarriers` overrides; the field docs list the supported source counts and the multi-NIC mapping (a 2–3-node mesh currently rides on `n_rx` until a dedicated node dimension lands). Model input width stays `num_subcarriers`; the presets only vary the resampling input. #4 (proof.rs uses synthetic data): reframed — a deterministic proof *must* use a reproducible source, so `verify-training` correctly stays on `SyntheticCsiDataset`. The real gap was that nothing exercised the on-disk `MmFiDataset` path. New `tests/test_real_loader.rs` writes synthetic CSI to `.npy` files in the `MmFiDataset::discover` layout, loads it back, and checks the resulting `CsiSample` — covering the no-interp case, the subcarrier-interpolation branch, and the empty-root case. Adds `ndarray` / `ndarray-npy` as dev-deps for the fixture writing. cargo check + cargo test -p wifi-densepose-train --no-default-features: clean, all existing tests green, 3 new loader tests + the updated config doctest pass. Purely additive — no model-shape change, no tch-module change. Co-Authored-By: claude-flow <ruv@ruv.net>
ruvnet
added a commit
that referenced
this pull request
May 12, 2026
Publishing the additive changes from PRs #536/#537 to crates.io: - `signal_features` module — wires `wifi-densepose-signal` into the pipeline (audit #1/#2) - `TrainingConfig::for_subcarriers` / `ht40_192()` / `multiband_168()` presets + the real `MmFiDataset` loader integration test (audit #4/#6/#7) No public API removals or changes — additive only, so 0.3.0 -> 0.3.1 is semver-correct. No other workspace crate depends on `wifi-densepose-train`, so this is a standalone bump. Co-Authored-By: claude-flow <ruv@ruv.net>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the remaining doable findings from the 2026-05-11 training-pipeline audit (after #535 fixed #5 and #536 fixed #1-extract/#2/#3):
TrainingConfig::for_subcarriers+ named presets + docsTrainingConfig::multiband_168()preset + multi-NIC mapping documentedproof.rsusesSyntheticCsiDatasetnot real datatests/test_real_loader.rscovers the real on-disk path#6 / #7 —
TrainingConfigsubcarrier-layout presetsnum_subcarriers: 56/native_subcarriers: 114were the only documented shape; using any other CSI source meant overriding both fields by hand. New, inconfig.rs:TrainingConfig::for_subcarriers(native, target)— explicit native→model resample.TrainingConfig::mmfi()(114→56, ==default()),ht40_192()(≈192-sc ESP32 HT40 → 56),multiband_168()(168-sc ADR-078 multi-band mesh → 56).[T, n_tx, n_rx, n_sc]via extran_rxuntil a dedicated node dimension lands.num_subcarriers— the presets only change the resampling input, not the architecture.#4 — real on-disk loader test
A deterministic proof must use a reproducible source, so
verify-trainingcorrectly stays onSyntheticCsiDataset— the real gap was that nothing exercisedMmFiDataset's.npydisk-loading path. Newtests/test_real_loader.rs:.npyfiles in theMmFiDataset::discoverlayout (<root>/S01/A01/{wifi_csi.npy, wifi_csi_phase.npy, gt_keypoints.npy}),discover+get, assertingCsiSampleshapes ([T,n_tx,n_rx,n_sc], keypoints[17,2], visibility[17]) and finiteness,ndarray/ndarray-npyas[dev-dependencies]for fixture writing.Tests
cargo check -p wifi-densepose-train --no-default-features— clean (only pre-existingruvector-*/wifi-densepose-nnwarnings).cargo test -p wifi-densepose-train --no-default-features— all existing tests green, plus the 3 newtest_real_loader.rstests and the updatedconfig.rsdoctest (now exercisesht40_192()/for_subcarriers) pass. Purely additive — no model-shape change, notch-module change, deterministic proof untouched. (An unrelated 109-lineCargo.lockdrift acargo checkintroduced was reverted, so the diff is clean.)Audit scoreboard
#1 (extract) ✅ #2 ✅ #3 ✅ (#536) · #4 ✅ #6 ✅ #7 ✅ (this PR) · #5 ✅ (#535). The one not closed: #1's training-target half — wiring the extracted
signal_featuresinto a vitals/multi-task supervision head — is blocked on a vitals-labeled dataset (MM-Fi/Wi-Pose carry no vitals labels; an ESP32 paired capture would). The end-to-end path is in thetraining-guide.mddelivered to the pulse-seed handoff. So all 7 findings are addressed/reframed; one has a remaining follow-up gated on data.🤖 Generated with claude-flow