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>
36 lines
2.2 KiB
Python
36 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Chip rows for the Horizon new-pow lane (scheme B, the tensor-shaped shadow), by the chip-model-v3 section 5 method.
|
|
|
|
Usage:
|
|
python3 chip_rows.py --card-uj <microjoules per hash of the honest card at R=0> \
|
|
--card-uj-r <microjoules per hash at the measured R> --r <R> \
|
|
[--mem-uj 0.466] [--k 1.0 0.5 0.3]
|
|
|
|
Model (docs/analysis/chip-model-v3.md 5.4 and docs/analysis/latency-shadow-2026-10-06.md 6):
|
|
chip energy per hash = memory system energy (f = 1 chip: 0.466 uJ GDDR7, 0.321 uJ one HBM3 stack)
|
|
+ block energy on the chip = (card block energy) x k
|
|
card block energy = card_uj_r - card_uj (the measured marginal of the block on the honest card)
|
|
gain per joule = card_uj_r / chip_uj
|
|
Every chip figure is arithmetic on cited figures and approximate; the card figures are measured and named in the lane file.
|
|
"""
|
|
import argparse
|
|
|
|
p = argparse.ArgumentParser()
|
|
p.add_argument("--card-uj", type=float, required=True, help="honest card microjoules per hash at R = 0 (measured)")
|
|
p.add_argument("--card-uj-r", type=float, required=True, help="honest card microjoules per hash at the measured R")
|
|
p.add_argument("--r", type=int, required=True, help="mm8 steps per iteration (8 R per hash)")
|
|
p.add_argument("--mem-uj", type=float, nargs="+", default=[0.466, 0.321], help="f = 1 chip memory energy per hash, uJ (GDDR7, HBM3 one stack)")
|
|
p.add_argument("--k", type=float, nargs="+", default=[1.0, 0.5, 0.3], help="chip block energy per op over the card's")
|
|
a = p.parse_args()
|
|
|
|
block = a.card_uj_r - a.card_uj
|
|
macs = 8 * a.r * 1024
|
|
print(f"R = {a.r}: {8*a.r} mm8 per hash, {macs} multiply-adds per hash")
|
|
print(f"card: {a.card_uj:.3f} uJ at R = 0, {a.card_uj_r:.3f} uJ at R = {a.r}; block {block:.3f} uJ = {block*1e6/macs if macs else 0:.3f} pJ per multiply-add")
|
|
print("| memory | k | chip uJ per hash | gain per joule (card over chip) | gain at R = 0 for comparison |")
|
|
print("|---|---|---|---|---|")
|
|
names = ["GDDR7 (16 devices)", "HBM3 (one stack)", "HBM3 (eight stacks)"]
|
|
for i, m in enumerate(a.mem_uj):
|
|
for k in a.k:
|
|
chip = m + block * k
|
|
print(f"| {names[i] if i < len(names) else m} | {k} | {chip:.3f} | {a.card_uj_r/chip:.2f}x | {a.card_uj/m:.2f}x |")
|