igneum/proto-newpow/mma-shadow/gen_block.py
igneum-labs a664af6fc9 Horizon: lane 8 (new-proof-of-work) lands: three schemes, two prototypes measured on rented 4090s
docs/analysis/horizon/new-pow.md sections 0 to 9: scheme A (mining is proving) never, on bytes,
the verifier and sampleability; scheme B (the tensor-shaped integer shadow) prototyped as
proto-newpow/mma-shadow and measured, never as class content on the energy reading, with the R8
two-output correction; scheme C (proof of stored state, sd1: the daily dataset derived from the
execution state) prototyped as proto-newpow/state-dataset, measured on the GPU and the box's
CPU, and put forward as the class v5 candidate with its spec items and the Devnet 2 gate. The
lane's standing rule: a shadow lever only works through joules the honest card is forced to
spend, so shadow work goes where the GPU is least efficient per op. Chip rows in
sim/horizon/new-pow/chip_rows.py by the chip-model-v3 method. Rented box addresses replaced by
placeholders in the READMEs and the run script.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 20:18:39 +00:00

75 lines
3.2 KiB
Python

#!/usr/bin/env python3
# gen_block.py: draws the mm8 block table for the mx8+mm8xR prototype and writes mm8_block.h.
# Stream: SplitMix64 seeded with FNV-1a-64 of the bytes "igneum-mm8/igneum-genesis".
# Per step k: a = below(8); b = below(7), b += (b >= a); c = below(8); c2 = below(7), c2 += (c2 >= c).
# Step semantics: r[c] += C[l >> 2][2 * (l & 3)] (PTX d0), r[c2] += C[l >> 2][2 * (l & 3) + 1] (PTX d1), both mod 2^32.
import sys
MASK64 = (1 << 64) - 1
R_MAX = 512
def fnv1a64(data: bytes) -> int:
h = 0xcbf29ce484222325
for byte in data:
h ^= byte
h = (h * 0x100000001b3) & MASK64
return h
class SplitMix64:
def __init__(self, seed: int):
self.s = seed & MASK64
def next(self) -> int:
self.s = (self.s + 0x9E3779B97F4A7C15) & MASK64
z = self.s
z = ((z ^ (z >> 30)) * 0xBF58476D1CE4E5B9) & MASK64
z = ((z ^ (z >> 27)) * 0x94D049BB133111EB) & MASK64
return z ^ (z >> 31)
def below(self, n: int) -> int:
return self.next() % n
def main():
seed_text = b"igneum-mm8/igneum-genesis"
seed = fnv1a64(seed_text)
rng = SplitMix64(seed)
rows = []
for k in range(R_MAX):
a = rng.below(8)
b = rng.below(7)
b += 1 if b >= a else 0
c = rng.below(8)
c2 = rng.below(7)
c2 += 1 if c2 >= c else 0
assert a != b and 0 <= b < 8 and c != c2 and 0 <= c2 < 8
rows.append((a, b, c, c2))
out = []
out.append("// Generated by gen_block.py. mm8 block draws for class mx8+mm8xR, seed text \"%s\"," % seed_text.decode())
out.append("// FNV-1a-64 seed 0x%016x, SplitMix64 stream. Step k uses (a, b, c, c2) = row k: r[c] += d0, r[c2] += d1. Do not edit by hand." % seed)
out.append("#pragma once")
out.append("#ifdef __cplusplus")
out.append("#include <cstdint>")
out.append("#else")
out.append("#include <stdint.h>")
out.append("#endif")
out.append("#define IGNEUM_MM8_R_MAX %d" % R_MAX)
out.append("#define IGNEUM_MM8_SEED 0x%016xull" % seed)
out.append("// Packed uint16: a = v & 7, b = (v >> 3) & 7, c = (v >> 6) & 7, c2 = (v >> 9) & 7.")
out.append("#define IGNEUM_MM8_TABLE_INIT { \\")
for i in range(0, R_MAX, 16):
chunk = rows[i:i+16]
vals = ["0x%03xu" % (a | (b << 3) | (c << 6) | (c2 << 9)) for (a, b, c, c2) in chunk]
out.append(" " + ", ".join(vals) + (", \\" if i + 16 < R_MAX else " }"))
out.append("// X-macro list: X(k, a, b, c, c2) for every step k in 0..R_MAX-1. The kernel guards each with k < IGNEUM_MM8_R,")
out.append("// so the register indices are compile-time constants (r[] stays in registers, no local memory).")
out.append("#define IGNEUM_MM8_STEPS(X) \\")
for k, (a, b, c, c2) in enumerate(rows):
out.append(" X(%d, %d, %d, %d, %d)%s" % (k, a, b, c, c2, " \\" if k + 1 < R_MAX else ""))
out.append("// Readable form, step: a b c c2")
for k, (a, b, c, c2) in enumerate(rows):
out.append("// %3d: %d %d %d %d" % (k, a, b, c, c2))
path = sys.argv[1] if len(sys.argv) > 1 else "mm8_block.h"
with open(path, "w") as f:
f.write("\n".join(out) + "\n")
print("seed 0x%016x, %d steps, first 4: %s -> %s" % (seed, R_MAX, rows[:4], path))
if __name__ == "__main__":
main()