test: fix dqn_action_collapse_fix_test for GPU composite reward

- Replace test_hold_penalty_weight_used_directly with
  test_idle_penalty_in_gpu_composite_reward (verifies w_idle > 0)
- Update hyperopt dimension assertions from 31D to 38D
  (7 composite reward weight dimensions added in prior commit)

All integration tests pass:
- dqn_training_smoke_test: 1/1
- hyperopt lib tests: 134/134
- dqn_action_collapse_fix_test: 10/10
- dqn_early_stopping_termination_test: 4/4

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-03-22 21:32:35 +01:00
parent 660b3f5b50
commit 3e8718468f

View File

@@ -197,23 +197,19 @@ async fn test_trainer_sets_hold_reward_zero() -> Result<()> {
}
#[test]
fn test_hold_penalty_weight_used_directly() {
use ml::dqn::reward::RewardConfig;
fn test_idle_penalty_in_gpu_composite_reward() {
use ml::trainers::dqn::DQNHyperparameters;
// The hold_penalty_weight in RewardConfig should be applied directly
// (old code divided by 1000, making it negligible)
// The fix is in reward.rs line 931: uses self.config.hold_penalty_weight directly
let config = RewardConfig::default();
// Verify hold_penalty_weight is a meaningful value (0.01 = 1%)
let weight: f64 = config.hold_penalty_weight.try_into().unwrap_or(0.0);
// hold_penalty_weight was removed from RewardConfig. Idle penalty is now
// handled by w_idle in the GPU composite reward kernel. Verify w_idle is
// a meaningful default in DQNHyperparameters.
let hp = DQNHyperparameters::default();
assert!(
weight >= 0.001,
"hold_penalty_weight should be >= 0.001 (meaningful), got {}",
weight
hp.w_idle > 0.0,
"w_idle should be > 0 (meaningful idle penalty), got {}",
hp.w_idle
);
// The weight is now used directly: penalty = -hold_penalty_weight
// Old code: penalty = -hold_penalty_weight / 1000 = negligible
// w_idle goes directly to the GPU kernel launch args — no CPU reward path.
}
// ── 4. Hyperopt 26D search space includes cql_alpha ────────────────────────
@@ -226,16 +222,16 @@ fn test_hyperopt_26d_includes_cql_alpha() {
let bounds = DQNParams::continuous_bounds();
assert_eq!(
bounds.len(),
31,
"Search space should be 31D (C7: added iqn_lambda), got {}D",
38,
"Search space should be 38D (31 base + 7 composite reward weights), got {}D",
bounds.len()
);
let names = DQNParams::param_names();
assert_eq!(
names.len(),
31,
"param_names should return 31 entries, got {}",
38,
"param_names should return 38 entries, got {}",
names.len()
);
@@ -300,7 +296,7 @@ fn test_hyperopt_cql_alpha_round_trip() {
params.cql_alpha = 0.25;
let continuous = params.to_continuous();
assert_eq!(continuous.len(), 31);
assert_eq!(continuous.len(), 38);
let reconstructed =
DQNParams::from_continuous(&continuous).expect("from_continuous should succeed");