fix: evaluate_baseline example bf16→f32 closure signatures

The evaluate closures now receive &CudaSlice<f32> from the backtest
evaluator. Updated all 3 closures (DQN, PPO, supervised) to match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-04-10 08:02:13 +02:00
parent 8329ca4187
commit a2370d7f33

View File

@@ -1239,11 +1239,12 @@ fn evaluate_dqn_fold_gpu(
let eval_stream = stream.clone();
evaluator
.evaluate(
&|states_flat: &cudarc::driver::CudaSlice<half::bf16>, batch_size: usize, state_dim: usize| -> Result<cudarc::driver::CudaSlice<i32>, ml::MLError> {
// Clone CudaSlice into a GpuTensor, forward through DQN, then argmax
let cloned = ml::cuda_pipeline::clone_cuda_slice_f32(states_flat, &eval_stream)?;
let states_tensor = GpuTensor::new(cloned, vec![batch_size, state_dim])
.map_err(|e| ml::MLError::ModelError(format!("GpuTensor wrap: {e}")))?;
&|states_flat: &cudarc::driver::CudaSlice<f32>, batch_size: usize, state_dim: usize| -> Result<cudarc::driver::CudaSlice<i32>, ml::MLError> {
// Download f32 states to host, then upload as bf16 GpuTensor for DQN forward
let host_f32 = eval_stream.clone_dtoh(states_flat)
.map_err(|e| ml::MLError::ModelError(format!("DtoH states: {e}")))?;
let states_tensor = GpuTensor::from_host(&host_f32, vec![batch_size, state_dim], &eval_stream)
.map_err(|e| ml::MLError::ModelError(format!("GpuTensor from_host: {e}")))?;
let q_values = dqn.q_values_for_batch(&states_tensor)?;
let argmax_indices = q_values.argmax(1, &eval_stream)
.map_err(|e| ml::MLError::ModelError(format!("argmax: {e}")))?;
@@ -1478,14 +1479,13 @@ fn evaluate_ppo_fold_gpu(
let eval_ppo_stream = ppo_stream.clone();
let metrics = evaluator
.evaluate(
&|states_flat: &cudarc::driver::CudaSlice<half::bf16>, batch_size: usize, state_dim: usize| -> Result<cudarc::driver::CudaSlice<i32>, ml::MLError> {
// Download bf16 states to host, then convert to f32 for PPO actor forward
&|states_flat: &cudarc::driver::CudaSlice<f32>, batch_size: usize, state_dim: usize| -> Result<cudarc::driver::CudaSlice<i32>, ml::MLError> {
// Download f32 states to host for PPO actor forward
let n_floats = batch_size * state_dim;
let view = states_flat.slice(..n_floats);
let mut host_bf16 = vec![bf16::ZERO; n_floats];
eval_ppo_stream.memcpy_dtoh(&view, &mut host_bf16)
let mut host_states = vec![0.0_f32; n_floats];
eval_ppo_stream.memcpy_dtoh(&view, &mut host_states)
.map_err(|e| ml::MLError::ModelError(format!("DtoH states: {e}")))?;
let host_states: Vec<f32> = host_bf16.iter().map(|v| v.to_f32()).collect();
// Get action probabilities [batch * 45]
let probs_host = match &ppo.actor {
@@ -1650,14 +1650,13 @@ fn evaluate_supervised_fold_gpu(
let metrics = evaluator
.evaluate(
&|states_flat: &cudarc::driver::CudaSlice<half::bf16>, batch_size: usize, state_dim: usize| -> Result<cudarc::driver::CudaSlice<i32>, ml::MLError> {
// Download bf16 states to host, then convert to f32 for supervised forward
&|states_flat: &cudarc::driver::CudaSlice<f32>, batch_size: usize, state_dim: usize| -> Result<cudarc::driver::CudaSlice<i32>, ml::MLError> {
// Download f32 states to host for supervised forward
let n_floats = batch_size * state_dim;
let view = states_flat.slice(..n_floats);
let mut host_bf16 = vec![bf16::ZERO; n_floats];
eval_sup_stream.memcpy_dtoh(&view, &mut host_bf16)
let mut host_states = vec![0.0_f32; n_floats];
eval_sup_stream.memcpy_dtoh(&view, &mut host_states)
.map_err(|e| ml::MLError::ModelError(format!("DtoH states: {e}")))?;
let host_states: Vec<f32> = host_bf16.iter().map(|v| v.to_f32()).collect();
// Extract market features only (strip portfolio dims)
let market_dim = state_dim.saturating_sub(3);