diff options
60 files changed, 1964 insertions, 1420 deletions
diff --git a/cnn_v3/src/cnn_v3_effect.cc b/cnn_v3/src/cnn_v3_effect.cc index e576ceb..fa1716f 100644 --- a/cnn_v3/src/cnn_v3_effect.cc +++ b/cnn_v3/src/cnn_v3_effect.cc @@ -22,18 +22,23 @@ // Format: Conv(IN→OUT, KxK) has OUT*IN*K*K weights + OUT biases // Layout: OIHW order (out × in × kH × kW), biases appended // --------------------------------------------------------------------------- -static const uint32_t kEnc0Weights = 20 * 8 * 9 + 8; // Conv(20→8, 3×3)+bias = 1448 -static const uint32_t kEnc1Weights = 8 * 16 * 9 + 16; // Conv(8→16, 3×3)+bias = 1168 -static const uint32_t kBnWeights = 16 * 16 * 9 + 16; // Conv(16→16, 3×3,dil=2)+bias = 2320 -static const uint32_t kDec1Weights = 32 * 8 * 9 + 8; // Conv(32→8, 3×3)+bias = 2312 -static const uint32_t kDec0Weights = 16 * 4 * 9 + 4; // Conv(16→4, 3×3)+bias = 580 +static const uint32_t kEnc0Weights = + 20 * 8 * 9 + 8; // Conv(20→8, 3×3)+bias = 1448 +static const uint32_t kEnc1Weights = + 8 * 16 * 9 + 16; // Conv(8→16, 3×3)+bias = 1168 +static const uint32_t kBnWeights = + 16 * 16 * 9 + 16; // Conv(16→16, 3×3,dil=2)+bias = 2320 +static const uint32_t kDec1Weights = + 32 * 8 * 9 + 8; // Conv(32→8, 3×3)+bias = 2312 +static const uint32_t kDec0Weights = + 16 * 4 * 9 + 4; // Conv(16→4, 3×3)+bias = 580 -static const uint32_t kEnc0Offset = 0; -static const uint32_t kEnc1Offset = kEnc0Offset + kEnc0Weights; -static const uint32_t kBnOffset = kEnc1Offset + kEnc1Weights; -static const uint32_t kDec1Offset = kBnOffset + kBnWeights; -static const uint32_t kDec0Offset = kDec1Offset + kDec1Weights; -static const uint32_t kTotalF16 = kDec0Offset + kDec0Weights; +static const uint32_t kEnc0Offset = 0; +static const uint32_t kEnc1Offset = kEnc0Offset + kEnc0Weights; +static const uint32_t kBnOffset = kEnc1Offset + kEnc1Weights; +static const uint32_t kDec1Offset = kBnOffset + kBnWeights; +static const uint32_t kDec0Offset = kDec1Offset + kDec1Weights; +static const uint32_t kTotalF16 = kDec0Offset + kDec0Weights; // = 1448 + 1168 + 2320 + 2312 + 580 = 7828 f16 static const uint32_t kWeightsBufBytes = ((kTotalF16 + 1) / 2) * 4; @@ -57,7 +62,7 @@ static WGPUShaderModule make_shader(WGPUDevice device, const char* wgsl) { WGPUShaderSourceWGSL src = {}; src.chain.sType = WGPUSType_ShaderSourceWGSL; - src.code = str_view(composed.c_str()); + src.code = str_view(composed.c_str()); WGPUShaderModuleDescriptor desc = {}; desc.nextInChain = &src.chain; @@ -69,7 +74,7 @@ static WGPUBindGroupLayout make_bgl(WGPUDevice device, uint32_t count) { WGPUBindGroupLayoutDescriptor desc = {}; desc.entryCount = count; - desc.entries = entries; + desc.entries = entries; return wgpuDeviceCreateBindGroupLayout(device, &desc); } @@ -79,14 +84,15 @@ static WGPUComputePipeline make_compute_pipeline(WGPUDevice device, WGPUBindGroupLayout bgl) { WGPUPipelineLayoutDescriptor pl_desc = {}; pl_desc.bindGroupLayoutCount = 1; - pl_desc.bindGroupLayouts = &bgl; + pl_desc.bindGroupLayouts = &bgl; WGPUPipelineLayout pl = wgpuDeviceCreatePipelineLayout(device, &pl_desc); WGPUComputePipelineDescriptor pipe_desc = {}; - pipe_desc.layout = pl; - pipe_desc.compute.module = shader; - pipe_desc.compute.entryPoint = str_view(entry); - WGPUComputePipeline pipe = wgpuDeviceCreateComputePipeline(device, &pipe_desc); + pipe_desc.layout = pl; + pipe_desc.compute.module = shader; + pipe_desc.compute.entryPoint = str_view(entry); + WGPUComputePipeline pipe = + wgpuDeviceCreateComputePipeline(device, &pipe_desc); wgpuPipelineLayoutRelease(pl); return pipe; @@ -95,36 +101,36 @@ static WGPUComputePipeline make_compute_pipeline(WGPUDevice device, // BGL entry helpers static WGPUBindGroupLayoutEntry bgl_uint_tex(uint32_t binding) { WGPUBindGroupLayoutEntry e = {}; - e.binding = binding; - e.visibility = WGPUShaderStage_Compute; - e.texture.sampleType = WGPUTextureSampleType_Uint; - e.texture.viewDimension = WGPUTextureViewDimension_2D; + e.binding = binding; + e.visibility = WGPUShaderStage_Compute; + e.texture.sampleType = WGPUTextureSampleType_Uint; + e.texture.viewDimension = WGPUTextureViewDimension_2D; return e; } static WGPUBindGroupLayoutEntry bgl_storage_buf(uint32_t binding) { WGPUBindGroupLayoutEntry e = {}; - e.binding = binding; - e.visibility = WGPUShaderStage_Compute; - e.buffer.type = WGPUBufferBindingType_ReadOnlyStorage; + e.binding = binding; + e.visibility = WGPUShaderStage_Compute; + e.buffer.type = WGPUBufferBindingType_ReadOnlyStorage; return e; } static WGPUBindGroupLayoutEntry bgl_uniform_buf(uint32_t binding, uint64_t min_size) { WGPUBindGroupLayoutEntry e = {}; - e.binding = binding; - e.visibility = WGPUShaderStage_Compute; - e.buffer.type = WGPUBufferBindingType_Uniform; - e.buffer.minBindingSize = min_size; + e.binding = binding; + e.visibility = WGPUShaderStage_Compute; + e.buffer.type = WGPUBufferBindingType_Uniform; + e.buffer.minBindingSize = min_size; return e; } -static WGPUBindGroupLayoutEntry bgl_storage_tex_write( - uint32_t binding, WGPUTextureFormat fmt) { +static WGPUBindGroupLayoutEntry bgl_storage_tex_write(uint32_t binding, + WGPUTextureFormat fmt) { WGPUBindGroupLayoutEntry e = {}; - e.binding = binding; - e.visibility = WGPUShaderStage_Compute; - e.storageTexture.access = WGPUStorageTextureAccess_WriteOnly; - e.storageTexture.format = fmt; - e.storageTexture.viewDimension = WGPUTextureViewDimension_2D; + e.binding = binding; + e.visibility = WGPUShaderStage_Compute; + e.storageTexture.access = WGPUStorageTextureAccess_WriteOnly; + e.storageTexture.format = fmt; + e.storageTexture.viewDimension = WGPUTextureViewDimension_2D; return e; } @@ -141,16 +147,16 @@ CNNv3Effect::CNNv3Effect(const GpuContext& ctx, const std::string& prefix = outputs.empty() ? std::string("cnn_v3") : outputs[0]; - node_enc0_ = prefix + "_enc0"; + node_enc0_ = prefix + "_enc0"; node_enc1_lo_ = prefix + "_enc1_lo"; node_enc1_hi_ = prefix + "_enc1_hi"; - node_bn_lo_ = prefix + "_bn_lo"; - node_bn_hi_ = prefix + "_bn_hi"; - node_dec1_ = prefix + "_dec1"; + node_bn_lo_ = prefix + "_bn_lo"; + node_bn_hi_ = prefix + "_bn_hi"; + node_dec1_ = prefix + "_dec1"; - weights_buf_ = gpu_create_buffer( - ctx_.device, kWeightsBufBytes, - WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst); + weights_buf_ = + gpu_create_buffer(ctx_.device, kWeightsBufBytes, + WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst); enc0_params_buf_.init(ctx_.device); enc1_params_buf_.init(ctx_.device); @@ -166,7 +172,9 @@ CNNv3Effect::CNNv3Effect(const GpuContext& ctx, } enc1_params_.weight_offset = kEnc1Offset; - for (int i = 0; i < 16; ++i) { enc1_params_.gamma[i] = 1.0f; } + for (int i = 0; i < 16; ++i) { + enc1_params_.gamma[i] = 1.0f; + } bn_params_.weight_offset = kBnOffset; @@ -177,7 +185,9 @@ CNNv3Effect::CNNv3Effect(const GpuContext& ctx, } dec0_params_.weight_offset = kDec0Offset; - for (int i = 0; i < 4; ++i) { dec0_params_.gamma[i] = 1.0f; } + for (int i = 0; i < 4; ++i) { + dec0_params_.gamma[i] = 1.0f; + } create_pipelines(); @@ -205,15 +215,15 @@ void CNNv3Effect::declare_nodes(NodeRegistry& registry) { const int H = registry.default_height(); // enc0: rgba32uint full-res (8ch packed f16) - registry.declare_node(node_enc0_, NodeType::GBUF_RGBA32UINT, W, H); + registry.declare_node(node_enc0_, NodeType::GBUF_RGBA32UINT, W, H); // enc1: two rgba32uint half-res (8ch each = 16ch total) registry.declare_node(node_enc1_lo_, NodeType::GBUF_RGBA32UINT, W / 2, H / 2); registry.declare_node(node_enc1_hi_, NodeType::GBUF_RGBA32UINT, W / 2, H / 2); // bottleneck: two rgba32uint quarter-res (8ch each = 16ch total) - registry.declare_node(node_bn_lo_, NodeType::GBUF_RGBA32UINT, W / 4, H / 4); - registry.declare_node(node_bn_hi_, NodeType::GBUF_RGBA32UINT, W / 4, H / 4); + registry.declare_node(node_bn_lo_, NodeType::GBUF_RGBA32UINT, W / 4, H / 4); + registry.declare_node(node_bn_hi_, NodeType::GBUF_RGBA32UINT, W / 4, H / 4); // dec1: rgba32uint half-res (8ch packed f16) - registry.declare_node(node_dec1_, NodeType::GBUF_RGBA32UINT, W / 2, H / 2); + registry.declare_node(node_dec1_, NodeType::GBUF_RGBA32UINT, W / 2, H / 2); // output_nodes_[0]: rgba16float full-res — declared externally by caller } @@ -222,12 +232,13 @@ void CNNv3Effect::declare_nodes(NodeRegistry& registry) { // --------------------------------------------------------------------------- void CNNv3Effect::upload_weights(WGPUQueue queue, const void* data, - uint32_t size_bytes) { + uint32_t size_bytes) { wgpuQueueWriteBuffer(queue, weights_buf_.buffer, 0, data, size_bytes); } void CNNv3Effect::load_film_mlp(const void* data, uint32_t size_bytes) { - if (size_bytes != sizeof(CNNv3FilmMlp)) return; + if (size_bytes != sizeof(CNNv3FilmMlp)) + return; memcpy(&mlp_, data, sizeof(CNNv3FilmMlp)); mlp_loaded_ = true; } @@ -246,16 +257,19 @@ void CNNv3Effect::set_film_params(const CNNv3FiLMParams& fp) { float h[16]; for (int j = 0; j < 16; ++j) { float s = mlp_.l0_b[j]; - for (int i = 0; i < 5; ++i) s += mlp_.l0_w[j * 5 + i] * cond[i]; + for (int i = 0; i < 5; ++i) + s += mlp_.l0_w[j * 5 + i] * cond[i]; h[j] = s > 0.f ? s : 0.f; } // Layer 1: Linear(16→72) - // Output split: g_enc0(8)|b_enc0(8)|g_enc1(16)|b_enc1(16)|g_dec1(8)|b_dec1(8)|g_dec0(4)|b_dec0(4) + // Output split: + // g_enc0(8)|b_enc0(8)|g_enc1(16)|b_enc1(16)|g_dec1(8)|b_dec1(8)|g_dec0(4)|b_dec0(4) float film[72]; for (int j = 0; j < 72; ++j) { float s = mlp_.l1_b[j]; - for (int i = 0; i < 16; ++i) s += mlp_.l1_w[j * 16 + i] * h[i]; + for (int i = 0; i < 16; ++i) + s += mlp_.l1_w[j * 16 + i] * h[i]; film[j] = s; } @@ -270,9 +284,11 @@ void CNNv3Effect::set_film_params(const CNNv3FiLMParams& fp) { enc0_params_.beta_hi[i] = p[i + 4]; } p += 8; - for (int i = 0; i < 16; ++i) enc1_params_.gamma[i] = p[i]; + for (int i = 0; i < 16; ++i) + enc1_params_.gamma[i] = p[i]; p += 16; - for (int i = 0; i < 16; ++i) enc1_params_.beta[i] = p[i]; + for (int i = 0; i < 16; ++i) + enc1_params_.beta[i] = p[i]; p += 16; for (int i = 0; i < 4; ++i) { dec1_params_.gamma_lo[i] = p[i]; @@ -284,9 +300,11 @@ void CNNv3Effect::set_film_params(const CNNv3FiLMParams& fp) { dec1_params_.beta_hi[i] = p[i + 4]; } p += 8; - for (int i = 0; i < 4; ++i) dec0_params_.gamma[i] = p[i]; + for (int i = 0; i < 4; ++i) + dec0_params_.gamma[i] = p[i]; p += 4; - for (int i = 0; i < 4; ++i) dec0_params_.beta[i] = p[i]; + for (int i = 0; i < 4; ++i) + dec0_params_.beta[i] = p[i]; } // --------------------------------------------------------------------------- @@ -307,27 +325,24 @@ void CNNv3Effect::render(WGPUCommandEncoder encoder, const int W = (int)params.resolution.x; const int H = (int)params.resolution.y; - auto dispatch = [&](WGPUComputePipeline pipe, WGPUBindGroup bg, - int w, int h) { + auto dispatch = [&](WGPUComputePipeline pipe, WGPUBindGroup bg, int w, + int h) { WGPUComputePassDescriptor pass_desc = {}; WGPUComputePassEncoder pass = wgpuCommandEncoderBeginComputePass(encoder, &pass_desc); wgpuComputePassEncoderSetPipeline(pass, pipe); wgpuComputePassEncoderSetBindGroup(pass, 0, bg, 0, nullptr); - wgpuComputePassEncoderDispatchWorkgroups( - pass, - (uint32_t)((w + 7) / 8), - (uint32_t)((h + 7) / 8), - 1); + wgpuComputePassEncoderDispatchWorkgroups(pass, (uint32_t)((w + 7) / 8), + (uint32_t)((h + 7) / 8), 1); wgpuComputePassEncoderEnd(pass); wgpuComputePassEncoderRelease(pass); }; - dispatch(enc0_pipeline_.get(), enc0_bg_.get(), W, H); - dispatch(enc1_pipeline_.get(), enc1_bg_.get(), W / 2, H / 2); - dispatch(bn_pipeline_.get(), bn_bg_.get(), W / 4, H / 4); - dispatch(dec1_pipeline_.get(), dec1_bg_.get(), W / 2, H / 2); - dispatch(dec0_pipeline_.get(), dec0_bg_.get(), W, H); + dispatch(enc0_pipeline_.get(), enc0_bg_.get(), W, H); + dispatch(enc1_pipeline_.get(), enc1_bg_.get(), W / 2, H / 2); + dispatch(bn_pipeline_.get(), bn_bg_.get(), W / 4, H / 4); + dispatch(dec1_pipeline_.get(), dec1_bg_.get(), W / 2, H / 2); + dispatch(dec0_pipeline_.get(), dec0_bg_.get(), W, H); } // --------------------------------------------------------------------------- @@ -443,40 +458,39 @@ void CNNv3Effect::create_pipelines() { static void bg_tex(WGPUBindGroupEntry& e, uint32_t binding, WGPUTextureView view) { e = {}; - e.binding = binding; + e.binding = binding; e.textureView = view; } static void bg_buf(WGPUBindGroupEntry& e, uint32_t binding, WGPUBuffer buf, uint64_t size) { e = {}; e.binding = binding; - e.buffer = buf; - e.size = size; + e.buffer = buf; + e.size = size; } void CNNv3Effect::update_bind_groups(NodeRegistry& nodes) { WGPUDevice dev = ctx_.device; - WGPUTextureView feat0_view = nodes.get_view(input_nodes_[0]); - WGPUTextureView feat1_view = nodes.get_view(input_nodes_[1]); - WGPUTextureView enc0_view = nodes.get_view(node_enc0_); + WGPUTextureView feat0_view = nodes.get_view(input_nodes_[0]); + WGPUTextureView feat1_view = nodes.get_view(input_nodes_[1]); + WGPUTextureView enc0_view = nodes.get_view(node_enc0_); WGPUTextureView enc1_lo_view = nodes.get_view(node_enc1_lo_); WGPUTextureView enc1_hi_view = nodes.get_view(node_enc1_hi_); - WGPUTextureView bn_lo_view = nodes.get_view(node_bn_lo_); - WGPUTextureView bn_hi_view = nodes.get_view(node_bn_hi_); - WGPUTextureView dec1_view = nodes.get_view(node_dec1_); - WGPUTextureView out_view = nodes.get_view(output_nodes_[0]); + WGPUTextureView bn_lo_view = nodes.get_view(node_bn_lo_); + WGPUTextureView bn_hi_view = nodes.get_view(node_bn_hi_); + WGPUTextureView dec1_view = nodes.get_view(node_dec1_); + WGPUTextureView out_view = nodes.get_view(output_nodes_[0]); WGPUBuffer wb = weights_buf_.buffer; auto make_bg = [&](WGPUComputePipeline pipe, WGPUBindGroupEntry* e, uint32_t count) -> WGPUBindGroup { - WGPUBindGroupLayout bgl = - wgpuComputePipelineGetBindGroupLayout(pipe, 0); + WGPUBindGroupLayout bgl = wgpuComputePipelineGetBindGroupLayout(pipe, 0); WGPUBindGroupDescriptor desc = {}; - desc.layout = bgl; + desc.layout = bgl; desc.entryCount = count; - desc.entries = e; + desc.entries = e; WGPUBindGroup bg = wgpuDeviceCreateBindGroup(dev, &desc); wgpuBindGroupLayoutRelease(bgl); return bg; @@ -504,7 +518,8 @@ void CNNv3Effect::update_bind_groups(NodeRegistry& nodes) { enc1_bg_.replace(make_bg(enc1_pipeline_.get(), e, 5)); } - // bottleneck: enc1_lo(B0), enc1_hi(B1), weights(B2), params(B3), bn_lo(B4), bn_hi(B5) + // bottleneck: enc1_lo(B0), enc1_hi(B1), weights(B2), params(B3), bn_lo(B4), + // bn_hi(B5) { WGPUBindGroupEntry e[6] = {}; bg_tex(e[0], 0, enc1_lo_view); diff --git a/cnn_v3/src/cnn_v3_effect.h b/cnn_v3/src/cnn_v3_effect.h index 589680c..ac0166f 100644 --- a/cnn_v3/src/cnn_v3_effect.h +++ b/cnn_v3/src/cnn_v3_effect.h @@ -38,12 +38,12 @@ // offset 80: beta_hi (vec4f) // total: 96 bytes struct CnnV3Params8ch { - uint32_t weight_offset; // offset 0 - uint32_t _pad[7]; // offsets 4-31 - float gamma_lo[4]; // offset 32 - float gamma_hi[4]; // offset 48 - float beta_lo[4]; // offset 64 - float beta_hi[4]; // offset 80 + uint32_t weight_offset; // offset 0 + uint32_t _pad[7]; // offsets 4-31 + float gamma_lo[4]; // offset 32 + float gamma_hi[4]; // offset 48 + float beta_lo[4]; // offset 64 + float beta_hi[4]; // offset 80 }; static_assert(sizeof(CnnV3Params8ch) == 96, "CnnV3Params8ch must be 96 bytes"); @@ -56,12 +56,13 @@ static_assert(sizeof(CnnV3Params8ch) == 96, "CnnV3Params8ch must be 96 bytes"); // offset 96: beta_0..3 (4x vec4f = 64 bytes) // total: 160 bytes struct CnnV3Params16ch { - uint32_t weight_offset; // offset 0 - uint32_t _pad[7]; // offsets 4-31 - float gamma[16]; // offsets 32-95 - float beta[16]; // offsets 96-159 + uint32_t weight_offset; // offset 0 + uint32_t _pad[7]; // offsets 4-31 + float gamma[16]; // offsets 32-95 + float beta[16]; // offsets 96-159 }; -static_assert(sizeof(CnnV3Params16ch) == 160, "CnnV3Params16ch must be 160 bytes"); +static_assert(sizeof(CnnV3Params16ch) == 160, + "CnnV3Params16ch must be 160 bytes"); // dec0: 4-channel FiLM // @@ -72,10 +73,10 @@ static_assert(sizeof(CnnV3Params16ch) == 160, "CnnV3Params16ch must be 160 bytes // offset 48: beta (vec4f) // total: 64 bytes struct CnnV3Params4ch { - uint32_t weight_offset; // offset 0 - uint32_t _pad[7]; // offsets 4-31 - float gamma[4]; // offset 32 - float beta[4]; // offset 48 + uint32_t weight_offset; // offset 0 + uint32_t _pad[7]; // offsets 4-31 + float gamma[4]; // offset 32 + float beta[4]; // offset 48 }; static_assert(sizeof(CnnV3Params4ch) == 64, "CnnV3Params4ch must be 64 bytes"); @@ -90,20 +91,20 @@ static_assert(sizeof(CnnV3ParamsBn) == 16, "CnnV3ParamsBn must be 16 bytes"); // FiLM conditioning inputs (CPU-side, uploaded via set_film_params each frame) // --------------------------------------------------------------------------- struct CNNv3FiLMParams { - float beat_phase = 0.0f; // 0-1 within current beat - float beat_norm = 0.0f; // beat_time / 8.0, normalized 8-beat cycle - float audio_intensity = 0.0f; // peak audio level 0-1 - float style_p0 = 0.0f; // user-defined style param - float style_p1 = 0.0f; // user-defined style param + float beat_phase = 0.0f; // 0-1 within current beat + float beat_norm = 0.0f; // beat_time / 8.0, normalized 8-beat cycle + float audio_intensity = 0.0f; // peak audio level 0-1 + float style_p0 = 0.0f; // user-defined style param + float style_p1 = 0.0f; // user-defined style param }; // FiLM MLP weights: Linear(5→16)→ReLU→Linear(16→72). // Loaded from cnn_v3_film_mlp.bin (1320 f32 = 5280 bytes). // Layout: l0_w(80) | l0_b(16) | l1_w(1152) | l1_b(72), all row-major f32. struct CNNv3FilmMlp { - float l0_w[16 * 5]; // (16, 5) row-major + float l0_w[16 * 5]; // (16, 5) row-major float l0_b[16]; - float l1_w[72 * 16]; // (72, 16) row-major + float l1_w[72 * 16]; // (72, 16) row-major float l1_b[72]; }; static_assert(sizeof(CNNv3FilmMlp) == 1320 * 4, "CNNv3FilmMlp size mismatch"); @@ -153,21 +154,21 @@ class CNNv3Effect : public Effect { BindGroup dec0_bg_; // Params uniform buffers (one per pass) - UniformBuffer<CnnV3Params8ch> enc0_params_buf_; + UniformBuffer<CnnV3Params8ch> enc0_params_buf_; UniformBuffer<CnnV3Params16ch> enc1_params_buf_; - UniformBuffer<CnnV3ParamsBn> bn_params_buf_; - UniformBuffer<CnnV3Params8ch> dec1_params_buf_; - UniformBuffer<CnnV3Params4ch> dec0_params_buf_; + UniformBuffer<CnnV3ParamsBn> bn_params_buf_; + UniformBuffer<CnnV3Params8ch> dec1_params_buf_; + UniformBuffer<CnnV3Params4ch> dec0_params_buf_; // Shared packed-f16 weights (storage buffer, read-only in all shaders) GpuBuffer weights_buf_; // Per-pass params shadow (updated by set_film_params, uploaded in render) - CnnV3Params8ch enc0_params_{}; + CnnV3Params8ch enc0_params_{}; CnnV3Params16ch enc1_params_{}; - CnnV3ParamsBn bn_params_{}; - CnnV3Params8ch dec1_params_{}; - CnnV3Params4ch dec0_params_{}; + CnnV3ParamsBn bn_params_{}; + CnnV3Params8ch dec1_params_{}; + CnnV3Params4ch dec0_params_{}; void create_pipelines(); void update_bind_groups(NodeRegistry& nodes); diff --git a/cnn_v3/src/gbuf_deferred_effect.cc b/cnn_v3/src/gbuf_deferred_effect.cc index de6bd29..561f660 100644 --- a/cnn_v3/src/gbuf_deferred_effect.cc +++ b/cnn_v3/src/gbuf_deferred_effect.cc @@ -1,4 +1,5 @@ -// GBufDeferredEffect — simple deferred render: albedo * shadow from packed G-buffer. +// GBufDeferredEffect — simple deferred render: albedo * shadow from packed +// G-buffer. #include "gbuf_deferred_effect.h" #include "gpu/gpu.h" @@ -10,22 +11,24 @@ extern const char* gbuf_deferred_wgsl; struct GBufDeferredUniforms { float resolution[2]; }; -static_assert(sizeof(GBufDeferredUniforms) == 8, "GBufDeferredUniforms must be 8 bytes"); +static_assert(sizeof(GBufDeferredUniforms) == 8, + "GBufDeferredUniforms must be 8 bytes"); static WGPUBindGroupLayoutEntry bgl_uint_tex(uint32_t binding) { WGPUBindGroupLayoutEntry e = {}; - e.binding = binding; - e.visibility = WGPUShaderStage_Fragment; - e.texture.sampleType = WGPUTextureSampleType_Uint; + e.binding = binding; + e.visibility = WGPUShaderStage_Fragment; + e.texture.sampleType = WGPUTextureSampleType_Uint; e.texture.viewDimension = WGPUTextureViewDimension_2D; return e; } -static WGPUBindGroupLayoutEntry bgl_uniform(uint32_t binding, uint64_t min_size) { +static WGPUBindGroupLayoutEntry bgl_uniform(uint32_t binding, + uint64_t min_size) { WGPUBindGroupLayoutEntry e = {}; - e.binding = binding; - e.visibility = WGPUShaderStage_Fragment; - e.buffer.type = WGPUBufferBindingType_Uniform; + e.binding = binding; + e.visibility = WGPUShaderStage_Fragment; + e.buffer.type = WGPUBufferBindingType_Uniform; e.buffer.minBindingSize = min_size; return e; } @@ -44,40 +47,43 @@ GBufDeferredEffect::GBufDeferredEffect(const GpuContext& ctx, }; WGPUBindGroupLayoutDescriptor bgl_desc = {}; bgl_desc.entryCount = 3; - bgl_desc.entries = entries; - WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); + bgl_desc.entries = entries; + WGPUBindGroupLayout bgl = + wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); WGPUPipelineLayoutDescriptor pl_desc = {}; pl_desc.bindGroupLayoutCount = 1; - pl_desc.bindGroupLayouts = &bgl; + pl_desc.bindGroupLayouts = &bgl; WGPUPipelineLayout pl = wgpuDeviceCreatePipelineLayout(ctx_.device, &pl_desc); WGPUShaderSourceWGSL wgsl_src = {}; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; - const std::string composed = ShaderComposer::Get().Compose({}, gbuf_deferred_wgsl); - wgsl_src.code = str_view(composed.c_str()); + const std::string composed = + ShaderComposer::Get().Compose({}, gbuf_deferred_wgsl); + wgsl_src.code = str_view(composed.c_str()); WGPUShaderModuleDescriptor shader_desc = {}; shader_desc.nextInChain = &wgsl_src.chain; - WGPUShaderModule shader = wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc); + WGPUShaderModule shader = + wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc); WGPUColorTargetState target = {}; - target.format = WGPUTextureFormat_RGBA8Unorm; + target.format = WGPUTextureFormat_RGBA8Unorm; target.writeMask = WGPUColorWriteMask_All; WGPUFragmentState frag = {}; - frag.module = shader; - frag.entryPoint = str_view("fs_main"); + frag.module = shader; + frag.entryPoint = str_view("fs_main"); frag.targetCount = 1; - frag.targets = ⌖ + frag.targets = ⌖ WGPURenderPipelineDescriptor pipe_desc = {}; - pipe_desc.layout = pl; - pipe_desc.vertex.module = shader; - pipe_desc.vertex.entryPoint = str_view("vs_main"); - pipe_desc.fragment = &frag; - pipe_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; - pipe_desc.multisample.count = 1; - pipe_desc.multisample.mask = UINT32_MAX; + pipe_desc.layout = pl; + pipe_desc.vertex.module = shader; + pipe_desc.vertex.entryPoint = str_view("vs_main"); + pipe_desc.fragment = &frag; + pipe_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; + pipe_desc.multisample.count = 1; + pipe_desc.multisample.mask = UINT32_MAX; pipeline_.set(wgpuDeviceCreateRenderPipeline(ctx_.device, &pipe_desc)); @@ -89,46 +95,47 @@ GBufDeferredEffect::GBufDeferredEffect(const GpuContext& ctx, void GBufDeferredEffect::render(WGPUCommandEncoder encoder, const UniformsSequenceParams& params, NodeRegistry& nodes) { - WGPUTextureView feat0_view = nodes.get_view(input_nodes_[0]); - WGPUTextureView feat1_view = nodes.get_view(input_nodes_[1]); + WGPUTextureView feat0_view = nodes.get_view(input_nodes_[0]); + WGPUTextureView feat1_view = nodes.get_view(input_nodes_[1]); WGPUTextureView output_view = nodes.get_view(output_nodes_[0]); - // Upload resolution uniform into the base class uniforms buffer (first 8 bytes). + // Upload resolution uniform into the base class uniforms buffer (first 8 + // bytes). GBufDeferredUniforms u; u.resolution[0] = params.resolution.x; u.resolution[1] = params.resolution.y; - wgpuQueueWriteBuffer(ctx_.queue, uniforms_buffer_.get().buffer, 0, - &u, sizeof(u)); + wgpuQueueWriteBuffer(ctx_.queue, uniforms_buffer_.get().buffer, 0, &u, + sizeof(u)); WGPUBindGroupLayout bgl = wgpuRenderPipelineGetBindGroupLayout(pipeline_.get(), 0); WGPUBindGroupEntry bg_entries[3] = {}; - bg_entries[0].binding = 0; + bg_entries[0].binding = 0; bg_entries[0].textureView = feat0_view; - bg_entries[1].binding = 1; + bg_entries[1].binding = 1; bg_entries[1].textureView = feat1_view; - bg_entries[2].binding = 2; - bg_entries[2].buffer = uniforms_buffer_.get().buffer; - bg_entries[2].size = sizeof(GBufDeferredUniforms); + bg_entries[2].binding = 2; + bg_entries[2].buffer = uniforms_buffer_.get().buffer; + bg_entries[2].size = sizeof(GBufDeferredUniforms); WGPUBindGroupDescriptor bg_desc = {}; - bg_desc.layout = bgl; + bg_desc.layout = bgl; bg_desc.entryCount = 3; - bg_desc.entries = bg_entries; + bg_desc.entries = bg_entries; bind_group_.replace(wgpuDeviceCreateBindGroup(ctx_.device, &bg_desc)); wgpuBindGroupLayoutRelease(bgl); WGPURenderPassColorAttachment color_att = {}; - color_att.view = output_view; - color_att.loadOp = WGPULoadOp_Clear; - color_att.storeOp = WGPUStoreOp_Store; + color_att.view = output_view; + color_att.loadOp = WGPULoadOp_Clear; + color_att.storeOp = WGPUStoreOp_Store; color_att.clearValue = {0.0f, 0.0f, 0.0f, 1.0f}; color_att.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; WGPURenderPassDescriptor pass_desc = {}; pass_desc.colorAttachmentCount = 1; - pass_desc.colorAttachments = &color_att; + pass_desc.colorAttachments = &color_att; WGPURenderPassEncoder pass = wgpuCommandEncoderBeginRenderPass(encoder, &pass_desc); diff --git a/cnn_v3/src/gbuf_deferred_effect.h b/cnn_v3/src/gbuf_deferred_effect.h index 4daf13d..d0368ff 100644 --- a/cnn_v3/src/gbuf_deferred_effect.h +++ b/cnn_v3/src/gbuf_deferred_effect.h @@ -1,5 +1,6 @@ // GBufDeferredEffect — simple deferred render from packed G-buffer. -// Inputs: feat_tex0, feat_tex1 (rgba32uint). Output: albedo * shadow (rgba8unorm). +// Inputs: feat_tex0, feat_tex1 (rgba32uint). Output: albedo * shadow +// (rgba8unorm). #pragma once #include "gpu/effect.h" @@ -10,11 +11,10 @@ class GBufDeferredEffect : public Effect { public: GBufDeferredEffect(const GpuContext& ctx, const std::vector<std::string>& inputs, - const std::vector<std::string>& outputs, - float start_time, float end_time); + const std::vector<std::string>& outputs, float start_time, + float end_time); - void render(WGPUCommandEncoder encoder, - const UniformsSequenceParams& params, + void render(WGPUCommandEncoder encoder, const UniformsSequenceParams& params, NodeRegistry& nodes) override; private: diff --git a/cnn_v3/src/gbuf_view_effect.cc b/cnn_v3/src/gbuf_view_effect.cc index ccf80b0..4c23322 100644 --- a/cnn_v3/src/gbuf_view_effect.cc +++ b/cnn_v3/src/gbuf_view_effect.cc @@ -19,28 +19,28 @@ extern const char* gbuf_view_wgsl; // BGL entry: texture_2d<u32> read binding (fragment stage) static WGPUBindGroupLayoutEntry bgl_uint_tex_frag(uint32_t binding) { WGPUBindGroupLayoutEntry e = {}; - e.binding = binding; - e.visibility = WGPUShaderStage_Fragment; - e.texture.sampleType = WGPUTextureSampleType_Uint; + e.binding = binding; + e.visibility = WGPUShaderStage_Fragment; + e.texture.sampleType = WGPUTextureSampleType_Uint; e.texture.viewDimension = WGPUTextureViewDimension_2D; return e; } // BGL entry: uniform buffer (fragment stage) static WGPUBindGroupLayoutEntry bgl_uniform_frag(uint32_t binding, - uint64_t min_size) { + uint64_t min_size) { WGPUBindGroupLayoutEntry e = {}; - e.binding = binding; - e.visibility = WGPUShaderStage_Fragment; - e.buffer.type = WGPUBufferBindingType_Uniform; + e.binding = binding; + e.visibility = WGPUShaderStage_Fragment; + e.buffer.type = WGPUBufferBindingType_Uniform; e.buffer.minBindingSize = min_size; return e; } GBufViewEffect::GBufViewEffect(const GpuContext& ctx, - const std::vector<std::string>& inputs, - const std::vector<std::string>& outputs, - float start_time, float end_time) + const std::vector<std::string>& inputs, + const std::vector<std::string>& outputs, + float start_time, float end_time) : Effect(ctx, inputs, outputs, start_time, end_time) { HEADLESS_RETURN_IF_NULL(ctx_.device); @@ -48,24 +48,26 @@ GBufViewEffect::GBufViewEffect(const GpuContext& ctx, WGPUBindGroupLayoutEntry entries[3] = { bgl_uint_tex_frag(0), bgl_uint_tex_frag(1), - bgl_uniform_frag(2, 8), // only resolution (vec2f = 8 bytes) is read + bgl_uniform_frag(2, 8), // only resolution (vec2f = 8 bytes) is read }; WGPUBindGroupLayoutDescriptor bgl_desc = {}; bgl_desc.entryCount = 3; - bgl_desc.entries = entries; - WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); + bgl_desc.entries = entries; + WGPUBindGroupLayout bgl = + wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); // Pipeline layout WGPUPipelineLayoutDescriptor pl_desc = {}; pl_desc.bindGroupLayoutCount = 1; - pl_desc.bindGroupLayouts = &bgl; + pl_desc.bindGroupLayouts = &bgl; WGPUPipelineLayout pl = wgpuDeviceCreatePipelineLayout(ctx_.device, &pl_desc); // Shader module WGPUShaderSourceWGSL wgsl_src = {}; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; - const std::string composed = ShaderComposer::Get().Compose({}, gbuf_view_wgsl); - wgsl_src.code = str_view(composed.c_str()); + const std::string composed = + ShaderComposer::Get().Compose({}, gbuf_view_wgsl); + wgsl_src.code = str_view(composed.c_str()); WGPUShaderModuleDescriptor shader_desc = {}; shader_desc.nextInChain = &wgsl_src.chain; WGPUShaderModule shader = @@ -73,23 +75,23 @@ GBufViewEffect::GBufViewEffect(const GpuContext& ctx, // Render pipeline WGPUColorTargetState target = {}; - target.format = WGPUTextureFormat_RGBA8Unorm; + target.format = WGPUTextureFormat_RGBA8Unorm; target.writeMask = WGPUColorWriteMask_All; WGPUFragmentState frag = {}; - frag.module = shader; - frag.entryPoint = str_view("fs_main"); + frag.module = shader; + frag.entryPoint = str_view("fs_main"); frag.targetCount = 1; - frag.targets = ⌖ + frag.targets = ⌖ WGPURenderPipelineDescriptor pipe_desc = {}; - pipe_desc.layout = pl; - pipe_desc.vertex.module = shader; - pipe_desc.vertex.entryPoint = str_view("vs_main"); - pipe_desc.fragment = &frag; - pipe_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; - pipe_desc.multisample.count = 1; - pipe_desc.multisample.mask = UINT32_MAX; + pipe_desc.layout = pl; + pipe_desc.vertex.module = shader; + pipe_desc.vertex.entryPoint = str_view("vs_main"); + pipe_desc.fragment = &frag; + pipe_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; + pipe_desc.multisample.count = 1; + pipe_desc.multisample.mask = UINT32_MAX; pipeline_.set(wgpuDeviceCreateRenderPipeline(ctx_.device, &pipe_desc)); @@ -99,10 +101,10 @@ GBufViewEffect::GBufViewEffect(const GpuContext& ctx, } void GBufViewEffect::render(WGPUCommandEncoder encoder, - const UniformsSequenceParams& params, - NodeRegistry& nodes) { - WGPUTextureView feat0_view = nodes.get_view(input_nodes_[0]); - WGPUTextureView feat1_view = nodes.get_view(input_nodes_[1]); + const UniformsSequenceParams& params, + NodeRegistry& nodes) { + WGPUTextureView feat0_view = nodes.get_view(input_nodes_[0]); + WGPUTextureView feat1_view = nodes.get_view(input_nodes_[1]); WGPUTextureView output_view = nodes.get_view(output_nodes_[0]); // Rebuild bind group (views may change with ping-pong or resize) @@ -110,31 +112,31 @@ void GBufViewEffect::render(WGPUCommandEncoder encoder, wgpuRenderPipelineGetBindGroupLayout(pipeline_.get(), 0); WGPUBindGroupEntry bg_entries[3] = {}; - bg_entries[0].binding = 0; + bg_entries[0].binding = 0; bg_entries[0].textureView = feat0_view; - bg_entries[1].binding = 1; + bg_entries[1].binding = 1; bg_entries[1].textureView = feat1_view; - bg_entries[2].binding = 2; - bg_entries[2].buffer = uniforms_buffer_.get().buffer; - bg_entries[2].size = sizeof(UniformsSequenceParams); + bg_entries[2].binding = 2; + bg_entries[2].buffer = uniforms_buffer_.get().buffer; + bg_entries[2].size = sizeof(UniformsSequenceParams); WGPUBindGroupDescriptor bg_desc = {}; - bg_desc.layout = bgl; + bg_desc.layout = bgl; bg_desc.entryCount = 3; - bg_desc.entries = bg_entries; + bg_desc.entries = bg_entries; bind_group_.replace(wgpuDeviceCreateBindGroup(ctx_.device, &bg_desc)); wgpuBindGroupLayoutRelease(bgl); WGPURenderPassColorAttachment color_att = {}; - color_att.view = output_view; - color_att.loadOp = WGPULoadOp_Clear; - color_att.storeOp = WGPUStoreOp_Store; - color_att.clearValue = {0.0f, 0.0f, 0.0f, 1.0f}; - color_att.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; + color_att.view = output_view; + color_att.loadOp = WGPULoadOp_Clear; + color_att.storeOp = WGPUStoreOp_Store; + color_att.clearValue = {0.0f, 0.0f, 0.0f, 1.0f}; + color_att.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; WGPURenderPassDescriptor pass_desc = {}; pass_desc.colorAttachmentCount = 1; - pass_desc.colorAttachments = &color_att; + pass_desc.colorAttachments = &color_att; WGPURenderPassEncoder pass = wgpuCommandEncoderBeginRenderPass(encoder, &pass_desc); diff --git a/cnn_v3/src/gbuf_view_effect.h b/cnn_v3/src/gbuf_view_effect.h index d4d8139..a8fd5c9 100644 --- a/cnn_v3/src/gbuf_view_effect.h +++ b/cnn_v3/src/gbuf_view_effect.h @@ -1,6 +1,7 @@ // GBufViewEffect: Visualizes G-buffer feature textures as a 4×5 channel grid. -// Inputs: feat_tex0 (rgba32uint, ch 0-7 f16), feat_tex1 (rgba32uint, ch 8-19 unorm8) -// Output: rgba8unorm tiled channel visualization (downscaled 4× per channel) +// Inputs: feat_tex0 (rgba32uint, ch 0-7 f16), feat_tex1 (rgba32uint, ch 8-19 +// unorm8) Output: rgba8unorm tiled channel visualization (downscaled 4× per +// channel) #pragma once @@ -10,16 +11,14 @@ class GBufViewEffect : public Effect { public: - GBufViewEffect(const GpuContext& ctx, - const std::vector<std::string>& inputs, - const std::vector<std::string>& outputs, - float start_time, float end_time); + GBufViewEffect(const GpuContext& ctx, const std::vector<std::string>& inputs, + const std::vector<std::string>& outputs, float start_time, + float end_time); - void render(WGPUCommandEncoder encoder, - const UniformsSequenceParams& params, + void render(WGPUCommandEncoder encoder, const UniformsSequenceParams& params, NodeRegistry& nodes) override; private: RenderPipeline pipeline_; - BindGroup bind_group_; + BindGroup bind_group_; }; diff --git a/cnn_v3/src/gbuffer_effect.cc b/cnn_v3/src/gbuffer_effect.cc index 82ad8b1..395c8bc 100644 --- a/cnn_v3/src/gbuffer_effect.cc +++ b/cnn_v3/src/gbuffer_effect.cc @@ -1,5 +1,6 @@ // GBufferEffect implementation -// Rasterizes proxy geometry to MRT G-buffer, then packs into CNN v3 feature textures. +// Rasterizes proxy geometry to MRT G-buffer, then packs into CNN v3 feature +// textures. #include "gbuffer_effect.h" #include "3d/object.h" @@ -10,9 +11,10 @@ #include <cstring> #include <vector> -// Shader source (loaded from asset at runtime — declared extern by the build system) -// For standalone use outside the asset system, the caller must ensure the WGSL -// source strings are available. They are declared here as weak-linkable externs. +// Shader source (loaded from asset at runtime — declared extern by the build +// system) For standalone use outside the asset system, the caller must ensure +// the WGSL source strings are available. They are declared here as +// weak-linkable externs. extern const char* gbuf_raster_wgsl; extern const char* gbuf_shadow_wgsl; extern const char* gbuf_pack_wgsl; @@ -20,7 +22,8 @@ extern const char* gbuf_pack_wgsl; // Maximum number of objects the G-buffer supports per frame. static const int kGBufMaxObjects = 256; -// ObjectData struct that mirrors the WGSL layout in gbuf_raster.wgsl and renderer.h +// ObjectData struct that mirrors the WGSL layout in gbuf_raster.wgsl and +// renderer.h struct GBufObjectData { mat4 model; mat4 inv_model; @@ -38,7 +41,7 @@ struct GBufGlobalUniforms { mat4 view_proj; mat4 inv_view_proj; vec4 camera_pos_time; - vec4 params; // x = num_objects + vec4 params; // x = num_objects vec2 resolution; vec2 padding; }; @@ -56,12 +59,12 @@ GBufferEffect::GBufferEffect(const GpuContext& ctx, // Derive internal node name prefix from the first output name. const std::string& prefix = outputs.empty() ? "gbuf" : outputs[0]; - node_albedo_ = prefix + "_albedo"; + node_albedo_ = prefix + "_albedo"; node_normal_mat_ = prefix + "_normal_mat"; - node_depth_ = prefix + "_depth"; - node_shadow_ = prefix + "_shadow"; - node_transp_ = prefix + "_transp"; - node_prev_tex_ = prefix + "_prev"; + node_depth_ = prefix + "_depth"; + node_shadow_ = prefix + "_shadow"; + node_transp_ = prefix + "_transp"; + node_prev_tex_ = prefix + "_prev"; // Allocate GPU buffers for scene data. global_uniforms_buf_ = gpu_create_buffer(ctx_.device, sizeof(GBufGlobalUniforms), @@ -83,11 +86,11 @@ GBufferEffect::GBufferEffect(const GpuContext& ctx, } void GBufferEffect::declare_nodes(NodeRegistry& registry) { - registry.declare_node(node_albedo_, NodeType::GBUF_ALBEDO, -1, -1); - registry.declare_node(node_normal_mat_, NodeType::GBUF_ALBEDO, -1, -1); - registry.declare_node(node_depth_, NodeType::GBUF_DEPTH32, -1, -1); - registry.declare_node(node_shadow_, NodeType::GBUF_R8, -1, -1); - registry.declare_node(node_transp_, NodeType::GBUF_R8, -1, -1); + registry.declare_node(node_albedo_, NodeType::GBUF_ALBEDO, -1, -1); + registry.declare_node(node_normal_mat_, NodeType::GBUF_ALBEDO, -1, -1); + registry.declare_node(node_depth_, NodeType::GBUF_DEPTH32, -1, -1); + registry.declare_node(node_shadow_, NodeType::GBUF_R8, -1, -1); + registry.declare_node(node_transp_, NodeType::GBUF_R8, -1, -1); // feat_tex0 / feat_tex1 are the declared output_nodes_ — they get registered // by the sequence infrastructure; declare them here as well if not already. if (!registry.has_node(output_nodes_[0])) { @@ -96,7 +99,8 @@ void GBufferEffect::declare_nodes(NodeRegistry& registry) { if (!registry.has_node(output_nodes_[1])) { registry.declare_node(output_nodes_[1], NodeType::GBUF_RGBA32UINT, -1, -1); } - // F16X8 = Rgba16Float with CopySrc|CopyDst — matches CNNv3Effect output format. + // F16X8 = Rgba16Float with CopySrc|CopyDst — matches CNNv3Effect output + // format. registry.declare_node(node_prev_tex_, NodeType::F16X8, -1, -1); } @@ -111,7 +115,7 @@ void GBufferEffect::set_scene() { seed ^= seed << 13; seed ^= seed >> 17; seed ^= seed << 5; - return (float)(seed >> 8) / 16777216.0f; // [0, 1) + return (float)(seed >> 8) / 16777216.0f; // [0, 1) }; auto rrange = [&](float lo, float hi) { return lo + rnd() * (hi - lo); }; @@ -120,8 +124,8 @@ void GBufferEffect::set_scene() { { Object3D obj(ObjectType::BOX); obj.position = vec3(1.0f, 0.0f, 0.0f); - obj.scale = vec3(0.6f, 0.6f, 0.6f); - obj.color = vec4(0.9f, 0.5f, 0.3f, 1.0f); + obj.scale = vec3(0.6f, 0.6f, 0.6f); + obj.color = vec4(0.9f, 0.5f, 0.3f, 1.0f); scene_.add_object(obj); cube_anims_.push_back({{0.0f, 1.0f, 0.0f}, 0.0f}); } @@ -129,8 +133,8 @@ void GBufferEffect::set_scene() { Object3D obj(ObjectType::SPHERE); obj.position = vec3(-1.0f, 0.0f, 0.0f); const float r = 0.9f; - obj.scale = vec3(r, r, r); - obj.color = vec4(0.3f, 0.6f, 0.9f, 1.0f); + obj.scale = vec3(r, r, r); + obj.color = vec4(0.3f, 0.6f, 0.9f, 1.0f); const int idx = (int)scene_.objects.size(); scene_.add_object(obj); sphere_anims_.push_back({idx, r}); @@ -141,36 +145,35 @@ void GBufferEffect::set_scene() { Object3D obj(ObjectType::SPHERE); obj.position = vec3(0.0f, 2.2f, 0.0f); const float r = 0.6f; - obj.scale = vec3(r, r, r); - obj.color = vec4(0.9f, 0.8f, 0.2f, 1.0f); + obj.scale = vec3(r, r, r); + obj.color = vec4(0.9f, 0.8f, 0.2f, 1.0f); const int idx = (int)scene_.objects.size(); scene_.add_object(obj); sphere_anims_.push_back({idx, r}); } // Camera: above and in front of the scene, looking at origin. - camera_.set_look_at(vec3(0.0f, 2.5f, 6.0f), - vec3(0.0f, 0.0f, 0.0f), + camera_.set_look_at(vec3(0.0f, 2.5f, 6.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); - camera_.fov_y_rad = 0.7854f; // 45° + camera_.fov_y_rad = 0.7854f; // 45° camera_.near_plane = 0.1f; - camera_.far_plane = 20.0f; + camera_.far_plane = 20.0f; // aspect_ratio is updated each frame from params.resolution. scene_ready_ = true; } static void clear_r8_node(WGPUCommandEncoder encoder, WGPUTextureView view, - float value) { + float value) { WGPURenderPassColorAttachment att = {}; - att.view = view; - att.loadOp = WGPULoadOp_Clear; - att.storeOp = WGPUStoreOp_Store; + att.view = view; + att.loadOp = WGPULoadOp_Clear; + att.storeOp = WGPUStoreOp_Store; att.clearValue = {value, value, value, value}; att.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; WGPURenderPassDescriptor pd = {}; pd.colorAttachmentCount = 1; - pd.colorAttachments = &att; + pd.colorAttachments = &att; WGPURenderPassEncoder p = wgpuCommandEncoderBeginRenderPass(encoder, &pd); wgpuRenderPassEncoderEnd(p); wgpuRenderPassEncoderRelease(p); @@ -190,8 +193,7 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, const float angle = params.time * 0.3f; const float R = 6.0f; camera_.set_look_at(vec3(R * sinf(angle), 2.5f, R * cosf(angle)), - vec3(0.0f, 0.0f, 0.0f), - vec3(0.0f, 1.0f, 0.0f)); + vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); // Animate cubes: axis-angle rotation driven by physical time. for (int i = 0; i < (int)cube_anims_.size(); ++i) { @@ -210,8 +212,8 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, GBufLightsUniforms lu = {}; lu.params = vec4(1.0f, 0.0f, 0.0f, 0.0f); // Key: warm sun, upper-right-front. - lu.lights[0].direction = vec4(0.408f, 0.816f, 0.408f, 0.0f); // norm(1,2,1) - lu.lights[0].color = vec4(1.00f, 0.92f, 0.78f, 1.0f); + lu.lights[0].direction = vec4(0.408f, 0.816f, 0.408f, 0.0f); // norm(1,2,1) + lu.lights[0].color = vec4(1.00f, 0.92f, 0.78f, 1.0f); // Fill: cool sky, upper-left-back. (disabled for debugging) // lu.lights[1].direction = vec4(-0.577f, 0.577f, -0.577f, 0.0f); // lu.lights[1].color = vec4(0.40f, 0.45f, 0.80f, 0.4f); @@ -227,11 +229,11 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, res_uni._pad1 = 0.0f; pack_res_uniform_.update(ctx_.queue, res_uni); - WGPUTextureView albedo_view = nodes.get_view(node_albedo_); + WGPUTextureView albedo_view = nodes.get_view(node_albedo_); WGPUTextureView normal_mat_view = nodes.get_view(node_normal_mat_); - WGPUTextureView depth_view = nodes.get_view(node_depth_); - WGPUTextureView feat0_view = nodes.get_view(output_nodes_[0]); - WGPUTextureView feat1_view = nodes.get_view(output_nodes_[1]); + WGPUTextureView depth_view = nodes.get_view(node_depth_); + WGPUTextureView feat0_view = nodes.get_view(output_nodes_[0]); + WGPUTextureView feat1_view = nodes.get_view(output_nodes_[1]); // node_prev_tex_ is updated by post_render() at the end of each frame. // On frame 0 it is zero (NodeRegistry zeroes new textures) — correct default. @@ -266,17 +268,16 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, raster_pass_desc.colorAttachments = color_attachments; raster_pass_desc.depthStencilAttachment = &depth_attachment; - const int num_objects = - (int)(scene_.objects.size() < (size_t)kGBufMaxObjects - ? scene_.objects.size() - : (size_t)kGBufMaxObjects); + const int num_objects = (int)(scene_.objects.size() < (size_t)kGBufMaxObjects + ? scene_.objects.size() + : (size_t)kGBufMaxObjects); if (num_objects > 0 && raster_pipeline_.get() != nullptr) { WGPURenderPassEncoder raster_pass = wgpuCommandEncoderBeginRenderPass(encoder, &raster_pass_desc); wgpuRenderPassEncoderSetPipeline(raster_pass, raster_pipeline_.get()); - wgpuRenderPassEncoderSetBindGroup(raster_pass, 0, - raster_bind_group_.get(), 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(raster_pass, 0, raster_bind_group_.get(), + 0, nullptr); // Draw 36 vertices (proxy box) × num_objects instances. wgpuRenderPassEncoderDraw(raster_pass, 36, (uint32_t)num_objects, 0, 0); wgpuRenderPassEncoderEnd(raster_pass); @@ -293,45 +294,46 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, if (shadow_pipeline_.get() != nullptr) { WGPUBindGroupEntry shadow_entries[5] = {}; shadow_entries[0].binding = 0; - shadow_entries[0].buffer = global_uniforms_buf_.buffer; - shadow_entries[0].size = sizeof(GBufGlobalUniforms); + shadow_entries[0].buffer = global_uniforms_buf_.buffer; + shadow_entries[0].size = sizeof(GBufGlobalUniforms); shadow_entries[1].binding = 1; - shadow_entries[1].buffer = objects_buf_.buffer; - shadow_entries[1].size = (size_t)objects_buf_capacity_ * sizeof(GBufObjectData); + shadow_entries[1].buffer = objects_buf_.buffer; + shadow_entries[1].size = + (size_t)objects_buf_capacity_ * sizeof(GBufObjectData); - shadow_entries[2].binding = 2; + shadow_entries[2].binding = 2; shadow_entries[2].textureView = depth_view; shadow_entries[3].binding = 3; - shadow_entries[3].buffer = lights_uniform_.get().buffer; - shadow_entries[3].size = sizeof(GBufLightsUniforms); + shadow_entries[3].buffer = lights_uniform_.get().buffer; + shadow_entries[3].size = sizeof(GBufLightsUniforms); - shadow_entries[4].binding = 4; + shadow_entries[4].binding = 4; shadow_entries[4].textureView = normal_mat_view; WGPUBindGroupLayout shadow_bgl = wgpuRenderPipelineGetBindGroupLayout(shadow_pipeline_.get(), 0); WGPUBindGroupDescriptor shadow_bg_desc = {}; - shadow_bg_desc.layout = shadow_bgl; + shadow_bg_desc.layout = shadow_bgl; shadow_bg_desc.entryCount = 5; - shadow_bg_desc.entries = shadow_entries; + shadow_bg_desc.entries = shadow_entries; WGPUBindGroup shadow_bg = wgpuDeviceCreateBindGroup(ctx_.device, &shadow_bg_desc); wgpuBindGroupLayoutRelease(shadow_bgl); WGPURenderPassColorAttachment shadow_att = {}; - shadow_att.view = nodes.get_view(node_shadow_); - shadow_att.loadOp = WGPULoadOp_Clear; - shadow_att.storeOp = WGPUStoreOp_Store; + shadow_att.view = nodes.get_view(node_shadow_); + shadow_att.loadOp = WGPULoadOp_Clear; + shadow_att.storeOp = WGPUStoreOp_Store; shadow_att.clearValue = {1.0f, 1.0f, 1.0f, 1.0f}; shadow_att.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; WGPURenderPassDescriptor shadow_pass_desc = {}; shadow_pass_desc.colorAttachmentCount = 1; - shadow_pass_desc.colorAttachments = &shadow_att; + shadow_pass_desc.colorAttachments = &shadow_att; WGPURenderPassEncoder shadow_pass = wgpuCommandEncoderBeginRenderPass(encoder, &shadow_pass_desc); @@ -408,7 +410,7 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, wgpuComputePassEncoderSetPipeline(compute_pass, pack_pipeline_.get()); wgpuComputePassEncoderSetBindGroup(compute_pass, 0, pack_bg, 0, nullptr); - const uint32_t wg_x = ((uint32_t)width_ + 7u) / 8u; + const uint32_t wg_x = ((uint32_t)width_ + 7u) / 8u; const uint32_t wg_y = ((uint32_t)height_ + 7u) / 8u; wgpuComputePassEncoderDispatchWorkgroups(compute_pass, wg_x, wg_y, 1); wgpuComputePassEncoderEnd(compute_pass); @@ -433,29 +435,29 @@ void GBufferEffect::ensure_objects_buffer(int num_objects) { objects_buf_capacity_ = num_objects; } -void GBufferEffect::upload_scene_data(const Scene& scene, - const Camera& camera, float time) { - const int num_objects = - (int)(scene.objects.size() < (size_t)kGBufMaxObjects - ? scene.objects.size() - : (size_t)kGBufMaxObjects); +void GBufferEffect::upload_scene_data(const Scene& scene, const Camera& camera, + float time) { + const int num_objects = (int)(scene.objects.size() < (size_t)kGBufMaxObjects + ? scene.objects.size() + : (size_t)kGBufMaxObjects); const mat4 view = camera.get_view_matrix(); mat4 proj = camera.get_projection_matrix(); - proj.m[5] = -proj.m[5]; // undo post-process Y flip: G-buffer uses integer reads - const mat4 vp = proj * view; + proj.m[5] = + -proj.m[5]; // undo post-process Y flip: G-buffer uses integer reads + const mat4 vp = proj * view; GBufGlobalUniforms gu = {}; - gu.view_proj = vp; - gu.inv_view_proj = vp.inverse(); - gu.camera_pos_time = vec4(camera.position.x, camera.position.y, - camera.position.z, time); - gu.params = vec4((float)num_objects, 0.0f, 0.0f, 0.0f); + gu.view_proj = vp; + gu.inv_view_proj = vp.inverse(); + gu.camera_pos_time = + vec4(camera.position.x, camera.position.y, camera.position.z, time); + gu.params = vec4((float)num_objects, 0.0f, 0.0f, 0.0f); gu.resolution = vec2((float)width_, (float)height_); - gu.padding = vec2(0.0f, 0.0f); + gu.padding = vec2(0.0f, 0.0f); - wgpuQueueWriteBuffer(ctx_.queue, global_uniforms_buf_.buffer, 0, - &gu, sizeof(GBufGlobalUniforms)); + wgpuQueueWriteBuffer(ctx_.queue, global_uniforms_buf_.buffer, 0, &gu, + sizeof(GBufGlobalUniforms)); // Upload object data (no per-frame heap alloc — reuse s_obj_staging). if (num_objects > 0) { @@ -463,13 +465,12 @@ void GBufferEffect::upload_scene_data(const Scene& scene, for (int i = 0; i < num_objects; ++i) { const Object3D& obj = scene.objects[(size_t)i]; const mat4 m = obj.get_model_matrix(); - s_obj_staging[i].model = m; + s_obj_staging[i].model = m; s_obj_staging[i].inv_model = m.inverse(); - s_obj_staging[i].color = obj.color; - s_obj_staging[i].params = vec4((float)(int)obj.type, 0.0f, 0.0f, 0.0f); + s_obj_staging[i].color = obj.color; + s_obj_staging[i].params = vec4((float)(int)obj.type, 0.0f, 0.0f, 0.0f); } - wgpuQueueWriteBuffer(ctx_.queue, objects_buf_.buffer, 0, - s_obj_staging, + wgpuQueueWriteBuffer(ctx_.queue, objects_buf_.buffer, 0, s_obj_staging, (size_t)num_objects * sizeof(GBufObjectData)); } } @@ -483,8 +484,7 @@ void GBufferEffect::create_raster_pipeline() { return; // Asset not loaded yet; pipeline creation deferred. } - const std::string composed = - ShaderComposer::Get().Compose({}, src); + const std::string composed = ShaderComposer::Get().Compose({}, src); WGPUShaderSourceWGSL wgsl_src = {}; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; @@ -492,7 +492,8 @@ void GBufferEffect::create_raster_pipeline() { WGPUShaderModuleDescriptor shader_desc = {}; shader_desc.nextInChain = &wgsl_src.chain; - WGPUShaderModule shader = wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc); + WGPUShaderModule shader = + wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc); // Bind group layout: B0 = GlobalUniforms, B1 = ObjectsBuffer (storage read) WGPUBindGroupLayoutEntry bgl_entries[2] = {}; @@ -511,7 +512,8 @@ void GBufferEffect::create_raster_pipeline() { WGPUBindGroupLayoutDescriptor bgl_desc = {}; bgl_desc.entryCount = 2; bgl_desc.entries = bgl_entries; - WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); + WGPUBindGroupLayout bgl = + wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); WGPUPipelineLayoutDescriptor pl_desc = {}; pl_desc.bindGroupLayoutCount = 1; @@ -542,9 +544,9 @@ void GBufferEffect::create_raster_pipeline() { pipe_desc.vertex.entryPoint = str_view("vs_main"); pipe_desc.fragment = &frag; pipe_desc.depthStencil = &ds; - pipe_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; - pipe_desc.primitive.cullMode = WGPUCullMode_Back; - pipe_desc.primitive.frontFace = WGPUFrontFace_CCW; // standard (no Y flip) + pipe_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; + pipe_desc.primitive.cullMode = WGPUCullMode_Back; + pipe_desc.primitive.frontFace = WGPUFrontFace_CCW; // standard (no Y flip) pipe_desc.multisample.count = 1; pipe_desc.multisample.mask = 0xFFFFFFFF; @@ -571,9 +573,11 @@ void GBufferEffect::create_shadow_pipeline() { WGPUShaderModuleDescriptor shader_desc = {}; shader_desc.nextInChain = &wgsl_src.chain; - WGPUShaderModule shader = wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc); + WGPUShaderModule shader = + wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc); - // BGL: B0=GlobalUniforms, B1=ObjectsBuffer, B2=texture_depth_2d, B3=GBufLightsUniforms + // BGL: B0=GlobalUniforms, B1=ObjectsBuffer, B2=texture_depth_2d, + // B3=GBufLightsUniforms WGPUBindGroupLayoutEntry bgl_entries[5] = {}; bgl_entries[0].binding = 0; @@ -605,7 +609,8 @@ void GBufferEffect::create_shadow_pipeline() { WGPUBindGroupLayoutDescriptor bgl_desc = {}; bgl_desc.entryCount = 5; bgl_desc.entries = bgl_entries; - WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); + WGPUBindGroupLayout bgl = + wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); WGPUPipelineLayoutDescriptor pl_desc = {}; pl_desc.bindGroupLayoutCount = 1; @@ -656,7 +661,8 @@ void GBufferEffect::create_pack_pipeline() { WGPUShaderModuleDescriptor shader_desc = {}; shader_desc.nextInChain = &wgsl_src.chain; - WGPUShaderModule shader = wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc); + WGPUShaderModule shader = + wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc); // Build explicit bind group layout for bindings 0-9. WGPUBindGroupLayoutEntry bgl_entries[10] = {}; @@ -725,7 +731,8 @@ void GBufferEffect::create_pack_pipeline() { WGPUBindGroupLayoutDescriptor bgl_desc = {}; bgl_desc.entryCount = 10; bgl_desc.entries = bgl_entries; - WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); + WGPUBindGroupLayout bgl = + wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); WGPUPipelineLayoutDescriptor pl_desc = {}; pl_desc.bindGroupLayoutCount = 1; @@ -755,12 +762,12 @@ void GBufferEffect::update_raster_bind_group(NodeRegistry& nodes) { WGPUBindGroupEntry entries[2] = {}; entries[0].binding = 0; - entries[0].buffer = global_uniforms_buf_.buffer; - entries[0].size = sizeof(GBufGlobalUniforms); + entries[0].buffer = global_uniforms_buf_.buffer; + entries[0].size = sizeof(GBufGlobalUniforms); entries[1].binding = 1; - entries[1].buffer = objects_buf_.buffer; - entries[1].size = (size_t)objects_buf_capacity_ * sizeof(GBufObjectData); + entries[1].buffer = objects_buf_.buffer; + entries[1].size = (size_t)objects_buf_capacity_ * sizeof(GBufObjectData); WGPUBindGroupLayout bgl = wgpuRenderPipelineGetBindGroupLayout(raster_pipeline_.get(), 0); @@ -777,20 +784,23 @@ void GBufferEffect::update_raster_bind_group(NodeRegistry& nodes) { void GBufferEffect::wire_dag(const std::vector<EffectDAGNode>& dag) { const std::string out = find_downstream_output(dag); // "sink" is an external view (no owned texture) — not a valid copy source. - if (out != "sink") cnn_output_node_ = out; + if (out != "sink") + cnn_output_node_ = out; } -void GBufferEffect::post_render(WGPUCommandEncoder encoder, NodeRegistry& nodes) { - if (cnn_output_node_.empty() || !nodes.has_node(cnn_output_node_)) return; +void GBufferEffect::post_render(WGPUCommandEncoder encoder, + NodeRegistry& nodes) { + if (cnn_output_node_.empty() || !nodes.has_node(cnn_output_node_)) + return; WGPUTexture src_tex = nodes.get_texture(cnn_output_node_); - if (!src_tex) return; // external view (e.g. sink) — no owned texture to copy + if (!src_tex) + return; // external view (e.g. sink) — no owned texture to copy WGPUTexelCopyTextureInfo src = {}; - src.texture = src_tex; + src.texture = src_tex; src.mipLevel = 0; WGPUTexelCopyTextureInfo dst = {}; - dst.texture = nodes.get_texture(node_prev_tex_); + dst.texture = nodes.get_texture(node_prev_tex_); dst.mipLevel = 0; WGPUExtent3D extent = {(uint32_t)width_, (uint32_t)height_, 1}; wgpuCommandEncoderCopyTextureToTexture(encoder, &src, &dst, &extent); } - diff --git a/cnn_v3/src/gbuffer_effect.h b/cnn_v3/src/gbuffer_effect.h index 76d4347..260444a 100644 --- a/cnn_v3/src/gbuffer_effect.h +++ b/cnn_v3/src/gbuffer_effect.h @@ -1,5 +1,6 @@ // GBufferEffect: Multi-pass G-buffer rendering for CNN v3 input -// Outputs: gbuf_feat0, gbuf_feat1 (packed rgba32uint feature textures, 32 bytes/pixel) +// Outputs: gbuf_feat0, gbuf_feat1 (packed rgba32uint feature textures, 32 +// bytes/pixel) #pragma once @@ -21,16 +22,17 @@ struct GBufResUniforms { static_assert(sizeof(GBufResUniforms) == 16, "GBufResUniforms must be 16 bytes"); -// Single directional light: direction points *toward* the light source (world space). +// Single directional light: direction points *toward* the light source (world +// space). struct GBufLight { - vec4 direction; // xyz = normalized direction toward light, w = unused - vec4 color; // rgb = color, a = intensity + vec4 direction; // xyz = normalized direction toward light, w = unused + vec4 color; // rgb = color, a = intensity }; static_assert(sizeof(GBufLight) == 32, "GBufLight must be 32 bytes"); struct GBufLightsUniforms { GBufLight lights[2]; - vec4 params; // x = num_lights + vec4 params; // x = num_lights }; static_assert(sizeof(GBufLightsUniforms) == 80, "GBufLightsUniforms must be 80 bytes"); @@ -60,12 +62,12 @@ class GBufferEffect : public Effect { private: // Per-cube animation state (axis-angle rotation) struct CubeAnim { - vec3 axis; - float speed; // radians/second, may be negative + vec3 axis; + float speed; // radians/second, may be negative }; // Per-sphere animation state (radius driven by audio_intensity) struct SphereAnim { - int obj_idx; // index into scene_.objects + int obj_idx; // index into scene_.objects float base_radius; }; @@ -75,41 +77,42 @@ class GBufferEffect : public Effect { std::string node_depth_; std::string node_shadow_; std::string node_transp_; - std::string node_prev_tex_; // persistent prev-frame CNN output (rgba8unorm) + std::string node_prev_tex_; // persistent prev-frame CNN output (rgba8unorm) // Name of the CNN effect's output node; set by caller before first render. // When non-empty, the CNN output is copied into node_prev_tex_ each frame. std::string cnn_output_node_; public: - void set_cnn_output_node(const std::string& name) { cnn_output_node_ = name; } + void set_cnn_output_node(const std::string& name) { + cnn_output_node_ = name; + } private: - // Owned scene and camera — populated by set_scene() - Scene scene_; + Scene scene_; Camera camera_; - bool scene_ready_ = false; + bool scene_ready_ = false; - std::vector<CubeAnim> cube_anims_; + std::vector<CubeAnim> cube_anims_; std::vector<SphereAnim> sphere_anims_; // Pass 1: MRT rasterization pipeline RenderPipeline raster_pipeline_; - BindGroup raster_bind_group_; + BindGroup raster_bind_group_; // Pass 2: SDF shadow pipeline RenderPipeline shadow_pipeline_; // Pass 4: Pack compute pipeline - ComputePipeline pack_pipeline_; - UniformBuffer<GBufResUniforms> pack_res_uniform_; + ComputePipeline pack_pipeline_; + UniformBuffer<GBufResUniforms> pack_res_uniform_; UniformBuffer<GBufLightsUniforms> lights_uniform_; // GPU-side object data buffers (global uniforms + objects storage) GpuBuffer global_uniforms_buf_; GpuBuffer objects_buf_; - int objects_buf_capacity_ = 0; + int objects_buf_capacity_ = 0; void create_raster_pipeline(); void create_shadow_pipeline(); @@ -117,7 +120,6 @@ class GBufferEffect : public Effect { void update_raster_bind_group(NodeRegistry& nodes); - void upload_scene_data(const Scene& scene, const Camera& camera, - float time); + void upload_scene_data(const Scene& scene, const Camera& camera, float time); void ensure_objects_buffer(int num_objects); }; diff --git a/cnn_v3/test_vectors.h b/cnn_v3/test_vectors.h index 080d295..abc7ef2 100644 --- a/cnn_v3/test_vectors.h +++ b/cnn_v3/test_vectors.h @@ -12,568 +12,901 @@ static const int kCnnV3TestH = 8; // 256 u32 values static const uint32_t kCnnV3TestFeat0U32[256] = { - 0x31f13a6fu, 0x397d3bbdu, 0x398c2dc4u, 0x356738d4u, 0x39c0342cu, 0x353c39eeu, 0x344d3b03u, 0x38cd2c79u, - 0x346d2edau, 0x3495380fu, 0x39a032e1u, 0x3ab83860u, 0x37bc38a6u, 0x3a56342eu, 0x33c0324du, 0x39ee3abcu, - 0x28fb38e7u, 0x38003012u, 0x376d39f9u, 0x31e6246du, 0x398e38b6u, 0x298c2847u, 0x2d58342eu, 0x2feb3856u, - 0x3a383930u, 0x3b963bc4u, 0x27873460u, 0x39ab3545u, 0x35c12ba8u, 0x330534c5u, 0x394639a6u, 0x3b493849u, - 0x30ca2e9au, 0x393f3623u, 0x2cbd38acu, 0x34e23babu, 0x38fd35beu, 0x394d3b90u, 0x32013ba3u, 0x3aa238f3u, - 0x35cb3812u, 0x30833be1u, 0x3afd3693u, 0x3bd83b34u, 0x2a863b14u, 0x36da3b70u, 0x364f3937u, 0x389b3a82u, - 0x32333ac4u, 0x370c31ebu, 0x398b1cdeu, 0x387534bdu, 0x31762c7bu, 0x34e438fcu, 0x335332dfu, 0x38fc32e0u, - 0x35ce315eu, 0x381c3981u, 0x340438c7u, 0x369f3b76u, 0x3b3c3497u, 0x38e9393eu, 0x2b7e3b18u, 0x396c3ab4u, - 0x341a35c3u, 0x3b872eb5u, 0x3427308bu, 0x39ae3987u, 0x3a833125u, 0x3aca3815u, 0x297b2d96u, 0x30cd3919u, - 0x23393833u, 0x3b323a3du, 0x3bab3ab6u, 0x371b3b3au, 0x3b2b3660u, 0x3bc83b6au, 0x32773a26u, 0x3b943b8fu, - 0x3adc3954u, 0x3b8e387du, 0x3ae92e03u, 0x356d2b1bu, 0x37ab3055u, 0x3b9e336fu, 0x3b2f3879u, 0x26a63473u, - 0x399e3a35u, 0x3a86385du, 0x38b43ab8u, 0x39c23bbau, 0x35c8396au, 0x33b618a0u, 0x39ae3a1du, 0x3901354cu, - 0x34383240u, 0x369c3b94u, 0x37cb33d7u, 0x39d63631u, 0x38bc3bb2u, 0x35d638bbu, 0x351c3884u, 0x3aee1479u, - 0x37e036dfu, 0x3ab22d58u, 0x36923173u, 0x37533ab9u, 0x32b33b73u, 0x3bd339b9u, 0x398a3866u, 0x3a03364bu, - 0x39a03b45u, 0x38b63b7du, 0x34e0389eu, 0x3b0e39adu, 0x3375392cu, 0x3a0c385au, 0x31033b84u, 0x369b3014u, - 0x3bd83005u, 0x384536cau, 0x37303344u, 0x37d23be1u, 0x33c32085u, 0x3bea3bd4u, 0x38ec32bcu, 0x389f2cecu, - 0x3a8d3008u, 0x31893b84u, 0x2e883767u, 0x2c2b356du, 0x3bec343cu, 0x3adf29b6u, 0x383b2cf5u, 0x3b74373cu, - 0x31c0325fu, 0x39ce39fdu, 0x26b03998u, 0x3ab83429u, 0x38d138cfu, 0x342a34bcu, 0x39d23b93u, 0x3b80300fu, - 0x355538a9u, 0x39ce365bu, 0x38a13605u, 0x324139afu, 0x35b33b8eu, 0x399736b6u, 0x370b38dfu, 0x3b393933u, - 0x3a983a67u, 0x36b63422u, 0x29a8386eu, 0x352d3a29u, 0x34263486u, 0x35693489u, 0x38ab38d7u, 0x329b3417u, - 0x2def3a9cu, 0x382a381au, 0x3b163898u, 0x3bca38feu, 0x32df3af9u, 0x358433b8u, 0x386d3644u, 0x331d3371u, - 0x3960361au, 0x3bcf3981u, 0x3649327au, 0x39853bb8u, 0x385138bdu, 0x3b262cd5u, 0x38933901u, 0x36453851u, - 0x3a0b3413u, 0x28583814u, 0x3b6e3663u, 0x369d35fbu, 0x3a6a38feu, 0x3acd3959u, 0x3b662f4bu, 0x38273b3bu, - 0x32cf38ffu, 0x327d372bu, 0x3bd925a0u, 0x38bf3425u, 0x35ee34ceu, 0x355c365du, 0x3bb03919u, 0x3bc936dcu, - 0x38db3958u, 0x2c073396u, 0x38983ad1u, 0x3a7f36a1u, 0x3a4534f8u, 0x3b5e353fu, 0x3067344au, 0x31363996u, - 0x393f3b98u, 0x32af3363u, 0x38dd3b64u, 0x2f0e3b26u, 0x38293b67u, 0x35f73959u, 0x3baa2b92u, 0x35d53bf5u, - 0x315e3b8du, 0x2cae30f3u, 0x2ab23643u, 0x306e3651u, 0x3aab39d8u, 0x326a3981u, 0x33fc3a23u, 0x388a3a13u, - 0x2d5835deu, 0x3b843a9fu, 0x3bb73954u, 0x323a3b79u, 0x359739dau, 0x310637cdu, 0x39cf3bccu, 0x35f23445u, - 0x39fb36c2u, 0x35253b68u, 0x38bf378fu, 0x3809364bu, 0x315e2ec4u, 0x3b52366bu, 0x33fe3597u, 0x3b9839f1u, - 0x20683759u, 0x36a43981u, 0x34723964u, 0x358318efu, 0x364a39a3u, 0x376d3303u, 0x2fa53a05u, 0x39573989u, - 0x3bc335efu, 0x350f3b28u, 0x34ef27f6u, 0x3861328du, 0x3af63b5au, 0x36dc34e5u, 0x385a28adu, 0x3b822c0eu, - 0x32db3aefu, 0x388b3998u, 0x379c3a69u, 0x391e3223u, 0x38ad2d23u, 0x397b32ceu, 0x2f023aa0u, 0x39de3667u, + 0x31f13a6fu, 0x397d3bbdu, 0x398c2dc4u, 0x356738d4u, 0x39c0342cu, + 0x353c39eeu, 0x344d3b03u, 0x38cd2c79u, 0x346d2edau, 0x3495380fu, + 0x39a032e1u, 0x3ab83860u, 0x37bc38a6u, 0x3a56342eu, 0x33c0324du, + 0x39ee3abcu, 0x28fb38e7u, 0x38003012u, 0x376d39f9u, 0x31e6246du, + 0x398e38b6u, 0x298c2847u, 0x2d58342eu, 0x2feb3856u, 0x3a383930u, + 0x3b963bc4u, 0x27873460u, 0x39ab3545u, 0x35c12ba8u, 0x330534c5u, + 0x394639a6u, 0x3b493849u, 0x30ca2e9au, 0x393f3623u, 0x2cbd38acu, + 0x34e23babu, 0x38fd35beu, 0x394d3b90u, 0x32013ba3u, 0x3aa238f3u, + 0x35cb3812u, 0x30833be1u, 0x3afd3693u, 0x3bd83b34u, 0x2a863b14u, + 0x36da3b70u, 0x364f3937u, 0x389b3a82u, 0x32333ac4u, 0x370c31ebu, + 0x398b1cdeu, 0x387534bdu, 0x31762c7bu, 0x34e438fcu, 0x335332dfu, + 0x38fc32e0u, 0x35ce315eu, 0x381c3981u, 0x340438c7u, 0x369f3b76u, + 0x3b3c3497u, 0x38e9393eu, 0x2b7e3b18u, 0x396c3ab4u, 0x341a35c3u, + 0x3b872eb5u, 0x3427308bu, 0x39ae3987u, 0x3a833125u, 0x3aca3815u, + 0x297b2d96u, 0x30cd3919u, 0x23393833u, 0x3b323a3du, 0x3bab3ab6u, + 0x371b3b3au, 0x3b2b3660u, 0x3bc83b6au, 0x32773a26u, 0x3b943b8fu, + 0x3adc3954u, 0x3b8e387du, 0x3ae92e03u, 0x356d2b1bu, 0x37ab3055u, + 0x3b9e336fu, 0x3b2f3879u, 0x26a63473u, 0x399e3a35u, 0x3a86385du, + 0x38b43ab8u, 0x39c23bbau, 0x35c8396au, 0x33b618a0u, 0x39ae3a1du, + 0x3901354cu, 0x34383240u, 0x369c3b94u, 0x37cb33d7u, 0x39d63631u, + 0x38bc3bb2u, 0x35d638bbu, 0x351c3884u, 0x3aee1479u, 0x37e036dfu, + 0x3ab22d58u, 0x36923173u, 0x37533ab9u, 0x32b33b73u, 0x3bd339b9u, + 0x398a3866u, 0x3a03364bu, 0x39a03b45u, 0x38b63b7du, 0x34e0389eu, + 0x3b0e39adu, 0x3375392cu, 0x3a0c385au, 0x31033b84u, 0x369b3014u, + 0x3bd83005u, 0x384536cau, 0x37303344u, 0x37d23be1u, 0x33c32085u, + 0x3bea3bd4u, 0x38ec32bcu, 0x389f2cecu, 0x3a8d3008u, 0x31893b84u, + 0x2e883767u, 0x2c2b356du, 0x3bec343cu, 0x3adf29b6u, 0x383b2cf5u, + 0x3b74373cu, 0x31c0325fu, 0x39ce39fdu, 0x26b03998u, 0x3ab83429u, + 0x38d138cfu, 0x342a34bcu, 0x39d23b93u, 0x3b80300fu, 0x355538a9u, + 0x39ce365bu, 0x38a13605u, 0x324139afu, 0x35b33b8eu, 0x399736b6u, + 0x370b38dfu, 0x3b393933u, 0x3a983a67u, 0x36b63422u, 0x29a8386eu, + 0x352d3a29u, 0x34263486u, 0x35693489u, 0x38ab38d7u, 0x329b3417u, + 0x2def3a9cu, 0x382a381au, 0x3b163898u, 0x3bca38feu, 0x32df3af9u, + 0x358433b8u, 0x386d3644u, 0x331d3371u, 0x3960361au, 0x3bcf3981u, + 0x3649327au, 0x39853bb8u, 0x385138bdu, 0x3b262cd5u, 0x38933901u, + 0x36453851u, 0x3a0b3413u, 0x28583814u, 0x3b6e3663u, 0x369d35fbu, + 0x3a6a38feu, 0x3acd3959u, 0x3b662f4bu, 0x38273b3bu, 0x32cf38ffu, + 0x327d372bu, 0x3bd925a0u, 0x38bf3425u, 0x35ee34ceu, 0x355c365du, + 0x3bb03919u, 0x3bc936dcu, 0x38db3958u, 0x2c073396u, 0x38983ad1u, + 0x3a7f36a1u, 0x3a4534f8u, 0x3b5e353fu, 0x3067344au, 0x31363996u, + 0x393f3b98u, 0x32af3363u, 0x38dd3b64u, 0x2f0e3b26u, 0x38293b67u, + 0x35f73959u, 0x3baa2b92u, 0x35d53bf5u, 0x315e3b8du, 0x2cae30f3u, + 0x2ab23643u, 0x306e3651u, 0x3aab39d8u, 0x326a3981u, 0x33fc3a23u, + 0x388a3a13u, 0x2d5835deu, 0x3b843a9fu, 0x3bb73954u, 0x323a3b79u, + 0x359739dau, 0x310637cdu, 0x39cf3bccu, 0x35f23445u, 0x39fb36c2u, + 0x35253b68u, 0x38bf378fu, 0x3809364bu, 0x315e2ec4u, 0x3b52366bu, + 0x33fe3597u, 0x3b9839f1u, 0x20683759u, 0x36a43981u, 0x34723964u, + 0x358318efu, 0x364a39a3u, 0x376d3303u, 0x2fa53a05u, 0x39573989u, + 0x3bc335efu, 0x350f3b28u, 0x34ef27f6u, 0x3861328du, 0x3af63b5au, + 0x36dc34e5u, 0x385a28adu, 0x3b822c0eu, 0x32db3aefu, 0x388b3998u, + 0x379c3a69u, 0x391e3223u, 0x38ad2d23u, 0x397b32ceu, 0x2f023aa0u, + 0x39de3667u, }; // 256 u32 values static const uint32_t kCnnV3TestFeat1U32[256] = { - 0x7a83c8aau, 0x29e8719fu, 0x3699bcbcu, 0x00000000u, 0x9107b1fbu, 0x558c0259u, 0xabfda3b7u, 0x00000000u, - 0xec4ac44au, 0x5ad3c0fbu, 0x8d47c5b9u, 0x00000000u, 0xd4fcca52u, 0x35d9a170u, 0x82ba7eacu, 0x00000000u, - 0x4e248fe3u, 0xa082bbdcu, 0xbe3a97b4u, 0x00000000u, 0x24103d56u, 0x2ffdc6e0u, 0x05edd340u, 0x00000000u, - 0x03161c84u, 0x0cfddbbcu, 0xb4f18c97u, 0x00000000u, 0xe7674f92u, 0x68e263f6u, 0xe1f4d9eeu, 0x00000000u, - 0xbacccb89u, 0xcebe5003u, 0xbd69c8aau, 0x00000000u, 0x3319c72bu, 0x85fb249au, 0x8684754du, 0x00000000u, - 0xa44067f2u, 0xcbce548eu, 0x1cd64d08u, 0x00000000u, 0xacb71e95u, 0xd541bdb0u, 0x1d92cc04u, 0x00000000u, - 0x6a3aec01u, 0xe5423025u, 0x063d68a2u, 0x00000000u, 0x29227b36u, 0xcdcd9d0au, 0x2bfacd74u, 0x00000000u, - 0xb3b535f2u, 0xe6a88063u, 0x7fa256a6u, 0x00000000u, 0x7c0fdb10u, 0x6dc2874bu, 0x5f75d6b5u, 0x00000000u, - 0x614b2490u, 0x8dbc72c1u, 0xe5427ceau, 0x00000000u, 0xfb3cdb08u, 0xdda9be44u, 0x1ea019fcu, 0x00000000u, - 0x4e88770cu, 0xc1c76656u, 0x8ba7cf95u, 0x00000000u, 0x55966134u, 0x4faa2974u, 0x1df6f0e6u, 0x00000000u, - 0x55195f40u, 0x6c03d30au, 0x6a7a1ba0u, 0x00000000u, 0x8c7b118fu, 0x45e2bf42u, 0x34b9e6e2u, 0x00000000u, - 0xe3345f64u, 0x67bfbd40u, 0x4137594eu, 0x00000000u, 0xa2bba9fcu, 0x8ad5501du, 0x939218f0u, 0x00000000u, - 0x38b53f86u, 0xb9210d7du, 0x313a2732u, 0x00000000u, 0xd61e9b83u, 0x6c8e8f0du, 0x68bd6bb8u, 0x00000000u, - 0x63741f09u, 0x6c479557u, 0xaa5246b0u, 0x00000000u, 0x7f273739u, 0x2076c006u, 0x90fc88f6u, 0x00000000u, - 0x445a89adu, 0x1bbb08e7u, 0xd705b821u, 0x00000000u, 0x5008deddu, 0x9854c474u, 0x2c0119c7u, 0x00000000u, - 0x56dcbd72u, 0x62c73f23u, 0x22471b81u, 0x00000000u, 0xf92dbb85u, 0x4fc512eeu, 0x952ddb21u, 0x00000000u, - 0x90c5dde4u, 0x6debf281u, 0x95ea6a56u, 0x00000000u, 0x90e13d88u, 0x147f3a0cu, 0xab4899e4u, 0x00000000u, - 0x1d3cca56u, 0x6f591c34u, 0x5d5dccf7u, 0x00000000u, 0x729d1c17u, 0x1268402au, 0xb38f0640u, 0x00000000u, - 0x6b272347u, 0x0f94b0b4u, 0x00e78afeu, 0x00000000u, 0x8a42b85au, 0xaa8fd193u, 0x8c1dacedu, 0x00000000u, - 0xb86f48f9u, 0xc1ba8424u, 0xdf392d7bu, 0x00000000u, 0xfb8e9b42u, 0xe281dff4u, 0xcbb695f0u, 0x00000000u, - 0x6e543497u, 0x80f84a5fu, 0x9db53238u, 0x00000000u, 0x2b614898u, 0xad7a95e1u, 0x96984562u, 0x00000000u, - 0x852b8218u, 0xd5949ca1u, 0xafea1ba3u, 0x00000000u, 0xeeb2b025u, 0xf9fca2cau, 0xd3478a80u, 0x00000000u, - 0x4c43b114u, 0x30603f20u, 0x4c9fa38au, 0x00000000u, 0xb66b5f31u, 0xdd426aaau, 0xe151d5aau, 0x00000000u, - 0xaf1977c2u, 0xae5720bfu, 0xf3b236ecu, 0x00000000u, 0xaf8d721cu, 0x2416d805u, 0x800aa2b6u, 0x00000000u, - 0x5bd23787u, 0xa310dfaau, 0xa2c60893u, 0x00000000u, 0x4b5c88e9u, 0x4cb8f96eu, 0x16bc4202u, 0x00000000u, - 0x4b1275c5u, 0xd3e51fbeu, 0xa7b6a819u, 0x00000000u, 0xf171e7c3u, 0xed23415bu, 0xdb58b564u, 0x00000000u, - 0x2dffef8fu, 0x557b5bd1u, 0x0eb74243u, 0x00000000u, 0x17f1978du, 0x3b26e0cfu, 0x47b7263du, 0x00000000u, - 0x03f0a396u, 0xd7c40f27u, 0x86e9d1e7u, 0x00000000u, 0xa7e375a6u, 0xa74f7353u, 0xf7794623u, 0x00000000u, - 0x25b792e0u, 0x57b9f177u, 0x4ef220d1u, 0x00000000u, 0x8d2d46e1u, 0x86b44f5fu, 0xca3ff1e4u, 0x00000000u, - 0x8f860c12u, 0x3be6e55du, 0x90925db2u, 0x00000000u, 0xf6ce99bfu, 0x94306929u, 0x97a75fb5u, 0x00000000u, - 0x2d0e5092u, 0x02059320u, 0x35a780d5u, 0x00000000u, 0x067071f0u, 0x73c6b996u, 0xe1d8e8aau, 0x00000000u, - 0x725dd47fu, 0xa5312b92u, 0xdb0a3019u, 0x00000000u, 0xc358b879u, 0xa68f590eu, 0xc8b545cbu, 0x00000000u, + 0x7a83c8aau, 0x29e8719fu, 0x3699bcbcu, 0x00000000u, 0x9107b1fbu, + 0x558c0259u, 0xabfda3b7u, 0x00000000u, 0xec4ac44au, 0x5ad3c0fbu, + 0x8d47c5b9u, 0x00000000u, 0xd4fcca52u, 0x35d9a170u, 0x82ba7eacu, + 0x00000000u, 0x4e248fe3u, 0xa082bbdcu, 0xbe3a97b4u, 0x00000000u, + 0x24103d56u, 0x2ffdc6e0u, 0x05edd340u, 0x00000000u, 0x03161c84u, + 0x0cfddbbcu, 0xb4f18c97u, 0x00000000u, 0xe7674f92u, 0x68e263f6u, + 0xe1f4d9eeu, 0x00000000u, 0xbacccb89u, 0xcebe5003u, 0xbd69c8aau, + 0x00000000u, 0x3319c72bu, 0x85fb249au, 0x8684754du, 0x00000000u, + 0xa44067f2u, 0xcbce548eu, 0x1cd64d08u, 0x00000000u, 0xacb71e95u, + 0xd541bdb0u, 0x1d92cc04u, 0x00000000u, 0x6a3aec01u, 0xe5423025u, + 0x063d68a2u, 0x00000000u, 0x29227b36u, 0xcdcd9d0au, 0x2bfacd74u, + 0x00000000u, 0xb3b535f2u, 0xe6a88063u, 0x7fa256a6u, 0x00000000u, + 0x7c0fdb10u, 0x6dc2874bu, 0x5f75d6b5u, 0x00000000u, 0x614b2490u, + 0x8dbc72c1u, 0xe5427ceau, 0x00000000u, 0xfb3cdb08u, 0xdda9be44u, + 0x1ea019fcu, 0x00000000u, 0x4e88770cu, 0xc1c76656u, 0x8ba7cf95u, + 0x00000000u, 0x55966134u, 0x4faa2974u, 0x1df6f0e6u, 0x00000000u, + 0x55195f40u, 0x6c03d30au, 0x6a7a1ba0u, 0x00000000u, 0x8c7b118fu, + 0x45e2bf42u, 0x34b9e6e2u, 0x00000000u, 0xe3345f64u, 0x67bfbd40u, + 0x4137594eu, 0x00000000u, 0xa2bba9fcu, 0x8ad5501du, 0x939218f0u, + 0x00000000u, 0x38b53f86u, 0xb9210d7du, 0x313a2732u, 0x00000000u, + 0xd61e9b83u, 0x6c8e8f0du, 0x68bd6bb8u, 0x00000000u, 0x63741f09u, + 0x6c479557u, 0xaa5246b0u, 0x00000000u, 0x7f273739u, 0x2076c006u, + 0x90fc88f6u, 0x00000000u, 0x445a89adu, 0x1bbb08e7u, 0xd705b821u, + 0x00000000u, 0x5008deddu, 0x9854c474u, 0x2c0119c7u, 0x00000000u, + 0x56dcbd72u, 0x62c73f23u, 0x22471b81u, 0x00000000u, 0xf92dbb85u, + 0x4fc512eeu, 0x952ddb21u, 0x00000000u, 0x90c5dde4u, 0x6debf281u, + 0x95ea6a56u, 0x00000000u, 0x90e13d88u, 0x147f3a0cu, 0xab4899e4u, + 0x00000000u, 0x1d3cca56u, 0x6f591c34u, 0x5d5dccf7u, 0x00000000u, + 0x729d1c17u, 0x1268402au, 0xb38f0640u, 0x00000000u, 0x6b272347u, + 0x0f94b0b4u, 0x00e78afeu, 0x00000000u, 0x8a42b85au, 0xaa8fd193u, + 0x8c1dacedu, 0x00000000u, 0xb86f48f9u, 0xc1ba8424u, 0xdf392d7bu, + 0x00000000u, 0xfb8e9b42u, 0xe281dff4u, 0xcbb695f0u, 0x00000000u, + 0x6e543497u, 0x80f84a5fu, 0x9db53238u, 0x00000000u, 0x2b614898u, + 0xad7a95e1u, 0x96984562u, 0x00000000u, 0x852b8218u, 0xd5949ca1u, + 0xafea1ba3u, 0x00000000u, 0xeeb2b025u, 0xf9fca2cau, 0xd3478a80u, + 0x00000000u, 0x4c43b114u, 0x30603f20u, 0x4c9fa38au, 0x00000000u, + 0xb66b5f31u, 0xdd426aaau, 0xe151d5aau, 0x00000000u, 0xaf1977c2u, + 0xae5720bfu, 0xf3b236ecu, 0x00000000u, 0xaf8d721cu, 0x2416d805u, + 0x800aa2b6u, 0x00000000u, 0x5bd23787u, 0xa310dfaau, 0xa2c60893u, + 0x00000000u, 0x4b5c88e9u, 0x4cb8f96eu, 0x16bc4202u, 0x00000000u, + 0x4b1275c5u, 0xd3e51fbeu, 0xa7b6a819u, 0x00000000u, 0xf171e7c3u, + 0xed23415bu, 0xdb58b564u, 0x00000000u, 0x2dffef8fu, 0x557b5bd1u, + 0x0eb74243u, 0x00000000u, 0x17f1978du, 0x3b26e0cfu, 0x47b7263du, + 0x00000000u, 0x03f0a396u, 0xd7c40f27u, 0x86e9d1e7u, 0x00000000u, + 0xa7e375a6u, 0xa74f7353u, 0xf7794623u, 0x00000000u, 0x25b792e0u, + 0x57b9f177u, 0x4ef220d1u, 0x00000000u, 0x8d2d46e1u, 0x86b44f5fu, + 0xca3ff1e4u, 0x00000000u, 0x8f860c12u, 0x3be6e55du, 0x90925db2u, + 0x00000000u, 0xf6ce99bfu, 0x94306929u, 0x97a75fb5u, 0x00000000u, + 0x2d0e5092u, 0x02059320u, 0x35a780d5u, 0x00000000u, 0x067071f0u, + 0x73c6b996u, 0xe1d8e8aau, 0x00000000u, 0x725dd47fu, 0xa5312b92u, + 0xdb0a3019u, 0x00000000u, 0xc358b879u, 0xa68f590eu, 0xc8b545cbu, + 0x00000000u, }; // 3914 u32 values static const uint32_t kCnnV3TestWeightsU32[3914] = { - 0xa8b23143u, 0x2f9432e3u, 0x3491b3cbu, 0x317e3104u, 0xa79fb324u, 0x3419acf6u, 0x32322d86u, 0xb13da859u, - 0xb4302831u, 0x2d0e324au, 0xad9630f5u, 0x338c3485u, 0xb1dd3158u, 0xb461a51du, 0x2f07b2a3u, 0x347d30b3u, - 0xacf9aeb0u, 0xb1f6a4adu, 0xa377b31bu, 0x2e85b13eu, 0x3263a8d4u, 0xaf352fb1u, 0x31da3261u, 0xb010ac52u, - 0xb2eb2f02u, 0xb4bbb1c3u, 0x2e553182u, 0x31642fe1u, 0x2948a64fu, 0xb367b2eau, 0xa4712e77u, 0x31172903u, - 0x281d2d2cu, 0xaf87288cu, 0xa8dcb481u, 0xab06b17bu, 0xb11c32c9u, 0xb033b43eu, 0x2e38afedu, 0x31732861u, - 0xab312e4fu, 0xb2653207u, 0xb3dfb495u, 0xa5db3045u, 0x1123b281u, 0x2f8ab2adu, 0xac92a823u, 0x2d01af9fu, - 0xb3ebad4eu, 0x346fb356u, 0x2fab33d8u, 0x3481b07fu, 0x302a315au, 0xb05fa7c7u, 0x33bbb3c0u, 0xb1b7a6cbu, - 0x2a16af74u, 0x32d9b235u, 0x303730f7u, 0x2ce3a937u, 0x2dc12a75u, 0xaa77b3fbu, 0x9b62b467u, 0xb2d3ae89u, - 0x2abbb39du, 0x3415b253u, 0xade12a3au, 0xb4952afbu, 0xa1703467u, 0xb401316eu, 0x9db6a019u, 0x29823434u, - 0xb079a412u, 0x225aae78u, 0xb498a8b1u, 0x339b3244u, 0x2826b2e8u, 0x2e9db384u, 0x2e1fb033u, 0x3128305cu, - 0x33fdb388u, 0xb471b12eu, 0xacf52836u, 0x31eb3255u, 0x3459af06u, 0x20a0b004u, 0x3430b0afu, 0xb45eb271u, - 0x34baa8fcu, 0x30c63385u, 0x338e3381u, 0xaf1121cbu, 0x2e353139u, 0xb3c9acdau, 0xb09030bdu, 0xb0f93432u, - 0x325bb33eu, 0xb228b2a8u, 0x33312ba2u, 0xaf49b1d4u, 0x34883154u, 0xb2d60f49u, 0xb131b4abu, 0x2ed2b312u, - 0x1bc7b343u, 0x2a3b2f76u, 0x31d7b1c4u, 0x30973023u, 0xb339b315u, 0xabde341bu, 0x9f04afa5u, 0x34602e41u, - 0x3414b01au, 0x283db490u, 0xb3912d25u, 0xaa36b2e8u, 0x2b60347au, 0x31d83428u, 0x3178a503u, 0xb381b4a1u, - 0x31b33253u, 0x24bab122u, 0x33102c12u, 0xaab72bebu, 0xa9b1acd5u, 0x330e2dd6u, 0xb0d7a715u, 0x30b9b10eu, - 0xb3943214u, 0x2b41b429u, 0x323cb2cbu, 0xb2d6af48u, 0xb26c340bu, 0xb2a7b022u, 0xb499b362u, 0xb23fb445u, - 0x2b00b44au, 0xac162ef0u, 0x1990aefdu, 0x32be3333u, 0xb21db462u, 0xb0d0b10eu, 0xaa6e2978u, 0xacdab454u, - 0xb3a6234cu, 0xb44d3267u, 0xb3b23414u, 0x33bb3299u, 0x31cd349bu, 0x2d79315eu, 0xb304315bu, 0x205f258au, - 0xa5b732deu, 0x2d5cac6au, 0xb2ebb07cu, 0xaa62a2ccu, 0xad16b122u, 0xaea0ad21u, 0x2f22aca1u, 0x344fafcdu, - 0xa1dd33feu, 0x2571ae97u, 0x2ddc32b1u, 0x250731d8u, 0xb0112d1bu, 0xb1b73083u, 0x32ed2f7bu, 0x2c64b310u, - 0x3055b3c6u, 0x342fb3fau, 0x3468b2f6u, 0x2b3231c7u, 0x31ab316du, 0xb0bc3448u, 0xb3c62aebu, 0xb2502c76u, - 0x299028fdu, 0x22f4a53au, 0x31bf3111u, 0x2ba69cd2u, 0xb34d3424u, 0xb3eab35au, 0xaa402e10u, 0x2e933144u, - 0x33a6ae63u, 0xb068310au, 0xaf20ad37u, 0xb2c3b293u, 0xa8c53430u, 0x3069ac7bu, 0x34302812u, 0xa2563162u, - 0x34acacbfu, 0x3455302eu, 0x32bbb353u, 0xb3422d43u, 0x2f252ac7u, 0xa704b4afu, 0xafdc323fu, 0xa86ea65eu, - 0x3404af9bu, 0xb37a3167u, 0x334834c6u, 0x3278b026u, 0x34cbb38fu, 0x2dc42e5du, 0x339fb3ddu, 0xb0fab486u, - 0x3150b2dbu, 0x33e2b1cbu, 0xb4742e00u, 0xb44eb4bfu, 0x31ca2c11u, 0x32b5b105u, 0x31c7b440u, 0x3139341bu, - 0x327d2f9cu, 0xb1bab46au, 0x1991b334u, 0x2cfe30b5u, 0xb29f32beu, 0xb1e53081u, 0x3008b067u, 0x2c49349cu, - 0x2c77b447u, 0x3360b465u, 0xb2473006u, 0xb213b3d7u, 0xa65d349cu, 0x2d3d3174u, 0xb2d02990u, 0xafa13448u, - 0x2fac29feu, 0x343b2dbbu, 0x1d22b2c0u, 0xa3efab5fu, 0xb306b350u, 0xaf80b043u, 0x2c43a989u, 0xaac62d2bu, - 0xb16cab01u, 0xaf072ac8u, 0xaa44b474u, 0xb145a3f2u, 0x290d2991u, 0x2dae2fc2u, 0xaf0f2ddau, 0x278c3185u, - 0x2cd7a944u, 0x1fd4ad5au, 0x336b308bu, 0x1877340bu, 0x31c2223au, 0x327aaf20u, 0xb3609b33u, 0x3291b41cu, - 0xb036b444u, 0xb247ae5fu, 0x30a9af26u, 0x3248b4a9u, 0xace832d9u, 0x2bbfb2a7u, 0xad30b34du, 0x34c23467u, - 0xaf423139u, 0x2fe32f35u, 0x2d69ac4fu, 0xb196b4b2u, 0xb27523b5u, 0x3275b26au, 0x284c34b2u, 0x34b53283u, - 0xa7f3b2e2u, 0xb408ac20u, 0xa91630e7u, 0xb2b5a4b6u, 0x33d1b220u, 0xb121b45fu, 0x9e06affcu, 0x9c1f2aa4u, - 0xb0ecb3fcu, 0x2d493299u, 0x2e892dbau, 0xb43e310cu, 0x2612ad1fu, 0x329dae34u, 0x3128a15bu, 0x19e332c2u, - 0x2ab133ddu, 0xae1f32bau, 0x24d391d1u, 0xabcbb396u, 0x2d063402u, 0xae30b231u, 0xb490b1ecu, 0xa7f5341bu, - 0x2b90af64u, 0xb043b4bbu, 0x2d232fccu, 0x2c9f34a0u, 0x3105a2e9u, 0x303d33beu, 0x316a3472u, 0xb369330bu, - 0xa89a3076u, 0x2deb2814u, 0x34a73483u, 0x307db011u, 0xade530cdu, 0xb468b339u, 0x9e543153u, 0xa56134a9u, - 0xaaca3497u, 0xb3f931a4u, 0x31cd2842u, 0x32323414u, 0xace3b472u, 0xb380b455u, 0x30182ebbu, 0x33043141u, - 0x31c73099u, 0xb119b454u, 0x32e02caeu, 0x207eb4c2u, 0xb4842ecfu, 0x3399ab93u, 0xb1092e97u, 0xadd632c6u, - 0xafb832c9u, 0xabea2af0u, 0x336cb053u, 0xb3f9b200u, 0x302eae12u, 0x34ca31e7u, 0xab12afd2u, 0x29c0b2f9u, - 0x2fb734c7u, 0xac222b50u, 0x979433f9u, 0xad2bb305u, 0xb1b9b428u, 0xa72db4a1u, 0xae042d2bu, 0x3469aa1du, - 0x264730d6u, 0x339fb023u, 0xaeb5b116u, 0x248a33dbu, 0x2af830a7u, 0xafb42de4u, 0xaed1b0f7u, 0x3330b29eu, - 0x28b9b029u, 0x3173319bu, 0xa34ba8bbu, 0x2eb434c0u, 0x33bb320bu, 0xb20b3186u, 0xb3a528c6u, 0x345f2ddfu, - 0xa9261fd3u, 0x346ab475u, 0xb468b39fu, 0xb42cb0e0u, 0x20f1a6e5u, 0xb450af33u, 0xac6fb375u, 0x2f9cb438u, - 0xaf9ab1a0u, 0xaa68ac11u, 0xb373b4c9u, 0xb4ca32f7u, 0x9e731d05u, 0xa946ae69u, 0x328d3163u, 0xaed1b09au, - 0xa230b0f2u, 0xb1382f0au, 0x3422ae80u, 0xa607b455u, 0xb2b63010u, 0xb2f2b458u, 0xb4b63405u, 0xb480b1fcu, - 0x2c9db37au, 0x2951b0f6u, 0x32b62aedu, 0x32c9b4c1u, 0xb27a2c93u, 0x32d3313eu, 0x3405b0b8u, 0x2bf1a6ffu, - 0xad5134a7u, 0xaef93203u, 0x2bbd31bfu, 0xaa9ab172u, 0xb40daf01u, 0xade5b483u, 0xb26cb49eu, 0x2ffe3053u, - 0xaf053095u, 0x2b35337du, 0xb2d7b32eu, 0xb2482f6au, 0x34b91c7bu, 0xb4a4b4c3u, 0x2a8034bcu, 0x33a1b32au, - 0x258f334eu, 0xb05b2cadu, 0x2b43b451u, 0x2e48afe2u, 0xb4a03275u, 0xb1292b5au, 0xb0bb332eu, 0x281d2c41u, - 0x2ed2abf9u, 0x29243056u, 0x34a430f6u, 0x207baa33u, 0x31afb4aeu, 0xab122237u, 0x337bb3cbu, 0x2f03ac08u, - 0x346eb2bbu, 0xb1c5b22du, 0x33ec32e4u, 0xa4a3b187u, 0x3344307cu, 0x213aaca5u, 0x307030a4u, 0x295f316fu, - 0x33c2b397u, 0x31b93305u, 0xb1adb3afu, 0xb49430adu, 0xacb8349au, 0x33713036u, 0xaef2ac0cu, 0x2a382c2du, - 0x2bd1aafau, 0xa4f8342eu, 0xacb7b1d3u, 0xb315ac11u, 0x2f16b279u, 0x345eae2au, 0xb3b3b0ecu, 0x335130deu, - 0xb1b8b043u, 0x22c3b209u, 0xb09ea4dau, 0xa1b0b45eu, 0x2ddb3469u, 0xb37a9986u, 0xafe1b0c1u, 0x333c3116u, - 0x34a733b6u, 0x345934a1u, 0xb2f4b41cu, 0x2810af82u, 0x32a4b3bdu, 0x26822c7cu, 0xb0bdb26du, 0x32c2b286u, - 0x30842a78u, 0xacf2afd5u, 0x30feab4fu, 0xb1a1313bu, 0xb349343du, 0xb3ac339bu, 0x32a7b085u, 0xaaa3b227u, - 0xb0e4a7b4u, 0x32bf3009u, 0xae2c3331u, 0xb0d524bdu, 0xb281b0e6u, 0x33733439u, 0x216d3153u, 0x24929dc5u, - 0xa907259eu, 0xb330b312u, 0xa1853457u, 0xb276345au, 0xb19d282eu, 0xb483b0bdu, 0x3400b351u, 0x2c27aedau, - 0xaba5a560u, 0xb20124e6u, 0x321d34b1u, 0xa4cc30a4u, 0x340ab2aau, 0xb452ae17u, 0x31a7ae0du, 0x30d12cb6u, - 0xb18831a3u, 0xa8c33411u, 0xb4c72d57u, 0xb03534bdu, 0xa669b434u, 0xb2adb31fu, 0xac1d2d14u, 0xaef2340du, - 0xa5fa3058u, 0x2ba82e24u, 0x3452a42eu, 0xb232ae0au, 0x32a52ed7u, 0xa7bdb46au, 0x30cb3389u, 0x24d334b9u, - 0xaf962e25u, 0xad22344cu, 0xab703094u, 0x303828bfu, 0x33d11d7du, 0x2da6aa33u, 0xab0eae0eu, 0xb32fa89bu, - 0x2e6eb3d7u, 0x2e412df9u, 0xaea9b49cu, 0x3157b1cdu, 0xb0dd32edu, 0xb31e2e72u, 0xb2f0b051u, 0x2eb6b028u, - 0xb1b633e1u, 0x2fbc2677u, 0x2c3a3459u, 0x2cd2b0b4u, 0x3492aee5u, 0x2f1fabb4u, 0xabadb494u, 0x2c3c3334u, - 0x342fa84eu, 0xaed432ccu, 0x9e4126d8u, 0xae5f2d14u, 0x33ecb0e9u, 0x32983412u, 0x30b43497u, 0x310b3115u, - 0xa6b0a1f5u, 0x2d90b0fdu, 0xb0a6b00cu, 0xaaea2a9au, 0x3211b166u, 0xb26132ecu, 0xae4bb4bau, 0x328331b6u, - 0x3144b2f2u, 0xac39b361u, 0xb1e734c9u, 0xa9eeb2a5u, 0x34282c98u, 0xb422349eu, 0x3195b2f3u, 0x3364b067u, - 0xb3742e47u, 0xb2373262u, 0x2802a9e0u, 0x2f260f88u, 0x34b92dddu, 0x210e34cbu, 0x3060b3c6u, 0xaefa3493u, - 0xa9c7a5f5u, 0x2e9db44eu, 0x3185ada2u, 0x322b3260u, 0xaedaaa66u, 0x31c930c7u, 0x338c9d5fu, 0x3347b2d6u, - 0xb2a7b3c1u, 0xb4272533u, 0xb4ccb44bu, 0x3146a8e4u, 0x2dd9b477u, 0xb2603234u, 0x32edb2c8u, 0x25fb3234u, - 0xb3d23221u, 0x3091ac0du, 0x30d8b0a8u, 0x30ce1922u, 0xad13a56du, 0xb199b164u, 0xb35130d4u, 0xb237b3f3u, - 0x3234b23cu, 0x34b5abcbu, 0x2de5b2f7u, 0xac1da7e0u, 0x34913334u, 0xb1e83329u, 0x2dfeb15cu, 0x3082b00du, - 0x27d2291au, 0x300b324fu, 0xb453b48bu, 0xa03e2bcdu, 0xaa3fb09bu, 0x324530f4u, 0xac6728b4u, 0x22bcb067u, - 0x28ecaf1du, 0xb42a2ec9u, 0xb186b4cau, 0x2d9e3393u, 0x337eb24cu, 0xa358a49du, 0xb43b342eu, 0x2a96b178u, - 0x2ee5b1d9u, 0xb3b2b17du, 0xa9efb1a0u, 0xb304b238u, 0xaee632ebu, 0xb445ad59u, 0xb084ad7au, 0xb1a82c3eu, - 0x34203375u, 0xb38ab3afu, 0x2c97b363u, 0x32c4b342u, 0x322430e2u, 0x34c52401u, 0xab95b460u, 0x344faec3u, - 0x31e129e7u, 0x3498b254u, 0x9bc792b0u, 0xac943485u, 0x2a82abdfu, 0xaedfb324u, 0xb39eb1e4u, 0x2adc3308u, - 0xab04ad6du, 0x2d1da942u, 0x34283419u, 0xae8eac2bu, 0x2938a785u, 0x2e19a5ddu, 0xaee2282eu, 0xaca9adedu, - 0xb269b3c8u, 0xac423049u, 0x28d0b17bu, 0xb0a830e8u, 0x341b3246u, 0x2e7d2b7bu, 0x3447b44cu, 0x3412ac21u, - 0xb4c12a11u, 0x2eeeb46eu, 0xb48c28d0u, 0x32c330adu, 0xa5429867u, 0x3181b4bfu, 0x3346ae80u, 0x28fface0u, - 0xb284b069u, 0x98313147u, 0x3478259bu, 0x32d43473u, 0x2b3db1ffu, 0xacd23343u, 0x31f8b3a9u, 0x28f2a19au, - 0x2c1e34a1u, 0xacfea9c3u, 0xb354aa54u, 0x327c31a9u, 0xaf89b024u, 0xb4923330u, 0xa5942249u, 0xb2762f4du, - 0xacbc2e77u, 0xb46a2c8fu, 0x22d6a5e1u, 0xb2ebb17cu, 0xadfcb1fbu, 0x344bb3beu, 0x31efab4cu, 0xb406348eu, - 0x33222dd3u, 0xa9732d28u, 0xb475a94bu, 0x34bd2551u, 0xb46a3467u, 0xaf9d2fe7u, 0xb45e33bdu, 0x327b342fu, - 0xb43ab358u, 0xb29c326du, 0x33fb255cu, 0xabe4292eu, 0xb432a839u, 0xaf453480u, 0xb01cb1f7u, 0xb3ca3475u, - 0x2ffb330du, 0x34923256u, 0x34423292u, 0x31aeb32au, 0x26ae2704u, 0x348833a9u, 0xa13e2fdeu, 0xac5da6b2u, - 0xac2bad51u, 0xb40eb3e0u, 0xa8243160u, 0x2c4f3422u, 0xb293b476u, 0x3491b1a6u, 0x20d7b167u, 0x34953430u, - 0xb454b110u, 0xb431b2a7u, 0x2944b1dbu, 0x25b833ebu, 0xb1b92cd7u, 0x2c8631c5u, 0x344f32feu, 0xb3dcadd7u, - 0xa8c6b143u, 0xacac3447u, 0x26383133u, 0xaee2b217u, 0x2ea32de2u, 0xb136a903u, 0xb25c3043u, 0xb1fe3431u, - 0x95c8b38au, 0x1d092201u, 0x34c0a8ddu, 0xa2c6a037u, 0xb429aa02u, 0xb1392b24u, 0xb4502d49u, 0xa4c3349fu, - 0xa382339eu, 0x3230b439u, 0x31692db1u, 0x2d4ca984u, 0x2d0832d7u, 0x2e3eadd9u, 0x346c2e99u, 0xa9c1acf5u, - 0x1b1531feu, 0xa630308bu, 0x30b5b176u, 0xb1cab315u, 0x30bf2cdfu, 0xb05e3394u, 0x3461b379u, 0xb1ceb2a3u, - 0x2484b002u, 0x3101335au, 0xb23d2ffeu, 0xa2a2ad77u, 0xb05ab2c5u, 0xb328af5cu, 0x2fe027b8u, 0xa1cdb421u, - 0x30c3316bu, 0xa7f3320du, 0xb0fa3228u, 0xb237ad58u, 0xac25a4ffu, 0x30d6b0f9u, 0xb05daf26u, 0xa8b3b316u, - 0xad05af91u, 0x310db112u, 0x95153421u, 0x330d2d7eu, 0x2c5c34cau, 0x33d8337cu, 0xa6003199u, 0xb4a6b405u, - 0x9afca301u, 0x293cab1du, 0x32772802u, 0xb147b384u, 0x32ae31a0u, 0x332934c0u, 0xaf21337cu, 0xb074ab8du, - 0x34362c15u, 0x2861adf7u, 0xb257afd2u, 0xb43eb1dau, 0xab753450u, 0x2ef7326au, 0xb23bb1eau, 0xb08431fdu, - 0xb2e933efu, 0x320a2ed3u, 0xb04cb115u, 0xb0853476u, 0xa92fa961u, 0x314cb0beu, 0xacac3138u, 0xb182326fu, - 0x2977b4c2u, 0xb46e34beu, 0x21d0b19bu, 0xb3e431f3u, 0x30beac06u, 0xb1f9acefu, 0xaae9b1d9u, 0x32f2a253u, - 0x2f502d76u, 0xaac534a3u, 0x3410ab6cu, 0x306ab0e1u, 0xb3b930e3u, 0xb1c0a4e1u, 0xa58eb20au, 0x31afb00bu, - 0x31d033d3u, 0xb056b07eu, 0xb302b0b6u, 0xab863443u, 0x32a8b149u, 0xb476abbeu, 0x2d59b27eu, 0xb18d316fu, - 0x32bd3402u, 0xb13b32b0u, 0x330eb451u, 0x2c91af75u, 0xb32330feu, 0x34363164u, 0xa8843063u, 0x2438333bu, - 0x322730b3u, 0xb01330cau, 0xb106b356u, 0x1a7c1711u, 0xac072a59u, 0x33ef3182u, 0x308bb0ddu, 0x23182ed6u, - 0x31abb1fbu, 0x3042346cu, 0x34a63403u, 0x2d4fadaeu, 0x34aca401u, 0xaabbb3cdu, 0xb0253336u, 0xac803187u, - 0x335d349cu, 0x3130afa1u, 0x2c16ae44u, 0x32542e16u, 0xb15fb491u, 0x28e13012u, 0xb4459967u, 0x3303add4u, - 0xabf4b481u, 0xb4503446u, 0xb0a730cbu, 0x30b9330au, 0xb1743368u, 0x315d24ceu, 0xb12bb0e2u, 0x3467b48au, - 0x2d353008u, 0x24db30afu, 0xa7c0a355u, 0xb1bb2d65u, 0x31fc3373u, 0x2a0aadc7u, 0x3489b2e4u, 0x340d33bcu, - 0xb25aae72u, 0xb3dfb189u, 0xb41eb34bu, 0xb41734b4u, 0x3249b30eu, 0x31452a2au, 0x33562d07u, 0x22cc2d51u, - 0xa80a3016u, 0xa4f8ade9u, 0x31b2b257u, 0xb2a7b098u, 0x3291b0dfu, 0x2f25ae85u, 0xb40e32d8u, 0xaf633117u, - 0x2f41b171u, 0xafdf33deu, 0xb0092949u, 0x2cae282bu, 0x2cbf2c3du, 0x2f6fb302u, 0x2f032eb6u, 0xa815b417u, - 0xb3efaafcu, 0xa889b155u, 0xb10c30aau, 0x27093255u, 0xa4373100u, 0x2c998fecu, 0x9d08341cu, 0x2bd52467u, - 0xb41c308fu, 0xa1a820d2u, 0x9bfb340cu, 0x3470a4deu, 0xb221a797u, 0xb3c6b16fu, 0xa93ab4cbu, 0x307c312bu, - 0x2960b47eu, 0x343cb2a3u, 0x2cddb263u, 0x2d70aeacu, 0x30fcaabdu, 0x33cbb12cu, 0x30eb081fu, 0x34ca32b7u, - 0xb017b14du, 0xb08eb0cbu, 0x34bd2a55u, 0x241d34b5u, 0x32e92d57u, 0xb1b03428u, 0x32642462u, 0xa89faf8fu, - 0x34a834a9u, 0x31bb33ccu, 0xaee1b06fu, 0x28ab2743u, 0x2d401ac3u, 0x30c9ab0au, 0xae81ae64u, 0xb1fab328u, - 0xa82032bbu, 0x30fbb13au, 0xb4992825u, 0xb234af0du, 0xb0522dfcu, 0xb446b42du, 0xb4972a47u, 0xb29e32b2u, - 0xa83f2c18u, 0xb41ca864u, 0x338c31d0u, 0xb22cb4b2u, 0x279a33c1u, 0xb1b5b2b8u, 0x30512e25u, 0x345a2ba3u, - 0xafab9b4bu, 0xad64a2feu, 0xb45cb14bu, 0x300fadadu, 0xa8acb49fu, 0x2c3d2d88u, 0x31f63150u, 0xb3a03011u, - 0x2bf1a3acu, 0xb464b0e3u, 0xa6eeb14fu, 0xb235aa9cu, 0x3416323bu, 0x3420b1bcu, 0x3414b4a1u, 0xb4af3457u, - 0x3484310du, 0x348533cbu, 0xb40d27bbu, 0x2c5f32b7u, 0xaa5b2c68u, 0xb2a72984u, 0xb414309bu, 0x32b33069u, - 0x1e0aa43bu, 0x3482af36u, 0xad08307au, 0xb162b23eu, 0x3440a58bu, 0xb178307fu, 0xacad32e7u, 0xb0f632c1u, - 0x34192c8eu, 0x2f69b0a6u, 0xb2b534aeu, 0x2eb0b3e7u, 0xb41eae27u, 0x30dfa396u, 0xae56b020u, 0x222b32a3u, - 0xa81e3295u, 0x2dca3459u, 0x3365b360u, 0xb2e19e98u, 0x2f34b2abu, 0xb019b458u, 0xa886b2ebu, 0x22b8aa94u, - 0xb47eb03bu, 0xacd92c64u, 0xb3832dd0u, 0xb0d5b4abu, 0xac11a6adu, 0xacb131f5u, 0x2b2f24adu, 0x20a6b497u, - 0xaa0cadf5u, 0x316eb3adu, 0xb496343fu, 0x31112bc9u, 0x3185b022u, 0x341f2d15u, 0xb465349eu, 0x2738a83bu, - 0xae49b2c8u, 0xb4a534aeu, 0x3294a74bu, 0xa235aec3u, 0xa3b83497u, 0xb44eb316u, 0xb07f3447u, 0xb3dc18feu, - 0x3421a9ddu, 0x348615eeu, 0x1996b0a1u, 0xa7f332e7u, 0x32d3b03cu, 0x24b8ac3au, 0xb2053493u, 0xb480afa0u, - 0xb1c2ac27u, 0xb21e2eeau, 0xb08b2eb6u, 0xadcead8fu, 0xa5253029u, 0x32c5ad53u, 0xb17f2987u, 0xae0b33afu, - 0x9aa3b46du, 0xb105b338u, 0xb31730bfu, 0x343231e5u, 0x300a2c17u, 0x34bb301au, 0xb279ae16u, 0x251b21e3u, - 0x2c58b22fu, 0x341bb4aau, 0xb46cb085u, 0xb0fdb386u, 0xb47cb057u, 0xb1e5b03du, 0xac69aca9u, 0xae9cae2fu, - 0xb48fb3e1u, 0x30edb1b8u, 0x341d34b6u, 0x24e3192fu, 0x3142af1fu, 0x329c3115u, 0xa90b3398u, 0x31e23120u, - 0x341faf5bu, 0x34bfb3cau, 0xb3cf3130u, 0xb4792e00u, 0x31bf3130u, 0x32da2bddu, 0xb04db3b8u, 0xb464aa97u, - 0xb082a7f4u, 0xa9c1ac1eu, 0xb0693349u, 0xa9af338fu, 0x162cae9du, 0xb0a9aa51u, 0xb2af1696u, 0x290dadb0u, - 0x3238aaa6u, 0x3483b0acu, 0x347d3177u, 0xb2df327eu, 0xb2562410u, 0x2a77321cu, 0x3420b08bu, 0x28e8b363u, - 0xb43c303eu, 0x32112b84u, 0x1f86b427u, 0x2e42b0a3u, 0x3432b352u, 0xb2073394u, 0x2abbaec9u, 0xa8673030u, - 0xb39ab299u, 0xa6dc34ccu, 0xa16a3327u, 0xb3ea340eu, 0x3420b369u, 0xaf1d344cu, 0xa74ead90u, 0xb1f3aa70u, - 0xb0bd33a6u, 0xb4282fe2u, 0x2de7b46eu, 0x2df8ae2fu, 0x3452b3cbu, 0x333930c5u, 0xaee8b2fbu, 0x25b6ad0eu, - 0xb438afcdu, 0xb0b6ad09u, 0xb1d2ac61u, 0x2ce0b092u, 0xadf0ac4bu, 0x31382535u, 0x2ab9aca7u, 0x22c1347au, - 0x31a333deu, 0xa972b43cu, 0x34ac2f9eu, 0xb3d2a665u, 0xb32c28c3u, 0x1cb730d4u, 0x3317304au, 0x2c512cf4u, - 0x329330e3u, 0xb4733316u, 0xb1732851u, 0x2db332ebu, 0xb1fdaa20u, 0x2fd3ae2eu, 0xb3ceb1adu, 0x31133373u, - 0xaffab1c4u, 0x2fff3488u, 0xaf632c3eu, 0xb46cafb7u, 0xb4633063u, 0x3068b4c1u, 0x30ed344fu, 0xa049a45bu, - 0xaebca8e8u, 0xa94a22acu, 0x33a52b8au, 0xb40b34c1u, 0xb221ac6eu, 0xb015adaeu, 0x3112b240u, 0x3406988fu, - 0xb428b47du, 0xb408ab6eu, 0x34aab08eu, 0xb1ccb197u, 0x94eb29a8u, 0xacbc2a2du, 0xb2f03246u, 0x2f49a980u, - 0xad023312u, 0xb4232934u, 0xb423b254u, 0xb0123060u, 0xb42a304cu, 0x327132f6u, 0xb492b3e4u, 0x32cab442u, - 0x276ab118u, 0x31ada9aau, 0x0e7f9ed2u, 0xb2b834b2u, 0xb44e3259u, 0x336ba2deu, 0x2f1d2e58u, 0xaa41b08bu, - 0x2296ad20u, 0xaea6a5cdu, 0xb0c9af78u, 0xb2b9ad2fu, 0x2bd83325u, 0x2f72b308u, 0xb10a32adu, 0xb4b8b2b5u, - 0x3109b459u, 0xb45f34adu, 0xb41c30c3u, 0x30eb2b13u, 0xb4b2ad68u, 0x34b72b4fu, 0xb1f6b0a7u, 0x283eb338u, - 0x319d2b68u, 0x338930dcu, 0xb0da31dfu, 0xafc8284bu, 0x3426ae89u, 0x348e2efcu, 0x25c0aa62u, 0xb38a9febu, - 0x243fb10eu, 0x3424b427u, 0xb1ccb339u, 0xb3bd3118u, 0x305533afu, 0x2f5eb424u, 0x30f12d0eu, 0x3031324du, - 0xaed12a9eu, 0x34632f93u, 0x2e502ab9u, 0x30eba8d4u, 0xb28534c7u, 0x260fb1b7u, 0x297fa1b9u, 0xab5ab454u, - 0x2a8b2a5fu, 0x303a2e0bu, 0x31932d6fu, 0x25c32ccau, 0xb3a82c14u, 0x2435b05bu, 0x2ee03329u, 0x2b16b3ddu, - 0x307eb158u, 0x2b2d3249u, 0xae332b04u, 0x32fea821u, 0x2211304au, 0xb451ad0fu, 0xb1e5b2dbu, 0x3444acddu, - 0xb1171a55u, 0xae36b392u, 0xac7b3210u, 0x31d0313bu, 0x2c2cb379u, 0xab843468u, 0x3410b450u, 0x22cd335eu, - 0xb1892803u, 0x92e23222u, 0x2f07b47au, 0x32523453u, 0xb44ab047u, 0x3432343au, 0x2d7724fbu, 0xaa29a5bfu, - 0xb3beb34eu, 0x3277b122u, 0xb13fb2cdu, 0xb1782778u, 0x28ddb277u, 0x2cd8ad11u, 0xb2b333eau, 0x33ba33f0u, - 0x2d0b3252u, 0x2d592c9du, 0xb4a42f51u, 0x2a933466u, 0xacb63167u, 0x1dfbb4aeu, 0xa8d71c6bu, 0xb0ceae28u, - 0xacca243bu, 0xb2483483u, 0xafe9aeedu, 0x8f1326a7u, 0x34522d85u, 0x2f67b020u, 0xb090b48fu, 0xb481a593u, - 0x2ed92c85u, 0x211730bdu, 0xabfb2bfcu, 0xb3aeb467u, 0x34c22df4u, 0x286cb4a6u, 0x324630d2u, 0x2c9b26f2u, - 0x32e42f8eu, 0x3417b341u, 0x3274b48du, 0xb1ddb410u, 0xa834b4c3u, 0xb26aae5cu, 0xab7fa783u, 0x338c3124u, - 0xb3362ddcu, 0x33f0afdbu, 0xab27b3e5u, 0x3454343fu, 0x2e6eaad2u, 0x30dea6a5u, 0xb2d5b47fu, 0xb1232c63u, - 0xadb72e60u, 0x3221336cu, 0x313d9c67u, 0x9b0eb065u, 0x32eeb1cfu, 0x33b93234u, 0x346a333fu, 0x3425b137u, - 0xa9f42978u, 0xae0b28a3u, 0xb0f7b00fu, 0x9839b402u, 0x2cff3372u, 0xa97c2272u, 0xb195a578u, 0xb1cb3233u, - 0x30fe3029u, 0x32f829c0u, 0x3354b003u, 0x31bc3068u, 0x32a62e52u, 0xaa2234bcu, 0x30b23207u, 0x3419a73du, - 0x2907ac0eu, 0xb144b391u, 0xabf2328bu, 0xb0e1ac11u, 0x31df9d28u, 0xb4203396u, 0xa50729bfu, 0xa80d2c63u, - 0xa452abc9u, 0x10d52a4cu, 0x321aa447u, 0xae1730b7u, 0x32ca31c5u, 0x2a5ab2a7u, 0x3098b01fu, 0x2e95b104u, - 0x1ed9b0b4u, 0xac8f344fu, 0x34ad3337u, 0xb26a3332u, 0xb47e3223u, 0x331eac19u, 0x25072f40u, 0x31ffac4eu, - 0xa4da3006u, 0xb12f3389u, 0x2d7cb254u, 0xb0da3488u, 0xb2ecb0ceu, 0xb14132ecu, 0x34b617d0u, 0x2857b4afu, - 0x31e71f8du, 0xaae3ad8fu, 0x30a0b260u, 0xb2fa3177u, 0x338bac17u, 0xafbab4c6u, 0xae5f283au, 0xa623b060u, - 0x248db21du, 0x29c82ff0u, 0x329db3d0u, 0x3116b23eu, 0x316ead5bu, 0xb204b1a4u, 0xb47c974fu, 0x304db146u, - 0xb406327au, 0x31b63356u, 0x2f9f3319u, 0x23b52eb0u, 0x34062ddeu, 0xaf13b3acu, 0x3445b41bu, 0x2ebca834u, - 0x34b7328du, 0x31c0b27eu, 0xb4553370u, 0xad9430e1u, 0x20512db5u, 0xb301b09du, 0xb39eb35bu, 0xadb52d4bu, - 0x2f5eb171u, 0x26042f2du, 0xac66342du, 0xb4143273u, 0x34b0309bu, 0x2a1e32a8u, 0xada22cdeu, 0x31312ee4u, - 0x9ca134c8u, 0x2b5db436u, 0xb0e7b351u, 0x3070ae93u, 0xb26bb212u, 0x332bb45eu, 0xb46b2f6eu, 0x2882b487u, - 0x2b6eb02du, 0x3410a906u, 0x2ee1b013u, 0x3460b448u, 0x3097349eu, 0xb160a558u, 0x308a3200u, 0xa77eb157u, - 0x3244a5b7u, 0x2d7f2f0fu, 0xb0682dc1u, 0xb45dacedu, 0xa9253182u, 0xb0e4a8beu, 0x2abfb194u, 0xb42fb123u, - 0xacbe3123u, 0xa946ac99u, 0xaee1320du, 0x343830f4u, 0xa93f2e2du, 0xa67830c2u, 0x23c4aa92u, 0xb399af00u, - 0xb339aa8au, 0x285faae1u, 0xb4743423u, 0xa67e2caau, 0xb0cfb49bu, 0xb170b353u, 0xab94b054u, 0xb4ca2476u, - 0xb3ceb27eu, 0xae9027a1u, 0xb157276fu, 0x343db491u, 0xb32ab385u, 0x349fb2c9u, 0x2c3c2c85u, 0xb3e734acu, - 0xb1af348eu, 0xaa232cbau, 0x3424ac75u, 0x34c6b2bcu, 0x2db7aca4u, 0xb43f347eu, 0x2935340fu, 0xb2bc2fd9u, - 0x2eaa2521u, 0xb2a0a6b8u, 0x32ceb0eau, 0x3003b478u, 0xb4ba34cbu, 0x2eb0b282u, 0x2ae5b439u, 0x2ac52f11u, - 0x2f93ad2du, 0xb19d2b3eu, 0x335528d9u, 0xa4552e68u, 0xb3f3aedau, 0xb4b1b0e7u, 0xb15434acu, 0xb25d320cu, - 0xaa47b028u, 0x31baaebeu, 0x33353465u, 0x3150b2a7u, 0x33f0b2c2u, 0xae48217eu, 0xb4b0b296u, 0x33f3b0d7u, - 0x348331b5u, 0x2b14b3aau, 0x2699b0aau, 0xb028aee5u, 0xb21529acu, 0x2dcba4beu, 0x3422b324u, 0x32231b09u, - 0x30082de9u, 0x33343026u, 0xb0422c5du, 0x2c14b3b0u, 0xb0f8b42au, 0x2782b438u, 0x2c3db286u, 0x322e3196u, - 0x2785af50u, 0xa42a28d7u, 0xb1912df5u, 0xb3b8349au, 0x2b3a3252u, 0x30b8b0e6u, 0x3145b3fau, 0xb3792ae9u, - 0x30d1b409u, 0x3379aff4u, 0x2f9c3108u, 0x3003b040u, 0xb3d8344du, 0xb118aeadu, 0x30a7ac19u, 0x296fa3eau, - 0xb2e3af23u, 0x32e8b07au, 0xacaf2bdeu, 0xb42e3191u, 0xb12fb0bau, 0x2fea34a9u, 0xb4c12c86u, 0x2d34b210u, - 0x3413ac9eu, 0xa80a3115u, 0x349030cau, 0x2d79a5feu, 0xb0d33405u, 0xb3ba336cu, 0x316e2db3u, 0x997d2c67u, - 0xb2b02c82u, 0xb06bb176u, 0xa8762b82u, 0x335ab0e8u, 0xa825acd7u, 0xb21baaefu, 0xa7eb3072u, 0x3474b4a5u, - 0x304b3210u, 0x33d03316u, 0x2c43ae3eu, 0xb0782c2eu, 0xb36ab157u, 0x31652e1eu, 0xaf0e3103u, 0xa720b1a9u, - 0x34062731u, 0x33fd3332u, 0x347632bau, 0xb458a54du, 0xac37b3ffu, 0xb256b0a7u, 0xb1d9345au, 0x31023469u, - 0x2ec22d6au, 0x2d9fae79u, 0x3434b204u, 0xb0b3af9cu, 0x2e02300eu, 0x2d16a77bu, 0x2ea8b28au, 0xb05db067u, - 0xae70b27cu, 0xa70aae7bu, 0xb1e5b1f2u, 0xb3202669u, 0x34432f41u, 0x33b4a99fu, 0xb463b3b6u, 0x31033040u, - 0xb4413296u, 0xacbe3151u, 0xb247af8du, 0xb43034c3u, 0x2d5b3247u, 0x30113083u, 0xb21232e2u, 0x2b91b4cbu, - 0xb339ad9du, 0xae76b207u, 0xb441b420u, 0xaf3733fdu, 0x347534a1u, 0x3020b2ddu, 0x2f522bbeu, 0xb1fbb3c1u, - 0x2bffb410u, 0x2e9b34acu, 0x34a7300cu, 0xb46a2ed6u, 0xad32330cu, 0x1c72b4c2u, 0xb0a93432u, 0xb2439d37u, - 0xb407b43fu, 0x32fd305cu, 0xb010b2d9u, 0xb48bb1dbu, 0x2fad281bu, 0xac4c2daeu, 0xb3cb283au, 0x3425b2a3u, - 0x340f3105u, 0x2dbd3400u, 0xaa66341cu, 0xb433b4c4u, 0xb3c5b37fu, 0x2fbbadb2u, 0x2aee3195u, 0x30c2b2cau, - 0xb4adad93u, 0xae81b036u, 0x31fdb056u, 0x2f8230feu, 0x31e9b2eeu, 0xb1dc2eceu, 0xa1112db0u, 0xb372a8a8u, - 0xb3ae21a0u, 0xb30eb272u, 0xb021345cu, 0xaed5ad8fu, 0x28d633a5u, 0xafaf3406u, 0x2851b365u, 0x31ccadeeu, - 0xa4363349u, 0x28123486u, 0x9ec6b066u, 0x31d6b471u, 0xaf58b3a7u, 0xb4632904u, 0x2f88b40au, 0xa30ab41cu, - 0xb139ae32u, 0x310fb1fau, 0xb2e93456u, 0x2b47346au, 0x30082d71u, 0x32242fd7u, 0x2520a114u, 0xb394aec4u, - 0xb47a2e52u, 0xb3cab04fu, 0x2d54b1f0u, 0xaa102cefu, 0xa91eb3deu, 0x303cada8u, 0x9d2f2a12u, 0x347aa000u, - 0x976c30ecu, 0xb48ca262u, 0xaef23440u, 0x34cbb0b0u, 0xb4583033u, 0xb48eb435u, 0xb41d2ba7u, 0x34323429u, - 0x2c7b2713u, 0xb430affeu, 0xb3a5308fu, 0xaf40b3f5u, 0xa911b4aeu, 0x31c92ffau, 0x32a92c01u, 0x32b2ab2eu, - 0xb1511bf4u, 0xb0523444u, 0xb0f1b48cu, 0xadb5ad1fu, 0x335b2394u, 0x2261aff9u, 0x322eae23u, 0xb39db293u, - 0x2e9a175cu, 0x2ae231adu, 0xac1f3142u, 0xb35fb47cu, 0xae92b46eu, 0xad84998au, 0xa1f528a7u, 0x2e692ed5u, - 0xade8aefdu, 0x2b682a8au, 0xae84af1eu, 0x2da92f74u, 0xa887b302u, 0xb474338au, 0xb27832d2u, 0xa9d01c74u, - 0x33fab4b4u, 0x345ca6ecu, 0x3308b018u, 0x285d340eu, 0x2f1db1b5u, 0x34442786u, 0xb072a8aau, 0x2fa1b2f2u, - 0xb487348du, 0x3419309eu, 0xb37cb415u, 0x2daf2f5fu, 0x326cb424u, 0x33d12332u, 0x32003342u, 0xb0c420e2u, - 0xb3aa1b58u, 0xb3072e1au, 0xb4471eddu, 0xb125afb3u, 0x31822c9cu, 0x32bab440u, 0xae0f32edu, 0xab7b2e1bu, - 0x2467b2a4u, 0x3344b3f1u, 0x322d3413u, 0x286c28cdu, 0xb0d734a7u, 0x28c2b412u, 0xaed2ae93u, 0x2b64b4bbu, - 0xb1feb088u, 0xad35b469u, 0xae463347u, 0x30ed2ee0u, 0x322dae9au, 0x288d2f5eu, 0xb477b4cau, 0x316b34b6u, - 0x33b93433u, 0x319ab49bu, 0x318fa781u, 0xb011b4bcu, 0x31a030d3u, 0xafa22c99u, 0x347baf48u, 0xa810a8abu, - 0xaaf32805u, 0xa932280cu, 0x33db3246u, 0x28f03426u, 0x2fe2a871u, 0x28d6327fu, 0x30cb2faeu, 0x30ba2ec6u, - 0x93fdb198u, 0xb4c72ac7u, 0x2c3a32d6u, 0x3213b31fu, 0x30f6302bu, 0x32cdac25u, 0x296aaa9au, 0x2d90b4cbu, - 0x29273030u, 0x31f3983bu, 0xb0432ef7u, 0x2ff63468u, 0x348634afu, 0x30e73406u, 0xb24b2c34u, 0x311826a9u, - 0x33122268u, 0xac92b37fu, 0xa9331b54u, 0xb2a7b384u, 0xa0cc327bu, 0xb4a4b455u, 0xb272a413u, 0x31ac2fe0u, - 0x2b14b137u, 0xaf8bb2a2u, 0x26c63377u, 0xb1463369u, 0xa476ae87u, 0x34c7a21fu, 0x32c2b367u, 0x281632fcu, - 0x21e8adfdu, 0x31beaff8u, 0x3417943bu, 0x20662cb6u, 0x18d5300du, 0xb20f33c4u, 0x31fe348bu, 0xa14032edu, - 0xaf6b3279u, 0xb2e73108u, 0xa82baf69u, 0xac57aed3u, 0xb0ac3225u, 0xb41830b6u, 0x319b311au, 0x3046ab8du, - 0x31c633f8u, 0xa0d9ac35u, 0xaff7315du, 0xae9a31d6u, 0xb3ef31e0u, 0x34c7b460u, 0x335a3318u, 0xa8bd3455u, - 0xb31bb018u, 0xb16011f1u, 0xb4c3342eu, 0xb0deb2dau, 0xb144b1c8u, 0xaea02dfeu, 0x337e2c6bu, 0x2f782be0u, - 0xb288ad2au, 0x3475aee4u, 0xb0462cadu, 0x3271a78au, 0x28a82e78u, 0x2e9f3365u, 0xb1f52d7bu, 0x3477b38fu, - 0xaa7a2b98u, 0xb4352ad6u, 0xb171322fu, 0x254831d9u, 0xb483b04au, 0xb2363210u, 0x30eab44du, 0xac40adc2u, - 0x32e5b0dbu, 0xb190afc8u, 0xb1b3af53u, 0xb401af01u, 0xaa5fb28eu, 0xb4403349u, 0x33d7b184u, 0x2ee4337du, - 0xaa29b0fcu, 0xb322b18bu, 0x29d3ac9cu, 0x2c41ad61u, 0xadebafd3u, 0x33433195u, 0x297eaed5u, 0xb44ab042u, - 0xb2513091u, 0x9ff6a9b5u, 0xb3c9b20fu, 0x3458add6u, 0xac8e2c6cu, 0x2bb3b46du, 0x2689b3d4u, 0xa9de30d6u, - 0xb458afb4u, 0xa960b490u, 0xb0ea335cu, 0x2f1429b0u, 0xb2a9b437u, 0x2e88ae7bu, 0x307fa8afu, 0x30f6330fu, - 0x30e234bau, 0x326232c3u, 0x31cb306cu, 0xa39e342cu, 0x20972d4fu, 0xa94632bdu, 0x31bf3224u, 0xb0d2346fu, - 0x30ef3006u, 0x33d03430u, 0x2a1429a6u, 0x348fb263u, 0x3051b0b4u, 0xa88431aeu, 0xb1f9b18cu, 0x1e9c32d8u, - 0x302bb3dfu, 0x333ab0ccu, 0xb1c1af50u, 0x1f16b3f9u, 0x30d3a791u, 0xadffa570u, 0xb042b094u, 0xb26e341bu, - 0xaea534b0u, 0xb0d3b3e7u, 0x3192b43du, 0xae421fb6u, 0x2d042e39u, 0x346e3439u, 0x321a2ef0u, 0x9d58319du, - 0xb40c2fdau, 0x346f30f4u, 0x3274b3f8u, 0xb1423428u, 0x341c239fu, 0xb325346bu, 0x2f9cadccu, 0xaebbb159u, - 0xb2a7b494u, 0x2de128c9u, 0x31582db8u, 0xb059aa82u, 0xb1a2b4a7u, 0xb22eaf34u, 0xb294b49bu, 0x2cfa2e61u, - 0x31ba342fu, 0xb2f52934u, 0xb43528ecu, 0xac37a94fu, 0xb03aa98bu, 0x328c2f23u, 0x2ce83128u, 0xb48025e4u, - 0x26e93048u, 0xae9cb067u, 0x2cc7342fu, 0x2ca5a366u, 0xa494aaa0u, 0xa89fb007u, 0xb46b2f20u, 0xb02b31aau, - 0x2d7b2f03u, 0x2c272ddcu, 0x1d203468u, 0x2fe43076u, 0xb029b110u, 0xb045a9d6u, 0xac30ad1eu, 0xb1612bfau, - 0xa8cc31d8u, 0xb4052febu, 0xb487a49du, 0xae002ec1u, 0xaec13450u, 0xb0a828e6u, 0xa5102c9du, 0xb1b0acf8u, - 0xb34cb375u, 0xaabc34cau, 0x3459b4c8u, 0xaa41b49cu, 0x33f6302du, 0xa5963016u, 0xb46c348eu, 0x32b534adu, - 0xb0b5341eu, 0x2e45b2ddu, 0x231e20dfu, 0x2c9c3414u, 0xabadaf41u, 0xb1e8b309u, 0x31f5b2d9u, 0x24a92fdeu, - 0x2e78acd3u, 0x33523202u, 0x32242739u, 0xa3d31ef2u, 0xac5d3304u, 0xaf7eabfeu, 0x26e421bfu, 0xa9562e29u, - 0x330bb16bu, 0x340fadeau, 0x289db19eu, 0x324f25a0u, 0x33dfb2efu, 0x2a9d24d4u, 0xb4741e3fu, 0xb08a9726u, - 0x2dbaae0au, 0xb3cf95a9u, 0xb209b419u, 0x2c29b1efu, 0x3354b230u, 0xb3dab193u, 0xafdc3337u, 0x3468a9bau, - 0x30203444u, 0x2b2bb423u, 0x344a34b2u, 0xabfdb391u, 0xb31caf15u, 0xb0582f7bu, 0xb3ddadf5u, 0xb29094ffu, - 0xb2d9a937u, 0xb2d1345bu, 0xb1d122b9u, 0xb1b7b411u, 0xb2ecb446u, 0x2dd49c01u, 0xa888b3ecu, 0xb11a2a3du, - 0xb41caceau, 0xa51bb160u, 0x34c434b5u, 0xa9e8349bu, 0xaec6b407u, 0xb4aab109u, 0xa731b3c6u, 0xb223ae28u, - 0xad7d3026u, 0xb0f932c2u, 0xb21125e6u, 0xb2ac99c6u, 0x2c4fb27fu, 0xb24ab089u, 0xb4633420u, 0x276a2901u, - 0xa741b0cau, 0x3040b3eau, 0xb1e3b158u, 0x33baaf1cu, 0x344a31b1u, 0x2e422dd6u, 0x33c8a222u, 0xad911eafu, - 0x27162d64u, 0xac1fb338u, 0x32a9af2bu, 0x322daca7u, 0x30dea86du, 0x3414b301u, 0xb09da1f9u, 0xb083b0f7u, - 0x302dad1eu, 0x2e7e3451u, 0xa7e5273fu, 0x32b7324du, 0x345aaff3u, 0x31c3ac07u, 0x2fd2347bu, 0x2a9eb280u, - 0x318db352u, 0x2f7fb033u, 0xb22033e0u, 0x2da6ac1du, 0xb23eaa2cu, 0xab2cb485u, 0x29af2dbbu, 0xa793b29au, - 0xb056ad03u, 0xaf4f3067u, 0x3410262au, 0x2c7e2608u, 0xb22eb419u, 0x3116b3a9u, 0xb2053273u, 0xaecab164u, - 0x2cad2affu, 0x33c82f2cu, 0x2e19afdfu, 0xaf752896u, 0xb3c433d3u, 0x30603012u, 0x21b533f9u, 0x324baedau, - 0x0a353133u, 0xb0753125u, 0x33032ae0u, 0xa10eaefdu, 0x31ba3454u, 0xac68336eu, 0xb2ac34c4u, 0xa25e21c4u, - 0x33d831bbu, 0x2cdf3070u, 0x1e58a993u, 0xb49b1db7u, 0x32d6177cu, 0x31ad3005u, 0x2473ac35u, 0xac7eb47bu, - 0xb0b3a3dcu, 0x2f50b480u, 0xaa7aa8fcu, 0x25d0b0cdu, 0xa3fea8c2u, 0xb4bd2a36u, 0xb41e33d4u, 0xb19ea78au, - 0xb038234eu, 0xabf632eau, 0xb0d22d54u, 0xab5cb49du, 0xa637259bu, 0x2ff1346fu, 0xafdf34c2u, 0x2844318du, - 0x34aa2c4bu, 0x33a82deau, 0xb3273056u, 0xa0d12fa8u, 0x31e43405u, 0xb307b39au, 0x9c26b422u, 0x304bb406u, - 0x32732805u, 0x21e1b03au, 0x3362b358u, 0xb3a2b23du, 0x31e1b1aau, 0x2c65b392u, 0x30d230bau, 0xb435b1f3u, - 0xb1b6a7ddu, 0xad812fa7u, 0xb36ca7c7u, 0xb20a2930u, 0xb41e2ee0u, 0x2f163492u, 0xb4aab21cu, 0xb2aaae5bu, - 0x3328b168u, 0xb2362bedu, 0xb0b0285au, 0xb47c3492u, 0x313e3076u, 0xb24db428u, 0x3312ac71u, 0x2df725afu, - 0x324d316fu, 0x1d67a349u, 0xb08b3030u, 0xb49a32ceu, 0x31c4b1d7u, 0xb2b9ae22u, 0x24b9b204u, 0xb41f32a6u, - 0xa55ab482u, 0xb03e3461u, 0x33723468u, 0x3216b02au, 0x1f442f23u, 0x320fa9ecu, 0x30ef31a1u, 0xa29a34c9u, - 0x32f631e5u, 0xb465b18au, 0x32d9ab51u, 0x2faeb00du, 0xad8eb4bbu, 0xb31c2c70u, 0xb299339du, 0xb17233deu, - 0x2c0634bfu, 0xb42cb3fbu, 0x2ae7b415u, 0xab7431f2u, 0x2adba83du, 0x2f392513u, 0x301ba455u, 0xadc034c6u, - 0xb330b4afu, 0xadfb281cu, 0x2ce53439u, 0x31b92241u, 0x3224b0a3u, 0x2c98b4c5u, 0x3187342cu, 0xabea32cau, - 0x27cf323au, 0xb43c2c8du, 0x27d4b1bbu, 0x30a3b43cu, 0x34093287u, 0x3439b3a5u, 0xa3f8b427u, 0xb4203288u, - 0xb48fb4a0u, 0x31fc1eedu, 0xb335b327u, 0xb11a2944u, 0x3451306cu, 0x333e311cu, 0x32612204u, 0xb425b217u, - 0xb44d2dfdu, 0x2f5b3389u, 0xaf263457u, 0x30a4a041u, 0x266eb0f0u, 0x34992e20u, 0xb35530b3u, 0x2ad1a394u, - 0xa93ab2c9u, 0xb352b026u, 0xb26b1f66u, 0xb2582af4u, 0xb1da304bu, 0xb48c339cu, 0xaee822c2u, 0xa45db147u, - 0x33f93291u, 0xb2a3af8eu, 0x2a4c303au, 0x30ffb1beu, 0x2de421d1u, 0xa8adad67u, 0x30edb223u, 0x3158b296u, - 0x30bc31b9u, 0xb05bb49du, 0x2b56a4ddu, 0xacc73406u, 0xb2763333u, 0xb44cacf1u, 0xb2b530a8u, 0x3149b0aau, - 0xb4aa2555u, 0x1e8db4c7u, 0xb223af7du, 0xb1372c5du, 0xaca32b15u, 0xb2f3b204u, 0xb483b10du, 0x33b8af5eu, - 0xacea325du, 0x292c29d3u, 0xb1103250u, 0xaf9dafd2u, 0xaf1eb468u, 0x33e93342u, 0xa671b37fu, 0x9e8aac8eu, - 0xb49b2834u, 0x348c3292u, 0x2e292de4u, 0xae5d244cu, 0x2a75b2bdu, 0x323bb45eu, 0xaa8caa13u, 0x3481aea3u, - 0xb2b2b23eu, 0x2e16b26cu, 0xb11434b9u, 0xb04033cau, 0xb4692daeu, 0x2def9957u, 0xb1092594u, 0x3483324fu, - 0x2d38a644u, 0xb0f73193u, 0xb03832ffu, 0xb373314cu, 0x252ab010u, 0x32ba23a8u, 0xb38b34c3u, 0xad78b064u, - 0x9b7ca27au, 0x313232d7u, 0xa6e9b49eu, 0xa6152c89u, 0xabe0b317u, 0xb1ffaac9u, 0xaedc30ecu, 0x20d52ad6u, - 0xb342333fu, 0xafabb368u, 0xafbca948u, 0xb0e4310eu, 0xaa9fb3f9u, 0x32bb3140u, 0x2872307bu, 0x2ef7304eu, - 0x27ccb11au, 0xaf063132u, 0xa1b02deau, 0xb3df17c3u, 0x33052e62u, 0xad24b2e2u, 0xb484b455u, 0x9c0334b3u, - 0xb053ad8cu, 0xb0c2349cu, 0xb0273055u, 0x2f0ab420u, 0x2ec0b4c9u, 0x30bab0cbu, 0x304e312eu, 0x2fd3b491u, - 0xb0f134b5u, 0x3205b056u, 0x2e2bb285u, 0xb47130e6u, 0x29d42821u, 0x333aaf8cu, 0xad37b27au, 0xb1f132b2u, - 0xb40a322cu, 0xb4149e9eu, 0x31942ed5u, 0x349f32b8u, 0x312a2e9bu, 0x33ed1b13u, 0x335d2d85u, 0x9802b114u, - 0xb1b5306au, 0x3497b18bu, 0xb21ca906u, 0xabe2ae79u, 0x34102cbau, 0x2dd334acu, 0xaed72fadu, 0xb16b32dcu, - 0x348bb38fu, 0xaf8a32feu, 0xa5112ebau, 0xb018aecbu, 0x2793b2fdu, 0x1f7da81au, 0x3436b177u, 0x33ac2d52u, - 0x2cb8b381u, 0xae7e32b6u, 0xb083b1dau, 0xa80eb05cu, 0xb064aeafu, 0xb44a2db4u, 0x2f49ae21u, 0xb15cb239u, - 0xb4cbb1bfu, 0xb46da407u, 0x34c0b05cu, 0xb1783404u, 0xa593af4cu, 0x31d0329du, 0xb336b32du, 0x331baa65u, - 0xb38a3356u, 0xb29c29b5u, 0x33ff2f26u, 0xb401a6f3u, 0xab072a16u, 0xae2131f8u, 0xb0583333u, 0xaf6eb293u, - 0xb033b477u, 0xb2de2e26u, 0xb30fb376u, 0x3331b40eu, 0xb45a3443u, 0x308e30feu, 0xadd734c5u, 0xa735b01eu, - 0x306432d9u, 0xb0e8a45cu, 0x32cf305cu, 0x2e79abafu, 0xa29babaau, 0x314b23a7u, 0xa8463496u, 0xacdbae0eu, - 0xafccb308u, 0xa98ab3f1u, 0xade6b263u, 0xb0e131a3u, 0x33b42c4cu, 0xb1e12924u, 0x2af1adf6u, 0xb2bf1c10u, - 0x269da816u, 0x2c51b078u, 0xae46b420u, 0xb09f31d8u, 0xaae92c0au, 0x33fdaf0cu, 0xb10eae05u, 0x30b933dcu, - 0xb4532efbu, 0x2d50b315u, 0xb145b194u, 0xb01c315cu, 0xb473b41du, 0x2c7fa85du, 0xb3793315u, 0x2494b1d3u, - 0xa15dad38u, 0x26e53412u, 0x34b3aa85u, 0x3426b42du, 0x189e1416u, 0x1c80340du, 0xb05ea8bbu, 0x29592e19u, - 0x3005b17cu, 0xabe22d88u, 0xa81ab4c2u, 0xb414b4beu, 0xb403a954u, 0x2df9b04fu, 0x34c7af59u, 0x2a8d33feu, - 0x3311347cu, 0x30cbaef4u, 0x2f16b2f9u, 0xb4a39d7bu, 0x345fb056u, 0xb21eaf12u, 0xa263b200u, 0x30f43294u, - 0xb198a8dau, 0xa5bdb45cu, 0x3069320bu, 0x2b46ab05u, 0x2a12a8e5u, 0x2ef32161u, 0x343b1cbcu, 0xb4a6a987u, - 0x0df7b110u, 0x2806263bu, 0xb054301fu, 0x2fd62e55u, 0xab83aad0u, 0xaa9bb22au, 0x33da3182u, 0xafb42b31u, - 0x309c2f00u, 0x3245ae71u, 0xb4b2b418u, 0xb29bb33du, 0xa9c33347u, 0xa972b052u, 0xafa0ac0au, 0x2dfdb2f4u, - 0x314ab2fau, 0x3071b1bau, 0xb33231deu, 0x3451b3efu, 0x2d00a5adu, 0xb040b494u, 0x336a1aa2u, 0x3149b063u, - 0xb3632e3bu, 0xb108afefu, 0x2d32a86au, 0xb0e8a91du, 0x2a7d2f86u, 0x282e21efu, 0x2eeeb157u, 0xad3eac52u, - 0x2b70b2bau, 0xae222be2u, 0x32a232e9u, 0x2f7db382u, 0x34ccac14u, 0xb037b148u, 0xb071a872u, 0xa1dd2f5fu, - 0x1bd5b15cu, 0x319d3377u, 0xb01091c2u, 0x3344b225u, 0x298b3009u, 0xb3433349u, 0xb1702f02u, 0xa548b349u, - 0x343cac53u, 0x320caec2u, 0x2e7330c7u, 0xab123409u, 0xb283ac3du, 0x334bb04eu, 0xae18a3dfu, 0xa09fb173u, - 0xb0183029u, 0x2cfc30f3u, 0xb0c83185u, 0xb2a62d08u, 0x304fad3bu, 0xb1fe2d0eu, 0xb44a32e1u, 0x34a52b50u, - 0x31c624d7u, 0x316f2b4fu, 0x2f572dfau, 0x30a5b13au, 0x349db108u, 0xb10eb13au, 0xb0ef32e3u, 0x301fad57u, - 0xb28cb28du, 0xb0eca031u, 0xb4b6b113u, 0xaefbacfau, 0x2ca8b480u, 0xb41f2cddu, 0x3328af07u, 0xaac32a4fu, - 0xb19aa55cu, 0x33f331fdu, 0xb14d33e2u, 0xb284af44u, 0xae6caf67u, 0xb1f52d1cu, 0xb39f3407u, 0x32d1b4bcu, - 0xad8e2fd3u, 0xb14f2b56u, 0xa46eb25eu, 0x2c6dada3u, 0x2e42b169u, 0xb2673120u, 0xa8a4b461u, 0x2dca3143u, - 0xab762fc1u, 0x24e2b117u, 0x3058b1adu, 0xb002b1d1u, 0xa0151c05u, 0xa8ce2bbfu, 0x32873407u, 0x2cf93347u, - 0x2c312d2fu, 0xaed5a900u, 0xb48e2b11u, 0x32c0b4bau, 0x239eb45bu, 0xb1cc2c6au, 0xb1f33399u, 0x310d3362u, - 0xb2b5b0fau, 0xabd6af0fu, 0x34cab0e2u, 0x3259b131u, 0x349cb28cu, 0xaa04b145u, 0xb34a287fu, 0xb0533215u, - 0x27a02791u, 0xb4442be2u, 0xb281b25du, 0xb2d1af9au, 0x1ff6340du, 0xad792cbfu, 0x17cfb04cu, 0xae01afe6u, - 0x1b0ca742u, 0xb15034a6u, 0xb2bb9f63u, 0x302cadc3u, 0x2a3fb240u, 0xb44eaa66u, 0xaaa33428u, 0xaa6d3174u, - 0xb0063433u, 0x30f8aabeu, 0xad35ae01u, 0x284534c0u, 0x2d822f46u, 0x32f2324cu, 0xafe428dcu, 0x2c65b495u, - 0xa7993240u, 0xb012b270u, 0x32771e23u, 0x2c4eb24du, 0x343030ddu, 0x3418b35cu, 0x311f2bcbu, 0x1b8eb449u, - 0xaf6b2cb5u, 0x282ca940u, 0xb4662809u, 0xb17fa8a6u, 0x34933400u, 0xb23dafb2u, 0xa2d6b163u, 0x016d3331u, - 0xb46bb445u, 0x3295b13cu, 0x28d62caau, 0x341faef4u, 0x326eae7cu, 0xa11f339au, 0xb0493392u, 0xb3e92e15u, - 0xb16da401u, 0xb4c4b433u, 0x2ae0aebbu, 0xaf9da6e0u, 0x343834b7u, 0xaa85b330u, 0x307c2db7u, 0x30bbad22u, - 0xae75b337u, 0x2cd43028u, 0xb45a3279u, 0xb456b240u, 0xb4c2b1e9u, 0x2459192cu, 0xac6b2e10u, 0x2eadb4c5u, - 0x3308b447u, 0x24aeb495u, 0x29913395u, 0x2ef92c2au, 0x2eb8b340u, 0x348d334eu, 0xadf9a860u, 0x269630ddu, - 0xb24bb0a9u, 0xa645b255u, 0xb49cb255u, 0x3420b44du, 0xb419b419u, 0xb0e5a77fu, 0x33e43471u, 0xa7e0ab51u, - 0xb470acccu, 0xb33faff4u, 0x28adb3a2u, 0xb3a0b3b4u, 0xa86fa1fcu, 0xb4c2b2f5u, 0xb112b1e5u, 0x33fa31c4u, - 0xab4bab39u, 0x2ce03014u, 0xb388b211u, 0x28fba8cbu, 0xaff0b2f0u, 0xb095af74u, 0x2de1a607u, 0xb1bb1dc5u, - 0x322eb3a0u, 0xb434a25cu, 0x31d6b0a5u, 0x333730d5u, 0xa9ec2bd7u, 0xb1e0a9a2u, 0x2a892dcau, 0x3368b2a0u, - 0xb453ad0du, 0x331aae9cu, 0x9de63401u, 0x33343462u, 0x32e8323fu, 0x30edac89u, 0x303829f1u, 0x3071b230u, - 0xaf943465u, 0xacac34abu, 0xb372b1c4u, 0x28363179u, 0x2c2aaf68u, 0xa7efae73u, 0x2e7532f7u, 0x2a6a310au, - 0xb0f734b8u, 0xb3d3b090u, 0x2c5a2826u, 0xae523057u, 0x2d14b4afu, 0xafe434cau, 0xb031b212u, 0xb0c8a9bau, - 0x2d4fade0u, 0xabfcadf3u, 0x3403b46au, 0xae99ab27u, 0x2d27b3f1u, 0xb46832fcu, 0xb2cab2d0u, 0x340b2bdbu, - 0xadffa8c8u, 0x30a8311bu, 0xb283b0ddu, 0x314bad76u, 0x2e5e2f7eu, 0xb0473253u, 0xb465ae28u, 0x2a553314u, - 0xb422afc1u, 0x30c7304au, 0xb1b02e62u, 0x30dc33efu, 0x2dcc2e0fu, 0x341d33c3u, 0xaa662b58u, 0x3220ad3cu, - 0xb40f2d8eu, 0x33afb2dfu, 0x34563362u, 0x3174a98bu, 0xaf14324du, 0x34c5b2cfu, 0x2b7ab483u, 0x2efb2dc5u, - 0x3041b0b1u, 0x3251b172u, 0x2f8eb165u, 0xb1f93171u, 0x315cb108u, 0xb1f0b3f3u, 0x3421a6d5u, 0xac5028c1u, - 0xa5933498u, 0xaac9a917u, 0xaeb1af36u, 0xb4682f37u, 0xb1bd2efbu, 0xb2c9ac72u, 0x3067280du, 0xb276ad95u, - 0x321cb140u, 0x3146b076u, 0xb1faae7bu, 0xa4d5305du, 0x346ab480u, 0xada1b2c3u, 0x9e7fac6du, 0xb4be317bu, - 0x2d9b3427u, 0x32183454u, 0x2bc2341bu, 0xa862ad7bu, 0xa99d2e12u, 0xb3d63073u, 0xb1ae3256u, 0xb29d3443u, - 0x31fdb31fu, 0x3096321eu, 0xb068346cu, 0xadaf3246u, 0xa82e25bfu, 0x29b8b4beu, 0xb24030c1u, 0x24ab3425u, - 0x2d9bb22du, 0xb431b1eau, 0xb37a2f1eu, 0x309bb390u, 0x31f3b445u, 0xb2e331b0u, 0xb3bf21a6u, 0xb4322d17u, - 0xb19d3444u, 0xb3232f06u, 0xa789b193u, 0x34ca299du, 0xb4ccb48du, 0xad24adbfu, 0x33ec335fu, 0xb2da334eu, - 0x30b9aac0u, 0x2e45af32u, 0xaec8b10cu, 0xb0ca32ecu, 0xaf713475u, 0xb0b5b493u, 0x1c32b250u, 0x2cd7b370u, - 0xad473333u, 0xabaeb25du, 0x2b07317eu, 0x25b6b3a8u, 0xaea4a4e7u, 0x349eb37cu, 0xb1e6b238u, 0x2964b2ceu, - 0xb0cfa854u, 0x2eaaa96cu, 0x33f9b031u, 0xb1ccaf70u, 0x31f6345du, 0x328eae06u, 0xade221c8u, 0x30d73285u, - 0x2c19afc3u, 0xb4caad04u, 0x279f346fu, 0x2bac2b8fu, 0xb00827c7u, 0x2cac3487u, 0xa6f22e90u, 0xb42fb013u, - 0xb238adc0u, 0x33472e39u, 0xae6baf93u, 0xb2bc2e8bu, 0xad3a341fu, 0xb23fb3a8u, 0xb0db3428u, 0xb29a2e3bu, - 0x3348b1e0u, 0xb49fb2c2u, 0x32f71210u, 0xb324aeafu, 0x2ec934a1u, 0x30d732bcu, 0xac6f2f9du, 0x302aaebfu, - 0x34533029u, 0xafe32946u, 0x2c5e9e6fu, 0x3197a9a1u, 0xb4b62a80u, 0x2d21295du, 0xaaa033f9u, 0xa3ae29b8u, - 0xb42724ddu, 0x33e133a1u, 0x28582762u, 0x2b86b43fu, 0x3003a971u, 0x300db459u, 0x2dd3b017u, 0xb13f2ce2u, - 0x3272a893u, 0xb4242c0eu, 0xaf3aa862u, 0x2c662d70u, 0x2c23b4b3u, 0x31293082u, 0xaf8ab43cu, 0xb226aa0cu, - 0xb41eaa16u, 0x2e7ab36du, 0x300fb08fu, 0x28d1b457u, 0x31b4ac2bu, 0xacc73174u, 0xb13b2cb6u, 0xb4052a2du, - 0xb217a906u, 0xa83b335cu, 0xad5d2af9u, 0xb1b4b00eu, 0x31c033e8u, 0x30bdb30bu, 0xb4a7aa42u, 0xb31a245bu, - 0x2f87b192u, 0x3386b0aau, 0x32612e09u, 0x33152c6cu, 0x278cad50u, 0x33c120e2u, 0x29ffb26fu, 0xacfd30e3u, - 0xace0330fu, 0x2a74b246u, 0xb4a7aa1au, 0xb1dab421u, 0x3387312cu, 0xb3932703u, 0x32d42549u, 0xb00330cau, - 0x33b1b339u, 0xb44932ccu, 0xb3bc3237u, 0x30f7b431u, 0xaa902594u, 0x328433c1u, 0x2c75b43fu, 0x27c1313au, - 0x2f2534a3u, 0xb1cbb39au, 0x34c53244u, 0xb3acb3b6u, 0xb42f310fu, 0x3377b424u, 0x335331c5u, 0xaed12dc8u, - 0xafbb33cdu, 0x336bb04fu, 0x33992ef2u, 0x3458b29bu, 0x2e742c54u, 0xac9433f3u, 0x2d643037u, 0x339f3186u, - 0xb4272eeau, 0x345cb215u, 0x347d3480u, 0xac84b472u, 0x30db30fcu, 0x2c34b3f3u, 0x9c2cb2dbu, 0xb44ab0ffu, - 0x33e4b408u, 0x342530b2u, 0xaaa9a49cu, 0x2c77ad70u, 0x30baadb3u, 0x333731c9u, 0x2427b0f0u, 0xb471b14fu, - 0x27862ffbu, 0xb3eb304du, 0x34bf34c2u, 0x3307a560u, 0x3090b0ecu, 0x320b3348u, 0xa5ae31fcu, 0x2f533225u, - 0xb368b30fu, 0x2cd13139u, 0x33d221f4u, 0xabfa2e21u, 0x2c0baa9cu, 0x28f130ffu, 0x305b1d62u, 0x32582fe2u, - 0x30e5b433u, 0xb415203au, 0x30282ee0u, 0x31a42342u, 0xb1b9afacu, 0xaae8adbbu, 0x32a22f86u, 0xb242303eu, - 0xb28fad23u, 0xb0d62f2cu, 0x319a23cdu, 0xafbe2e90u, 0x2de4ae6bu, 0xb3c02799u, 0x1fc0332eu, 0xb1caa417u, - 0xae6bacb9u, 0x292db067u, 0x3379a5cbu, 0xb163343du, 0x317ab3aeu, 0x32fb34c0u, 0xb0c7b493u, 0x3229b462u, - 0x20372a41u, 0xb0c1282fu, 0xb4812bceu, 0x30802d9bu, 0xae722ea5u, 0x30233244u, 0xb1dab323u, 0xb00b2d44u, - 0xb2a0b34fu, 0xa2d3b26cu, 0xb2372c20u, 0xb0343014u, 0xb14faf3cu, 0x346a317au, 0xb4669c9cu, 0xb291b099u, - 0xb3f93295u, 0x2acc347au, 0x32ab2173u, 0x3152b489u, 0x328bb35cu, 0xb437247bu, 0xb48a3266u, 0x31b8b2f1u, - 0x3353a565u, 0x2cbe2d33u, 0xb309affau, 0xb396346du, 0xb05e2475u, 0x2b44b087u, 0x315231b8u, 0xaff43315u, - 0xb4b6a543u, 0xaf9730bdu, 0xb25928b9u, 0x32173222u, 0xb45c333fu, 0xb0d834bau, 0xb0d0af51u, 0x280bb077u, - 0xac14b0ffu, 0x32742dfau, 0x2b3e2f67u, 0x3212b2c3u, 0xb087b471u, 0x2e6eb441u, 0x2dd7ad0eu, 0xa6ccade0u, - 0xb45da675u, 0x2d6ba95cu, 0xb4142713u, 0xaf572e74u, 0xb29db4a9u, 0xaf4895ffu, 0xb0fb2f77u, 0xb01a313du, - 0x31bf2ca4u, 0xb45aac65u, 0x34c22572u, 0xb15b3481u, 0xadf430e9u, 0x2e5fb286u, 0x26071045u, 0xae473249u, - 0xad232e6bu, 0xacafb464u, 0xa1243452u, 0x2f36b386u, 0x33d53473u, 0xacc02987u, 0x32112a32u, 0x321f32f0u, - 0xb351a6d7u, 0xb2992950u, 0x928cb437u, 0x32cd2df7u, 0x32dc316eu, 0x2fce30feu, 0x2cd8b4b4u, 0xb43db349u, - 0x3235b299u, 0x344f30afu, 0x338d3499u, 0x3344b30cu, 0x33203280u, 0xb35cb2b0u, 0xb2433412u, 0xa6c3ad0cu, - 0xb49ab336u, 0x333b34beu, 0xb02333ebu, 0xa9b2b160u, 0xb4bfa72cu, 0x34c5315du, 0xac4a2468u, 0xb3c1ac1eu, - 0x153eb07du, 0x26eba93cu, 0xb14632b4u, 0xb46fb489u, 0x296ab306u, 0x336d31ebu, 0xab702d30u, 0xab92b2a2u, - 0x331bae6fu, 0xb142a014u, 0xb2fbb00eu, 0xb4513405u, 0xb216b4adu, 0x233631f8u, 0xad772cd5u, 0x32d7b424u, - 0xb47cb1eau, 0xb4002995u, 0x31c4b3c3u, 0xb0f79d28u, 0x3067add0u, 0xb35db42au, 0x2c1c2c77u, 0xacd13489u, - 0x25c4b42du, 0xb2eb2d50u, 0xb1ce280fu, 0x326f329eu, 0x347ba968u, 0xb31e349bu, 0x2bb4ad14u, 0xac82b3f9u, - 0x3457b096u, 0x310baacau, 0xb312ac5au, 0xb4cc32f9u, 0xad35b443u, 0xae142f2du, 0xaeffb42au, 0xb4bfb0e5u, - 0xb35c2558u, 0x2d6cb014u, 0xb08b3052u, 0xb0dcae8fu, 0xb1f13463u, 0xa839b215u, 0xb297b1f7u, 0x2d62b3c2u, - 0x2dc42c4eu, 0xaeab313fu, 0x307a3404u, 0x303e31dau, 0xb02aad6fu, 0xb3bda9f3u, 0xb463a77cu, 0x3424b4c3u, - 0x28c02f45u, 0x296bae1au, 0x2dda3385u, 0xa61d2bdfu, 0x2fa0adedu, 0xa9c7349eu, 0xa985ac24u, 0x34b6a9b8u, - 0xad682ff1u, 0xa951acefu, 0x2446b473u, 0x2e2a31fau, 0x3061b1cau, 0xb08f3037u, 0x2c432cb8u, 0xb2fd3286u, - 0xa04fb1dcu, 0xaa7bb460u, 0xb2bf3189u, 0x34b4a627u, 0x941f1b46u, 0xb2072884u, 0x2ecfb2c6u, 0xb009ac01u, - 0x32a5b480u, 0x30cdb47du, 0x2b94ac88u, 0xb29eb0d8u, 0x2f832521u, 0xa8e3b1d9u, 0xb174a840u, 0xb2cc28ffu, - 0xb36c1dfdu, 0xaf3ca071u, 0xa917a756u, 0x9e2f33d5u, 0xb144321du, 0xb414adaeu, 0x2e7aaa16u, 0x2910327eu, - 0xb2322d61u, 0x319ab471u, 0xb3d9b265u, 0x34733433u, 0xaca92c77u, 0xb1ab3266u, 0xad7ea96cu, 0x340833edu, - 0xb3792dcbu, 0xb0e4a178u, 0xb2f13364u, 0x2fdab447u, 0x327fa72du, 0x31c8b415u, 0xb488b471u, 0xb15aa5f1u, - 0xb48d2b33u, 0x305cb476u, 0x2e02b191u, 0xb43b30ccu, 0xb072312eu, 0xb3f0ac3eu, 0x28aa3280u, 0x348019bcu, - 0x3381ae5bu, 0x341d3038u, 0x34b733d4u, 0x31afb312u, 0x2d8b31d9u, 0x3477b03fu, 0x8c2db1adu, 0xb27e229au, - 0xb3e53046u, 0x32b22f6au, 0x3005adc8u, 0x32a4b297u, 0xb2ab3457u, 0x1b2a2f5eu, 0x2fee24d7u, 0x2bb49eebu, - 0xacaab12bu, 0xb37d3303u, 0xb2102b7eu, 0x2a1232a7u, 0xb0ceab72u, 0x3465a8dau, 0xa4b01da8u, 0xaca530bau, - 0xae43a993u, 0x301bb2b4u, 0x33ca332au, 0xa7683350u, 0x2d4cb025u, 0x305c345du, 0x2f409a55u, 0x3406313cu, - 0xa922310eu, 0x84a7b059u, 0x3440ae99u, 0xa44b1ce5u, 0x2d5aadd4u, 0xb31f2229u, 0xad6a3317u, 0xb1a7a92eu, - 0x2fc2281au, 0xb44e3352u, 0x2fd4348bu, 0xb1adb024u, 0x3337afd5u, 0xa5b6b001u, 0x33242fe6u, 0x30dc2e17u, - 0x333fb246u, 0xb323b04eu, 0xb1ba3492u, 0x2cd7b2fau, 0xb30aaef5u, 0x30f92bc4u, 0xb29d31a1u, 0x3206285eu, - 0xb19db282u, 0x2391b4c7u, 0x304eb1ddu, 0xb1983470u, 0xb1882dbau, 0x30f7b4a1u, 0x344aa912u, 0xb2942544u, - 0xb1b4a7b7u, 0x2f553342u, 0x2446ae19u, 0x316e2e82u, 0xb495b408u, 0xac08b367u, 0xb2fba51du, 0xa87caad3u, - 0x3400b381u, 0xac482b9du, 0xaf231c3eu, 0x29c332ceu, 0x33e49a46u, 0x3201327du, 0xb2a9b145u, 0xa4d12f4du, - 0x31012f0eu, 0xb022afdcu, 0xb0599da2u, 0x30bd2e6du, 0x304ca44bu, 0x30161e6au, 0x3096b148u, 0xb07b3021u, - 0x32d2284cu, 0x3088b0cfu, 0x3308345cu, 0x2c1eab90u, 0x294234b9u, 0xb45db364u, 0xa9de3193u, 0xadd9b0dcu, - 0xa55730f1u, 0x30833313u, 0x3376348du, 0x2e1cb0b6u, 0x34b7b49au, 0x2e54b097u, 0xb28532b4u, 0xb4af32aeu, - 0xa44ca875u, 0x2aa2acd6u, 0xaea533f7u, 0x333f2a16u, 0xb469313eu, 0xb45a3440u, 0x29ca2ad1u, 0xb2c03180u, - 0x30d7b228u, 0xa4b1b2bbu, 0x2dcf3073u, 0xaf87b18eu, 0xa7e23481u, 0xb162b460u, 0x34ccae0du, 0xb48caf94u, - 0xb3ff1ff0u, 0x34bab057u, 0xb4502fdcu, 0xb24ea7e2u, 0x2ab0b33du, 0x30aa1af3u, 0xb0dd3388u, 0x21873410u, - 0x32a4b0a1u, 0x2892b475u, 0xb0393041u, 0xb0fd32fbu, 0xb40c3287u, 0xac92b288u, 0xb2d332ccu, 0xb1303335u, - 0xada8a74bu, 0x3444b355u, 0x2f4fa8bfu, 0x143829c8u, 0x33a62c7au, 0x24fd2fa7u, 0x2c162d93u, 0x2ccaa923u, - 0x30f2a855u, 0x346a3480u, 0x2bd13228u, 0xb22e30cau, 0xb0a9a272u, 0x347bb4c4u, 0x203532fcu, 0x2f69b0b8u, - 0x31d3a902u, 0xadcc34ccu, 0xb077b0e8u, 0xac12b3cfu, 0xb367b4a2u, 0xb288b062u, 0xb3933075u, 0xb15b3307u, - 0xb4b4b384u, 0xb0ac3022u, 0xb3751dd6u, 0xb33134a9u, 0x32c0aac4u, 0xb079b0e6u, 0xb05a31ecu, 0xa989b4c6u, - 0x33deb4aeu, 0x2a602d72u, 0x2faeb1bbu, 0xb4382eceu, 0x2a193350u, 0xb08d319eu, 0x2fc6b342u, 0xac6031a4u, - 0x321cb493u, 0xae2eb1a5u, 0xb3ae2cedu, 0xb48eb41cu, 0xaf3e3400u, 0x34b22e2bu, 0x23b62e82u, 0xacba226du, - 0x34682baau, 0xa9d23188u, 0x335dae6fu, 0x32b6b2feu, 0x3024b0b4u, 0xa31131e1u, 0x329fb1e8u, 0xaee3ad16u, - 0xa8fc1e27u, 0xb2f72f07u, 0x3385a8f0u, 0xa68eb474u, 0x33722e2au, 0x323b2b34u, 0xada7b153u, 0x3369343fu, - 0xa3882873u, 0xb43ca784u, 0x321c3389u, 0xb03ca6b8u, 0xb33cae08u, 0x285a3042u, 0x2cb9b11bu, 0xb340349au, - 0x9b2da660u, 0x24dab266u, 0xb2942c12u, 0x32d8b2a1u, 0x2d01af3eu, 0x32832cdeu, 0x328a309bu, 0xa7c32ccfu, - 0xaca5ac16u, 0xb31eaa44u, 0xac3fa9d7u, 0xb051b478u, 0x29fc30d6u, 0x268f31e1u, 0x31af32ccu, 0x3494b3b7u, - 0x2b70b4a9u, 0xae75319eu, 0xad4b2b92u, 0xb4b8b438u, 0xb3b6b3c7u, 0x23f22c42u, 0x2f5fa6d7u, 0xb066b4a3u, - 0x33df3153u, 0xb405a8bcu, 0x336531bcu, 0xb0edaaa2u, 0x2affb461u, 0x2ed533dfu, 0x2d7daf05u, 0xa36d3260u, - 0xac273224u, 0x2a60add1u, 0x3495a56du, 0xac692109u, 0x275dac09u, 0x3048ad92u, 0xac73ac95u, 0xb4372c7eu, - 0x1a1c2df7u, 0x3036a737u, 0x32a630f5u, 0xaea4accfu, 0x2a48301eu, 0x28442d10u, 0xb1f4313cu, 0xb2902847u, - 0x2e4cab20u, 0xaca09c42u, 0x313d3364u, 0x3452240au, 0x3188a9cfu, 0xb01db260u, 0xb391ae38u, 0xb1e9146fu, - 0xb1f32d27u, 0x3481b33bu, 0x34312e14u, 0xb47b9e37u, 0x287b29b6u, 0x32f0b4a8u, 0x30b32c9bu, 0x2c8c9b78u, - 0x348cb0a8u, 0xb27caba0u, 0x2d3bb443u, 0x339934a4u, 0x34b62fc3u, 0xae2c3047u, 0xb4092bc6u, 0xaa55b158u, - 0x345bb1bau, 0xacf534c2u, 0xab153004u, 0xae43b2ecu, 0xae9ab11fu, 0xb371b179u, 0x33cab16du, 0xaebbb3f7u, - 0xad96245fu, 0xb4622169u, 0x28e02db4u, 0x292a2ef3u, 0xadc1a8c5u, 0x02aab141u, 0xae98b48du, 0xb3832ed5u, - 0x2dd8b432u, 0x31ccabdau, 0x34633433u, 0xb086a9b7u, 0x2cec2c2cu, 0xaed82cb3u, 0xb191b430u, 0xb339b2a3u, - 0xb4ab3418u, 0x344c2bd3u, 0x242aad60u, 0xaf052f85u, 0x3217a2deu, 0x31ec30b6u, 0xacfb34aeu, 0x2be530bfu, - 0x309b2e66u, 0x336830cbu, 0x2de5adc9u, 0x2b43b038u, 0x319630d3u, 0x1d5caa22u, 0xb25bae61u, 0x33eab099u, - 0x348faf56u, 0x3048b0f7u, 0x2f8f29adu, 0x2ff02d87u, 0x28e033c9u, 0xb066b426u, 0x9b482fffu, 0x2b6b2775u, - 0x3142ac82u, 0x301d304bu, 0x337f3022u, 0x347c2b53u, 0x2d11b350u, 0xa2ff302au, 0x27b0b011u, 0x33dbad32u, - 0xb23aad80u, 0xabfd29deu, 0x28fbb3c2u, 0xb24625d0u, 0x292c2b80u, 0xad513141u, 0x3455b0d3u, 0xb48a28b4u, - 0xb1d23228u, 0x2fe1317eu, 0x34783480u, 0x311eb055u, 0x2cf6af08u, 0xb4472b82u, 0xb43fb4c0u, 0xb0a7b325u, - 0x21b933d0u, 0x327f31b3u, 0xac2c3083u, 0x30a632fcu, 0x33b630abu, 0x24642b94u, 0xa6ff337eu, 0xb44831fbu, - 0x2459b4cau, 0x3493b418u, 0x3030b4bfu, 0x347db0edu, 0xb48aac8cu, 0x2819b48bu, 0x349b34acu, 0xa150ae40u, - 0x22d0b3acu, 0xb0c82ba8u, 0x33ad2c4eu, 0xb134b4cau, 0xb339b192u, 0x2cd6b269u, 0x3094b3a1u, 0x3418336eu, - 0xb1cf2e27u, 0xb125b3f6u, 0x3470346fu, 0xaeb1ac89u, 0xb0001e27u, 0xb15a349bu, 0xa96dad06u, 0xac80b333u, - 0xb2e832d9u, 0xab2c2a74u, 0xb4aeb253u, 0xb435b05au, 0x31f5acbbu, 0x344b3038u, 0x2ffba99bu, 0xb16f2e59u, - 0x2495af8bu, 0xa5de31b2u, 0x34bdb13au, 0x3460b362u, 0x328231efu, 0xb19a31aau, 0x30ee2d17u, 0xb06330b8u, - 0xae9ab21fu, 0x29aba231u, 0x312a3278u, 0xb08a2ec4u, 0xae52a27du, 0xb4b4b117u, 0xb0afae2au, 0xb4342986u, - 0xb45fb068u, 0x293d2d6eu, 0xb2c5ae3eu, 0x2a7b3465u, 0x24d12ee1u, 0x339c31e3u, 0x2f4cac81u, 0x2dd5b130u, - 0xb4bcabbfu, 0x33133460u, 0x34c7b004u, 0xa652af06u, 0xaf8132bfu, 0x2e5ca799u, 0xa9f7b318u, 0x2ecaaf52u, - 0xb122b2fdu, 0xb29a300fu, 0x3016a9fdu, 0xb3c73119u, 0x304d32c2u, 0x3111ae2cu, 0x2bc03062u, 0x3082287eu, - 0x2a0834cbu, 0x30b131edu, 0x345d32d5u, 0xb26cb1e5u, 0xa7ca2aa2u, 0x31b9296eu, 0xaa583425u, 0xb1d2302fu, - 0xb497254fu, 0x26f7189cu, 0x2dbd3085u, 0xb4bfad70u, 0x348bb362u, 0xaeb7340eu, 0xa8e2b0a1u, 0xad7f2f4bu, - 0xab77b427u, 0xaeb9b099u, 0x2e19b279u, 0xb0662417u, 0x9c7b2823u, 0x346131afu, 0x335fb317u, 0x2f652fddu, - 0xadfeacd4u, 0x34a1b4bfu, 0xab802c17u, 0xb46926b9u, 0x2cbdb244u, 0x31832062u, 0x2bca2e19u, 0xb425320eu, - 0x30242f54u, 0xb1d8b051u, 0xb1ccb17eu, 0xb2ff234eu, 0xb3952e1eu, 0xaef0b48bu, 0x34b1b1ebu, 0xb156af91u, - 0xacd8b1d2u, 0x316a2c11u, 0x2cd6ad33u, 0x32a7a183u, 0xb009294du, 0x32252fd1u, 0x34ada54fu, 0xb1d23347u, - 0x2bc13181u, 0x20482559u, 0x2c4232c9u, 0xb45525cbu, 0x33d6a7f1u, 0xb4503011u, 0x3246335fu, 0xb496272cu, - 0xb44728cbu, 0x2cf3aee6u, 0xad7633eeu, 0x340432eau, 0xb101b499u, 0x30ee3008u, 0x2e05ac22u, 0x309b2c4fu, - 0xb3f43033u, 0xb30db290u, 0x33f13427u, 0xb35c31b6u, 0xb20129b4u, 0xb079ad0eu, 0xb2d43251u, 0x34a52d9du, - 0xb40a2f2fu, 0x2d7f33d5u, 0x2e22a6b6u, 0xa3073347u, 0xa74e24d0u, 0x3183b41au, 0xac0cb32cu, 0xb039ac59u, - 0x2c88ab7du, 0xb24aaf3eu, 0x34853318u, 0xaea4a65du, 0xb472b458u, 0x3421ac1du, 0xadca306eu, 0xa979347eu, - 0xa9a8b049u, 0x3367b18au, 0x2e11ad55u, 0x33b7ac43u, 0x9f382d78u, 0x33b8b310u, 0xb0212731u, 0xb4473342u, - 0x25a8af24u, 0xa326ae27u, 0xb31ab086u, 0xb293b472u, 0x29ca3459u, 0xac719ec8u, 0xb2e33000u, 0x2dfdb04cu, - 0x3130a26eu, 0x323533a0u, 0xb3d8b210u, 0x3172b259u, 0x341633f2u, 0x3289afc0u, 0x32332591u, 0xb2cd276eu, - 0x3464b40au, 0xadbda9b3u, 0xaca6ad85u, 0xb4333446u, 0x3190b350u, 0xb3222797u, 0xb14bb478u, 0xb4aab098u, - 0x3093b173u, 0x33a532d3u, 0xaeefac3au, 0x312c34ccu, 0xb0b525bdu, 0x20b8aeddu, 0xb4ab2677u, 0x29ce3469u, - 0xb18a2ad9u, 0x308e3116u, 0x2b4cb3c6u, 0x32712e13u, 0x3340b1a5u, 0xb3bfa5ebu, 0xb1cdb392u, 0x986bb02cu, - 0xb20430c7u, 0xb28034bbu, 0x341e2ba2u, 0x2dae3262u, 0xb3063023u, 0xa90fb4b5u, 0xad76b3e2u, 0x33feb14eu, - 0x3220334cu, 0xb2a4301cu, 0x2de9b456u, 0xad042d76u, 0x9eaba432u, 0xaf23b0feu, 0x2bedaa45u, 0x25e93460u, - 0x31e53070u, 0x2de1b36cu, 0x2990a17fu, 0x33cdb46eu, 0xb4c43459u, 0xb224b184u, 0x2b883167u, 0x3207b232u, - 0xa603ada0u, 0x2291ac54u, 0xb054a21au, 0x33d7a9cbu, 0x33ff171du, 0x312927b3u, 0x3193afedu, 0xb49db086u, - 0xb498b284u, 0x34cd344bu, 0xb3863109u, 0x30ae33a9u, 0x1599ae71u, 0xb4922e36u, 0x30761393u, 0xa851b1fcu, - 0x308624ffu, 0x32b03475u, 0x2a6c2cabu, 0x26f02bedu, 0x2f9db43bu, 0x1fab3027u, 0x2e9f331du, 0xb49cad46u, - 0xadb1b43bu, 0xb265a5d2u, 0xb12eb1f7u, 0x31353163u, 0xb24aac7fu, 0xb3edb378u, 0xb45dac2du, 0x346eae63u, - 0x32321c9cu, 0xb074b31eu, 0xac793449u, 0x34922db3u, 0xaf7a27cdu, 0xb44724e8u, 0xb4bbb371u, 0x2e943360u, - 0xb15bafbeu, 0x34072f08u, 0xaedaafb7u, 0x338e32cdu, 0xaff133f3u, 0xa89cb34au, 0x335fafd8u, 0x2d24b473u, - 0x349333ccu, 0x34522dc4u, 0xad67b413u, 0x349fb4b7u, 0xb48833bbu, 0xad1cb4a0u, 0x32a9b0a3u, 0x3195b285u, - 0xacb5282fu, 0x34c7b2cdu, 0xa8a82c88u, 0x33caacf3u, 0x31fa322bu, 0x33732c76u, 0x2fd3afb5u, 0x2baeab57u, - 0x34a734c8u, 0x29ac1fc1u, 0x34a933a1u, 0xb42d3159u, 0x339daed0u, 0x30a73127u, 0xaa822e73u, 0x31eeab6eu, - 0x2f19afebu, 0x329e3058u, 0x30a5aeebu, 0xb2f3b38eu, 0xb445aa59u, 0x33b7344cu, 0x327fb455u, 0x2fc11d74u, - 0x29e9336eu, 0xb4c6b35eu, 0x34509791u, 0xace12994u, 0x33f8b481u, 0x2fddaea3u, 0xb0ba2f75u, 0xac6ab430u, - 0x2fb1af06u, 0xb1543224u, 0xb4692456u, 0x3107b17cu, 0x314f31a2u, 0x27d7b2deu, 0x34b8a9f0u, 0x342e2debu, - 0xa78cb2cfu, 0xad133137u, 0x1f312d17u, 0xb24334b9u, 0xab8f342eu, 0x2465a4ebu, 0x3473b081u, 0x348a33e7u, - 0x2e8534c5u, 0x32bca76cu, 0x326cb492u, 0x2ea796abu, 0xad0bacd6u, 0xa9dab47fu, 0xb149ab0au, 0x2a76b0dau, - 0x3257aeffu, 0x29f7b376u, 0x2456b287u, 0x2d772809u, 0x1dd2a993u, 0xa5aeb220u, 0x2e61ace0u, 0x315da901u, - 0xb113a9afu, 0xb45eb058u, 0x325a2622u, 0xa8c7312bu, 0x32fbb1d6u, 0xabbdb441u, 0xac1a32d9u, 0xb07eb356u, - 0xb2ae2bafu, 0xa8c02df3u, 0xb0f9ae5cu, 0xabef3235u, 0xa8953094u, 0xa892b3d6u, 0xa67a1cb9u, 0x33e33212u, - 0x2a5c3182u, 0x2d8e265eu, 0x31fdb013u, 0xb07832dau, 0x32b233bcu, 0x33daa9cdu, 0xb488b34au, 0x2907add8u, - 0x343eadb4u, 0xb033b0b6u, 0xb4c32d2du, 0xacb5305eu, 0x2f5a3496u, 0xb3d2b44cu, 0x3458b3e8u, 0xa98f2f11u, - 0x332db1c0u, 0x2ff0b1bbu, 0xafe3310eu, 0xb1521a0au, 0x3477aca6u, 0x32a82f6bu, 0xb103263cu, 0x0d953016u, - 0xaabab234u, 0x30852d2eu, 0x3338b0eeu, 0xb065aca0u, 0x31d7b1dbu, 0xa11aad9au, 0x2f25b152u, 0xae2b3165u, - 0xb4823446u, 0x2ad2b30cu, 0xb0c92fbcu, 0xaef92827u, 0x2e1e2827u, 0xa6ce348au, 0x29fe2db1u, 0xb0beaf02u, - 0xb1a134afu, 0xb2c93193u, + 0xa8b23143u, 0x2f9432e3u, 0x3491b3cbu, 0x317e3104u, 0xa79fb324u, + 0x3419acf6u, 0x32322d86u, 0xb13da859u, 0xb4302831u, 0x2d0e324au, + 0xad9630f5u, 0x338c3485u, 0xb1dd3158u, 0xb461a51du, 0x2f07b2a3u, + 0x347d30b3u, 0xacf9aeb0u, 0xb1f6a4adu, 0xa377b31bu, 0x2e85b13eu, + 0x3263a8d4u, 0xaf352fb1u, 0x31da3261u, 0xb010ac52u, 0xb2eb2f02u, + 0xb4bbb1c3u, 0x2e553182u, 0x31642fe1u, 0x2948a64fu, 0xb367b2eau, + 0xa4712e77u, 0x31172903u, 0x281d2d2cu, 0xaf87288cu, 0xa8dcb481u, + 0xab06b17bu, 0xb11c32c9u, 0xb033b43eu, 0x2e38afedu, 0x31732861u, + 0xab312e4fu, 0xb2653207u, 0xb3dfb495u, 0xa5db3045u, 0x1123b281u, + 0x2f8ab2adu, 0xac92a823u, 0x2d01af9fu, 0xb3ebad4eu, 0x346fb356u, + 0x2fab33d8u, 0x3481b07fu, 0x302a315au, 0xb05fa7c7u, 0x33bbb3c0u, + 0xb1b7a6cbu, 0x2a16af74u, 0x32d9b235u, 0x303730f7u, 0x2ce3a937u, + 0x2dc12a75u, 0xaa77b3fbu, 0x9b62b467u, 0xb2d3ae89u, 0x2abbb39du, + 0x3415b253u, 0xade12a3au, 0xb4952afbu, 0xa1703467u, 0xb401316eu, + 0x9db6a019u, 0x29823434u, 0xb079a412u, 0x225aae78u, 0xb498a8b1u, + 0x339b3244u, 0x2826b2e8u, 0x2e9db384u, 0x2e1fb033u, 0x3128305cu, + 0x33fdb388u, 0xb471b12eu, 0xacf52836u, 0x31eb3255u, 0x3459af06u, + 0x20a0b004u, 0x3430b0afu, 0xb45eb271u, 0x34baa8fcu, 0x30c63385u, + 0x338e3381u, 0xaf1121cbu, 0x2e353139u, 0xb3c9acdau, 0xb09030bdu, + 0xb0f93432u, 0x325bb33eu, 0xb228b2a8u, 0x33312ba2u, 0xaf49b1d4u, + 0x34883154u, 0xb2d60f49u, 0xb131b4abu, 0x2ed2b312u, 0x1bc7b343u, + 0x2a3b2f76u, 0x31d7b1c4u, 0x30973023u, 0xb339b315u, 0xabde341bu, + 0x9f04afa5u, 0x34602e41u, 0x3414b01au, 0x283db490u, 0xb3912d25u, + 0xaa36b2e8u, 0x2b60347au, 0x31d83428u, 0x3178a503u, 0xb381b4a1u, + 0x31b33253u, 0x24bab122u, 0x33102c12u, 0xaab72bebu, 0xa9b1acd5u, + 0x330e2dd6u, 0xb0d7a715u, 0x30b9b10eu, 0xb3943214u, 0x2b41b429u, + 0x323cb2cbu, 0xb2d6af48u, 0xb26c340bu, 0xb2a7b022u, 0xb499b362u, + 0xb23fb445u, 0x2b00b44au, 0xac162ef0u, 0x1990aefdu, 0x32be3333u, + 0xb21db462u, 0xb0d0b10eu, 0xaa6e2978u, 0xacdab454u, 0xb3a6234cu, + 0xb44d3267u, 0xb3b23414u, 0x33bb3299u, 0x31cd349bu, 0x2d79315eu, + 0xb304315bu, 0x205f258au, 0xa5b732deu, 0x2d5cac6au, 0xb2ebb07cu, + 0xaa62a2ccu, 0xad16b122u, 0xaea0ad21u, 0x2f22aca1u, 0x344fafcdu, + 0xa1dd33feu, 0x2571ae97u, 0x2ddc32b1u, 0x250731d8u, 0xb0112d1bu, + 0xb1b73083u, 0x32ed2f7bu, 0x2c64b310u, 0x3055b3c6u, 0x342fb3fau, + 0x3468b2f6u, 0x2b3231c7u, 0x31ab316du, 0xb0bc3448u, 0xb3c62aebu, + 0xb2502c76u, 0x299028fdu, 0x22f4a53au, 0x31bf3111u, 0x2ba69cd2u, + 0xb34d3424u, 0xb3eab35au, 0xaa402e10u, 0x2e933144u, 0x33a6ae63u, + 0xb068310au, 0xaf20ad37u, 0xb2c3b293u, 0xa8c53430u, 0x3069ac7bu, + 0x34302812u, 0xa2563162u, 0x34acacbfu, 0x3455302eu, 0x32bbb353u, + 0xb3422d43u, 0x2f252ac7u, 0xa704b4afu, 0xafdc323fu, 0xa86ea65eu, + 0x3404af9bu, 0xb37a3167u, 0x334834c6u, 0x3278b026u, 0x34cbb38fu, + 0x2dc42e5du, 0x339fb3ddu, 0xb0fab486u, 0x3150b2dbu, 0x33e2b1cbu, + 0xb4742e00u, 0xb44eb4bfu, 0x31ca2c11u, 0x32b5b105u, 0x31c7b440u, + 0x3139341bu, 0x327d2f9cu, 0xb1bab46au, 0x1991b334u, 0x2cfe30b5u, + 0xb29f32beu, 0xb1e53081u, 0x3008b067u, 0x2c49349cu, 0x2c77b447u, + 0x3360b465u, 0xb2473006u, 0xb213b3d7u, 0xa65d349cu, 0x2d3d3174u, + 0xb2d02990u, 0xafa13448u, 0x2fac29feu, 0x343b2dbbu, 0x1d22b2c0u, + 0xa3efab5fu, 0xb306b350u, 0xaf80b043u, 0x2c43a989u, 0xaac62d2bu, + 0xb16cab01u, 0xaf072ac8u, 0xaa44b474u, 0xb145a3f2u, 0x290d2991u, + 0x2dae2fc2u, 0xaf0f2ddau, 0x278c3185u, 0x2cd7a944u, 0x1fd4ad5au, + 0x336b308bu, 0x1877340bu, 0x31c2223au, 0x327aaf20u, 0xb3609b33u, + 0x3291b41cu, 0xb036b444u, 0xb247ae5fu, 0x30a9af26u, 0x3248b4a9u, + 0xace832d9u, 0x2bbfb2a7u, 0xad30b34du, 0x34c23467u, 0xaf423139u, + 0x2fe32f35u, 0x2d69ac4fu, 0xb196b4b2u, 0xb27523b5u, 0x3275b26au, + 0x284c34b2u, 0x34b53283u, 0xa7f3b2e2u, 0xb408ac20u, 0xa91630e7u, + 0xb2b5a4b6u, 0x33d1b220u, 0xb121b45fu, 0x9e06affcu, 0x9c1f2aa4u, + 0xb0ecb3fcu, 0x2d493299u, 0x2e892dbau, 0xb43e310cu, 0x2612ad1fu, + 0x329dae34u, 0x3128a15bu, 0x19e332c2u, 0x2ab133ddu, 0xae1f32bau, + 0x24d391d1u, 0xabcbb396u, 0x2d063402u, 0xae30b231u, 0xb490b1ecu, + 0xa7f5341bu, 0x2b90af64u, 0xb043b4bbu, 0x2d232fccu, 0x2c9f34a0u, + 0x3105a2e9u, 0x303d33beu, 0x316a3472u, 0xb369330bu, 0xa89a3076u, + 0x2deb2814u, 0x34a73483u, 0x307db011u, 0xade530cdu, 0xb468b339u, + 0x9e543153u, 0xa56134a9u, 0xaaca3497u, 0xb3f931a4u, 0x31cd2842u, + 0x32323414u, 0xace3b472u, 0xb380b455u, 0x30182ebbu, 0x33043141u, + 0x31c73099u, 0xb119b454u, 0x32e02caeu, 0x207eb4c2u, 0xb4842ecfu, + 0x3399ab93u, 0xb1092e97u, 0xadd632c6u, 0xafb832c9u, 0xabea2af0u, + 0x336cb053u, 0xb3f9b200u, 0x302eae12u, 0x34ca31e7u, 0xab12afd2u, + 0x29c0b2f9u, 0x2fb734c7u, 0xac222b50u, 0x979433f9u, 0xad2bb305u, + 0xb1b9b428u, 0xa72db4a1u, 0xae042d2bu, 0x3469aa1du, 0x264730d6u, + 0x339fb023u, 0xaeb5b116u, 0x248a33dbu, 0x2af830a7u, 0xafb42de4u, + 0xaed1b0f7u, 0x3330b29eu, 0x28b9b029u, 0x3173319bu, 0xa34ba8bbu, + 0x2eb434c0u, 0x33bb320bu, 0xb20b3186u, 0xb3a528c6u, 0x345f2ddfu, + 0xa9261fd3u, 0x346ab475u, 0xb468b39fu, 0xb42cb0e0u, 0x20f1a6e5u, + 0xb450af33u, 0xac6fb375u, 0x2f9cb438u, 0xaf9ab1a0u, 0xaa68ac11u, + 0xb373b4c9u, 0xb4ca32f7u, 0x9e731d05u, 0xa946ae69u, 0x328d3163u, + 0xaed1b09au, 0xa230b0f2u, 0xb1382f0au, 0x3422ae80u, 0xa607b455u, + 0xb2b63010u, 0xb2f2b458u, 0xb4b63405u, 0xb480b1fcu, 0x2c9db37au, + 0x2951b0f6u, 0x32b62aedu, 0x32c9b4c1u, 0xb27a2c93u, 0x32d3313eu, + 0x3405b0b8u, 0x2bf1a6ffu, 0xad5134a7u, 0xaef93203u, 0x2bbd31bfu, + 0xaa9ab172u, 0xb40daf01u, 0xade5b483u, 0xb26cb49eu, 0x2ffe3053u, + 0xaf053095u, 0x2b35337du, 0xb2d7b32eu, 0xb2482f6au, 0x34b91c7bu, + 0xb4a4b4c3u, 0x2a8034bcu, 0x33a1b32au, 0x258f334eu, 0xb05b2cadu, + 0x2b43b451u, 0x2e48afe2u, 0xb4a03275u, 0xb1292b5au, 0xb0bb332eu, + 0x281d2c41u, 0x2ed2abf9u, 0x29243056u, 0x34a430f6u, 0x207baa33u, + 0x31afb4aeu, 0xab122237u, 0x337bb3cbu, 0x2f03ac08u, 0x346eb2bbu, + 0xb1c5b22du, 0x33ec32e4u, 0xa4a3b187u, 0x3344307cu, 0x213aaca5u, + 0x307030a4u, 0x295f316fu, 0x33c2b397u, 0x31b93305u, 0xb1adb3afu, + 0xb49430adu, 0xacb8349au, 0x33713036u, 0xaef2ac0cu, 0x2a382c2du, + 0x2bd1aafau, 0xa4f8342eu, 0xacb7b1d3u, 0xb315ac11u, 0x2f16b279u, + 0x345eae2au, 0xb3b3b0ecu, 0x335130deu, 0xb1b8b043u, 0x22c3b209u, + 0xb09ea4dau, 0xa1b0b45eu, 0x2ddb3469u, 0xb37a9986u, 0xafe1b0c1u, + 0x333c3116u, 0x34a733b6u, 0x345934a1u, 0xb2f4b41cu, 0x2810af82u, + 0x32a4b3bdu, 0x26822c7cu, 0xb0bdb26du, 0x32c2b286u, 0x30842a78u, + 0xacf2afd5u, 0x30feab4fu, 0xb1a1313bu, 0xb349343du, 0xb3ac339bu, + 0x32a7b085u, 0xaaa3b227u, 0xb0e4a7b4u, 0x32bf3009u, 0xae2c3331u, + 0xb0d524bdu, 0xb281b0e6u, 0x33733439u, 0x216d3153u, 0x24929dc5u, + 0xa907259eu, 0xb330b312u, 0xa1853457u, 0xb276345au, 0xb19d282eu, + 0xb483b0bdu, 0x3400b351u, 0x2c27aedau, 0xaba5a560u, 0xb20124e6u, + 0x321d34b1u, 0xa4cc30a4u, 0x340ab2aau, 0xb452ae17u, 0x31a7ae0du, + 0x30d12cb6u, 0xb18831a3u, 0xa8c33411u, 0xb4c72d57u, 0xb03534bdu, + 0xa669b434u, 0xb2adb31fu, 0xac1d2d14u, 0xaef2340du, 0xa5fa3058u, + 0x2ba82e24u, 0x3452a42eu, 0xb232ae0au, 0x32a52ed7u, 0xa7bdb46au, + 0x30cb3389u, 0x24d334b9u, 0xaf962e25u, 0xad22344cu, 0xab703094u, + 0x303828bfu, 0x33d11d7du, 0x2da6aa33u, 0xab0eae0eu, 0xb32fa89bu, + 0x2e6eb3d7u, 0x2e412df9u, 0xaea9b49cu, 0x3157b1cdu, 0xb0dd32edu, + 0xb31e2e72u, 0xb2f0b051u, 0x2eb6b028u, 0xb1b633e1u, 0x2fbc2677u, + 0x2c3a3459u, 0x2cd2b0b4u, 0x3492aee5u, 0x2f1fabb4u, 0xabadb494u, + 0x2c3c3334u, 0x342fa84eu, 0xaed432ccu, 0x9e4126d8u, 0xae5f2d14u, + 0x33ecb0e9u, 0x32983412u, 0x30b43497u, 0x310b3115u, 0xa6b0a1f5u, + 0x2d90b0fdu, 0xb0a6b00cu, 0xaaea2a9au, 0x3211b166u, 0xb26132ecu, + 0xae4bb4bau, 0x328331b6u, 0x3144b2f2u, 0xac39b361u, 0xb1e734c9u, + 0xa9eeb2a5u, 0x34282c98u, 0xb422349eu, 0x3195b2f3u, 0x3364b067u, + 0xb3742e47u, 0xb2373262u, 0x2802a9e0u, 0x2f260f88u, 0x34b92dddu, + 0x210e34cbu, 0x3060b3c6u, 0xaefa3493u, 0xa9c7a5f5u, 0x2e9db44eu, + 0x3185ada2u, 0x322b3260u, 0xaedaaa66u, 0x31c930c7u, 0x338c9d5fu, + 0x3347b2d6u, 0xb2a7b3c1u, 0xb4272533u, 0xb4ccb44bu, 0x3146a8e4u, + 0x2dd9b477u, 0xb2603234u, 0x32edb2c8u, 0x25fb3234u, 0xb3d23221u, + 0x3091ac0du, 0x30d8b0a8u, 0x30ce1922u, 0xad13a56du, 0xb199b164u, + 0xb35130d4u, 0xb237b3f3u, 0x3234b23cu, 0x34b5abcbu, 0x2de5b2f7u, + 0xac1da7e0u, 0x34913334u, 0xb1e83329u, 0x2dfeb15cu, 0x3082b00du, + 0x27d2291au, 0x300b324fu, 0xb453b48bu, 0xa03e2bcdu, 0xaa3fb09bu, + 0x324530f4u, 0xac6728b4u, 0x22bcb067u, 0x28ecaf1du, 0xb42a2ec9u, + 0xb186b4cau, 0x2d9e3393u, 0x337eb24cu, 0xa358a49du, 0xb43b342eu, + 0x2a96b178u, 0x2ee5b1d9u, 0xb3b2b17du, 0xa9efb1a0u, 0xb304b238u, + 0xaee632ebu, 0xb445ad59u, 0xb084ad7au, 0xb1a82c3eu, 0x34203375u, + 0xb38ab3afu, 0x2c97b363u, 0x32c4b342u, 0x322430e2u, 0x34c52401u, + 0xab95b460u, 0x344faec3u, 0x31e129e7u, 0x3498b254u, 0x9bc792b0u, + 0xac943485u, 0x2a82abdfu, 0xaedfb324u, 0xb39eb1e4u, 0x2adc3308u, + 0xab04ad6du, 0x2d1da942u, 0x34283419u, 0xae8eac2bu, 0x2938a785u, + 0x2e19a5ddu, 0xaee2282eu, 0xaca9adedu, 0xb269b3c8u, 0xac423049u, + 0x28d0b17bu, 0xb0a830e8u, 0x341b3246u, 0x2e7d2b7bu, 0x3447b44cu, + 0x3412ac21u, 0xb4c12a11u, 0x2eeeb46eu, 0xb48c28d0u, 0x32c330adu, + 0xa5429867u, 0x3181b4bfu, 0x3346ae80u, 0x28fface0u, 0xb284b069u, + 0x98313147u, 0x3478259bu, 0x32d43473u, 0x2b3db1ffu, 0xacd23343u, + 0x31f8b3a9u, 0x28f2a19au, 0x2c1e34a1u, 0xacfea9c3u, 0xb354aa54u, + 0x327c31a9u, 0xaf89b024u, 0xb4923330u, 0xa5942249u, 0xb2762f4du, + 0xacbc2e77u, 0xb46a2c8fu, 0x22d6a5e1u, 0xb2ebb17cu, 0xadfcb1fbu, + 0x344bb3beu, 0x31efab4cu, 0xb406348eu, 0x33222dd3u, 0xa9732d28u, + 0xb475a94bu, 0x34bd2551u, 0xb46a3467u, 0xaf9d2fe7u, 0xb45e33bdu, + 0x327b342fu, 0xb43ab358u, 0xb29c326du, 0x33fb255cu, 0xabe4292eu, + 0xb432a839u, 0xaf453480u, 0xb01cb1f7u, 0xb3ca3475u, 0x2ffb330du, + 0x34923256u, 0x34423292u, 0x31aeb32au, 0x26ae2704u, 0x348833a9u, + 0xa13e2fdeu, 0xac5da6b2u, 0xac2bad51u, 0xb40eb3e0u, 0xa8243160u, + 0x2c4f3422u, 0xb293b476u, 0x3491b1a6u, 0x20d7b167u, 0x34953430u, + 0xb454b110u, 0xb431b2a7u, 0x2944b1dbu, 0x25b833ebu, 0xb1b92cd7u, + 0x2c8631c5u, 0x344f32feu, 0xb3dcadd7u, 0xa8c6b143u, 0xacac3447u, + 0x26383133u, 0xaee2b217u, 0x2ea32de2u, 0xb136a903u, 0xb25c3043u, + 0xb1fe3431u, 0x95c8b38au, 0x1d092201u, 0x34c0a8ddu, 0xa2c6a037u, + 0xb429aa02u, 0xb1392b24u, 0xb4502d49u, 0xa4c3349fu, 0xa382339eu, + 0x3230b439u, 0x31692db1u, 0x2d4ca984u, 0x2d0832d7u, 0x2e3eadd9u, + 0x346c2e99u, 0xa9c1acf5u, 0x1b1531feu, 0xa630308bu, 0x30b5b176u, + 0xb1cab315u, 0x30bf2cdfu, 0xb05e3394u, 0x3461b379u, 0xb1ceb2a3u, + 0x2484b002u, 0x3101335au, 0xb23d2ffeu, 0xa2a2ad77u, 0xb05ab2c5u, + 0xb328af5cu, 0x2fe027b8u, 0xa1cdb421u, 0x30c3316bu, 0xa7f3320du, + 0xb0fa3228u, 0xb237ad58u, 0xac25a4ffu, 0x30d6b0f9u, 0xb05daf26u, + 0xa8b3b316u, 0xad05af91u, 0x310db112u, 0x95153421u, 0x330d2d7eu, + 0x2c5c34cau, 0x33d8337cu, 0xa6003199u, 0xb4a6b405u, 0x9afca301u, + 0x293cab1du, 0x32772802u, 0xb147b384u, 0x32ae31a0u, 0x332934c0u, + 0xaf21337cu, 0xb074ab8du, 0x34362c15u, 0x2861adf7u, 0xb257afd2u, + 0xb43eb1dau, 0xab753450u, 0x2ef7326au, 0xb23bb1eau, 0xb08431fdu, + 0xb2e933efu, 0x320a2ed3u, 0xb04cb115u, 0xb0853476u, 0xa92fa961u, + 0x314cb0beu, 0xacac3138u, 0xb182326fu, 0x2977b4c2u, 0xb46e34beu, + 0x21d0b19bu, 0xb3e431f3u, 0x30beac06u, 0xb1f9acefu, 0xaae9b1d9u, + 0x32f2a253u, 0x2f502d76u, 0xaac534a3u, 0x3410ab6cu, 0x306ab0e1u, + 0xb3b930e3u, 0xb1c0a4e1u, 0xa58eb20au, 0x31afb00bu, 0x31d033d3u, + 0xb056b07eu, 0xb302b0b6u, 0xab863443u, 0x32a8b149u, 0xb476abbeu, + 0x2d59b27eu, 0xb18d316fu, 0x32bd3402u, 0xb13b32b0u, 0x330eb451u, + 0x2c91af75u, 0xb32330feu, 0x34363164u, 0xa8843063u, 0x2438333bu, + 0x322730b3u, 0xb01330cau, 0xb106b356u, 0x1a7c1711u, 0xac072a59u, + 0x33ef3182u, 0x308bb0ddu, 0x23182ed6u, 0x31abb1fbu, 0x3042346cu, + 0x34a63403u, 0x2d4fadaeu, 0x34aca401u, 0xaabbb3cdu, 0xb0253336u, + 0xac803187u, 0x335d349cu, 0x3130afa1u, 0x2c16ae44u, 0x32542e16u, + 0xb15fb491u, 0x28e13012u, 0xb4459967u, 0x3303add4u, 0xabf4b481u, + 0xb4503446u, 0xb0a730cbu, 0x30b9330au, 0xb1743368u, 0x315d24ceu, + 0xb12bb0e2u, 0x3467b48au, 0x2d353008u, 0x24db30afu, 0xa7c0a355u, + 0xb1bb2d65u, 0x31fc3373u, 0x2a0aadc7u, 0x3489b2e4u, 0x340d33bcu, + 0xb25aae72u, 0xb3dfb189u, 0xb41eb34bu, 0xb41734b4u, 0x3249b30eu, + 0x31452a2au, 0x33562d07u, 0x22cc2d51u, 0xa80a3016u, 0xa4f8ade9u, + 0x31b2b257u, 0xb2a7b098u, 0x3291b0dfu, 0x2f25ae85u, 0xb40e32d8u, + 0xaf633117u, 0x2f41b171u, 0xafdf33deu, 0xb0092949u, 0x2cae282bu, + 0x2cbf2c3du, 0x2f6fb302u, 0x2f032eb6u, 0xa815b417u, 0xb3efaafcu, + 0xa889b155u, 0xb10c30aau, 0x27093255u, 0xa4373100u, 0x2c998fecu, + 0x9d08341cu, 0x2bd52467u, 0xb41c308fu, 0xa1a820d2u, 0x9bfb340cu, + 0x3470a4deu, 0xb221a797u, 0xb3c6b16fu, 0xa93ab4cbu, 0x307c312bu, + 0x2960b47eu, 0x343cb2a3u, 0x2cddb263u, 0x2d70aeacu, 0x30fcaabdu, + 0x33cbb12cu, 0x30eb081fu, 0x34ca32b7u, 0xb017b14du, 0xb08eb0cbu, + 0x34bd2a55u, 0x241d34b5u, 0x32e92d57u, 0xb1b03428u, 0x32642462u, + 0xa89faf8fu, 0x34a834a9u, 0x31bb33ccu, 0xaee1b06fu, 0x28ab2743u, + 0x2d401ac3u, 0x30c9ab0au, 0xae81ae64u, 0xb1fab328u, 0xa82032bbu, + 0x30fbb13au, 0xb4992825u, 0xb234af0du, 0xb0522dfcu, 0xb446b42du, + 0xb4972a47u, 0xb29e32b2u, 0xa83f2c18u, 0xb41ca864u, 0x338c31d0u, + 0xb22cb4b2u, 0x279a33c1u, 0xb1b5b2b8u, 0x30512e25u, 0x345a2ba3u, + 0xafab9b4bu, 0xad64a2feu, 0xb45cb14bu, 0x300fadadu, 0xa8acb49fu, + 0x2c3d2d88u, 0x31f63150u, 0xb3a03011u, 0x2bf1a3acu, 0xb464b0e3u, + 0xa6eeb14fu, 0xb235aa9cu, 0x3416323bu, 0x3420b1bcu, 0x3414b4a1u, + 0xb4af3457u, 0x3484310du, 0x348533cbu, 0xb40d27bbu, 0x2c5f32b7u, + 0xaa5b2c68u, 0xb2a72984u, 0xb414309bu, 0x32b33069u, 0x1e0aa43bu, + 0x3482af36u, 0xad08307au, 0xb162b23eu, 0x3440a58bu, 0xb178307fu, + 0xacad32e7u, 0xb0f632c1u, 0x34192c8eu, 0x2f69b0a6u, 0xb2b534aeu, + 0x2eb0b3e7u, 0xb41eae27u, 0x30dfa396u, 0xae56b020u, 0x222b32a3u, + 0xa81e3295u, 0x2dca3459u, 0x3365b360u, 0xb2e19e98u, 0x2f34b2abu, + 0xb019b458u, 0xa886b2ebu, 0x22b8aa94u, 0xb47eb03bu, 0xacd92c64u, + 0xb3832dd0u, 0xb0d5b4abu, 0xac11a6adu, 0xacb131f5u, 0x2b2f24adu, + 0x20a6b497u, 0xaa0cadf5u, 0x316eb3adu, 0xb496343fu, 0x31112bc9u, + 0x3185b022u, 0x341f2d15u, 0xb465349eu, 0x2738a83bu, 0xae49b2c8u, + 0xb4a534aeu, 0x3294a74bu, 0xa235aec3u, 0xa3b83497u, 0xb44eb316u, + 0xb07f3447u, 0xb3dc18feu, 0x3421a9ddu, 0x348615eeu, 0x1996b0a1u, + 0xa7f332e7u, 0x32d3b03cu, 0x24b8ac3au, 0xb2053493u, 0xb480afa0u, + 0xb1c2ac27u, 0xb21e2eeau, 0xb08b2eb6u, 0xadcead8fu, 0xa5253029u, + 0x32c5ad53u, 0xb17f2987u, 0xae0b33afu, 0x9aa3b46du, 0xb105b338u, + 0xb31730bfu, 0x343231e5u, 0x300a2c17u, 0x34bb301au, 0xb279ae16u, + 0x251b21e3u, 0x2c58b22fu, 0x341bb4aau, 0xb46cb085u, 0xb0fdb386u, + 0xb47cb057u, 0xb1e5b03du, 0xac69aca9u, 0xae9cae2fu, 0xb48fb3e1u, + 0x30edb1b8u, 0x341d34b6u, 0x24e3192fu, 0x3142af1fu, 0x329c3115u, + 0xa90b3398u, 0x31e23120u, 0x341faf5bu, 0x34bfb3cau, 0xb3cf3130u, + 0xb4792e00u, 0x31bf3130u, 0x32da2bddu, 0xb04db3b8u, 0xb464aa97u, + 0xb082a7f4u, 0xa9c1ac1eu, 0xb0693349u, 0xa9af338fu, 0x162cae9du, + 0xb0a9aa51u, 0xb2af1696u, 0x290dadb0u, 0x3238aaa6u, 0x3483b0acu, + 0x347d3177u, 0xb2df327eu, 0xb2562410u, 0x2a77321cu, 0x3420b08bu, + 0x28e8b363u, 0xb43c303eu, 0x32112b84u, 0x1f86b427u, 0x2e42b0a3u, + 0x3432b352u, 0xb2073394u, 0x2abbaec9u, 0xa8673030u, 0xb39ab299u, + 0xa6dc34ccu, 0xa16a3327u, 0xb3ea340eu, 0x3420b369u, 0xaf1d344cu, + 0xa74ead90u, 0xb1f3aa70u, 0xb0bd33a6u, 0xb4282fe2u, 0x2de7b46eu, + 0x2df8ae2fu, 0x3452b3cbu, 0x333930c5u, 0xaee8b2fbu, 0x25b6ad0eu, + 0xb438afcdu, 0xb0b6ad09u, 0xb1d2ac61u, 0x2ce0b092u, 0xadf0ac4bu, + 0x31382535u, 0x2ab9aca7u, 0x22c1347au, 0x31a333deu, 0xa972b43cu, + 0x34ac2f9eu, 0xb3d2a665u, 0xb32c28c3u, 0x1cb730d4u, 0x3317304au, + 0x2c512cf4u, 0x329330e3u, 0xb4733316u, 0xb1732851u, 0x2db332ebu, + 0xb1fdaa20u, 0x2fd3ae2eu, 0xb3ceb1adu, 0x31133373u, 0xaffab1c4u, + 0x2fff3488u, 0xaf632c3eu, 0xb46cafb7u, 0xb4633063u, 0x3068b4c1u, + 0x30ed344fu, 0xa049a45bu, 0xaebca8e8u, 0xa94a22acu, 0x33a52b8au, + 0xb40b34c1u, 0xb221ac6eu, 0xb015adaeu, 0x3112b240u, 0x3406988fu, + 0xb428b47du, 0xb408ab6eu, 0x34aab08eu, 0xb1ccb197u, 0x94eb29a8u, + 0xacbc2a2du, 0xb2f03246u, 0x2f49a980u, 0xad023312u, 0xb4232934u, + 0xb423b254u, 0xb0123060u, 0xb42a304cu, 0x327132f6u, 0xb492b3e4u, + 0x32cab442u, 0x276ab118u, 0x31ada9aau, 0x0e7f9ed2u, 0xb2b834b2u, + 0xb44e3259u, 0x336ba2deu, 0x2f1d2e58u, 0xaa41b08bu, 0x2296ad20u, + 0xaea6a5cdu, 0xb0c9af78u, 0xb2b9ad2fu, 0x2bd83325u, 0x2f72b308u, + 0xb10a32adu, 0xb4b8b2b5u, 0x3109b459u, 0xb45f34adu, 0xb41c30c3u, + 0x30eb2b13u, 0xb4b2ad68u, 0x34b72b4fu, 0xb1f6b0a7u, 0x283eb338u, + 0x319d2b68u, 0x338930dcu, 0xb0da31dfu, 0xafc8284bu, 0x3426ae89u, + 0x348e2efcu, 0x25c0aa62u, 0xb38a9febu, 0x243fb10eu, 0x3424b427u, + 0xb1ccb339u, 0xb3bd3118u, 0x305533afu, 0x2f5eb424u, 0x30f12d0eu, + 0x3031324du, 0xaed12a9eu, 0x34632f93u, 0x2e502ab9u, 0x30eba8d4u, + 0xb28534c7u, 0x260fb1b7u, 0x297fa1b9u, 0xab5ab454u, 0x2a8b2a5fu, + 0x303a2e0bu, 0x31932d6fu, 0x25c32ccau, 0xb3a82c14u, 0x2435b05bu, + 0x2ee03329u, 0x2b16b3ddu, 0x307eb158u, 0x2b2d3249u, 0xae332b04u, + 0x32fea821u, 0x2211304au, 0xb451ad0fu, 0xb1e5b2dbu, 0x3444acddu, + 0xb1171a55u, 0xae36b392u, 0xac7b3210u, 0x31d0313bu, 0x2c2cb379u, + 0xab843468u, 0x3410b450u, 0x22cd335eu, 0xb1892803u, 0x92e23222u, + 0x2f07b47au, 0x32523453u, 0xb44ab047u, 0x3432343au, 0x2d7724fbu, + 0xaa29a5bfu, 0xb3beb34eu, 0x3277b122u, 0xb13fb2cdu, 0xb1782778u, + 0x28ddb277u, 0x2cd8ad11u, 0xb2b333eau, 0x33ba33f0u, 0x2d0b3252u, + 0x2d592c9du, 0xb4a42f51u, 0x2a933466u, 0xacb63167u, 0x1dfbb4aeu, + 0xa8d71c6bu, 0xb0ceae28u, 0xacca243bu, 0xb2483483u, 0xafe9aeedu, + 0x8f1326a7u, 0x34522d85u, 0x2f67b020u, 0xb090b48fu, 0xb481a593u, + 0x2ed92c85u, 0x211730bdu, 0xabfb2bfcu, 0xb3aeb467u, 0x34c22df4u, + 0x286cb4a6u, 0x324630d2u, 0x2c9b26f2u, 0x32e42f8eu, 0x3417b341u, + 0x3274b48du, 0xb1ddb410u, 0xa834b4c3u, 0xb26aae5cu, 0xab7fa783u, + 0x338c3124u, 0xb3362ddcu, 0x33f0afdbu, 0xab27b3e5u, 0x3454343fu, + 0x2e6eaad2u, 0x30dea6a5u, 0xb2d5b47fu, 0xb1232c63u, 0xadb72e60u, + 0x3221336cu, 0x313d9c67u, 0x9b0eb065u, 0x32eeb1cfu, 0x33b93234u, + 0x346a333fu, 0x3425b137u, 0xa9f42978u, 0xae0b28a3u, 0xb0f7b00fu, + 0x9839b402u, 0x2cff3372u, 0xa97c2272u, 0xb195a578u, 0xb1cb3233u, + 0x30fe3029u, 0x32f829c0u, 0x3354b003u, 0x31bc3068u, 0x32a62e52u, + 0xaa2234bcu, 0x30b23207u, 0x3419a73du, 0x2907ac0eu, 0xb144b391u, + 0xabf2328bu, 0xb0e1ac11u, 0x31df9d28u, 0xb4203396u, 0xa50729bfu, + 0xa80d2c63u, 0xa452abc9u, 0x10d52a4cu, 0x321aa447u, 0xae1730b7u, + 0x32ca31c5u, 0x2a5ab2a7u, 0x3098b01fu, 0x2e95b104u, 0x1ed9b0b4u, + 0xac8f344fu, 0x34ad3337u, 0xb26a3332u, 0xb47e3223u, 0x331eac19u, + 0x25072f40u, 0x31ffac4eu, 0xa4da3006u, 0xb12f3389u, 0x2d7cb254u, + 0xb0da3488u, 0xb2ecb0ceu, 0xb14132ecu, 0x34b617d0u, 0x2857b4afu, + 0x31e71f8du, 0xaae3ad8fu, 0x30a0b260u, 0xb2fa3177u, 0x338bac17u, + 0xafbab4c6u, 0xae5f283au, 0xa623b060u, 0x248db21du, 0x29c82ff0u, + 0x329db3d0u, 0x3116b23eu, 0x316ead5bu, 0xb204b1a4u, 0xb47c974fu, + 0x304db146u, 0xb406327au, 0x31b63356u, 0x2f9f3319u, 0x23b52eb0u, + 0x34062ddeu, 0xaf13b3acu, 0x3445b41bu, 0x2ebca834u, 0x34b7328du, + 0x31c0b27eu, 0xb4553370u, 0xad9430e1u, 0x20512db5u, 0xb301b09du, + 0xb39eb35bu, 0xadb52d4bu, 0x2f5eb171u, 0x26042f2du, 0xac66342du, + 0xb4143273u, 0x34b0309bu, 0x2a1e32a8u, 0xada22cdeu, 0x31312ee4u, + 0x9ca134c8u, 0x2b5db436u, 0xb0e7b351u, 0x3070ae93u, 0xb26bb212u, + 0x332bb45eu, 0xb46b2f6eu, 0x2882b487u, 0x2b6eb02du, 0x3410a906u, + 0x2ee1b013u, 0x3460b448u, 0x3097349eu, 0xb160a558u, 0x308a3200u, + 0xa77eb157u, 0x3244a5b7u, 0x2d7f2f0fu, 0xb0682dc1u, 0xb45dacedu, + 0xa9253182u, 0xb0e4a8beu, 0x2abfb194u, 0xb42fb123u, 0xacbe3123u, + 0xa946ac99u, 0xaee1320du, 0x343830f4u, 0xa93f2e2du, 0xa67830c2u, + 0x23c4aa92u, 0xb399af00u, 0xb339aa8au, 0x285faae1u, 0xb4743423u, + 0xa67e2caau, 0xb0cfb49bu, 0xb170b353u, 0xab94b054u, 0xb4ca2476u, + 0xb3ceb27eu, 0xae9027a1u, 0xb157276fu, 0x343db491u, 0xb32ab385u, + 0x349fb2c9u, 0x2c3c2c85u, 0xb3e734acu, 0xb1af348eu, 0xaa232cbau, + 0x3424ac75u, 0x34c6b2bcu, 0x2db7aca4u, 0xb43f347eu, 0x2935340fu, + 0xb2bc2fd9u, 0x2eaa2521u, 0xb2a0a6b8u, 0x32ceb0eau, 0x3003b478u, + 0xb4ba34cbu, 0x2eb0b282u, 0x2ae5b439u, 0x2ac52f11u, 0x2f93ad2du, + 0xb19d2b3eu, 0x335528d9u, 0xa4552e68u, 0xb3f3aedau, 0xb4b1b0e7u, + 0xb15434acu, 0xb25d320cu, 0xaa47b028u, 0x31baaebeu, 0x33353465u, + 0x3150b2a7u, 0x33f0b2c2u, 0xae48217eu, 0xb4b0b296u, 0x33f3b0d7u, + 0x348331b5u, 0x2b14b3aau, 0x2699b0aau, 0xb028aee5u, 0xb21529acu, + 0x2dcba4beu, 0x3422b324u, 0x32231b09u, 0x30082de9u, 0x33343026u, + 0xb0422c5du, 0x2c14b3b0u, 0xb0f8b42au, 0x2782b438u, 0x2c3db286u, + 0x322e3196u, 0x2785af50u, 0xa42a28d7u, 0xb1912df5u, 0xb3b8349au, + 0x2b3a3252u, 0x30b8b0e6u, 0x3145b3fau, 0xb3792ae9u, 0x30d1b409u, + 0x3379aff4u, 0x2f9c3108u, 0x3003b040u, 0xb3d8344du, 0xb118aeadu, + 0x30a7ac19u, 0x296fa3eau, 0xb2e3af23u, 0x32e8b07au, 0xacaf2bdeu, + 0xb42e3191u, 0xb12fb0bau, 0x2fea34a9u, 0xb4c12c86u, 0x2d34b210u, + 0x3413ac9eu, 0xa80a3115u, 0x349030cau, 0x2d79a5feu, 0xb0d33405u, + 0xb3ba336cu, 0x316e2db3u, 0x997d2c67u, 0xb2b02c82u, 0xb06bb176u, + 0xa8762b82u, 0x335ab0e8u, 0xa825acd7u, 0xb21baaefu, 0xa7eb3072u, + 0x3474b4a5u, 0x304b3210u, 0x33d03316u, 0x2c43ae3eu, 0xb0782c2eu, + 0xb36ab157u, 0x31652e1eu, 0xaf0e3103u, 0xa720b1a9u, 0x34062731u, + 0x33fd3332u, 0x347632bau, 0xb458a54du, 0xac37b3ffu, 0xb256b0a7u, + 0xb1d9345au, 0x31023469u, 0x2ec22d6au, 0x2d9fae79u, 0x3434b204u, + 0xb0b3af9cu, 0x2e02300eu, 0x2d16a77bu, 0x2ea8b28au, 0xb05db067u, + 0xae70b27cu, 0xa70aae7bu, 0xb1e5b1f2u, 0xb3202669u, 0x34432f41u, + 0x33b4a99fu, 0xb463b3b6u, 0x31033040u, 0xb4413296u, 0xacbe3151u, + 0xb247af8du, 0xb43034c3u, 0x2d5b3247u, 0x30113083u, 0xb21232e2u, + 0x2b91b4cbu, 0xb339ad9du, 0xae76b207u, 0xb441b420u, 0xaf3733fdu, + 0x347534a1u, 0x3020b2ddu, 0x2f522bbeu, 0xb1fbb3c1u, 0x2bffb410u, + 0x2e9b34acu, 0x34a7300cu, 0xb46a2ed6u, 0xad32330cu, 0x1c72b4c2u, + 0xb0a93432u, 0xb2439d37u, 0xb407b43fu, 0x32fd305cu, 0xb010b2d9u, + 0xb48bb1dbu, 0x2fad281bu, 0xac4c2daeu, 0xb3cb283au, 0x3425b2a3u, + 0x340f3105u, 0x2dbd3400u, 0xaa66341cu, 0xb433b4c4u, 0xb3c5b37fu, + 0x2fbbadb2u, 0x2aee3195u, 0x30c2b2cau, 0xb4adad93u, 0xae81b036u, + 0x31fdb056u, 0x2f8230feu, 0x31e9b2eeu, 0xb1dc2eceu, 0xa1112db0u, + 0xb372a8a8u, 0xb3ae21a0u, 0xb30eb272u, 0xb021345cu, 0xaed5ad8fu, + 0x28d633a5u, 0xafaf3406u, 0x2851b365u, 0x31ccadeeu, 0xa4363349u, + 0x28123486u, 0x9ec6b066u, 0x31d6b471u, 0xaf58b3a7u, 0xb4632904u, + 0x2f88b40au, 0xa30ab41cu, 0xb139ae32u, 0x310fb1fau, 0xb2e93456u, + 0x2b47346au, 0x30082d71u, 0x32242fd7u, 0x2520a114u, 0xb394aec4u, + 0xb47a2e52u, 0xb3cab04fu, 0x2d54b1f0u, 0xaa102cefu, 0xa91eb3deu, + 0x303cada8u, 0x9d2f2a12u, 0x347aa000u, 0x976c30ecu, 0xb48ca262u, + 0xaef23440u, 0x34cbb0b0u, 0xb4583033u, 0xb48eb435u, 0xb41d2ba7u, + 0x34323429u, 0x2c7b2713u, 0xb430affeu, 0xb3a5308fu, 0xaf40b3f5u, + 0xa911b4aeu, 0x31c92ffau, 0x32a92c01u, 0x32b2ab2eu, 0xb1511bf4u, + 0xb0523444u, 0xb0f1b48cu, 0xadb5ad1fu, 0x335b2394u, 0x2261aff9u, + 0x322eae23u, 0xb39db293u, 0x2e9a175cu, 0x2ae231adu, 0xac1f3142u, + 0xb35fb47cu, 0xae92b46eu, 0xad84998au, 0xa1f528a7u, 0x2e692ed5u, + 0xade8aefdu, 0x2b682a8au, 0xae84af1eu, 0x2da92f74u, 0xa887b302u, + 0xb474338au, 0xb27832d2u, 0xa9d01c74u, 0x33fab4b4u, 0x345ca6ecu, + 0x3308b018u, 0x285d340eu, 0x2f1db1b5u, 0x34442786u, 0xb072a8aau, + 0x2fa1b2f2u, 0xb487348du, 0x3419309eu, 0xb37cb415u, 0x2daf2f5fu, + 0x326cb424u, 0x33d12332u, 0x32003342u, 0xb0c420e2u, 0xb3aa1b58u, + 0xb3072e1au, 0xb4471eddu, 0xb125afb3u, 0x31822c9cu, 0x32bab440u, + 0xae0f32edu, 0xab7b2e1bu, 0x2467b2a4u, 0x3344b3f1u, 0x322d3413u, + 0x286c28cdu, 0xb0d734a7u, 0x28c2b412u, 0xaed2ae93u, 0x2b64b4bbu, + 0xb1feb088u, 0xad35b469u, 0xae463347u, 0x30ed2ee0u, 0x322dae9au, + 0x288d2f5eu, 0xb477b4cau, 0x316b34b6u, 0x33b93433u, 0x319ab49bu, + 0x318fa781u, 0xb011b4bcu, 0x31a030d3u, 0xafa22c99u, 0x347baf48u, + 0xa810a8abu, 0xaaf32805u, 0xa932280cu, 0x33db3246u, 0x28f03426u, + 0x2fe2a871u, 0x28d6327fu, 0x30cb2faeu, 0x30ba2ec6u, 0x93fdb198u, + 0xb4c72ac7u, 0x2c3a32d6u, 0x3213b31fu, 0x30f6302bu, 0x32cdac25u, + 0x296aaa9au, 0x2d90b4cbu, 0x29273030u, 0x31f3983bu, 0xb0432ef7u, + 0x2ff63468u, 0x348634afu, 0x30e73406u, 0xb24b2c34u, 0x311826a9u, + 0x33122268u, 0xac92b37fu, 0xa9331b54u, 0xb2a7b384u, 0xa0cc327bu, + 0xb4a4b455u, 0xb272a413u, 0x31ac2fe0u, 0x2b14b137u, 0xaf8bb2a2u, + 0x26c63377u, 0xb1463369u, 0xa476ae87u, 0x34c7a21fu, 0x32c2b367u, + 0x281632fcu, 0x21e8adfdu, 0x31beaff8u, 0x3417943bu, 0x20662cb6u, + 0x18d5300du, 0xb20f33c4u, 0x31fe348bu, 0xa14032edu, 0xaf6b3279u, + 0xb2e73108u, 0xa82baf69u, 0xac57aed3u, 0xb0ac3225u, 0xb41830b6u, + 0x319b311au, 0x3046ab8du, 0x31c633f8u, 0xa0d9ac35u, 0xaff7315du, + 0xae9a31d6u, 0xb3ef31e0u, 0x34c7b460u, 0x335a3318u, 0xa8bd3455u, + 0xb31bb018u, 0xb16011f1u, 0xb4c3342eu, 0xb0deb2dau, 0xb144b1c8u, + 0xaea02dfeu, 0x337e2c6bu, 0x2f782be0u, 0xb288ad2au, 0x3475aee4u, + 0xb0462cadu, 0x3271a78au, 0x28a82e78u, 0x2e9f3365u, 0xb1f52d7bu, + 0x3477b38fu, 0xaa7a2b98u, 0xb4352ad6u, 0xb171322fu, 0x254831d9u, + 0xb483b04au, 0xb2363210u, 0x30eab44du, 0xac40adc2u, 0x32e5b0dbu, + 0xb190afc8u, 0xb1b3af53u, 0xb401af01u, 0xaa5fb28eu, 0xb4403349u, + 0x33d7b184u, 0x2ee4337du, 0xaa29b0fcu, 0xb322b18bu, 0x29d3ac9cu, + 0x2c41ad61u, 0xadebafd3u, 0x33433195u, 0x297eaed5u, 0xb44ab042u, + 0xb2513091u, 0x9ff6a9b5u, 0xb3c9b20fu, 0x3458add6u, 0xac8e2c6cu, + 0x2bb3b46du, 0x2689b3d4u, 0xa9de30d6u, 0xb458afb4u, 0xa960b490u, + 0xb0ea335cu, 0x2f1429b0u, 0xb2a9b437u, 0x2e88ae7bu, 0x307fa8afu, + 0x30f6330fu, 0x30e234bau, 0x326232c3u, 0x31cb306cu, 0xa39e342cu, + 0x20972d4fu, 0xa94632bdu, 0x31bf3224u, 0xb0d2346fu, 0x30ef3006u, + 0x33d03430u, 0x2a1429a6u, 0x348fb263u, 0x3051b0b4u, 0xa88431aeu, + 0xb1f9b18cu, 0x1e9c32d8u, 0x302bb3dfu, 0x333ab0ccu, 0xb1c1af50u, + 0x1f16b3f9u, 0x30d3a791u, 0xadffa570u, 0xb042b094u, 0xb26e341bu, + 0xaea534b0u, 0xb0d3b3e7u, 0x3192b43du, 0xae421fb6u, 0x2d042e39u, + 0x346e3439u, 0x321a2ef0u, 0x9d58319du, 0xb40c2fdau, 0x346f30f4u, + 0x3274b3f8u, 0xb1423428u, 0x341c239fu, 0xb325346bu, 0x2f9cadccu, + 0xaebbb159u, 0xb2a7b494u, 0x2de128c9u, 0x31582db8u, 0xb059aa82u, + 0xb1a2b4a7u, 0xb22eaf34u, 0xb294b49bu, 0x2cfa2e61u, 0x31ba342fu, + 0xb2f52934u, 0xb43528ecu, 0xac37a94fu, 0xb03aa98bu, 0x328c2f23u, + 0x2ce83128u, 0xb48025e4u, 0x26e93048u, 0xae9cb067u, 0x2cc7342fu, + 0x2ca5a366u, 0xa494aaa0u, 0xa89fb007u, 0xb46b2f20u, 0xb02b31aau, + 0x2d7b2f03u, 0x2c272ddcu, 0x1d203468u, 0x2fe43076u, 0xb029b110u, + 0xb045a9d6u, 0xac30ad1eu, 0xb1612bfau, 0xa8cc31d8u, 0xb4052febu, + 0xb487a49du, 0xae002ec1u, 0xaec13450u, 0xb0a828e6u, 0xa5102c9du, + 0xb1b0acf8u, 0xb34cb375u, 0xaabc34cau, 0x3459b4c8u, 0xaa41b49cu, + 0x33f6302du, 0xa5963016u, 0xb46c348eu, 0x32b534adu, 0xb0b5341eu, + 0x2e45b2ddu, 0x231e20dfu, 0x2c9c3414u, 0xabadaf41u, 0xb1e8b309u, + 0x31f5b2d9u, 0x24a92fdeu, 0x2e78acd3u, 0x33523202u, 0x32242739u, + 0xa3d31ef2u, 0xac5d3304u, 0xaf7eabfeu, 0x26e421bfu, 0xa9562e29u, + 0x330bb16bu, 0x340fadeau, 0x289db19eu, 0x324f25a0u, 0x33dfb2efu, + 0x2a9d24d4u, 0xb4741e3fu, 0xb08a9726u, 0x2dbaae0au, 0xb3cf95a9u, + 0xb209b419u, 0x2c29b1efu, 0x3354b230u, 0xb3dab193u, 0xafdc3337u, + 0x3468a9bau, 0x30203444u, 0x2b2bb423u, 0x344a34b2u, 0xabfdb391u, + 0xb31caf15u, 0xb0582f7bu, 0xb3ddadf5u, 0xb29094ffu, 0xb2d9a937u, + 0xb2d1345bu, 0xb1d122b9u, 0xb1b7b411u, 0xb2ecb446u, 0x2dd49c01u, + 0xa888b3ecu, 0xb11a2a3du, 0xb41caceau, 0xa51bb160u, 0x34c434b5u, + 0xa9e8349bu, 0xaec6b407u, 0xb4aab109u, 0xa731b3c6u, 0xb223ae28u, + 0xad7d3026u, 0xb0f932c2u, 0xb21125e6u, 0xb2ac99c6u, 0x2c4fb27fu, + 0xb24ab089u, 0xb4633420u, 0x276a2901u, 0xa741b0cau, 0x3040b3eau, + 0xb1e3b158u, 0x33baaf1cu, 0x344a31b1u, 0x2e422dd6u, 0x33c8a222u, + 0xad911eafu, 0x27162d64u, 0xac1fb338u, 0x32a9af2bu, 0x322daca7u, + 0x30dea86du, 0x3414b301u, 0xb09da1f9u, 0xb083b0f7u, 0x302dad1eu, + 0x2e7e3451u, 0xa7e5273fu, 0x32b7324du, 0x345aaff3u, 0x31c3ac07u, + 0x2fd2347bu, 0x2a9eb280u, 0x318db352u, 0x2f7fb033u, 0xb22033e0u, + 0x2da6ac1du, 0xb23eaa2cu, 0xab2cb485u, 0x29af2dbbu, 0xa793b29au, + 0xb056ad03u, 0xaf4f3067u, 0x3410262au, 0x2c7e2608u, 0xb22eb419u, + 0x3116b3a9u, 0xb2053273u, 0xaecab164u, 0x2cad2affu, 0x33c82f2cu, + 0x2e19afdfu, 0xaf752896u, 0xb3c433d3u, 0x30603012u, 0x21b533f9u, + 0x324baedau, 0x0a353133u, 0xb0753125u, 0x33032ae0u, 0xa10eaefdu, + 0x31ba3454u, 0xac68336eu, 0xb2ac34c4u, 0xa25e21c4u, 0x33d831bbu, + 0x2cdf3070u, 0x1e58a993u, 0xb49b1db7u, 0x32d6177cu, 0x31ad3005u, + 0x2473ac35u, 0xac7eb47bu, 0xb0b3a3dcu, 0x2f50b480u, 0xaa7aa8fcu, + 0x25d0b0cdu, 0xa3fea8c2u, 0xb4bd2a36u, 0xb41e33d4u, 0xb19ea78au, + 0xb038234eu, 0xabf632eau, 0xb0d22d54u, 0xab5cb49du, 0xa637259bu, + 0x2ff1346fu, 0xafdf34c2u, 0x2844318du, 0x34aa2c4bu, 0x33a82deau, + 0xb3273056u, 0xa0d12fa8u, 0x31e43405u, 0xb307b39au, 0x9c26b422u, + 0x304bb406u, 0x32732805u, 0x21e1b03au, 0x3362b358u, 0xb3a2b23du, + 0x31e1b1aau, 0x2c65b392u, 0x30d230bau, 0xb435b1f3u, 0xb1b6a7ddu, + 0xad812fa7u, 0xb36ca7c7u, 0xb20a2930u, 0xb41e2ee0u, 0x2f163492u, + 0xb4aab21cu, 0xb2aaae5bu, 0x3328b168u, 0xb2362bedu, 0xb0b0285au, + 0xb47c3492u, 0x313e3076u, 0xb24db428u, 0x3312ac71u, 0x2df725afu, + 0x324d316fu, 0x1d67a349u, 0xb08b3030u, 0xb49a32ceu, 0x31c4b1d7u, + 0xb2b9ae22u, 0x24b9b204u, 0xb41f32a6u, 0xa55ab482u, 0xb03e3461u, + 0x33723468u, 0x3216b02au, 0x1f442f23u, 0x320fa9ecu, 0x30ef31a1u, + 0xa29a34c9u, 0x32f631e5u, 0xb465b18au, 0x32d9ab51u, 0x2faeb00du, + 0xad8eb4bbu, 0xb31c2c70u, 0xb299339du, 0xb17233deu, 0x2c0634bfu, + 0xb42cb3fbu, 0x2ae7b415u, 0xab7431f2u, 0x2adba83du, 0x2f392513u, + 0x301ba455u, 0xadc034c6u, 0xb330b4afu, 0xadfb281cu, 0x2ce53439u, + 0x31b92241u, 0x3224b0a3u, 0x2c98b4c5u, 0x3187342cu, 0xabea32cau, + 0x27cf323au, 0xb43c2c8du, 0x27d4b1bbu, 0x30a3b43cu, 0x34093287u, + 0x3439b3a5u, 0xa3f8b427u, 0xb4203288u, 0xb48fb4a0u, 0x31fc1eedu, + 0xb335b327u, 0xb11a2944u, 0x3451306cu, 0x333e311cu, 0x32612204u, + 0xb425b217u, 0xb44d2dfdu, 0x2f5b3389u, 0xaf263457u, 0x30a4a041u, + 0x266eb0f0u, 0x34992e20u, 0xb35530b3u, 0x2ad1a394u, 0xa93ab2c9u, + 0xb352b026u, 0xb26b1f66u, 0xb2582af4u, 0xb1da304bu, 0xb48c339cu, + 0xaee822c2u, 0xa45db147u, 0x33f93291u, 0xb2a3af8eu, 0x2a4c303au, + 0x30ffb1beu, 0x2de421d1u, 0xa8adad67u, 0x30edb223u, 0x3158b296u, + 0x30bc31b9u, 0xb05bb49du, 0x2b56a4ddu, 0xacc73406u, 0xb2763333u, + 0xb44cacf1u, 0xb2b530a8u, 0x3149b0aau, 0xb4aa2555u, 0x1e8db4c7u, + 0xb223af7du, 0xb1372c5du, 0xaca32b15u, 0xb2f3b204u, 0xb483b10du, + 0x33b8af5eu, 0xacea325du, 0x292c29d3u, 0xb1103250u, 0xaf9dafd2u, + 0xaf1eb468u, 0x33e93342u, 0xa671b37fu, 0x9e8aac8eu, 0xb49b2834u, + 0x348c3292u, 0x2e292de4u, 0xae5d244cu, 0x2a75b2bdu, 0x323bb45eu, + 0xaa8caa13u, 0x3481aea3u, 0xb2b2b23eu, 0x2e16b26cu, 0xb11434b9u, + 0xb04033cau, 0xb4692daeu, 0x2def9957u, 0xb1092594u, 0x3483324fu, + 0x2d38a644u, 0xb0f73193u, 0xb03832ffu, 0xb373314cu, 0x252ab010u, + 0x32ba23a8u, 0xb38b34c3u, 0xad78b064u, 0x9b7ca27au, 0x313232d7u, + 0xa6e9b49eu, 0xa6152c89u, 0xabe0b317u, 0xb1ffaac9u, 0xaedc30ecu, + 0x20d52ad6u, 0xb342333fu, 0xafabb368u, 0xafbca948u, 0xb0e4310eu, + 0xaa9fb3f9u, 0x32bb3140u, 0x2872307bu, 0x2ef7304eu, 0x27ccb11au, + 0xaf063132u, 0xa1b02deau, 0xb3df17c3u, 0x33052e62u, 0xad24b2e2u, + 0xb484b455u, 0x9c0334b3u, 0xb053ad8cu, 0xb0c2349cu, 0xb0273055u, + 0x2f0ab420u, 0x2ec0b4c9u, 0x30bab0cbu, 0x304e312eu, 0x2fd3b491u, + 0xb0f134b5u, 0x3205b056u, 0x2e2bb285u, 0xb47130e6u, 0x29d42821u, + 0x333aaf8cu, 0xad37b27au, 0xb1f132b2u, 0xb40a322cu, 0xb4149e9eu, + 0x31942ed5u, 0x349f32b8u, 0x312a2e9bu, 0x33ed1b13u, 0x335d2d85u, + 0x9802b114u, 0xb1b5306au, 0x3497b18bu, 0xb21ca906u, 0xabe2ae79u, + 0x34102cbau, 0x2dd334acu, 0xaed72fadu, 0xb16b32dcu, 0x348bb38fu, + 0xaf8a32feu, 0xa5112ebau, 0xb018aecbu, 0x2793b2fdu, 0x1f7da81au, + 0x3436b177u, 0x33ac2d52u, 0x2cb8b381u, 0xae7e32b6u, 0xb083b1dau, + 0xa80eb05cu, 0xb064aeafu, 0xb44a2db4u, 0x2f49ae21u, 0xb15cb239u, + 0xb4cbb1bfu, 0xb46da407u, 0x34c0b05cu, 0xb1783404u, 0xa593af4cu, + 0x31d0329du, 0xb336b32du, 0x331baa65u, 0xb38a3356u, 0xb29c29b5u, + 0x33ff2f26u, 0xb401a6f3u, 0xab072a16u, 0xae2131f8u, 0xb0583333u, + 0xaf6eb293u, 0xb033b477u, 0xb2de2e26u, 0xb30fb376u, 0x3331b40eu, + 0xb45a3443u, 0x308e30feu, 0xadd734c5u, 0xa735b01eu, 0x306432d9u, + 0xb0e8a45cu, 0x32cf305cu, 0x2e79abafu, 0xa29babaau, 0x314b23a7u, + 0xa8463496u, 0xacdbae0eu, 0xafccb308u, 0xa98ab3f1u, 0xade6b263u, + 0xb0e131a3u, 0x33b42c4cu, 0xb1e12924u, 0x2af1adf6u, 0xb2bf1c10u, + 0x269da816u, 0x2c51b078u, 0xae46b420u, 0xb09f31d8u, 0xaae92c0au, + 0x33fdaf0cu, 0xb10eae05u, 0x30b933dcu, 0xb4532efbu, 0x2d50b315u, + 0xb145b194u, 0xb01c315cu, 0xb473b41du, 0x2c7fa85du, 0xb3793315u, + 0x2494b1d3u, 0xa15dad38u, 0x26e53412u, 0x34b3aa85u, 0x3426b42du, + 0x189e1416u, 0x1c80340du, 0xb05ea8bbu, 0x29592e19u, 0x3005b17cu, + 0xabe22d88u, 0xa81ab4c2u, 0xb414b4beu, 0xb403a954u, 0x2df9b04fu, + 0x34c7af59u, 0x2a8d33feu, 0x3311347cu, 0x30cbaef4u, 0x2f16b2f9u, + 0xb4a39d7bu, 0x345fb056u, 0xb21eaf12u, 0xa263b200u, 0x30f43294u, + 0xb198a8dau, 0xa5bdb45cu, 0x3069320bu, 0x2b46ab05u, 0x2a12a8e5u, + 0x2ef32161u, 0x343b1cbcu, 0xb4a6a987u, 0x0df7b110u, 0x2806263bu, + 0xb054301fu, 0x2fd62e55u, 0xab83aad0u, 0xaa9bb22au, 0x33da3182u, + 0xafb42b31u, 0x309c2f00u, 0x3245ae71u, 0xb4b2b418u, 0xb29bb33du, + 0xa9c33347u, 0xa972b052u, 0xafa0ac0au, 0x2dfdb2f4u, 0x314ab2fau, + 0x3071b1bau, 0xb33231deu, 0x3451b3efu, 0x2d00a5adu, 0xb040b494u, + 0x336a1aa2u, 0x3149b063u, 0xb3632e3bu, 0xb108afefu, 0x2d32a86au, + 0xb0e8a91du, 0x2a7d2f86u, 0x282e21efu, 0x2eeeb157u, 0xad3eac52u, + 0x2b70b2bau, 0xae222be2u, 0x32a232e9u, 0x2f7db382u, 0x34ccac14u, + 0xb037b148u, 0xb071a872u, 0xa1dd2f5fu, 0x1bd5b15cu, 0x319d3377u, + 0xb01091c2u, 0x3344b225u, 0x298b3009u, 0xb3433349u, 0xb1702f02u, + 0xa548b349u, 0x343cac53u, 0x320caec2u, 0x2e7330c7u, 0xab123409u, + 0xb283ac3du, 0x334bb04eu, 0xae18a3dfu, 0xa09fb173u, 0xb0183029u, + 0x2cfc30f3u, 0xb0c83185u, 0xb2a62d08u, 0x304fad3bu, 0xb1fe2d0eu, + 0xb44a32e1u, 0x34a52b50u, 0x31c624d7u, 0x316f2b4fu, 0x2f572dfau, + 0x30a5b13au, 0x349db108u, 0xb10eb13au, 0xb0ef32e3u, 0x301fad57u, + 0xb28cb28du, 0xb0eca031u, 0xb4b6b113u, 0xaefbacfau, 0x2ca8b480u, + 0xb41f2cddu, 0x3328af07u, 0xaac32a4fu, 0xb19aa55cu, 0x33f331fdu, + 0xb14d33e2u, 0xb284af44u, 0xae6caf67u, 0xb1f52d1cu, 0xb39f3407u, + 0x32d1b4bcu, 0xad8e2fd3u, 0xb14f2b56u, 0xa46eb25eu, 0x2c6dada3u, + 0x2e42b169u, 0xb2673120u, 0xa8a4b461u, 0x2dca3143u, 0xab762fc1u, + 0x24e2b117u, 0x3058b1adu, 0xb002b1d1u, 0xa0151c05u, 0xa8ce2bbfu, + 0x32873407u, 0x2cf93347u, 0x2c312d2fu, 0xaed5a900u, 0xb48e2b11u, + 0x32c0b4bau, 0x239eb45bu, 0xb1cc2c6au, 0xb1f33399u, 0x310d3362u, + 0xb2b5b0fau, 0xabd6af0fu, 0x34cab0e2u, 0x3259b131u, 0x349cb28cu, + 0xaa04b145u, 0xb34a287fu, 0xb0533215u, 0x27a02791u, 0xb4442be2u, + 0xb281b25du, 0xb2d1af9au, 0x1ff6340du, 0xad792cbfu, 0x17cfb04cu, + 0xae01afe6u, 0x1b0ca742u, 0xb15034a6u, 0xb2bb9f63u, 0x302cadc3u, + 0x2a3fb240u, 0xb44eaa66u, 0xaaa33428u, 0xaa6d3174u, 0xb0063433u, + 0x30f8aabeu, 0xad35ae01u, 0x284534c0u, 0x2d822f46u, 0x32f2324cu, + 0xafe428dcu, 0x2c65b495u, 0xa7993240u, 0xb012b270u, 0x32771e23u, + 0x2c4eb24du, 0x343030ddu, 0x3418b35cu, 0x311f2bcbu, 0x1b8eb449u, + 0xaf6b2cb5u, 0x282ca940u, 0xb4662809u, 0xb17fa8a6u, 0x34933400u, + 0xb23dafb2u, 0xa2d6b163u, 0x016d3331u, 0xb46bb445u, 0x3295b13cu, + 0x28d62caau, 0x341faef4u, 0x326eae7cu, 0xa11f339au, 0xb0493392u, + 0xb3e92e15u, 0xb16da401u, 0xb4c4b433u, 0x2ae0aebbu, 0xaf9da6e0u, + 0x343834b7u, 0xaa85b330u, 0x307c2db7u, 0x30bbad22u, 0xae75b337u, + 0x2cd43028u, 0xb45a3279u, 0xb456b240u, 0xb4c2b1e9u, 0x2459192cu, + 0xac6b2e10u, 0x2eadb4c5u, 0x3308b447u, 0x24aeb495u, 0x29913395u, + 0x2ef92c2au, 0x2eb8b340u, 0x348d334eu, 0xadf9a860u, 0x269630ddu, + 0xb24bb0a9u, 0xa645b255u, 0xb49cb255u, 0x3420b44du, 0xb419b419u, + 0xb0e5a77fu, 0x33e43471u, 0xa7e0ab51u, 0xb470acccu, 0xb33faff4u, + 0x28adb3a2u, 0xb3a0b3b4u, 0xa86fa1fcu, 0xb4c2b2f5u, 0xb112b1e5u, + 0x33fa31c4u, 0xab4bab39u, 0x2ce03014u, 0xb388b211u, 0x28fba8cbu, + 0xaff0b2f0u, 0xb095af74u, 0x2de1a607u, 0xb1bb1dc5u, 0x322eb3a0u, + 0xb434a25cu, 0x31d6b0a5u, 0x333730d5u, 0xa9ec2bd7u, 0xb1e0a9a2u, + 0x2a892dcau, 0x3368b2a0u, 0xb453ad0du, 0x331aae9cu, 0x9de63401u, + 0x33343462u, 0x32e8323fu, 0x30edac89u, 0x303829f1u, 0x3071b230u, + 0xaf943465u, 0xacac34abu, 0xb372b1c4u, 0x28363179u, 0x2c2aaf68u, + 0xa7efae73u, 0x2e7532f7u, 0x2a6a310au, 0xb0f734b8u, 0xb3d3b090u, + 0x2c5a2826u, 0xae523057u, 0x2d14b4afu, 0xafe434cau, 0xb031b212u, + 0xb0c8a9bau, 0x2d4fade0u, 0xabfcadf3u, 0x3403b46au, 0xae99ab27u, + 0x2d27b3f1u, 0xb46832fcu, 0xb2cab2d0u, 0x340b2bdbu, 0xadffa8c8u, + 0x30a8311bu, 0xb283b0ddu, 0x314bad76u, 0x2e5e2f7eu, 0xb0473253u, + 0xb465ae28u, 0x2a553314u, 0xb422afc1u, 0x30c7304au, 0xb1b02e62u, + 0x30dc33efu, 0x2dcc2e0fu, 0x341d33c3u, 0xaa662b58u, 0x3220ad3cu, + 0xb40f2d8eu, 0x33afb2dfu, 0x34563362u, 0x3174a98bu, 0xaf14324du, + 0x34c5b2cfu, 0x2b7ab483u, 0x2efb2dc5u, 0x3041b0b1u, 0x3251b172u, + 0x2f8eb165u, 0xb1f93171u, 0x315cb108u, 0xb1f0b3f3u, 0x3421a6d5u, + 0xac5028c1u, 0xa5933498u, 0xaac9a917u, 0xaeb1af36u, 0xb4682f37u, + 0xb1bd2efbu, 0xb2c9ac72u, 0x3067280du, 0xb276ad95u, 0x321cb140u, + 0x3146b076u, 0xb1faae7bu, 0xa4d5305du, 0x346ab480u, 0xada1b2c3u, + 0x9e7fac6du, 0xb4be317bu, 0x2d9b3427u, 0x32183454u, 0x2bc2341bu, + 0xa862ad7bu, 0xa99d2e12u, 0xb3d63073u, 0xb1ae3256u, 0xb29d3443u, + 0x31fdb31fu, 0x3096321eu, 0xb068346cu, 0xadaf3246u, 0xa82e25bfu, + 0x29b8b4beu, 0xb24030c1u, 0x24ab3425u, 0x2d9bb22du, 0xb431b1eau, + 0xb37a2f1eu, 0x309bb390u, 0x31f3b445u, 0xb2e331b0u, 0xb3bf21a6u, + 0xb4322d17u, 0xb19d3444u, 0xb3232f06u, 0xa789b193u, 0x34ca299du, + 0xb4ccb48du, 0xad24adbfu, 0x33ec335fu, 0xb2da334eu, 0x30b9aac0u, + 0x2e45af32u, 0xaec8b10cu, 0xb0ca32ecu, 0xaf713475u, 0xb0b5b493u, + 0x1c32b250u, 0x2cd7b370u, 0xad473333u, 0xabaeb25du, 0x2b07317eu, + 0x25b6b3a8u, 0xaea4a4e7u, 0x349eb37cu, 0xb1e6b238u, 0x2964b2ceu, + 0xb0cfa854u, 0x2eaaa96cu, 0x33f9b031u, 0xb1ccaf70u, 0x31f6345du, + 0x328eae06u, 0xade221c8u, 0x30d73285u, 0x2c19afc3u, 0xb4caad04u, + 0x279f346fu, 0x2bac2b8fu, 0xb00827c7u, 0x2cac3487u, 0xa6f22e90u, + 0xb42fb013u, 0xb238adc0u, 0x33472e39u, 0xae6baf93u, 0xb2bc2e8bu, + 0xad3a341fu, 0xb23fb3a8u, 0xb0db3428u, 0xb29a2e3bu, 0x3348b1e0u, + 0xb49fb2c2u, 0x32f71210u, 0xb324aeafu, 0x2ec934a1u, 0x30d732bcu, + 0xac6f2f9du, 0x302aaebfu, 0x34533029u, 0xafe32946u, 0x2c5e9e6fu, + 0x3197a9a1u, 0xb4b62a80u, 0x2d21295du, 0xaaa033f9u, 0xa3ae29b8u, + 0xb42724ddu, 0x33e133a1u, 0x28582762u, 0x2b86b43fu, 0x3003a971u, + 0x300db459u, 0x2dd3b017u, 0xb13f2ce2u, 0x3272a893u, 0xb4242c0eu, + 0xaf3aa862u, 0x2c662d70u, 0x2c23b4b3u, 0x31293082u, 0xaf8ab43cu, + 0xb226aa0cu, 0xb41eaa16u, 0x2e7ab36du, 0x300fb08fu, 0x28d1b457u, + 0x31b4ac2bu, 0xacc73174u, 0xb13b2cb6u, 0xb4052a2du, 0xb217a906u, + 0xa83b335cu, 0xad5d2af9u, 0xb1b4b00eu, 0x31c033e8u, 0x30bdb30bu, + 0xb4a7aa42u, 0xb31a245bu, 0x2f87b192u, 0x3386b0aau, 0x32612e09u, + 0x33152c6cu, 0x278cad50u, 0x33c120e2u, 0x29ffb26fu, 0xacfd30e3u, + 0xace0330fu, 0x2a74b246u, 0xb4a7aa1au, 0xb1dab421u, 0x3387312cu, + 0xb3932703u, 0x32d42549u, 0xb00330cau, 0x33b1b339u, 0xb44932ccu, + 0xb3bc3237u, 0x30f7b431u, 0xaa902594u, 0x328433c1u, 0x2c75b43fu, + 0x27c1313au, 0x2f2534a3u, 0xb1cbb39au, 0x34c53244u, 0xb3acb3b6u, + 0xb42f310fu, 0x3377b424u, 0x335331c5u, 0xaed12dc8u, 0xafbb33cdu, + 0x336bb04fu, 0x33992ef2u, 0x3458b29bu, 0x2e742c54u, 0xac9433f3u, + 0x2d643037u, 0x339f3186u, 0xb4272eeau, 0x345cb215u, 0x347d3480u, + 0xac84b472u, 0x30db30fcu, 0x2c34b3f3u, 0x9c2cb2dbu, 0xb44ab0ffu, + 0x33e4b408u, 0x342530b2u, 0xaaa9a49cu, 0x2c77ad70u, 0x30baadb3u, + 0x333731c9u, 0x2427b0f0u, 0xb471b14fu, 0x27862ffbu, 0xb3eb304du, + 0x34bf34c2u, 0x3307a560u, 0x3090b0ecu, 0x320b3348u, 0xa5ae31fcu, + 0x2f533225u, 0xb368b30fu, 0x2cd13139u, 0x33d221f4u, 0xabfa2e21u, + 0x2c0baa9cu, 0x28f130ffu, 0x305b1d62u, 0x32582fe2u, 0x30e5b433u, + 0xb415203au, 0x30282ee0u, 0x31a42342u, 0xb1b9afacu, 0xaae8adbbu, + 0x32a22f86u, 0xb242303eu, 0xb28fad23u, 0xb0d62f2cu, 0x319a23cdu, + 0xafbe2e90u, 0x2de4ae6bu, 0xb3c02799u, 0x1fc0332eu, 0xb1caa417u, + 0xae6bacb9u, 0x292db067u, 0x3379a5cbu, 0xb163343du, 0x317ab3aeu, + 0x32fb34c0u, 0xb0c7b493u, 0x3229b462u, 0x20372a41u, 0xb0c1282fu, + 0xb4812bceu, 0x30802d9bu, 0xae722ea5u, 0x30233244u, 0xb1dab323u, + 0xb00b2d44u, 0xb2a0b34fu, 0xa2d3b26cu, 0xb2372c20u, 0xb0343014u, + 0xb14faf3cu, 0x346a317au, 0xb4669c9cu, 0xb291b099u, 0xb3f93295u, + 0x2acc347au, 0x32ab2173u, 0x3152b489u, 0x328bb35cu, 0xb437247bu, + 0xb48a3266u, 0x31b8b2f1u, 0x3353a565u, 0x2cbe2d33u, 0xb309affau, + 0xb396346du, 0xb05e2475u, 0x2b44b087u, 0x315231b8u, 0xaff43315u, + 0xb4b6a543u, 0xaf9730bdu, 0xb25928b9u, 0x32173222u, 0xb45c333fu, + 0xb0d834bau, 0xb0d0af51u, 0x280bb077u, 0xac14b0ffu, 0x32742dfau, + 0x2b3e2f67u, 0x3212b2c3u, 0xb087b471u, 0x2e6eb441u, 0x2dd7ad0eu, + 0xa6ccade0u, 0xb45da675u, 0x2d6ba95cu, 0xb4142713u, 0xaf572e74u, + 0xb29db4a9u, 0xaf4895ffu, 0xb0fb2f77u, 0xb01a313du, 0x31bf2ca4u, + 0xb45aac65u, 0x34c22572u, 0xb15b3481u, 0xadf430e9u, 0x2e5fb286u, + 0x26071045u, 0xae473249u, 0xad232e6bu, 0xacafb464u, 0xa1243452u, + 0x2f36b386u, 0x33d53473u, 0xacc02987u, 0x32112a32u, 0x321f32f0u, + 0xb351a6d7u, 0xb2992950u, 0x928cb437u, 0x32cd2df7u, 0x32dc316eu, + 0x2fce30feu, 0x2cd8b4b4u, 0xb43db349u, 0x3235b299u, 0x344f30afu, + 0x338d3499u, 0x3344b30cu, 0x33203280u, 0xb35cb2b0u, 0xb2433412u, + 0xa6c3ad0cu, 0xb49ab336u, 0x333b34beu, 0xb02333ebu, 0xa9b2b160u, + 0xb4bfa72cu, 0x34c5315du, 0xac4a2468u, 0xb3c1ac1eu, 0x153eb07du, + 0x26eba93cu, 0xb14632b4u, 0xb46fb489u, 0x296ab306u, 0x336d31ebu, + 0xab702d30u, 0xab92b2a2u, 0x331bae6fu, 0xb142a014u, 0xb2fbb00eu, + 0xb4513405u, 0xb216b4adu, 0x233631f8u, 0xad772cd5u, 0x32d7b424u, + 0xb47cb1eau, 0xb4002995u, 0x31c4b3c3u, 0xb0f79d28u, 0x3067add0u, + 0xb35db42au, 0x2c1c2c77u, 0xacd13489u, 0x25c4b42du, 0xb2eb2d50u, + 0xb1ce280fu, 0x326f329eu, 0x347ba968u, 0xb31e349bu, 0x2bb4ad14u, + 0xac82b3f9u, 0x3457b096u, 0x310baacau, 0xb312ac5au, 0xb4cc32f9u, + 0xad35b443u, 0xae142f2du, 0xaeffb42au, 0xb4bfb0e5u, 0xb35c2558u, + 0x2d6cb014u, 0xb08b3052u, 0xb0dcae8fu, 0xb1f13463u, 0xa839b215u, + 0xb297b1f7u, 0x2d62b3c2u, 0x2dc42c4eu, 0xaeab313fu, 0x307a3404u, + 0x303e31dau, 0xb02aad6fu, 0xb3bda9f3u, 0xb463a77cu, 0x3424b4c3u, + 0x28c02f45u, 0x296bae1au, 0x2dda3385u, 0xa61d2bdfu, 0x2fa0adedu, + 0xa9c7349eu, 0xa985ac24u, 0x34b6a9b8u, 0xad682ff1u, 0xa951acefu, + 0x2446b473u, 0x2e2a31fau, 0x3061b1cau, 0xb08f3037u, 0x2c432cb8u, + 0xb2fd3286u, 0xa04fb1dcu, 0xaa7bb460u, 0xb2bf3189u, 0x34b4a627u, + 0x941f1b46u, 0xb2072884u, 0x2ecfb2c6u, 0xb009ac01u, 0x32a5b480u, + 0x30cdb47du, 0x2b94ac88u, 0xb29eb0d8u, 0x2f832521u, 0xa8e3b1d9u, + 0xb174a840u, 0xb2cc28ffu, 0xb36c1dfdu, 0xaf3ca071u, 0xa917a756u, + 0x9e2f33d5u, 0xb144321du, 0xb414adaeu, 0x2e7aaa16u, 0x2910327eu, + 0xb2322d61u, 0x319ab471u, 0xb3d9b265u, 0x34733433u, 0xaca92c77u, + 0xb1ab3266u, 0xad7ea96cu, 0x340833edu, 0xb3792dcbu, 0xb0e4a178u, + 0xb2f13364u, 0x2fdab447u, 0x327fa72du, 0x31c8b415u, 0xb488b471u, + 0xb15aa5f1u, 0xb48d2b33u, 0x305cb476u, 0x2e02b191u, 0xb43b30ccu, + 0xb072312eu, 0xb3f0ac3eu, 0x28aa3280u, 0x348019bcu, 0x3381ae5bu, + 0x341d3038u, 0x34b733d4u, 0x31afb312u, 0x2d8b31d9u, 0x3477b03fu, + 0x8c2db1adu, 0xb27e229au, 0xb3e53046u, 0x32b22f6au, 0x3005adc8u, + 0x32a4b297u, 0xb2ab3457u, 0x1b2a2f5eu, 0x2fee24d7u, 0x2bb49eebu, + 0xacaab12bu, 0xb37d3303u, 0xb2102b7eu, 0x2a1232a7u, 0xb0ceab72u, + 0x3465a8dau, 0xa4b01da8u, 0xaca530bau, 0xae43a993u, 0x301bb2b4u, + 0x33ca332au, 0xa7683350u, 0x2d4cb025u, 0x305c345du, 0x2f409a55u, + 0x3406313cu, 0xa922310eu, 0x84a7b059u, 0x3440ae99u, 0xa44b1ce5u, + 0x2d5aadd4u, 0xb31f2229u, 0xad6a3317u, 0xb1a7a92eu, 0x2fc2281au, + 0xb44e3352u, 0x2fd4348bu, 0xb1adb024u, 0x3337afd5u, 0xa5b6b001u, + 0x33242fe6u, 0x30dc2e17u, 0x333fb246u, 0xb323b04eu, 0xb1ba3492u, + 0x2cd7b2fau, 0xb30aaef5u, 0x30f92bc4u, 0xb29d31a1u, 0x3206285eu, + 0xb19db282u, 0x2391b4c7u, 0x304eb1ddu, 0xb1983470u, 0xb1882dbau, + 0x30f7b4a1u, 0x344aa912u, 0xb2942544u, 0xb1b4a7b7u, 0x2f553342u, + 0x2446ae19u, 0x316e2e82u, 0xb495b408u, 0xac08b367u, 0xb2fba51du, + 0xa87caad3u, 0x3400b381u, 0xac482b9du, 0xaf231c3eu, 0x29c332ceu, + 0x33e49a46u, 0x3201327du, 0xb2a9b145u, 0xa4d12f4du, 0x31012f0eu, + 0xb022afdcu, 0xb0599da2u, 0x30bd2e6du, 0x304ca44bu, 0x30161e6au, + 0x3096b148u, 0xb07b3021u, 0x32d2284cu, 0x3088b0cfu, 0x3308345cu, + 0x2c1eab90u, 0x294234b9u, 0xb45db364u, 0xa9de3193u, 0xadd9b0dcu, + 0xa55730f1u, 0x30833313u, 0x3376348du, 0x2e1cb0b6u, 0x34b7b49au, + 0x2e54b097u, 0xb28532b4u, 0xb4af32aeu, 0xa44ca875u, 0x2aa2acd6u, + 0xaea533f7u, 0x333f2a16u, 0xb469313eu, 0xb45a3440u, 0x29ca2ad1u, + 0xb2c03180u, 0x30d7b228u, 0xa4b1b2bbu, 0x2dcf3073u, 0xaf87b18eu, + 0xa7e23481u, 0xb162b460u, 0x34ccae0du, 0xb48caf94u, 0xb3ff1ff0u, + 0x34bab057u, 0xb4502fdcu, 0xb24ea7e2u, 0x2ab0b33du, 0x30aa1af3u, + 0xb0dd3388u, 0x21873410u, 0x32a4b0a1u, 0x2892b475u, 0xb0393041u, + 0xb0fd32fbu, 0xb40c3287u, 0xac92b288u, 0xb2d332ccu, 0xb1303335u, + 0xada8a74bu, 0x3444b355u, 0x2f4fa8bfu, 0x143829c8u, 0x33a62c7au, + 0x24fd2fa7u, 0x2c162d93u, 0x2ccaa923u, 0x30f2a855u, 0x346a3480u, + 0x2bd13228u, 0xb22e30cau, 0xb0a9a272u, 0x347bb4c4u, 0x203532fcu, + 0x2f69b0b8u, 0x31d3a902u, 0xadcc34ccu, 0xb077b0e8u, 0xac12b3cfu, + 0xb367b4a2u, 0xb288b062u, 0xb3933075u, 0xb15b3307u, 0xb4b4b384u, + 0xb0ac3022u, 0xb3751dd6u, 0xb33134a9u, 0x32c0aac4u, 0xb079b0e6u, + 0xb05a31ecu, 0xa989b4c6u, 0x33deb4aeu, 0x2a602d72u, 0x2faeb1bbu, + 0xb4382eceu, 0x2a193350u, 0xb08d319eu, 0x2fc6b342u, 0xac6031a4u, + 0x321cb493u, 0xae2eb1a5u, 0xb3ae2cedu, 0xb48eb41cu, 0xaf3e3400u, + 0x34b22e2bu, 0x23b62e82u, 0xacba226du, 0x34682baau, 0xa9d23188u, + 0x335dae6fu, 0x32b6b2feu, 0x3024b0b4u, 0xa31131e1u, 0x329fb1e8u, + 0xaee3ad16u, 0xa8fc1e27u, 0xb2f72f07u, 0x3385a8f0u, 0xa68eb474u, + 0x33722e2au, 0x323b2b34u, 0xada7b153u, 0x3369343fu, 0xa3882873u, + 0xb43ca784u, 0x321c3389u, 0xb03ca6b8u, 0xb33cae08u, 0x285a3042u, + 0x2cb9b11bu, 0xb340349au, 0x9b2da660u, 0x24dab266u, 0xb2942c12u, + 0x32d8b2a1u, 0x2d01af3eu, 0x32832cdeu, 0x328a309bu, 0xa7c32ccfu, + 0xaca5ac16u, 0xb31eaa44u, 0xac3fa9d7u, 0xb051b478u, 0x29fc30d6u, + 0x268f31e1u, 0x31af32ccu, 0x3494b3b7u, 0x2b70b4a9u, 0xae75319eu, + 0xad4b2b92u, 0xb4b8b438u, 0xb3b6b3c7u, 0x23f22c42u, 0x2f5fa6d7u, + 0xb066b4a3u, 0x33df3153u, 0xb405a8bcu, 0x336531bcu, 0xb0edaaa2u, + 0x2affb461u, 0x2ed533dfu, 0x2d7daf05u, 0xa36d3260u, 0xac273224u, + 0x2a60add1u, 0x3495a56du, 0xac692109u, 0x275dac09u, 0x3048ad92u, + 0xac73ac95u, 0xb4372c7eu, 0x1a1c2df7u, 0x3036a737u, 0x32a630f5u, + 0xaea4accfu, 0x2a48301eu, 0x28442d10u, 0xb1f4313cu, 0xb2902847u, + 0x2e4cab20u, 0xaca09c42u, 0x313d3364u, 0x3452240au, 0x3188a9cfu, + 0xb01db260u, 0xb391ae38u, 0xb1e9146fu, 0xb1f32d27u, 0x3481b33bu, + 0x34312e14u, 0xb47b9e37u, 0x287b29b6u, 0x32f0b4a8u, 0x30b32c9bu, + 0x2c8c9b78u, 0x348cb0a8u, 0xb27caba0u, 0x2d3bb443u, 0x339934a4u, + 0x34b62fc3u, 0xae2c3047u, 0xb4092bc6u, 0xaa55b158u, 0x345bb1bau, + 0xacf534c2u, 0xab153004u, 0xae43b2ecu, 0xae9ab11fu, 0xb371b179u, + 0x33cab16du, 0xaebbb3f7u, 0xad96245fu, 0xb4622169u, 0x28e02db4u, + 0x292a2ef3u, 0xadc1a8c5u, 0x02aab141u, 0xae98b48du, 0xb3832ed5u, + 0x2dd8b432u, 0x31ccabdau, 0x34633433u, 0xb086a9b7u, 0x2cec2c2cu, + 0xaed82cb3u, 0xb191b430u, 0xb339b2a3u, 0xb4ab3418u, 0x344c2bd3u, + 0x242aad60u, 0xaf052f85u, 0x3217a2deu, 0x31ec30b6u, 0xacfb34aeu, + 0x2be530bfu, 0x309b2e66u, 0x336830cbu, 0x2de5adc9u, 0x2b43b038u, + 0x319630d3u, 0x1d5caa22u, 0xb25bae61u, 0x33eab099u, 0x348faf56u, + 0x3048b0f7u, 0x2f8f29adu, 0x2ff02d87u, 0x28e033c9u, 0xb066b426u, + 0x9b482fffu, 0x2b6b2775u, 0x3142ac82u, 0x301d304bu, 0x337f3022u, + 0x347c2b53u, 0x2d11b350u, 0xa2ff302au, 0x27b0b011u, 0x33dbad32u, + 0xb23aad80u, 0xabfd29deu, 0x28fbb3c2u, 0xb24625d0u, 0x292c2b80u, + 0xad513141u, 0x3455b0d3u, 0xb48a28b4u, 0xb1d23228u, 0x2fe1317eu, + 0x34783480u, 0x311eb055u, 0x2cf6af08u, 0xb4472b82u, 0xb43fb4c0u, + 0xb0a7b325u, 0x21b933d0u, 0x327f31b3u, 0xac2c3083u, 0x30a632fcu, + 0x33b630abu, 0x24642b94u, 0xa6ff337eu, 0xb44831fbu, 0x2459b4cau, + 0x3493b418u, 0x3030b4bfu, 0x347db0edu, 0xb48aac8cu, 0x2819b48bu, + 0x349b34acu, 0xa150ae40u, 0x22d0b3acu, 0xb0c82ba8u, 0x33ad2c4eu, + 0xb134b4cau, 0xb339b192u, 0x2cd6b269u, 0x3094b3a1u, 0x3418336eu, + 0xb1cf2e27u, 0xb125b3f6u, 0x3470346fu, 0xaeb1ac89u, 0xb0001e27u, + 0xb15a349bu, 0xa96dad06u, 0xac80b333u, 0xb2e832d9u, 0xab2c2a74u, + 0xb4aeb253u, 0xb435b05au, 0x31f5acbbu, 0x344b3038u, 0x2ffba99bu, + 0xb16f2e59u, 0x2495af8bu, 0xa5de31b2u, 0x34bdb13au, 0x3460b362u, + 0x328231efu, 0xb19a31aau, 0x30ee2d17u, 0xb06330b8u, 0xae9ab21fu, + 0x29aba231u, 0x312a3278u, 0xb08a2ec4u, 0xae52a27du, 0xb4b4b117u, + 0xb0afae2au, 0xb4342986u, 0xb45fb068u, 0x293d2d6eu, 0xb2c5ae3eu, + 0x2a7b3465u, 0x24d12ee1u, 0x339c31e3u, 0x2f4cac81u, 0x2dd5b130u, + 0xb4bcabbfu, 0x33133460u, 0x34c7b004u, 0xa652af06u, 0xaf8132bfu, + 0x2e5ca799u, 0xa9f7b318u, 0x2ecaaf52u, 0xb122b2fdu, 0xb29a300fu, + 0x3016a9fdu, 0xb3c73119u, 0x304d32c2u, 0x3111ae2cu, 0x2bc03062u, + 0x3082287eu, 0x2a0834cbu, 0x30b131edu, 0x345d32d5u, 0xb26cb1e5u, + 0xa7ca2aa2u, 0x31b9296eu, 0xaa583425u, 0xb1d2302fu, 0xb497254fu, + 0x26f7189cu, 0x2dbd3085u, 0xb4bfad70u, 0x348bb362u, 0xaeb7340eu, + 0xa8e2b0a1u, 0xad7f2f4bu, 0xab77b427u, 0xaeb9b099u, 0x2e19b279u, + 0xb0662417u, 0x9c7b2823u, 0x346131afu, 0x335fb317u, 0x2f652fddu, + 0xadfeacd4u, 0x34a1b4bfu, 0xab802c17u, 0xb46926b9u, 0x2cbdb244u, + 0x31832062u, 0x2bca2e19u, 0xb425320eu, 0x30242f54u, 0xb1d8b051u, + 0xb1ccb17eu, 0xb2ff234eu, 0xb3952e1eu, 0xaef0b48bu, 0x34b1b1ebu, + 0xb156af91u, 0xacd8b1d2u, 0x316a2c11u, 0x2cd6ad33u, 0x32a7a183u, + 0xb009294du, 0x32252fd1u, 0x34ada54fu, 0xb1d23347u, 0x2bc13181u, + 0x20482559u, 0x2c4232c9u, 0xb45525cbu, 0x33d6a7f1u, 0xb4503011u, + 0x3246335fu, 0xb496272cu, 0xb44728cbu, 0x2cf3aee6u, 0xad7633eeu, + 0x340432eau, 0xb101b499u, 0x30ee3008u, 0x2e05ac22u, 0x309b2c4fu, + 0xb3f43033u, 0xb30db290u, 0x33f13427u, 0xb35c31b6u, 0xb20129b4u, + 0xb079ad0eu, 0xb2d43251u, 0x34a52d9du, 0xb40a2f2fu, 0x2d7f33d5u, + 0x2e22a6b6u, 0xa3073347u, 0xa74e24d0u, 0x3183b41au, 0xac0cb32cu, + 0xb039ac59u, 0x2c88ab7du, 0xb24aaf3eu, 0x34853318u, 0xaea4a65du, + 0xb472b458u, 0x3421ac1du, 0xadca306eu, 0xa979347eu, 0xa9a8b049u, + 0x3367b18au, 0x2e11ad55u, 0x33b7ac43u, 0x9f382d78u, 0x33b8b310u, + 0xb0212731u, 0xb4473342u, 0x25a8af24u, 0xa326ae27u, 0xb31ab086u, + 0xb293b472u, 0x29ca3459u, 0xac719ec8u, 0xb2e33000u, 0x2dfdb04cu, + 0x3130a26eu, 0x323533a0u, 0xb3d8b210u, 0x3172b259u, 0x341633f2u, + 0x3289afc0u, 0x32332591u, 0xb2cd276eu, 0x3464b40au, 0xadbda9b3u, + 0xaca6ad85u, 0xb4333446u, 0x3190b350u, 0xb3222797u, 0xb14bb478u, + 0xb4aab098u, 0x3093b173u, 0x33a532d3u, 0xaeefac3au, 0x312c34ccu, + 0xb0b525bdu, 0x20b8aeddu, 0xb4ab2677u, 0x29ce3469u, 0xb18a2ad9u, + 0x308e3116u, 0x2b4cb3c6u, 0x32712e13u, 0x3340b1a5u, 0xb3bfa5ebu, + 0xb1cdb392u, 0x986bb02cu, 0xb20430c7u, 0xb28034bbu, 0x341e2ba2u, + 0x2dae3262u, 0xb3063023u, 0xa90fb4b5u, 0xad76b3e2u, 0x33feb14eu, + 0x3220334cu, 0xb2a4301cu, 0x2de9b456u, 0xad042d76u, 0x9eaba432u, + 0xaf23b0feu, 0x2bedaa45u, 0x25e93460u, 0x31e53070u, 0x2de1b36cu, + 0x2990a17fu, 0x33cdb46eu, 0xb4c43459u, 0xb224b184u, 0x2b883167u, + 0x3207b232u, 0xa603ada0u, 0x2291ac54u, 0xb054a21au, 0x33d7a9cbu, + 0x33ff171du, 0x312927b3u, 0x3193afedu, 0xb49db086u, 0xb498b284u, + 0x34cd344bu, 0xb3863109u, 0x30ae33a9u, 0x1599ae71u, 0xb4922e36u, + 0x30761393u, 0xa851b1fcu, 0x308624ffu, 0x32b03475u, 0x2a6c2cabu, + 0x26f02bedu, 0x2f9db43bu, 0x1fab3027u, 0x2e9f331du, 0xb49cad46u, + 0xadb1b43bu, 0xb265a5d2u, 0xb12eb1f7u, 0x31353163u, 0xb24aac7fu, + 0xb3edb378u, 0xb45dac2du, 0x346eae63u, 0x32321c9cu, 0xb074b31eu, + 0xac793449u, 0x34922db3u, 0xaf7a27cdu, 0xb44724e8u, 0xb4bbb371u, + 0x2e943360u, 0xb15bafbeu, 0x34072f08u, 0xaedaafb7u, 0x338e32cdu, + 0xaff133f3u, 0xa89cb34au, 0x335fafd8u, 0x2d24b473u, 0x349333ccu, + 0x34522dc4u, 0xad67b413u, 0x349fb4b7u, 0xb48833bbu, 0xad1cb4a0u, + 0x32a9b0a3u, 0x3195b285u, 0xacb5282fu, 0x34c7b2cdu, 0xa8a82c88u, + 0x33caacf3u, 0x31fa322bu, 0x33732c76u, 0x2fd3afb5u, 0x2baeab57u, + 0x34a734c8u, 0x29ac1fc1u, 0x34a933a1u, 0xb42d3159u, 0x339daed0u, + 0x30a73127u, 0xaa822e73u, 0x31eeab6eu, 0x2f19afebu, 0x329e3058u, + 0x30a5aeebu, 0xb2f3b38eu, 0xb445aa59u, 0x33b7344cu, 0x327fb455u, + 0x2fc11d74u, 0x29e9336eu, 0xb4c6b35eu, 0x34509791u, 0xace12994u, + 0x33f8b481u, 0x2fddaea3u, 0xb0ba2f75u, 0xac6ab430u, 0x2fb1af06u, + 0xb1543224u, 0xb4692456u, 0x3107b17cu, 0x314f31a2u, 0x27d7b2deu, + 0x34b8a9f0u, 0x342e2debu, 0xa78cb2cfu, 0xad133137u, 0x1f312d17u, + 0xb24334b9u, 0xab8f342eu, 0x2465a4ebu, 0x3473b081u, 0x348a33e7u, + 0x2e8534c5u, 0x32bca76cu, 0x326cb492u, 0x2ea796abu, 0xad0bacd6u, + 0xa9dab47fu, 0xb149ab0au, 0x2a76b0dau, 0x3257aeffu, 0x29f7b376u, + 0x2456b287u, 0x2d772809u, 0x1dd2a993u, 0xa5aeb220u, 0x2e61ace0u, + 0x315da901u, 0xb113a9afu, 0xb45eb058u, 0x325a2622u, 0xa8c7312bu, + 0x32fbb1d6u, 0xabbdb441u, 0xac1a32d9u, 0xb07eb356u, 0xb2ae2bafu, + 0xa8c02df3u, 0xb0f9ae5cu, 0xabef3235u, 0xa8953094u, 0xa892b3d6u, + 0xa67a1cb9u, 0x33e33212u, 0x2a5c3182u, 0x2d8e265eu, 0x31fdb013u, + 0xb07832dau, 0x32b233bcu, 0x33daa9cdu, 0xb488b34au, 0x2907add8u, + 0x343eadb4u, 0xb033b0b6u, 0xb4c32d2du, 0xacb5305eu, 0x2f5a3496u, + 0xb3d2b44cu, 0x3458b3e8u, 0xa98f2f11u, 0x332db1c0u, 0x2ff0b1bbu, + 0xafe3310eu, 0xb1521a0au, 0x3477aca6u, 0x32a82f6bu, 0xb103263cu, + 0x0d953016u, 0xaabab234u, 0x30852d2eu, 0x3338b0eeu, 0xb065aca0u, + 0x31d7b1dbu, 0xa11aad9au, 0x2f25b152u, 0xae2b3165u, 0xb4823446u, + 0x2ad2b30cu, 0xb0c92fbcu, 0xaef92827u, 0x2e1e2827u, 0xa6ce348au, + 0x29fe2db1u, 0xb0beaf02u, 0xb1a134afu, 0xb2c93193u, }; // enc0: 8ch rgba32uint → W*H*8 f16 values @@ -701,4 +1034,3 @@ static const uint16_t kCnnV3ExpectedOutputU16[256] = { 0x35c5u, 0x3801u, 0x3856u, 0x34ebu, 0x34f3u, 0x36bfu, 0x385du, 0x3829u, 0x37d3u, 0x384du, 0x3828u, 0x383au, 0x3557u, 0x380bu, 0x38beu, 0x349bu, }; - diff --git a/src/3d/object.h b/src/3d/object.h index e2cd15a..eb1125c 100644 --- a/src/3d/object.h +++ b/src/3d/object.h @@ -9,7 +9,7 @@ #include <memory> // For std::shared_ptr enum class ObjectType { - CUBE, // Legacy alias for BOX (value 0, kept for binary scene compat) + CUBE, // Legacy alias for BOX (value 0, kept for binary scene compat) SPHERE, PLANE, TORUS, diff --git a/src/3d/physics.cc b/src/3d/physics.cc index 788246f..592428b 100644 --- a/src/3d/physics.cc +++ b/src/3d/physics.cc @@ -16,7 +16,8 @@ float PhysicsSystem::sample_sdf(const Object3D& obj, vec3 world_p) { float d = 1000.0f; if (obj.type == ObjectType::SPHERE) { d = q.len() - 1.0f; - } else if (obj.type == ObjectType::BOX || obj.type == ObjectType::CUBE) { // CUBE is legacy alias + } else if (obj.type == ObjectType::BOX || + obj.type == ObjectType::CUBE) { // CUBE is legacy alias d = sdf::sdBox(q, vec3(1.0f, 1.0f, 1.0f)); } else if (obj.type == ObjectType::TORUS) { d = sdf::sdTorus(q, vec2(1.0f, 0.4f)); diff --git a/src/3d/renderer.h b/src/3d/renderer.h index 21192f3..5a9a065 100644 --- a/src/3d/renderer.h +++ b/src/3d/renderer.h @@ -80,7 +80,9 @@ class Renderer3D { // Call before init(). When true, renders directly to surface (no post-process // Y-flip): uses standard perspective (Y not negated) and CCW winding. - void set_direct_render(bool v) { direct_render_ = v; } + void set_direct_render(bool v) { + direct_render_ = v; + } struct MeshGpuData { WGPUBuffer vertex_buffer; @@ -124,7 +126,8 @@ class Renderer3D { BVH cpu_bvh_; // Keep a CPU-side copy for building/uploading bool bvh_enabled_ = true; - bool direct_render_ = false; // true = render to surface (no post-process flip) + bool direct_render_ = + false; // true = render to surface (no post-process flip) bool bind_group_dirty_ = true; // Recreate bind group when textures change std::map<AssetId, MeshGpuData> mesh_cache_; diff --git a/src/3d/renderer_draw.cc b/src/3d/renderer_draw.cc index 929f261..bd7e994 100644 --- a/src/3d/renderer_draw.cc +++ b/src/3d/renderer_draw.cc @@ -10,11 +10,11 @@ void Renderer3D::update_uniforms(const Scene& scene, const Camera& camera, float time) { mat4 proj = camera.get_projection_matrix(); - if (direct_render_) proj.m[5] = -proj.m[5]; // undo Y-negate for direct surface + if (direct_render_) + proj.m[5] = -proj.m[5]; // undo Y-negate for direct surface const mat4 vp = proj * camera.get_view_matrix(); const GlobalUniforms globals = GlobalUniforms::make( - vp, - vec4(camera.position.x, camera.position.y, camera.position.z, time), + vp, vec4(camera.position.x, camera.position.y, camera.position.z, time), vec4((float)std::min((size_t)kMaxObjects, scene.objects.size()), 0.0f, 0.0f, 0.0f), vec2((float)width_, (float)height_)); @@ -26,13 +26,25 @@ void Renderer3D::update_uniforms(const Scene& scene, const Camera& camera, for (const auto& obj : scene.objects) { float type_id = 0.0f; switch (obj.type) { - case ObjectType::SPHERE: type_id = 1.0f; break; - case ObjectType::CUBE: // fallthrough (legacy alias for BOX) - case ObjectType::BOX: type_id = 2.0f; break; - case ObjectType::TORUS: type_id = 3.0f; break; - case ObjectType::PLANE: type_id = 4.0f; break; - case ObjectType::MESH: type_id = 5.0f; break; - default: type_id = 0.0f; break; + case ObjectType::SPHERE: + type_id = 1.0f; + break; + case ObjectType::CUBE: // fallthrough (legacy alias for BOX) + case ObjectType::BOX: + type_id = 2.0f; + break; + case ObjectType::TORUS: + type_id = 3.0f; + break; + case ObjectType::PLANE: + type_id = 4.0f; + break; + case ObjectType::MESH: + type_id = 5.0f; + break; + default: + type_id = 0.0f; + break; } float plane_distance = 0.0f; @@ -69,68 +81,69 @@ void Renderer3D::draw(WGPURenderPassEncoder pass, const Scene& scene, } else { bind_group_dirty_ = false; - if (bind_group_) - wgpuBindGroupRelease(bind_group_); + if (bind_group_) + wgpuBindGroupRelease(bind_group_); - std::vector<WGPUBindGroupEntry> bg_entries; + std::vector<WGPUBindGroupEntry> bg_entries; - { - WGPUBindGroupEntry e = {}; - e.binding = 0; - e.buffer = global_uniform_buffer_; - e.size = sizeof(GlobalUniforms); - bg_entries.push_back(e); - } + { + WGPUBindGroupEntry e = {}; + e.binding = 0; + e.buffer = global_uniform_buffer_; + e.size = sizeof(GlobalUniforms); + bg_entries.push_back(e); + } - { - WGPUBindGroupEntry e = {}; - e.binding = 1; - e.buffer = object_storage_buffer_; - e.size = sizeof(ObjectData) * kMaxObjects; - bg_entries.push_back(e); - } + { + WGPUBindGroupEntry e = {}; + e.binding = 1; + e.buffer = object_storage_buffer_; + e.size = sizeof(ObjectData) * kMaxObjects; + bg_entries.push_back(e); + } - if (bvh_enabled_) { - WGPUBindGroupEntry e = {}; - e.binding = 2; - e.buffer = bvh_storage_buffer_; - e.size = sizeof(BVHNode) * kMaxObjects * 2; - bg_entries.push_back(e); - } + if (bvh_enabled_) { + WGPUBindGroupEntry e = {}; + e.binding = 2; + e.buffer = bvh_storage_buffer_; + e.size = sizeof(BVHNode) * kMaxObjects * 2; + bg_entries.push_back(e); + } - { - WGPUBindGroupEntry e = {}; - e.binding = 3; - e.textureView = noise_texture_view_; - bg_entries.push_back(e); - } + { + WGPUBindGroupEntry e = {}; + e.binding = 3; + e.textureView = noise_texture_view_; + bg_entries.push_back(e); + } - { - WGPUBindGroupEntry e = {}; - e.binding = 4; - e.sampler = default_sampler_; - bg_entries.push_back(e); - } + { + WGPUBindGroupEntry e = {}; + e.binding = 4; + e.sampler = default_sampler_; + bg_entries.push_back(e); + } - { - WGPUBindGroupEntry e = {}; - e.binding = 5; - e.textureView = sky_texture_view_ ? sky_texture_view_ : noise_texture_view_; - bg_entries.push_back(e); - } + { + WGPUBindGroupEntry e = {}; + e.binding = 5; + e.textureView = + sky_texture_view_ ? sky_texture_view_ : noise_texture_view_; + bg_entries.push_back(e); + } - WGPURenderPipeline cp = bvh_enabled_ ? pipeline_ : pipeline_no_bvh_; - WGPUBindGroupLayout current_layout = - wgpuRenderPipelineGetBindGroupLayout(cp, 0); + WGPURenderPipeline cp = bvh_enabled_ ? pipeline_ : pipeline_no_bvh_; + WGPUBindGroupLayout current_layout = + wgpuRenderPipelineGetBindGroupLayout(cp, 0); - WGPUBindGroupDescriptor bg_desc = {}; - bg_desc.layout = current_layout; - bg_desc.entryCount = (uint32_t)bg_entries.size(); - bg_desc.entries = bg_entries.data(); + WGPUBindGroupDescriptor bg_desc = {}; + bg_desc.layout = current_layout; + bg_desc.entryCount = (uint32_t)bg_entries.size(); + bg_desc.entries = bg_entries.data(); - bind_group_ = wgpuDeviceCreateBindGroup(device_, &bg_desc); + bind_group_ = wgpuDeviceCreateBindGroup(device_, &bg_desc); - wgpuBindGroupLayoutRelease(current_layout); + wgpuBindGroupLayoutRelease(current_layout); } // end dirty block WGPURenderPipeline current_pipeline = @@ -208,7 +221,8 @@ void Renderer3D::draw(WGPURenderPassEncoder pass, const Scene& scene, } mat4 dbg_proj = camera.get_projection_matrix(); - if (direct_render_) dbg_proj.m[5] = -dbg_proj.m[5]; + if (direct_render_) + dbg_proj.m[5] = -dbg_proj.m[5]; mat4 view_proj = dbg_proj * camera.get_view_matrix(); visual_debug_.render(pass, view_proj); } diff --git a/src/3d/renderer_pipelines.cc b/src/3d/renderer_pipelines.cc index 195baad..9e1e2fb 100644 --- a/src/3d/renderer_pipelines.cc +++ b/src/3d/renderer_pipelines.cc @@ -253,8 +253,8 @@ void Renderer3D::create_mesh_pipeline() { pipeline_desc.vertex.buffers = &vert_buffer_layout; pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; pipeline_desc.primitive.cullMode = WGPUCullMode_Back; - // CW winding compensates for Y-negation in perspective() (post-process chain). - // Direct-to-surface rendering uses standard CCW winding. + // CW winding compensates for Y-negation in perspective() (post-process + // chain). Direct-to-surface rendering uses standard CCW winding. pipeline_desc.primitive.frontFace = direct_render_ ? WGPUFrontFace_CCW : WGPUFrontFace_CW; pipeline_desc.multisample.count = 1; diff --git a/src/3d/scene_loader.cc b/src/3d/scene_loader.cc index d5c1879..d27cc16 100644 --- a/src/3d/scene_loader.cc +++ b/src/3d/scene_loader.cc @@ -64,26 +64,40 @@ bool LoadScene(Scene& scene, const uint8_t* data, size_t size) { if (offset + 12 + 16 + 12 + 16 > size) return false; // Transforms + Color - float px = read_f32(data + offset); offset += 4; - float py = read_f32(data + offset); offset += 4; - float pz = read_f32(data + offset); offset += 4; + float px = read_f32(data + offset); + offset += 4; + float py = read_f32(data + offset); + offset += 4; + float pz = read_f32(data + offset); + offset += 4; vec3 pos(px, py, pz); - float rx = read_f32(data + offset); offset += 4; - float ry = read_f32(data + offset); offset += 4; - float rz = read_f32(data + offset); offset += 4; - float rw = read_f32(data + offset); offset += 4; + float rx = read_f32(data + offset); + offset += 4; + float ry = read_f32(data + offset); + offset += 4; + float rz = read_f32(data + offset); + offset += 4; + float rw = read_f32(data + offset); + offset += 4; quat rot(rx, ry, rz, rw); - float sx = read_f32(data + offset); offset += 4; - float sy = read_f32(data + offset); offset += 4; - float sz = read_f32(data + offset); offset += 4; + float sx = read_f32(data + offset); + offset += 4; + float sy = read_f32(data + offset); + offset += 4; + float sz = read_f32(data + offset); + offset += 4; vec3 scale(sx, sy, sz); - float cr = read_f32(data + offset); offset += 4; - float cg = read_f32(data + offset); offset += 4; - float cb = read_f32(data + offset); offset += 4; - float ca = read_f32(data + offset); offset += 4; + float cr = read_f32(data + offset); + offset += 4; + float cg = read_f32(data + offset); + offset += 4; + float cb = read_f32(data + offset); + offset += 4; + float ca = read_f32(data + offset); + offset += 4; vec4 color(cr, cg, cb, ca); // Plane Distance (if type == PLANE) @@ -127,9 +141,12 @@ bool LoadScene(Scene& scene, const uint8_t* data, size_t size) { // Physics properties if (offset + 4 + 4 + 4 > size) return false; - float mass = read_f32(data + offset); offset += 4; - float restitution = read_f32(data + offset); offset += 4; - uint32_t is_static_u32 = read_u32(data + offset); offset += 4; + float mass = read_f32(data + offset); + offset += 4; + float restitution = read_f32(data + offset); + offset += 4; + uint32_t is_static_u32 = read_u32(data + offset); + offset += 4; bool is_static = (is_static_u32 != 0); // Create Object3D diff --git a/src/audio/audio_engine.cc b/src/audio/audio_engine.cc index 1d6659d..3033882 100644 --- a/src/audio/audio_engine.cc +++ b/src/audio/audio_engine.cc @@ -170,7 +170,8 @@ void AudioEngine::seek(float target_time) { // 1. Reset synth state (clear all active voices) synth_init(); - // 2. Re-init tracker: re-registers all spectrograms with now-clean synth slots + // 2. Re-init tracker: re-registers all spectrograms with now-clean synth + // slots resource_mgr_.reset(); ::tracker_init(&resource_mgr_); diff --git a/src/audio/backend/miniaudio_backend.cc b/src/audio/backend/miniaudio_backend.cc index 8871d10..e591c72 100644 --- a/src/audio/backend/miniaudio_backend.cc +++ b/src/audio/backend/miniaudio_backend.cc @@ -286,7 +286,7 @@ float MiniaudioBackend::get_realtime_peak() { } void MiniaudioBackend::get_callback_state(double* out_time, - int64_t* out_samples) { + int64_t* out_samples) { *out_time = last_callback_time_.load(std::memory_order_acquire); *out_samples = last_callback_samples_.load(std::memory_order_acquire); } diff --git a/src/audio/backend/miniaudio_backend.h b/src/audio/backend/miniaudio_backend.h index 01fa790..c959f2b 100644 --- a/src/audio/backend/miniaudio_backend.h +++ b/src/audio/backend/miniaudio_backend.h @@ -36,7 +36,8 @@ class MiniaudioBackend : public AudioBackend { static std::atomic<float> realtime_peak_; // Smooth playback time interpolation (updated in callback) - static std::atomic<double> last_callback_time_; // Absolute CLOCK_MONOTONIC time + static std::atomic<double> + last_callback_time_; // Absolute CLOCK_MONOTONIC time static std::atomic<int64_t> last_callback_samples_; // Static callback required by miniaudio C API diff --git a/src/audio/gen.cc b/src/audio/gen.cc index 9d18517..723a9cb 100644 --- a/src/audio/gen.cc +++ b/src/audio/gen.cc @@ -12,7 +12,8 @@ std::vector<float> generate_note_spectrogram(const NoteParams& params, int* out_num_frames) { - int num_frames = (int)(params.duration_sec * RING_BUFFER_SAMPLE_RATE / DCT_SIZE); + int num_frames = + (int)(params.duration_sec * RING_BUFFER_SAMPLE_RATE / DCT_SIZE); if (num_frames < 1) num_frames = 1; *out_num_frames = num_frames; diff --git a/src/audio/ola.h b/src/audio/ola.h index 1fb2a4a..33ec674 100644 --- a/src/audio/ola.h +++ b/src/audio/ola.h @@ -21,6 +21,6 @@ void ola_decode(const float* spec, int num_frames, float* pcm); // Single-frame OLA-IDCT decoder. // spec_frame: single DCT_SIZE spectral frame. -// overlap: OLA_OVERLAP buffer (read/write). Must be zero-initialized for first frame. -// out_hop: OLA_HOP_SIZE buffer for the resulting time-domain samples. +// overlap: OLA_OVERLAP buffer (read/write). Must be zero-initialized for first +// frame. out_hop: OLA_HOP_SIZE buffer for the resulting time-domain samples. void ola_decode_frame(const float* spec_frame, float* overlap, float* out_hop); diff --git a/src/audio/synth.cc b/src/audio/synth.cc index d584c62..57972cc 100644 --- a/src/audio/synth.cc +++ b/src/audio/synth.cc @@ -110,8 +110,8 @@ int synth_register_spectrogram(const Spectrogram* spec) { for (int i = 0; i < MAX_SPECTROGRAMS; ++i) { if (!g_synth_data.spectrogram_registered[i]) { g_synth_data.spectrograms[i] = *spec; - g_synth_data.active_spectrogram_data[i].store( - spec->spectral_data_a, std::memory_order_release); + g_synth_data.active_spectrogram_data[i].store(spec->spectral_data_a, + std::memory_order_release); g_synth_data.spectrogram_registered[i] = true; return i; } @@ -184,9 +184,8 @@ void synth_trigger_voice(int spectrogram_id, float volume, float pan, volume, spectrogram_id); } if (pan < -1.0f || pan > 1.0f) { - DEBUG_SYNTH( - "[SYNTH WARNING] Invalid pan=%.2f for spectrogram_id=%d\n", - pan, spectrogram_id); + DEBUG_SYNTH("[SYNTH WARNING] Invalid pan=%.2f for spectrogram_id=%d\n", pan, + spectrogram_id); } if (start_offset_samples < 0) { DEBUG_SYNTH("[SYNTH WARNING] Negative start_offset=%d, clamping to 0\n", diff --git a/src/audio/tracker.cc b/src/audio/tracker.cc index e634333..f9657e9 100644 --- a/src/audio/tracker.cc +++ b/src/audio/tracker.cc @@ -176,7 +176,8 @@ void tracker_update(double music_time_sec, double dt_music_sec) { const TrackerPatternTrigger& trigger = g_tracker_score.triggers[g_last_trigger_idx]; - const double trigger_time_sec = (double)trigger.unit_time * unit_duration_sec; + const double trigger_time_sec = + (double)trigger.unit_time * unit_duration_sec; if (trigger_time_sec > end_music_time) break; @@ -214,8 +215,8 @@ void tracker_update(double music_time_sec, double dt_music_sec) { // Offset = (music_time_delta / tempo_scale) * sample_rate int sample_offset = 0; if (event_music_time > music_time_sec) { - sample_offset = (int)((event_music_time - music_time_sec) / tempo_scale * - (double)RING_BUFFER_SAMPLE_RATE); + sample_offset = (int)((event_music_time - music_time_sec) / + tempo_scale * (double)RING_BUFFER_SAMPLE_RATE); } // Apply humanization if enabled @@ -230,9 +231,10 @@ void tracker_update(double music_time_sec, double dt_music_sec) { // Timing variation: jitter by % of beat duration if (g_tracker_score.timing_variation_pct > 0.0f) { double beat_sec = 60.0 / (double)g_tracker_score.bpm; - double jitter = dist(rng) * - (double)(g_tracker_score.timing_variation_pct / 100.0f) * - beat_sec; + double jitter = + dist(rng) * + (double)(g_tracker_score.timing_variation_pct / 100.0f) * + beat_sec; sample_offset += (int)(jitter / tempo_scale * (double)RING_BUFFER_SAMPLE_RATE); } @@ -240,7 +242,8 @@ void tracker_update(double music_time_sec, double dt_music_sec) { // Volume variation: vary by % if (g_tracker_score.volume_variation_pct > 0.0f) { volume_mult += - (float)(dist(rng) * (double)(g_tracker_score.volume_variation_pct / 100.0f)); + (float)(dist(rng) * + (double)(g_tracker_score.volume_variation_pct / 100.0f)); } } @@ -250,7 +253,8 @@ void tracker_update(double music_time_sec, double dt_music_sec) { // Pattern remains active until full duration elapses const double pattern_end_time = - active.start_music_time + (double)pattern.unit_length * unit_duration_sec; + active.start_music_time + + (double)pattern.unit_length * unit_duration_sec; if (pattern_end_time <= end_music_time) { active.active = false; } diff --git a/src/effects/flash_effect.h b/src/effects/flash_effect.h index 1cfe1ee..1871186 100644 --- a/src/effects/flash_effect.h +++ b/src/effects/flash_effect.h @@ -9,5 +9,6 @@ struct Flash : public WgslEffect { const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - flash_shader_wgsl) {} + flash_shader_wgsl) { + } }; diff --git a/src/effects/gaussian_blur_effect.h b/src/effects/gaussian_blur_effect.h index 0c528c5..43d0120 100644 --- a/src/effects/gaussian_blur_effect.h +++ b/src/effects/gaussian_blur_effect.h @@ -11,5 +11,6 @@ struct GaussianBlur : public WgslEffect { float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, gaussian_blur_shader_wgsl, WGPULoadOp_Clear, - WgslEffectParams{{8.0f, 0.5f, 1.0f, 0.0f}, {}}) {} + WgslEffectParams{{8.0f, 0.5f, 1.0f, 0.0f}, {}}) { + } }; diff --git a/src/effects/heptagon_effect.h b/src/effects/heptagon_effect.h index 3762202..ff1be46 100644 --- a/src/effects/heptagon_effect.h +++ b/src/effects/heptagon_effect.h @@ -9,5 +9,6 @@ struct Heptagon : public WgslEffect { const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - heptagon_shader_wgsl) {} + heptagon_shader_wgsl) { + } }; diff --git a/src/effects/ntsc_effect.h b/src/effects/ntsc_effect.h index 4737291..b975c4d 100644 --- a/src/effects/ntsc_effect.h +++ b/src/effects/ntsc_effect.h @@ -9,14 +9,17 @@ struct Ntsc : public WgslEffect { const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - ntsc_rgb_shader_wgsl) {} + ntsc_rgb_shader_wgsl) { + } }; -// YIQ input: input texture already stores luma/chroma/phase (e.g. RotatingCube output). +// YIQ input: input texture already stores luma/chroma/phase (e.g. RotatingCube +// output). struct NtscYiq : public WgslEffect { NtscYiq(const GpuContext& ctx, const std::vector<std::string>& inputs, const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - ntsc_yiq_shader_wgsl) {} + ntsc_yiq_shader_wgsl) { + } }; diff --git a/src/effects/passthrough_effect.h b/src/effects/passthrough_effect.h index 285663f..9137b48 100644 --- a/src/effects/passthrough_effect.h +++ b/src/effects/passthrough_effect.h @@ -9,5 +9,6 @@ struct Passthrough : public WgslEffect { const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - passthrough_shader_wgsl) {} + passthrough_shader_wgsl) { + } }; diff --git a/src/effects/peak_meter_effect.cc b/src/effects/peak_meter_effect.cc index 8956e32..6c6e8fd 100644 --- a/src/effects/peak_meter_effect.cc +++ b/src/effects/peak_meter_effect.cc @@ -67,9 +67,8 @@ void PeakMeter::render(WGPUCommandEncoder encoder, WGPUTextureView input_view = nodes.get_view(input_nodes_[0]); WGPUTextureView output_view = nodes.get_view(output_nodes_[0]); - pp_update_bind_group(ctx_.device, pipeline_.get(), - bind_group_.get_address(), input_view, - uniforms_buffer_.get(), {nullptr, 0}); + pp_update_bind_group(ctx_.device, pipeline_.get(), bind_group_.get_address(), + input_view, uniforms_buffer_.get(), {nullptr, 0}); run_fullscreen_pass(encoder, pipeline_.get(), bind_group_.get(), output_view, WGPULoadOp_Load); diff --git a/src/effects/rotating_cube_effect.cc b/src/effects/rotating_cube_effect.cc index 000d177..ec587b5 100644 --- a/src/effects/rotating_cube_effect.cc +++ b/src/effects/rotating_cube_effect.cc @@ -44,7 +44,8 @@ RotatingCube::RotatingCube(const GpuContext& ctx, wgpuDeviceCreatePipelineLayout(ctx_.device, &pl_desc); // Load shader - const std::string composed = ShaderComposer::Get().Compose({}, rotating_cube_wgsl); + const std::string composed = + ShaderComposer::Get().Compose({}, rotating_cube_wgsl); WGPUShaderSourceWGSL wgsl_src = {}; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; wgsl_src.code = str_view(composed.c_str()); @@ -78,7 +79,7 @@ RotatingCube::RotatingCube(const GpuContext& ctx, pipeline_desc.vertex.entryPoint = str_view("vs_main"); pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; pipeline_desc.primitive.cullMode = WGPUCullMode_Back; - pipeline_desc.primitive.frontFace = WGPUFrontFace_CW; // Y-flipped perspective + pipeline_desc.primitive.frontFace = WGPUFrontFace_CW; // Y-flipped perspective pipeline_desc.depthStencil = &depth_stencil; pipeline_desc.multisample.count = 1; pipeline_desc.multisample.mask = 0xFFFFFFFF; @@ -136,8 +137,7 @@ void RotatingCube::render(WGPUCommandEncoder encoder, // Update uniforms const Uniforms uniforms = Uniforms::make( - view_proj, - vec4(camera_pos.x, camera_pos.y, camera_pos.z, params.time), + view_proj, vec4(camera_pos.x, camera_pos.y, camera_pos.z, params.time), vec4(1.0f, 0.0f, 0.0f, 0.0f), params.resolution, params.aspect_ratio); const ObjectData obj_data = { diff --git a/src/effects/scene2_effect.h b/src/effects/scene2_effect.h index 0e26fc3..1ede2e7 100644 --- a/src/effects/scene2_effect.h +++ b/src/effects/scene2_effect.h @@ -13,5 +13,6 @@ struct Scene2Effect : public WgslEffect { float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, scene2_shader_wgsl, WGPULoadOp_Clear, {}, - WgslSamplerType::Nearest) {} + WgslSamplerType::Nearest) { + } }; diff --git a/src/effects/scratch_effect.h b/src/effects/scratch_effect.h index 6c0e0cb..dc67118 100644 --- a/src/effects/scratch_effect.h +++ b/src/effects/scratch_effect.h @@ -9,5 +9,6 @@ struct Scratch : public WgslEffect { const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - scratch_shader_wgsl) {} + scratch_shader_wgsl) { + } }; diff --git a/src/effects/shaders.cc b/src/effects/shaders.cc index 7ca66fa..a099bf4 100644 --- a/src/effects/shaders.cc +++ b/src/effects/shaders.cc @@ -51,7 +51,7 @@ void InitShaderComposer() { register_if_exists("ray_box", AssetId::ASSET_SHADER_RAY_BOX); register_if_exists("ray_triangle", AssetId::ASSET_SHADER_RAY_TRIANGLE); - register_if_exists("ray_sphere", AssetId::ASSET_SHADER_RAY_SPHERE); + register_if_exists("ray_sphere", AssetId::ASSET_SHADER_RAY_SPHERE); register_if_exists("debug/debug_print", AssetId::ASSET_SHADER_DEBUG_DEBUG_PRINT); @@ -73,12 +73,13 @@ void InitShaderComposer() { register_if_exists("render/raymarching_id", AssetId::ASSET_SHADER_RENDER_RAYMARCHING_ID); // CNN v3 inference snippets - register_if_exists("cnn_v3/common", AssetId::ASSET_SHADER_CNN_V3_COMMON); - register_if_exists("cnn_v3/enc0", AssetId::ASSET_SHADER_CNN_V3_ENC0); - register_if_exists("cnn_v3/enc1", AssetId::ASSET_SHADER_CNN_V3_ENC1); - register_if_exists("cnn_v3/bottleneck", AssetId::ASSET_SHADER_CNN_V3_BOTTLENECK); - register_if_exists("cnn_v3/dec1", AssetId::ASSET_SHADER_CNN_V3_DEC1); - register_if_exists("cnn_v3/dec0", AssetId::ASSET_SHADER_CNN_V3_DEC0); + register_if_exists("cnn_v3/common", AssetId::ASSET_SHADER_CNN_V3_COMMON); + register_if_exists("cnn_v3/enc0", AssetId::ASSET_SHADER_CNN_V3_ENC0); + register_if_exists("cnn_v3/enc1", AssetId::ASSET_SHADER_CNN_V3_ENC1); + register_if_exists("cnn_v3/bottleneck", + AssetId::ASSET_SHADER_CNN_V3_BOTTLENECK); + register_if_exists("cnn_v3/dec1", AssetId::ASSET_SHADER_CNN_V3_DEC1); + register_if_exists("cnn_v3/dec0", AssetId::ASSET_SHADER_CNN_V3_DEC0); // CNN shaders (workspace-specific) // register_if_exists("cnn_activation", AssetId::ASSET_SHADER_CNN_ACTIVATION); @@ -119,16 +120,18 @@ const char* scene2_shader_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_SCENE2); const char* scratch_shader_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_SCRATCH); const char* ntsc_rgb_shader_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_NTSC_RGB); const char* ntsc_yiq_shader_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_NTSC_YIQ); -const char* gbuf_raster_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_RASTER); -const char* gbuf_pack_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_PACK); -const char* gbuf_shadow_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_SHADOW); -const char* gbuf_view_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_VIEW); -const char* gbuf_deferred_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_DEFERRED); -const char* cnn_v3_enc0_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_ENC0); -const char* cnn_v3_enc1_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_ENC1); -const char* cnn_v3_bottleneck_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_BOTTLENECK); -const char* cnn_v3_dec1_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_DEC1); -const char* cnn_v3_dec0_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_DEC0); +const char* gbuf_raster_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_RASTER); +const char* gbuf_pack_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_PACK); +const char* gbuf_shadow_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_SHADOW); +const char* gbuf_view_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_VIEW); +const char* gbuf_deferred_wgsl = + SafeGetAsset(AssetId::ASSET_SHADER_GBUF_DEFERRED); +const char* cnn_v3_enc0_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_ENC0); +const char* cnn_v3_enc1_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_ENC1); +const char* cnn_v3_bottleneck_wgsl = + SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_BOTTLENECK); +const char* cnn_v3_dec1_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_DEC1); +const char* cnn_v3_dec0_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_DEC0); // Compute shaders const char* gen_noise_compute_wgsl = diff --git a/src/gpu/demo_effects.h b/src/gpu/demo_effects.h index 1f859bc..d67478e 100644 --- a/src/gpu/demo_effects.h +++ b/src/gpu/demo_effects.h @@ -22,6 +22,7 @@ #include "effects/gaussian_blur_effect.h" #include "effects/heptagon_effect.h" #include "effects/hybrid3_d_effect.h" +#include "effects/ntsc_effect.h" #include "effects/particles_effect.h" #include "effects/passthrough_effect.h" #include "effects/peak_meter_effect.h" @@ -30,12 +31,11 @@ #include "effects/scene1_effect.h" #include "effects/scene2_effect.h" #include "effects/scratch_effect.h" -#include "effects/ntsc_effect.h" // CNN v3 G-buffer + inference + debug view -#include "../../cnn_v3/src/gbuffer_effect.h" #include "../../cnn_v3/src/cnn_v3_effect.h" -#include "../../cnn_v3/src/gbuf_view_effect.h" #include "../../cnn_v3/src/gbuf_deferred_effect.h" +#include "../../cnn_v3/src/gbuf_view_effect.h" +#include "../../cnn_v3/src/gbuffer_effect.h" #include <memory> diff --git a/src/gpu/effect.cc b/src/gpu/effect.cc index 2e93a11..d761b2d 100644 --- a/src/gpu/effect.cc +++ b/src/gpu/effect.cc @@ -59,8 +59,8 @@ void Effect::blit_input_to_output(WGPUCommandEncoder encoder, &extent); } -std::string Effect::find_downstream_output( - const std::vector<EffectDAGNode>& dag) const { +std::string +Effect::find_downstream_output(const std::vector<EffectDAGNode>& dag) const { for (const auto& node : dag) { for (const auto& in : node.input_nodes) { for (const auto& out : output_nodes_) { diff --git a/src/gpu/effect.h b/src/gpu/effect.h index 47dd3c2..4c9b157 100644 --- a/src/gpu/effect.h +++ b/src/gpu/effect.h @@ -77,7 +77,8 @@ class Effect { // Returns output_nodes[0] of the first effect in |dag| whose input_nodes // intersect this effect's output_nodes_ (i.e. the first direct downstream // consumer). Returns "" if no such effect exists or it has no outputs. - std::string find_downstream_output(const std::vector<EffectDAGNode>& dag) const; + std::string + find_downstream_output(const std::vector<EffectDAGNode>& dag) const; // Helper: Run a fullscreen triangle pass (pipeline + bind_group → output) static void run_fullscreen_pass(WGPUCommandEncoder encoder, diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc index f5f1515..3200655 100644 --- a/src/gpu/gpu.cc +++ b/src/gpu/gpu.cc @@ -138,14 +138,18 @@ WGPUShaderModule gpu_create_shader_module(WGPUDevice device, } WGPUSampler gpu_create_linear_sampler(WGPUDevice device) { - WGPUSampler s = SamplerCache::Get().get_or_create(device, SamplerCache::clamp()); - if (s) wgpuSamplerAddRef(s); // Caller owns a reference (for RAII wrappers) + WGPUSampler s = + SamplerCache::Get().get_or_create(device, SamplerCache::clamp()); + if (s) + wgpuSamplerAddRef(s); // Caller owns a reference (for RAII wrappers) return s; } WGPUSampler gpu_create_nearest_sampler(WGPUDevice device) { - WGPUSampler s = SamplerCache::Get().get_or_create(device, SamplerCache::nearest()); - if (s) wgpuSamplerAddRef(s); // Caller owns a reference (for RAII wrappers) + WGPUSampler s = + SamplerCache::Get().get_or_create(device, SamplerCache::nearest()); + if (s) + wgpuSamplerAddRef(s); // Caller owns a reference (for RAII wrappers) return s; } @@ -170,8 +174,8 @@ RenderPass gpu_create_render_pass(WGPUDevice device, WGPUTextureFormat format, // Compose shader to resolve #include directives std::string composed_shader = ShaderComposer::Get().Compose({}, shader_code); - WGPUShaderModule shader_module = - gpu_create_shader_module(device, composed_shader.c_str(), "render_shader"); + WGPUShaderModule shader_module = gpu_create_shader_module( + device, composed_shader.c_str(), "render_shader"); // Create Bind Group Layout & Bind Group std::vector<WGPUBindGroupLayoutEntry> bgl_entries; @@ -268,8 +272,8 @@ ComputePass gpu_create_compute_pass(WGPUDevice device, const char* shader_code, // Compose shader to resolve #include directives std::string composed_shader = ShaderComposer::Get().Compose({}, shader_code); - WGPUShaderModule shader_module = - gpu_create_shader_module(device, composed_shader.c_str(), "compute_shader"); + WGPUShaderModule shader_module = gpu_create_shader_module( + device, composed_shader.c_str(), "compute_shader"); std::vector<WGPUBindGroupLayoutEntry> bgl_entries; std::vector<WGPUBindGroupEntry> bg_entries; @@ -379,7 +383,7 @@ void gpu_init(PlatformState* platform_state) { // Exclude GL backend: wgpu's WGL pixel-format selection panics under Wine. WGPUInstanceExtras win_extras = {}; win_extras.chain.sType = (WGPUSType)WGPUSType_InstanceExtras; - win_extras.backends = WGPUInstanceBackend_Primary; // Vulkan + DX12, no GL + win_extras.backends = WGPUInstanceBackend_Primary; // Vulkan + DX12, no GL WGPUInstanceDescriptor win_desc = {}; win_desc.nextInChain = (WGPUChainedStruct*)&win_extras; g_instance = wgpuCreateInstance(&win_desc); @@ -435,7 +439,6 @@ void gpu_init(PlatformState* platform_state) { wgpuSurfaceConfigure(g_surface, &g_config); InitShaderComposer(); - } void gpu_resize(int width, int height) { diff --git a/src/gpu/pipeline_builder.cc b/src/gpu/pipeline_builder.cc index acd2ae9..03eb9dd 100644 --- a/src/gpu/pipeline_builder.cc +++ b/src/gpu/pipeline_builder.cc @@ -16,8 +16,8 @@ RenderPipelineBuilder& RenderPipelineBuilder::shader(const char* wgsl, shader_text_ = compose ? ShaderComposer::Get().Compose({}, wgsl) : wgsl; if (device_ == nullptr) return *this; - shader_module_ = - gpu_create_shader_module(device_, shader_text_.c_str(), "pipeline_shader"); + shader_module_ = gpu_create_shader_module(device_, shader_text_.c_str(), + "pipeline_shader"); desc_.vertex.module = shader_module_; desc_.vertex.entryPoint = str_view("vs_main"); return *this; diff --git a/src/gpu/post_process_helper.cc b/src/gpu/post_process_helper.cc index 871a238..8e5bae2 100644 --- a/src/gpu/post_process_helper.cc +++ b/src/gpu/post_process_helper.cc @@ -40,8 +40,8 @@ WGPURenderPipeline create_post_process_pipeline(WGPUDevice device, } // NOTE: create_post_process_pipeline_simple() was removed (zero callers). -// If a 3-binding pipeline is needed in the future, add a `bool use_effect_params` -// parameter to create_post_process_pipeline() instead. +// If a 3-binding pipeline is needed in the future, add a `bool +// use_effect_params` parameter to create_post_process_pipeline() instead. // Example: // WGPURenderPipeline p = create_post_process_pipeline(device, format, code); // // Then pass {nullptr, 0} as effect_params to pp_update_bind_group — diff --git a/src/gpu/post_process_helper.h b/src/gpu/post_process_helper.h index 8f2bd21..645ac4f 100644 --- a/src/gpu/post_process_helper.h +++ b/src/gpu/post_process_helper.h @@ -21,6 +21,7 @@ void pp_update_bind_group(WGPUDevice device, WGPURenderPipeline pipeline, WGPUBindGroup* bind_group, WGPUTextureView input_view, GpuBuffer uniforms, GpuBuffer effect_params); -// Upload a mat4 to a GPU buffer, transposing from C++ row-major to WGSL column-major. +// Upload a mat4 to a GPU buffer, transposing from C++ row-major to WGSL +// column-major. void gpu_upload_mat4(WGPUQueue queue, WGPUBuffer buffer, size_t offset, const mat4& m); diff --git a/src/gpu/sequence.cc b/src/gpu/sequence.cc index c81a912..f0e0356 100644 --- a/src/gpu/sequence.cc +++ b/src/gpu/sequence.cc @@ -226,10 +226,10 @@ void NodeRegistry::create_texture(Node& node) { view_desc.mipLevelCount = 1; view_desc.baseArrayLayer = 0; view_desc.arrayLayerCount = 1; - view_desc.aspect = (node.type == NodeType::DEPTH24 || - node.type == NodeType::GBUF_DEPTH32) - ? WGPUTextureAspect_DepthOnly - : WGPUTextureAspect_All; + view_desc.aspect = + (node.type == NodeType::DEPTH24 || node.type == NodeType::GBUF_DEPTH32) + ? WGPUTextureAspect_DepthOnly + : WGPUTextureAspect_All; node.view = wgpuTextureCreateView(node.texture, &view_desc); FATAL_CHECK(node.view != nullptr, "Failed to create texture view\n"); diff --git a/src/gpu/sequence.h b/src/gpu/sequence.h index 51c8af1..ee0260d 100644 --- a/src/gpu/sequence.h +++ b/src/gpu/sequence.h @@ -19,9 +19,11 @@ enum class NodeType { DEPTH24, COMPUTE_F32, // G-buffer types for CNN v3 - GBUF_ALBEDO, // rgba16float: RENDER_ATTACHMENT | TEXTURE_BINDING | STORAGE_BINDING | COPY_SRC - GBUF_DEPTH32, // depth32float: RENDER_ATTACHMENT | TEXTURE_BINDING | COPY_SRC - GBUF_R8, // rgba8unorm (4ch for compat): STORAGE_BINDING | TEXTURE_BINDING | RENDER_ATTACHMENT + GBUF_ALBEDO, // rgba16float: RENDER_ATTACHMENT | TEXTURE_BINDING | + // STORAGE_BINDING | COPY_SRC + GBUF_DEPTH32, // depth32float: RENDER_ATTACHMENT | TEXTURE_BINDING | COPY_SRC + GBUF_R8, // rgba8unorm (4ch for compat): STORAGE_BINDING | TEXTURE_BINDING | + // RENDER_ATTACHMENT GBUF_RGBA32UINT, // rgba32uint: STORAGE_BINDING | TEXTURE_BINDING }; @@ -69,8 +71,12 @@ class NodeRegistry { void set_external_view(const std::string& name, WGPUTextureView view); - int default_width() const { return default_width_; } - int default_height() const { return default_height_; } + int default_width() const { + return default_width_; + } + int default_height() const { + return default_height_; + } private: WGPUDevice device_; diff --git a/src/gpu/texture_manager.cc b/src/gpu/texture_manager.cc index 20e215d..9e42841 100644 --- a/src/gpu/texture_manager.cc +++ b/src/gpu/texture_manager.cc @@ -285,10 +285,12 @@ void TextureManager::dispatch_compute(const std::string& func_name, wgpuTextureViewRelease(target_view); } -void TextureManager::create_gpu_procedural( - const std::string& name, const std::string& func_name, - const char* shader_code, const GpuProceduralParams& params, - const void* uniform_data, size_t uniform_size) { +void TextureManager::create_gpu_procedural(const std::string& name, + const std::string& func_name, + const char* shader_code, + const GpuProceduralParams& params, + const void* uniform_data, + size_t uniform_size) { get_or_create_compute_pipeline(func_name, shader_code, uniform_size); TextureWithView tv = gpu_create_storage_texture_2d( diff --git a/src/gpu/wgsl_effect.cc b/src/gpu/wgsl_effect.cc index 4f658a5..4c5f7e2 100644 --- a/src/gpu/wgsl_effect.cc +++ b/src/gpu/wgsl_effect.cc @@ -13,8 +13,7 @@ WgslEffect::WgslEffect(const GpuContext& ctx, WgslEffectParams initial_params, WgslSamplerType sampler_type) : Effect(ctx, inputs, outputs, start_time, end_time), - effect_params(initial_params), - load_op_(load_op) { + effect_params(initial_params), load_op_(load_op) { HEADLESS_RETURN_IF_NULL(ctx_.device); if (sampler_type == WgslSamplerType::Nearest) @@ -23,9 +22,8 @@ WgslEffect::WgslEffect(const GpuContext& ctx, create_linear_sampler(); params_buffer_.init(ctx_.device); - pipeline_.set(create_post_process_pipeline(ctx_.device, - WGPUTextureFormat_RGBA8Unorm, - shader_code)); + pipeline_.set(create_post_process_pipeline( + ctx_.device, WGPUTextureFormat_RGBA8Unorm, shader_code)); } void WgslEffect::render(WGPUCommandEncoder encoder, diff --git a/src/gpu/wgsl_effect.h b/src/gpu/wgsl_effect.h index f487ef7..49e97c5 100644 --- a/src/gpu/wgsl_effect.h +++ b/src/gpu/wgsl_effect.h @@ -11,12 +11,16 @@ // effect_params.p — 4 generic floats (strength, scale, etc.) // effect_params.c — color or secondary vec4 struct WgslEffectParams { - float p[4]; // vec4: generic float params - float c[4]; // vec4: color / secondary params + float p[4]; // vec4: generic float params + float c[4]; // vec4: color / secondary params }; -static_assert(sizeof(WgslEffectParams) == 32, "WgslEffectParams must be 32 bytes"); +static_assert(sizeof(WgslEffectParams) == 32, + "WgslEffectParams must be 32 bytes"); -enum class WgslSamplerType { Linear, Nearest }; +enum class WgslSamplerType { + Linear, + Nearest +}; class WgslEffect : public Effect { public: diff --git a/src/platform/stub_types.h b/src/platform/stub_types.h index 6cef8c7..850f5b8 100644 --- a/src/platform/stub_types.h +++ b/src/platform/stub_types.h @@ -163,5 +163,4 @@ static inline void platform_wgpu_wait_any(WGPUInstance) { #define WGPUOptionalBool_True true #define WGPUOptionalBool_False false - #endif // STRIP_EXTERNAL_LIBS diff --git a/src/procedural/generator.cc b/src/procedural/generator.cc index a2a383b..ee2dcc0 100644 --- a/src/procedural/generator.cc +++ b/src/procedural/generator.cc @@ -211,9 +211,18 @@ bool gen_plasma(uint8_t* buffer, int w, int h, const float* params, const float kTau = 6.2832f; const float kPhase = 2.0944f; // 2*pi/3 const int idx = (y * w + x) * 4; - buffer[idx + 0] = (uint8_t)(fminf(fmaxf(sinf(v * kTau) * 0.5f + 0.5f, 0.0f), 1.0f) * 255.0f); - buffer[idx + 1] = (uint8_t)(fminf(fmaxf(sinf(v * kTau + kPhase) * 0.5f + 0.5f, 0.0f), 1.0f) * 255.0f); - buffer[idx + 2] = (uint8_t)(fminf(fmaxf(sinf(v * kTau + 2.0f * kPhase) * 0.5f + 0.5f, 0.0f), 1.0f) * 255.0f); + buffer[idx + 0] = + (uint8_t)(fminf(fmaxf(sinf(v * kTau) * 0.5f + 0.5f, 0.0f), 1.0f) * + 255.0f); + buffer[idx + 1] = + (uint8_t)(fminf(fmaxf(sinf(v * kTau + kPhase) * 0.5f + 0.5f, 0.0f), + 1.0f) * + 255.0f); + buffer[idx + 2] = + (uint8_t)(fminf(fmaxf(sinf(v * kTau + 2.0f * kPhase) * 0.5f + 0.5f, + 0.0f), + 1.0f) * + 255.0f); buffer[idx + 3] = 255; } } @@ -247,15 +256,22 @@ bool gen_voronoi(uint8_t* buffer, int w, int h, const float* params, const float ddy = py - fy; const float dist2 = ddx * ddx + ddy * ddy; - if (dist2 < f1) { f2 = f1; f1 = dist2; } - else if (dist2 < f2) { f2 = dist2; } + if (dist2 < f1) { + f2 = f1; + f1 = dist2; + } else if (dist2 < f2) { + f2 = dist2; + } } } float value; - if (mode == 0) value = sqrtf(f1) * 1.5f; - else if (mode == 1) value = sqrtf(f2) * 1.2f; - else value = (sqrtf(f2) - sqrtf(f1)) * 3.0f; + if (mode == 0) + value = sqrtf(f1) * 1.5f; + else if (mode == 1) + value = sqrtf(f2) * 1.2f; + else + value = (sqrtf(f2) - sqrtf(f1)) * 3.0f; value = fminf(fmaxf(value, 0.0f), 1.0f); const uint8_t uval = (uint8_t)(value * 255.0f); @@ -305,7 +321,11 @@ bool gen_normalmap(uint8_t* buffer, int w, int h, const float* params, // Test-only: Failing generator bool gen_fail(uint8_t* buffer, int w, int h, const float* params, int num_params) { - (void)buffer; (void)w; (void)h; (void)params; (void)num_params; + (void)buffer; + (void)w; + (void)h; + (void)params; + (void)num_params; return false; } #endif diff --git a/src/tests/3d/test_3d_render.cc b/src/tests/3d/test_3d_render.cc index ef799ec..3a440be 100644 --- a/src/tests/3d/test_3d_render.cc +++ b/src/tests/3d/test_3d_render.cc @@ -105,7 +105,8 @@ bool gen_periodic_noise(uint8_t* buffer, int w, int h, const float* params, // Wrapper: fBm noise → normal map bool gen_fbm_normalmap(uint8_t* buffer, int w, int h, const float* params, int num_params) { - (void)params; (void)num_params; + (void)params; + (void)num_params; float fbm_params[] = {0.0f, 4.0f, 1.0f, 0.5f, 5.0f}; if (!procedural::gen_perlin(buffer, w, h, fbm_params, 5)) return false; @@ -140,7 +141,8 @@ int main(int argc, char** argv) { InitShaderComposer(); - g_renderer.set_direct_render(true); // Renders to surface, no post-process flip + g_renderer.set_direct_render( + true); // Renders to surface, no post-process flip g_renderer.init(g_device, g_queue, g_format); g_renderer.resize(platform_state.width, platform_state.height); diff --git a/src/tests/audio/test_fft.cc b/src/tests/audio/test_fft.cc index 2d47aa0..a34d203 100644 --- a/src/tests/audio/test_fft.cc +++ b/src/tests/audio/test_fft.cc @@ -39,7 +39,7 @@ static void idct_reference(const float* input, float* output, size_t N) { // Reference direct DFT matching fft_forward convention (e^{+j} sign). // fft_radix2 with direction=+1 computes X[k] = sum x[n] * e^{+j*2*pi*k*n/N}. static void dft_reference(const float* real_in, const float* imag_in, - float* real_out, float* imag_out, size_t N) { + float* real_out, float* imag_out, size_t N) { const float PI = 3.14159265358979323846f; for (size_t k = 0; k < N; k++) { real_out[k] = 0.0f; @@ -68,7 +68,8 @@ static bool arrays_match(const float* a, const float* b, size_t N, // Test B: fft_forward small N=4 — all 4 unit impulses vs direct DFT static void test_b_fft_radix2_small_n() { - printf("Test B: fft_forward N=4 (unit impulses vs direct DFT, tol=1e-5)...\n"); + printf( + "Test B: fft_forward N=4 (unit impulses vs direct DFT, tol=1e-5)...\n"); const size_t N = 4; const float tolerance = 1e-5f; @@ -117,8 +118,7 @@ static void test_c_twiddle_accumulation() { if (k >= 128 && k < 256) { const float wr_direct = cosf(angle * (float)k); const float wi_direct = sinf(angle * (float)k); - const float err = - fabsf(wr_iter - wr_direct) + fabsf(wi_iter - wi_direct); + const float err = fabsf(wr_iter - wr_direct) + fabsf(wi_iter - wi_direct); if (err > max_err) { max_err = err; max_err_k = k; @@ -129,9 +129,8 @@ static void test_c_twiddle_accumulation() { wi_iter = wr_old * wi_delta + wi_iter * wr_delta; } - printf( - " ✓ iterative twiddle drift at k=128..255: max_err=%.2e at k=%zu\n", - (double)max_err, max_err_k); + printf(" ✓ iterative twiddle drift at k=128..255: max_err=%.2e at k=%zu\n", + (double)max_err, max_err_k); printf(" ✓ fixed code uses cosf/sinf directly — no accumulation\n"); printf("Test C: PASSED ✓\n\n"); } @@ -279,7 +278,8 @@ static void test_idct_correctness() { assert(arrays_match(output_ref, output_fft, N)); printf(" ✓ Single bin test passed\n"); - // Mixed spectrum: IDCT→DCT round-trip (dct_fft and idct_fft are mutual inverses) + // Mixed spectrum: IDCT→DCT round-trip (dct_fft and idct_fft are mutual + // inverses) for (size_t i = 0; i < N; i++) { input[i] = sinf(i * 0.1f) * cosf(i * 0.05f) + cosf(i * 0.03f); } diff --git a/src/tests/gpu/test_cnn_v3_parity.cc b/src/tests/gpu/test_cnn_v3_parity.cc index 4fada5d..9663b09 100644 --- a/src/tests/gpu/test_cnn_v3_parity.cc +++ b/src/tests/gpu/test_cnn_v3_parity.cc @@ -4,10 +4,10 @@ // 2. Random-weight test: output must match Python-generated test vectors // (within 1/255 per pixel) +#include "../../cnn_v3/test_vectors.h" #include "../common/webgpu_test_fixture.h" #include "cnn_v3/src/cnn_v3_effect.h" #include "gpu/sequence.h" -#include "../../cnn_v3/test_vectors.h" #include <cassert> #include <cmath> @@ -20,37 +20,46 @@ static float fp16_bits_to_f32(uint16_t h) { uint32_t sign = (h & 0x8000u) << 16; - uint32_t exp = (h & 0x7C00u) >> 10; + uint32_t exp = (h & 0x7C00u) >> 10; uint32_t mant = (h & 0x03FFu); if (exp == 0 && mant == 0) { - float r; uint32_t b = sign; __builtin_memcpy(&r, &b, 4); return r; + float r; + uint32_t b = sign; + __builtin_memcpy(&r, &b, 4); + return r; } if (exp == 31) { uint32_t b = sign | 0x7F800000u | (mant << 13); - float r; __builtin_memcpy(&r, &b, 4); return r; + float r; + __builtin_memcpy(&r, &b, 4); + return r; } uint32_t b = sign | ((exp + 112) << 23) | (mant << 13); - float r; __builtin_memcpy(&r, &b, 4); return r; + float r; + __builtin_memcpy(&r, &b, 4); + return r; } // --------------------------------------------------------------------------- // Raw RGBA16Float readback → flat array of f32 (one per channel per pixel) // --------------------------------------------------------------------------- -struct MapState { bool done = false; WGPUMapAsyncStatus status; }; +struct MapState { + bool done = false; + WGPUMapAsyncStatus status; +}; static std::vector<float> readback_rgba16float(WGPUDevice device, - WGPUQueue queue, - WGPUTexture tex, - int W, int H) { - const uint32_t bytes_per_px = 8; // 4 × f16 - const uint32_t unaligned_bpr = (uint32_t)(W * bytes_per_px); - const uint32_t aligned_bpr = ((unaligned_bpr + 255u) / 256u) * 256u; - const size_t buf_size = aligned_bpr * (size_t)H; + WGPUQueue queue, WGPUTexture tex, + int W, int H) { + const uint32_t bytes_per_px = 8; // 4 × f16 + const uint32_t unaligned_bpr = (uint32_t)(W * bytes_per_px); + const uint32_t aligned_bpr = ((unaligned_bpr + 255u) / 256u) * 256u; + const size_t buf_size = aligned_bpr * (size_t)H; WGPUBufferDescriptor bd = {}; bd.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_MapRead; - bd.size = buf_size; + bd.size = buf_size; WGPUBuffer staging = wgpuDeviceCreateBuffer(device, &bd); WGPUCommandEncoder enc = wgpuDeviceCreateCommandEncoder(device, nullptr); @@ -58,9 +67,9 @@ static std::vector<float> readback_rgba16float(WGPUDevice device, src.texture = tex; WGPUTexelCopyBufferInfo dst = {}; dst.buffer = staging; - dst.layout.bytesPerRow = aligned_bpr; + dst.layout.bytesPerRow = aligned_bpr; dst.layout.rowsPerImage = (uint32_t)H; - WGPUExtent3D extent = { (uint32_t)W, (uint32_t)H, 1 }; + WGPUExtent3D extent = {(uint32_t)W, (uint32_t)H, 1}; wgpuCommandEncoderCopyTextureToBuffer(enc, &src, &dst, &extent); WGPUCommandBuffer cmds = wgpuCommandEncoderFinish(enc, nullptr); wgpuQueueSubmit(queue, 1, &cmds); @@ -73,7 +82,8 @@ static std::vector<float> readback_rgba16float(WGPUDevice device, mi.mode = WGPUCallbackMode_AllowProcessEvents; mi.callback = [](WGPUMapAsyncStatus s, WGPUStringView, void* u, void*) { auto* st = (MapState*)u; - st->status = s; st->done = true; + st->status = s; + st->done = true; }; mi.userdata1 = &ms; wgpuBufferMapAsync(staging, WGPUMapMode_Read, 0, buf_size, mi); @@ -82,16 +92,15 @@ static std::vector<float> readback_rgba16float(WGPUDevice device, std::vector<float> result(W * H * 4, 0.0f); if (ms.done && ms.status == WGPUMapAsyncStatus_Success) { - const uint8_t* mapped = (const uint8_t*)wgpuBufferGetConstMappedRange( - staging, 0, buf_size); + const uint8_t* mapped = + (const uint8_t*)wgpuBufferGetConstMappedRange(staging, 0, buf_size); if (mapped) { for (int y = 0; y < H; ++y) { const uint16_t* row = (const uint16_t*)(mapped + (size_t)y * aligned_bpr); for (int x = 0; x < W; ++x) { for (int c = 0; c < 4; ++c) { - result[(y * W + x) * 4 + c] = - fp16_bits_to_f32(row[x * 4 + c]); + result[(y * W + x) * 4 + c] = fp16_bits_to_f32(row[x * 4 + c]); } } } @@ -107,17 +116,17 @@ static std::vector<float> readback_rgba16float(WGPUDevice device, // --------------------------------------------------------------------------- static std::vector<float> readback_rgba32uint_8ch(WGPUDevice device, - WGPUQueue queue, - WGPUTexture tex, - int W, int H) { - const uint32_t bytes_per_px = 16; // 4 × u32 - const uint32_t unaligned_bpr = (uint32_t)(W * bytes_per_px); - const uint32_t aligned_bpr = ((unaligned_bpr + 255u) / 256u) * 256u; - const size_t buf_size = aligned_bpr * (size_t)H; + WGPUQueue queue, + WGPUTexture tex, int W, + int H) { + const uint32_t bytes_per_px = 16; // 4 × u32 + const uint32_t unaligned_bpr = (uint32_t)(W * bytes_per_px); + const uint32_t aligned_bpr = ((unaligned_bpr + 255u) / 256u) * 256u; + const size_t buf_size = aligned_bpr * (size_t)H; WGPUBufferDescriptor bd = {}; bd.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_MapRead; - bd.size = buf_size; + bd.size = buf_size; WGPUBuffer staging = wgpuDeviceCreateBuffer(device, &bd); WGPUCommandEncoder enc = wgpuDeviceCreateCommandEncoder(device, nullptr); @@ -125,9 +134,9 @@ static std::vector<float> readback_rgba32uint_8ch(WGPUDevice device, src.texture = tex; WGPUTexelCopyBufferInfo dst = {}; dst.buffer = staging; - dst.layout.bytesPerRow = aligned_bpr; + dst.layout.bytesPerRow = aligned_bpr; dst.layout.rowsPerImage = (uint32_t)H; - WGPUExtent3D extent = { (uint32_t)W, (uint32_t)H, 1 }; + WGPUExtent3D extent = {(uint32_t)W, (uint32_t)H, 1}; wgpuCommandEncoderCopyTextureToBuffer(enc, &src, &dst, &extent); WGPUCommandBuffer cmds = wgpuCommandEncoderFinish(enc, nullptr); wgpuQueueSubmit(queue, 1, &cmds); @@ -140,7 +149,8 @@ static std::vector<float> readback_rgba32uint_8ch(WGPUDevice device, mi.mode = WGPUCallbackMode_AllowProcessEvents; mi.callback = [](WGPUMapAsyncStatus s, WGPUStringView, void* u, void*) { auto* st = (MapState*)u; - st->status = s; st->done = true; + st->status = s; + st->done = true; }; mi.userdata1 = &ms; wgpuBufferMapAsync(staging, WGPUMapMode_Read, 0, buf_size, mi); @@ -149,8 +159,8 @@ static std::vector<float> readback_rgba32uint_8ch(WGPUDevice device, std::vector<float> result(W * H * 8, 0.0f); if (ms.done && ms.status == WGPUMapAsyncStatus_Success) { - const uint8_t* mapped = (const uint8_t*)wgpuBufferGetConstMappedRange( - staging, 0, buf_size); + const uint8_t* mapped = + (const uint8_t*)wgpuBufferGetConstMappedRange(staging, 0, buf_size); if (mapped) { for (int y = 0; y < H; ++y) { const uint32_t* row = @@ -178,31 +188,31 @@ static std::vector<float> readback_rgba32uint_8ch(WGPUDevice device, static WGPUTexture make_feat_tex(WGPUDevice dev, int W, int H) { WGPUTextureDescriptor d = {}; - d.format = WGPUTextureFormat_RGBA32Uint; - d.usage = WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst; - d.dimension = WGPUTextureDimension_2D; - d.size = { (uint32_t)W, (uint32_t)H, 1 }; + d.format = WGPUTextureFormat_RGBA32Uint; + d.usage = WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst; + d.dimension = WGPUTextureDimension_2D; + d.size = {(uint32_t)W, (uint32_t)H, 1}; d.mipLevelCount = 1; - d.sampleCount = 1; + d.sampleCount = 1; return wgpuDeviceCreateTexture(dev, &d); } static WGPUTexture make_output_tex(WGPUDevice dev, int W, int H) { WGPUTextureDescriptor d = {}; - d.format = WGPUTextureFormat_RGBA16Float; - d.usage = WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc; - d.dimension = WGPUTextureDimension_2D; - d.size = { (uint32_t)W, (uint32_t)H, 1 }; + d.format = WGPUTextureFormat_RGBA16Float; + d.usage = WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc; + d.dimension = WGPUTextureDimension_2D; + d.size = {(uint32_t)W, (uint32_t)H, 1}; d.mipLevelCount = 1; - d.sampleCount = 1; + d.sampleCount = 1; return wgpuDeviceCreateTexture(dev, &d); } static WGPUTextureView make_view(WGPUTexture tex, WGPUTextureFormat fmt) { WGPUTextureViewDescriptor d = {}; - d.format = fmt; - d.dimension = WGPUTextureViewDimension_2D; - d.mipLevelCount = 1; + d.format = fmt; + d.dimension = WGPUTextureViewDimension_2D; + d.mipLevelCount = 1; d.arrayLayerCount = 1; return wgpuTextureCreateView(tex, &d); } @@ -211,38 +221,36 @@ static WGPUTextureView make_view(WGPUTexture tex, WGPUTextureFormat fmt) { // Run one CNN v3 forward pass and return output pixels // --------------------------------------------------------------------------- -static std::vector<float> run_cnn_v3(WebGPUTestFixture& fixture, - int W, int H, - const uint32_t* feat0_u32, // W*H*4 - const uint32_t* feat1_u32, // W*H*4 - const uint32_t* weights_u32, // (TOTAL_F16+1)/2 - uint32_t weights_bytes, - std::vector<float>* enc0_out = nullptr, - std::vector<float>* dec1_out = nullptr) { +static std::vector<float> +run_cnn_v3(WebGPUTestFixture& fixture, int W, int H, + const uint32_t* feat0_u32, // W*H*4 + const uint32_t* feat1_u32, // W*H*4 + const uint32_t* weights_u32, // (TOTAL_F16+1)/2 + uint32_t weights_bytes, std::vector<float>* enc0_out = nullptr, + std::vector<float>* dec1_out = nullptr) { GpuContext ctx = fixture.ctx(); // Create input textures manually (with CopyDst for upload) WGPUTexture feat0_tex = make_feat_tex(ctx.device, W, H); WGPUTexture feat1_tex = make_feat_tex(ctx.device, W, H); - WGPUTexture out_tex = make_output_tex(ctx.device, W, H); + WGPUTexture out_tex = make_output_tex(ctx.device, W, H); WGPUTextureView feat0_view = make_view(feat0_tex, WGPUTextureFormat_RGBA32Uint); WGPUTextureView feat1_view = make_view(feat1_tex, WGPUTextureFormat_RGBA32Uint); - WGPUTextureView out_view = - make_view(out_tex, WGPUTextureFormat_RGBA16Float); + WGPUTextureView out_view = make_view(out_tex, WGPUTextureFormat_RGBA16Float); // Upload feat texture data auto upload_tex = [&](WGPUTexture tex, const uint32_t* data) { WGPUTexelCopyTextureInfo dst_tex = {}; dst_tex.texture = tex; WGPUTexelCopyBufferLayout layout = {}; - layout.bytesPerRow = (uint32_t)(W * 16); // 4 u32 per pixel + layout.bytesPerRow = (uint32_t)(W * 16); // 4 u32 per pixel layout.rowsPerImage = (uint32_t)H; - WGPUExtent3D ext = { (uint32_t)W, (uint32_t)H, 1 }; - wgpuQueueWriteTexture(ctx.queue, &dst_tex, data, - (size_t)(W * H * 16), &layout, &ext); + WGPUExtent3D ext = {(uint32_t)W, (uint32_t)H, 1}; + wgpuQueueWriteTexture(ctx.queue, &dst_tex, data, (size_t)(W * H * 16), + &layout, &ext); }; upload_tex(feat0_tex, feat0_u32); upload_tex(feat1_tex, feat1_u32); @@ -267,10 +275,9 @@ static std::vector<float> run_cnn_v3(WebGPUTestFixture& fixture, } // Run 5 compute passes - WGPUCommandEncoder enc = - wgpuDeviceCreateCommandEncoder(ctx.device, nullptr); + WGPUCommandEncoder enc = wgpuDeviceCreateCommandEncoder(ctx.device, nullptr); UniformsSequenceParams params = {}; - params.resolution = { (float)W, (float)H }; + params.resolution = {(float)W, (float)H}; params.aspect_ratio = 1.0f; effect.render(enc, params, registry); @@ -292,7 +299,8 @@ static std::vector<float> run_cnn_v3(WebGPUTestFixture& fixture, if (dec1_out) { // dec1 is rgba32uint, 8ch (pack2x16float), half-res WGPUTexture dec1_tex = registry.get_texture("cnn3_out_dec1"); - *dec1_out = readback_rgba32uint_8ch(ctx.device, ctx.queue, dec1_tex, W / 2, H / 2); + *dec1_out = + readback_rgba32uint_8ch(ctx.device, ctx.queue, dec1_tex, W / 2, H / 2); } // Cleanup @@ -326,9 +334,8 @@ static int test_zero_weights() { std::vector<uint32_t> feat0(W * H * 4, 0u); std::vector<uint32_t> feat1(W * H * 4, 0u); - auto pixels = run_cnn_v3(fixture, W, H, - feat0.data(), feat1.data(), - nullptr, 0); // null = zero weights (default) + auto pixels = run_cnn_v3(fixture, W, H, feat0.data(), feat1.data(), nullptr, + 0); // null = zero weights (default) // Expected: sigmoid(0) = 0.5 exactly const float expected = 0.5f; @@ -360,14 +367,12 @@ static int test_random_weights() { InitShaderComposer(); const int W = kCnnV3TestW, H = kCnnV3TestH; - const uint32_t weights_bytes = - (uint32_t)sizeof(kCnnV3TestWeightsU32); + const uint32_t weights_bytes = (uint32_t)sizeof(kCnnV3TestWeightsU32); std::vector<float> enc0_pixels, dec1_pixels; - auto pixels = run_cnn_v3(fixture, W, H, - kCnnV3TestFeat0U32, kCnnV3TestFeat1U32, - kCnnV3TestWeightsU32, weights_bytes, - &enc0_pixels, &dec1_pixels); + auto pixels = run_cnn_v3(fixture, W, H, kCnnV3TestFeat0U32, + kCnnV3TestFeat1U32, kCnnV3TestWeightsU32, + weights_bytes, &enc0_pixels, &dec1_pixels); // Check enc0 layer first (8ch, rgba32uint) const float tol = 1.0f / 255.0f; @@ -376,15 +381,18 @@ static int test_random_weights() { for (int i = 0; i < W * H * 8; ++i) { float ref = fp16_bits_to_f32(kCnnV3ExpectedEnc0U16[i]); float err = fabsf(enc0_pixels[i] - ref); - if (err > enc0_max_err) { enc0_max_err = err; enc0_worst = i; } + if (err > enc0_max_err) { + enc0_max_err = err; + enc0_worst = i; + } } bool enc0_ok = (enc0_max_err <= tol); if (!enc0_ok) { int px = enc0_worst / 8, ch = enc0_worst % 8; - fprintf(stderr, " ✗ enc0 mismatch: max_err=%.5f > %.5f at px=%d ch=%d" + fprintf(stderr, + " ✗ enc0 mismatch: max_err=%.5f > %.5f at px=%d ch=%d" " gpu=%.5f ref=%.5f\n", - enc0_max_err, tol, px, ch, - enc0_pixels[enc0_worst], + enc0_max_err, tol, px, ch, enc0_pixels[enc0_worst], fp16_bits_to_f32(kCnnV3ExpectedEnc0U16[enc0_worst])); } else { fprintf(stdout, " ✓ enc0: max_err=%.2e OK\n", enc0_max_err); @@ -397,15 +405,18 @@ static int test_random_weights() { for (int i = 0; i < dec1_n; ++i) { float ref = fp16_bits_to_f32(kCnnV3ExpectedDec1U16[i]); float err = fabsf(dec1_pixels[i] - ref); - if (err > dec1_max_err) { dec1_max_err = err; dec1_worst = i; } + if (err > dec1_max_err) { + dec1_max_err = err; + dec1_worst = i; + } } bool dec1_ok = (dec1_max_err <= tol); if (!dec1_ok) { int px = dec1_worst / 8, ch = dec1_worst % 8; - fprintf(stderr, " ✗ dec1 mismatch: max_err=%.5f > %.5f at px=%d ch=%d" + fprintf(stderr, + " ✗ dec1 mismatch: max_err=%.5f > %.5f at px=%d ch=%d" " gpu=%.5f ref=%.5f\n", - dec1_max_err, tol, px, ch, - dec1_pixels[dec1_worst], + dec1_max_err, tol, px, ch, dec1_pixels[dec1_worst], fp16_bits_to_f32(kCnnV3ExpectedDec1U16[dec1_worst])); } else { fprintf(stdout, " ✓ dec1: max_err=%.2e OK\n", dec1_max_err); @@ -418,16 +429,19 @@ static int test_random_weights() { for (int i = 0; i < n; ++i) { float ref = fp16_bits_to_f32(kCnnV3ExpectedOutputU16[i]); float err = fabsf(pixels[i] - ref); - if (err > max_err) { max_err = err; worst = i; } + if (err > max_err) { + max_err = err; + worst = i; + } } bool out_ok = (max_err <= tol); if (!out_ok) { int px = worst / 4, ch = worst % 4; - fprintf(stderr, " ✗ random_weights: max_err=%.5f > %.5f at px=%d ch=%d" + fprintf(stderr, + " ✗ random_weights: max_err=%.5f > %.5f at px=%d ch=%d" " gpu=%.5f ref=%.5f\n", - max_err, tol, px, ch, - pixels[worst], + max_err, tol, px, ch, pixels[worst], fp16_bits_to_f32(kCnnV3ExpectedOutputU16[worst])); } else { fprintf(stdout, " ✓ random_weights: max_err=%.2e OK\n", max_err); @@ -442,8 +456,10 @@ static int test_random_weights() { int main() { int pass = 0, total = 0; - ++total; pass += test_zero_weights(); - ++total; pass += test_random_weights(); + ++total; + pass += test_zero_weights(); + ++total; + pass += test_random_weights(); fprintf(stdout, "\nCNN v3 parity: %d/%d passed\n", pass, total); return (pass == total) ? 0 : 1; diff --git a/src/tests/gpu/test_demo_effects.cc b/src/tests/gpu/test_demo_effects.cc index 1bb89f9..fa1ac87 100644 --- a/src/tests/gpu/test_demo_effects.cc +++ b/src/tests/gpu/test_demo_effects.cc @@ -73,9 +73,9 @@ static void test_effects() { {"Scratch", std::make_shared<Scratch>( fixture.ctx(), std::vector<std::string>{"source"}, std::vector<std::string>{"sink"}, 0.0f, 1000.0f)}, - {"Ntsc", std::make_shared<Ntsc>( - fixture.ctx(), std::vector<std::string>{"source"}, - std::vector<std::string>{"sink"}, 0.0f, 1000.0f)}, + {"Ntsc", + std::make_shared<Ntsc>(fixture.ctx(), std::vector<std::string>{"source"}, + std::vector<std::string>{"sink"}, 0.0f, 1000.0f)}, {"NtscYiq", std::make_shared<NtscYiq>( fixture.ctx(), std::vector<std::string>{"source"}, std::vector<std::string>{"sink"}, 0.0f, 1000.0f)}, @@ -86,18 +86,15 @@ static void test_effects() { 1000.0f)}, {"CNNv3Effect", std::make_shared<CNNv3Effect>( - fixture.ctx(), - std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, + fixture.ctx(), std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, std::vector<std::string>{"cnn_v3_output"}, 0.0f, 1000.0f)}, {"GBufViewEffect", std::make_shared<GBufViewEffect>( - fixture.ctx(), - std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, + fixture.ctx(), std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, std::vector<std::string>{"gbuf_view_out"}, 0.0f, 1000.0f)}, {"GBufDeferredEffect", std::make_shared<GBufDeferredEffect>( - fixture.ctx(), - std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, + fixture.ctx(), std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, std::vector<std::string>{"gbuf_deferred_out"}, 0.0f, 1000.0f)}, }; diff --git a/src/tests/gpu/test_effect_base.cc b/src/tests/gpu/test_effect_base.cc index ad7bca3..57d0504 100644 --- a/src/tests/gpu/test_effect_base.cc +++ b/src/tests/gpu/test_effect_base.cc @@ -214,12 +214,15 @@ class WireDagTestEffect : public Effect { public: WireDagTestEffect(const GpuContext& ctx, std::vector<std::string> ins, std::vector<std::string> outs) - : Effect(ctx, std::move(ins), std::move(outs), 0.0f, 1000.0f) {} + : Effect(ctx, std::move(ins), std::move(outs), 0.0f, 1000.0f) { + } void render(WGPUCommandEncoder, const UniformsSequenceParams&, - NodeRegistry&) override {} + NodeRegistry&) override { + } - std::string call_find_downstream(const std::vector<EffectDAGNode>& dag) const { + std::string + call_find_downstream(const std::vector<EffectDAGNode>& dag) const { return find_downstream_output(dag); } @@ -239,12 +242,12 @@ static void test_find_downstream_output() { return; } - auto a = std::make_shared<WireDagTestEffect>( - fixture.ctx(), std::vector<std::string>{"src"}, - std::vector<std::string>{"mid"}); - auto b = std::make_shared<WireDagTestEffect>( - fixture.ctx(), std::vector<std::string>{"mid"}, - std::vector<std::string>{"out"}); + auto a = std::make_shared<WireDagTestEffect>(fixture.ctx(), + std::vector<std::string>{"src"}, + std::vector<std::string>{"mid"}); + auto b = std::make_shared<WireDagTestEffect>(fixture.ctx(), + std::vector<std::string>{"mid"}, + std::vector<std::string>{"out"}); auto c = std::make_shared<WireDagTestEffect>( fixture.ctx(), std::vector<std::string>{"out"}, std::vector<std::string>{"final"}); @@ -304,7 +307,8 @@ static void test_find_downstream_output() { a->wire_dag(dag_to_sink); assert(a->wired_to == "sink" && "base helper returns sink — caller must guard"); - fprintf(stdout, " ✓ sink downstream: find returns 'sink', caller must guard\n"); + fprintf(stdout, + " ✓ sink downstream: find returns 'sink', caller must guard\n"); } // Test 8: wire_dag called automatically by init_effect_nodes @@ -326,13 +330,12 @@ static void test_wire_dag_called_by_sequence() { class TestSequence : public Sequence { public: - TestSequence(const GpuContext& ctx, - std::shared_ptr<Effect> up, + TestSequence(const GpuContext& ctx, std::shared_ptr<Effect> up, std::shared_ptr<Effect> down) : Sequence(ctx, 256, 256) { - effect_dag_.push_back({up, {"source"}, {"mid"}, 0}); - effect_dag_.push_back({down, {"mid"}, {"sink"}, 1}); - init_effect_nodes(); // triggers wire_dag on both effects + effect_dag_.push_back({up, {"source"}, {"mid"}, 0}); + effect_dag_.push_back({down, {"mid"}, {"sink"}, 1}); + init_effect_nodes(); // triggers wire_dag on both effects } }; diff --git a/src/tests/gpu/test_shader_composer.cc b/src/tests/gpu/test_shader_composer.cc index 2f87e57..8d1f7c7 100644 --- a/src/tests/gpu/test_shader_composer.cc +++ b/src/tests/gpu/test_shader_composer.cc @@ -52,8 +52,7 @@ void test_asset_composition() { assert(snippet_a_code != nullptr); sc.RegisterSnippet("TEST_WGSL", std::string(snippet_a_code, snippet_a_size)); - std::string main_code = - "fn main() -> f32 { return test_wgsl(); }"; + std::string main_code = "fn main() -> f32 { return test_wgsl(); }"; std::string result = sc.Compose({"TEST_WGSL"}, main_code); assert(result.find("fn snippet_a()") != std::string::npos); diff --git a/src/tests/util/test_ans.cc b/src/tests/util/test_ans.cc index 108c46d..d8cc85c 100644 --- a/src/tests/util/test_ans.cc +++ b/src/tests/util/test_ans.cc @@ -15,8 +15,7 @@ namespace { bool RoundtripCheck(const std::vector<uint8_t>& input, - const uint32_t* initial_counts, - const char* label) { + const uint32_t* initial_counts, const char* label) { std::vector<uint8_t> compressed; if (!ans::Encode(input.data(), input.size(), &compressed, initial_counts)) { fprintf(stderr, "[%s] Encode failed\n", label); @@ -47,7 +46,8 @@ bool RoundtripCheck(const std::vector<uint8_t>& input, void TestRoundtripVariants() { std::mt19937 rng_uniform(12345); std::vector<uint8_t> random_uniform(64 * 1024); - for (auto& b : random_uniform) b = (uint8_t)(rng_uniform() & 0xff); + for (auto& b : random_uniform) + b = (uint8_t)(rng_uniform() & 0xff); std::mt19937 rng_skewed(67890); std::vector<uint8_t> random_skewed(32 * 1024); @@ -66,7 +66,7 @@ void TestRoundtripVariants() { " return textureSample(tex, smplr, uv);\n" "}\n"; std::vector<uint8_t> ascii_block; - for (int i = 0; i < 50; ++i) { // cross chunk boundary + for (int i = 0; i < 50; ++i) { // cross chunk boundary ascii_block.insert(ascii_block.end(), ascii, ascii + std::strlen(ascii)); } @@ -124,7 +124,8 @@ void TestRejection() { // 1) Mismatched models. { std::vector<uint8_t> v(4096); - for (auto& b : v) b = (uint8_t)('a' + (rng() % 26)); + for (auto& b : v) + b = (uint8_t)('a' + (rng() % 26)); uint32_t hist[256] = {}; ans::Histogram(v.data(), v.size(), hist); @@ -141,10 +142,11 @@ void TestRejection() { // 2) Corruption. { std::vector<uint8_t> v(2048); - for (auto& b : v) b = (uint8_t)(rng() & 0xff); + for (auto& b : v) + b = (uint8_t)(rng() & 0xff); std::vector<uint8_t> encoded; assert(ans::Encode(v.data(), v.size(), &encoded, nullptr)); - encoded[encoded.size() / 2] ^= 0x55; // flip a payload byte + encoded[encoded.size() / 2] ^= 0x55; // flip a payload byte std::vector<uint8_t> decoded(v.size()); size_t decoded_size = 0; @@ -156,7 +158,8 @@ void TestRejection() { // 3) Truncation. { std::vector<uint8_t> v(4096); - for (size_t i = 0; i < v.size(); ++i) v[i] = (uint8_t)i; + for (size_t i = 0; i < v.size(); ++i) + v[i] = (uint8_t)i; std::vector<uint8_t> encoded; assert(ans::Encode(v.data(), v.size(), &encoded, nullptr)); encoded.resize(encoded.size() - 8); @@ -173,11 +176,10 @@ void TestPeekSize() { std::vector<uint8_t> v(1234, 'Q'); std::vector<uint8_t> encoded; assert(ans::Encode(v.data(), v.size(), &encoded, nullptr)); - assert(ans::PeekUncompressedSize(encoded.data(), encoded.size()) == - v.size()); + assert(ans::PeekUncompressedSize(encoded.data(), encoded.size()) == v.size()); } -} // namespace +} // namespace int main() { TestRoundtripVariants(); diff --git a/src/tests/util/test_procedural.cc b/src/tests/util/test_procedural.cc index c6616ad..355f70c 100644 --- a/src/tests/util/test_procedural.cc +++ b/src/tests/util/test_procedural.cc @@ -165,7 +165,10 @@ void test_voronoi() { bool nonzero = false; for (size_t i = 0; i < buffer.size(); i += 4) { - if (buffer[i] > 0) { nonzero = true; break; } + if (buffer[i] > 0) { + nonzero = true; + break; + } } assert(nonzero); @@ -204,7 +207,10 @@ void test_normalmap() { // (non-flat normals expected) bool has_normal_variation = false; for (size_t i = 0; i < buffer.size(); i += 4) { - if (buffer[i] != 128) { has_normal_variation = true; break; } + if (buffer[i] != 128) { + has_normal_variation = true; + break; + } } assert(has_normal_variation); diff --git a/src/util/ans.cc b/src/util/ans.cc index aa79e4b..779ef81 100644 --- a/src/util/ans.cc +++ b/src/util/ans.cc @@ -58,8 +58,7 @@ struct Stats { // the slot. Increments the symbol's count on the fly. void decode_lookup(uint32_t s, uint8_t* sym, uint32_t* p, uint32_t* r) { // upper_bound(s) - 1; cumul is strictly non-decreasing. - const uint32_t* it = - std::upper_bound(cumul, cumul + kNumSymbols + 1, s); + const uint32_t* it = std::upper_bound(cumul, cumul + kNumSymbols + 1, s); const int c = (int)(it - cumul) - 1; stats[c] += 1; *sym = (uint8_t)c; @@ -97,27 +96,31 @@ inline void AppendU32BE(std::vector<uint8_t>* dst, uint32_t v) { } #endif -} // namespace +} // namespace uint32_t PeekUncompressedSize(const uint8_t* src, size_t src_size) { - if (!src || src_size < 4) return 0; + if (!src || src_size < 4) + return 0; return ReadU32BE(src); } -bool Decode(const uint8_t* src, size_t src_size, - uint8_t* dst, size_t dst_capacity, - size_t* out_size, +bool Decode(const uint8_t* src, size_t src_size, uint8_t* dst, + size_t dst_capacity, size_t* out_size, const uint32_t* initial_counts) { - if (out_size) *out_size = 0; - if (!src || src_size < 4) return false; + if (out_size) + *out_size = 0; + if (!src || src_size < 4) + return false; const uint8_t* p = src; const uint8_t* end = src + src_size; const uint32_t output_size = ReadU32BE(p); p += 4; - if (output_size > dst_capacity) return false; - if (output_size > 0 && !dst) return false; + if (output_size > dst_capacity) + return false; + if (output_size > 0 && !dst) + return false; Stats stats; stats.init(initial_counts); @@ -126,14 +129,16 @@ bool Decode(const uint8_t* src, size_t src_size, while (t < output_size) { const uint32_t chunk = std::min<uint32_t>(kChunkSize, output_size - t); - if (end - p < 4) return false; + if (end - p < 4) + return false; uint32_t s = ReadU32BE(p); p += 4; for (uint32_t i = 0; i < chunk; ++i) { if (s <= kMask) { // Pull in one renorm word. - if (end - p < 2) return false; + if (end - p < 2) + return false; s = (s << kBits) | (uint32_t)ReadU16BE(p); p += 2; } @@ -144,31 +149,37 @@ bool Decode(const uint8_t* src, size_t src_size, s = proba * (s >> kBits) + residual; } // Final-state sanity check: catches stream corruption and model mismatch. - if (s != kInitState) return false; + if (s != kInitState) + return false; stats.normalize(); t += chunk; } - if (out_size) *out_size = output_size; + if (out_size) + *out_size = output_size; return true; } #if defined(ANS_ENABLE_ENCODER) void Histogram(const uint8_t* src, size_t size, uint32_t* out_counts) { - if (!src || !out_counts) return; - for (size_t i = 0; i < size; ++i) out_counts[src[i]] += 1; + if (!src || !out_counts) + return; + for (size_t i = 0; i < size; ++i) + out_counts[src[i]] += 1; } -bool Encode(const uint8_t* src, size_t size, - std::vector<uint8_t>* dst, +bool Encode(const uint8_t* src, size_t size, std::vector<uint8_t>* dst, const uint32_t* initial_counts) { - if (!dst) return false; + if (!dst) + return false; dst->clear(); - if (size > 0xffffffffu) return false; // header is u32 + if (size > 0xffffffffu) + return false; // header is u32 AppendU32BE(dst, (uint32_t)size); - if (size == 0) return true; + if (size == 0) + return true; Stats stats; stats.init(initial_counts); @@ -200,9 +211,11 @@ bool Encode(const uint8_t* src, size_t size, } // Invariant: final state must be > kMask so the decoder's first read is // a valid renormalized state. - if (s <= kMask) return false; + if (s <= kMask) + return false; AppendU32BE(dst, s); - for (size_t k = pos; k < chunk; ++k) AppendU16BE(dst, tmp[k]); + for (size_t k = pos; k < chunk; ++k) + AppendU16BE(dst, tmp[k]); stats.normalize(); t += chunk; @@ -210,6 +223,6 @@ bool Encode(const uint8_t* src, size_t size, return true; } -#endif // ANS_ENABLE_ENCODER +#endif // ANS_ENABLE_ENCODER -} // namespace ans +} // namespace ans diff --git a/src/util/ans.h b/src/util/ans.h index 53c34b1..cf3d83a 100644 --- a/src/util/ans.h +++ b/src/util/ans.h @@ -34,25 +34,23 @@ uint32_t PeekUncompressedSize(const uint8_t* src, size_t src_size); // 'initial_counts' (256 entries) seeds the per-chunk adaptive model; pass // nullptr for the uniform default (all-ones). // Returns true on success and writes the decoded size to '*out_size'. -bool Decode(const uint8_t* src, size_t src_size, - uint8_t* dst, size_t dst_capacity, - size_t* out_size, +bool Decode(const uint8_t* src, size_t src_size, uint8_t* dst, + size_t dst_capacity, size_t* out_size, const uint32_t* initial_counts = nullptr); #if defined(ANS_ENABLE_ENCODER) // Encodes 'src[0..size]' into '*dst' (cleared and re-filled). // 'initial_counts' has the same semantics as in Decode(). // Returns true on success. -bool Encode(const uint8_t* src, size_t size, - std::vector<uint8_t>* dst, +bool Encode(const uint8_t* src, size_t size, std::vector<uint8_t>* dst, const uint32_t* initial_counts = nullptr); // Computes a byte histogram over 'src[0..size]', accumulating into // 'out_counts[256]' (caller must zero-initialize before the first call). // Useful for deriving a corpus-wide initial distribution from many files. void Histogram(const uint8_t* src, size_t size, uint32_t* out_counts); -#endif // ANS_ENABLE_ENCODER +#endif // ANS_ENABLE_ENCODER -} // namespace ans +} // namespace ans -#endif // ANS_H_ +#endif // ANS_H_ diff --git a/src/util/asset_manager.cc b/src/util/asset_manager.cc index 82c07be..aef67f3 100644 --- a/src/util/asset_manager.cc +++ b/src/util/asset_manager.cc @@ -120,7 +120,8 @@ const uint8_t* GetAsset(AssetId asset_id, size_t* out_size) { const size_t uncomp = source_record.uncompressed_size; uint8_t* buffer = new (std::nothrow) uint8_t[uncomp + 1]; CHECK_RETURN_BEGIN(!buffer, nullptr) - if (out_size) *out_size = 0; + if (out_size) + *out_size = 0; ERROR_MSG("Failed to allocate buffer for ANS-compressed asset id=%u", index); return nullptr; @@ -130,7 +131,8 @@ const uint8_t* GetAsset(AssetId asset_id, size_t* out_size) { &got, GetAnsAsciiHistogram()) || got != uncomp) { delete[] buffer; - if (out_size) *out_size = 0; + if (out_size) + *out_size = 0; ERROR_MSG("ANS decode failed for asset id=%u", index); return nullptr; } @@ -139,7 +141,8 @@ const uint8_t* GetAsset(AssetId asset_id, size_t* out_size) { cached_record.size = uncomp; cached_record.uncompressed_size = uncomp; g_asset_cache[index] = cached_record; - if (out_size) *out_size = uncomp; + if (out_size) + *out_size = uncomp; return buffer; } @@ -279,9 +282,8 @@ bool ReloadAssetsFromFile(const char* config_path) { const AssetRecord& e = g_asset_cache[i]; if (e.data && (e.type == AssetType::PROC || e.type == AssetType::PROC_GPU || - e.compression != AssetCompression::NONE || - e.type == AssetType::SPEC || e.type == AssetType::MP3 || - e.type == AssetType::WGSL)) { + e.compression != AssetCompression::NONE || e.type == AssetType::SPEC || + e.type == AssetType::MP3 || e.type == AssetType::WGSL)) { delete[] e.data; } g_asset_cache[i] = {}; diff --git a/src/util/mini_math.h b/src/util/mini_math.h index 0aa66a3..c386134 100644 --- a/src/util/mini_math.h +++ b/src/util/mini_math.h @@ -229,7 +229,7 @@ struct mat4 { mat4 r = {}; float t = 1.0f / std::tan(fov * 0.5f); r.m[0] = t / asp; - r.m[5] = -t; // Negate Y: post-process chain samples textures Y-flipped + r.m[5] = -t; // Negate Y: post-process chain samples textures Y-flipped r.m[10] = f / (n - f); r.m[11] = -1; r.m[14] = (n * f) / (n - f); diff --git a/tools/asset_packer.cc b/tools/asset_packer.cc index 6162f19..4b7e9dd 100644 --- a/tools/asset_packer.cc +++ b/tools/asset_packer.cc @@ -350,12 +350,14 @@ static bool ProcessImageFile(const std::string& full_path, // Returns false (without populating *out) if encoding fails, the compressed // payload is not smaller, or the round-trip mismatches. static bool TryAnsCompress(const std::vector<uint8_t>& raw, - const uint32_t* hist, - std::vector<uint8_t>* out) { - if (raw.empty()) return false; + const uint32_t* hist, std::vector<uint8_t>* out) { + if (raw.empty()) + return false; std::vector<uint8_t> enc; - if (!ans::Encode(raw.data(), raw.size(), &enc, hist)) return false; - if (enc.size() >= raw.size()) return false; + if (!ans::Encode(raw.data(), raw.size(), &enc, hist)) + return false; + if (enc.size() >= raw.size()) + return false; std::vector<uint8_t> verify(raw.size()); size_t got = 0; if (!ans::Decode(enc.data(), enc.size(), verify.data(), verify.size(), &got, @@ -373,9 +375,11 @@ static bool TryAnsCompress(const std::vector<uint8_t>& raw, template <typename T, typename FormatFn> static void EmitArrayInit(FILE* f, const T* data, size_t n, FormatFn fmt) { for (size_t i = 0; i < n; ++i) { - if (i % 12 == 0) fprintf(f, "\n "); + if (i % 12 == 0) + fprintf(f, "\n "); fmt(f, data[i]); - if (i + 1 != n) fprintf(f, ", "); + if (i + 1 != n) + fprintf(f, ", "); } fprintf(f, "\n"); } @@ -531,12 +535,15 @@ int main(int argc, char* argv[]) { uint32_t ans_ascii_hist[256] = {}; if (!disk_load_mode) { for (const auto& info : asset_build_infos) { - if (info.asset_type != "WGSL") continue; + if (info.asset_type != "WGSL") + continue; std::string base_dir = assets_txt_path.substr(0, assets_txt_path.find_last_of("/\\") + 1); - std::filesystem::path p = std::filesystem::absolute(base_dir) / info.filename; + std::filesystem::path p = + std::filesystem::absolute(base_dir) / info.filename; std::ifstream f(p.lexically_normal().string(), std::ios::binary); - if (!f.is_open()) continue; + if (!f.is_open()) + continue; std::vector<uint8_t> buf((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>()); ans::Histogram(buf.data(), buf.size(), ans_ascii_hist); @@ -551,7 +558,8 @@ int main(int argc, char* argv[]) { [](FILE* f, uint32_t v) { fprintf(f, "%u", v); }); fprintf(assets_data_cc_file, "};\n"); fprintf(assets_data_cc_file, - "const uint32_t* GetAnsAsciiHistogram() { return kAnsAsciiHistogram; }\n\n"); + "const uint32_t* GetAnsAsciiHistogram() { return kAnsAsciiHistogram; " + "}\n\n"); for (auto& info : asset_build_infos) { if (info.asset_type != "PROC" && info.asset_type != "PROC_GPU") { @@ -585,8 +593,7 @@ int main(int argc, char* argv[]) { fprintf(stderr, "Warning: Asset file not found, skipping: %s (%s)\n", info.name.c_str(), full_path.c_str()); - fprintf(assets_data_cc_file, - "const size_t ASSET_SIZE_%s = 0;\n", + fprintf(assets_data_cc_file, "const size_t ASSET_SIZE_%s = 0;\n", info.name.c_str()); fprintf(assets_data_cc_file, "alignas(16) static const uint8_t %s[] = {0};\n", @@ -613,13 +620,12 @@ int main(int argc, char* argv[]) { original_size, compressed.size(), (double)compressed.size() / (double)original_size); } else { - buffer.push_back(0); // null-terminate raw assets + buffer.push_back(0); // null-terminate raw assets } const std::vector<uint8_t>& payload = use_ans ? compressed : buffer; fprintf(assets_data_cc_file, "const size_t ASSET_SIZE_%s = %zu;\n", - info.name.c_str(), - use_ans ? payload.size() : original_size); + info.name.c_str(), use_ans ? payload.size() : original_size); fprintf(assets_data_cc_file, "alignas(16) static const uint8_t %s[] = {", info.data_array_name.c_str()); diff --git a/tools/cnn_test.cc b/tools/cnn_test.cc index beeef8f..a707723 100644 --- a/tools/cnn_test.cc +++ b/tools/cnn_test.cc @@ -33,10 +33,12 @@ static uint16_t f32_to_f16(float f) { uint32_t b; memcpy(&b, &f, 4); uint32_t sign = (b >> 16) & 0x8000u; - int32_t exp = (int32_t)((b >> 23) & 0xFFu) - 127 + 15; + int32_t exp = (int32_t)((b >> 23) & 0xFFu) - 127 + 15; uint32_t mant = b & 0x7FFFFFu; - if (exp <= 0) return (uint16_t)sign; - if (exp >= 31) return (uint16_t)(sign | 0x7C00u); + if (exp <= 0) + return (uint16_t)sign; + if (exp >= 31) + return (uint16_t)(sign | 0x7C00u); return (uint16_t)(sign | ((uint32_t)exp << 10) | (mant >> 13)); } @@ -49,8 +51,10 @@ static uint32_t pack2x16f(float a, float b) { static uint32_t pack4x8u(float a, float b, float c, float d) { auto u8 = [](float v) -> uint32_t { int i = (int)(v * 255.0f + 0.5f); - if (i < 0) i = 0; - if (i > 255) i = 255; + if (i < 0) + i = 0; + if (i > 255) + i = 255; return (uint32_t)i; }; return u8(a) | (u8(b) << 8) | (u8(c) << 16) | (u8(d) << 24); @@ -60,8 +64,8 @@ static uint32_t pack4x8u(float a, float b, float c, float d) { // Oct-decode [0,1] → unit normal (matches Python cnn_v3_utils.oct_decode) // --------------------------------------------------------------------------- -static void oct_decode_01(float nx01, float ny01, - float* out_x, float* out_y, float* out_z) { +static void oct_decode_01(float nx01, float ny01, float* out_x, float* out_y, + float* out_z) { float fx = nx01 * 2.0f - 1.0f; float fy = ny01 * 2.0f - 1.0f; float fz = 1.0f - fabsf(fx) - fabsf(fy); @@ -71,8 +75,9 @@ static void oct_decode_01(float nx01, float ny01, fx = (1.0f - fabsf(fy)) * sx; fy = (1.0f - fabsf(fx)) * sy; } - float len = sqrtf(fx*fx + fy*fy + fz*fz); - if (len < 1e-8f) len = 1e-8f; + float len = sqrtf(fx * fx + fy * fy + fz * fz); + if (len < 1e-8f) + len = 1e-8f; *out_x = fx / len; *out_y = fy / len; *out_z = fz / len; @@ -89,8 +94,8 @@ static void oct_decode_01(float nx01, float ny01, // Output: mip1_out and mip2_out are (H*W*3) float arrays in row-major order. static void compute_mips(const float* rgb, int w, int h, - std::vector<float>& mip1_out, - std::vector<float>& mip2_out) { + std::vector<float>& mip1_out, + std::vector<float>& mip2_out) { const int w2 = w / 2, h2 = h / 2; const int w4 = w / 4, h4 = h / 4; @@ -99,10 +104,9 @@ static void compute_mips(const float* rgb, int w, int h, for (int x2 = 0; x2 < w2; ++x2) { for (int c = 0; c < 3; ++c) { int y0 = y2 * 2, x0 = x2 * 2; - float v = rgb[(y0 * w + x0 ) * 3 + c] - + rgb[(y0 * w + x0+1) * 3 + c] - + rgb[((y0+1) * w + x0 ) * 3 + c] - + rgb[((y0+1) * w + x0+1) * 3 + c]; + float v = rgb[(y0 * w + x0) * 3 + c] + rgb[(y0 * w + x0 + 1) * 3 + c] + + rgb[((y0 + 1) * w + x0) * 3 + c] + + rgb[((y0 + 1) * w + x0 + 1) * 3 + c]; m1[(y2 * w2 + x2) * 3 + c] = v * 0.25f; } } @@ -113,10 +117,9 @@ static void compute_mips(const float* rgb, int w, int h, for (int x4 = 0; x4 < w4; ++x4) { for (int c = 0; c < 3; ++c) { int y0 = y4 * 2, x0 = x4 * 2; - float v = m1[(y0 * w2 + x0 ) * 3 + c] - + m1[(y0 * w2 + x0+1) * 3 + c] - + m1[((y0+1) * w2 + x0 ) * 3 + c] - + m1[((y0+1) * w2 + x0+1) * 3 + c]; + float v = m1[(y0 * w2 + x0) * 3 + c] + m1[(y0 * w2 + x0 + 1) * 3 + c] + + m1[((y0 + 1) * w2 + x0) * 3 + c] + + m1[((y0 + 1) * w2 + x0 + 1) * 3 + c]; m2[(y4 * w4 + x4) * 3 + c] = v * 0.25f; } } @@ -128,14 +131,14 @@ static void compute_mips(const float* rgb, int w, int h, for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { int i = (y * w + x) * 3; - int i1 = ((y/2) * w2 + (x/2)) * 3; - int i2 = ((y/4) * w4 + (x/4)) * 3; - mip1_out[i ] = (y/2 < h2 && x/2 < w2) ? m1[i1 ] : 0.0f; - mip1_out[i+1] = (y/2 < h2 && x/2 < w2) ? m1[i1+1] : 0.0f; - mip1_out[i+2] = (y/2 < h2 && x/2 < w2) ? m1[i1+2] : 0.0f; - mip2_out[i ] = (y/4 < h4 && x/4 < w4) ? m2[i2 ] : 0.0f; - mip2_out[i+1] = (y/4 < h4 && x/4 < w4) ? m2[i2+1] : 0.0f; - mip2_out[i+2] = (y/4 < h4 && x/4 < w4) ? m2[i2+2] : 0.0f; + int i1 = ((y / 2) * w2 + (x / 2)) * 3; + int i2 = ((y / 4) * w4 + (x / 4)) * 3; + mip1_out[i] = (y / 2 < h2 && x / 2 < w2) ? m1[i1] : 0.0f; + mip1_out[i + 1] = (y / 2 < h2 && x / 2 < w2) ? m1[i1 + 1] : 0.0f; + mip1_out[i + 2] = (y / 2 < h2 && x / 2 < w2) ? m1[i1 + 2] : 0.0f; + mip2_out[i] = (y / 4 < h4 && x / 4 < w4) ? m2[i2] : 0.0f; + mip2_out[i + 1] = (y / 4 < h4 && x / 4 < w4) ? m2[i2 + 1] : 0.0f; + mip2_out[i + 2] = (y / 4 < h4 && x / 4 < w4) ? m2[i2 + 2] : 0.0f; } } } @@ -161,17 +164,17 @@ static void compute_mips(const float* rgb, int w, int h, struct FeatureImages { int w, h; - std::vector<float> albedo; // w*h*3 [0,1] - std::vector<float> normal; // w*h*2 [0,1] oct-encoded - std::vector<float> depth; // w*h [0,1] - std::vector<float> matid; // w*h [0,1] - std::vector<float> shadow; // w*h [0,1] - std::vector<float> transp; // w*h [0,1] + std::vector<float> albedo; // w*h*3 [0,1] + std::vector<float> normal; // w*h*2 [0,1] oct-encoded + std::vector<float> depth; // w*h [0,1] + std::vector<float> matid; // w*h [0,1] + std::vector<float> shadow; // w*h [0,1] + std::vector<float> transp; // w*h [0,1] }; static void pack_features(const FeatureImages& img, - std::vector<uint32_t>& feat0, // w*h*4 u32 - std::vector<uint32_t>& feat1) // w*h*4 u32 + std::vector<uint32_t>& feat0, // w*h*4 u32 + std::vector<uint32_t>& feat1) // w*h*4 u32 { const int W = img.w, H = img.h; feat0.resize(W * H * 4); @@ -184,49 +187,49 @@ static void pack_features(const FeatureImages& img, for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { - const int pi = y * W + x; - const int i3 = pi * 3; - const int i4 = pi * 4; + const int pi = y * W + x; + const int i3 = pi * 3; + const int i4 = pi * 4; - float ar = img.albedo[i3 ]; - float ag = img.albedo[i3+1]; - float ab = img.albedo[i3+2]; + float ar = img.albedo[i3]; + float ag = img.albedo[i3 + 1]; + float ab = img.albedo[i3 + 2]; - float nx = img.normal[pi * 2 ]; // [0,1] - float ny = img.normal[pi * 2 + 1]; // [0,1] + float nx = img.normal[pi * 2]; // [0,1] + float ny = img.normal[pi * 2 + 1]; // [0,1] float d = img.depth[pi]; // Central finite difference depth gradient - int xm = (x > 0) ? x-1 : 0; - int xp = (x < W-1) ? x+1 : W-1; - int ym = (y > 0) ? y-1 : 0; - int yp = (y < H-1) ? y+1 : H-1; - float dzdx = (img.depth[y * W + xp] - img.depth[y * W + xm]) * 0.5f; - float dzdy = (img.depth[yp * W + x ] - img.depth[ym * W + x ]) * 0.5f; + int xm = (x > 0) ? x - 1 : 0; + int xp = (x < W - 1) ? x + 1 : W - 1; + int ym = (y > 0) ? y - 1 : 0; + int yp = (y < H - 1) ? y + 1 : H - 1; + float dzdx = (img.depth[y * W + xp] - img.depth[y * W + xm]) * 0.5f; + float dzdy = (img.depth[yp * W + x] - img.depth[ym * W + x]) * 0.5f; - float mat = img.matid[pi]; + float mat = img.matid[pi]; float shad = img.shadow[pi]; - float trp = img.transp[pi]; + float trp = img.transp[pi]; // Diffuse = max(0, dot(oct_decode(normal), KEY_LIGHT)) * shadow float n3x, n3y, n3z; oct_decode_01(nx, ny, &n3x, &n3y, &n3z); - float dif = fmaxf(0.0f, n3x*KEY_X + n3y*KEY_Y + n3z*KEY_Z) * shad; + float dif = fmaxf(0.0f, n3x * KEY_X + n3y * KEY_Y + n3z * KEY_Z) * shad; - float m1r = mip1[i3 ], m1g = mip1[i3+1], m1b = mip1[i3+2]; - float m2r = mip2[i3 ], m2g = mip2[i3+1], m2b = mip2[i3+2]; + float m1r = mip1[i3], m1g = mip1[i3 + 1], m1b = mip1[i3 + 2]; + float m2r = mip2[i3], m2g = mip2[i3 + 1], m2b = mip2[i3 + 2]; // prev.rgb = 0 (no temporal history) - feat0[i4 ] = pack2x16f(ar, ag); - feat0[i4+1] = pack2x16f(ab, nx); - feat0[i4+2] = pack2x16f(ny, d ); - feat0[i4+3] = pack2x16f(dzdx, dzdy); + feat0[i4] = pack2x16f(ar, ag); + feat0[i4 + 1] = pack2x16f(ab, nx); + feat0[i4 + 2] = pack2x16f(ny, d); + feat0[i4 + 3] = pack2x16f(dzdx, dzdy); - feat1[i4 ] = pack4x8u(mat, 0.0f, 0.0f, 0.0f); // mat_id, prev.rgb=0 - feat1[i4+1] = pack4x8u(m1r, m1g, m1b, m2r); - feat1[i4+2] = pack4x8u(m2g, m2b, dif, trp); - feat1[i4+3] = 0u; + feat1[i4] = pack4x8u(mat, 0.0f, 0.0f, 0.0f); // mat_id, prev.rgb=0 + feat1[i4 + 1] = pack4x8u(m1r, m1g, m1b, m2r); + feat1[i4 + 2] = pack4x8u(m2g, m2b, dif, trp); + feat1[i4 + 3] = 0u; } } } @@ -237,41 +240,41 @@ static void pack_features(const FeatureImages& img, static WGPUTexture make_feat_tex(WGPUDevice dev, int W, int H) { WGPUTextureDescriptor d = {}; - d.format = WGPUTextureFormat_RGBA32Uint; - d.usage = WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst; - d.dimension = WGPUTextureDimension_2D; - d.size = {(uint32_t)W, (uint32_t)H, 1}; + d.format = WGPUTextureFormat_RGBA32Uint; + d.usage = WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst; + d.dimension = WGPUTextureDimension_2D; + d.size = {(uint32_t)W, (uint32_t)H, 1}; d.mipLevelCount = 1; - d.sampleCount = 1; + d.sampleCount = 1; return wgpuDeviceCreateTexture(dev, &d); } static WGPUTexture make_output_tex(WGPUDevice dev, int W, int H) { WGPUTextureDescriptor d = {}; - d.format = WGPUTextureFormat_RGBA16Float; - d.usage = WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc; - d.dimension = WGPUTextureDimension_2D; - d.size = {(uint32_t)W, (uint32_t)H, 1}; + d.format = WGPUTextureFormat_RGBA16Float; + d.usage = WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc; + d.dimension = WGPUTextureDimension_2D; + d.size = {(uint32_t)W, (uint32_t)H, 1}; d.mipLevelCount = 1; - d.sampleCount = 1; + d.sampleCount = 1; return wgpuDeviceCreateTexture(dev, &d); } static WGPUTextureView make_view(WGPUTexture tex, WGPUTextureFormat fmt) { WGPUTextureViewDescriptor d = {}; - d.format = fmt; - d.dimension = WGPUTextureViewDimension_2D; - d.mipLevelCount = 1; + d.format = fmt; + d.dimension = WGPUTextureViewDimension_2D; + d.mipLevelCount = 1; d.arrayLayerCount = 1; return wgpuTextureCreateView(tex, &d); } -static void upload_tex(WGPUQueue queue, WGPUTexture tex, - const uint32_t* data, int W, int H) { +static void upload_tex(WGPUQueue queue, WGPUTexture tex, const uint32_t* data, + int W, int H) { WGPUTexelCopyTextureInfo dst = {}; dst.texture = tex; WGPUTexelCopyBufferLayout layout = {}; - layout.bytesPerRow = (uint32_t)(W * 16); + layout.bytesPerRow = (uint32_t)(W * 16); layout.rowsPerImage = (uint32_t)H; WGPUExtent3D ext = {(uint32_t)W, (uint32_t)H, 1}; wgpuQueueWriteTexture(queue, &dst, data, (size_t)(W * H * 16), &layout, &ext); @@ -281,37 +284,53 @@ static void upload_tex(WGPUQueue queue, WGPUTexture tex, // RGBA16Float readback // --------------------------------------------------------------------------- -static uint16_t fp16_bits_to_f16(float f) { return f32_to_f16(f); } +static uint16_t fp16_bits_to_f16(float f) { + return f32_to_f16(f); +} static float fp16_bits_to_f32(uint16_t h) { uint32_t sign = (uint32_t)(h & 0x8000u) << 16; - uint32_t exp = (h & 0x7C00u) >> 10; + uint32_t exp = (h & 0x7C00u) >> 10; uint32_t mant = h & 0x03FFu; - if (exp == 0 && mant == 0) { float r; memcpy(&r, &sign, 4); return r; } - if (exp == 31) { uint32_t b = sign | 0x7F800000u | (mant << 13); - float r; memcpy(&r, &b, 4); return r; } + if (exp == 0 && mant == 0) { + float r; + memcpy(&r, &sign, 4); + return r; + } + if (exp == 31) { + uint32_t b = sign | 0x7F800000u | (mant << 13); + float r; + memcpy(&r, &b, 4); + return r; + } uint32_t b = sign | ((exp + 112u) << 23) | (mant << 13); - float r; memcpy(&r, &b, 4); return r; + float r; + memcpy(&r, &b, 4); + return r; } -struct MapState { bool done = false; WGPUMapAsyncStatus status = {}; }; +struct MapState { + bool done = false; + WGPUMapAsyncStatus status = {}; +}; static std::vector<float> readback_rgba16f(WGPUDevice device, WGPUQueue queue, - WGPUTexture tex, int W, int H) { - const uint32_t bytes_per_px = 8; - const uint32_t raw_bpr = (uint32_t)(W * bytes_per_px); - const uint32_t aligned_bpr = ((raw_bpr + 255u) / 256u) * 256u; - const size_t buf_size = (size_t)aligned_bpr * (size_t)H; + WGPUTexture tex, int W, int H) { + const uint32_t bytes_per_px = 8; + const uint32_t raw_bpr = (uint32_t)(W * bytes_per_px); + const uint32_t aligned_bpr = ((raw_bpr + 255u) / 256u) * 256u; + const size_t buf_size = (size_t)aligned_bpr * (size_t)H; WGPUBufferDescriptor bd = {}; bd.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_MapRead; - bd.size = buf_size; + bd.size = buf_size; WGPUBuffer staging = wgpuDeviceCreateBuffer(device, &bd); WGPUCommandEncoder enc = wgpuDeviceCreateCommandEncoder(device, nullptr); - WGPUTexelCopyTextureInfo src = {}; src.texture = tex; - WGPUTexelCopyBufferInfo dst = {}; - dst.buffer = staging; - dst.layout.bytesPerRow = aligned_bpr; + WGPUTexelCopyTextureInfo src = {}; + src.texture = tex; + WGPUTexelCopyBufferInfo dst = {}; + dst.buffer = staging; + dst.layout.bytesPerRow = aligned_bpr; dst.layout.rowsPerImage = (uint32_t)H; WGPUExtent3D ext = {(uint32_t)W, (uint32_t)H, 1}; wgpuCommandEncoderCopyTextureToBuffer(enc, &src, &dst, &ext); @@ -323,9 +342,11 @@ static std::vector<float> readback_rgba16f(WGPUDevice device, WGPUQueue queue, MapState ms = {}; WGPUBufferMapCallbackInfo mi = {}; - mi.mode = WGPUCallbackMode_AllowProcessEvents; + mi.mode = WGPUCallbackMode_AllowProcessEvents; mi.callback = [](WGPUMapAsyncStatus s, WGPUStringView, void* u, void*) { - auto* st = (MapState*)u; st->status = s; st->done = true; + auto* st = (MapState*)u; + st->status = s; + st->done = true; }; mi.userdata1 = &ms; wgpuBufferMapAsync(staging, WGPUMapMode_Read, 0, buf_size, mi); @@ -334,11 +355,12 @@ static std::vector<float> readback_rgba16f(WGPUDevice device, WGPUQueue queue, std::vector<float> pixels(W * H * 4, 0.0f); if (ms.done && ms.status == WGPUMapAsyncStatus_Success) { - const uint8_t* mapped = (const uint8_t*) - wgpuBufferGetConstMappedRange(staging, 0, buf_size); + const uint8_t* mapped = + (const uint8_t*)wgpuBufferGetConstMappedRange(staging, 0, buf_size); if (mapped) { for (int y = 0; y < H; ++y) { - const uint16_t* row = (const uint16_t*)(mapped + (size_t)y * aligned_bpr); + const uint16_t* row = + (const uint16_t*)(mapped + (size_t)y * aligned_bpr); for (int x = 0; x < W; ++x) { for (int c = 0; c < 4; ++c) pixels[(y * W + x) * 4 + c] = fp16_bits_to_f32(row[x * 4 + c]); @@ -355,14 +377,16 @@ static std::vector<float> readback_rgba16f(WGPUDevice device, WGPUQueue queue, // Image I/O helpers // --------------------------------------------------------------------------- -static std::vector<float> load_png_rgb(const char* path, int* out_w, int* out_h) { +static std::vector<float> load_png_rgb(const char* path, int* out_w, + int* out_h) { int w, h, ch; uint8_t* data = stbi_load(path, &w, &h, &ch, 3); if (!data) { fprintf(stderr, "Error: cannot load '%s'\n", path); return {}; } - *out_w = w; *out_h = h; + *out_w = w; + *out_h = h; std::vector<float> out(w * h * 3); for (int i = 0; i < w * h * 3; ++i) out[i] = data[i] / 255.0f; @@ -375,14 +399,16 @@ static std::vector<float> load_png_rg(const char* path, int ew, int eh) { int w, h, ch; uint8_t* data = stbi_load(path, &w, &h, &ch, 3); if (!data || w != ew || h != eh) { - if (data) stbi_image_free(data); - fprintf(stderr, "Warning: cannot load normal '%s' — using (0.5,0.5)\n", path); + if (data) + stbi_image_free(data); + fprintf(stderr, "Warning: cannot load normal '%s' — using (0.5,0.5)\n", + path); std::vector<float> def(ew * eh * 2, 0.5f); return def; } std::vector<float> out(w * h * 2); for (int i = 0; i < w * h; ++i) { - out[i * 2 ] = data[i * 3 ] / 255.0f; + out[i * 2] = data[i * 3] / 255.0f; out[i * 2 + 1] = data[i * 3 + 1] / 255.0f; } stbi_image_free(data); @@ -394,7 +420,8 @@ static std::vector<float> load_png_depth16(const char* path, int ew, int eh) { int w, h, ch; uint16_t* data = stbi_load_16(path, &w, &h, &ch, 1); if (!data || w != ew || h != eh) { - if (data) stbi_image_free(data); + if (data) + stbi_image_free(data); fprintf(stderr, "Warning: cannot load depth '%s' — using 0\n", path); return std::vector<float>(ew * eh, 0.0f); } @@ -407,11 +434,12 @@ static std::vector<float> load_png_depth16(const char* path, int ew, int eh) { // Load 8-bit greyscale PNG → [0,1] static std::vector<float> load_png_gray(const char* path, int ew, int eh, - float default_val = 0.0f) { + float default_val = 0.0f) { int w, h, ch; uint8_t* data = stbi_load(path, &w, &h, &ch, 1); if (!data || w != ew || h != eh) { - if (data) stbi_image_free(data); + if (data) + stbi_image_free(data); return std::vector<float>(ew * eh, default_val); } std::vector<float> out(w * h); @@ -468,29 +496,37 @@ static bool load_weights_bin(const char* path, std::vector<uint32_t>& out) { // --------------------------------------------------------------------------- struct Args { - const char* input_path = nullptr; - const char* output_path = nullptr; - const char* sample_dir = nullptr; + const char* input_path = nullptr; + const char* output_path = nullptr; + const char* sample_dir = nullptr; const char* weights_path = nullptr; - bool debug_hex = false; + bool debug_hex = false; }; static void print_usage(const char* prog) { fprintf(stderr, "Usage: %s input.png output.png [OPTIONS]\n", prog); fprintf(stderr, "\nOPTIONS:\n"); - fprintf(stderr, " --sample-dir DIR Full sample dir with albedo/normal/depth/matid/shadow/transp\n"); - fprintf(stderr, " --weights FILE Load weights from cnn_v3_weights.bin\n"); + fprintf(stderr, + " --sample-dir DIR Full sample dir with " + "albedo/normal/depth/matid/shadow/transp\n"); + fprintf(stderr, + " --weights FILE Load weights from cnn_v3_weights.bin\n"); fprintf(stderr, " --debug-hex Print first 8 output pixels as hex\n"); fprintf(stderr, " --help Show this help\n"); - fprintf(stderr, "\nSimple mode (single PNG): geometry channels zeroed, normal=(0.5,0.5).\n"); + fprintf(stderr, + "\nSimple mode (single PNG): geometry channels zeroed, " + "normal=(0.5,0.5).\n"); fprintf(stderr, "FiLM is always identity (gamma=1, beta=0).\n"); - fprintf(stderr, "\nNote: feature packing uses [0,1] oct-normals (training format) to match\n"); + fprintf(stderr, + "\nNote: feature packing uses [0,1] oct-normals (training format) to " + "match\n"); fprintf(stderr, " infer_cnn_v3.py for direct Python/WGSL comparison.\n"); } static bool parse_args(int argc, char** argv, Args* args) { - if (argc < 3) return false; - args->input_path = argv[1]; + if (argc < 3) + return false; + args->input_path = argv[1]; args->output_path = argv[2]; for (int i = 3; i < argc; ++i) { if (strcmp(argv[i], "--sample-dir") == 0 && i + 1 < argc) { @@ -535,7 +571,8 @@ int main(int argc, char** argv) { // --- Load input image --- int W, H; std::vector<float> albedo = load_png_rgb(args.input_path, &W, &H); - if (albedo.empty()) return 1; + if (albedo.empty()) + return 1; // Pad to multiples of 4 (U-Net requires 2 pooling levels) const int W4 = (W + 3) & ~3; @@ -548,14 +585,16 @@ int main(int argc, char** argv) { for (int c = 0; c < 3; ++c) padded[(y * W4 + x) * 3 + c] = albedo[(y * W + x) * 3 + c]; albedo = std::move(padded); - W = W4; H = H4; + W = W4; + H = H4; } printf("Input: %s (%dx%d)\n", args.input_path, W, H); // --- Build FeatureImages --- FeatureImages img; - img.w = W; img.h = H; + img.w = W; + img.h = H; img.albedo = albedo; if (args.sample_dir) { @@ -564,8 +603,8 @@ int main(int argc, char** argv) { return std::string(args.sample_dir) + "/" + name; }; img.normal = load_png_rg(path("normal.png").c_str(), W, H); - img.depth = load_png_depth16(path("depth.png").c_str(), W, H); - img.matid = load_png_gray(path("matid.png").c_str(), W, H, 0.0f); + img.depth = load_png_depth16(path("depth.png").c_str(), W, H); + img.matid = load_png_gray(path("matid.png").c_str(), W, H, 0.0f); img.shadow = load_png_gray(path("shadow.png").c_str(), W, H, 1.0f); img.transp = load_png_gray(path("transp.png").c_str(), W, H, 0.0f); } else { @@ -584,11 +623,13 @@ int main(int argc, char** argv) { // --- Create GPU textures --- WGPUTexture feat0_tex = make_feat_tex(ctx.device, W, H); WGPUTexture feat1_tex = make_feat_tex(ctx.device, W, H); - WGPUTexture out_tex = make_output_tex(ctx.device, W, H); + WGPUTexture out_tex = make_output_tex(ctx.device, W, H); - WGPUTextureView feat0_view = make_view(feat0_tex, WGPUTextureFormat_RGBA32Uint); - WGPUTextureView feat1_view = make_view(feat1_tex, WGPUTextureFormat_RGBA32Uint); - WGPUTextureView out_view = make_view(out_tex, WGPUTextureFormat_RGBA16Float); + WGPUTextureView feat0_view = + make_view(feat0_tex, WGPUTextureFormat_RGBA32Uint); + WGPUTextureView feat1_view = + make_view(feat1_tex, WGPUTextureFormat_RGBA32Uint); + WGPUTextureView out_view = make_view(out_tex, WGPUTextureFormat_RGBA16Float); upload_tex(ctx.queue, feat0_tex, feat0.data(), W, H); upload_tex(ctx.queue, feat1_tex, feat1.data(), W, H); @@ -605,7 +646,8 @@ int main(int argc, char** argv) { // --- Load weights --- if (args.weights_path) { std::vector<uint32_t> wdata; - if (!load_weights_bin(args.weights_path, wdata)) return 1; + if (!load_weights_bin(args.weights_path, wdata)) + return 1; effect.upload_weights(ctx.queue, wdata.data(), (uint32_t)(wdata.size() * 4)); printf("Weights: %s (%zu bytes)\n", args.weights_path, wdata.size() * 4); @@ -616,7 +658,7 @@ int main(int argc, char** argv) { // --- Run 5 compute passes --- WGPUCommandEncoder enc = wgpuDeviceCreateCommandEncoder(ctx.device, nullptr); UniformsSequenceParams params = {}; - params.resolution = {(float)W, (float)H}; + params.resolution = {(float)W, (float)H}; params.aspect_ratio = (float)W / (float)H; effect.render(enc, params, registry); @@ -627,23 +669,27 @@ int main(int argc, char** argv) { wgpuDevicePoll(ctx.device, true, nullptr); // --- Readback --- - std::vector<float> pixels = readback_rgba16f(ctx.device, ctx.queue, out_tex, W, H); + std::vector<float> pixels = + readback_rgba16f(ctx.device, ctx.queue, out_tex, W, H); // --- Save output (crop to original size, already same if no padding) --- - if (!save_png(args.output_path, pixels, W, H)) return 1; + if (!save_png(args.output_path, pixels, W, H)) + return 1; printf("Saved: %s\n", args.output_path); if (args.debug_hex) { printf("First 8 output pixels (RGBA f32 → hex):\n"); for (int i = 0; i < 8 && i < W * H; ++i) { - float r = pixels[i*4 ], g = pixels[i*4+1]; - float b = pixels[i*4+2], a = pixels[i*4+3]; - int ri = (int)(r*255+.5f), gi = (int)(g*255+.5f); - int bi = (int)(b*255+.5f), ai = (int)(a*255+.5f); - ri = ri<0?0:ri>255?255:ri; gi = gi<0?0:gi>255?255:gi; - bi = bi<0?0:bi>255?255:bi; ai = ai<0?0:ai>255?255:ai; - printf(" [%d] 0x%02X%02X%02X%02X (%.4f %.4f %.4f %.4f)\n", - i, ri, gi, bi, ai, r, g, b, a); + float r = pixels[i * 4], g = pixels[i * 4 + 1]; + float b = pixels[i * 4 + 2], a = pixels[i * 4 + 3]; + int ri = (int)(r * 255 + .5f), gi = (int)(g * 255 + .5f); + int bi = (int)(b * 255 + .5f), ai = (int)(a * 255 + .5f); + ri = ri < 0 ? 0 : ri > 255 ? 255 : ri; + gi = gi < 0 ? 0 : gi > 255 ? 255 : gi; + bi = bi < 0 ? 0 : bi > 255 ? 255 : bi; + ai = ai < 0 ? 0 : ai > 255 ? 255 : ai; + printf(" [%d] 0x%02X%02X%02X%02X (%.4f %.4f %.4f %.4f)\n", i, ri, gi, + bi, ai, r, g, b, a); } } |
