From c5961cb766cd387dffee41551f91d22374bf008e Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Mon, 16 Mar 2026 16:26:41 +0100 Subject: [PATCH] refactor(cuda): remove all #[cfg(not(feature = "cuda"))] dead CPU paths Delete every CPU fallback block across 14 files (-286 lines): - dqn.rs: CPU replay buffer, tensor construction, PER fallback, gradient paths - hyperopt/adapters/ppo.rs: CPU curiosity modules, trajectory generation - hyperopt/adapters/dqn.rs: CPU backtest fallback, sync no-op - trainers/ppo.rs: CPU training error stub - l2_cache.rs: CPU stub functions (gate callers behind cuda too) - replay_buffer_type.rs: CPU is_gpu_prioritized fallback - validation/harness.rs: CPU regime breakdown fallback - build.rs: cpu_only_build cfg (never referenced) - evaluate_baseline.rs: CPU gpu_handled fallback - testing/integration/gpu: CPU test stubs Zero #[cfg(not(feature = "cuda"))] remains in the codebase. Co-Authored-By: Claude Opus 4.6 --- crates/ml-core/src/gpu/l2_cache.rs | 17 +- crates/ml-dqn/src/dqn.rs | 177 +++--------------- crates/ml-dqn/src/replay_buffer_type.rs | 5 +- crates/ml-dqn/src/training_guard_gpu_tests.rs | 9 - crates/ml/build.rs | 17 -- crates/ml/examples/evaluate_baseline.rs | 7 - crates/ml/src/hyperopt/adapters/dqn.rs | 6 - crates/ml/src/hyperopt/adapters/ppo.rs | 32 +--- crates/ml/src/trainers/ppo.rs | 15 +- crates/ml/src/validation/harness.rs | 6 - .../gpu/cuda_initialization_test.rs | 4 - testing/integration/gpu/cuda_kernel_test.rs | 16 -- testing/integration/gpu/mod.rs | 9 +- .../gpu/production_gpu_integration_test.rs | 5 - 14 files changed, 39 insertions(+), 286 deletions(-) diff --git a/crates/ml-core/src/gpu/l2_cache.rs b/crates/ml-core/src/gpu/l2_cache.rs index 43e05df36..1409c8563 100644 --- a/crates/ml-core/src/gpu/l2_cache.rs +++ b/crates/ml-core/src/gpu/l2_cache.rs @@ -149,18 +149,10 @@ pub fn set_persisting_l2_cache_size(num_bytes: usize) -> Result { Ok(target) } -/// CPU-only stub: always returns `Ok(0)`. -#[cfg(not(feature = "cuda"))] -pub fn set_persisting_l2_cache_size(_num_bytes: usize) -> Result { - Ok(0) -} - /// Reset the persisting L2 cache, releasing all persistent cache lines. /// /// Call this during shutdown or when switching between models of very /// different sizes to avoid stale persistence reservations. -/// -/// No-op on non-CUDA builds or when L2 persistence is not supported. #[cfg(feature = "cuda")] pub fn reset_persisting_l2_cache() -> Result<(), String> { use candle_core::cuda_backend::cudarc::driver::sys::{ @@ -178,11 +170,6 @@ pub fn reset_persisting_l2_cache() -> Result<(), String> { Ok(()) } -/// CPU-only stub: always returns `Ok(())`. -#[cfg(not(feature = "cuda"))] -pub fn reset_persisting_l2_cache() -> Result<(), String> { - Ok(()) -} /// Convenience: configure L2 persistence for model weights if the GPU supports it. /// @@ -198,6 +185,7 @@ pub fn reset_persisting_l2_cache() -> Result<(), String> { /// tracing::info!("L2 pinning active: {} MB reserved", reserved / 1_048_576); /// } /// ``` +#[cfg(feature = "cuda")] pub fn pin_weights_in_l2(gpu_name: &str, weight_bytes: usize) -> Result { if !supports_l2_persistence(gpu_name) { tracing::debug!( @@ -211,11 +199,12 @@ pub fn pin_weights_in_l2(gpu_name: &str, weight_bytes: usize) -> Result Result<(), String> { reset_persisting_l2_cache() } -#[cfg(test)] +#[cfg(all(test, feature = "cuda"))] #[allow(clippy::let_underscore_must_use)] mod tests { use super::*; diff --git a/crates/ml-dqn/src/dqn.rs b/crates/ml-dqn/src/dqn.rs index a4e12658d..466acc114 100644 --- a/crates/ml-dqn/src/dqn.rs +++ b/crates/ml-dqn/src/dqn.rs @@ -1367,32 +1367,19 @@ impl DQN { // GPU PER: on CUDA, allocate GPU-resident ring buffer (hard error on failure). // This activates the GpuBatch fast path in compute_loss_internal() and // GPU TD error retention — eliminating 5 of 6 CPU↔GPU roundtrips per train step. - #[cfg(feature = "cuda")] - { - if device.is_cuda() { - // GPU PER is mandatory on CUDA. - super::replay_buffer_type::ReplayBufferType::try_gpu_with_halving( - config.replay_buffer_capacity, - config.state_dim, - config.per_alpha, - config.per_beta_start, - config.per_beta_max, - config.per_beta_annealing_steps, - config.per_max_memory_bytes, - &device, - )? - } else { - super::replay_buffer_type::ReplayBufferType::new_prioritized( - config.replay_buffer_capacity, - config.per_alpha, - config.per_beta_start, - config.per_beta_max, - config.per_beta_annealing_steps, - )? - } - } - #[cfg(not(feature = "cuda"))] - { + if device.is_cuda() { + // GPU PER is mandatory on CUDA. + super::replay_buffer_type::ReplayBufferType::try_gpu_with_halving( + config.replay_buffer_capacity, + config.state_dim, + config.per_alpha, + config.per_beta_start, + config.per_beta_max, + config.per_beta_annealing_steps, + config.per_max_memory_bytes, + &device, + )? + } else { super::replay_buffer_type::ReplayBufferType::new_prioritized( config.replay_buffer_capacity, config.per_alpha, @@ -2476,14 +2463,7 @@ impl DQN { self.memory.sample(self.config.batch_size)? }; - #[cfg(feature = "cuda")] let gpu_batch_opt = batch_sample.gpu_batch; - // CPU-side experience/weight Vecs: only needed for non-CUDA tensor construction. - // In the CUDA path, gpu_batch tensors replace these entirely. - #[cfg(not(feature = "cuda"))] - let experiences = batch_sample.experiences; - #[cfg(not(feature = "cuda"))] - let weights = batch_sample.weights; let indices = batch_sample.indices; // Initialize optimizer if not done @@ -2590,62 +2570,9 @@ impl DQN { } // CUDA production: GpuBatch is mandatory — no CPU path. - #[cfg(feature = "cuda")] return Err(MLError::TrainingError( "GPU batch required — GPU PER is mandatory for DQN training.".to_owned(), )); - - // Non-CUDA (tests only): build tensors from experience data via Tensor::new. - #[cfg(not(feature = "cuda"))] - { - let batch_size = experiences.len(); - let state_dim = self.config.state_dim; - let (states, next_states, actions, rewards, dones) = experiences.iter().fold( - ( - Vec::with_capacity(batch_size * state_dim), - Vec::with_capacity(batch_size * state_dim), - Vec::::with_capacity(batch_size), - Vec::::with_capacity(batch_size), - Vec::::with_capacity(batch_size), - ), - |(mut s, mut ns, mut a, mut r, mut d), exp| { - s.extend_from_slice(&exp.state); - if exp.state.len() < state_dim { - s.resize(s.len() + state_dim - exp.state.len(), 0.0); - } - ns.extend_from_slice(&exp.next_state); - if exp.next_state.len() < state_dim { - ns.resize(ns.len() + state_dim - exp.next_state.len(), 0.0); - } - a.push(exp.action as u32); - r.push(exp.reward_f32()); - d.push(if exp.done { 1.0_f32 } else { 0.0_f32 }); - (s, ns, a, r, d) - }, - ); - - let states_tensor = Tensor::new(states.as_slice(), device) - .and_then(|t| t.reshape((batch_size, state_dim))) - .and_then(|t| t.to_dtype(candle_core::DType::BF16)) - .map_err(|e| MLError::TrainingError(format!("States tensor: {}", e)))?; - let next_states_tensor = Tensor::new(next_states.as_slice(), device) - .and_then(|t| t.reshape((batch_size, state_dim))) - .and_then(|t| t.to_dtype(candle_core::DType::BF16)) - .map_err(|e| MLError::TrainingError(format!("Next states tensor: {}", e)))?; - let actions_tensor = Tensor::new(actions.as_slice(), device) - .map_err(|e| MLError::TrainingError(format!("Actions tensor: {}", e)))?; - let rewards_tensor = Tensor::new(rewards.as_slice(), device) - .map_err(|e| MLError::TrainingError(format!("Rewards tensor: {}", e)))?; - let dones_tensor = Tensor::new(dones.as_slice(), device) - .map_err(|e| MLError::TrainingError(format!("Dones tensor: {}", e)))?; - let weights_tensor = Tensor::new(weights.as_slice(), device) - .and_then(|t| t.to_dtype(dtype)) - .map(|t| t.detach()) - .map_err(|e| MLError::TrainingError(format!("Weights tensor: {}", e)))?; - - break 'tensor_prep (batch_size, states_tensor, next_states_tensor, actions_tensor, - rewards_tensor, dones_tensor, Some(weights_tensor)); - } }; // Phase C+ branching loss path: independent advantage heads per action dimension. @@ -2938,33 +2865,21 @@ impl DQN { let loss_f32_tensor = loss_tensor.to_dtype(DType::F32)?; // TD errors for PER priority updates - #[cfg(feature = "cuda")] let is_gpu_per_br = self.memory.is_gpu_prioritized(); - #[cfg(not(feature = "cuda"))] - let is_gpu_per_br = false; - #[allow(unused_variables)] let (td_errors_vec, td_gpu, idx_gpu) = if self.config.use_per { if is_gpu_per_br { let td_tensor = td_errors_for_per.to_dtype(DType::F32)?; - #[cfg(feature = "cuda")] - { - let idx_tensor = gpu_batch_opt.as_ref() - .map(|gpu| gpu.indices.clone()) - .ok_or_else(|| MLError::TrainingError( - "GPU PER indices required (branching path) — CPU fallback removed".to_owned() - ))?; - (Vec::new(), Some(td_tensor), Some(idx_tensor)) - } - #[cfg(not(feature = "cuda"))] - return Err(MLError::TrainingError("GPU PER requires cuda feature".to_owned())) + let idx_tensor = gpu_batch_opt.as_ref() + .map(|gpu| gpu.indices.clone()) + .ok_or_else(|| MLError::TrainingError( + "GPU PER indices required (branching path) — CPU fallback removed".to_owned() + ))?; + (Vec::new(), Some(td_tensor), Some(idx_tensor)) } else { - #[cfg(feature = "cuda")] return Err(MLError::TrainingError( "CPU PER fallback disabled — use ReplayBufferType::GpuPrioritized when cuda is enabled".to_owned() )); - #[cfg(not(feature = "cuda"))] - (td_errors_for_per.to_dtype(DType::F32)?.to_vec1()?, None::, None::) } } else { (Vec::new(), None::, None::) @@ -3409,34 +3324,22 @@ impl DQN { // GPU SATURATION: Keep TD errors on GPU as Tensor — trainer uses // update_priorities_gpu() directly, zero CPU transfer. // CPU PER fallback is a hard error when cuda feature is enabled. - #[cfg(feature = "cuda")] let is_gpu_per = self.memory.is_gpu_prioritized(); - #[cfg(not(feature = "cuda"))] - let is_gpu_per = false; - #[allow(unused_variables)] // td_gpu/idx_gpu consumed in #[cfg(feature = "cuda")] struct fields let (td_errors_vec, td_gpu, idx_gpu) = if self.config.use_per { if is_gpu_per { // GPU PER: keep TD errors on GPU, use GpuBatch indices directly let td_tensor = diff.detach().to_dtype(DType::F32)?; - #[cfg(feature = "cuda")] - { - let idx_tensor = gpu_batch_opt.as_ref() - .map(|gpu| gpu.indices.clone()) - .ok_or_else(|| MLError::TrainingError( - "GPU PER indices required (non-branching path) — CPU fallback removed".to_owned() - ))?; - (Vec::new(), Some(td_tensor), Some(idx_tensor)) - } - #[cfg(not(feature = "cuda"))] - return Err(MLError::TrainingError("GPU PER requires cuda feature".to_owned())) + let idx_tensor = gpu_batch_opt.as_ref() + .map(|gpu| gpu.indices.clone()) + .ok_or_else(|| MLError::TrainingError( + "GPU PER indices required (non-branching path) — CPU fallback removed".to_owned() + ))?; + (Vec::new(), Some(td_tensor), Some(idx_tensor)) } else { - #[cfg(feature = "cuda")] return Err(MLError::TrainingError( "CPU PER fallback disabled — use ReplayBufferType::GpuPrioritized when cuda is enabled".to_owned() )); - #[cfg(not(feature = "cuda"))] - (diff.detach().to_dtype(DType::F32)?.to_vec1()?, None::, None::) } } else { (Vec::new(), None::, None::) @@ -3547,25 +3450,16 @@ impl DQN { self.training_steps += 1; // Update priorities for PER (if using prioritized replay) - #[cfg(feature = "cuda")] + if let (Some(ref td_gpu), Some(ref idx_gpu)) = + (&result.td_errors_gpu, &result.indices_gpu) { - if let (Some(ref td_gpu), Some(ref idx_gpu)) = - (&result.td_errors_gpu, &result.indices_gpu) - { - self.memory.update_priorities_gpu(idx_gpu, td_gpu)?; - } else if !result.indices.is_empty() { - self.memory - .update_priorities(&result.indices, &result.td_errors)?; - } else { - // No priorities to update (empty batch or non-PER path) - } - } - #[cfg(not(feature = "cuda"))] - if !result.indices.is_empty() { + self.memory.update_priorities_gpu(idx_gpu, td_gpu)?; + } else if !result.indices.is_empty() { self.memory .update_priorities(&result.indices, &result.td_errors)?; + } else { + // No priorities to update (empty batch or non-PER path) } - // Step beta annealing for PER self.memory.step(); @@ -3659,7 +3553,6 @@ impl DQN { let result = self.compute_loss_internal(batch)?; // Backward + clip WITHOUT optimizer step — zero GPU→CPU sync - #[cfg(feature = "cuda")] let (grads, grad_norm_tensor) = if let Some(ref optimizer) = self.optimizer { optimizer.backward_and_clip(&result.loss_tensor, self.gradient_clip_norm)? } else { @@ -3667,14 +3560,6 @@ impl DQN { "Optimizer not initialized".to_owned(), )); }; - #[cfg(not(feature = "cuda"))] - let (grads, _grad_norm_tensor) = if let Some(ref optimizer) = self.optimizer { - optimizer.backward_and_clip(&result.loss_tensor, self.gradient_clip_norm)? - } else { - return Err(MLError::TrainingError( - "Optimizer not initialized".to_owned(), - )); - }; // Squeeze grad_norm from [1] → rank-0 scalar tensor (cuda only — used by GPU accumulation path) #[cfg(feature = "cuda")] diff --git a/crates/ml-dqn/src/replay_buffer_type.rs b/crates/ml-dqn/src/replay_buffer_type.rs index aa47fae64..f804e0f8b 100644 --- a/crates/ml-dqn/src/replay_buffer_type.rs +++ b/crates/ml-dqn/src/replay_buffer_type.rs @@ -493,10 +493,7 @@ impl ReplayBufferType { /// Check if using GPU-resident prioritized replay. /// Returns false when compiled without `cuda` feature (variant doesn't exist). pub const fn is_gpu_prioritized(&self) -> bool { - #[cfg(feature = "cuda")] - { matches!(self, Self::GpuPrioritized(_)) } - #[cfg(not(feature = "cuda"))] - { false } + matches!(self, Self::GpuPrioritized(_)) } /// Adaptive buffer sizing based on epsilon decay diff --git a/crates/ml-dqn/src/training_guard_gpu_tests.rs b/crates/ml-dqn/src/training_guard_gpu_tests.rs index 27cbb6f47..2b22554e0 100644 --- a/crates/ml-dqn/src/training_guard_gpu_tests.rs +++ b/crates/ml-dqn/src/training_guard_gpu_tests.rs @@ -237,15 +237,6 @@ mod tests { } } - // Without the cuda feature, verify the source file is readable and intact. - #[cfg(not(feature = "cuda"))] - { - assert!(!src.is_empty(), "training_guard_kernel.cu should not be empty"); - assert!( - src.contains("training_guard_check"), - "kernel source must contain training_guard_check" - ); - } } // ════════════════════════════════════════════════════════════════════════ diff --git a/crates/ml/build.rs b/crates/ml/build.rs index 7cfac296f..c2bce4fe2 100644 --- a/crates/ml/build.rs +++ b/crates/ml/build.rs @@ -1,20 +1,3 @@ -//! Build script for ML crate - CUDA support conditional -//! -//! Enables CUDA when the 'cuda' feature is enabled, otherwise CPU-only - fn main() { println!("cargo:rerun-if-changed=build.rs"); - - // Only set cpu_only_build when CUDA feature is NOT enabled - #[cfg(not(feature = "cuda"))] - { - println!("cargo:rustc-cfg=cpu_only_build"); - println!("cargo:info=Building CPU-only ML crate"); - } - - #[cfg(feature = "cuda")] - { - println!("cargo:info=Building ML crate with CUDA support"); - // CUDA-specific configuration can go here if needed - } } diff --git a/crates/ml/examples/evaluate_baseline.rs b/crates/ml/examples/evaluate_baseline.rs index d0a5efd66..34b1ff2ac 100644 --- a/crates/ml/examples/evaluate_baseline.rs +++ b/crates/ml/examples/evaluate_baseline.rs @@ -1963,10 +1963,6 @@ fn main() -> Result<()> { false // --no-gpu-eval was set; use CPU path }; - // When compiled without CUDA, gpu_handled is always false. - #[cfg(not(feature = "cuda"))] - let gpu_handled = false; - if !gpu_handled { match evaluate_dqn_fold( window.fold, @@ -2198,9 +2194,6 @@ fn main() -> Result<()> { false }; - #[cfg(not(feature = "cuda"))] - let gpu_handled = false; - if !gpu_handled { warn!( " [{}] Fold {} - GPU eval not available; use evaluate_supervised binary for CPU eval", diff --git a/crates/ml/src/hyperopt/adapters/dqn.rs b/crates/ml/src/hyperopt/adapters/dqn.rs index 4bbb95bb2..585666188 100644 --- a/crates/ml/src/hyperopt/adapters/dqn.rs +++ b/crates/ml/src/hyperopt/adapters/dqn.rs @@ -3132,8 +3132,6 @@ impl HyperparameterOptimizable for DQNTrainer { None } } - #[cfg(not(feature = "cuda"))] - { None } }; if let Some(metrics) = gpu_result { @@ -3247,10 +3245,6 @@ impl HyperparameterOptimizable for DQNTrainer { cuda_dev.synchronize() .map_err(|e| MLError::TrainingError(format!("CUDA synchronize between trials FAILED — GPU in bad state: {e}")))?; } - #[cfg(not(feature = "cuda"))] - { - // CPU-only: no GPU sync needed - } info!("Resource cleanup complete"); // MEMORY LEAK FIX: Monitor memory usage after trial diff --git a/crates/ml/src/hyperopt/adapters/ppo.rs b/crates/ml/src/hyperopt/adapters/ppo.rs index e91038fa3..2345c4ec2 100644 --- a/crates/ml/src/hyperopt/adapters/ppo.rs +++ b/crates/ml/src/hyperopt/adapters/ppo.rs @@ -1007,21 +1007,6 @@ impl HyperparameterOptimizable for PPOTrainer { #[cfg(feature = "cuda")] self.ensure_gpu_data(&training_data, &ppo_agent)?; - // CPU path uses curiosity/reward shaping modules; GPU path handles these internally. - #[cfg(not(feature = "cuda"))] - let mut curiosity_module = (params.curiosity_weight > 0.001) - .then(|| { - info!("Curiosity-driven exploration enabled (weight={:.3})", params.curiosity_weight); - CuriosityModule::new(trial_device.clone(), 0.001, 2.0, 42, 128, 3) - }) - .transpose()?; - #[cfg(not(feature = "cuda"))] - let curiosity_weight = params.curiosity_weight; - #[cfg(not(feature = "cuda"))] - let mut reward_shaper = Some(PPORewardShaper::default()); - #[cfg(not(feature = "cuda"))] - let mut composite_reward = Some(CompositeReward::new()); - // Create ExO-PPO trajectory replay buffer (M=4 rollouts, 4x sample efficiency) let mut replay_buffer = TrajectoryReplayBuffer::new(4, params.clip_epsilon as f32); info!("ExO-PPO trajectory replay enabled (M=4 rollouts)"); @@ -1036,18 +1021,8 @@ impl HyperparameterOptimizable for PPOTrainer { for _batch_idx in 0..num_batches { let episodes_this_batch = batch_episodes.min(num_train - _batch_idx * batch_episodes); - // GPU experience collection — no CPU fallback when CUDA enabled - #[cfg(feature = "cuda")] + // GPU experience collection let mut trajectory_batch = self.gpu_collect_trajectories(episodes_this_batch)?; - #[cfg(not(feature = "cuda"))] - let mut trajectory_batch = self.generate_trajectories_from_data( - &ppo_agent, train_data, episodes_this_batch, - &mut curiosity_module, curiosity_weight, - &mut reward_shaper, &mut composite_reward, - gae_gamma, gae_lambda, &trial_device, - ).map_err(|e| { - MLError::TrainingError(format!("Failed to generate trajectories: {}", e)) - })?; // Update PPO with on-policy trajectory batch let (policy_loss, value_loss) = ppo_agent @@ -1145,8 +1120,7 @@ impl HyperparameterOptimizable for PPOTrainer { let avg_value_loss = total_value_loss / num_batches as f64; let avg_reward = total_reward / num_batches as f64; - // GPU walk-forward backtest (CUDA only, graceful fallback to None) - #[cfg(feature = "cuda")] + // GPU walk-forward backtest let (bt_sharpe, bt_trades) = if trial_device.is_cuda() { match self.run_gpu_backtest(&ppo_agent, &trial_device, ¶ms) { Ok((s, t)) => { @@ -1160,8 +1134,6 @@ impl HyperparameterOptimizable for PPOTrainer { } else { (None, None) }; - #[cfg(not(feature = "cuda"))] - let (bt_sharpe, bt_trades): (Option, Option) = (None, None); let metrics = PPOMetrics { policy_loss: avg_policy_loss, diff --git a/crates/ml/src/trainers/ppo.rs b/crates/ml/src/trainers/ppo.rs index e12f1667e..d497afe15 100644 --- a/crates/ml/src/trainers/ppo.rs +++ b/crates/ml/src/trainers/ppo.rs @@ -16,10 +16,7 @@ use candle_core::Device; #[cfg(feature = "cuda")] use common::metrics::training_metrics; use tokio::sync::Mutex; -#[cfg(feature = "cuda")] use tracing::{debug, info, warn}; -#[cfg(not(feature = "cuda"))] -use tracing::{debug, info}; use crate::common::action::FactoredAction; use crate::gpu::DeviceConfig; @@ -459,17 +456,7 @@ impl PpoTrainer { self.hyperparams.epochs ); - #[cfg(feature = "cuda")] - return self.train_gpu(market_data, progress_callback).await; - - #[cfg(not(feature = "cuda"))] - { - drop(market_data); - drop(progress_callback); - Err(MLError::TrainingError( - "PPO training requires CUDA — CPU training path has been removed".to_owned(), - )) - } + self.train_gpu(market_data, progress_callback).await } #[cfg(feature = "cuda")] diff --git a/crates/ml/src/validation/harness.rs b/crates/ml/src/validation/harness.rs index c5b62ab61..43727bbbd 100644 --- a/crates/ml/src/validation/harness.rs +++ b/crates/ml/src/validation/harness.rs @@ -237,9 +237,7 @@ impl ValidationHarness { // 8. Per-regime breakdown (GPU when available, CPU fallback) let per_regime_metrics = { - #[cfg(feature = "cuda")] { - // Try GPU classification first; fall back to CPU on any error. let cuda_device = candle_core::Device::cuda_if_available(0); match cuda_device { Ok(ref dev) if dev.is_cuda() => { @@ -249,10 +247,6 @@ impl ValidationHarness { _ => per_regime_breakdown(&all_returns, &all_features), } } - #[cfg(not(feature = "cuda"))] - { - per_regime_breakdown(&all_returns, &all_features) - } }; // 9. Verdict diff --git a/testing/integration/gpu/cuda_initialization_test.rs b/testing/integration/gpu/cuda_initialization_test.rs index f08597785..d8e18f0ac 100644 --- a/testing/integration/gpu/cuda_initialization_test.rs +++ b/testing/integration/gpu/cuda_initialization_test.rs @@ -97,10 +97,6 @@ mod tests { } } - #[cfg(not(feature = "cuda"))] - { - info!("⚠️ CUDA feature not enabled - skipping device properties test"); - } } #[test] diff --git a/testing/integration/gpu/cuda_kernel_test.rs b/testing/integration/gpu/cuda_kernel_test.rs index 8de43d058..9c169ebde 100644 --- a/testing/integration/gpu/cuda_kernel_test.rs +++ b/testing/integration/gpu/cuda_kernel_test.rs @@ -342,22 +342,6 @@ mod tests { } } - #[cfg(not(feature = "cuda"))] - #[test] - fn test_cuda_feature_disabled() { - init_gpu_test_env(); - info!("⚠️ CUDA feature not enabled - testing graceful handling"); - - // Test that the system handles missing CUDA gracefully - assert!(!cuda_available(), "CUDA should not be available when feature is disabled"); - - // Test that we can still get a CPU device - let device = get_test_device(); - assert!(!device.is_cuda(), "Should fallback to CPU device"); - - info!("✅ Graceful CUDA feature disabled handling verified"); - } - #[test] fn test_cuda_kernel_integration_framework() { init_gpu_test_env(); diff --git a/testing/integration/gpu/mod.rs b/testing/integration/gpu/mod.rs index 9aa9159c5..b3e87a1ad 100644 --- a/testing/integration/gpu/mod.rs +++ b/testing/integration/gpu/mod.rs @@ -33,14 +33,7 @@ pub mod utils { /// Check if CUDA is available for testing pub fn cuda_available() -> bool { - #[cfg(feature = "cuda")] - { - cudarc::driver::CudaDevice::new(0).is_ok() - } - #[cfg(not(feature = "cuda"))] - { - false - } + cudarc::driver::CudaDevice::new(0).is_ok() } /// Get test device (CUDA if available, CPU otherwise) diff --git a/testing/integration/gpu/production_gpu_integration_test.rs b/testing/integration/gpu/production_gpu_integration_test.rs index 0207530d1..8ea304c6a 100644 --- a/testing/integration/gpu/production_gpu_integration_test.rs +++ b/testing/integration/gpu/production_gpu_integration_test.rs @@ -403,11 +403,6 @@ mod tests { } } - #[cfg(not(feature = "cuda"))] - { - info!("GPU monitoring fallback - CUDA feature not enabled"); - } - info!("✅ Production GPU monitoring test completed"); }