Research-Stack/4-Infrastructure/shim/q16_lut_vcn.py
Brandon Schneider 53e38e4c71 feat: 12 math enhancements — Q16 LUT, braid VCN encoder, FPGA Verilog, FFT, crypto
Pipeline:
- q16_lut_vcn.py: Q16_16 LUT generation + VCN frame encoding (8 ops)
- braid_vcn_encoder.py: Delta+RLE → RS ECC → ChaCha20 → VCN → MKV
- braid_search.py: Sidon set slots, soliton search, QUBO optimization
- test_braid_pipeline.py: 67 tests covering full round-trip

WebGPU/Scripts:
- braid_fft.wgsl: Cooley-Tukey radix-2 FFT on phase vectors
- reed_solomon_vcn.py: Reed-Solomon ECC for VCN frame data
- chacha20_braid.py: ChaCha20 encryption + key derivation
- polynomial_commitment.py: KZG scheme for receipt verification

Lean:
- BraidBitwiseODE.lean: XOR crossing, O(1) integration, 2 proved theorems

FPGA (Tang Nano 9K):
- q16_lut_core.v: 8-op arithmetic, 2-stage pipeline, BRAM reciprocal
- braid_crossing_core.v: 4-stage crossing residual, 7 Q16 instances
- Testbenches with edge cases + VCD dumps
2026-05-28 14:49:26 -05:00

256 lines
8.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Q16_16 Lookup Table VCN Encoder
Generates Q16_16 lookup tables for arithmetic operations (add/sub/mul/div/
max/min/neg/abs), encodes each LUT as a VCN YUV420 frame via the existing
vcn_compute_substrate infrastructure, and provides round-trip decode.
The full Q16_16 range is 2^32 values, but we discretize into 65536 entries
per operation (sampling every 65536-th input or using a 256×256 grid for
two-operand ops) so the LUT fits a single VCN frame.
Usage:
python3 q16_lut_vcn.py gen_add 1080p -> writes add_lut.mkv
"""
from __future__ import annotations
import struct
import math
import hashlib
from pathlib import Path
from typing import Dict, List, Tuple, Optional
# Local imports same directory
import sys as _sys
_sys.path.insert(0, str(Path(__file__).resolve().parent))
from vcn_compute_substrate import (
VCNComputeFrameSpec, VCN_RESOLUTIONS, SIGNATURE_HEADER, SIGNATURE_SIZE,
compute_frame_size, create_frame_dynamic, encode_frames_hardware,
)
# ── Constants ────────────────────────────────────────────────────────────────
Q16_ONE = 0x00010000 # 1.0 in Q16_16
Q16_MASK = 0xFFFFFFFF
LUT_ENTRIES = 65536 # 256 × 256 grid for two-operand ops
GRID_SIDE = 256 # sample every 256-th value along each axis
SAMPLE_STRIDE = Q16_ONE // GRID_SIDE # 256
SUPPORTED_OPS = ("add", "sub", "mul", "div", "max", "min", "neg", "abs")
# ── Q16_16 arithmetic (integer-only, no float in compute paths) ─────────────
def _q16_add(a: int, b: int) -> int:
return (a + b) & Q16_MASK
def _q16_sub(a: int, b: int) -> int:
return (a - b) & Q16_MASK
def _q16_mul(a: int, b: int) -> int:
"""Saturating Q16_16 multiply."""
sa = a if a < 0x80000000 else a - 0x100000000
sb = b if b < 0x80000000 else b - 0x100000000
result = (sa * sb) >> 16
# Clamp to Q16_16 range
if result > 0x7FFFFFFF:
return 0x7FFFFFFF
if result < -0x80000000:
return 0x80000000
return result & Q16_MASK
def _q16_div(a: int, b: int) -> int:
"""Saturating Q16_16 divide."""
if b == 0:
return 0x7FFFFFFF # saturate
sa = a if a < 0x80000000 else a - 0x100000000
sb = b if b < 0x80000000 else b - 0x100000000
result = (sa << 16) // sb
if result > 0x7FFFFFFF:
return 0x7FFFFFFF
if result < -0x80000000:
return 0x80000000
return result & Q16_MASK
def _q16_max(a: int, b: int) -> int:
sa = a if a < 0x80000000 else a - 0x100000000
sb = b if b < 0x80000000 else b - 0x100000000
return (sa if sa >= sb else sb) & Q16_MASK
def _q16_min(a: int, b: int) -> int:
sa = a if a < 0x80000000 else a - 0x100000000
sb = b if b < 0x80000000 else b - 0x100000000
return (sa if sa <= sb else sb) & Q16_MASK
def _q16_neg(a: int) -> int:
return (-a) & Q16_MASK
def _q16_abs(a: int) -> int:
sa = a if a < 0x80000000 else a - 0x100000000
return (sa if sa >= 0 else -sa) & Q16_MASK
# Two-operand dispatch table
_TWO_OP = {
"add": _q16_add,
"sub": _q16_sub,
"mul": _q16_mul,
"div": _q16_div,
"max": _q16_max,
"min": _q16_min,
}
# Single-operand dispatch table
_ONE_OP = {
"neg": _q16_neg,
"abs": _q16_abs,
}
# ── LUT generation ───────────────────────────────────────────────────────────
def generate_lut(operation: str) -> List[int]:
"""Generate 65536-entry LUT for *operation*.
For two-operand ops we build a 256×256 grid: entry[i*256+j] = op(i*stride, j*stride).
For single-operand ops we store op(i*stride) for i in 0..65535.
Returns a list of 65536 unsigned 32-bit Q16_16 results.
"""
if operation not in SUPPORTED_OPS:
raise ValueError(f"Unsupported operation '{operation}'. Choose from {SUPPORTED_OPS}")
table: List[int] = [0] * LUT_ENTRIES
if operation in _TWO_OP:
fn = _TWO_OP[operation]
for i in range(GRID_SIDE):
a = (i * SAMPLE_STRIDE) & Q16_MASK
for j in range(GRID_SIDE):
b = (j * SAMPLE_STRIDE) & Q16_MASK
table[i * GRID_SIDE + j] = fn(a, b)
else:
fn = _ONE_OP[operation]
for i in range(LUT_ENTRIES):
val = (i * (Q16_ONE // LUT_ENTRIES * LUT_ENTRIES if LUT_ENTRIES < Q16_ONE else 1)) & Q16_MASK
# For single-operand, map index to Q16 value
val = (i * (Q16_MASK // LUT_ENTRIES + 1)) & Q16_MASK
table[i] = fn(val)
return table
def serialize_lut(table: List[int]) -> bytes:
"""Serialize LUT to bytes (65536 × 4 = 256 KiB)."""
return struct.pack(f"<{LUT_ENTRIES}I", *table)
def deserialize_lut(data: bytes) -> List[int]:
"""Deserialize bytes back to LUT."""
return list(struct.unpack(f"<{LUT_ENTRIES}I", data[:LUT_ENTRIES * 4]))
def lut_checksum(table: List[int]) -> str:
"""SHA-256 hex digest of the serialized LUT."""
return hashlib.sha256(serialize_lut(table)).hexdigest()
# ── VCN frame encode / decode ───────────────────────────────────────────────
def encode_q16_lut_frame(operation: str, resolution: str = "1080p") -> bytes:
"""Generate a Q16_16 LUT for *operation* and encode it as a VCN YUV420 frame.
The frame payload is: [4-byte op tag][32-byte SHA-256][256 KiB LUT data]
Returns raw YUV420 frame bytes.
"""
table = generate_lut(operation)
payload = serialize_lut(table)
# Prepend operation tag + checksum for validation on decode
op_tag = operation.encode("ascii").ljust(4, b"\x00")[:4]
checksum = hashlib.sha256(payload).digest() # 32 bytes
frame_data = op_tag + checksum + payload # 4 + 32 + 262144 = 262180 bytes
w, h = VCN_RESOLUTIONS.get(resolution, VCN_RESOLUTIONS["1080p"])
spec = VCNComputeFrameSpec(
width=w, height=h,
bytes_per_frame=compute_frame_size(w, h, "yuv420p"),
encoder="libx264",
)
return create_frame_dynamic(frame_data, seq=0, spec=spec)
def decode_q16_lut_frame(frame_bytes: bytes, operation: str) -> Dict:
"""Decode a VCN YUV420 frame back to a Q16_16 LUT.
Parses the frame payload, validates the SHA-256 checksum, and returns:
{
"operation": str,
"entries": List[int], # 65536 Q16_16 values
"checksum_valid": bool,
"checksum": str, # hex
}
"""
# Strip signature header (first SIGNATURE_SIZE bytes)
payload = frame_bytes[SIGNATURE_SIZE:]
# Parse header
op_tag = payload[:4].rstrip(b"\x00").decode("ascii")
stored_checksum = payload[4:36] # 32 bytes
lut_data = payload[36:36 + LUT_ENTRIES * 4]
table = deserialize_lut(lut_data)
computed_checksum = hashlib.sha256(lut_data).digest()
valid = computed_checksum == stored_checksum
return {
"operation": op_tag if op_tag else operation,
"entries": table,
"checksum_valid": valid,
"checksum": computed_checksum.hex(),
}
def encode_q16_lut_to_mkv(operation: str, output_path: str | Path,
resolution: str = "1080p") -> Path:
"""Full pipeline: generate LUT → VCN frame → hardware encode to MKV."""
output_path = Path(output_path)
frame = encode_q16_lut_frame(operation, resolution)
w, h = VCN_RESOLUTIONS.get(resolution, VCN_RESOLUTIONS["1080p"])
spec = VCNComputeFrameSpec(
width=w, height=h,
bytes_per_frame=compute_frame_size(w, h, "yuv420p"),
encoder="libx264",
)
result = encode_frames_hardware([frame], output_path, spec)
if result.returncode != 0:
raise RuntimeError(f"VCN encode failed: {result.stderr}")
return output_path
# ── CLI entry-point ──────────────────────────────────────────────────────────
def main():
import sys
if len(sys.argv) < 3:
print("Usage: q16_lut_vcn.py <operation> <resolution>")
print(f" operations: {SUPPORTED_OPS}")
print(" resolution: 240p .. 16K")
sys.exit(1)
op = sys.argv[1]
res = sys.argv[2] if len(sys.argv) > 2 else "1080p"
print(f"Generating Q16_16 LUT for '{op}' ...")
table = generate_lut(op)
print(f" LUT size: {len(table)} entries, checksum: {lut_checksum(table)}")
out = encode_q16_lut_to_mkv(op, Path(f"{op}_lut.mkv"), res)
print(f" Written to {out}")
if __name__ == "__main__":
main()