Counter ASIC 3.0 gates (hash): follow-up 1 on the program-id fix (e05eb0c merged): crate suite 97 of 97, the seven v4 packs re-exported byte-identical (generator 4, id c120d7963abdcd96), fingerprints unchanged on Metal and Apple OpenCL, Mac G2 16 x 1,024 of 1,024 through the v4 class token, the harness 4 of 4 on the class and on the era with the id assert_ne holding; the job scripts take the class token from the pack

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-06 16:38:48 +00:00
parent 5db43eda30
commit 43664184ed
4 changed files with 91 additions and 5 deletions

View file

@ -0,0 +1,65 @@
{
"pass": true,
"gate": "follow-up 1: G3 and the fingerprints on the program-id fix (ca3-v4-node 7c22d0d merged as 5314771)",
"checks": {
"crate_suite_97_of_97_on_the_merged_tree": true,
"seven_v4_packs_re_exported_byte_identical_to_the_tree": true,
"v4_packs_generator_4_class_v4_id_c120d7963abdcd96": true,
"v3_control_keeps_id_73bcbfe8ccf988f1": true,
"fingerprints_unchanged_metal_and_apple_opencl_eight_packs": true,
"mac_g2_serve_16_x_1024_of_1024_through_the_v4_class_token": true,
"harness_fuzz_edge_stats_determinism_4_of_4_on_the_class": true,
"harness_4_of_4_with_era_test_0_and_the_id_assert_ne_holding": true
},
"when_utc": "2026-10-06T16:25:16Z to 16:37:58Z",
"load_average": "144 at the start of the runs, 68 at the end (other agents' suites; every run here is functional: counts, digests and fingerprints, no timing taken)",
"crate_suite": "60 + 0 + 7 + 4 + 19 + 7 + 0 = 97 passed, 0 failed (with-lock.sh build, nice 19, -j4, release)",
"packs": {
"mx8-devnet-epoch0": {
"fingerprint_metal_and_apple_opencl": "90f794dd556f7a3b",
"program_id": "73bcbfe8ccf988f1",
"generator": 3
},
"v4-devnet-epoch0": {
"fingerprint_metal_and_apple_opencl": "f410c731b6bc2d31",
"program_id": "c120d7963abdcd96",
"generator": 4
},
"v4-era-0": {
"fingerprint_metal_and_apple_opencl": "b115c410e08be6ca",
"program_id": "c120d7963abdcd96",
"generator": 4
},
"v4-era-1": {
"fingerprint_metal_and_apple_opencl": "edc2b18fc67e9d1c",
"program_id": "c120d7963abdcd96",
"generator": 4
},
"v4-era-2": {
"fingerprint_metal_and_apple_opencl": "604ed87109570559",
"program_id": "c120d7963abdcd96",
"generator": 4
},
"v4-era-3": {
"fingerprint_metal_and_apple_opencl": "9541e2a41dde2ee6",
"program_id": "c120d7963abdcd96",
"generator": 4
},
"v4-era-4": {
"fingerprint_metal_and_apple_opencl": "a9ffa2b67bd2e366",
"program_id": "c120d7963abdcd96",
"generator": 4
},
"v4-era-5": {
"fingerprint_metal_and_apple_opencl": "1f34e9c465945249",
"program_id": "c120d7963abdcd96",
"generator": 4
}
},
"re_export": "igneum-pow export --epoch-hex <epoch> --day-hex <day> --class mx8+sh256x27 --era <n>:<hex> on the merged tree: 0 differing files against proto-cuda/packs-ca3-v4/<pack> for each of the seven (seeds.txt excluded)",
"harness": {
"class": "fuzz 200 programs 800 units, stats 49.96 and 49.98 percent (z 2.65, 3.56), edge pass, determinism equal to packs-ca3-shadow/sh256x27, 4 of 4 in 8.23 s",
"era_test_0": "fuzz 50 programs 200 units, stats 50.03 and 50.11 percent (z 2.65, 3.76), determinism two builds equal, 4 of 4 in 4.40 s; the program id now differs from the generator-3 id of the same seeds (assert_ne, no \"same with and without the shadow\" line)"
},
"mac_g2": "Metal serve (prepare and job lines with class=v4 era=<hex>) and Apple OpenCL serve: 1,024 of 1,024 on all eight packs, 16:35:31Z to 16:37:45Z"
}

View file

@ -52,3 +52,18 @@ G4, G5 and G6 are not this worker's (the node seam, the release build, the fork
- AMD (the RX 9070 XT, gfx1201): G1 and G2 on PC 1 inside another job later ("PC 1 job 1"); the OpenCL kernels are in every pack and pass on Apple OpenCL. - AMD (the RX 9070 XT, gfx1201): G1 and G2 on PC 1 inside another job later ("PC 1 job 1"); the OpenCL kernels are in every pack and pass on Apple OpenCL.
- The 2019-class core (O-1.14): the 2.5x rule stands in. - The 2019-class core (O-1.14): the 2.5x rule stands in.
## Follow-up 1 (16:25 to 16:38 UTC): the program-id fix, re-run
The node lane's fix (ca3-v4-node 7c22d0d, merged here as 5314771): a class v4 program is generator 4 wherever it is made, so its id differs from the generator-3 id of the same seeds. Re-run on the merged tree, every run functional (load 144 to 68, other agents' suites; no timing taken):
| Check | Result |
|---|---|
| The crate suite | 60 + 7 + 4 + 19 + 7 = 97 of 97, 0 failed |
| The seven v4 packs re-exported (`--class mx8+sh256x27 --era <n>:<hex>`) against the tree's | 0 differing files each; generator 4, class "v4", id c120d7963abdcd96 (one id per epoch seed across its eras); the v3 control keeps 73bcbfe8ccf988f1 |
| The fingerprints on the rebuilt Metal and Apple OpenCL harnesses | unchanged on all eight packs (the table above), self-tests PASS: the id is not a hash input |
| The Mac G2 serve through the v4 class token (`class=v4 era=<hex>` on the prepare and job lines) | 1,024 of 1,024 on all eight packs, Metal and Apple OpenCL |
| The harness on `mx8+sh256x27` (fuzz 200, stats, edge, determinism) | 4 of 4; avalanche 49.96 and 49.98 percent, determinism equal to the pinned sh256x27 |
| The harness with era test/0 composed (fuzz 50, stats, edge, determinism) | 4 of 4; the id now differs from the generator-3 id (`assert_ne`), the "same with and without the shadow" line gone |
`class-v4-20261006-1632Z-followup1-id-fix.json`. The cut-stopper of the first run is closed on the hash side; the node lane's G4 re-run with the id assertion is its own evidence. The RTX 5090 and AMD rows need the re-exported packs (the 5090 run of 15:52Z used the generator-3 packs; the kernels and vectors are byte-identical, so its fingerprints stand, and only the id and class lines of program.h differ). The G2 job script now takes the class token from the pack (v3 or v4).

View file

@ -18,7 +18,7 @@
//! shadow, draw for draw. The edge test is the dataset's alone (the shadow touches no dataset word) and takes no class. //! shadow, draw for draw. The edge test is the dataset's alone (the shadow touches no dataset word) and takes no class.
use igneum_pow::emit::{export_pack, vectors_json}; use igneum_pow::emit::{export_pack, vectors_json};
use igneum_pow::generator::{generate_era, generate_from_seed_bytes, generate_from_seed_bytes_class, generate_from_seed_bytes_program_class, EraParams, LoadClass, Op, Program, ProgramClass, GENERATOR_VERSION_V3, INSTR_COUNT, V3_ALLOWED, V3_CLASS}; use igneum_pow::generator::{era_generator_of, generate_era, generate_from_seed_bytes, generate_from_seed_bytes_class, generate_from_seed_bytes_program_class, EraParams, LoadClass, Op, Program, ProgramClass, GENERATOR_VERSION_V3, GENERATOR_VERSION_V4, INSTR_COUNT, V3_ALLOWED, V3_CLASS};
use igneum_pow::memhard::{derive_item, mixer, round_key, Cache, MixParams, Shape}; use igneum_pow::memhard::{derive_item, mixer, round_key, Cache, MixParams, Shape};
use igneum_pow::seed::{day_key, SplitMix64}; use igneum_pow::seed::{day_key, SplitMix64};
use igneum_pow::verify::{DatasetMode, DatasetSource, Epoch}; use igneum_pow::verify::{DatasetMode, DatasetSource, Epoch};
@ -52,8 +52,11 @@ fn program_of(seed: &str, class: LoadClass, era: Option<[u8; 32]>) -> Program {
} }
fn contract(p: &Program, seed: &str, class: LoadClass, era: Option<[u8; 32]>) { fn contract(p: &Program, seed: &str, class: LoadClass, era: Option<[u8; 32]>) {
if class == V3_CLASS || era.is_some() { if class == V3_CLASS {
assert_eq!(p.generator, GENERATOR_VERSION_V3); assert_eq!(p.generator, GENERATOR_VERSION_V3);
} else if era.is_some() {
// the generator of an era class is the class's (ca3-v4-node 7c22d0d): 4 on V4_CLASS, 3 otherwise
assert_eq!(p.generator, era_generator_of(&LoadClass { era: None, ..class }));
} }
assert_eq!(p.class, class); assert_eq!(p.class, class);
assert_eq!(p.instrs.len(), INSTR_COUNT); assert_eq!(p.instrs.len(), INSTR_COUNT);
@ -91,7 +94,9 @@ fn contract(p: &Program, seed: &str, class: LoadClass, era: Option<[u8; 32]>) {
let base = program_of(seed, LoadClass { shadow: None, ..class }, era); let base = program_of(seed, LoadClass { shadow: None, ..class }, era);
assert_eq!(p.instrs, base.instrs, "{seed}: the base program is the class's without the shadow"); assert_eq!(p.instrs, base.instrs, "{seed}: the base program is the class's without the shadow");
assert_eq!(p.attempt, base.attempt); assert_eq!(p.attempt, base.attempt);
if era.is_none() { if era.is_none() || p.generator == GENERATOR_VERSION_V4 {
// a generator-2 program carries the shadow in its id bytes; a class v4 program is generator 4
// (ca3-v4-node 7c22d0d), so its id differs from the generator-3 id of the same seeds
assert_ne!(p.program_id(), base.program_id(), "{seed}: the shadow is in the program id"); assert_ne!(p.program_id(), base.program_id(), "{seed}: the shadow is in the program id");
} else { } else {
// a generator-3 program's id is program_id(3, seed, attempt), class-independent by construction // a generator-3 program's id is program_id(3, seed, attempt), class-independent by construction

View file

@ -75,9 +75,10 @@ function G2-JobLines([string] $d) {
$epoch = ([regex]::Match($ph, '#define IGNEUM_SEED_BYTES_HEX "([0-9a-f]+)"')).Groups[1].Value $epoch = ([regex]::Match($ph, '#define IGNEUM_SEED_BYTES_HEX "([0-9a-f]+)"')).Groups[1].Value
$day = ([regex]::Match($ph, '#define IGNEUM_DAY_BYTES_HEX "([0-9a-f]+)"')).Groups[1].Value $day = ([regex]::Match($ph, '#define IGNEUM_DAY_BYTES_HEX "([0-9a-f]+)"')).Groups[1].Value
$tokens = '' $tokens = ''
$cls = [regex]::Match($ph, '#define IGNEUM_PROGRAM_CLASS "(v[23])"') $cls = [regex]::Match($ph, '#define IGNEUM_PROGRAM_CLASS "(v[234])"')
$era = [regex]::Match($ph, '#define IGNEUM_ERA_SEED_HEX "([0-9a-f]+)"') $era = [regex]::Match($ph, '#define IGNEUM_ERA_SEED_HEX "([0-9a-f]+)"')
if ($cls.Success -and $cls.Groups[1].Value -eq 'v3') { $tokens = ' class=v3'; if ($era.Success) { $tokens += ' era=' + $era.Groups[1].Value } } # the class token is the pack's own (v3 or v4 since ca3-v4-node 7c22d0d: a class v4 pack is generator 4 and says "v4")
if ($cls.Success -and $cls.Groups[1].Value -ne 'v2') { $tokens = ' class=' + $cls.Groups[1].Value; if ($era.Success) { $tokens += ' era=' + $era.Groups[1].Value } }
return @("job g2 $g2Pre ffffffffffffffff 0 1024 $epoch $day$tokens", 'quit') return @("job g2 $g2Pre ffffffffffffffff 0 1024 $epoch $day$tokens", 'quit')
} }
foreach ($pk in $order) { foreach ($pk in $order) {