Files
foxhunt/crates
jgrusewski f29dcc47c9 feat(sp21): T2.2 Phase 6.5a — val state retention infrastructure (mapped-pinned, atomic)
Lays the consumer-side infrastructure for true E7 hindsight synthetic
injection. Phase 6.5b will follow with the producer wireup.

What lands:
1. EvalTrade.window_index + HindsightExperience.window_index fields
   (host-side only; set in read_per_trade_tape from the w loop var
   and propagated by compute_hindsight_labels).
2. GpuBacktestEvaluator.retained_states_buf — mapped-pinned
   MappedF32Buffer sized [max_len × n_windows × state_dim_padded].
   Populated by a DtoD copy after every launch_gather_chunk inside
   submit_dqn_step_loop_cublas; layout matches chunked_states_buf
   so the copy is a single contiguous block per chunk (no
   transpose).
3. pub fn read_retained_state(window_idx, bar_idx) — zero-copy
   host read via std::ptr::read_volatile on host_ptr (no
   memcpy_dtoh per feedback_no_htod_htoh_only_mapped_pinned).

Mapped-pinned decision (jgrusewski review):
- Initial draft used CudaSlice<f32> + memcpy_dtoh for host read,
  caught at review: violates feedback_no_htod_htoh_only_mapped_pinned.
- Refactored to MappedF32Buffer (cuMemHostAlloc DEVICEMAP). The
  DtoD copy remains (rule forbids HtoD/DtoH, not DtoD; kernel
  writes via dev_ptr aliasing pinned host memory). Caller must
  sync eval stream before read_retained_state — production path's
  consume_metrics_after_event already does this.

Memory cost at production cfg (max_len=200_000, n_windows=5,
state_dim_padded≈128): ~512 MB pinned host RAM. Substantial but
feasible on L40S host (192 GB+).

Files changed:
- crates/ml/src/cuda_pipeline/gpu_backtest_evaluator.rs: +retained
  buffer + accessor; EvalTrade.window_index field
- crates/ml/src/trainers/dqn/trainer/enrichment.rs: HindsightExperience
  .window_index field
- docs/dqn-wire-up-audit.md: 2026-05-11 audit entry

Verification (passing):
- cargo check -p ml --tests --features cuda: 0 errors
- cargo test -p ml --lib sp21_isv_slots: 3/3
- sp20_aggregate_inputs_test: 12/12
- sp20_phase1_4_wireup_test: 2/2
- sp20_emas_compute_test: 4/4
- sp20_controllers_compute_test: 7/7
- sp21_per_trade_predicted_q_test: 3/3
Total: 34 tests, 0 failures. Infrastructure works without exercising
it (accessor returns None until eval populates the retained buffer
— graceful degradation for test scaffolds bypassing the full eval).

After this commit (Phase 6.5b):
- Mapped-pinned synthetic-tuple scratch on GpuReplayBuffer
- New insert_synthetic_via_pinned API (raw dev_ptrs, no HtoD)
- training_loop hindsight injection wireup (~300 LOC)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 00:09:10 +02:00
..