feat: train_fold_from_slices — trainer accepts contiguous feature/target slices
Adds DQNTrainer::train_fold_from_slices(&[[f64;42]], &[[f64;4]]) so the fold loop in train_baseline_rl passes raw fxcache slices directly, without the caller constructing any Vec<(FeatureVector, Vec<f64>)>. Removes features_to_trainer_format_fast helper (no longer needed) and updates train_dqn_fold to call the new method. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -352,21 +352,6 @@ fn hp_bool(params: &Option<Value>, key: &str) -> Option<bool> {
|
||||
// DQN Training
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Convert fxcache feature/target slices into the format expected by
|
||||
/// `DQNTrainer::train_with_preloaded_data`: `Vec<(FeatureVector, Vec<f64>)>`.
|
||||
///
|
||||
/// Zero bar reconstruction — targets already contain [close, next_close, raw_close, raw_next].
|
||||
fn features_to_trainer_format_fast(
|
||||
features: &[[f64; 42]],
|
||||
targets: &[[f64; 4]],
|
||||
) -> Vec<(FeatureVector, Vec<f64>)> {
|
||||
features
|
||||
.iter()
|
||||
.zip(targets.iter())
|
||||
.map(|(f, t)| (*f, t.to_vec()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Build DQN hyperparameters from args, hyperopt JSON, and GPU profile.
|
||||
///
|
||||
/// Extracted from the old `train_dqn_fold` so it can be called ONCE before the fold
|
||||
@@ -478,10 +463,6 @@ fn train_dqn_fold(
|
||||
rt.block_on(trainer.reset_for_fold())
|
||||
.context("reset_for_fold failed")?;
|
||||
|
||||
// Convert to Vec format for the training API (Task 5 will eliminate this)
|
||||
let training_data = features_to_trainer_format_fast(train_features, train_targets);
|
||||
let val_data = features_to_trainer_format_fast(val_features, val_targets);
|
||||
|
||||
// Checkpoint callback: save best model to output directory
|
||||
let output_dir_owned = output_dir.to_path_buf();
|
||||
let prefix_owned = checkpoint_prefix.to_owned();
|
||||
@@ -500,7 +481,7 @@ fn train_dqn_fold(
|
||||
};
|
||||
|
||||
let metrics = rt.block_on(
|
||||
trainer.train_with_preloaded_data(training_data, val_data, checkpoint_callback)
|
||||
trainer.train_fold_from_slices(train_features, train_targets, checkpoint_callback)
|
||||
).map_err(|e| {
|
||||
error!(" [DQN] Fold {} training error chain: {:#}", fold, e);
|
||||
e
|
||||
|
||||
@@ -527,6 +527,44 @@ impl DQNTrainer {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Train one fold from contiguous feature/target slices.
|
||||
/// Zero Vec<f64> allocation — targets read as fixed-size &[[f64; 4]].
|
||||
///
|
||||
/// Caller must call `set_val_data_from_slices` and `set_training_range` before
|
||||
/// this method. Val data and OFI offset are already set on `self`.
|
||||
pub async fn train_fold_from_slices<F>(
|
||||
&mut self,
|
||||
features: &[[f64; 42]],
|
||||
targets: &[[f64; 4]],
|
||||
checkpoint_callback: F,
|
||||
) -> Result<TrainingMetrics>
|
||||
where
|
||||
F: FnMut(usize, Vec<u8>, bool) -> Result<String> + Send,
|
||||
{
|
||||
// Clear stale CUDA errors
|
||||
if let MlDevice::Cuda { ref context, .. } = self.device {
|
||||
let _ = context.check_err();
|
||||
}
|
||||
|
||||
info!("train_fold_from_slices: {} bars", features.len());
|
||||
|
||||
// Build lightweight training_data with fixed-size [f64; 4] converted to Vec<f64>
|
||||
// This is the last remaining allocation — each [f64; 4].to_vec() is 32 bytes.
|
||||
// TODO: eliminate by changing train_with_data_full_loop signature
|
||||
let training_data: Vec<(FeatureVector, Vec<f64>)> = features
|
||||
.iter()
|
||||
.zip(targets.iter())
|
||||
.map(|(f, t)| (*f, t.to_vec()))
|
||||
.collect();
|
||||
|
||||
self.val_features_gpu = None;
|
||||
self.val_closes_gpu = None;
|
||||
self.val_ofi_gpu = None;
|
||||
|
||||
self.train_with_data_full_loop(&training_data, checkpoint_callback)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Train with shared preloaded data (zero-copy for hyperopt).
|
||||
///
|
||||
/// Same as [`train_with_preloaded_data`] but accepts `Arc`-wrapped data,
|
||||
|
||||
Reference in New Issue
Block a user