feat(cpp/datascience): GPU Monte Carlo kernels (K1-K3)
Tres kernels Monte Carlo intensivos sobre las primitivas G1-G7 + las puras CPU como oraculo de tests numericos. Apuntados a hyper-paralelizar los calculadores de sources/calculadoras (vr_tiered_lab, mcmc-bayes / full / lab, mcmc-visualizer) en RTX-class GPUs. - mc_session_sim_gpu (K1): N sesiones independientes de K spins en paralelo (1 thread = 1 sesion). Modelo variable-ratio escalonado con tiers (q, m), modes Pure/Pity/Streak, miss_streak, drawdown. SSBOs summary[N*8] y tier_counts[N*max_tiers]. Portea vr_tiered_lab. - mc_metropolis_hastings_gpu (K2): M cadenas independientes 1D. Target log-pdf inyectable como string GLSL (mismo patron de gl_shader). u_user[16] para cambiar parametros desde sliders sin recompilar. Output compatible con rhat_split / ess_basic. - mc_random_walk_2d_gpu (K3): walkers 2D MH con trace_xy xy-interleaved en SSBO; pasable directamente a gpu_histogram_2d sin readback intermedio. Pipeline GPU-only para mcmc-visualizer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
---
|
||||
name: mc_session_sim_gpu
|
||||
kind: function
|
||||
lang: cpp
|
||||
domain: datascience
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "McSessionSim mc_session_sim_create(int n_sessions, int max_tiers); void mc_session_sim_reseed(McSessionSim&, uint64 seed); void mc_session_sim_run(McSessionSim&, const McSessionParams&); void mc_session_sim_readback_summary(const McSessionSim&, float* out); void mc_session_sim_readback_tier_counts(const McSessionSim&, unsigned int* out); void mc_session_sim_destroy(McSessionSim&)"
|
||||
description: "N sesiones independientes de K spins en paralelo en GPU (1 thread = 1 sesion). Implementa el modelo variable-ratio escalonado de vr_tiered_lab: tiers (q, m), modes Pure/Pity/Streak, miss_streak, drawdown. Output SSBOs: summary[N*8] + tier_counts[N*max_tiers]."
|
||||
tags: [montecarlo, gpu, simulation, vr_tiered, sessions, datascience]
|
||||
uses_functions: ["gl_loader_cpp_gfx", "gpu_ssbo_cpp_gfx", "gpu_compute_program_cpp_gfx", "gpu_dispatch_cpp_gfx", "gpu_rng_glsl_cpp_gfx"]
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: [GL/gl.h, GL/glext.h, vector, cstdio]
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "cpp/functions/datascience/mc_session_sim_gpu.cpp"
|
||||
framework: opengl
|
||||
params:
|
||||
- name: n_sessions
|
||||
desc: "Numero de sesiones independientes a simular en paralelo. 1 thread por sesion. Tipico: 10^4 - 10^6."
|
||||
- name: max_tiers
|
||||
desc: "Maximo de tiers que el simulador soportara (cota dura del shader = 8). Reservar el max que necesites; los runs pueden usar menos."
|
||||
- name: master_seed
|
||||
desc: "Semilla base. Cada sesion deriva su PCG state via SplitMix64 (deterministico bit-exacto)."
|
||||
- name: p
|
||||
desc: "McSessionParams: p_base, cost, start_balance, n_spins, n_tiers (<= max_tiers), tiers_q[n_tiers], tiers_m[n_tiers], mode, mode_p1, mode_p2."
|
||||
- name: out
|
||||
desc: "(summary) float[N*8]; (tier_counts) uint[N*max_tiers]."
|
||||
output: "Tras run, summary tiene 8 floats por sesion: [final_balance, pnl, max_dd, peak, trough, spins, wins, longest_miss]. tier_counts tiene un uint por (sesion, tier_idx). El SSBO de seeds se actualiza para permitir runs subsiguientes que continuen la cadena RNG."
|
||||
---
|
||||
|
||||
# mc_session_sim_gpu
|
||||
|
||||
Kernel GPU que portea el simulador de sesiones de `vr_tiered_lab_v2.jsx`. Cada sesion vive entera en un thread con state local en registros — sin atomics, sin shared memory, paralelismo trivial.
|
||||
|
||||
## Performance esperada
|
||||
|
||||
RTX 3070, 5888 cores: 10^6 sesiones × 10^4 spins = **10^10 ops Monte Carlo** en ~1-3 s. Comparado con CPU single-thread (~60 s) el speedup es 20-60x.
|
||||
|
||||
## Patron de uso
|
||||
|
||||
```cpp
|
||||
auto sim = fn::ds::mc_session_sim_create(/*n_sessions=*/100'000, /*max_tiers=*/5);
|
||||
fn::ds::mc_session_sim_reseed(sim, 0xC0FFEE);
|
||||
|
||||
// Mid vol preset
|
||||
float qs[] = {0.7f, 0.22f, 0.07f, 0.01f};
|
||||
float ms[] = {1.5f, 4.0f, 15.0f, 100.0f};
|
||||
|
||||
fn::ds::McSessionParams p{};
|
||||
p.p_base = 0.20f;
|
||||
p.cost = 1.0f;
|
||||
p.start_balance = 100.0f;
|
||||
p.n_spins = 1000;
|
||||
p.n_tiers = 4;
|
||||
p.tiers_q = qs;
|
||||
p.tiers_m = ms;
|
||||
p.mode = fn::ds::McSessionMode::Pity;
|
||||
p.mode_p1 = 5.0f; // pity soft = 5 misses
|
||||
p.mode_p2 = 20.0f; // pity hard = 20 misses
|
||||
|
||||
fn::ds::mc_session_sim_run(sim, p);
|
||||
|
||||
std::vector<float> summary(100'000 * 8);
|
||||
fn::ds::mc_session_sim_readback_summary(sim, summary.data());
|
||||
|
||||
// summary[sid*8 + 1] = pnl de la sesion sid
|
||||
// histograma de pnl para distribucion -> stats_summary, drawdown, etc.
|
||||
|
||||
fn::ds::mc_session_sim_destroy(sim);
|
||||
```
|
||||
|
||||
## Modes
|
||||
|
||||
| mode | mode_p1 | mode_p2 | Descripcion |
|
||||
|---|---|---|---|
|
||||
| Pure | — | — | p_eff = p_base (sin compensacion) |
|
||||
| Pity | soft | hard | p_eff sube linealmente p_base->1 entre soft y hard miss_streak |
|
||||
| Streak | lambda | — | p_eff = min(1, p_base * (1 + lambda * miss_streak)) |
|
||||
|
||||
## Layout summary[sid * 8 + k]
|
||||
|
||||
| k | Campo |
|
||||
|---|---|
|
||||
| 0 | final_balance |
|
||||
| 1 | pnl (= final - start) |
|
||||
| 2 | max_dd (peak-to-trough absoluto) |
|
||||
| 3 | peak |
|
||||
| 4 | trough |
|
||||
| 5 | spins (= n_spins o menor si rota antes por ruina) |
|
||||
| 6 | wins (numero de hits) |
|
||||
| 7 | longest_miss |
|
||||
|
||||
## Notas
|
||||
|
||||
- max_tiers esta cap a 8 (cota dura del shader, registros locales). Si necesitas mas, usar variante con SSBO de counters por sesion en vez de registros.
|
||||
- Tras `run`, el SSBO de seeds RNG queda actualizado. Llamar `run` otra vez con `n_spins` adicional simula los siguientes spins continuando la cadena (no rearranca). Util para "stream" sesiones largas en chunks.
|
||||
- Para batches mas grandes que VRAM (n_sessions > 10^7 con summary float[8] = 320 MB), partir en sub-batches y readback entre llamadas.
|
||||
- Compatibilidad GL 4.3+ (compute shaders + atomicAdd uint). RTX 3070 expone GL 4.6, sobra.
|
||||
Reference in New Issue
Block a user