c74fd4ae0d
Stack base de compute shaders OpenGL 4.3 para cargas Monte Carlo intensivas en GPU. Reutiliza el patron de graph_force_layout_gpu (SSBO + compute) y se integra con el resto del registry sin nuevos simbolos en gl_loader (todo lo que se necesita ya estaba expuesto). - gpu_ssbo: lifecycle de Shader Storage Buffer Objects. - gpu_compute_program: compila compute GLSL 4.3 con preamble inyectable (mismo pattern de gl_shader::compile_fragment). - gpu_dispatch: dispatch_1d/2d/3d con ceil(N/local) automatico + barrier helpers (storage, uniform, image, buffer_update, all). - gpu_rng_glsl: PCG32 GLSL (uniform/normal/below) + SplitMix64 seed walkers para sembrar deterministicamente N walkers desde un master seed. - gpu_histogram_1d: SSBO float[N] -> uint[nbins] via atomicAdd. - gpu_histogram_2d: SSBO float[2N] xy-interleaved -> uint[nx*ny] + to_density helper para alimentar heatmap_cpp_viz. - gpu_reduce: workgroup-shared sum/min/max/mean (local 256, partials CPU). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.0 KiB
4.0 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, tested, tests, test_file_path, file_path, framework, params, output
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | tested | tests | test_file_path | file_path | framework | params | output | |||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| gpu_rng_glsl | function | cpp | gfx | 1.0.0 | pure | std::string glsl_rng_preamble(int seed_binding); void seed_walkers_init(uint64_t master_seed, uint32_t* out, int count) | Generador de preamble GLSL con primitivas PCG32 (uniform, normal, below) inyectables en compute shaders, mas helper CPU para sembrar N seeds deterministas via SplitMix64. Sin GL ni I/O — funciones puras que producen string y rellenan array. |
|
false |
|
false | cpp/functions/gfx/gpu_rng_glsl.cpp | opengl |
|
glsl_rng_preamble: string GLSL listo para concatenar como preamble de compile_compute. seed_walkers_init: rellena out[count] in-place. Ambas son puras. |
gpu_rng_glsl
Pareja CPU + GLSL para Monte Carlo en compute shaders.
Calidad
PCG32 (variante recomendada por O'Neill, 2014) tiene state de 32 bits, periodo 2^32 por chain y supera los tests de PractRand hasta varios TB. Para Monte Carlo no criptografico es la opcion estandar moderna. Cada thread tiene su propio state independiente (sin contention atomico), asi que el periodo agregado de N chains es N · 2^32 — mas que suficiente para 10^10 samples.
rng_normal usa Box-Muller con cos (descarta la sin) — ~30 ciclos GPU por sample, un orden de magnitud mas barato que el Ziggurat y sin tablas de lookup que machacarian el cache.
API GLSL inyectada por glsl_rng_preamble
layout(std430, binding = <seed_binding>) buffer RngSeeds { uint rng_seeds[]; };
uint pcg32 (inout uint state);
float rng_uniform (inout uint state); // [0, 1)
float rng_normal (inout uint state); // N(0, 1)
uint rng_below (inout uint state, uint n); // [0, n) sin sesgo
Patron de uso
CPU:
std::vector<unsigned int> seeds(N);
fn::gfx::seed_walkers_init(0xC0FFEE, seeds.data(), N);
fn::gfx::Ssbo seed_ssbo = fn::gfx::ssbo_create(
N * sizeof(unsigned int), seeds.data(), GL_DYNAMIC_COPY);
auto rng_src = fn::gfx::glsl_rng_preamble(/*seed_binding=*/9);
auto r = fn::gfx::compile_compute(my_body, 64, rng_src);
GLSL (my_body):
layout(std430, binding = 0) buffer Out { float samples[]; };
uniform uint u_count;
void main() {
uint i = gl_GlobalInvocationID.x;
if (i >= u_count) return;
uint s = rng_seeds[i];
samples[i] = rng_normal(s);
rng_seeds[i] = s; // persistir para el siguiente dispatch
}
Despacho:
glUseProgram(r.program);
fn::gfx::ssbo_bind(out_ssbo, 0);
fn::gfx::ssbo_bind(seed_ssbo, 9);
glUniform1ui(loc_count, N);
fn::gfx::dispatch_1d(N, 64);
fn::gfx::barrier_storage();
Notas
- El binding del SSBO de seeds es parametro porque cada shader puede usar bindings distintos para sus datos. Convencion sugerida: el ultimo binding del shader (8 o 9).
- Para reproducibilidad bit-exacta entre runs, mantener
master_seedy N constantes; los samples seran identicos. Util para tests numericos. seed_walkers_inites deterministica y no depende de GL — se puede invocar en tests unitarios CPU sin contexto OpenGL.- Para muestreo categorico (sampleTier de vr_tiered_lab) usar
rng_uniformcon cumulative-sum manual en el shader; un helper dedicado se puede añadir si aparece en multiples kernels.