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>
75 lines
3.2 KiB
Python
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()
|