Files
foxhunt/crates/ml-alpha/cuda/rl_increment_step.cu
jgrusewski a7c1d763d8 perf(rl): device-resident step counter + fused controllers (-9 launches)
Two CUDA Graph prerequisites implemented:

1. Device-resident step counter (ISV[548]):
   - New rl_increment_step.cu kernel (single thread, ISV += 1)
   - All kernels that took current_step as scalar now read from ISV
   - Updated: confidence_gate, frd_gate, unit_state_update,
     trade_context_update, gate_threshold_controller
   - Enables CUDA Graph capture (no scalar arg changes between replays)

2. Fused controllers (rl_fused_controllers.cu):
   - Combines 10 single-thread controllers into 1 kernel launch:
     gamma, tau, ppo_clip, entropy, rollout_steps, per_alpha,
     reward_scale (with ±2% clamp), ppo_ratio_clamp,
     gate_threshold, q_distill_lambda
   - Saves 9 kernel launches per step (~40-80μs)
   - Individual .cu files retained for testing/documentation

ISV slot 548 (step counter). Local smoke: 100 steps, no crash.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 21:35:50 +02:00

21 lines
823 B
Plaintext

// rl_increment_step.cu — bump the device-resident step counter.
//
// Single thread (grid=1, block=1), runs once per step at the very start
// of the step_with_lobsim pipeline, BEFORE any kernel that reads
// current_step. Kernels read `(int)isv[RL_STEP_COUNTER_ISV_INDEX]`
// instead of receiving `int current_step` as a scalar argument. This
// makes ALL kernel argument lists constant across calls, enabling CUDA
// Graph capture (scalar args can't change between replays).
//
// Per `feedback_no_atomicadd`: single thread, no atomics.
// Per `feedback_cpu_is_read_only`: pure device-side increment.
#define RL_STEP_COUNTER_ISV_INDEX 548
extern "C" __global__ void rl_increment_step(
float* __restrict__ isv
) {
if (threadIdx.x != 0 || blockIdx.x != 0) return;
isv[RL_STEP_COUNTER_ISV_INDEX] += 1.0f;
}