Commit Graph

2782 Commits

Author SHA1 Message Date
jgrusewski
359f847026 docs: add S3 binary share implementation plan (15 tasks)
Detailed step-by-step plan covering: S3 bucket creation, CI builder
updates, 3 base image Dockerfiles, CI pipeline rewiring, 8 cache PVCs,
all service deployment YAML updates, training job template, and cleanup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 17:50:37 +01:00
jgrusewski
df20ed74d4 docs: add S3 binary share design — eliminate Docker builds, faster pod startup
Replace per-service Docker images with generic base images + S3-based binary
distribution. CI compiles and uploads stripped binaries to S3. Pods fetch
binaries via initContainer with PVC cache fallback for trading resilience.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 17:46:13 +01:00
jgrusewski
40febb0061 fix(cuda): enable GPU experience collection for regime-conditional DQN
The GPU experience collector only supported DQNAgentType::Standard, but
enable_regime_qnetwork defaults to true, creating RegimeConditional
agents. This silently fell back to CPU with a debug! message invisible
at INFO log level.

- Add primary_head() accessor to RegimeConditionalDQN (returns trending head)
- Extract weights from primary head for both collector init and weight sync
- Upgrade debug! to warn! for missing GPU collection prerequisites
- Add warn! to PPO for silent GPU skip when raw market data not uploaded

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 17:01:01 +01:00
jgrusewski
5a27bde9dd fix(ci): add NVRTC to training image for GPU experience kernel JIT compilation
The GPU experience collection kernels (dqn_experience_kernel.cu,
ppo_experience_kernel.cu) use cudarc::nvrtc::compile_ptx() at runtime.
Without libnvrtc.so the kernel compile fails silently and falls back to
CPU experience collection. Adding cuda-nvrtc-12-4 (~30MB) enables full
GPU-accelerated experience collection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:07:00 +01:00
jgrusewski
6d97277b80 refactor(infra): consolidate training-rl and training-supervised into single training image
Both images now use identical cuda:12.4.1-cudnn-runtime base, so maintaining
two separate Dockerfiles and build jobs was wasteful. Single image contains
all 7 training binaries, halving registry storage and Kaniko build time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 15:26:07 +01:00
jgrusewski
4ab97f7698 fix(ci): add cuDNN to training-rl image for CUDA pipeline
candle's CUDA backend links against libcudnn.so.9 for kernel operations.
Switch training-rl base from cuda:12.4.1-runtime to cuda:12.4.1-cudnn-runtime.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 15:10:02 +01:00
jgrusewski
fa74f9afcf fix(cuda): add missing gpu_portfolio.rs and experience_kernels.cu files
These files were part of the Phase 2 cuda_pipeline but were untracked
and not included in previous commits. Required for compilation with
--features ml/cuda.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 14:41:54 +01:00
jgrusewski
9b2804f9ec feat(cuda): wire GPU experience collection into DQN & PPO training loops
Phase 3 of the CUDA pipeline: both trainers now take a GPU-first path
for experience collection (128×500 = 64K experiences per kernel launch,
zero CPU-GPU roundtrips per timestep) with automatic CPU fallback.

- DQN: upload features alongside targets, GPU collection branch before
  CPU loop, gpu_batch_to_experiences() conversion into replay buffer
- PPO: set_raw_market_data() for CudaSlice upload, GPU collection
  branch bypasses collect_rollouts + prepare_training_batch entirely,
  gpu_batch_to_trajectory_batch() conversion with in-kernel GAE
- Configurable GPU batch sizes (gpu_n_episodes, gpu_timesteps_per_episode)
  and trading params (initial_capital, avg_spread) via hyperparameters
- SAFETY training diagnostics downgraded from warn! to debug!
- 4 new batch index-math validation tests in cuda_pipeline

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 14:14:48 +01:00
jgrusewski
d4b22910d7 fix(ppo): replace wildcard match with explicit Device variants for clippy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:38:42 +01:00
jgrusewski
341514a4b0 feat(ppo): integrate GPU experience collector with weight sync
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:32:57 +01:00
jgrusewski
50b360c23c test(cuda): add PPO collector config defaults and source concatenation tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:30:58 +01:00
jgrusewski
6b4c309760 feat(cuda): add GpuPpoExperienceCollector with zero-roundtrip kernel launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:29:24 +01:00
jgrusewski
141aa46848 feat(cuda): add PPO actor/critic weight extraction and GPU upload
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:25:20 +01:00
jgrusewski
4c22b15ca4 feat(cuda): add PPO experience kernel — actor, critic, GAE, full rollout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:20:45 +01:00
jgrusewski
dfcc19538a refactor(cuda): extract shared device functions to common_device_functions.cuh
Move 10 shared device functions (gpu_random, leaky_relu, matvec_leaky_relu,
action_to_exposure, action_to_tx_cost, barrier_init/check/reset,
diversity_entropy, curiosity_inference) and shared constants from
dqn_experience_kernel.cu into a new common_device_functions.cuh header.

The DQN kernel now expects the common header to be prepended via NVRTC
source concatenation at compile time. DQN-specific functions
(q_forward_dueling, argmax_q) remain in the kernel file. This enables
the upcoming PPO kernel to reuse the same shared functions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:14:55 +01:00
jgrusewski
f0f779a971 docs: add PPO CUDA pipeline Phase 2c implementation plan — 11 tasks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:07:20 +01:00
jgrusewski
a38dd64a71 docs: add PPO CUDA pipeline Phase 2c design — zero-roundtrip experience collection
Single monolithic kernel with in-kernel GAE, full portfolio simulation,
shared device functions header, 5-layer critic matching trainer exactly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:59:45 +01:00
jgrusewski
e7a6814045 feat(dqn): integrate GPU experience collector with weight sync
Adds GpuExperienceCollector field to DQNTrainer, initializes it when
dueling networks and curiosity module are present on CUDA device, and
syncs GPU weight copies after each training epoch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:34:23 +01:00
jgrusewski
b43070ee6c test(cuda): add unit tests for weight extraction, kernel source, and experience config
Adds 4 tests:
- gpu_weights: verify all 12 VarMap key paths exist with correct shapes
- gpu_weights: verify total parameter count matches spec (151,598)
- mod: verify kernel source contains entry-point function name
- mod: verify ExperienceCollectorConfig defaults and total_experiences()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:25:08 +01:00
jgrusewski
260981b20a feat(cuda): add GpuExperienceCollector with zero-roundtrip kernel launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:20:28 +01:00
jgrusewski
86c81f21d4 feat(cuda): add weight extraction module for Q-network and curiosity GPU upload
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:15:43 +01:00
jgrusewski
39158ecab2 fix(cuda): spec compliance — barrier_done, step_in_episode, diversity penalty
Three fixes from spec review:
1. diversity_entropy returns -0.1 penalty (threshold < 1.0) instead of raw entropy
2. barrier_done included in episode termination (barrier hit ends episode)
3. step_in_episode counter resets properly on mid-loop episode reset

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:10:36 +01:00
jgrusewski
adf248f383 feat(cuda): add zero-roundtrip DQN experience collection kernel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:03:27 +01:00
jgrusewski
5c23c79a1c docs: add Phase 2b implementation plan — 10 tasks for zero-roundtrip kernel
Detailed task-by-task plan for implementing the full GPU experience
collection pipeline:

Task 1-3: CUDA kernel (Q-network, curiosity, barrier, diversity, reward)
Task 4: Weight extraction module (VarMap → CudaSlice)
Task 5: GPU experience collector (Rust wrapper + buffer management)
Task 6: Unit tests for weights and kernel compilation
Task 7: DQN trainer integration (GPU round-based collection)
Task 8: Periodic curiosity training with weight sync
Task 9: Workspace verification (2392+ tests, clippy)
Task 10: Final commit and branch completion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 11:58:30 +01:00
jgrusewski
fccd703bcb docs: add GPU pipeline Phase 2b design — zero-roundtrip CUDA experience collection
Full design for monolithic CUDA kernel that runs the entire DQN
experience collection pipeline on GPU: Dueling Q-network inference
(online + target), epsilon-greedy action selection, portfolio
simulation, barrier tracking, diversity entropy, curiosity inference,
and reward combination. 128 parallel episodes × 500 timesteps =
64,000 experiences per kernel launch with zero CPU roundtrips.

Key decisions:
- Approach A (monolithic kernel) for speed + accuracy
- Parallel episode architecture (N threads × L timesteps)
- Q-network + curiosity inference in raw CUDA (matrix-vector multiply)
- Curiosity training stays on Candle (periodic batch updates)
- TD error pre-computed for priority replay
- Weight sync after gradient updates (~1.2MB upload)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 11:51:43 +01:00
jgrusewski
c731bef759 feat(infra): split training image into RL + supervised, rename ci-compile → ci-rl
RL models (DQN/PPO) only need basic CUDA runtime (~2GB), while supervised
models need cuDNN (~4GB). Splitting saves ~2GB pull time per RL job.
Rename the L4 GPU pool from ci-compile to ci-rl to reflect its actual use.
Add DaemonSet image pre-puller to cache training images on GPU nodes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 10:16:42 +01:00
jgrusewski
f9b57cdecb feat(trading_engine): migrate OrderRequest to FinancialPrice/FinancialQuantity
Replace raw f64 price/quantity in SmallBatchOptimizer with typed
financial values. Conversion to f64 happens at the SIMD boundary
(_mm256_loadu_pd) only. Delete 3 orphaned dead-code files:
financial_safe.rs, simd_optimizations.rs, tests/financial_tests.rs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 10:10:18 +01:00
jgrusewski
acf77461cb feat(common): re-export financial_types as FinancialPrice/Quantity/Money/Ratio
Aliased re-exports avoid collision with existing types::Price/Quantity/Money
during migration. Will rename to canonical names in Phase 6 cleanup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 09:49:00 +01:00
jgrusewski
c745693420 fix(common): seal Ratio finite invariant and i128→i64 saturation
- Ratio arithmetic (Add, Sub, Mul, Div) now clamps overflow to
  f64::MAX/f64::MIN instead of producing Inf from finite inputs
- Cross-type Price*Quantity→Money and Money/Quantity→Price use
  saturating i128→i64 conversion via clamp instead of silent truncation
- Added clamp_finite() and saturating_i128_to_i64() helper functions
- Added 9 edge-case tests: 89/89 passing, clippy clean

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 09:47:52 +01:00
jgrusewski
bc5a333402 fix(ci): serialize compile jobs — CPU pool fits one 28-core job at a time
compile-training now needs compile-services. Both request 28 vCPUs but
the ci-compile-cpu pool (POP2-32C-128G) has only 32 vCPUs total.
Build-services jobs start as soon as compile-services finishes while
compile-training runs; no wall-clock penalty.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 09:45:46 +01:00
jgrusewski
00b57f6f94 fix(ci): route compile-training to CPU node pool with CUDA stubs
compile-training was stuck on GPU node autoscale (L4 pool) but only
needs CUDA stubs for candle-kernels PTX generation, not a real GPU.
Switch to .rust-base-cpu (ci-compile-cpu pool) with ci-builder image
override for CUDA stubs. Unify pool labels — all compilation on CPU.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 09:41:05 +01:00
jgrusewski
0d68bfdd11 fix(common): add serde derives, preserve Ratio finite invariant
- Add Serialize/Deserialize to all four financial types
- Ratio::ln returns 0.0 for non-positive inputs (prevents NaN leak)
- Ratio::exp clamps to f64::MAX on overflow (prevents Inf leak)
- Ratio::powi clamps to f64::MAX/MIN on overflow
- Add 4 invariant-preservation tests (80 total)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 09:39:22 +01:00
jgrusewski
85eab3eca2 feat(common): add financial_types module (Price/Quantity/Money/Ratio i64/6dp)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 09:33:13 +01:00
jgrusewski
d78b163613 Merge branch 'feature/cuda-pipeline' (GPU data pre-upload for DQN/PPO)
Phase 1 of GPU pipeline: eliminates per-bar/per-step heap allocations
by pre-uploading training data as GPU tensors at epoch start.

- New cuda_pipeline module with DqnGpuData + PpoGpuData structs
- DQN: bulk upload [N,51] features + [N,4] targets, narrow() slices
- PPO: bulk upload [N,state_dim] states, zero-copy per-step access
- VRAM safety guards (2GB limit) and estimation utilities
- 8 new tests, 2411 total ML tests passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 09:28:19 +01:00
jgrusewski
388f54dd06 feat(dqn): pre-upload training data to GPU, use cached targets in hot loop
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:49:10 +01:00
jgrusewski
10b139c029 feat(cuda_pipeline): add VRAM estimation and safety guards
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:48:58 +01:00
jgrusewski
3cfa99de3f feat(ppo): pre-upload rollout states to GPU, eliminate per-step tensor allocs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:48:33 +01:00
jgrusewski
3883284219 feat(ml): add cuda_pipeline module with GPU data pre-upload for DQN/PPO
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:45:48 +01:00
jgrusewski
43754bf5d5 docs: numeric type standardization implementation plan
12-worktree phased migration: foundation types → core crates →
ML boundary → services → peripheral → cleanup. Full code for
Phase 1 (Price/Quantity/Money/Ratio in common/financial_types),
migration patterns for Phases 2-6.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:37:53 +01:00
jgrusewski
de3a807670 docs: numeric type standardization design (i64/6dp financial types)
Consolidate competing Price/Quantity implementations into canonical
i64 fixed-point types in common/. Adds Money and Ratio newtypes.
Phased migration plan across 5 phases using parallel worktrees.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:32:46 +01:00
jgrusewski
52630a77d3 perf: eliminate heap-alloc Decimal→float casts across 19 files (36 instances)
Replace all `.to_string().parse::<f32/f64>()` patterns with
`num_traits::ToPrimitive` methods (`.to_f32()`, `.to_f64()`).
Each string roundtrip heap-allocated per conversion — fatal in
DQN hot loop (300K+ bars × epochs). Decimal stays as canonical
financial type; conversions happen at GPU/float boundaries only.

Also fixes blocking_read() in async context (risk_integration.rs).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:29:04 +01:00
jgrusewski
35ac61b68d chore(ml): downgrade P2-C reversal warns to debug, delete stale patch
P2-C reversal/cash warns fire thousands of times per hyperopt trial
during backtest simulation. Also removes stale Kelly patch file (already
applied).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 01:13:37 +01:00
jgrusewski
5579efe7b1 chore(ml): downgrade portfolio-feature warns to debug
These fire every training step when portfolio isn't populated yet —
extremely noisy during hyperopt with parallel trials.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 01:10:36 +01:00
jgrusewski
21a8e3410f fix(hyperopt): require GPU for RL hyperopt, propagate device to trainers
The previous "auto-detect" logic forced CPU which was wrong — GPU is
faster for forward/backward even with parallel trials (DQN/PPO use
<350MB of 24GB VRAM across 7 threads).

Changes:
- Remove --device flag, always require CUDA GPU
- Add DQNTrainer::new_with_device() to share CUDA context across trials
- Propagate hyperopt device to internal DQN trainer (was ignoring it)
- PPO/DQN adapters error on missing GPU instead of silent CPU fallback
- Downgrade batch-size clamping from warn to debug

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 01:08:46 +01:00
jgrusewski
623d4b52ae fix(docker): correct web-gateway binary path after CI compile split
The compile-services stage outputs binaries to build-out/services/ but
the web-gateway Dockerfile still referenced the old build-out/ path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:59:33 +01:00
jgrusewski
9c503f002a feat(infra): scale CPU compile pool to max 4 nodes
POP2-32C-128G pool now allows up to 4 concurrent nodes for parallel
CI compilation (services + training + builder image builds).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:43:08 +01:00
jgrusewski
fc48395ad1 Merge branch 'worktree-training-deploy' (CPU pipeline split) 2026-02-28 00:23:20 +01:00
jgrusewski
829d05e870 feat(ci): split compile pipeline into CPU services and CUDA training
- Add CI_BUILDER_CPU_IMAGE variable and build-ci-builder-cpu prepare job
- Add .rust-base-cpu template (no CUDA_COMPUTE_CAP)
- Split compile-services into compile-services (CPU) and compile-training (CUDA)
- Split .kaniko-base into .kaniko-service-base and .kaniko-training-base
- Service builds use build-out/services/, training uses build-out/training/
- Each compile job has conditional changes: rules for its source paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:21:23 +01:00
jgrusewski
c328e3eb3a fix(ci): make infra-plan dependency optional for API/web pipelines
infra-apply needs infra-plan, but infra-plan only runs when infra/**
changes. API/web-triggered pipelines fail to create because the
dependency doesn't exist. Adding optional: true allows infra-apply
to run without infra-plan for manual triggers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:20:08 +01:00
jgrusewski
d4bd3d9465 feat(ci): add CUDA-free CI builder image for service compilation
Based on rust:1.89-slim-bookworm (~2-3GB vs ~8GB CUDA devel).
Same toolchain: mold 2.35, protoc 28.3, sccache 0.10, clang, lld.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:16:28 +01:00