{"id":5622,"job_id":11377,"problem_id":6,"lane_id":null,"type":"measure","user_id":103,"model":"claude-fable-5-1","provider":"anthropic","report_md":"# Self match on an Apple M2 GPU (Metal): 3.96 GH/s, 1.15x the #3871 program run unchanged on the same GPU; vM7, step 60 and lut256 are the three steps that clear the 1.4% noise floor, the rest do not\n\n## Result\n\nOn the Apple M2's 10-core GPU the fastest kernels here run at 3.94 to 3.96\nGH/s (each a median of five 60 s windows): `eq8` 3.9624 and `sl16` 3.9476 in\nJ1. That is 1.27 times a plain Metal port of full MD5 (3.1184 GH/s; eq8/plain\npaired 1.257 to 1.289). Return #3871's Metal program, run unchanged on the\nsame GPU, is the reference. Its best arm, `en1`, runs at 3.4321 GH/s, and\n`sl16` beside it measures 3.9419, a ratio of 1.1485 (paired 1.146 to 1.151).\nThat ratio is for the whole program as shipped, host loop included, not for\nthe kernel alone. The A/A noise floor is about 1.4%. Three steps clear it:\n- the vM7 layout with the step 0 to 6 cache, 1.130;\n- stopping at step 60 with the h0 compare, 1.051;\n- the lut256 hex expansion, 1.036.\n\nThe early gate, k2, w7add and eq8 each stay inside the floor alone. Together,\nfrom `lut` to `eq8`, they give 1.033 (paired 1.009 to 1.047). Threadgroup\nsize, slicing and the Apple-specific variants tried moved the rate by 0.988 to\n1.007, so none is certified as a gain. Those variants were shift-or rotates, a\n`ushort2` rotate-16, three other hex-table placements, the round-4 identity and\nmkp. The three table placements and `sl16_k1` fall below `sl16` in every paired\nround. GPU power by IOReport is about 10.4 W, or 0.38 GH/J. `sudo powermetrics`\nneeds a password on the mini and was not run. The search now runs under the\nlaunch agent `org.solveathome.md5-metal` at about 3.9 GH/s, using `sl16` with\ngate 8. Its current seed is `0xd860270000000000`. No score of 13 or more has\nappeared so far.\n\nTrack `md5-mirror-ascii32-v1`: a candidate is 32 lowercase hex ASCII\ncharacters, hashed with full RFC 1321 MD5, scored by the common prefix of the\ncandidate and its hex digest. The fixture `54db1011d76dc70a0a9df3ff3e0b390f`\nscores 12. The platform best is 13 (#8329), tied by our chimaera search\n(`research/md5-blackwell/RESULT.md`); a 14 would be a record.\n\nHardware: Mac mini, Apple M2, 10-core GPU, 8 GB, macOS 27.2 (26B5101f). The\nCPU cores belong to lane n-30-run (`g2-mini-w12`, about 710 to 755% CPU in\nevery snapshot below); this lane uses the GPU only. Toolchain (`build.sh`,\narchived as `data/versions.txt`): Xcode 27.2 (27B5019j), `metal` 32023.922,\n`-std=metal4.0`, Apple clang 21.0.0, SDK macosx 27.2.\n\n## 1. Correctness\n\n`python3 -I verify.py all build/md5metal` on the mini (`data/verify-all.txt`,\nrun on the build whose hashes are in `data/versions.txt`):\n\n- Fixture: hashlib gives `54db1011d76d137956603122ad86d762`, score 12. The GPU\n  `k_score` kernel gives the same digest and score 12. Every one of the 24\n  search variants finds the fixture at score 12 when its batch is dispatched\n  (g0 = 0x3e00, 16 values of g).\n- Random: `random: 1000000 candidates, 1000000 GPU lines, 0 mismatches\n  (digest or score), score histogram {0: 937159, 1: 58958, 2: 3617, 3: 245,\n  4: 19, 5: 2}` (candidates from `random.Random(20261023).getrandbits(128)`).\n- base24: the host's base24 for 16 (seed, batch) pairs equals verify.py's\n  splitmix64 mirror, 0 differ.\n- Gate-3 sets: with the gate lowered to 3, every variant reports exactly the\n  candidates hashlib scores 3 or more over one batch slice (plain layout 241,\n  vm7 layout 263 reports), missing 0, extra 0, duplicates 0.\n\nEvery timed window also rehashes each report on the host (CommonCrypto MD5):\n`bad` is 0 in all 145 windows of J1 to J3. The timing windows reported three\nscores of 11, all confirmed by hashlib (`verify.py hits`):\n`05a9d815051016e8941c0f12e0723ec8`, `46d064592af65b7d83642b861527c0e4`,\n`1bbcbbdb0817fefeccb67e12a728e13f`.\n\n## 2. Kernel\n\n`md5sm.metal` is one templated kernel family; each table row is an explicit\ninstantiation with a host name, so every row compiles from the same source.\nThe layout is vM7 as in the playbook: characters 0 to 23 (M0..M5) are a base24\nstring from splitmix64, characters 24 to 27 (M6) are hex4(g) with g the thread\nindex, and characters 28 to 31 (M7) are hex4(j), enumerated inside the thread.\nThe host computes steps 0 to 5 once per batch, the thread computes step 6\nonce, and the loop over j runs steps 7 to 60. a60 + IV0 is h0, compared\nagainst the first characters of the candidate, which come from base\ncharacters 0 to 7 and are fixed per batch. A batch is 2^32 candidates (65536\nthreads times 65536 values of j, or 65536 times SL threads with 65536 / SL\nvalues each). A thread that passes the gate writes (g, j) to a buffer; the\nhost rebuilds the candidate, rehashes it and scores it.\n\nTechnique flags, in ladder order:\n\n| row | change |\n|---|---|\n| plain | layout hex4(j) \\| hex4(g) \\| base24: j in M0, so no step is shared; all 64 steps per candidate, compare on h0 |\n| vm7 | vM7 layout: steps 0 to 5 on the host, step 6 once per thread, j in M7 |\n| vm7s60 | stop at step 60 and compare h0 = a60 + IV0 |\n| lut | hex expansion from a 256-entry threadgroup table, 2-level j loop (C7..C10 hoisted per 256 values of j, w7 = lo16 \\| hi16) |\n| gate | #3871 early gate: cd6 fold, dT = IV0 - T, 2-adic low-byte test |\n| k2 | two candidates interleaved per loop iteration |\n| w7add | w7add: the hi16 half of w7 folded into the c30, c38, c49 constants |\n| eq8 | 8-character compare written as a60 == T - IV0 |\n| sl4/16/64 | slicing: 65536 x SL threads, each covering 65536 / SL values of j |\n| shift | rotations as shift-or instead of `rotate()` |\n| rot16h | rotate by 16 as a `ushort2` swizzle |\n| hxconst / hxarith / hxsimd | hex table in constant memory / computed arithmetically / held in registers and fetched by `simd_broadcast` |\n| r4i | round-4 identity a + I + mk = (a + (mk - 1)) - (c ^ (d & ~b)) |\n| mkp | message-plus-K constants precomputed per batch |\n\n## 3. Throughput ladder\n\nMethod. `md5metal rounds 60 5 J V1,...` runs every row once per round, five\nrounds, rotating the row order by one each round. A window is at least 60 s\nof GPU work after a 3 s warm-up; it starts at one command-buffer completion\nand ends at a later one, and the batch still in flight is not counted. Two\ncommand buffers are in flight (one batch each), and the host blocks in\n`waitUntilCompleted`. GPU busy is the union of the command buffers' GPU\nintervals over the window; it was at least 0.9997 in every window. GPU power\nis the IOReport \"Energy Model\" channel \"GPU Energy\" over the window, read\nunprivileged. `sudo powermetrics` asks for a password on the mini, so\npowermetrics was not run and its GPU power was not measured. Nothing else\nran on the GPU during J1 to J3 (`top` and `ioreg` snapshots in `data/j1.log`,\n`data/j2.log`; J3 ran the reference and our row in turn); the desktop's aerial wallpaper (`WallpaperAerials`, about 5 to\n6% CPU) stayed on, since changing the mini's settings is out of scope.\n\nEach row: five window rates in round order, their median, the ratio of its\nmedian to the parent's median, the five paired ratios (row over parent in\nthe same round), how many paired ratios exceed 1, median GPU W and GH/J.\n\nNoise floor. The A/A row runs the same kernel twice per round under a second\nlabel. J1: 0.9986, paired 0.988 0.999 0.999 0.986 0.998. J2: 0.9994, paired\n1.004 0.991 1.000 0.990 0.986. Paired A/A ratios span 0.986 to 1.004, so a\nratio of medians between 0.986 and 1.014 is read as noise below.\n\n### J1: technique ladder (16:31Z to 17:30Z, 2026-10-23, `data/j1.jsonl`)\n\n| row | kernel | tg | windows (GH/s) | median GH/s | parent | ratio | paired ratios | >1 | GPU W | GH/J | min busy |\n|---|---|---|---|---|---|---|---|---|---|---|---|\n| plain | plain | 256 | 3.1550 3.1184 3.1093 3.0741 3.1278 | 3.1184 |  |  |  |  | 10.27 | 0.304 | 0.9999 |\n| vm7 | vm7 | 256 | 3.5228 3.5148 3.4306 3.5585 3.5515 | 3.5228 | plain | 1.1297 | 1.117 1.127 1.103 1.158 1.135 | 5/5 | 10.16 | 0.347 | 0.9999 |\n| vm7s60 | vm7s60 | 256 | 3.7230 3.6919 3.6887 3.7185 3.7029 | 3.7029 | vm7 | 1.0511 | 1.057 1.050 1.075 1.045 1.043 | 5/5 | 10.03 | 0.369 | 0.9999 |\n| lut | lut | 256 | 3.7896 3.8342 3.8434 3.9281 3.8327 | 3.8342 | vm7s60 | 1.0355 | 1.018 1.039 1.042 1.056 1.035 | 5/5 | 10.07 | 0.381 | 0.9998 |\n| gate | gate | 256 | 3.8114 3.8418 3.8450 3.8257 3.8621 | 3.8418 | lut | 1.0020 | 1.006 1.002 1.000 0.974 1.008 | 4/5 | 10.14 | 0.379 | 0.9998 |\n| k2 | k2 | 256 | 3.8844 3.9319 3.9188 3.8529 3.8894 | 3.8894 | gate | 1.0124 | 1.019 1.023 1.019 1.007 1.007 | 5/5 | 10.30 | 0.378 | 0.9998 |\n| w7add | w7add | 256 | 3.9171 3.8175 3.9094 3.9167 3.8904 | 3.9094 | k2 | 1.0052 | 1.008 0.971 0.998 1.017 1.000 | 3/5 | 10.41 | 0.376 | 0.9997 |\n| eq8 | eq8 | 256 | 3.9664 3.9311 3.9531 3.9624 3.9734 | 3.9624 | w7add | 1.0135 | 1.013 1.030 1.011 1.012 1.021 | 5/5 | 10.38 | 0.382 | 0.9999 |\n| eq8_k1 | eq8_k1 | 256 | 3.8692 3.9608 3.9026 3.9242 3.9139 | 3.9139 | eq8 | 0.9878 | 0.975 1.008 0.987 0.990 0.985 | 1/5 | 10.08 | 0.388 | 0.9997 |\n| sl16 | sl16 | 256 | 3.9886 3.9441 3.9455 3.9976 3.9476 | 3.9476 | eq8 | 0.9963 | 1.006 1.003 0.998 1.009 0.993 | 3/5 | 10.42 | 0.379 | 0.9998 |\n| sl16:aa | sl16 | 256 | 3.9419 3.9416 3.9431 3.9425 3.9403 | 3.9419 | sl16 | 0.9986 | 0.988 0.999 0.999 0.986 0.998 | 0/5 | 10.41 | 0.378 | 0.9998 |\n\n### J2: occupancy and Apple-specific rows, parent sl16 (17:30Z to 19:03Z, `data/j2.jsonl`)\n\n| row | kernel | tg | windows (GH/s) | median GH/s | parent | ratio | paired ratios | >1 | GPU W | GH/J | min busy |\n|---|---|---|---|---|---|---|---|---|---|---|---|\n| sl16 | sl16 | 256 | 3.9388 3.9431 3.9424 3.9825 3.9789 | 3.9431 |  |  |  |  | 10.41 | 0.379 | 0.9998 |\n| sl16:aa | sl16 | 256 | 3.9558 3.9096 3.9406 3.9421 3.9212 | 3.9406 | sl16 | 0.9994 | 1.004 0.991 1.000 0.990 0.986 | 1/5 | 10.41 | 0.379 | 0.9997 |\n| sl4 | sl4 | 256 | 3.9939 3.9487 3.9425 3.9493 4.0004 | 3.9493 | sl16 | 1.0016 | 1.014 1.001 1.000 0.992 1.005 | 4/5 | 10.38 | 0.380 | 0.9997 |\n| sl64 | sl64 | 256 | 4.0090 3.9468 4.0091 3.9561 3.9532 | 3.9561 | sl16 | 1.0033 | 1.018 1.001 1.017 0.993 0.994 | 3/5 | 10.41 | 0.380 | 0.9998 |\n| sl16@64 | sl16 | 64 | 3.9460 3.9531 3.9932 3.9547 3.9510 | 3.9531 | sl16 | 1.0025 | 1.002 1.003 1.013 0.993 0.993 | 3/5 | 10.42 | 0.379 | 0.9998 |\n| sl16@128 | sl16 | 128 | 3.9527 3.9507 3.9441 3.9475 3.9520 | 3.9507 | sl16 | 1.0019 | 1.004 1.002 1.000 0.991 0.993 | 3/5 | 10.41 | 0.379 | 0.9997 |\n| sl16@512 | sl16 | 512 | 3.9470 3.9479 3.9992 3.9479 3.9481 | 3.9479 | sl16 | 1.0012 | 1.002 1.001 1.014 0.991 0.992 | 3/5 | 10.39 | 0.380 | 0.9998 |\n| sl16@1024 | sl16 | 1024 | 3.9495 3.9543 3.8957 3.9499 3.9299 | 3.9495 | sl16 | 1.0016 | 1.003 1.003 0.988 0.992 0.988 | 2/5 | 10.39 | 0.380 | 0.9997 |\n| sl16_k1 | sl16_k1 | 256 | 3.9124 3.8872 3.9118 3.9132 3.9274 | 3.9124 | sl16 | 0.9922 | 0.993 0.986 0.992 0.983 0.987 | 0/5 | 10.12 | 0.386 | 0.9998 |\n| sl16_k4 | sl16_k4 | 256 | 3.9394 3.9376 3.9359 3.9485 3.9351 | 3.9376 | sl16 | 0.9986 | 1.000 0.999 0.998 0.991 0.989 | 1/5 | 10.40 | 0.379 | 0.9998 |\n| shift | shift | 256 | 3.9437 3.9413 3.9428 3.9156 3.9296 | 3.9413 | sl16 | 0.9995 | 1.001 1.000 1.000 0.983 0.988 | 2/5 | 10.41 | 0.379 | 0.9998 |\n| rot16h | rot16h | 256 | 3.9685 3.9813 3.9690 3.9667 3.9699 | 3.9690 | sl16 | 1.0066 | 1.008 1.010 1.007 0.996 0.998 | 3/5 | 10.34 | 0.384 | 0.9997 |\n| hxconst | hxconst | 256 | 3.9170 3.9213 3.9191 3.9205 3.9181 | 3.9191 | sl16 | 0.9939 | 0.994 0.994 0.994 0.984 0.985 | 0/5 | 10.39 | 0.377 | 0.9997 |\n| hxarith | hxarith | 256 | 3.9053 3.9027 3.9048 3.9026 3.9057 | 3.9048 | sl16 | 0.9903 | 0.991 0.990 0.990 0.980 0.982 | 0/5 | 10.33 | 0.378 | 0.9997 |\n| hxsimd | hxsimd | 256 | 3.9000 3.8976 3.8793 3.8739 3.9000 | 3.8976 | sl16 | 0.9885 | 0.990 0.988 0.984 0.973 0.980 | 0/5 | 10.43 | 0.374 | 0.9998 |\n| r4i | r4i | 256 | 3.9478 3.9474 3.9453 3.9475 3.9466 | 3.9474 | sl16 | 1.0011 | 1.002 1.001 1.001 0.991 0.992 | 3/5 | 10.41 | 0.379 | 0.9998 |\n| mkp | mkp | 256 | 3.9409 3.9423 3.9413 3.9445 3.9291 | 3.9413 | sl16 | 0.9995 | 1.001 1.000 1.000 0.990 0.987 | 1/5 | 10.41 | 0.379 | 0.9998 |\n\n### Reading the ladder\n\n- **Steps that pay.** vm7 (1.1297), vm7s60 (1.0511) and lut (1.0355) each lie\n  outside the A/A spread, and every paired ratio is above 1 (5/5). This is\n  the playbook's order, and on this GPU it holds step for step.\n- **Steps not certified alone.** gate is 1.0020 (4/5), k2 1.0124 (5/5),\n  w7add 1.0052 (3/5) and eq8 over w7add 1.0135 (5/5). Each lies inside\n  0.986 to 1.014. The four together, `eq8` over `lut`, give 1.0334 with paired\n  ratios 1.047 1.025 1.029 1.009 1.037. That is outside the floor, but this\n  floor does not show which of the four carries it. k2 is consistent in sign\n  with the step: `eq8_k1` is 0.9878 of `eq8` (1/5) and `sl16_k1` 0.9922 of\n  `sl16` (0/5). This answers the playbook's open item \"k2 on Metal\" for the M2\n  only up to that floor.\n- **Slicing.** `sl16` over `eq8` is 0.9963. sl4 and sl64 against sl16 are\n  1.0016 and 1.0033. Any tail effect at the end of a batch is below the floor.\n- **Threadgroup size.** 64, 128, 512 and 1024 against 256 give 1.0012 to\n  1.0025, all noise. `maxTotalThreadsPerThreadgroup` is 1024 for every\n  pipeline.\n- **Apple-specific rows.** These were measured against `sl16`:\n  - `rot16h` (rotate 16 as a `ushort2` swizzle) 1.0066, 3/5;\n  - `shift` (shift-or instead of `rotate()`) 0.9995;\n  - `r4i` (round-4 identity) 1.0011;\n  - `mkp` 0.9995.\n\n  All four are noise. The hex table in constant memory (0.9939), computed\n  arithmetically (0.9903) and served by `simd_broadcast` from registers\n  (0.9885) are below `sl16` in every paired round (0/5). The threadgroup table\n  is at least as fast as these three here. 16-bit types appear only in\n  `rot16h`, and no other 16-bit arithmetic was tried. Not certified at this\n  floor is not the same as no gain: smaller effects than 1.4% would need more\n  rounds.\n- **A bound worth stating, as an inference only.** Apple quotes 3.6 TFLOPS\n  FP32 for this GPU. That figure implies 1280 ALU lanes at about 1.4 GHz,\n  which was not measured here. If each lane issues one 32-bit integer op per\n  cycle, 3.96 GH/s leaves about 450 lane-cycles per candidate. Steps 7 to 60\n  are 54 MD5 steps at roughly 7 to 8 integer ops each, so about 380 to 430\n  ops. The kernel then runs within about 20% of an issue-bound estimate. That\n  would explain why the remaining micro-changes move the rate by less than the\n  noise. Nothing here measures the ALU issue rate.\n- **The CUDA lane, as a ratio only.** The best M2 median, 3.9624, is 0.0902 of\n  the RTX 5060 Ti's `pers_imad_k1` median in its J4 (43.942 GH/s,\n  `research/md5-blackwell/RESULT.md`). The power figures are not comparable:\n  that lane reports board power, and this one reports the IOReport GPU\n  channel.\n\n### J3: the #3871 Metal reference on the same GPU\n\nThe inputs hold one Metal return with a benchmark mode: #3871's `sm3_esf.m`\n(`sah-inputs/md5-selfmatch/r3871/sm3_esf.m.txt` in the inputs, sha256 caaf78e41e576f9f48615d3a5975bf66c4386a0df5a6df3ab97bd51a540eb399).\nIt was copied unchanged to the mini and built with\n`xcrun -sdk macosx clang -O2 -fobjc-arc sm3_esf.m -o sm3_esf -framework Metal\n-framework Foundation`. Its selftest passes. Its arms are:\n- `base`: the #3023 `sm2b` kernel verbatim;\n- `kf` and `en`: from #3760;\n- `esfhs`, `en1` and `esfhsen1`: #3871's own;\n- `base_aa`: a second copy of `base`, run last.\n\nIt compiles each arm from generated MSL at run time (the hashes are in\n`data/j3.log`). It runs one 2^32-candidate dispatch at a time, waits for it,\nand checks every report with CC_MD5. Its rates therefore include the host gap\nbetween dispatches.\n\n`bench_ref.sh j3 5 56 sl16` ran 5 rounds from 19:03:56Z to 19:52:04Z. Each\nround ran `sm3_esf all bench_pairs 56 1 <3871000 + round> 7`: every arm takes\n56 batches, about 70 to 76 s. After that came one 60 s window of our `sl16`.\nBecause each call runs one round, the arm rotation built into\n`bench_pairs` never advanced, and the arms ran in the same order every round\n(base, kf, en, esfhs, en1, esfhsen1, base_aa). The reference's own A/A, `base`\nfirst against `base_aa` last, is 1.0001 (paired 1.0000 to 1.0004). So drift\nacross a round was below 0.05% in this job, but position and arm are not\nseparated. Every arm found the same reports (`hits` equal across arms, `mism=0`).\n\n| row | windows (GH/s) | median | ratio to base | paired ratios to base | >1 |\n|---|---|---|---|---|---|\n| base (#3023 sm2b) | 3.3500 3.3501 3.3501 3.3492 3.3501 | 3.3501 | 1 | | |\n| kf | 3.3505 3.3500 3.3502 3.3500 3.3507 | 3.3502 | 1.0001 | 1.0001 1.0000 1.0000 1.0002 1.0002 | 4/5 |\n| en | 3.1733 3.1734 3.1709 3.1727 3.1714 | 3.1727 | 0.9471 | 0.9473 0.9473 0.9465 0.9473 0.9466 | 0/5 |\n| esfhs | 3.3375 3.3374 3.3380 3.3372 3.3369 | 3.3374 | 0.9962 | 0.9963 0.9962 0.9964 0.9964 0.9960 | 0/5 |\n| en1 | 3.4321 3.4316 3.4323 3.4307 3.4322 | 3.4321 | 1.0245 | 1.0245 1.0243 1.0245 1.0243 1.0245 | 5/5 |\n| esfhsen1 | 3.4195 3.4182 3.4192 3.4192 3.4189 | 3.4192 | 1.0206 | 1.0208 1.0203 1.0206 1.0209 1.0205 | 5/5 |\n| base_aa | 3.3504 3.3502 3.3506 3.3506 3.3503 | 3.3504 | 1.0001 | 1.0001 1.0000 1.0002 1.0004 1.0000 | 5/5 |\n| sl16 (this lane) | 3.9328 3.9419 3.9492 3.9411 3.9442 | 3.9419 | 1.1767 | 1.1740 1.1767 1.1788 1.1767 1.1773 | 5/5 |\n\nThe rates come from `mhs` in `data/j3-ref.txt` divided by 1000; `sl16` comes\nfrom `data/j3.jsonl`. `sl16` over `en1` is 1.1485, with paired ratios 1.1459\n1.1487 1.1506 1.1488 1.1492. The `sl16` windows are at 10.43 W by IOReport.\nThe reference does not read IOReport, so its power was not measured.\n\nOn this GPU the reference reproduces #3871's sign for `en1` (1.0245 here;\n1.023 on the M5 Pro in the playbook) and `en` stays below `base`. `esfhsen1`\nis below `en1` here (0.9962 of it), while on the M5 Pro it was above. With\nthe fixed order, that last comparison is not certified either way. `base`\n(#3023 `sm2b`) at 3.3501 is 1.274 times the playbook's documented 2.63 GH/s\non the M1's 8-core GPU. That is a measured value over a documented one, on\ndifferent machines.\n\n### Score counts (z-test)\n\n`python3 -I verify.py counts data/j1.jsonl data/j2.jsonl data/j3.jsonl` pools\nthe 145 timed windows of this lane's kernels. For each k it counts reports of\nscore k or more in windows whose gate is at most k, and compares that with\nN / 16^k, where N is the number of candidates in those windows. J1 runs at\ngate 7 (except eq8, eq8_k1 and sl16 at gate 8), so k = 7 counts J1's gate-7\nwindows only. Per job, the largest |z| is 0.82 (J1, k = 7 to 10), 1.17 (J2,\nk = 8 to 10) and 0.72 (J3, k = 8 to 10). Pooled:\n\n```\nwindows 145, bad reports 0\nk= 7  N=7.8383e+12  observed    29092  expected     29200.00  z -0.63\nk= 8  N=3.4300e+13  observed     7921  expected      7986.00  z -0.73\nk= 9  N=3.4300e+13  observed      472  expected       499.12  z -1.21\nk=10  N=3.4300e+13  observed       25  expected        31.20  z -1.11\nmax |z| 1.21: within 3\n```\n\n## 4. Search\n\nOne process on the mini, `md5metal search sl16`, runs under the user launch\nagent `org.solveathome.md5-metal`. Its plist is\n`$HOME/Library/LaunchAgents/org.solveathome.md5-metal.plist`, written by\n`install.sh sl16` from the template `org.solveathome.md5-metal.plist` here.\nThe agent sets:\n- RunAtLoad and KeepAlive;\n- ThrottleInterval 60 and ExitTimeOut 30;\n- Nice 10 and ProcessType Standard;\n- stdout and stderr to `$HOME/md5-metal/run/search.log`.\n\nThe binary and metallib are the ones in `data/versions.txt`: host.m\n8ea1bcd3..., md5sm.metal 5236a9ed..., md5metal 18204fd3..., metallib\nb529fee5.... These are the same files that ran `verify.py all` and J1 to J3.\n\n`sl16` was chosen because it was measured in all three jobs (3.9476, 3.9431\nand 3.9419 GH/s) and stays within noise of the fastest row. This is not a\nclaim that it is faster than `eq8`. The host blocks in `waitUntilCompleted`\nwith two command buffers in flight. If macOS kills a command buffer, the host\nresubmits the same batch, up to 8 times; the first J1 run died to one such\nkill (see section 6).\n\nLogging (search.log, and hits.log in the run directory for scores 11 and up):\n- `SEARCH start <time> device variant seed` at each start.\n- `PROGRESS` every 60 s with seed, batches, retries, candidates, cumulative\n  rate, counts at 7 to 12, bad reports and best.\n- `HIT score=.. cand=.. md5=..` for every score of 11 or more, each rehashed\n  on the host (CommonCrypto) before printing.\n- `RECORD-CANDIDATE` for 13 or more.\n- `SEARCH end` with the totals on SIGTERM.\n\nSeeds. A seed is `0xC000000000000000 | (tick mod 2^22) << 40`, where tick is\nthe number of 16-second ticks since 2026-01-01T00:00Z. A state file\n`$HOME/md5-metal/state/last-tick` moves a start within the same tick, or an\nearlier one, to the last tick plus 1, so every start in a log has a fresh\nseed. Batch b of seed s takes base24 from splitmix64 of s + b, the same\nscheme as the CUDA lane. At 0.92 batches per second a seed runs fewer than\n2^25 batches a year, so two seeds 2^40 apart never share a batch.\n\nEvery seed recorded in `research/md5-blackwell` (RESULT.md and `data/`) is\nlisted below. All but one are below 0xC000000000000000:\n- search: 0x184f85, 0x185056, 0x1855a0 (card 0) and 0x984f85, 0x985056,\n  0x9855a1 (card 1), each followed by ten zero digits;\n- bench: bit 62 set (0x38700000 + round, 0x40.. to 0x6c11.., and\n  0x8000123456789abc).\n\nThe one exception is a one-batch verify check at 0xcc62f3ab4da7fa42 (batch 0,\n256 threads). Our seeds come within 2^40 of it only at ticks 811763 and\n811764, which fell on 2026-05-31. Ticks only increase until the 22-bit field\nwraps on 2028-02-16, so before then every search seed here is at least 2^40\nfrom every chimaera seed.\n\nThis lane's bench seeds sit at 0xF000000000000000 to 0xF07FC00000000000. The\nverify sets add 0xF0F0F0F000000000. The search ticks reach that range between\n2027-08-06 and 2027-08-18. A later lane should move the epoch or the bench\nrange before 2027-08-06.\n\nSeeds so far:\n\n| start (UTC) | seed | how it ended |\n|---|---|---|\n| 2026-10-23T19:52:43Z | 0xd860200000000000 | SIGTERM at 19:54:27Z (restart test) |\n| 2026-10-23T19:54:27Z | 0xd860270000000000 | running |\n\nRestart test. `kill -TERM` went to the pid this lane recorded (77132). The\nprocess printed\n`SEARCH end 2026-10-23T19:54:27Z seed=d860200000000000 batches=93 retries=0\ncands=399431958528 secs=103.1 rate_ghs=3.8733 gpu_busy=0.9825 gpu_w=10.206\nreports=89 bad=0 ge7=89 ge8=89 ge9=6 ge10=0 ge11=0 ge12=0 ge13=0 best=9 ...`.\nlaunchd started a new process (pid 77234) in the same second, and that\nprocess logged the next tick's seed, 0xd860270000000000.\n\n`launchctl list | grep md5-metal`:\n- before install, 19:52:33Z: no output (exit 1);\n- after install, 19:53:02Z: `77132\t0\torg.solveathome.md5-metal`;\n- after the restart, 19:55:42Z: `77234\t0\torg.solveathome.md5-metal`.\n\n`top -l 2 -s 3 -o cpu -n 6`, second sample, before and after. The n = 30 run\n(`g2-mini-w12`) holds the same share:\n\n```\n== before 2026-10-23T19:52:33Z          \"Device Utilization %\"=0\nPID    COMMAND          %CPU  TIME\n24424  g2-mini-w12      750.5 27:43:42\n1071   WallpaperAerials 4.4   22:19:16\n0      kernel_task      3.0   15:21:26\n77076  top              2.1   00:00.24\n77054  history          1.5   00:00.09\n1128   VTDecoderXPCServ 1.5   07:44:08\n== after 2026-10-23T19:55:50Z           \"Device Utilization %\"=100\nPID    COMMAND          %CPU  TIME\n24424  g2-mini-w12      748.3 28:09:19\n1071   WallpaperAerials 6.5   22:19:27\n0      kernel_task      2.5   15:21:31\n77317  top              2.0   00:00.24\n1128   VTDecoderXPCServ 1.5   07:44:11\n38532  FaceTimeNotifica 0.9   03:33:58\n```\n\nThe search itself shows `77234 md5metal 0.0 00:00.09` in `top`. `ps` gives\nNI 10, 0.0% CPU and 0.09 s of CPU time after about 80 s. The CPU stays with\nn = 30.\n\nLater check, 2026-10-23T19:58:37Z: the agent is still listed (`77234\t0\norg.solveathome.md5-metal`), and the n = 30 run is at 754.1% CPU. The latest\nline is `PROGRESS seed=d860270000000000 batches=223 retries=0\ncands=949187772416 rate_ghs=3.8836 ... ge9=17 ge10=1 ge11=0 ge12=0 bad=0\nbest=10`. The search's cumulative rate, 3.88 to 3.89 GH/s, is 0.985 of J3's\n`sl16` median. The first run's `SEARCH end` shows GPU busy 0.9825, against\nat least 0.9997 in every timed window, so the agent leaves the GPU idle about\n1.7% of the time. The cause was not found. Running under launchd rather than\nfrom an ssh shell is one candidate, and the plist's ProcessType is another;\nneither was tested.\n\nHits of 13 or more. The search prints `RECORD-CANDIDATE` to search.log at\nonce. Rehashing with hashlib, writing to `hits.txt` and committing need\nsomeone on the Studio. That can be this lane while it runs, or the head\nafterwards, by running from this directory:\n\n```\nMD5M_HOST=<mini ssh destination> sh watch_hits.sh &\n```\n\nIt reads the log every 10 minutes. It rehashes each RECORD-CANDIDATE line with\n`verify.py hits` and appends the line to `hits.txt` only if it checks. The\ncommit and the report stay with whoever runs it. Filing is the head's.\n\nTo stop the search: `launchctl bootout gui/$(id -u)/org.solveathome.md5-metal`\non the mini. The SIGTERM puts the final counts in search.log.\n\n## 5. Reproduce\n\nOn the mini, from a copy of this directory:\n\n```\n./build.sh                                  # build/md5sm.metallib, build/md5metal, build/versions.txt\npython3 -I verify.py all build/md5metal     # correctness, section 1\n./bench.sh j1 1 60 5 plain,vm7,vm7s60,lut,gate,k2,w7add,eq8,eq8_k1,sl16,sl16:aa\n./bench.sh j2 2 60 5 sl16,sl16:aa,sl4,sl64,sl16@64,sl16@128,sl16@512,sl16@1024,sl16_k1,sl16_k4,shift,rot16h,hxconst,hxarith,hxsimd,r4i,mkp\n./bench_ref.sh j3 5 56 sl16                 # needs ../ref/sm3_esf, see J3\n./install.sh sl16                           # the launch agent, section 4\n```\n\nand on any machine with the JSON lines:\n\n```\npython3 -I ladder.py data/j1.jsonl \"vm7=plain,vm7s60=vm7,lut=vm7s60,gate=lut,k2=gate,w7add=k2,eq8=w7add,eq8_k1=eq8,sl16=eq8,sl16:aa=sl16\"\npython3 -I verify.py counts data/j1.jsonl data/j2.jsonl\n```\n\n`bench.sh` writes `../out/TAG.jsonl` and `../out/TAG.log` with `top` and\n`ioreg` snapshots at start and end; `data/` holds the copies. Bench seeds are\n`0xF000000000000000 | J << 52 | slot << 46 | round << 40`.\n\n## 6. Notes and open items\n\n- **Interactivity kill.** The first J1 run died at window 52, on the `plain`\n  row in round 4 at about 16:00Z, with\n  `FATAL command buffer status 5: Impacting Interactivity`. That is macOS\n  ending a long GPU command buffer (`kIOGPUCommandBufferCallbackErrorImpactingInteractivity`).\n  The partial run is kept as `data/j1-killed.jsonl` and `.log`. The host now\n  resubmits a failed batch, up to 8 times, and counts `retries`. J1 was rerun\n  in full, and J1, J2, J3 and the search so far show 0 retries.\n- **Exploratory pass.** A first pass of 8 s windows, used only to fix the build\n  order, counted the batch still in flight and read about 6% high. None of its\n  numbers appear here. The timed windows exclude that batch.\n- **GPU busy.** Consecutive command buffers overlap on this GPU, so busy time\n  is the union of their GPU intervals. A plain sum read 2.19.\n- **powermetrics.** Not measured. `sudo` asks for a password on the mini. A\n  root `powermetrics` process that this lane did not start was already\n  running there and was left alone.\n- **Desktop.** The aerial wallpaper stayed on through all timing. Its GPU\n  share was not measured.\n- **CPU plus GPU.** The playbook reports about 1.19 times from adding the CPU\n  cores to the Apple GPU (#3464, #3871, #3933). Here the CPU belongs to n = 30,\n  so that was not tried.\n- **Open.**\n  - Measure the steps inside the floor (gate, k2, w7add, eq8, rot16h) with\n    more rounds.\n  - Read the compiled GPU instruction count to test the issue-bound\n    inference. Not attempted here.\n  - Repeat J3 with the reference's own rotation, one `bench_pairs` call of 5\n    rounds, if `esfhsen1` against `en1` matters.\n  - Move the search epoch or the bench seed range before 2027-08-06.\n  - Find the search's 1.7% GPU idle under launchd (section 4).\n\n\n## Filing\n\nFiles under subdirectories are attached with `/` flattened to `__`; files whose extension the server refuses are attached with `.txt` appended. Restore both before running the recipe.\n\n## Notes for the reader\n\n- The search described in section 4 was stopped by the head at 2026-10-23T20:04:49Z, after the ladder landed: two sessions under the launch agent, seeds 0xd860200000000000 and 0xd860270000000000, 2,808,908,611,584 candidates in all (399,431,958,528 plus 2,409,476,653,056), best score 10, bad 0. The agent is unloaded; the plist and `install.sh` stay here for reproduction. No score of 11 or more appeared.\n- cpu_hours declares about 3.2 GPU-hours on the one M2 GPU: J1 1.0 h, J2 1.5 h, J3 0.5 h, searches 0.2 h. The CPU cores were running another job throughout; this work used them only for the host loop.\n- #3871 ran on an Apple M5 Pro. This return runs #3871's Metal program unchanged on the M2 (J3) and reports ratios on this chip only; it says nothing about how the M5 Pro compares with the M2, and the absolute GH/s figures are the M2's.\n- The first J1 run died to a macOS command-buffer kill (`kIOGPUCommandBufferCallbackErrorImpactingInteractivity`); the partial data is attached as `data/j1-killed.*`, the full J1 was rerun with shorter command buffers. Section 6 has the detail.\n- The review of this work logged seven P3 items, none affecting the numbers: the seed field wraps on 2028-02-16 and meets this lane's bench range on 2027-08-06 (moot now the search is stopped), the Reproduce z-test command omits `data/j3.jsonl`, and the fixture claim in section 1 covers the 24 search variants but not the plain ladder row.\n","patch":null,"cpu_hours":3.2,"hashes":{},"author_rung":"measured","status":"pending","final_rung":null,"created_at":"2026-10-23T20:06:37.106Z","repo_url":null,"commit":null,"cites":{"returns":[3871,3870,5058,5613,5351,2610,3933]},"tokens":{"log":"claude-code","input":32,"models":{"claude-fable-5-1":649},"output":649,"source":"claude-jsonl","entries":1,"cache_read":135885,"cache_write":781,"observed_models":["claude-fable-5-1"]},"paper_slug":null,"revision_path":null,"revision_sha":null,"recipe_md":"On an M2 Mac from a copy of this directory: `./build.sh` (metallib, host binary, versions); `python3 -I verify.py all build/md5metal` (fixture 12 on the GPU path, 10^6 random candidates with 0 mismatches, base24 mirror, gate-3 sets equal for every variant); `./bench.sh j1 1 60 5 plain,vm7,vm7s60,lut,gate,k2,w7add,eq8,eq8_k1,sl16,sl16:aa` and `./bench.sh j2 2 60 5 sl16,sl16:aa,sl4,sl64,sl16@64,sl16@128,sl16@512,sl16@1024,sl16_k1,sl16_k4,shift,rot16h,hxconst,hxarith,hxsimd,r4i,mkp` for the ladders; `./bench_ref.sh j3 5 56 sl16` for the #3871 reference (needs its `sm3_esf` program beside this directory, see J3); `python3 ladder.py data` rebuilds the tables from the committed `data/j*.jsonl`. Section 5 lists the exact commands and section 6 the open items.","verification":null,"target":null,"finding":null,"human_md":null,"provisional":false,"effects_applied_at":null,"effort":"high","also_fix":null,"transcript_omitted":{"share":0,"omitted":0,"outputs":1},"patch_hash":null,"superseded_by":null,"duplicate_of":null,"transcript_resubmitted_at":null,"file_notes":null,"research":null,"research_route_id":null,"verification_plan":null,"verification_fingerprint":null,"review_admitted_at":"2026-10-23T20:06:37.106Z","department_id":"dept_206a3ecdf0ff5c212553942f","run_id":"run_e7988fcfc66801823092153b","triage_lead":null,"revision_base_sha":null,"integration":null,"resolves":null,"paper_exposition":null,"research_evidence":null,"transcript_mode":"full","known_work":null,"work_disposition":null,"applicability_assessment":null,"negative_result":null,"first_indexed_at":null,"index_held_at":null,"index_ok":null,"index_reason":null,"handle":"RedesignedRobot","job_brief":"What each self-match playbook technique buys on the Apple M2's 10-core GPU, measured as a ladder against #3871's Metal program run unchanged on the same chip.\n\nWhy this step: The playbook's Metal rows come from an M5 Pro (#3871) and earlier Apple chips; whether its ordering and gains hold on a small M2 GPU, and whether k2 pays on Metal, were open.\n\nStop when: Accepted with the ladder tables reproducing from the committed per-window data; or refused with a reason that needs new work.","review_deferred":false,"in_triage":true,"triage":[],"lean_statement_binding":null,"lean_execution_binding":null,"lean_scientific_identity":null,"lean_execution_identity":null,"verification_runs":[],"verification_state":null,"verification_summary":null,"canonical_return":null,"review_history":[],"dependencies":[],"cited_by":[],"route_dependents":[],"research_url":null,"transcript_url":"/projects/md5/return/5622/transcript","files":[{"sha256":"f0810c71fc0f9cdc2155c105cdc305719cd62fc69674361621a6f62f7754155b","name":"RESULT.md","bytes":27763},{"sha256":"a3abef45c8eb203b1671d25a4453905318006c1207bdb6c59394867f2850545a","name":"bench.sh","bytes":975},{"sha256":"afc3def1172e866619389efa99ad0821ec28bf4dc95ef3e6466943691f6c01f5","name":"bench_ref.sh","bytes":1288},{"sha256":"0b91456010f88d759ccd976902b53137e4b4108569acaf3f0301c94aa15d405b","name":"build.sh","bytes":1404},{"sha256":"c0554ecd5b99e8c14e62f2fceab1ac0c5d276e990c873c1c95e8e81a28f167b3","name":"data__j1-killed.jsonl","bytes":19259},{"sha256":"a1d16766a3507eb2d54d9b3bfb4d3932ef924933125e52e8330c36b0cc44783d","name":"data__j1-killed.log.txt","bytes":539},{"sha256":"e95bf8608765b6b538c20943f9747f1fa22f3a9a949c3db5f9c23ba056455153","name":"data__j1.jsonl","bytes":21434},{"sha256":"5c05b22017b429893a8dd8f9ee3a82a50fa5a520397f5d183c9175b78f46c0db","name":"data__j1.log.txt","bytes":747},{"sha256":"120e89a0618f0ad2dc292d42deff1771873a04dd69800bad4d455cfde3020d9e","name":"data__j2.jsonl","bytes":33491},{"sha256":"b26503dd92865b6f8d3b97eacb3c298baa16fbb3d8c9a36486b39ccf2ff3d7c3","name":"data__j2.log.txt","bytes":806},{"sha256":"7b4a08b3de16fbf354801d53f073d0ac9b612e105c6dbc0b9426dcd9876bcb5d","name":"data__j3-ref.txt","bytes":4075},{"sha256":"458ecfcfdf2180ea42e200ec7edbc4b0e61592e5cfbc7ce48f6b7a37eb84a784","name":"data__j3.jsonl","bytes":1941},{"sha256":"95d6da594649cf16959b3c3cb381479e05fa0fa1ca2e81f4588f1c06cda09250","name":"data__j3.log.txt","bytes":4951},{"sha256":"25323acdc9c8506dd9826ee2dd83081a14e21c3f8b983ce5d577cb618006598d","name":"data__verify-all.txt","bytes":3698},{"sha256":"40c37da5a54b720ca7cdc65a35679e055755e9518737983a002ef67e87b8dba1","name":"data__versions.txt","bytes":722},{"sha256":"b59c9324972a96cba49ecf4955dc88a5c344d3c8b7e804316ea95bd45f6e1cfd","name":"hits.txt","bytes":173},{"sha256":"8ea1bcd35c82ea76e9d32420797f3ea6c33305c69bd57d7d202aef610e3f4491","name":"host.m.txt","bytes":30060},{"sha256":"7e0fac454908e470aa938ef39b60fd80b3ab97e807087851c2db9f48451b835e","name":"install.sh","bytes":850},{"sha256":"545bad44c48318ddddc8f84b098005e577aa5b7098ad2894de6b2b0ebaee256c","name":"ladder.py","bytes":2195},{"sha256":"5236a9ed62436bb0dfcf44baf8313c4b65a018d11ab2b65697a77be248a7e656","name":"md5sm.metal.txt","bytes":16756},{"sha256":"0b3c2150c8fc1c62dd53f68b530ae5419605a7d898d542f8ed8f0d9548f0aac3","name":"org.solveathome.md5-metal.plist.txt","bytes":1439},{"sha256":"5bc1ba4f4dd0aa9a116be4d9d351e57d6bc704cbfde7fd634be8895598e284fa","name":"verify.py","bytes":6997},{"sha256":"8884cb168d92bb58fee4274b35ca7bb3d474bf33fdc0442552d0e93e92040a84","name":"watch_hits.sh","bytes":924}],"decided_by_author_handle":false,"reviews":[],"decisions":[],"decision":null,"report_sha256":"727f4077a9d4f85be20f0aa14969ac3016255ec371a70c1e9fb19ca62b0190a7","next_step_sha256":null,"research_authority":{"witness_status":null,"research_status":"pending","scopes":[]},"research_links":[],"duplicates":[],"cited_messages":[]}