perf(htod): migrate PPO trainer + hyperopt adapters to mapped-pinned (6 sites)
- trainers/ppo.rs: 2 sites (features, targets in set_raw_market_data)
- hyperopt/adapters/ppo.rs: 3 sites (features, targets in upload path;
action_indices in run_gpu_backtest forward closure)
- hyperopt/adapters/mamba2.rs: 1 site (gpu_to_stream)
All clone_htod_f32 and bare stream.clone_htod calls rewritten to
mapped_pinned::clone_to_device_{f32,i32}_via_pinned.
Audit row appended (Fix 7) in docs/dqn-gpu-hot-path-audit.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -745,7 +745,8 @@ fn gpu_to_stream(
|
||||
stream: &Arc<cudarc::driver::CudaStream>,
|
||||
) -> Result<StreamTensor, MLError> {
|
||||
let host = t.to_host(stream)?;
|
||||
let data = crate::cuda_pipeline::clone_htod_f32(stream, &host)?;
|
||||
let data = crate::cuda_pipeline::mapped_pinned::clone_to_device_f32_via_pinned(stream, &host)
|
||||
.map_err(|e| MLError::ModelError(format!("gpu_to_stream upload via pinned: {e}")))?;
|
||||
Ok(StreamTensor {
|
||||
data,
|
||||
shape: t.shape().to_vec(), // cpu-side shape clone
|
||||
|
||||
@@ -580,14 +580,14 @@ impl PPOTrainer {
|
||||
for (features, _) in training_data {
|
||||
flat_features.extend_from_slice(features);
|
||||
}
|
||||
match crate::cuda_pipeline::clone_htod_f32(&stream, &flat_features) {
|
||||
match crate::cuda_pipeline::mapped_pinned::clone_to_device_f32_via_pinned(&stream, &flat_features) {
|
||||
Ok(buf) => {
|
||||
info!("PPO CUDA features uploaded: {} bars × 42 ({:.1} MB)",
|
||||
num_bars, (num_bars * 42 * 4) as f64 / 1_048_576.0);
|
||||
self.features_cuda = Some(buf);
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(MLError::TrainingError(format!("PPO CUDA features upload FAILED (no CPU fallback): {e}")));
|
||||
return Err(MLError::TrainingError(format!("PPO CUDA features upload via pinned FAILED (no CPU fallback): {e}")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -604,7 +604,7 @@ impl PPOTrainer {
|
||||
flat_targets.push(close);
|
||||
flat_targets.push(next_close);
|
||||
}
|
||||
match crate::cuda_pipeline::clone_htod_f32(&stream, &flat_targets) {
|
||||
match crate::cuda_pipeline::mapped_pinned::clone_to_device_f32_via_pinned(&stream, &flat_targets) {
|
||||
Ok(buf) => {
|
||||
info!("PPO CUDA targets uploaded: {} bars × 4 ({:.1} MB)",
|
||||
num_bars, (num_bars * 4 * 4) as f64 / 1_048_576.0);
|
||||
@@ -612,7 +612,7 @@ impl PPOTrainer {
|
||||
}
|
||||
Err(e) => {
|
||||
self.features_cuda = None;
|
||||
return Err(MLError::TrainingError(format!("PPO CUDA targets upload FAILED (no CPU fallback): {e}")));
|
||||
return Err(MLError::TrainingError(format!("PPO CUDA targets upload via pinned FAILED (no CPU fallback): {e}")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1326,10 +1326,9 @@ impl PPOTrainer {
|
||||
}
|
||||
}
|
||||
|
||||
// Upload action indices to GPU
|
||||
stream.clone_htod(&action_indices).map_err(|e| {
|
||||
MLError::ModelError(format!("PPO backtest action upload: {e}"))
|
||||
})
|
||||
// Upload action indices to GPU via mapped-pinned staging (no explicit HtoD)
|
||||
crate::cuda_pipeline::mapped_pinned::clone_to_device_i32_via_pinned(stream, &action_indices)
|
||||
.map_err(|e| MLError::ModelError(format!("PPO backtest action upload via pinned: {e}")))
|
||||
},
|
||||
24, // portfolio_dim: 8 portfolio + 16 multi-timeframe (matches training state layout)
|
||||
)?;
|
||||
|
||||
@@ -395,7 +395,8 @@ impl PpoTrainer {
|
||||
flat_features.push(v as f32);
|
||||
}
|
||||
}
|
||||
let features_buf = crate::cuda_pipeline::clone_htod_f32(&stream, &flat_features)?;
|
||||
let features_buf = crate::cuda_pipeline::mapped_pinned::clone_to_device_f32_via_pinned(&stream, &flat_features)
|
||||
.map_err(|e| MLError::ModelError(format!("PPO features upload via pinned: {e}")))?;
|
||||
self.features_raw_cuda = Some(features_buf);
|
||||
|
||||
// Upload targets [num_bars * 4]
|
||||
@@ -405,7 +406,8 @@ impl PpoTrainer {
|
||||
flat_targets.push(targets.get(i).copied().unwrap_or(0.0) as f32);
|
||||
}
|
||||
}
|
||||
let targets_buf = crate::cuda_pipeline::clone_htod_f32(&stream, &flat_targets)?;
|
||||
let targets_buf = crate::cuda_pipeline::mapped_pinned::clone_to_device_f32_via_pinned(&stream, &flat_targets)
|
||||
.map_err(|e| MLError::ModelError(format!("PPO targets upload via pinned: {e}")))?;
|
||||
self.targets_raw_cuda = Some(targets_buf);
|
||||
self.raw_data_num_bars = num_bars;
|
||||
|
||||
|
||||
@@ -103,3 +103,6 @@
|
||||
|
||||
### Fix 6 — Migrate `gpu_walk_forward.rs` to mapped-pinned (3 sites)
|
||||
`gpu_walk_forward.rs`: 3 `clone_htod_f32` calls in the walk-forward GPU data upload (features, targets, OFI) rewritten to `mapped_pinned::clone_to_device_f32_via_pinned`.
|
||||
|
||||
### Fix 7 — Migrate PPO trainer + hyperopt adapters to mapped-pinned (6 sites)
|
||||
`trainers/ppo.rs` (2 sites: features, targets in `set_raw_market_data`), `hyperopt/adapters/ppo.rs` (3 sites: features, targets in upload path; action_indices in backtest forward closure), `hyperopt/adapters/mamba2.rs` (1 site: `gpu_to_stream`). All `clone_htod_f32` and bare `stream.clone_htod` calls rewritten to `mapped_pinned::clone_to_device_{f32,i32}_via_pinned`.
|
||||
|
||||
Reference in New Issue
Block a user