diff --git a/igneum-pow/tests/packs.rs b/igneum-pow/tests/packs.rs index 3d6418d4e..f66d91536 100644 --- a/igneum-pow/tests/packs.rs +++ b/igneum-pow/tests/packs.rs @@ -947,7 +947,7 @@ fn v5_pack_is_the_v4_program_over_the_state_leaves() { let e4 = v5_epoch("v4-genesis"); let v4 = v5_json("v4-genesis", "vectors.json"); // the known-failed case: the v4 pack's hashes are not the v5 epoch's on any lane - let out4: Vec = v4["warps"][0]["out"].as_array().unwrap().iter().map(hex64).collect(); + let out4: Vec = v4["warps"][0]["expected"].as_array().unwrap().iter().map(hex64).collect(); let got5 = e5.hash_warp(0); assert_eq!(out4.iter().zip(got5.iter()).filter(|(a, b)| a == b).count(), 0, "0 of 32 lanes of the v4 pack agree with the v5 epoch"); assert_eq!(e4.hash_warp(0).to_vec(), out4, "the v4 control pack is the v4 epoch"); diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/kernel.cl b/proto-cuda/packs-ca3-v5/v4-genesis/kernel.cl new file mode 100644 index 000000000..72f7ca4d0 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/kernel.cl @@ -0,0 +1,538 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// OpenCL C twin of the Metal kernel for the same seed (see proto-opencl/README.md, WAVEFRONT.md and program.metal). +// Built from source at runtime by proto-opencl/host.c, which passes these defines: +// IGNEUM_GROUP work-group size of igneum_hash, a multiple of 32 (default 32: one work-group = one 32-lane unit) +// IGNEUM_EXCHANGE 0 = local-memory exchange with a barrier (any device, any wave width; the default) +// 1 = sub_group_shuffle_xor (cl_khr_subgroup_shuffle), only with IGNEUM_GROUP 32 and a sub-group size of exactly 32 +// 2 = intel_sub_group_shuffle_xor (cl_intel_subgroups), same condition +// The verification unit is always 32 lanes. A 64-wide hardware wave (AMD GCN/CDNA, RDNA in wave64) runs two units; +// the exchange masks are 1, 2, 4, 8, 16, so every partner lane lies inside the lane's own aligned run of 32. +#ifndef IGNEUM_GROUP +#define IGNEUM_GROUP 32 +#endif +#ifndef IGNEUM_EXCHANGE +#define IGNEUM_EXCHANGE 0 +#endif +#ifdef __OPENCL_VERSION__ +#define IGNEUM_KERNEL_HASH __kernel __attribute__((reqd_work_group_size(IGNEUM_GROUP, 1, 1))) +#define IGNEUM_LOCAL_WORDS(name, n) __local uint name[n] +#if IGNEUM_EXCHANGE == 1 +#ifdef cl_khr_subgroups +#pragma OPENCL EXTENSION cl_khr_subgroups : enable +#endif +#ifdef cl_khr_subgroup_shuffle +#pragma OPENCL EXTENSION cl_khr_subgroup_shuffle : enable +#endif +#elif IGNEUM_EXCHANGE == 2 +#pragma OPENCL EXTENSION cl_intel_subgroups : enable +#endif +#else +// Not an OpenCL compiler: proto-opencl/emu compiles this file as C++ and supplies the built-ins and these two macros. +#include "emu_opencl.h" +#endif + +#if IGNEUM_EXCHANGE == 1 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#elif IGNEUM_EXCHANGE == 2 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = intel_sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#else +// Local-memory exchange. Two buffers of IGNEUM_GROUP words alternate (xk counts exchanges), so one barrier per +// exchange is enough: a lane can only overwrite buffer b at exchange k+2 after passing barrier k+1, and every lane +// reaches barrier k+1 only after its read of buffer b at exchange k. The partner lid ^ m stays inside the lane's +// aligned run of 32 because m < 32. Control flow is uniform, so every work-item reaches every barrier. +#define IGNEUM_SHFL_XOR(dst, a, m) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid ^ (uint)(m))]; xk += 1u; } +#define IGNEUM_BCAST0(dst, a) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid & ~31u)]; xk += 1u; } +#endif + +static inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site. OpenCL rotate() rotates left by n modulo 32. +static inline uint rotl_imm(uint x, uint n) { return rotate(x, n); } +// Right rotation by n modulo 32 as a left rotation by (32 - n) modulo 32; n == 0 gives x. +static inline uint rotr_var(uint x, uint n) { return rotate(x, (0u - n) & 31u); } +static inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +static inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +static inline void mh_chacha_block(const uint* x, uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +static inline void mh_cache_segment(__global uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + __global uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +static inline void mh_mixer(uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +static inline void mh_item(__global const uint* cache, uint t, uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + __global const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +static inline uint mh_word(__global const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// Memory-hard dataset (MEMHARD.md). One work-item per cache segment; one work-item per 64-byte dataset item. +// The same constants as memhard.h in this pack (one emitter, three dialects). +__kernel void igneum_cache_fill(__global uint* cache, uint nSegments) { + uint seg = (uint)get_global_id(0); + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__kernel void igneum_build(__global uint* ds, __global const uint* cache, uint nItems) { + uint t = (uint)get_global_id(0); + if (t < nItems) { + uint s[16]; + mh_item(cache, t, s); + __global uint* d = ds + ((ulong)t * 16u); + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per work-item. IGNEUM_GROUP is a multiple of 32; lane = lid & 31 and every exchange stays inside the +// lane's own aligned run of 32 work-items, exactly like simd_shuffle_xor inside a 32-wide Metal SIMD group and +// __shfl_xor_sync inside a CUDA warp. Control flow is uniform (no branches at all). +IGNEUM_KERNEL_HASH void igneum_hash(__global const uint* ds, __global ulong* out, uint baseNonce, uint mask) { + uint gid = (uint)get_global_id(0); + uint lid = (uint)get_local_id(0); + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; +#if IGNEUM_EXCHANGE == 0 + IGNEUM_LOCAL_WORDS(xch, 2 * IGNEUM_GROUP); + uint xk = 0u; +#else + (void)lid; +#endif + { uint x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/kernel.cu b/proto-cuda/packs-ca3-v5/v4-genesis/kernel.cu new file mode 100644 index 000000000..62d29f6ff --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/kernel.cu @@ -0,0 +1,423 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + if (nItems == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/kernel_bound.cl b/proto-cuda/packs-ca3-v5/v4-genesis/kernel_bound.cl new file mode 100644 index 000000000..02546cd07 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/kernel_bound.cl @@ -0,0 +1,891 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// OpenCL C twin of the Metal kernel for the same seed (see proto-opencl/README.md, WAVEFRONT.md and program.metal). +// Built from source at runtime by proto-opencl/host.c, which passes these defines: +// IGNEUM_GROUP work-group size of igneum_hash, a multiple of 32 (default 32: one work-group = one 32-lane unit) +// IGNEUM_EXCHANGE 0 = local-memory exchange with a barrier (any device, any wave width; the default) +// 1 = sub_group_shuffle_xor (cl_khr_subgroup_shuffle), only with IGNEUM_GROUP 32 and a sub-group size of exactly 32 +// 2 = intel_sub_group_shuffle_xor (cl_intel_subgroups), same condition +// The verification unit is always 32 lanes. A 64-wide hardware wave (AMD GCN/CDNA, RDNA in wave64) runs two units; +// the exchange masks are 1, 2, 4, 8, 16, so every partner lane lies inside the lane's own aligned run of 32. +#ifndef IGNEUM_GROUP +#define IGNEUM_GROUP 32 +#endif +#ifndef IGNEUM_EXCHANGE +#define IGNEUM_EXCHANGE 0 +#endif +#ifdef __OPENCL_VERSION__ +#define IGNEUM_KERNEL_HASH __kernel __attribute__((reqd_work_group_size(IGNEUM_GROUP, 1, 1))) +#define IGNEUM_LOCAL_WORDS(name, n) __local uint name[n] +#if IGNEUM_EXCHANGE == 1 +#ifdef cl_khr_subgroups +#pragma OPENCL EXTENSION cl_khr_subgroups : enable +#endif +#ifdef cl_khr_subgroup_shuffle +#pragma OPENCL EXTENSION cl_khr_subgroup_shuffle : enable +#endif +#elif IGNEUM_EXCHANGE == 2 +#pragma OPENCL EXTENSION cl_intel_subgroups : enable +#endif +#else +// Not an OpenCL compiler: proto-opencl/emu compiles this file as C++ and supplies the built-ins and these two macros. +#include "emu_opencl.h" +#endif + +#if IGNEUM_EXCHANGE == 1 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#elif IGNEUM_EXCHANGE == 2 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = intel_sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#else +// Local-memory exchange. Two buffers of IGNEUM_GROUP words alternate (xk counts exchanges), so one barrier per +// exchange is enough: a lane can only overwrite buffer b at exchange k+2 after passing barrier k+1, and every lane +// reaches barrier k+1 only after its read of buffer b at exchange k. The partner lid ^ m stays inside the lane's +// aligned run of 32 because m < 32. Control flow is uniform, so every work-item reaches every barrier. +#define IGNEUM_SHFL_XOR(dst, a, m) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid ^ (uint)(m))]; xk += 1u; } +#define IGNEUM_BCAST0(dst, a) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid & ~31u)]; xk += 1u; } +#endif + +static inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site. OpenCL rotate() rotates left by n modulo 32. +static inline uint rotl_imm(uint x, uint n) { return rotate(x, n); } +// Right rotation by n modulo 32 as a left rotation by (32 - n) modulo 32; n == 0 gives x. +static inline uint rotr_var(uint x, uint n) { return rotate(x, (0u - n) & 31u); } +static inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +static inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +static inline void mh_chacha_block(const uint* x, uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +static inline void mh_cache_segment(__global uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + __global uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +static inline void mh_mixer(uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +static inline void mh_item(__global const uint* cache, uint t, uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + __global const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +static inline uint mh_word(__global const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// Memory-hard dataset (MEMHARD.md). One work-item per cache segment; one work-item per 64-byte dataset item. +// The same constants as memhard.h in this pack (one emitter, three dialects). +__kernel void igneum_cache_fill(__global uint* cache, uint nSegments) { + uint seg = (uint)get_global_id(0); + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__kernel void igneum_build(__global uint* ds, __global const uint* cache, uint nItems) { + uint t = (uint)get_global_id(0); + if (t < nItems) { + uint s[16]; + mh_item(cache, t, s); + __global uint* d = ds + ((ulong)t * 16u); + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per work-item. IGNEUM_GROUP is a multiple of 32; lane = lid & 31 and every exchange stays inside the +// lane's own aligned run of 32 work-items, exactly like simd_shuffle_xor inside a 32-wide Metal SIMD group and +// __shfl_xor_sync inside a CUDA warp. Control flow is uniform (no branches at all). +IGNEUM_KERNEL_HASH void igneum_hash(__global const uint* ds, __global ulong* out, uint baseNonce, uint mask) { + uint gid = (uint)get_global_id(0); + uint lid = (uint)get_local_id(0); + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; +#if IGNEUM_EXCHANGE == 0 + IGNEUM_LOCAL_WORDS(xch, 2 * IGNEUM_GROUP); + uint xk = 0u; +#else + (void)lid; +#endif + { uint x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif + +// Header-bound variant (bind.rs): the init words come from initw, not SEEDW. Same body as igneum_hash. +IGNEUM_KERNEL_HASH void igneum_hash_bound(__global const uint* ds, __global ulong* out, uint baseNonce, uint mask, __global const uint* initw) { + uint gid = (uint)get_global_id(0); + uint lid = (uint)get_local_id(0); + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; + uint iw0 = initw[0], iw1 = initw[1], iw2 = initw[2], iw3 = initw[3], iw4 = initw[4], iw5 = initw[5], iw6 = initw[6], iw7 = initw[7]; +#if IGNEUM_EXCHANGE == 0 + IGNEUM_LOCAL_WORDS(xch, 2 * IGNEUM_GROUP); + uint xk = 0u; +#else + (void)lid; +#endif + { uint x = nonce ^ iw0; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw1; } + { uint x = nonce ^ iw1; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw2; } + { uint x = nonce ^ iw2; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw3; } + { uint x = nonce ^ iw3; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw4; } + { uint x = nonce ^ iw4; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw5; } + { uint x = nonce ^ iw5; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw6; } + { uint x = nonce ^ iw6; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw7; } + { uint x = nonce ^ iw7; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw0; } + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/kernel_bound.cu b/proto-cuda/packs-ca3-v5/v4-genesis/kernel_bound.cu new file mode 100644 index 000000000..4a823531b --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/kernel_bound.cu @@ -0,0 +1,382 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/memhard.h b/proto-cuda/packs-ca3-v5/v4-genesis/memhard.h new file mode 100644 index 000000000..f7f34c732 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/memhard.h @@ -0,0 +1,109 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, uint32_t w) { uint32_t s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/memhard.metal b/proto-cuda/packs-ca3-v5/v4-genesis/memhard.metal new file mode 100644 index 000000000..01b263d6d --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/memhard.metal @@ -0,0 +1,107 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/program.h b/proto-cuda/packs-ca3-v5/v4-genesis/program.h new file mode 100644 index 000000000..55bfd8226 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/program.h @@ -0,0 +1,74 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 4 +#define IGNEUM_PROGRAM_ATTEMPT 0 +#define IGNEUM_PROGRAM_ID 0x853a971d7813fd5cull +#define IGNEUM_DAY_STRING "2026-10-03" +#define IGNEUM_DAY_BYTES_HEX "6461792f323032362d31302d3033" +#define IGNEUM_DAY0 0x3067619fu +#define IGNEUM_DAY1 0x3c269176u +#define IGNEUM_DATASET_LOG2 28 +#define IGNEUM_MASK 0x0fffffffu +#define IGNEUM_LANES 32 +#define IGNEUM_ITERATIONS 8 +#define IGNEUM_INSTR_COUNT 64 +#define IGNEUM_LOADS_PER_HASH 128 +#define IGNEUM_WIDE_LOADS_PER_HASH 0 +#define IGNEUM_OP_MIX "load=16 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1" +// Program class v4 (Counter ASIC 3.0, docs/plans/counter-asic-3-node.md): generator version 4, class v3 plus the +// latency-shadow block (IGNEUM_SHADOW_INSTRS x IGNEUM_SHADOW_REPS per iteration); a worker that runs another class +// refuses this pack, and a job line names the class it wants (class=v4 era=). +#define IGNEUM_PROGRAM_CLASS "v4" +// Class v3 construction (Counter ASIC 2.0, 5 October 2026, docs/plans/mixer-x4.md): version 2 loads; the dataset item +// derivation applies the mixer IGNEUM_MIXER_MULT times per round (memhard.h), and the cache follows the growth rule. +#define IGNEUM_LOAD_CLASS "mx8+sh256x27" +#define IGNEUM_CLASS_MIXER_MULT 8 +#define IGNEUM_CACHE_GROWTH 1 // 1: cache words = 2^(26 + doublings(day)), doublings = floor(log2(1 + day / 1460)) +#define IGNEUM_LOAD_SLOTS 16 +#define IGNEUM_LOAD_MIX { 100, 0, 0 } +#define IGNEUM_LOAD_WIDTH_COUNTS { 16, 0, 0 } // loads of 4, 16, 64 bytes per program +#define IGNEUM_BYTES_PER_HASH 512 +#define IGNEUM_FOLD_ROT 11 +#define IGNEUM_FOLD_MUL 0x9e3779b1u +// Latency-shadow block (Counter ASIC 3.0 item 8, docs/analysis/latency-shadow-2026-10-06.md): NOT the lottery hash. A block of +// IGNEUM_SHADOW_INSTRS ALU instructions (the ten non-load families) runs IGNEUM_SHADOW_REPS times at the end of every +// iteration; the 16 loads, the acceptance rule and the base program are the class's without the shadow. +#define IGNEUM_SHADOW_INSTRS 256 +#define IGNEUM_SHADOW_REPS 27 +#define IGNEUM_SHADOW_INSTRS_PER_HASH 55296 +#define IGNEUM_SHADOW_OP_MIX "add=47 rotl=30 xor=30 shfl=29 mad=27 mul=22 sub=21 rotr=20 mulhi=18 or=12" +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/program.json b/proto-cuda/packs-ca3-v5/v4-genesis/program.json new file mode 100644 index 000000000..76a4e4c27 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/program.json @@ -0,0 +1,390 @@ +{ + "format": "igneum-program-pack-3", + "generator": 4, + "attempt": 0, + "program_id": "0x853a971d7813fd5c", + "program_id_derivation": "FNV-1a 64 over 'igneum-program/' || generator_le32 || seed_words as little-endian bytes || attempt_le32", + "dataset_mode": "memory-hard", + "seed": "igneum-genesis", + "seed_bytes": "69676e65756d2d67656e65736973", + "seed_words": ["0x67a9a7be", "0x1a155b25", "0xfddfb732", "0x4b5af2e8", "0xc55caf33", "0xa27c13b7", "0x06628a48", "0x03852469"], + "seed_derivation": "seed_words = FNV-1a 64 over seed_bytes (attempt 0) or seed_bytes || attempt_le32 (attempt k >= 1), basis ^ (salt * 0x9E3779B97F4A7C15) for salt 0..3, then h ^= h>>33; h *= 0xff51afd7ed558ccd; h ^= h>>33; words[2*salt] = low 32, words[2*salt+1] = high 32", + "generator_rule": "version 2: exactly 16 load slots drawn first from instructions 1..63 (partial Fisher-Yates), the other 48 ops from the ten non-load weights (sum 75); a load's source is drawn from the registers other than dst written by an earlier instruction and not read by a load since; the candidate must pass the acceptance rule of spec 01 section 1.4.6 (static: no cyclically stale load source, every register has an injecting write; dynamic: 64 units on the seed-keyed closed-form dataset with no constant register bit, no lane-constant load site, under 164 saturated final values, every output bit within 136 of 1024, distinct addresses above 245760), else the next attempt of the seed is tried", + "lanes": 32, + "registers": 8, + "iterations": 8, + "instruction_count": 64, + "loads_per_hash": 128, + "program_class": "v4", + "load_class": "mx8+sh256x27", + "mixer_mult": 8, + "cache_growth": true, + "mixer": "class v3 (Counter ASIC 2.0, 5 October 2026, docs/plans/mixer-x4.md): every mixer application of the item derivation is 8 applications with round keys (r * 8 + j + 1) * 0x9E3779B9, the 8 dependent cache reads per item unchanged; cache growth rule option C: cache words = 2^(26 + doublings(day)), dataset words = 2^(genesis_log2 + doublings(day)), doublings(day) = floor(log2(1 + day / 1460)) for day = days since genesis", + "load_slots": 16, + "load_mix_percent_4_16_64": [100, 0, 0], + "load_width_counts_4_16_64": [16, 0, 0], + "bytes_per_hash": 512, + "wide_load": "read-width experiment (5 October 2026, docs/plans/read-width.md), NOT the lottery hash: a load of W words (width field, 4 or 16) reads dataset[b .. b + W) with b = (src & mask) & ~(W - 1) and folds every word into dst: x = dst ^ w[0]; for j in 1..W: x = (rotl(x, 11) * 0x9e3779b1) ^ w[j]; dst = x; width 1 is the plain load; the width is drawn per instruction from the class mix with one extra below(100) draw after the nine of version 2, and the program id is FNV-1a 64 over 'igneum-program-rw/' || generator_le32 || seed words || attempt_le32 || mix[3] || load_slots", + "op_mix": {"load": 16, "add": 8, "shfl": 8, "xor": 6, "mad": 5, "mul": 5, "mulhi": 5, "sub": 4, "rotl": 3, "rotr": 3, "or": 1}, + "register_init": "for i in 0..7: x = nonce ^ seed_words[i]; x += 0x9e3779b9 * (i+1) (mod 2^32); x = splitmix32(x); r[i] = x ^ seed_words[(i+1) & 7]", + "splitmix32": "x ^= x>>16; x *= 0x7feb352d; x ^= x>>15; x *= 0x846ca68b; x ^= x>>16", + "iteration": "sel = r0 sampled once at the top of each iteration, then all instructions in order", + "output": "lo = r0 ^ rotl(r1,7) ^ rotl(r2,14) ^ rotl(r3,21); hi = r4 ^ rotl(r5,9) ^ rotl(r6,18) ^ rotl(r7,27); out = (hi << 32) | lo", + "op_semantics": { + "add": "dst = dst + src + (bit `bit` of sel ? imm2 : imm)", + "sub": "dst = dst - src", + "mul": "dst = dst * src (low 32)", + "mulhi": "dst = high 32 bits of dst * src", + "xor": "dst = dst ^ src", + "or": "dst = dst | src", + "rotl": "dst = rotl(dst, rot), rot in 1..31", + "rotr": "dst = rotr(dst, src & 31)", + "mad": "dst = src * src2 + dst", + "shfl": "dst = dst ^ (src of lane (lane ^ mask)), mask in {1,2,4,8,16}, within the 32-lane warp", + "load": "dst = dst ^ dataset[src & dataset.mask]", + "wload": "base = (src of lane 0 & dataset.mask) & ~31; dst = dst ^ dataset[base + lane] (warp-coalesced 128-byte load, lever b, only when --wide-frac > 0)" + }, + "dataset": { + "log2_words": 28, + "bytes": 1073741824, + "mask": "0x0fffffff", + "day": "2026-10-03", + "day_bytes": "6461792f323032362d31302d3033", + "day_words_from": "seed_words_from_bytes(day_bytes)", + "d0": "0x3067619f", + "d1": "0x3c269176", + "mode": "memory-hard", + "spec": "proto-metal/MEMHARD.md", + "key": ["0x3067619f", "0x3c269176", "0x84a03b03", "0xf8c63294", "0xff977c5b", "0xe60def3e", "0x63630141", "0xb8fbcb58"], + "key_derivation": "the 8 words of seed_words_from_bytes(day_bytes); d0, d1 are key[0], key[1]", + "cache": {"log2_words": 26, "bytes": 268435456, "line_words": 16, "segment_lines": 64, "segments": 65536, "block": "ChaCha12 core + feed-forward, rotations 16 12 8 7", "sigma": ["0x61707865", "0x3320646e", "0x79622d32", "0x6b206574"], "tag": ["0x49676e65", "0x756d4d48"], "chain": "in_j = prev_line ^ (sigma[0..3] || key[0..7] || seg || j || tag[0..1]); line_j = block(in_j); prev_0 = 0"}, + "mixer": {"draw": "SplitMix64 seeded with key[0] | key[1] << 32: rot[0..7] = 1 + next() % 31, mul[0..15] = low32(next()) | 1, rc[0..15] = low32(next())", "rot": [20, 20, 19, 4, 26, 3, 3, 27], "mul": ["0x42146205", "0x52cbe0fb", "0x7ecf4a03", "0x6728907f", "0xd81d9751", "0x132952c3", "0xf60de277", "0x05358035", "0xbaf6499d", "0xe4db9667", "0x3e98f45d", "0xd0004edd", "0x2691630d", "0x9beb3bcf", "0xab310379", "0x99cfb423"], "rc": ["0xbab68293", "0xcc162340", "0x6ce151cc", "0xe62b8997", "0xc9c80297", "0xf74a1654", "0x3d704af5", "0x3cf522b7", "0x2b9cac04", "0xa880ac10", "0x13e5dd1d", "0x6fc3e233", "0x2d83eeac", "0x9006e8bf", "0x2c4b5362", "0x31b49ee2"], "round": "for i in 0..15: s[i] = (s[i] ^ (rc[i] + (r+1) * 0x9E3779B9)) * mul[i]; then quarter rounds on columns (0,4,8,12) (1,5,9,13) (2,6,10,14) (3,7,11,15) with rot[0..3] and diagonals (0,5,10,15) (1,6,11,12) (2,7,8,13) (3,4,9,14) with rot[4..7]", "quarter_round": "a += b; d ^= a; d = rotl(d, r1); c += d; b ^= c; b = rotl(b, r2); a += b; d ^= a; d = rotl(d, r3); c += d; b ^= c; b = rotl(b, r4)"}, + "mixer_mult": 8, + "item": "s[0..7] = key; s[8+i] = t * mul[i] + rc[i] for i in 0..7; for r in 0..7: for j in 0..7: s = M(s, rk = (r * 8 + j + 1) * 0x9E3779B9); line = s[0] & 0x003fffff; s[i] ^= cache[line * 16 + i]; then for j in 0..7: s = M(s, rk = (64 + j + 1) * 0x9E3779B9); item(t) = s", + "word": "dataset[w] = item(w >> 4)[w & 15]" + }, + "shadow": {"instrs": 256, "reps": 27, "instrs_per_hash": 55296, "op_mix": {"add": 47, "rotl": 30, "xor": 30, "shfl": 29, "mad": 27, "mul": 22, "sub": 21, "rotr": 20, "mulhi": 18, "or": 12}, "rule": "Counter ASIC 3.0 item 8 (docs/analysis/latency-shadow-2026-10-06.md): after the 64 base instructions the program stream draws instrs more ALU instructions (the non-load table, nine draws each, the source as on an ALU slot); the block runs reps times at the end of every iteration with the iteration's sel; the acceptance rule interprets the base program only", "program_id_suffix": "'shadow/' || instrs_le16 || reps_le16", "instructions": [ + {"i": 0, "op": "add", "dst": 5, "src": 2, "src2": 1, "imm": "0x92199f99", "imm2": "0x8bc12da9", "rot": 9, "bit": 18, "mask": 4}, + {"i": 1, "op": "add", "dst": 0, "src": 7, "src2": 1, "imm": "0x8d72d3ad", "imm2": "0x63079e5a", "rot": 20, "bit": 26, "mask": 4}, + {"i": 2, "op": "shfl", "dst": 6, "src": 3, "src2": 6, "imm": "0x9beaeddf", "imm2": "0x744ecb00", "rot": 10, "bit": 4, "mask": 2}, + {"i": 3, "op": "sub", "dst": 4, "src": 2, "src2": 0, "imm": "0x2a3ddc67", "imm2": "0x72c80241", "rot": 30, "bit": 1, "mask": 16}, + {"i": 4, "op": "add", "dst": 7, "src": 0, "src2": 5, "imm": "0xb21b4bab", "imm2": "0x5d4c7a60", "rot": 17, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 0, "src": 6, "src2": 3, "imm": "0xe69d7919", "imm2": "0xa048c61e", "rot": 11, "bit": 1, "mask": 8}, + {"i": 6, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2fe0e98b", "imm2": "0xc88e2942", "rot": 5, "bit": 16, "mask": 16}, + {"i": 7, "op": "xor", "dst": 7, "src": 1, "src2": 0, "imm": "0xc16efe98", "imm2": "0x01a638c8", "rot": 8, "bit": 17, "mask": 1}, + {"i": 8, "op": "mad", "dst": 1, "src": 6, "src2": 5, "imm": "0x76ec7b8b", "imm2": "0x25663feb", "rot": 29, "bit": 30, "mask": 2}, + {"i": 9, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x6c8ee3cb", "imm2": "0xea93237e", "rot": 27, "bit": 1, "mask": 4}, + {"i": 10, "op": "mad", "dst": 1, "src": 2, "src2": 2, "imm": "0x6dc4ea18", "imm2": "0x6efde6f5", "rot": 3, "bit": 20, "mask": 2}, + {"i": 11, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x023613fc", "imm2": "0x18c51939", "rot": 19, "bit": 31, "mask": 1}, + {"i": 12, "op": "shfl", "dst": 2, "src": 6, "src2": 1, "imm": "0x74aec8d2", "imm2": "0x7f7ad29c", "rot": 7, "bit": 8, "mask": 4}, + {"i": 13, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xbdf8f9a5", "imm2": "0xbc48c63e", "rot": 6, "bit": 25, "mask": 2}, + {"i": 14, "op": "rotl", "dst": 1, "src": 2, "src2": 6, "imm": "0x7ad8ca8b", "imm2": "0x14c712ad", "rot": 29, "bit": 25, "mask": 8}, + {"i": 15, "op": "sub", "dst": 1, "src": 4, "src2": 5, "imm": "0xd3349f69", "imm2": "0x70aac45a", "rot": 29, "bit": 9, "mask": 16}, + {"i": 16, "op": "or", "dst": 7, "src": 1, "src2": 2, "imm": "0x08168ed1", "imm2": "0x28964037", "rot": 26, "bit": 0, "mask": 2}, + {"i": 17, "op": "shfl", "dst": 2, "src": 4, "src2": 6, "imm": "0x98d85f72", "imm2": "0x3dc87042", "rot": 29, "bit": 22, "mask": 8}, + {"i": 18, "op": "xor", "dst": 7, "src": 4, "src2": 0, "imm": "0x651d4a0e", "imm2": "0x93c198bd", "rot": 26, "bit": 12, "mask": 8}, + {"i": 19, "op": "mul", "dst": 6, "src": 1, "src2": 6, "imm": "0xd38ce89d", "imm2": "0x3dfad388", "rot": 5, "bit": 28, "mask": 8}, + {"i": 20, "op": "mad", "dst": 5, "src": 6, "src2": 0, "imm": "0x59d78b36", "imm2": "0xc4db274e", "rot": 25, "bit": 24, "mask": 1}, + {"i": 21, "op": "sub", "dst": 3, "src": 1, "src2": 7, "imm": "0xf6c6a6c7", "imm2": "0x8536f4e6", "rot": 6, "bit": 12, "mask": 4}, + {"i": 22, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x599445b4", "imm2": "0x632f8c32", "rot": 19, "bit": 4, "mask": 8}, + {"i": 23, "op": "add", "dst": 2, "src": 0, "src2": 7, "imm": "0x45c37cec", "imm2": "0x96e8f127", "rot": 15, "bit": 1, "mask": 4}, + {"i": 24, "op": "sub", "dst": 6, "src": 4, "src2": 3, "imm": "0xc1c44491", "imm2": "0x92e3ce57", "rot": 20, "bit": 25, "mask": 4}, + {"i": 25, "op": "mad", "dst": 7, "src": 3, "src2": 4, "imm": "0x89bfb8d3", "imm2": "0x19b5455e", "rot": 22, "bit": 2, "mask": 16}, + {"i": 26, "op": "rotl", "dst": 3, "src": 5, "src2": 7, "imm": "0x2f47ce8d", "imm2": "0x8b458ec5", "rot": 9, "bit": 0, "mask": 4}, + {"i": 27, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0x9f0dce23", "imm2": "0x3cdca814", "rot": 25, "bit": 1, "mask": 2}, + {"i": 28, "op": "mulhi", "dst": 6, "src": 0, "src2": 3, "imm": "0x61fc9eb8", "imm2": "0x23202e9d", "rot": 30, "bit": 16, "mask": 16}, + {"i": 29, "op": "shfl", "dst": 2, "src": 4, "src2": 3, "imm": "0x339dbd65", "imm2": "0xc175f639", "rot": 15, "bit": 22, "mask": 2}, + {"i": 30, "op": "shfl", "dst": 1, "src": 6, "src2": 1, "imm": "0x5bd14589", "imm2": "0xa68a2bed", "rot": 31, "bit": 31, "mask": 1}, + {"i": 31, "op": "add", "dst": 1, "src": 6, "src2": 1, "imm": "0x37985632", "imm2": "0xb1cdb2ab", "rot": 29, "bit": 1, "mask": 8}, + {"i": 32, "op": "rotr", "dst": 0, "src": 1, "src2": 6, "imm": "0x4b2058f4", "imm2": "0xf06d8ac9", "rot": 9, "bit": 15, "mask": 16}, + {"i": 33, "op": "shfl", "dst": 3, "src": 4, "src2": 4, "imm": "0x2081626c", "imm2": "0x08d1bb87", "rot": 24, "bit": 29, "mask": 2}, + {"i": 34, "op": "shfl", "dst": 0, "src": 3, "src2": 6, "imm": "0xe4fcfe03", "imm2": "0x78a46b13", "rot": 15, "bit": 29, "mask": 4}, + {"i": 35, "op": "mul", "dst": 7, "src": 0, "src2": 4, "imm": "0x33148d30", "imm2": "0x5780a3d6", "rot": 6, "bit": 11, "mask": 2}, + {"i": 36, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0x804e777e", "imm2": "0x856e0180", "rot": 22, "bit": 0, "mask": 16}, + {"i": 37, "op": "xor", "dst": 1, "src": 6, "src2": 0, "imm": "0xc69aa2f6", "imm2": "0xafebe3e8", "rot": 15, "bit": 9, "mask": 16}, + {"i": 38, "op": "mul", "dst": 2, "src": 7, "src2": 4, "imm": "0xeb4c4082", "imm2": "0x3f1e0da7", "rot": 25, "bit": 20, "mask": 16}, + {"i": 39, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0x0b06c8a7", "imm2": "0xe9bd0cc4", "rot": 6, "bit": 2, "mask": 4}, + {"i": 40, "op": "mul", "dst": 5, "src": 7, "src2": 7, "imm": "0x070af1b6", "imm2": "0x6b648e75", "rot": 10, "bit": 6, "mask": 16}, + {"i": 41, "op": "mulhi", "dst": 2, "src": 3, "src2": 2, "imm": "0x389753b2", "imm2": "0x9e657305", "rot": 30, "bit": 2, "mask": 4}, + {"i": 42, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x0960e5b9", "imm2": "0xa925a406", "rot": 4, "bit": 6, "mask": 16}, + {"i": 43, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0x8eabe09f", "imm2": "0x76ef71e2", "rot": 4, "bit": 19, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 4, "src": 3, "src2": 7, "imm": "0x6a34768a", "imm2": "0x2e427c64", "rot": 21, "bit": 5, "mask": 4}, + {"i": 45, "op": "add", "dst": 6, "src": 7, "src2": 5, "imm": "0xee822e17", "imm2": "0xcdcb63f6", "rot": 27, "bit": 12, "mask": 16}, + {"i": 46, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xc89ead43", "imm2": "0x4d3108b2", "rot": 26, "bit": 17, "mask": 1}, + {"i": 47, "op": "shfl", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd62be9e", "imm2": "0xf243f6f2", "rot": 8, "bit": 4, "mask": 8}, + {"i": 48, "op": "mulhi", "dst": 6, "src": 5, "src2": 0, "imm": "0xd3f7fa72", "imm2": "0x0debc83f", "rot": 25, "bit": 5, "mask": 2}, + {"i": 49, "op": "sub", "dst": 0, "src": 2, "src2": 6, "imm": "0x7afadd15", "imm2": "0xc07fc39c", "rot": 30, "bit": 29, "mask": 8}, + {"i": 50, "op": "sub", "dst": 3, "src": 5, "src2": 3, "imm": "0x179b78ec", "imm2": "0xaeccde37", "rot": 30, "bit": 17, "mask": 1}, + {"i": 51, "op": "rotr", "dst": 1, "src": 4, "src2": 1, "imm": "0xa4bfcea6", "imm2": "0xbf63bb2f", "rot": 2, "bit": 21, "mask": 2}, + {"i": 52, "op": "mad", "dst": 6, "src": 7, "src2": 7, "imm": "0xabf5ed10", "imm2": "0x8a285f51", "rot": 3, "bit": 23, "mask": 2}, + {"i": 53, "op": "xor", "dst": 5, "src": 3, "src2": 5, "imm": "0x88b416eb", "imm2": "0x36271d87", "rot": 19, "bit": 10, "mask": 2}, + {"i": 54, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0xa3417dd3", "imm2": "0xcd98f620", "rot": 28, "bit": 2, "mask": 1}, + {"i": 55, "op": "sub", "dst": 5, "src": 6, "src2": 2, "imm": "0x45996c6f", "imm2": "0xe3d41087", "rot": 4, "bit": 31, "mask": 1}, + {"i": 56, "op": "add", "dst": 3, "src": 2, "src2": 0, "imm": "0x3dfad1b6", "imm2": "0xd4758987", "rot": 27, "bit": 10, "mask": 2}, + {"i": 57, "op": "add", "dst": 4, "src": 1, "src2": 3, "imm": "0xfca75bc2", "imm2": "0x0602d6be", "rot": 19, "bit": 0, "mask": 16}, + {"i": 58, "op": "mulhi", "dst": 5, "src": 6, "src2": 5, "imm": "0x83250a7b", "imm2": "0x2f93d53b", "rot": 25, "bit": 7, "mask": 2}, + {"i": 59, "op": "shfl", "dst": 2, "src": 1, "src2": 0, "imm": "0x13f4a089", "imm2": "0x145ea125", "rot": 12, "bit": 3, "mask": 2}, + {"i": 60, "op": "rotl", "dst": 2, "src": 5, "src2": 6, "imm": "0xad3170e3", "imm2": "0x15db04d1", "rot": 9, "bit": 13, "mask": 2}, + {"i": 61, "op": "or", "dst": 4, "src": 6, "src2": 2, "imm": "0x4b6305b2", "imm2": "0x6e7b2e9c", "rot": 27, "bit": 16, "mask": 4}, + {"i": 62, "op": "rotr", "dst": 6, "src": 4, "src2": 6, "imm": "0xfcd4b1c9", "imm2": "0xaf5c733b", "rot": 6, "bit": 21, "mask": 16}, + {"i": 63, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x95cebb3e", "imm2": "0xbba9cdfc", "rot": 19, "bit": 23, "mask": 1}, + {"i": 64, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x5f7579ff", "imm2": "0xb104e01a", "rot": 25, "bit": 12, "mask": 8}, + {"i": 65, "op": "xor", "dst": 2, "src": 7, "src2": 3, "imm": "0x749c7611", "imm2": "0xf17df3bb", "rot": 27, "bit": 26, "mask": 2}, + {"i": 66, "op": "add", "dst": 2, "src": 1, "src2": 6, "imm": "0xd71c02ff", "imm2": "0x8596687a", "rot": 4, "bit": 6, "mask": 2}, + {"i": 67, "op": "rotl", "dst": 1, "src": 3, "src2": 2, "imm": "0xd2864071", "imm2": "0xaa644ef3", "rot": 21, "bit": 5, "mask": 1}, + {"i": 68, "op": "mul", "dst": 3, "src": 2, "src2": 1, "imm": "0xd0689a5f", "imm2": "0xa3a1f063", "rot": 13, "bit": 28, "mask": 2}, + {"i": 69, "op": "shfl", "dst": 7, "src": 5, "src2": 6, "imm": "0xd01476eb", "imm2": "0x76abb5c2", "rot": 7, "bit": 30, "mask": 2}, + {"i": 70, "op": "mul", "dst": 3, "src": 2, "src2": 5, "imm": "0x59a75c10", "imm2": "0x1e1fbb72", "rot": 20, "bit": 16, "mask": 1}, + {"i": 71, "op": "mad", "dst": 0, "src": 2, "src2": 5, "imm": "0x39cca1df", "imm2": "0x22c057ac", "rot": 5, "bit": 23, "mask": 16}, + {"i": 72, "op": "add", "dst": 6, "src": 7, "src2": 3, "imm": "0x3c6fe15d", "imm2": "0x08ac5733", "rot": 14, "bit": 0, "mask": 4}, + {"i": 73, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x2098627d", "imm2": "0xf4fecc81", "rot": 20, "bit": 30, "mask": 8}, + {"i": 74, "op": "mul", "dst": 3, "src": 6, "src2": 5, "imm": "0xf82e9e23", "imm2": "0x3ad62132", "rot": 10, "bit": 14, "mask": 16}, + {"i": 75, "op": "xor", "dst": 6, "src": 7, "src2": 4, "imm": "0x70548a91", "imm2": "0xa9715d2e", "rot": 6, "bit": 24, "mask": 1}, + {"i": 76, "op": "or", "dst": 3, "src": 0, "src2": 7, "imm": "0xa164325f", "imm2": "0xf300838b", "rot": 23, "bit": 23, "mask": 16}, + {"i": 77, "op": "add", "dst": 2, "src": 4, "src2": 6, "imm": "0x295d5fae", "imm2": "0xc100b495", "rot": 7, "bit": 1, "mask": 2}, + {"i": 78, "op": "mulhi", "dst": 3, "src": 7, "src2": 4, "imm": "0xb62cca87", "imm2": "0x2ebde415", "rot": 14, "bit": 7, "mask": 2}, + {"i": 79, "op": "or", "dst": 4, "src": 1, "src2": 7, "imm": "0xfcbc482d", "imm2": "0x8876e6cd", "rot": 29, "bit": 5, "mask": 2}, + {"i": 80, "op": "rotr", "dst": 4, "src": 3, "src2": 0, "imm": "0x6d64013b", "imm2": "0x675f4a8d", "rot": 26, "bit": 18, "mask": 8}, + {"i": 81, "op": "add", "dst": 4, "src": 3, "src2": 3, "imm": "0x274a9221", "imm2": "0x5cc59530", "rot": 15, "bit": 15, "mask": 2}, + {"i": 82, "op": "add", "dst": 7, "src": 3, "src2": 0, "imm": "0xc8651f8e", "imm2": "0x141479ec", "rot": 18, "bit": 5, "mask": 1}, + {"i": 83, "op": "rotr", "dst": 3, "src": 6, "src2": 0, "imm": "0xcc8a7766", "imm2": "0xc2eb5161", "rot": 4, "bit": 29, "mask": 2}, + {"i": 84, "op": "mad", "dst": 2, "src": 4, "src2": 7, "imm": "0xbc507d51", "imm2": "0x0b1196fd", "rot": 9, "bit": 7, "mask": 8}, + {"i": 85, "op": "shfl", "dst": 2, "src": 5, "src2": 5, "imm": "0x5a156c90", "imm2": "0xa6b3fbfa", "rot": 11, "bit": 2, "mask": 16}, + {"i": 86, "op": "xor", "dst": 3, "src": 2, "src2": 1, "imm": "0x8b042658", "imm2": "0xacf37a8f", "rot": 12, "bit": 23, "mask": 16}, + {"i": 87, "op": "shfl", "dst": 5, "src": 7, "src2": 2, "imm": "0x1a214238", "imm2": "0x017fdf5d", "rot": 29, "bit": 14, "mask": 2}, + {"i": 88, "op": "xor", "dst": 0, "src": 4, "src2": 2, "imm": "0xd523e612", "imm2": "0x2158c2ed", "rot": 30, "bit": 14, "mask": 4}, + {"i": 89, "op": "add", "dst": 3, "src": 2, "src2": 7, "imm": "0x53f915c2", "imm2": "0x883c0c92", "rot": 9, "bit": 18, "mask": 8}, + {"i": 90, "op": "rotr", "dst": 7, "src": 5, "src2": 5, "imm": "0xbd633b21", "imm2": "0xcf8c356c", "rot": 25, "bit": 31, "mask": 4}, + {"i": 91, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0xe2be00a5", "imm2": "0x3cc5bd20", "rot": 10, "bit": 31, "mask": 1}, + {"i": 92, "op": "shfl", "dst": 7, "src": 2, "src2": 4, "imm": "0x3d3da600", "imm2": "0x1f22df89", "rot": 4, "bit": 24, "mask": 1}, + {"i": 93, "op": "rotr", "dst": 6, "src": 2, "src2": 7, "imm": "0xb0f57471", "imm2": "0x8f2a7eca", "rot": 16, "bit": 25, "mask": 1}, + {"i": 94, "op": "rotl", "dst": 7, "src": 0, "src2": 4, "imm": "0x00a21815", "imm2": "0xeb4d7218", "rot": 14, "bit": 18, "mask": 16}, + {"i": 95, "op": "mad", "dst": 4, "src": 5, "src2": 5, "imm": "0xc4c3828e", "imm2": "0xfb7bba17", "rot": 16, "bit": 10, "mask": 16}, + {"i": 96, "op": "mad", "dst": 2, "src": 4, "src2": 5, "imm": "0xfc5bbc75", "imm2": "0xfc43468f", "rot": 31, "bit": 20, "mask": 16}, + {"i": 97, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x1fe9c249", "imm2": "0x164bb16b", "rot": 15, "bit": 9, "mask": 4}, + {"i": 98, "op": "mul", "dst": 5, "src": 4, "src2": 1, "imm": "0xeda725fa", "imm2": "0x66f7e9a2", "rot": 21, "bit": 6, "mask": 2}, + {"i": 99, "op": "sub", "dst": 2, "src": 0, "src2": 7, "imm": "0x8fb29f7d", "imm2": "0xf530eda1", "rot": 27, "bit": 30, "mask": 4}, + {"i": 100, "op": "rotl", "dst": 7, "src": 2, "src2": 0, "imm": "0x9f4de742", "imm2": "0x9b5ff871", "rot": 30, "bit": 21, "mask": 16}, + {"i": 101, "op": "add", "dst": 5, "src": 6, "src2": 7, "imm": "0x423fd9c9", "imm2": "0xbfd646cb", "rot": 17, "bit": 17, "mask": 2}, + {"i": 102, "op": "add", "dst": 7, "src": 6, "src2": 3, "imm": "0x8d3c011d", "imm2": "0x19b74a43", "rot": 12, "bit": 11, "mask": 4}, + {"i": 103, "op": "rotl", "dst": 5, "src": 6, "src2": 0, "imm": "0xcfc70303", "imm2": "0xf2b3e8ef", "rot": 6, "bit": 24, "mask": 1}, + {"i": 104, "op": "mul", "dst": 0, "src": 4, "src2": 5, "imm": "0x650475eb", "imm2": "0x11dcbd94", "rot": 15, "bit": 10, "mask": 1}, + {"i": 105, "op": "or", "dst": 0, "src": 5, "src2": 3, "imm": "0xaacaa145", "imm2": "0x9139d3fe", "rot": 4, "bit": 18, "mask": 2}, + {"i": 106, "op": "add", "dst": 0, "src": 1, "src2": 7, "imm": "0x8ce14721", "imm2": "0x7dcb7e18", "rot": 24, "bit": 15, "mask": 8}, + {"i": 107, "op": "rotl", "dst": 0, "src": 3, "src2": 3, "imm": "0xb36d6d98", "imm2": "0x2c3390c8", "rot": 15, "bit": 10, "mask": 16}, + {"i": 108, "op": "sub", "dst": 4, "src": 2, "src2": 5, "imm": "0xf6bbdaef", "imm2": "0x9db6f65e", "rot": 25, "bit": 10, "mask": 1}, + {"i": 109, "op": "mulhi", "dst": 2, "src": 0, "src2": 0, "imm": "0xb1721fd6", "imm2": "0xd96d52c9", "rot": 1, "bit": 27, "mask": 8}, + {"i": 110, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0xfb4ca37f", "imm2": "0xb6ec7dbe", "rot": 27, "bit": 12, "mask": 8}, + {"i": 111, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x2d9fc6b9", "imm2": "0x3c179ad8", "rot": 9, "bit": 28, "mask": 16}, + {"i": 112, "op": "mulhi", "dst": 2, "src": 0, "src2": 6, "imm": "0x71a9f6bd", "imm2": "0xd3417bf5", "rot": 2, "bit": 14, "mask": 8}, + {"i": 113, "op": "sub", "dst": 6, "src": 3, "src2": 5, "imm": "0xa3d19400", "imm2": "0x15df7330", "rot": 5, "bit": 2, "mask": 8}, + {"i": 114, "op": "mad", "dst": 7, "src": 6, "src2": 3, "imm": "0x1400d92e", "imm2": "0xfa4a158e", "rot": 16, "bit": 9, "mask": 1}, + {"i": 115, "op": "rotr", "dst": 5, "src": 1, "src2": 3, "imm": "0xd01684c3", "imm2": "0x6367febb", "rot": 23, "bit": 19, "mask": 2}, + {"i": 116, "op": "rotr", "dst": 6, "src": 4, "src2": 2, "imm": "0x8cd9eb96", "imm2": "0x98f33b24", "rot": 25, "bit": 1, "mask": 2}, + {"i": 117, "op": "add", "dst": 2, "src": 1, "src2": 7, "imm": "0x502138e2", "imm2": "0x47359729", "rot": 5, "bit": 22, "mask": 4}, + {"i": 118, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xd94a35c7", "imm2": "0xb83416c3", "rot": 11, "bit": 3, "mask": 4}, + {"i": 119, "op": "mul", "dst": 1, "src": 3, "src2": 6, "imm": "0x09b30cf7", "imm2": "0xef3b98e7", "rot": 17, "bit": 23, "mask": 8}, + {"i": 120, "op": "mad", "dst": 2, "src": 0, "src2": 4, "imm": "0x56416fe0", "imm2": "0x5e1dc8f3", "rot": 17, "bit": 14, "mask": 2}, + {"i": 121, "op": "mul", "dst": 0, "src": 3, "src2": 2, "imm": "0x2892697c", "imm2": "0x9cb3b14e", "rot": 29, "bit": 25, "mask": 2}, + {"i": 122, "op": "mulhi", "dst": 2, "src": 0, "src2": 3, "imm": "0xc33089a1", "imm2": "0xd6c5b530", "rot": 27, "bit": 13, "mask": 8}, + {"i": 123, "op": "mul", "dst": 5, "src": 6, "src2": 4, "imm": "0xdfe04e4a", "imm2": "0x3cc40160", "rot": 3, "bit": 14, "mask": 2}, + {"i": 124, "op": "mad", "dst": 4, "src": 2, "src2": 4, "imm": "0xb33dc1b7", "imm2": "0xab97743a", "rot": 7, "bit": 21, "mask": 4}, + {"i": 125, "op": "shfl", "dst": 4, "src": 2, "src2": 0, "imm": "0xfd469909", "imm2": "0xfc85dc55", "rot": 28, "bit": 24, "mask": 2}, + {"i": 126, "op": "xor", "dst": 2, "src": 0, "src2": 5, "imm": "0xa0094578", "imm2": "0xf1bee474", "rot": 31, "bit": 7, "mask": 2}, + {"i": 127, "op": "rotl", "dst": 1, "src": 7, "src2": 2, "imm": "0xb7ae00a0", "imm2": "0x86cce297", "rot": 7, "bit": 31, "mask": 8}, + {"i": 128, "op": "shfl", "dst": 7, "src": 2, "src2": 7, "imm": "0x019d1940", "imm2": "0x3fe9e7dd", "rot": 14, "bit": 4, "mask": 4}, + {"i": 129, "op": "rotl", "dst": 6, "src": 7, "src2": 7, "imm": "0x40a74cc4", "imm2": "0x09eb4adf", "rot": 17, "bit": 30, "mask": 1}, + {"i": 130, "op": "add", "dst": 2, "src": 5, "src2": 5, "imm": "0x33dff776", "imm2": "0x6c57e4e7", "rot": 27, "bit": 15, "mask": 4}, + {"i": 131, "op": "or", "dst": 0, "src": 3, "src2": 1, "imm": "0xe0c53bb9", "imm2": "0x124404f6", "rot": 4, "bit": 21, "mask": 16}, + {"i": 132, "op": "rotr", "dst": 5, "src": 0, "src2": 1, "imm": "0xe4353fce", "imm2": "0x559d0118", "rot": 2, "bit": 29, "mask": 4}, + {"i": 133, "op": "add", "dst": 2, "src": 3, "src2": 6, "imm": "0x5db25b34", "imm2": "0xe8212c0c", "rot": 21, "bit": 30, "mask": 1}, + {"i": 134, "op": "xor", "dst": 4, "src": 3, "src2": 6, "imm": "0x7366e50e", "imm2": "0x7cc1ffbd", "rot": 19, "bit": 18, "mask": 16}, + {"i": 135, "op": "xor", "dst": 6, "src": 1, "src2": 2, "imm": "0xa36decb7", "imm2": "0x79291734", "rot": 26, "bit": 0, "mask": 8}, + {"i": 136, "op": "sub", "dst": 1, "src": 7, "src2": 0, "imm": "0x225b03e4", "imm2": "0x7183e193", "rot": 16, "bit": 6, "mask": 2}, + {"i": 137, "op": "mad", "dst": 2, "src": 6, "src2": 2, "imm": "0x6f620d51", "imm2": "0x4e814e19", "rot": 6, "bit": 6, "mask": 2}, + {"i": 138, "op": "mulhi", "dst": 0, "src": 5, "src2": 6, "imm": "0x919d6bf3", "imm2": "0xc6240638", "rot": 17, "bit": 11, "mask": 16}, + {"i": 139, "op": "add", "dst": 2, "src": 7, "src2": 7, "imm": "0x218d4090", "imm2": "0xd44ff710", "rot": 1, "bit": 10, "mask": 16}, + {"i": 140, "op": "rotr", "dst": 1, "src": 4, "src2": 4, "imm": "0x4cbfa722", "imm2": "0x114e9564", "rot": 28, "bit": 9, "mask": 16}, + {"i": 141, "op": "shfl", "dst": 3, "src": 6, "src2": 2, "imm": "0xf702c6a1", "imm2": "0xf8f3c5d9", "rot": 7, "bit": 24, "mask": 1}, + {"i": 142, "op": "mad", "dst": 7, "src": 6, "src2": 2, "imm": "0xa2d285be", "imm2": "0x9cc94532", "rot": 15, "bit": 20, "mask": 8}, + {"i": 143, "op": "mul", "dst": 2, "src": 3, "src2": 7, "imm": "0x08b7ed80", "imm2": "0xa8abced4", "rot": 18, "bit": 10, "mask": 4}, + {"i": 144, "op": "add", "dst": 7, "src": 4, "src2": 2, "imm": "0xf4b1a8de", "imm2": "0xb98942fa", "rot": 18, "bit": 29, "mask": 8}, + {"i": 145, "op": "rotl", "dst": 7, "src": 6, "src2": 1, "imm": "0x64b6ba2d", "imm2": "0xf9e86793", "rot": 15, "bit": 24, "mask": 8}, + {"i": 146, "op": "xor", "dst": 7, "src": 5, "src2": 3, "imm": "0x41c42b5f", "imm2": "0x7c7e0e39", "rot": 8, "bit": 23, "mask": 2}, + {"i": 147, "op": "mad", "dst": 4, "src": 7, "src2": 4, "imm": "0x3caa807a", "imm2": "0x553a0cec", "rot": 11, "bit": 22, "mask": 8}, + {"i": 148, "op": "rotr", "dst": 6, "src": 5, "src2": 3, "imm": "0x3cb1289a", "imm2": "0x6b36f78a", "rot": 1, "bit": 9, "mask": 16}, + {"i": 149, "op": "mad", "dst": 1, "src": 2, "src2": 4, "imm": "0x95310ea8", "imm2": "0xc533aa6a", "rot": 16, "bit": 17, "mask": 1}, + {"i": 150, "op": "add", "dst": 1, "src": 7, "src2": 7, "imm": "0x2bef10f2", "imm2": "0x0d48ba42", "rot": 8, "bit": 17, "mask": 4}, + {"i": 151, "op": "xor", "dst": 5, "src": 4, "src2": 7, "imm": "0xda997ab2", "imm2": "0xae31d69e", "rot": 11, "bit": 31, "mask": 2}, + {"i": 152, "op": "add", "dst": 7, "src": 0, "src2": 6, "imm": "0xdc5cc080", "imm2": "0xc98dea9c", "rot": 16, "bit": 30, "mask": 2}, + {"i": 153, "op": "mul", "dst": 4, "src": 6, "src2": 7, "imm": "0xbfbf5f6c", "imm2": "0x61f611bb", "rot": 14, "bit": 22, "mask": 2}, + {"i": 154, "op": "mul", "dst": 0, "src": 2, "src2": 3, "imm": "0xa78008c3", "imm2": "0xbad5eeb1", "rot": 10, "bit": 28, "mask": 8}, + {"i": 155, "op": "xor", "dst": 6, "src": 5, "src2": 4, "imm": "0x1a73b866", "imm2": "0x1f5a62c9", "rot": 9, "bit": 27, "mask": 8}, + {"i": 156, "op": "rotr", "dst": 4, "src": 2, "src2": 0, "imm": "0x9c88500c", "imm2": "0xe25dccf9", "rot": 11, "bit": 2, "mask": 16}, + {"i": 157, "op": "rotl", "dst": 1, "src": 4, "src2": 4, "imm": "0xb05e7669", "imm2": "0x9db704b1", "rot": 11, "bit": 28, "mask": 4}, + {"i": 158, "op": "add", "dst": 5, "src": 0, "src2": 6, "imm": "0x18197438", "imm2": "0x6c752dcb", "rot": 11, "bit": 11, "mask": 2}, + {"i": 159, "op": "mad", "dst": 4, "src": 1, "src2": 5, "imm": "0x4796a65e", "imm2": "0x00e08c7a", "rot": 8, "bit": 19, "mask": 4}, + {"i": 160, "op": "rotl", "dst": 4, "src": 7, "src2": 5, "imm": "0x08a03052", "imm2": "0x0204f0ba", "rot": 26, "bit": 5, "mask": 2}, + {"i": 161, "op": "mad", "dst": 3, "src": 0, "src2": 7, "imm": "0xa0603b0e", "imm2": "0x7eee83d5", "rot": 28, "bit": 22, "mask": 16}, + {"i": 162, "op": "rotr", "dst": 3, "src": 1, "src2": 6, "imm": "0x78a3c69d", "imm2": "0x684693a0", "rot": 21, "bit": 23, "mask": 4}, + {"i": 163, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xf1c46574", "imm2": "0x8e481727", "rot": 9, "bit": 3, "mask": 4}, + {"i": 164, "op": "mulhi", "dst": 0, "src": 4, "src2": 3, "imm": "0x04644afa", "imm2": "0x64bda2b5", "rot": 26, "bit": 16, "mask": 16}, + {"i": 165, "op": "add", "dst": 2, "src": 6, "src2": 2, "imm": "0xac578137", "imm2": "0x550ab406", "rot": 13, "bit": 20, "mask": 16}, + {"i": 166, "op": "rotl", "dst": 0, "src": 4, "src2": 5, "imm": "0x7f564760", "imm2": "0xb9a8b4f8", "rot": 13, "bit": 29, "mask": 1}, + {"i": 167, "op": "add", "dst": 3, "src": 1, "src2": 0, "imm": "0xa33e6706", "imm2": "0xaebb5966", "rot": 12, "bit": 14, "mask": 16}, + {"i": 168, "op": "or", "dst": 3, "src": 5, "src2": 3, "imm": "0x65b2f3eb", "imm2": "0xb1d00d20", "rot": 12, "bit": 2, "mask": 8}, + {"i": 169, "op": "rotr", "dst": 6, "src": 2, "src2": 3, "imm": "0x7f21faf5", "imm2": "0xbbf0d3f9", "rot": 17, "bit": 13, "mask": 8}, + {"i": 170, "op": "xor", "dst": 4, "src": 6, "src2": 2, "imm": "0x162c7140", "imm2": "0x90d404ad", "rot": 26, "bit": 1, "mask": 4}, + {"i": 171, "op": "sub", "dst": 6, "src": 1, "src2": 7, "imm": "0x6ef9c76e", "imm2": "0xfb7ba272", "rot": 31, "bit": 25, "mask": 1}, + {"i": 172, "op": "rotl", "dst": 7, "src": 5, "src2": 4, "imm": "0xde04eb3b", "imm2": "0xd56caa00", "rot": 22, "bit": 21, "mask": 4}, + {"i": 173, "op": "rotl", "dst": 5, "src": 3, "src2": 5, "imm": "0xa9eac934", "imm2": "0x2c338e51", "rot": 15, "bit": 22, "mask": 2}, + {"i": 174, "op": "shfl", "dst": 7, "src": 0, "src2": 3, "imm": "0x700be4e3", "imm2": "0x4bcfc732", "rot": 19, "bit": 6, "mask": 8}, + {"i": 175, "op": "xor", "dst": 0, "src": 5, "src2": 1, "imm": "0x02ccdba9", "imm2": "0xd0915be0", "rot": 15, "bit": 2, "mask": 16}, + {"i": 176, "op": "rotl", "dst": 7, "src": 4, "src2": 1, "imm": "0x489c8165", "imm2": "0xf24b5a4f", "rot": 6, "bit": 22, "mask": 1}, + {"i": 177, "op": "sub", "dst": 7, "src": 0, "src2": 6, "imm": "0x23ad9693", "imm2": "0x9a8c2f7b", "rot": 24, "bit": 2, "mask": 2}, + {"i": 178, "op": "rotl", "dst": 3, "src": 0, "src2": 6, "imm": "0xafa72a42", "imm2": "0x371d74ee", "rot": 30, "bit": 16, "mask": 1}, + {"i": 179, "op": "mad", "dst": 7, "src": 6, "src2": 1, "imm": "0x18a2a3f3", "imm2": "0xb811b951", "rot": 2, "bit": 9, "mask": 2}, + {"i": 180, "op": "rotl", "dst": 6, "src": 4, "src2": 1, "imm": "0xe6c69c0e", "imm2": "0xfc46a951", "rot": 9, "bit": 31, "mask": 4}, + {"i": 181, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0xbd1b89e4", "imm2": "0xdf4bce5c", "rot": 15, "bit": 19, "mask": 4}, + {"i": 182, "op": "xor", "dst": 2, "src": 7, "src2": 5, "imm": "0x3dd12aed", "imm2": "0xd0756a69", "rot": 13, "bit": 16, "mask": 4}, + {"i": 183, "op": "xor", "dst": 7, "src": 2, "src2": 3, "imm": "0x77ce69d6", "imm2": "0x2b39bdf2", "rot": 8, "bit": 22, "mask": 16}, + {"i": 184, "op": "add", "dst": 1, "src": 2, "src2": 4, "imm": "0xd94d55ac", "imm2": "0x5bb7550f", "rot": 31, "bit": 21, "mask": 1}, + {"i": 185, "op": "or", "dst": 3, "src": 5, "src2": 6, "imm": "0x7b1ce846", "imm2": "0xcc3b8509", "rot": 28, "bit": 9, "mask": 4}, + {"i": 186, "op": "mulhi", "dst": 6, "src": 3, "src2": 0, "imm": "0xa5e24690", "imm2": "0x2200ba81", "rot": 26, "bit": 10, "mask": 16}, + {"i": 187, "op": "or", "dst": 4, "src": 0, "src2": 3, "imm": "0xf6efe759", "imm2": "0xae1f7118", "rot": 19, "bit": 20, "mask": 4}, + {"i": 188, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0xdb318b45", "imm2": "0xcec459c9", "rot": 20, "bit": 11, "mask": 2}, + {"i": 189, "op": "add", "dst": 6, "src": 5, "src2": 1, "imm": "0x89e747fe", "imm2": "0x2a354e2d", "rot": 22, "bit": 6, "mask": 1}, + {"i": 190, "op": "xor", "dst": 1, "src": 4, "src2": 2, "imm": "0xc379e617", "imm2": "0x75e9d63b", "rot": 23, "bit": 3, "mask": 2}, + {"i": 191, "op": "mulhi", "dst": 7, "src": 4, "src2": 3, "imm": "0x5a710287", "imm2": "0x7fe4ead6", "rot": 10, "bit": 25, "mask": 4}, + {"i": 192, "op": "rotl", "dst": 2, "src": 1, "src2": 2, "imm": "0x4d5e59a3", "imm2": "0x1e4fef28", "rot": 26, "bit": 0, "mask": 1}, + {"i": 193, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x7444c47d", "imm2": "0xdad5f8be", "rot": 8, "bit": 30, "mask": 2}, + {"i": 194, "op": "shfl", "dst": 4, "src": 5, "src2": 7, "imm": "0x6a225bbb", "imm2": "0xd6532cd7", "rot": 13, "bit": 17, "mask": 16}, + {"i": 195, "op": "xor", "dst": 4, "src": 5, "src2": 3, "imm": "0x68344b9a", "imm2": "0xcb46a38b", "rot": 1, "bit": 27, "mask": 16}, + {"i": 196, "op": "mul", "dst": 1, "src": 3, "src2": 4, "imm": "0xbebf7359", "imm2": "0x3f0890ba", "rot": 18, "bit": 12, "mask": 4}, + {"i": 197, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0xea03e8e7", "imm2": "0x10cfdc71", "rot": 31, "bit": 7, "mask": 8}, + {"i": 198, "op": "add", "dst": 7, "src": 5, "src2": 1, "imm": "0xa7ee0102", "imm2": "0x66e148d3", "rot": 12, "bit": 15, "mask": 1}, + {"i": 199, "op": "sub", "dst": 5, "src": 2, "src2": 4, "imm": "0xc215584e", "imm2": "0x55fce30f", "rot": 30, "bit": 9, "mask": 2}, + {"i": 200, "op": "shfl", "dst": 5, "src": 1, "src2": 1, "imm": "0x308f8358", "imm2": "0x489f1f93", "rot": 13, "bit": 13, "mask": 2}, + {"i": 201, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0x713f1957", "imm2": "0x2239f757", "rot": 15, "bit": 7, "mask": 8}, + {"i": 202, "op": "rotr", "dst": 4, "src": 5, "src2": 1, "imm": "0xb037b6e7", "imm2": "0x49a8b528", "rot": 27, "bit": 13, "mask": 16}, + {"i": 203, "op": "xor", "dst": 7, "src": 5, "src2": 1, "imm": "0x56110241", "imm2": "0xefc8386d", "rot": 22, "bit": 20, "mask": 1}, + {"i": 204, "op": "xor", "dst": 7, "src": 0, "src2": 0, "imm": "0x0827fcc7", "imm2": "0xf4f5dd07", "rot": 13, "bit": 7, "mask": 2}, + {"i": 205, "op": "add", "dst": 6, "src": 2, "src2": 0, "imm": "0x8379a4de", "imm2": "0x8558b619", "rot": 26, "bit": 10, "mask": 1}, + {"i": 206, "op": "rotl", "dst": 4, "src": 3, "src2": 3, "imm": "0x091ceef0", "imm2": "0x69b0f72f", "rot": 13, "bit": 7, "mask": 1}, + {"i": 207, "op": "mulhi", "dst": 1, "src": 3, "src2": 4, "imm": "0x758edac1", "imm2": "0x98dd2f21", "rot": 15, "bit": 9, "mask": 1}, + {"i": 208, "op": "mad", "dst": 1, "src": 4, "src2": 4, "imm": "0x78871a1a", "imm2": "0x5e14e1c8", "rot": 19, "bit": 6, "mask": 2}, + {"i": 209, "op": "shfl", "dst": 2, "src": 0, "src2": 2, "imm": "0xf7e0b9aa", "imm2": "0xaecfd347", "rot": 21, "bit": 9, "mask": 4}, + {"i": 210, "op": "add", "dst": 7, "src": 0, "src2": 7, "imm": "0xaa8cb14e", "imm2": "0xf4049c4c", "rot": 24, "bit": 11, "mask": 8}, + {"i": 211, "op": "shfl", "dst": 7, "src": 1, "src2": 6, "imm": "0xc230d919", "imm2": "0xf76d08fb", "rot": 21, "bit": 13, "mask": 16}, + {"i": 212, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x31a5af90", "imm2": "0x7eef58ee", "rot": 9, "bit": 12, "mask": 4}, + {"i": 213, "op": "rotl", "dst": 7, "src": 1, "src2": 6, "imm": "0x0db26138", "imm2": "0x8e3c31f9", "rot": 3, "bit": 26, "mask": 2}, + {"i": 214, "op": "rotr", "dst": 4, "src": 7, "src2": 3, "imm": "0x29558100", "imm2": "0xe4b13ad6", "rot": 29, "bit": 24, "mask": 8}, + {"i": 215, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x1b48c3d0", "imm2": "0x5c674ff6", "rot": 5, "bit": 9, "mask": 16}, + {"i": 216, "op": "or", "dst": 5, "src": 1, "src2": 0, "imm": "0xef768632", "imm2": "0x6de9d10d", "rot": 10, "bit": 4, "mask": 4}, + {"i": 217, "op": "sub", "dst": 1, "src": 2, "src2": 5, "imm": "0x88ca7f5a", "imm2": "0x24718a36", "rot": 18, "bit": 31, "mask": 1}, + {"i": 218, "op": "sub", "dst": 6, "src": 5, "src2": 0, "imm": "0xc4a06728", "imm2": "0xdc2a4fd8", "rot": 9, "bit": 9, "mask": 2}, + {"i": 219, "op": "rotl", "dst": 6, "src": 5, "src2": 7, "imm": "0xb7489e47", "imm2": "0xf13795c5", "rot": 4, "bit": 3, "mask": 8}, + {"i": 220, "op": "mulhi", "dst": 2, "src": 0, "src2": 2, "imm": "0x873cd31b", "imm2": "0x3dfbc55d", "rot": 12, "bit": 23, "mask": 8}, + {"i": 221, "op": "or", "dst": 2, "src": 0, "src2": 3, "imm": "0xdc21f099", "imm2": "0xee06f01e", "rot": 2, "bit": 17, "mask": 8}, + {"i": 222, "op": "shfl", "dst": 5, "src": 2, "src2": 6, "imm": "0x36def499", "imm2": "0xa2849d59", "rot": 23, "bit": 4, "mask": 8}, + {"i": 223, "op": "mulhi", "dst": 5, "src": 6, "src2": 7, "imm": "0xfb95fbca", "imm2": "0xc1aac427", "rot": 14, "bit": 11, "mask": 2}, + {"i": 224, "op": "sub", "dst": 0, "src": 6, "src2": 7, "imm": "0x3d9d29c4", "imm2": "0x34d0dcc0", "rot": 17, "bit": 6, "mask": 4}, + {"i": 225, "op": "rotl", "dst": 7, "src": 0, "src2": 5, "imm": "0x93b01b8e", "imm2": "0xfe1d75ac", "rot": 23, "bit": 15, "mask": 1}, + {"i": 226, "op": "or", "dst": 4, "src": 2, "src2": 4, "imm": "0xfed76e8e", "imm2": "0x1c24ecd8", "rot": 2, "bit": 6, "mask": 16}, + {"i": 227, "op": "mul", "dst": 2, "src": 4, "src2": 1, "imm": "0x5795f5b0", "imm2": "0x0566ea2a", "rot": 6, "bit": 28, "mask": 4}, + {"i": 228, "op": "rotl", "dst": 3, "src": 0, "src2": 2, "imm": "0x8c8486de", "imm2": "0xd066aa8f", "rot": 12, "bit": 20, "mask": 1}, + {"i": 229, "op": "rotr", "dst": 0, "src": 4, "src2": 0, "imm": "0x23a3e882", "imm2": "0xaca23902", "rot": 5, "bit": 22, "mask": 16}, + {"i": 230, "op": "add", "dst": 0, "src": 6, "src2": 4, "imm": "0x1d176220", "imm2": "0x2a7fecb2", "rot": 20, "bit": 16, "mask": 2}, + {"i": 231, "op": "shfl", "dst": 1, "src": 2, "src2": 0, "imm": "0x91172787", "imm2": "0xc5d7af28", "rot": 3, "bit": 24, "mask": 4}, + {"i": 232, "op": "mul", "dst": 2, "src": 1, "src2": 2, "imm": "0x0be68835", "imm2": "0xde692bdb", "rot": 30, "bit": 17, "mask": 1}, + {"i": 233, "op": "mad", "dst": 7, "src": 0, "src2": 1, "imm": "0xf90d2db5", "imm2": "0x96c4c175", "rot": 28, "bit": 7, "mask": 4}, + {"i": 234, "op": "rotl", "dst": 5, "src": 2, "src2": 1, "imm": "0x16379736", "imm2": "0x6973b905", "rot": 22, "bit": 17, "mask": 4}, + {"i": 235, "op": "rotr", "dst": 4, "src": 6, "src2": 2, "imm": "0x84292a13", "imm2": "0x0f897740", "rot": 12, "bit": 6, "mask": 8}, + {"i": 236, "op": "mad", "dst": 0, "src": 5, "src2": 1, "imm": "0xeb7de837", "imm2": "0x64f0c302", "rot": 4, "bit": 19, "mask": 1}, + {"i": 237, "op": "xor", "dst": 6, "src": 4, "src2": 4, "imm": "0x6ab4b683", "imm2": "0x20f17adb", "rot": 1, "bit": 0, "mask": 16}, + {"i": 238, "op": "xor", "dst": 4, "src": 6, "src2": 1, "imm": "0x5836b35c", "imm2": "0x3293cc4a", "rot": 16, "bit": 22, "mask": 16}, + {"i": 239, "op": "rotl", "dst": 6, "src": 1, "src2": 6, "imm": "0x769d8bc0", "imm2": "0xdc86c9cc", "rot": 18, "bit": 27, "mask": 16}, + {"i": 240, "op": "add", "dst": 4, "src": 7, "src2": 1, "imm": "0x17dafb4d", "imm2": "0xadce39f3", "rot": 12, "bit": 25, "mask": 8}, + {"i": 241, "op": "sub", "dst": 0, "src": 7, "src2": 4, "imm": "0xd4690bda", "imm2": "0xdab9b27b", "rot": 30, "bit": 21, "mask": 1}, + {"i": 242, "op": "rotr", "dst": 1, "src": 6, "src2": 2, "imm": "0x670a2d0a", "imm2": "0x0612e33c", "rot": 31, "bit": 25, "mask": 2}, + {"i": 243, "op": "add", "dst": 3, "src": 0, "src2": 2, "imm": "0xf2f77d26", "imm2": "0x0e7033b6", "rot": 27, "bit": 29, "mask": 1}, + {"i": 244, "op": "mad", "dst": 2, "src": 7, "src2": 4, "imm": "0xa9eefc9d", "imm2": "0x16166c85", "rot": 18, "bit": 23, "mask": 16}, + {"i": 245, "op": "mad", "dst": 4, "src": 0, "src2": 6, "imm": "0xb26f6c0f", "imm2": "0x0630e821", "rot": 23, "bit": 30, "mask": 4}, + {"i": 246, "op": "mul", "dst": 5, "src": 7, "src2": 2, "imm": "0x269ce4bf", "imm2": "0x1ce28d32", "rot": 30, "bit": 15, "mask": 16}, + {"i": 247, "op": "add", "dst": 3, "src": 5, "src2": 0, "imm": "0xfed2da4e", "imm2": "0x7b2ff6b7", "rot": 25, "bit": 31, "mask": 2}, + {"i": 248, "op": "add", "dst": 0, "src": 7, "src2": 5, "imm": "0x03b2891c", "imm2": "0xb5fad7b1", "rot": 2, "bit": 0, "mask": 4}, + {"i": 249, "op": "mulhi", "dst": 5, "src": 4, "src2": 6, "imm": "0xa69a1e71", "imm2": "0x15f0c0ea", "rot": 4, "bit": 1, "mask": 4}, + {"i": 250, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x042cd6e3", "imm2": "0xa7e71c2f", "rot": 24, "bit": 11, "mask": 8}, + {"i": 251, "op": "shfl", "dst": 6, "src": 1, "src2": 2, "imm": "0x89c6b683", "imm2": "0x10bbf661", "rot": 24, "bit": 5, "mask": 1}, + {"i": 252, "op": "xor", "dst": 6, "src": 1, "src2": 3, "imm": "0x265c66d6", "imm2": "0xd4a689ed", "rot": 6, "bit": 14, "mask": 8}, + {"i": 253, "op": "mul", "dst": 2, "src": 5, "src2": 5, "imm": "0x890b8201", "imm2": "0x97c36bf3", "rot": 17, "bit": 22, "mask": 4}, + {"i": 254, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0x784a302b", "imm2": "0xb83d78de", "rot": 27, "bit": 16, "mask": 4}, + {"i": 255, "op": "sub", "dst": 2, "src": 4, "src2": 0, "imm": "0x817adb38", "imm2": "0xf3a3534b", "rot": 7, "bit": 22, "mask": 4} + ]}, + "instructions": [ + {"i": 0, "op": "mad", "dst": 2, "src": 3, "src2": 4, "imm": "0xbf7b174d", "imm2": "0x337b762e", "rot": 17, "bit": 2, "mask": 2, "width": 1}, + {"i": 1, "op": "mad", "dst": 2, "src": 1, "src2": 1, "imm": "0xdd04a5da", "imm2": "0x42da7657", "rot": 15, "bit": 30, "mask": 16, "width": 1}, + {"i": 2, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0x734003fa", "imm2": "0x5bb67700", "rot": 3, "bit": 20, "mask": 1, "width": 1}, + {"i": 3, "op": "xor", "dst": 3, "src": 5, "src2": 5, "imm": "0xc55a1b1c", "imm2": "0xa19720f3", "rot": 7, "bit": 8, "mask": 1, "width": 1}, + {"i": 4, "op": "load", "dst": 7, "src": 2, "src2": 5, "imm": "0xad572dd7", "imm2": "0x9ceb3ea7", "rot": 18, "bit": 30, "mask": 2, "width": 1}, + {"i": 5, "op": "load", "dst": 5, "src": 7, "src2": 3, "imm": "0x769a53be", "imm2": "0x80f9067e", "rot": 12, "bit": 22, "mask": 1, "width": 1}, + {"i": 6, "op": "shfl", "dst": 1, "src": 4, "src2": 0, "imm": "0xd3613d88", "imm2": "0x262fb219", "rot": 10, "bit": 30, "mask": 8, "width": 1}, + {"i": 7, "op": "shfl", "dst": 7, "src": 3, "src2": 4, "imm": "0xce38e42f", "imm2": "0xb868b818", "rot": 11, "bit": 8, "mask": 8, "width": 1}, + {"i": 8, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xa5eebca5", "imm2": "0x5703a72b", "rot": 13, "bit": 13, "mask": 16, "width": 1}, + {"i": 9, "op": "rotr", "dst": 6, "src": 3, "src2": 4, "imm": "0x17a5a9c7", "imm2": "0xdcfb93a1", "rot": 20, "bit": 27, "mask": 2, "width": 1}, + {"i": 10, "op": "or", "dst": 3, "src": 4, "src2": 1, "imm": "0xccb7d785", "imm2": "0xc335364c", "rot": 14, "bit": 12, "mask": 4, "width": 1}, + {"i": 11, "op": "load", "dst": 4, "src": 3, "src2": 2, "imm": "0x88cb9af3", "imm2": "0x4e7dc10d", "rot": 24, "bit": 17, "mask": 4, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 0, "src": 4, "src2": 4, "imm": "0x45374321", "imm2": "0x3cd91989", "rot": 11, "bit": 4, "mask": 2, "width": 1}, + {"i": 13, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc7934706", "imm2": "0xd3177981", "rot": 16, "bit": 30, "mask": 2, "width": 1}, + {"i": 14, "op": "load", "dst": 0, "src": 4, "src2": 3, "imm": "0xfd7f56bb", "imm2": "0x65e14f52", "rot": 13, "bit": 22, "mask": 2, "width": 1}, + {"i": 15, "op": "sub", "dst": 2, "src": 4, "src2": 4, "imm": "0x35a80b49", "imm2": "0x060f2d13", "rot": 16, "bit": 20, "mask": 16, "width": 1}, + {"i": 16, "op": "load", "dst": 2, "src": 0, "src2": 2, "imm": "0xae0a32c2", "imm2": "0x4c2a4cfe", "rot": 8, "bit": 31, "mask": 16, "width": 1}, + {"i": 17, "op": "load", "dst": 7, "src": 2, "src2": 6, "imm": "0x82a84cc3", "imm2": "0x21a38d68", "rot": 15, "bit": 21, "mask": 2, "width": 1}, + {"i": 18, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0xa3818806", "imm2": "0x8f66b5c8", "rot": 14, "bit": 6, "mask": 4, "width": 1}, + {"i": 19, "op": "mul", "dst": 5, "src": 0, "src2": 1, "imm": "0xa00de107", "imm2": "0x77bfcaa5", "rot": 3, "bit": 10, "mask": 2, "width": 1}, + {"i": 20, "op": "shfl", "dst": 3, "src": 4, "src2": 7, "imm": "0x1d2b8cab", "imm2": "0x80b4f9a2", "rot": 14, "bit": 25, "mask": 2, "width": 1}, + {"i": 21, "op": "shfl", "dst": 2, "src": 4, "src2": 5, "imm": "0x3ac915d2", "imm2": "0x5fba7bc2", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 22, "op": "mulhi", "dst": 6, "src": 2, "src2": 0, "imm": "0xdc3ec8fd", "imm2": "0x599e2fa3", "rot": 22, "bit": 3, "mask": 2, "width": 1}, + {"i": 23, "op": "load", "dst": 6, "src": 1, "src2": 5, "imm": "0x2a6b16d5", "imm2": "0xd73e396f", "rot": 28, "bit": 29, "mask": 2, "width": 1}, + {"i": 24, "op": "mul", "dst": 5, "src": 0, "src2": 7, "imm": "0x376d0223", "imm2": "0xe1c2169a", "rot": 4, "bit": 16, "mask": 16, "width": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 7, "src2": 3, "imm": "0x78ad8c60", "imm2": "0x6f5b77d5", "rot": 19, "bit": 11, "mask": 16, "width": 1}, + {"i": 26, "op": "shfl", "dst": 7, "src": 6, "src2": 5, "imm": "0x93915b9f", "imm2": "0x1e61fb6b", "rot": 28, "bit": 23, "mask": 2, "width": 1}, + {"i": 27, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x6378fe15", "imm2": "0x66c78f42", "rot": 12, "bit": 31, "mask": 8, "width": 1}, + {"i": 28, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x20a57fda", "imm2": "0x088c848e", "rot": 16, "bit": 13, "mask": 4, "width": 1}, + {"i": 29, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x49d95fd5", "imm2": "0x1a5f946a", "rot": 6, "bit": 12, "mask": 1, "width": 1}, + {"i": 30, "op": "mul", "dst": 5, "src": 1, "src2": 7, "imm": "0x0a816217", "imm2": "0x405c4f73", "rot": 13, "bit": 27, "mask": 4, "width": 1}, + {"i": 31, "op": "load", "dst": 7, "src": 2, "src2": 2, "imm": "0x09ed045e", "imm2": "0xd69c4715", "rot": 5, "bit": 9, "mask": 2, "width": 1}, + {"i": 32, "op": "load", "dst": 1, "src": 0, "src2": 6, "imm": "0xeb79ea49", "imm2": "0xcc587f5a", "rot": 6, "bit": 8, "mask": 16, "width": 1}, + {"i": 33, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0x3027401e", "imm2": "0x5f20c27e", "rot": 18, "bit": 9, "mask": 2, "width": 1}, + {"i": 34, "op": "load", "dst": 5, "src": 1, "src2": 3, "imm": "0x0e1cab07", "imm2": "0x09356c5b", "rot": 19, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mulhi", "dst": 0, "src": 5, "src2": 2, "imm": "0x90e31357", "imm2": "0xabd32484", "rot": 26, "bit": 5, "mask": 8, "width": 1}, + {"i": 36, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xee9a955f", "imm2": "0x31b3faed", "rot": 8, "bit": 24, "mask": 4, "width": 1}, + {"i": 37, "op": "load", "dst": 7, "src": 0, "src2": 7, "imm": "0x3ba2f832", "imm2": "0x1160dcd3", "rot": 4, "bit": 29, "mask": 1, "width": 1}, + {"i": 38, "op": "add", "dst": 3, "src": 1, "src2": 7, "imm": "0x75ba2fad", "imm2": "0x230c005c", "rot": 4, "bit": 27, "mask": 1, "width": 1}, + {"i": 39, "op": "shfl", "dst": 1, "src": 5, "src2": 3, "imm": "0xdbf37e75", "imm2": "0xb5ac1969", "rot": 30, "bit": 13, "mask": 4, "width": 1}, + {"i": 40, "op": "xor", "dst": 2, "src": 5, "src2": 5, "imm": "0x47f136c5", "imm2": "0x06ce9153", "rot": 19, "bit": 10, "mask": 2, "width": 1}, + {"i": 41, "op": "mad", "dst": 3, "src": 6, "src2": 3, "imm": "0xce13eff8", "imm2": "0x04cc1d55", "rot": 3, "bit": 1, "mask": 4, "width": 1}, + {"i": 42, "op": "sub", "dst": 6, "src": 7, "src2": 1, "imm": "0x6a65ab71", "imm2": "0x8fbc1bcd", "rot": 4, "bit": 1, "mask": 8, "width": 1}, + {"i": 43, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xdaeb4928", "imm2": "0xc0423027", "rot": 24, "bit": 11, "mask": 8, "width": 1}, + {"i": 44, "op": "load", "dst": 1, "src": 7, "src2": 7, "imm": "0x778f01c9", "imm2": "0x28cedcea", "rot": 12, "bit": 4, "mask": 16, "width": 1}, + {"i": 45, "op": "mul", "dst": 2, "src": 3, "src2": 2, "imm": "0xf4264f1b", "imm2": "0x0f627d56", "rot": 5, "bit": 28, "mask": 8, "width": 1}, + {"i": 46, "op": "mulhi", "dst": 1, "src": 5, "src2": 1, "imm": "0xffb2147a", "imm2": "0xccde9b05", "rot": 13, "bit": 9, "mask": 2, "width": 1}, + {"i": 47, "op": "sub", "dst": 4, "src": 3, "src2": 5, "imm": "0x73b36234", "imm2": "0x3f5d5997", "rot": 7, "bit": 18, "mask": 2, "width": 1}, + {"i": 48, "op": "rotr", "dst": 2, "src": 6, "src2": 3, "imm": "0x3a4d9aa9", "imm2": "0x212bec7b", "rot": 4, "bit": 29, "mask": 16, "width": 1}, + {"i": 49, "op": "load", "dst": 3, "src": 5, "src2": 2, "imm": "0x626f11df", "imm2": "0x56cd5bfd", "rot": 7, "bit": 1, "mask": 1, "width": 1}, + {"i": 50, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0x81b8bc2c", "imm2": "0x1907970c", "rot": 28, "bit": 7, "mask": 4, "width": 1}, + {"i": 51, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0xa8848b30", "imm2": "0xef6ac348", "rot": 9, "bit": 15, "mask": 8, "width": 1}, + {"i": 52, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x4f92b968", "imm2": "0x699fd448", "rot": 22, "bit": 6, "mask": 4, "width": 1}, + {"i": 53, "op": "add", "dst": 1, "src": 0, "src2": 2, "imm": "0x2bb965af", "imm2": "0x77b1520d", "rot": 2, "bit": 12, "mask": 8, "width": 1}, + {"i": 54, "op": "rotl", "dst": 7, "src": 1, "src2": 0, "imm": "0x553e678b", "imm2": "0x3cc8eae0", "rot": 14, "bit": 20, "mask": 2, "width": 1}, + {"i": 55, "op": "add", "dst": 3, "src": 7, "src2": 2, "imm": "0x7b0fe07a", "imm2": "0xa54c55a0", "rot": 10, "bit": 1, "mask": 1, "width": 1}, + {"i": 56, "op": "load", "dst": 6, "src": 7, "src2": 4, "imm": "0x01eba9aa", "imm2": "0x2758c0f7", "rot": 14, "bit": 15, "mask": 4, "width": 1}, + {"i": 57, "op": "rotr", "dst": 1, "src": 5, "src2": 2, "imm": "0x1f5267b3", "imm2": "0x236f5a27", "rot": 2, "bit": 31, "mask": 16, "width": 1}, + {"i": 58, "op": "load", "dst": 5, "src": 4, "src2": 3, "imm": "0xa9954a9b", "imm2": "0x6a54d4e8", "rot": 11, "bit": 10, "mask": 16, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 2, "src2": 4, "imm": "0x9923ff88", "imm2": "0x9357254e", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 60, "op": "mad", "dst": 3, "src": 5, "src2": 0, "imm": "0xc0cc51a6", "imm2": "0x3fd7701b", "rot": 20, "bit": 1, "mask": 4, "width": 1}, + {"i": 61, "op": "add", "dst": 5, "src": 7, "src2": 7, "imm": "0xaf9dd72d", "imm2": "0xad7493e7", "rot": 7, "bit": 31, "mask": 16, "width": 1}, + {"i": 62, "op": "add", "dst": 4, "src": 6, "src2": 2, "imm": "0x89841d87", "imm2": "0x1e07c3d9", "rot": 6, "bit": 27, "mask": 1, "width": 1}, + {"i": 63, "op": "rotl", "dst": 5, "src": 4, "src2": 2, "imm": "0xae210f8d", "imm2": "0x8e499ba4", "rot": 19, "bit": 9, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/program.metal b/proto-cuda/packs-ca3-v5/v4-genesis/program.metal new file mode 100644 index 000000000..2830702a7 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/program.metal @@ -0,0 +1,368 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +inline uint rotl_imm(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 +inline uint rotr_var(uint x, uint n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +kernel void igneum_hash(device const uint* dataset [[buffer(0)]], + device ulong* out [[buffer(1)]], + constant uint& baseNonce [[buffer(2)]], + uint gid [[thread_position_in_grid]]) { + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; + { uint x = nonce ^ SEEDW[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ SEEDW[1]; } + { uint x = nonce ^ SEEDW[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ SEEDW[2]; } + { uint x = nonce ^ SEEDW[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ SEEDW[3]; } + { uint x = nonce ^ SEEDW[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ SEEDW[4]; } + { uint x = nonce ^ SEEDW[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ SEEDW[5]; } + { uint x = nonce ^ SEEDW[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ SEEDW[6]; } + { uint x = nonce ^ SEEDW[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ SEEDW[7]; } + { uint x = nonce ^ SEEDW[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ SEEDW[0]; } + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/program_bound.metal b/proto-cuda/packs-ca3-v5/v4-genesis/program_bound.metal new file mode 100644 index 000000000..7a8da2d3e --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/program_bound.metal @@ -0,0 +1,370 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +inline uint rotl_imm(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 +inline uint rotr_var(uint x, uint n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Header-bound variant: the init words come from buffer 3 (bind.rs), not from SEEDW. +kernel void igneum_hash_bound(device const uint* dataset [[buffer(0)]], + device ulong* out [[buffer(1)]], + constant uint& baseNonce [[buffer(2)]], + constant uint* initw [[buffer(3)]], + uint gid [[thread_position_in_grid]]) { + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; + { uint x = nonce ^ initw[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ initw[1]; } + { uint x = nonce ^ initw[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ initw[2]; } + { uint x = nonce ^ initw[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ initw[3]; } + { uint x = nonce ^ initw[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ initw[4]; } + { uint x = nonce ^ initw[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ initw[5]; } + { uint x = nonce ^ initw[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ initw[6]; } + { uint x = nonce ^ initw[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ initw[7]; } + { uint x = nonce ^ initw[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ initw[0]; } + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/vectors.h b/proto-cuda/packs-ca3-v5/v4-genesis/vectors.h new file mode 100644 index 000000000..49509d75a --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v4, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0x2576769ee4a14c8dull, 0x6408f60b1f606a96ull, 0x8e1825542dbd3636ull, 0xb25c17d8820ae079ull, 0xb6e1a578d06323b2ull, 0x8bea2965eaa47f55ull, 0x3684da53df965532ull, 0x3392668d50a45aadull, + 0x5e78d14aaaadce6eull, 0xcb0a7992844c9192ull, 0xfe4ad7fbc328f9efull, 0x7e64515d7d5941a4ull, 0x425e4eedb7b0ca4bull, 0x4f57a8f93ce317b8ull, 0x081360e3cf765b3aull, 0x1e9e919c50331254ull, + 0x998e7a76718adcbaull, 0xde5600e2b1838d9full, 0x4f85d0539779a267ull, 0x40661123ffbce40cull, 0x95b247ca86ff61dcull, 0xbe2bf61b9fcd1362ull, 0xfd6d6687a07997daull, 0x9935965e43f25045ull, + 0x27fe1552873c0b40ull, 0x972c952c83cf5ea9ull, 0x525b975fb9610333ull, 0x4f81431408d27e2dull, 0x6375d14f804f061full, 0xff6492be48775872ull, 0x81b2e098e1a01f8full, 0xc58ddcb717dd3370ull + }, + { // base nonce 4096 + 0x1ce77a600ec573b4ull, 0xb126a41f83521e45ull, 0x875547a82d6145fcull, 0xd4b04bf258ce4941ull, 0xe24c23e2b2371ad6ull, 0x7687a4beddbbd270ull, 0x63b9346ba234a0beull, 0x2500fb30f5e7eb20ull, + 0x7a185d59a30e3333ull, 0xa3c14cec7e2bcce2ull, 0x5730e39d367c6b21ull, 0x03e10c84ac832a3full, 0xf6dd88e0208019efull, 0xd539425d3bc497fcull, 0x71461f5d0c23f626ull, 0xa4c64db97fb4a425ull, + 0x61f56436538b61f8ull, 0x749b10eccde2f0bcull, 0xbe447d39b5f3aa29ull, 0x0e4ada60a90088b7ull, 0x3eda0e2db0bc9f9eull, 0xf90d81a21a10089cull, 0x7cf50a8f14d2430eull, 0x14601dea6a5d8625ull, + 0x23c448ee2f31a26dull, 0x60e5c3d4b218c0c2ull, 0x46ed8a924ac431fbull, 0xcc77440ffbe5c23dull, 0x9a15a2da9d6ba946ull, 0x37117ce37ca8c606ull, 0x69b85ea283597190ull, 0x03600a05ffba0055ull + }, + { // base nonce 1000000 + 0x6b390e64bbdd91ceull, 0x9b34dd7b05214a6bull, 0x60c14bcda3df2768ull, 0x557f5df495f92ad5ull, 0x5ac883b3090f344bull, 0xdec4058df6f8b088ull, 0x6e3dcb56bbb79ec9ull, 0x6450bb96c6c686bdull, + 0xc2021c81ef714e23ull, 0xcc0b3f77c0cf7bf6ull, 0x03cb474759279b0dull, 0x93cf69a5cd961b9cull, 0x61318f0c14d7e3deull, 0x9df2144c49b171beull, 0xa335ecfaf465e9cdull, 0x4f8661257c1706c3ull, + 0xab374ea37f8e253cull, 0x117242d65e8ebdb4ull, 0x9022069313586cd7ull, 0xe97f096510d6ad03ull, 0xa93d76b12894ffc5ull, 0x7823119022da1590ull, 0xde6f389ece0c83e9ull, 0x84e97ea778e4fb15ull, + 0x23d0802d386a21c8ull, 0xbaacd8512e9bbb31ull, 0x10522970c58234bbull, 0x90f0b64b38eed0b1ull, 0xb250988d2986d15bull, 0xf81e101bb298710full, 0x20e9cca5ade09113ull, 0x91c944d603539c62ull + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0xfdad4319u, 0x1a7b68e1u, 0xde6db608u, 0x13d73892u, 0xd17f447au, 0xb2221ccfu, 0x9db004bdu, 0x57d7d367u, + 0xdbc4cf34u, 0x697c009au, 0xc43af1d4u, 0x97f12b2eu, 0x74c37cd0u, 0xc651ea15u, 0x665a6d29u, 0x22330a2du +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0xa83e7aa6u; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0x3230bc7bu, 0x7fbfe2c9u, 0xb2690991u, 0x1745c7c5u, 0x0ab0ccafu, 0x1bf87d6bu, 0x160139fdu, 0x719817acu, 0x0155df4bu, 0xbe1e86c3u, 0x680bcd6cu, 0x79c3dc6cu, 0x181e7e5fu, 0x0713a109u, 0xc705dd9fu, 0x3933b7a8u, 0xdd1c0431u, 0x50522b30u, 0xa0020b38u, 0xbff39e96u, 0x21b67e18u, 0x740f8db3u, 0x2baba568u, 0x2c9bef83u, 0x0ad9b671u, 0xc4327869u, 0x7b4fd7d0u, 0x2c29965fu, 0xec56f15fu, 0x61111746u, 0x303a1d6eu, 0xbddcfd1au, 0xf829a355u, 0x6d5df2a9u, 0x01ab8e44u, 0x06d13507u, 0xda8dcfc6u, 0x01a703e1u, 0xafe7d2c1u, 0xc091c3a2u, 0xac1814feu, 0x6e6ff62au, 0x8fdf01bau, 0xdd3f7159u, 0xdfa0d75cu, 0x26684c35u, 0x7f441e63u, 0x88df2570u, 0x8aa4d5ebu, 0xcc816c05u, 0x434df890u, 0xcd392ad6u, 0x1ab4cb63u, 0x595926fau, 0x7cd76b41u, 0x20cb95c4u, 0x13cf823fu, 0xf9daf901u, 0xff9af40au, 0x2c7dfa51u, 0x871206dbu, 0x938c116cu, 0xb64bf199u, 0x5751f874u +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/vectors.json b/proto-cuda/packs-ca3-v5/v4-genesis/vectors.json new file mode 100644 index 000000000..fa3dc9f00 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v4-genesis/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v4, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0x2576769ee4a14c8d", "0x6408f60b1f606a96", "0x8e1825542dbd3636", "0xb25c17d8820ae079", "0xb6e1a578d06323b2", "0x8bea2965eaa47f55", "0x3684da53df965532", "0x3392668d50a45aad", + "0x5e78d14aaaadce6e", "0xcb0a7992844c9192", "0xfe4ad7fbc328f9ef", "0x7e64515d7d5941a4", "0x425e4eedb7b0ca4b", "0x4f57a8f93ce317b8", "0x081360e3cf765b3a", "0x1e9e919c50331254", + "0x998e7a76718adcba", "0xde5600e2b1838d9f", "0x4f85d0539779a267", "0x40661123ffbce40c", "0x95b247ca86ff61dc", "0xbe2bf61b9fcd1362", "0xfd6d6687a07997da", "0x9935965e43f25045", + "0x27fe1552873c0b40", "0x972c952c83cf5ea9", "0x525b975fb9610333", "0x4f81431408d27e2d", "0x6375d14f804f061f", "0xff6492be48775872", "0x81b2e098e1a01f8f", "0xc58ddcb717dd3370" + ]}, + {"base_nonce": 4096, "expected": [ + "0x1ce77a600ec573b4", "0xb126a41f83521e45", "0x875547a82d6145fc", "0xd4b04bf258ce4941", "0xe24c23e2b2371ad6", "0x7687a4beddbbd270", "0x63b9346ba234a0be", "0x2500fb30f5e7eb20", + "0x7a185d59a30e3333", "0xa3c14cec7e2bcce2", "0x5730e39d367c6b21", "0x03e10c84ac832a3f", "0xf6dd88e0208019ef", "0xd539425d3bc497fc", "0x71461f5d0c23f626", "0xa4c64db97fb4a425", + "0x61f56436538b61f8", "0x749b10eccde2f0bc", "0xbe447d39b5f3aa29", "0x0e4ada60a90088b7", "0x3eda0e2db0bc9f9e", "0xf90d81a21a10089c", "0x7cf50a8f14d2430e", "0x14601dea6a5d8625", + "0x23c448ee2f31a26d", "0x60e5c3d4b218c0c2", "0x46ed8a924ac431fb", "0xcc77440ffbe5c23d", "0x9a15a2da9d6ba946", "0x37117ce37ca8c606", "0x69b85ea283597190", "0x03600a05ffba0055" + ]}, + {"base_nonce": 1000000, "expected": [ + "0x6b390e64bbdd91ce", "0x9b34dd7b05214a6b", "0x60c14bcda3df2768", "0x557f5df495f92ad5", "0x5ac883b3090f344b", "0xdec4058df6f8b088", "0x6e3dcb56bbb79ec9", "0x6450bb96c6c686bd", + "0xc2021c81ef714e23", "0xcc0b3f77c0cf7bf6", "0x03cb474759279b0d", "0x93cf69a5cd961b9c", "0x61318f0c14d7e3de", "0x9df2144c49b171be", "0xa335ecfaf465e9cd", "0x4f8661257c1706c3", + "0xab374ea37f8e253c", "0x117242d65e8ebdb4", "0x9022069313586cd7", "0xe97f096510d6ad03", "0xa93d76b12894ffc5", "0x7823119022da1590", "0xde6f389ece0c83e9", "0x84e97ea778e4fb15", + "0x23d0802d386a21c8", "0xbaacd8512e9bbb31", "0x10522970c58234bb", "0x90f0b64b38eed0b1", "0xb250988d2986d15b", "0xf81e101bb298710f", "0x20e9cca5ade09113", "0x91c944d603539c62" + ]} + ], + "dataset_head": ["0xfdad4319", "0x1a7b68e1", "0xde6db608", "0x13d73892", "0xd17f447a", "0xb2221ccf", "0x9db004bd", "0x57d7d367", "0xdbc4cf34", "0x697c009a", "0xc43af1d4", "0x97f12b2e", "0x74c37cd0", "0xc651ea15", "0x665a6d29", "0x22330a2d"], + "dataset_last_index": 268435455, + "dataset_last": "0xa83e7aa6", + "dataset_samples": [{"index": 59471966, "value": "0x3230bc7b"}, {"index": 217795994, "value": "0x7fbfe2c9"}, {"index": 208353206, "value": "0xb2690991"}, {"index": 42483309, "value": "0x1745c7c5"}, {"index": 172547758, "value": "0x0ab0ccaf"}, {"index": 148076330, "value": "0x1bf87d6b"}, {"index": 183853158, "value": "0x160139fd"}, {"index": 214389424, "value": "0x719817ac"}, {"index": 267488061, "value": "0x0155df4b"}, {"index": 169781097, "value": "0xbe1e86c3"}, {"index": 184093494, "value": "0x680bcd6c"}, {"index": 153880993, "value": "0x79c3dc6c"}, {"index": 84977930, "value": "0x181e7e5f"}, {"index": 46426879, "value": "0x0713a109"}, {"index": 3093825, "value": "0xc705dd9f"}, {"index": 225364072, "value": "0x3933b7a8"}, {"index": 44593546, "value": "0xdd1c0431"}, {"index": 260713159, "value": "0x50522b30"}, {"index": 168250303, "value": "0xa0020b38"}, {"index": 52384140, "value": "0xbff39e96"}, {"index": 223401610, "value": "0x21b67e18"}, {"index": 45554030, "value": "0x740f8db3"}, {"index": 95410555, "value": "0x2baba568"}, {"index": 175039924, "value": "0x2c9bef83"}, {"index": 79171087, "value": "0x0ad9b671"}, {"index": 267580473, "value": "0xc4327869"}, {"index": 24168642, "value": "0x7b4fd7d0"}, {"index": 37981670, "value": "0x2c29965f"}, {"index": 171551130, "value": "0xec56f15f"}, {"index": 195559979, "value": "0x61111746"}, {"index": 204611762, "value": "0x303a1d6e"}, {"index": 140997658, "value": "0xbddcfd1a"}, {"index": 138925853, "value": "0xf829a355"}, {"index": 86637313, "value": "0x6d5df2a9"}, {"index": 20736778, "value": "0x01ab8e44"}, {"index": 219665210, "value": "0x06d13507"}, {"index": 160430336, "value": "0xda8dcfc6"}, {"index": 264654675, "value": "0x01a703e1"}, {"index": 8013395, "value": "0xafe7d2c1"}, {"index": 228945585, "value": "0xc091c3a2"}, {"index": 213884386, "value": "0xac1814fe"}, {"index": 104419827, "value": "0x6e6ff62a"}, {"index": 44185464, "value": "0x8fdf01ba"}, {"index": 142737231, "value": "0xdd3f7159"}, {"index": 99284897, "value": "0xdfa0d75c"}, {"index": 132475900, "value": "0x26684c35"}, {"index": 61861762, "value": "0x7f441e63"}, {"index": 132056166, "value": "0x88df2570"}, {"index": 262388043, "value": "0x8aa4d5eb"}, {"index": 91878046, "value": "0xcc816c05"}, {"index": 117353561, "value": "0x434df890"}, {"index": 124768597, "value": "0xcd392ad6"}, {"index": 71352993, "value": "0x1ab4cb63"}, {"index": 190698941, "value": "0x595926fa"}, {"index": 46055428, "value": "0x7cd76b41"}, {"index": 55281366, "value": "0x20cb95c4"}, {"index": 165145231, "value": "0x13cf823f"}, {"index": 106810753, "value": "0xf9daf901"}, {"index": 171985651, "value": "0xff9af40a"}, {"index": 232085256, "value": "0x2c7dfa51"}, {"index": 159510492, "value": "0x871206db"}, {"index": 40072060, "value": "0x938c116c"}, {"index": 209107596, "value": "0xb64bf199"}, {"index": 39023794, "value": "0x5751f874"}], + "cache_head": ["0x355a86d2", "0x7957db1c", "0xd21772af", "0x6fc1e09b", "0xd55ce61d", "0x6e6a278b", "0xd3f543ce", "0x223d8e82", "0x143ab337", "0x2e9f05bd", "0x2eb389bf", "0x0c6e449e", "0x5cfa4222", "0xba6560fe", "0x8e3e1aa4", "0xdbcc1d53"], + "cache_last_line": ["0x41190d91", "0xbd277957", "0x22ddbb49", "0x6986f207", "0xdf69a4d6", "0x26401a3a", "0x818230fb", "0xc417122d", "0x3597b211", "0xb553ce55", "0xcf39cc0d", "0x3b7fc43a", "0x3fd43b00", "0x67e1c80e", "0xffa7ea7d", "0xca2960ab"], + "cache_fnv1a64": "0x48c4f5bf24166b2e" +} diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/kernel.cl b/proto-cuda/packs-ca3-v5/v5-genesis/kernel.cl new file mode 100644 index 000000000..e0db2dfbd --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/kernel.cl @@ -0,0 +1,542 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// OpenCL C twin of the Metal kernel for the same seed (see proto-opencl/README.md, WAVEFRONT.md and program.metal). +// Built from source at runtime by proto-opencl/host.c, which passes these defines: +// IGNEUM_GROUP work-group size of igneum_hash, a multiple of 32 (default 32: one work-group = one 32-lane unit) +// IGNEUM_EXCHANGE 0 = local-memory exchange with a barrier (any device, any wave width; the default) +// 1 = sub_group_shuffle_xor (cl_khr_subgroup_shuffle), only with IGNEUM_GROUP 32 and a sub-group size of exactly 32 +// 2 = intel_sub_group_shuffle_xor (cl_intel_subgroups), same condition +// The verification unit is always 32 lanes. A 64-wide hardware wave (AMD GCN/CDNA, RDNA in wave64) runs two units; +// the exchange masks are 1, 2, 4, 8, 16, so every partner lane lies inside the lane's own aligned run of 32. +#ifndef IGNEUM_GROUP +#define IGNEUM_GROUP 32 +#endif +#ifndef IGNEUM_EXCHANGE +#define IGNEUM_EXCHANGE 0 +#endif +#ifdef __OPENCL_VERSION__ +#define IGNEUM_KERNEL_HASH __kernel __attribute__((reqd_work_group_size(IGNEUM_GROUP, 1, 1))) +#define IGNEUM_LOCAL_WORDS(name, n) __local uint name[n] +#if IGNEUM_EXCHANGE == 1 +#ifdef cl_khr_subgroups +#pragma OPENCL EXTENSION cl_khr_subgroups : enable +#endif +#ifdef cl_khr_subgroup_shuffle +#pragma OPENCL EXTENSION cl_khr_subgroup_shuffle : enable +#endif +#elif IGNEUM_EXCHANGE == 2 +#pragma OPENCL EXTENSION cl_intel_subgroups : enable +#endif +#else +// Not an OpenCL compiler: proto-opencl/emu compiles this file as C++ and supplies the built-ins and these two macros. +#include "emu_opencl.h" +#endif + +#if IGNEUM_EXCHANGE == 1 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#elif IGNEUM_EXCHANGE == 2 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = intel_sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#else +// Local-memory exchange. Two buffers of IGNEUM_GROUP words alternate (xk counts exchanges), so one barrier per +// exchange is enough: a lane can only overwrite buffer b at exchange k+2 after passing barrier k+1, and every lane +// reaches barrier k+1 only after its read of buffer b at exchange k. The partner lid ^ m stays inside the lane's +// aligned run of 32 because m < 32. Control flow is uniform, so every work-item reaches every barrier. +#define IGNEUM_SHFL_XOR(dst, a, m) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid ^ (uint)(m))]; xk += 1u; } +#define IGNEUM_BCAST0(dst, a) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid & ~31u)]; xk += 1u; } +#endif + +static inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site. OpenCL rotate() rotates left by n modulo 32. +static inline uint rotl_imm(uint x, uint n) { return rotate(x, n); } +// Right rotation by n modulo 32 as a left rotation by (32 - n) modulo 32; n == 0 gives x. +static inline uint rotr_var(uint x, uint n) { return rotate(x, (0u - n) & 31u); } +static inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +static inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +static inline void mh_chacha_block(const uint* x, uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +static inline void mh_cache_segment(__global uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + __global uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +static inline void mh_mixer(uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +static inline void mh_item(__global const uint* cache, __global const uint* leaf, uint t, uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint i = 0u; i < 16u; ++i) s[i] ^= leaf[i]; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + __global const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// Class v5 (docs/design/class-v5-stored-state.md): leaf(t) = leaves[t mod nLeaves], 16 words per leaf (leaves.bin). +static inline __global const uint* mh_leaf(__global const uint* leaves, uint nLeaves, uint t) { return leaves + ((t % nLeaves) * 16u); } +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +static inline uint mh_word(__global const uint* cache, __global const uint* leaves, uint nLeaves, uint w) { uint s[16]; mh_item(cache, mh_leaf(leaves, nLeaves, w >> 4u), w >> 4u, s); return s[w & 15u]; } + +// Memory-hard dataset (MEMHARD.md). One work-item per cache segment; one work-item per 64-byte dataset item. +// The same constants as memhard.h in this pack (one emitter, three dialects). +__kernel void igneum_cache_fill(__global uint* cache, uint nSegments) { + uint seg = (uint)get_global_id(0); + if (seg < nSegments) mh_cache_segment(cache, seg); +} +// Class v5: the window's leaves (leaves.bin, IGNEUM_STATE_LEAVES x 16 words) and their count. +__kernel void igneum_build(__global uint* ds, __global const uint* cache, __global const uint* leaves, uint nLeaves, uint nItems) { + uint t = (uint)get_global_id(0); + if (t < nItems) { + uint s[16]; + mh_item(cache, mh_leaf(leaves, nLeaves, t), t, s); + __global uint* d = ds + ((ulong)t * 16u); + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per work-item. IGNEUM_GROUP is a multiple of 32; lane = lid & 31 and every exchange stays inside the +// lane's own aligned run of 32 work-items, exactly like simd_shuffle_xor inside a 32-wide Metal SIMD group and +// __shfl_xor_sync inside a CUDA warp. Control flow is uniform (no branches at all). +IGNEUM_KERNEL_HASH void igneum_hash(__global const uint* ds, __global ulong* out, uint baseNonce, uint mask) { + uint gid = (uint)get_global_id(0); + uint lid = (uint)get_local_id(0); + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; +#if IGNEUM_EXCHANGE == 0 + IGNEUM_LOCAL_WORDS(xch, 2 * IGNEUM_GROUP); + uint xk = 0u; +#else + (void)lid; +#endif + { uint x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/kernel.cu b/proto-cuda/packs-ca3-v5/v5-genesis/kernel.cu new file mode 100644 index 000000000..a6c11eecf --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/kernel.cu @@ -0,0 +1,424 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +// Class v5: the window's leaves (leaves.bin, IGNEUM_STATE_LEAVES x 16 words) and their count. +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, const uint32_t* leaves, uint32_t nLeaves, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, mh_leaf(leaves, nLeaves, t), t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, const uint32_t* leaves, uint32_t nLeaves, uint32_t nItems) { + if (nItems == 0u || nLeaves == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, leaves, nLeaves, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/kernel_bound.cl b/proto-cuda/packs-ca3-v5/v5-genesis/kernel_bound.cl new file mode 100644 index 000000000..006b90b79 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/kernel_bound.cl @@ -0,0 +1,895 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// OpenCL C twin of the Metal kernel for the same seed (see proto-opencl/README.md, WAVEFRONT.md and program.metal). +// Built from source at runtime by proto-opencl/host.c, which passes these defines: +// IGNEUM_GROUP work-group size of igneum_hash, a multiple of 32 (default 32: one work-group = one 32-lane unit) +// IGNEUM_EXCHANGE 0 = local-memory exchange with a barrier (any device, any wave width; the default) +// 1 = sub_group_shuffle_xor (cl_khr_subgroup_shuffle), only with IGNEUM_GROUP 32 and a sub-group size of exactly 32 +// 2 = intel_sub_group_shuffle_xor (cl_intel_subgroups), same condition +// The verification unit is always 32 lanes. A 64-wide hardware wave (AMD GCN/CDNA, RDNA in wave64) runs two units; +// the exchange masks are 1, 2, 4, 8, 16, so every partner lane lies inside the lane's own aligned run of 32. +#ifndef IGNEUM_GROUP +#define IGNEUM_GROUP 32 +#endif +#ifndef IGNEUM_EXCHANGE +#define IGNEUM_EXCHANGE 0 +#endif +#ifdef __OPENCL_VERSION__ +#define IGNEUM_KERNEL_HASH __kernel __attribute__((reqd_work_group_size(IGNEUM_GROUP, 1, 1))) +#define IGNEUM_LOCAL_WORDS(name, n) __local uint name[n] +#if IGNEUM_EXCHANGE == 1 +#ifdef cl_khr_subgroups +#pragma OPENCL EXTENSION cl_khr_subgroups : enable +#endif +#ifdef cl_khr_subgroup_shuffle +#pragma OPENCL EXTENSION cl_khr_subgroup_shuffle : enable +#endif +#elif IGNEUM_EXCHANGE == 2 +#pragma OPENCL EXTENSION cl_intel_subgroups : enable +#endif +#else +// Not an OpenCL compiler: proto-opencl/emu compiles this file as C++ and supplies the built-ins and these two macros. +#include "emu_opencl.h" +#endif + +#if IGNEUM_EXCHANGE == 1 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#elif IGNEUM_EXCHANGE == 2 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = intel_sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#else +// Local-memory exchange. Two buffers of IGNEUM_GROUP words alternate (xk counts exchanges), so one barrier per +// exchange is enough: a lane can only overwrite buffer b at exchange k+2 after passing barrier k+1, and every lane +// reaches barrier k+1 only after its read of buffer b at exchange k. The partner lid ^ m stays inside the lane's +// aligned run of 32 because m < 32. Control flow is uniform, so every work-item reaches every barrier. +#define IGNEUM_SHFL_XOR(dst, a, m) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid ^ (uint)(m))]; xk += 1u; } +#define IGNEUM_BCAST0(dst, a) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid & ~31u)]; xk += 1u; } +#endif + +static inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site. OpenCL rotate() rotates left by n modulo 32. +static inline uint rotl_imm(uint x, uint n) { return rotate(x, n); } +// Right rotation by n modulo 32 as a left rotation by (32 - n) modulo 32; n == 0 gives x. +static inline uint rotr_var(uint x, uint n) { return rotate(x, (0u - n) & 31u); } +static inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +static inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +static inline void mh_chacha_block(const uint* x, uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +static inline void mh_cache_segment(__global uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + __global uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +static inline void mh_mixer(uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +static inline void mh_item(__global const uint* cache, __global const uint* leaf, uint t, uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint i = 0u; i < 16u; ++i) s[i] ^= leaf[i]; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + __global const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// Class v5 (docs/design/class-v5-stored-state.md): leaf(t) = leaves[t mod nLeaves], 16 words per leaf (leaves.bin). +static inline __global const uint* mh_leaf(__global const uint* leaves, uint nLeaves, uint t) { return leaves + ((t % nLeaves) * 16u); } +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +static inline uint mh_word(__global const uint* cache, __global const uint* leaves, uint nLeaves, uint w) { uint s[16]; mh_item(cache, mh_leaf(leaves, nLeaves, w >> 4u), w >> 4u, s); return s[w & 15u]; } + +// Memory-hard dataset (MEMHARD.md). One work-item per cache segment; one work-item per 64-byte dataset item. +// The same constants as memhard.h in this pack (one emitter, three dialects). +__kernel void igneum_cache_fill(__global uint* cache, uint nSegments) { + uint seg = (uint)get_global_id(0); + if (seg < nSegments) mh_cache_segment(cache, seg); +} +// Class v5: the window's leaves (leaves.bin, IGNEUM_STATE_LEAVES x 16 words) and their count. +__kernel void igneum_build(__global uint* ds, __global const uint* cache, __global const uint* leaves, uint nLeaves, uint nItems) { + uint t = (uint)get_global_id(0); + if (t < nItems) { + uint s[16]; + mh_item(cache, mh_leaf(leaves, nLeaves, t), t, s); + __global uint* d = ds + ((ulong)t * 16u); + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per work-item. IGNEUM_GROUP is a multiple of 32; lane = lid & 31 and every exchange stays inside the +// lane's own aligned run of 32 work-items, exactly like simd_shuffle_xor inside a 32-wide Metal SIMD group and +// __shfl_xor_sync inside a CUDA warp. Control flow is uniform (no branches at all). +IGNEUM_KERNEL_HASH void igneum_hash(__global const uint* ds, __global ulong* out, uint baseNonce, uint mask) { + uint gid = (uint)get_global_id(0); + uint lid = (uint)get_local_id(0); + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; +#if IGNEUM_EXCHANGE == 0 + IGNEUM_LOCAL_WORDS(xch, 2 * IGNEUM_GROUP); + uint xk = 0u; +#else + (void)lid; +#endif + { uint x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif + +// Header-bound variant (bind.rs): the init words come from initw, not SEEDW. Same body as igneum_hash. +IGNEUM_KERNEL_HASH void igneum_hash_bound(__global const uint* ds, __global ulong* out, uint baseNonce, uint mask, __global const uint* initw) { + uint gid = (uint)get_global_id(0); + uint lid = (uint)get_local_id(0); + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; + uint iw0 = initw[0], iw1 = initw[1], iw2 = initw[2], iw3 = initw[3], iw4 = initw[4], iw5 = initw[5], iw6 = initw[6], iw7 = initw[7]; +#if IGNEUM_EXCHANGE == 0 + IGNEUM_LOCAL_WORDS(xch, 2 * IGNEUM_GROUP); + uint xk = 0u; +#else + (void)lid; +#endif + { uint x = nonce ^ iw0; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw1; } + { uint x = nonce ^ iw1; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw2; } + { uint x = nonce ^ iw2; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw3; } + { uint x = nonce ^ iw3; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw4; } + { uint x = nonce ^ iw4; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw5; } + { uint x = nonce ^ iw5; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw6; } + { uint x = nonce ^ iw6; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw7; } + { uint x = nonce ^ iw7; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw0; } + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/kernel_bound.cu b/proto-cuda/packs-ca3-v5/v5-genesis/kernel_bound.cu new file mode 100644 index 000000000..4a823531b --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/kernel_bound.cu @@ -0,0 +1,382 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/leaves.bin b/proto-cuda/packs-ca3-v5/v5-genesis/leaves.bin new file mode 100644 index 000000000..dfbdae998 Binary files /dev/null and b/proto-cuda/packs-ca3-v5/v5-genesis/leaves.bin differ diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/memhard.h b/proto-cuda/packs-ca3-v5/v5-genesis/memhard.h new file mode 100644 index 000000000..cb4ea995b --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/memhard.h @@ -0,0 +1,112 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, const uint32_t* leaf, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= leaf[i]; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// Class v5 (docs/design/class-v5-stored-state.md): leaf(t) = leaves[t mod nLeaves], 16 words per leaf (leaves.bin). +IGNEUM_HD const uint32_t* mh_leaf(const uint32_t* leaves, uint32_t nLeaves, uint32_t t) { return leaves + ((t % nLeaves) * 16u); } +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, const uint32_t* leaves, uint32_t nLeaves, uint32_t w) { uint32_t s[16]; mh_item(cache, mh_leaf(leaves, nLeaves, w >> 4u), w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/memhard.metal b/proto-cuda/packs-ca3-v5/v5-genesis/memhard.metal new file mode 100644 index 000000000..239ceeacb --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/memhard.metal @@ -0,0 +1,112 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, device const uint* leaf, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint i = 0u; i < 16u; ++i) s[i] ^= leaf[i]; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// Class v5 (docs/design/class-v5-stored-state.md): leaf(t) = leaves[t mod nLeaves], 16 words per leaf (leaves.bin). +inline device const uint* mh_leaf(device const uint* leaves, uint nLeaves, uint t) { return leaves + ((t % nLeaves) * 16u); } +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, device const uint* leaves, uint nLeaves, uint w) { uint s[16]; mh_item(cache, mh_leaf(leaves, nLeaves, w >> 4u), w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +// Class v5: the window's leaves (leaves.bin, IGNEUM_STATE_LEAVES x 16 words) in buffer 2, their count in buffer 3. +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + device const uint* leaves [[buffer(2)]], constant uint& nLeaves [[buffer(3)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, mh_leaf(leaves, nLeaves, gid), gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/program.h b/proto-cuda/packs-ca3-v5/v5-genesis/program.h new file mode 100644 index 000000000..f3bc078b8 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/program.h @@ -0,0 +1,84 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 5 +#define IGNEUM_PROGRAM_ATTEMPT 0 +#define IGNEUM_PROGRAM_ID 0x7c54302b487340a1ull +#define IGNEUM_DAY_STRING "2026-10-03" +#define IGNEUM_DAY_BYTES_HEX "6461792f323032362d31302d3033" +#define IGNEUM_DAY0 0x3067619fu +#define IGNEUM_DAY1 0x3c269176u +#define IGNEUM_DATASET_LOG2 28 +#define IGNEUM_MASK 0x0fffffffu +#define IGNEUM_LANES 32 +#define IGNEUM_ITERATIONS 8 +#define IGNEUM_INSTR_COUNT 64 +#define IGNEUM_LOADS_PER_HASH 128 +#define IGNEUM_WIDE_LOADS_PER_HASH 0 +#define IGNEUM_OP_MIX "load=16 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1" +// Program class v5 (proof of stored state and of following, docs/design/class-v5-stored-state.md): generator version 5, +// class v4 over a dataset whose every item is keyed by the window's execution state (IGNEUM_STATE_* below, leaves.bin); +// a worker that runs another class refuses this pack, and a job line names the class it wants (class=v5 era=). +#define IGNEUM_PROGRAM_CLASS "v5" +// Class v3 construction (Counter ASIC 2.0, 5 October 2026, docs/plans/mixer-x4.md): version 2 loads; the dataset item +// derivation applies the mixer IGNEUM_MIXER_MULT times per round (memhard.h), and the cache follows the growth rule. +#define IGNEUM_LOAD_CLASS "mx8+sh256x27+state" +#define IGNEUM_CLASS_MIXER_MULT 8 +#define IGNEUM_CACHE_GROWTH 1 // 1: cache words = 2^(26 + doublings(day)), doublings = floor(log2(1 + day / 1460)) +#define IGNEUM_LOAD_SLOTS 16 +#define IGNEUM_LOAD_MIX { 100, 0, 0 } +#define IGNEUM_LOAD_WIDTH_COUNTS { 16, 0, 0 } // loads of 4, 16, 64 bytes per program +#define IGNEUM_BYTES_PER_HASH 512 +#define IGNEUM_FOLD_ROT 11 +#define IGNEUM_FOLD_MUL 0x9e3779b1u +// Class v5 state (docs/design/class-v5-stored-state.md): the window's reference chain block and the state root after it; +// leaves.bin holds IGNEUM_STATE_LEAVES leaves of 16 little-endian words, leaf(t) = leaves[t mod IGNEUM_STATE_LEAVES]. +#define IGNEUM_STATE_BLOCK_HEX "af89be5ddbadb6f6b4aee28ac8f249713be5d4c12621e3cea7f83ceada3c66b3" +#define IGNEUM_STATE_BLOCK_NUMBER 159357 +#define IGNEUM_STATE_ROOT_HEX "1c583d352bb9c75a06dadb8d82d42836ebe8afa82d0b413be87bf921741f1526" +#define IGNEUM_STATE_LEAVES 93 +#define IGNEUM_STATE_RECORDS 93 +#define IGNEUM_STATE_SAMPLED 0 +#define IGNEUM_STATE_LEAVES_FNV64 0x850ad094a937a5c5ull +#define IGNEUM_STATE_LEAVES_FILE "leaves.bin" +// Latency-shadow block (Counter ASIC 3.0 item 8, docs/analysis/latency-shadow-2026-10-06.md): NOT the lottery hash. A block of +// IGNEUM_SHADOW_INSTRS ALU instructions (the ten non-load families) runs IGNEUM_SHADOW_REPS times at the end of every +// iteration; the 16 loads, the acceptance rule and the base program are the class's without the shadow. +#define IGNEUM_SHADOW_INSTRS 256 +#define IGNEUM_SHADOW_REPS 27 +#define IGNEUM_SHADOW_INSTRS_PER_HASH 55296 +#define IGNEUM_SHADOW_OP_MIX "add=47 rotl=30 xor=30 shfl=29 mad=27 mul=22 sub=21 rotr=20 mulhi=18 or=12" +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, const uint32_t* leaves, uint32_t nLeaves, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/program.json b/proto-cuda/packs-ca3-v5/v5-genesis/program.json new file mode 100644 index 000000000..161b614eb --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/program.json @@ -0,0 +1,401 @@ +{ + "format": "igneum-program-pack-3", + "generator": 5, + "attempt": 0, + "program_id": "0x7c54302b487340a1", + "program_id_derivation": "FNV-1a 64 over 'igneum-program/' || generator_le32 || seed_words as little-endian bytes || attempt_le32", + "dataset_mode": "memory-hard", + "seed": "igneum-genesis", + "seed_bytes": "69676e65756d2d67656e65736973", + "seed_words": ["0x67a9a7be", "0x1a155b25", "0xfddfb732", "0x4b5af2e8", "0xc55caf33", "0xa27c13b7", "0x06628a48", "0x03852469"], + "seed_derivation": "seed_words = FNV-1a 64 over seed_bytes (attempt 0) or seed_bytes || attempt_le32 (attempt k >= 1), basis ^ (salt * 0x9E3779B97F4A7C15) for salt 0..3, then h ^= h>>33; h *= 0xff51afd7ed558ccd; h ^= h>>33; words[2*salt] = low 32, words[2*salt+1] = high 32", + "generator_rule": "version 2: exactly 16 load slots drawn first from instructions 1..63 (partial Fisher-Yates), the other 48 ops from the ten non-load weights (sum 75); a load's source is drawn from the registers other than dst written by an earlier instruction and not read by a load since; the candidate must pass the acceptance rule of spec 01 section 1.4.6 (static: no cyclically stale load source, every register has an injecting write; dynamic: 64 units on the seed-keyed closed-form dataset with no constant register bit, no lane-constant load site, under 164 saturated final values, every output bit within 136 of 1024, distinct addresses above 245760), else the next attempt of the seed is tried", + "lanes": 32, + "registers": 8, + "iterations": 8, + "instruction_count": 64, + "loads_per_hash": 128, + "program_class": "v5", + "state": { + "block": "af89be5ddbadb6f6b4aee28ac8f249713be5d4c12621e3cea7f83ceada3c66b3", + "block_number": 159357, + "root": "1c583d352bb9c75a06dadb8d82d42836ebe8afa82d0b413be87bf921741f1526", + "leaves": 93, + "records": 93, + "sampled": false, + "leaves_fnv1a64": "0x850ad094a937a5c5", + "leaf_derivation": "leaves[i] = Blake2b-512('igneum-sd1/' || root || i_le32 || record_i) as 16 little-endian words; item t XORs leaves[t mod leaves] into its 16 initial words before the first mixer", + "file": "leaves.bin" + }, + "load_class": "mx8+sh256x27+state", + "mixer_mult": 8, + "cache_growth": true, + "mixer": "class v3 (Counter ASIC 2.0, 5 October 2026, docs/plans/mixer-x4.md): every mixer application of the item derivation is 8 applications with round keys (r * 8 + j + 1) * 0x9E3779B9, the 8 dependent cache reads per item unchanged; cache growth rule option C: cache words = 2^(26 + doublings(day)), dataset words = 2^(genesis_log2 + doublings(day)), doublings(day) = floor(log2(1 + day / 1460)) for day = days since genesis", + "load_slots": 16, + "load_mix_percent_4_16_64": [100, 0, 0], + "load_width_counts_4_16_64": [16, 0, 0], + "bytes_per_hash": 512, + "wide_load": "read-width experiment (5 October 2026, docs/plans/read-width.md), NOT the lottery hash: a load of W words (width field, 4 or 16) reads dataset[b .. b + W) with b = (src & mask) & ~(W - 1) and folds every word into dst: x = dst ^ w[0]; for j in 1..W: x = (rotl(x, 11) * 0x9e3779b1) ^ w[j]; dst = x; width 1 is the plain load; the width is drawn per instruction from the class mix with one extra below(100) draw after the nine of version 2, and the program id is FNV-1a 64 over 'igneum-program-rw/' || generator_le32 || seed words || attempt_le32 || mix[3] || load_slots", + "op_mix": {"load": 16, "add": 8, "shfl": 8, "xor": 6, "mad": 5, "mul": 5, "mulhi": 5, "sub": 4, "rotl": 3, "rotr": 3, "or": 1}, + "register_init": "for i in 0..7: x = nonce ^ seed_words[i]; x += 0x9e3779b9 * (i+1) (mod 2^32); x = splitmix32(x); r[i] = x ^ seed_words[(i+1) & 7]", + "splitmix32": "x ^= x>>16; x *= 0x7feb352d; x ^= x>>15; x *= 0x846ca68b; x ^= x>>16", + "iteration": "sel = r0 sampled once at the top of each iteration, then all instructions in order", + "output": "lo = r0 ^ rotl(r1,7) ^ rotl(r2,14) ^ rotl(r3,21); hi = r4 ^ rotl(r5,9) ^ rotl(r6,18) ^ rotl(r7,27); out = (hi << 32) | lo", + "op_semantics": { + "add": "dst = dst + src + (bit `bit` of sel ? imm2 : imm)", + "sub": "dst = dst - src", + "mul": "dst = dst * src (low 32)", + "mulhi": "dst = high 32 bits of dst * src", + "xor": "dst = dst ^ src", + "or": "dst = dst | src", + "rotl": "dst = rotl(dst, rot), rot in 1..31", + "rotr": "dst = rotr(dst, src & 31)", + "mad": "dst = src * src2 + dst", + "shfl": "dst = dst ^ (src of lane (lane ^ mask)), mask in {1,2,4,8,16}, within the 32-lane warp", + "load": "dst = dst ^ dataset[src & dataset.mask]", + "wload": "base = (src of lane 0 & dataset.mask) & ~31; dst = dst ^ dataset[base + lane] (warp-coalesced 128-byte load, lever b, only when --wide-frac > 0)" + }, + "dataset": { + "log2_words": 28, + "bytes": 1073741824, + "mask": "0x0fffffff", + "day": "2026-10-03", + "day_bytes": "6461792f323032362d31302d3033", + "day_words_from": "seed_words_from_bytes(day_bytes)", + "d0": "0x3067619f", + "d1": "0x3c269176", + "mode": "memory-hard", + "spec": "proto-metal/MEMHARD.md", + "key": ["0x3067619f", "0x3c269176", "0x84a03b03", "0xf8c63294", "0xff977c5b", "0xe60def3e", "0x63630141", "0xb8fbcb58"], + "key_derivation": "the 8 words of seed_words_from_bytes(day_bytes); d0, d1 are key[0], key[1]", + "cache": {"log2_words": 26, "bytes": 268435456, "line_words": 16, "segment_lines": 64, "segments": 65536, "block": "ChaCha12 core + feed-forward, rotations 16 12 8 7", "sigma": ["0x61707865", "0x3320646e", "0x79622d32", "0x6b206574"], "tag": ["0x49676e65", "0x756d4d48"], "chain": "in_j = prev_line ^ (sigma[0..3] || key[0..7] || seg || j || tag[0..1]); line_j = block(in_j); prev_0 = 0"}, + "mixer": {"draw": "SplitMix64 seeded with key[0] | key[1] << 32: rot[0..7] = 1 + next() % 31, mul[0..15] = low32(next()) | 1, rc[0..15] = low32(next())", "rot": [20, 20, 19, 4, 26, 3, 3, 27], "mul": ["0x42146205", "0x52cbe0fb", "0x7ecf4a03", "0x6728907f", "0xd81d9751", "0x132952c3", "0xf60de277", "0x05358035", "0xbaf6499d", "0xe4db9667", "0x3e98f45d", "0xd0004edd", "0x2691630d", "0x9beb3bcf", "0xab310379", "0x99cfb423"], "rc": ["0xbab68293", "0xcc162340", "0x6ce151cc", "0xe62b8997", "0xc9c80297", "0xf74a1654", "0x3d704af5", "0x3cf522b7", "0x2b9cac04", "0xa880ac10", "0x13e5dd1d", "0x6fc3e233", "0x2d83eeac", "0x9006e8bf", "0x2c4b5362", "0x31b49ee2"], "round": "for i in 0..15: s[i] = (s[i] ^ (rc[i] + (r+1) * 0x9E3779B9)) * mul[i]; then quarter rounds on columns (0,4,8,12) (1,5,9,13) (2,6,10,14) (3,7,11,15) with rot[0..3] and diagonals (0,5,10,15) (1,6,11,12) (2,7,8,13) (3,4,9,14) with rot[4..7]", "quarter_round": "a += b; d ^= a; d = rotl(d, r1); c += d; b ^= c; b = rotl(b, r2); a += b; d ^= a; d = rotl(d, r3); c += d; b ^= c; b = rotl(b, r4)"}, + "mixer_mult": 8, + "item": "s[0..7] = key; s[8+i] = t * mul[i] + rc[i] for i in 0..7; for r in 0..7: for j in 0..7: s = M(s, rk = (r * 8 + j + 1) * 0x9E3779B9); line = s[0] & 0x003fffff; s[i] ^= cache[line * 16 + i]; then for j in 0..7: s = M(s, rk = (64 + j + 1) * 0x9E3779B9); item(t) = s", + "word": "dataset[w] = item(w >> 4)[w & 15]" + }, + "shadow": {"instrs": 256, "reps": 27, "instrs_per_hash": 55296, "op_mix": {"add": 47, "rotl": 30, "xor": 30, "shfl": 29, "mad": 27, "mul": 22, "sub": 21, "rotr": 20, "mulhi": 18, "or": 12}, "rule": "Counter ASIC 3.0 item 8 (docs/analysis/latency-shadow-2026-10-06.md): after the 64 base instructions the program stream draws instrs more ALU instructions (the non-load table, nine draws each, the source as on an ALU slot); the block runs reps times at the end of every iteration with the iteration's sel; the acceptance rule interprets the base program only", "program_id_suffix": "'shadow/' || instrs_le16 || reps_le16", "instructions": [ + {"i": 0, "op": "add", "dst": 5, "src": 2, "src2": 1, "imm": "0x92199f99", "imm2": "0x8bc12da9", "rot": 9, "bit": 18, "mask": 4}, + {"i": 1, "op": "add", "dst": 0, "src": 7, "src2": 1, "imm": "0x8d72d3ad", "imm2": "0x63079e5a", "rot": 20, "bit": 26, "mask": 4}, + {"i": 2, "op": "shfl", "dst": 6, "src": 3, "src2": 6, "imm": "0x9beaeddf", "imm2": "0x744ecb00", "rot": 10, "bit": 4, "mask": 2}, + {"i": 3, "op": "sub", "dst": 4, "src": 2, "src2": 0, "imm": "0x2a3ddc67", "imm2": "0x72c80241", "rot": 30, "bit": 1, "mask": 16}, + {"i": 4, "op": "add", "dst": 7, "src": 0, "src2": 5, "imm": "0xb21b4bab", "imm2": "0x5d4c7a60", "rot": 17, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 0, "src": 6, "src2": 3, "imm": "0xe69d7919", "imm2": "0xa048c61e", "rot": 11, "bit": 1, "mask": 8}, + {"i": 6, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2fe0e98b", "imm2": "0xc88e2942", "rot": 5, "bit": 16, "mask": 16}, + {"i": 7, "op": "xor", "dst": 7, "src": 1, "src2": 0, "imm": "0xc16efe98", "imm2": "0x01a638c8", "rot": 8, "bit": 17, "mask": 1}, + {"i": 8, "op": "mad", "dst": 1, "src": 6, "src2": 5, "imm": "0x76ec7b8b", "imm2": "0x25663feb", "rot": 29, "bit": 30, "mask": 2}, + {"i": 9, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x6c8ee3cb", "imm2": "0xea93237e", "rot": 27, "bit": 1, "mask": 4}, + {"i": 10, "op": "mad", "dst": 1, "src": 2, "src2": 2, "imm": "0x6dc4ea18", "imm2": "0x6efde6f5", "rot": 3, "bit": 20, "mask": 2}, + {"i": 11, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x023613fc", "imm2": "0x18c51939", "rot": 19, "bit": 31, "mask": 1}, + {"i": 12, "op": "shfl", "dst": 2, "src": 6, "src2": 1, "imm": "0x74aec8d2", "imm2": "0x7f7ad29c", "rot": 7, "bit": 8, "mask": 4}, + {"i": 13, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xbdf8f9a5", "imm2": "0xbc48c63e", "rot": 6, "bit": 25, "mask": 2}, + {"i": 14, "op": "rotl", "dst": 1, "src": 2, "src2": 6, "imm": "0x7ad8ca8b", "imm2": "0x14c712ad", "rot": 29, "bit": 25, "mask": 8}, + {"i": 15, "op": "sub", "dst": 1, "src": 4, "src2": 5, "imm": "0xd3349f69", "imm2": "0x70aac45a", "rot": 29, "bit": 9, "mask": 16}, + {"i": 16, "op": "or", "dst": 7, "src": 1, "src2": 2, "imm": "0x08168ed1", "imm2": "0x28964037", "rot": 26, "bit": 0, "mask": 2}, + {"i": 17, "op": "shfl", "dst": 2, "src": 4, "src2": 6, "imm": "0x98d85f72", "imm2": "0x3dc87042", "rot": 29, "bit": 22, "mask": 8}, + {"i": 18, "op": "xor", "dst": 7, "src": 4, "src2": 0, "imm": "0x651d4a0e", "imm2": "0x93c198bd", "rot": 26, "bit": 12, "mask": 8}, + {"i": 19, "op": "mul", "dst": 6, "src": 1, "src2": 6, "imm": "0xd38ce89d", "imm2": "0x3dfad388", "rot": 5, "bit": 28, "mask": 8}, + {"i": 20, "op": "mad", "dst": 5, "src": 6, "src2": 0, "imm": "0x59d78b36", "imm2": "0xc4db274e", "rot": 25, "bit": 24, "mask": 1}, + {"i": 21, "op": "sub", "dst": 3, "src": 1, "src2": 7, "imm": "0xf6c6a6c7", "imm2": "0x8536f4e6", "rot": 6, "bit": 12, "mask": 4}, + {"i": 22, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x599445b4", "imm2": "0x632f8c32", "rot": 19, "bit": 4, "mask": 8}, + {"i": 23, "op": "add", "dst": 2, "src": 0, "src2": 7, "imm": "0x45c37cec", "imm2": "0x96e8f127", "rot": 15, "bit": 1, "mask": 4}, + {"i": 24, "op": "sub", "dst": 6, "src": 4, "src2": 3, "imm": "0xc1c44491", "imm2": "0x92e3ce57", "rot": 20, "bit": 25, "mask": 4}, + {"i": 25, "op": "mad", "dst": 7, "src": 3, "src2": 4, "imm": "0x89bfb8d3", "imm2": "0x19b5455e", "rot": 22, "bit": 2, "mask": 16}, + {"i": 26, "op": "rotl", "dst": 3, "src": 5, "src2": 7, "imm": "0x2f47ce8d", "imm2": "0x8b458ec5", "rot": 9, "bit": 0, "mask": 4}, + {"i": 27, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0x9f0dce23", "imm2": "0x3cdca814", "rot": 25, "bit": 1, "mask": 2}, + {"i": 28, "op": "mulhi", "dst": 6, "src": 0, "src2": 3, "imm": "0x61fc9eb8", "imm2": "0x23202e9d", "rot": 30, "bit": 16, "mask": 16}, + {"i": 29, "op": "shfl", "dst": 2, "src": 4, "src2": 3, "imm": "0x339dbd65", "imm2": "0xc175f639", "rot": 15, "bit": 22, "mask": 2}, + {"i": 30, "op": "shfl", "dst": 1, "src": 6, "src2": 1, "imm": "0x5bd14589", "imm2": "0xa68a2bed", "rot": 31, "bit": 31, "mask": 1}, + {"i": 31, "op": "add", "dst": 1, "src": 6, "src2": 1, "imm": "0x37985632", "imm2": "0xb1cdb2ab", "rot": 29, "bit": 1, "mask": 8}, + {"i": 32, "op": "rotr", "dst": 0, "src": 1, "src2": 6, "imm": "0x4b2058f4", "imm2": "0xf06d8ac9", "rot": 9, "bit": 15, "mask": 16}, + {"i": 33, "op": "shfl", "dst": 3, "src": 4, "src2": 4, "imm": "0x2081626c", "imm2": "0x08d1bb87", "rot": 24, "bit": 29, "mask": 2}, + {"i": 34, "op": "shfl", "dst": 0, "src": 3, "src2": 6, "imm": "0xe4fcfe03", "imm2": "0x78a46b13", "rot": 15, "bit": 29, "mask": 4}, + {"i": 35, "op": "mul", "dst": 7, "src": 0, "src2": 4, "imm": "0x33148d30", "imm2": "0x5780a3d6", "rot": 6, "bit": 11, "mask": 2}, + {"i": 36, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0x804e777e", "imm2": "0x856e0180", "rot": 22, "bit": 0, "mask": 16}, + {"i": 37, "op": "xor", "dst": 1, "src": 6, "src2": 0, "imm": "0xc69aa2f6", "imm2": "0xafebe3e8", "rot": 15, "bit": 9, "mask": 16}, + {"i": 38, "op": "mul", "dst": 2, "src": 7, "src2": 4, "imm": "0xeb4c4082", "imm2": "0x3f1e0da7", "rot": 25, "bit": 20, "mask": 16}, + {"i": 39, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0x0b06c8a7", "imm2": "0xe9bd0cc4", "rot": 6, "bit": 2, "mask": 4}, + {"i": 40, "op": "mul", "dst": 5, "src": 7, "src2": 7, "imm": "0x070af1b6", "imm2": "0x6b648e75", "rot": 10, "bit": 6, "mask": 16}, + {"i": 41, "op": "mulhi", "dst": 2, "src": 3, "src2": 2, "imm": "0x389753b2", "imm2": "0x9e657305", "rot": 30, "bit": 2, "mask": 4}, + {"i": 42, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x0960e5b9", "imm2": "0xa925a406", "rot": 4, "bit": 6, "mask": 16}, + {"i": 43, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0x8eabe09f", "imm2": "0x76ef71e2", "rot": 4, "bit": 19, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 4, "src": 3, "src2": 7, "imm": "0x6a34768a", "imm2": "0x2e427c64", "rot": 21, "bit": 5, "mask": 4}, + {"i": 45, "op": "add", "dst": 6, "src": 7, "src2": 5, "imm": "0xee822e17", "imm2": "0xcdcb63f6", "rot": 27, "bit": 12, "mask": 16}, + {"i": 46, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xc89ead43", "imm2": "0x4d3108b2", "rot": 26, "bit": 17, "mask": 1}, + {"i": 47, "op": "shfl", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd62be9e", "imm2": "0xf243f6f2", "rot": 8, "bit": 4, "mask": 8}, + {"i": 48, "op": "mulhi", "dst": 6, "src": 5, "src2": 0, "imm": "0xd3f7fa72", "imm2": "0x0debc83f", "rot": 25, "bit": 5, "mask": 2}, + {"i": 49, "op": "sub", "dst": 0, "src": 2, "src2": 6, "imm": "0x7afadd15", "imm2": "0xc07fc39c", "rot": 30, "bit": 29, "mask": 8}, + {"i": 50, "op": "sub", "dst": 3, "src": 5, "src2": 3, "imm": "0x179b78ec", "imm2": "0xaeccde37", "rot": 30, "bit": 17, "mask": 1}, + {"i": 51, "op": "rotr", "dst": 1, "src": 4, "src2": 1, "imm": "0xa4bfcea6", "imm2": "0xbf63bb2f", "rot": 2, "bit": 21, "mask": 2}, + {"i": 52, "op": "mad", "dst": 6, "src": 7, "src2": 7, "imm": "0xabf5ed10", "imm2": "0x8a285f51", "rot": 3, "bit": 23, "mask": 2}, + {"i": 53, "op": "xor", "dst": 5, "src": 3, "src2": 5, "imm": "0x88b416eb", "imm2": "0x36271d87", "rot": 19, "bit": 10, "mask": 2}, + {"i": 54, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0xa3417dd3", "imm2": "0xcd98f620", "rot": 28, "bit": 2, "mask": 1}, + {"i": 55, "op": "sub", "dst": 5, "src": 6, "src2": 2, "imm": "0x45996c6f", "imm2": "0xe3d41087", "rot": 4, "bit": 31, "mask": 1}, + {"i": 56, "op": "add", "dst": 3, "src": 2, "src2": 0, "imm": "0x3dfad1b6", "imm2": "0xd4758987", "rot": 27, "bit": 10, "mask": 2}, + {"i": 57, "op": "add", "dst": 4, "src": 1, "src2": 3, "imm": "0xfca75bc2", "imm2": "0x0602d6be", "rot": 19, "bit": 0, "mask": 16}, + {"i": 58, "op": "mulhi", "dst": 5, "src": 6, "src2": 5, "imm": "0x83250a7b", "imm2": "0x2f93d53b", "rot": 25, "bit": 7, "mask": 2}, + {"i": 59, "op": "shfl", "dst": 2, "src": 1, "src2": 0, "imm": "0x13f4a089", "imm2": "0x145ea125", "rot": 12, "bit": 3, "mask": 2}, + {"i": 60, "op": "rotl", "dst": 2, "src": 5, "src2": 6, "imm": "0xad3170e3", "imm2": "0x15db04d1", "rot": 9, "bit": 13, "mask": 2}, + {"i": 61, "op": "or", "dst": 4, "src": 6, "src2": 2, "imm": "0x4b6305b2", "imm2": "0x6e7b2e9c", "rot": 27, "bit": 16, "mask": 4}, + {"i": 62, "op": "rotr", "dst": 6, "src": 4, "src2": 6, "imm": "0xfcd4b1c9", "imm2": "0xaf5c733b", "rot": 6, "bit": 21, "mask": 16}, + {"i": 63, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x95cebb3e", "imm2": "0xbba9cdfc", "rot": 19, "bit": 23, "mask": 1}, + {"i": 64, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x5f7579ff", "imm2": "0xb104e01a", "rot": 25, "bit": 12, "mask": 8}, + {"i": 65, "op": "xor", "dst": 2, "src": 7, "src2": 3, "imm": "0x749c7611", "imm2": "0xf17df3bb", "rot": 27, "bit": 26, "mask": 2}, + {"i": 66, "op": "add", "dst": 2, "src": 1, "src2": 6, "imm": "0xd71c02ff", "imm2": "0x8596687a", "rot": 4, "bit": 6, "mask": 2}, + {"i": 67, "op": "rotl", "dst": 1, "src": 3, "src2": 2, "imm": "0xd2864071", "imm2": "0xaa644ef3", "rot": 21, "bit": 5, "mask": 1}, + {"i": 68, "op": "mul", "dst": 3, "src": 2, "src2": 1, "imm": "0xd0689a5f", "imm2": "0xa3a1f063", "rot": 13, "bit": 28, "mask": 2}, + {"i": 69, "op": "shfl", "dst": 7, "src": 5, "src2": 6, "imm": "0xd01476eb", "imm2": "0x76abb5c2", "rot": 7, "bit": 30, "mask": 2}, + {"i": 70, "op": "mul", "dst": 3, "src": 2, "src2": 5, "imm": "0x59a75c10", "imm2": "0x1e1fbb72", "rot": 20, "bit": 16, "mask": 1}, + {"i": 71, "op": "mad", "dst": 0, "src": 2, "src2": 5, "imm": "0x39cca1df", "imm2": "0x22c057ac", "rot": 5, "bit": 23, "mask": 16}, + {"i": 72, "op": "add", "dst": 6, "src": 7, "src2": 3, "imm": "0x3c6fe15d", "imm2": "0x08ac5733", "rot": 14, "bit": 0, "mask": 4}, + {"i": 73, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x2098627d", "imm2": "0xf4fecc81", "rot": 20, "bit": 30, "mask": 8}, + {"i": 74, "op": "mul", "dst": 3, "src": 6, "src2": 5, "imm": "0xf82e9e23", "imm2": "0x3ad62132", "rot": 10, "bit": 14, "mask": 16}, + {"i": 75, "op": "xor", "dst": 6, "src": 7, "src2": 4, "imm": "0x70548a91", "imm2": "0xa9715d2e", "rot": 6, "bit": 24, "mask": 1}, + {"i": 76, "op": "or", "dst": 3, "src": 0, "src2": 7, "imm": "0xa164325f", "imm2": "0xf300838b", "rot": 23, "bit": 23, "mask": 16}, + {"i": 77, "op": "add", "dst": 2, "src": 4, "src2": 6, "imm": "0x295d5fae", "imm2": "0xc100b495", "rot": 7, "bit": 1, "mask": 2}, + {"i": 78, "op": "mulhi", "dst": 3, "src": 7, "src2": 4, "imm": "0xb62cca87", "imm2": "0x2ebde415", "rot": 14, "bit": 7, "mask": 2}, + {"i": 79, "op": "or", "dst": 4, "src": 1, "src2": 7, "imm": "0xfcbc482d", "imm2": "0x8876e6cd", "rot": 29, "bit": 5, "mask": 2}, + {"i": 80, "op": "rotr", "dst": 4, "src": 3, "src2": 0, "imm": "0x6d64013b", "imm2": "0x675f4a8d", "rot": 26, "bit": 18, "mask": 8}, + {"i": 81, "op": "add", "dst": 4, "src": 3, "src2": 3, "imm": "0x274a9221", "imm2": "0x5cc59530", "rot": 15, "bit": 15, "mask": 2}, + {"i": 82, "op": "add", "dst": 7, "src": 3, "src2": 0, "imm": "0xc8651f8e", "imm2": "0x141479ec", "rot": 18, "bit": 5, "mask": 1}, + {"i": 83, "op": "rotr", "dst": 3, "src": 6, "src2": 0, "imm": "0xcc8a7766", "imm2": "0xc2eb5161", "rot": 4, "bit": 29, "mask": 2}, + {"i": 84, "op": "mad", "dst": 2, "src": 4, "src2": 7, "imm": "0xbc507d51", "imm2": "0x0b1196fd", "rot": 9, "bit": 7, "mask": 8}, + {"i": 85, "op": "shfl", "dst": 2, "src": 5, "src2": 5, "imm": "0x5a156c90", "imm2": "0xa6b3fbfa", "rot": 11, "bit": 2, "mask": 16}, + {"i": 86, "op": "xor", "dst": 3, "src": 2, "src2": 1, "imm": "0x8b042658", "imm2": "0xacf37a8f", "rot": 12, "bit": 23, "mask": 16}, + {"i": 87, "op": "shfl", "dst": 5, "src": 7, "src2": 2, "imm": "0x1a214238", "imm2": "0x017fdf5d", "rot": 29, "bit": 14, "mask": 2}, + {"i": 88, "op": "xor", "dst": 0, "src": 4, "src2": 2, "imm": "0xd523e612", "imm2": "0x2158c2ed", "rot": 30, "bit": 14, "mask": 4}, + {"i": 89, "op": "add", "dst": 3, "src": 2, "src2": 7, "imm": "0x53f915c2", "imm2": "0x883c0c92", "rot": 9, "bit": 18, "mask": 8}, + {"i": 90, "op": "rotr", "dst": 7, "src": 5, "src2": 5, "imm": "0xbd633b21", "imm2": "0xcf8c356c", "rot": 25, "bit": 31, "mask": 4}, + {"i": 91, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0xe2be00a5", "imm2": "0x3cc5bd20", "rot": 10, "bit": 31, "mask": 1}, + {"i": 92, "op": "shfl", "dst": 7, "src": 2, "src2": 4, "imm": "0x3d3da600", "imm2": "0x1f22df89", "rot": 4, "bit": 24, "mask": 1}, + {"i": 93, "op": "rotr", "dst": 6, "src": 2, "src2": 7, "imm": "0xb0f57471", "imm2": "0x8f2a7eca", "rot": 16, "bit": 25, "mask": 1}, + {"i": 94, "op": "rotl", "dst": 7, "src": 0, "src2": 4, "imm": "0x00a21815", "imm2": "0xeb4d7218", "rot": 14, "bit": 18, "mask": 16}, + {"i": 95, "op": "mad", "dst": 4, "src": 5, "src2": 5, "imm": "0xc4c3828e", "imm2": "0xfb7bba17", "rot": 16, "bit": 10, "mask": 16}, + {"i": 96, "op": "mad", "dst": 2, "src": 4, "src2": 5, "imm": "0xfc5bbc75", "imm2": "0xfc43468f", "rot": 31, "bit": 20, "mask": 16}, + {"i": 97, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x1fe9c249", "imm2": "0x164bb16b", "rot": 15, "bit": 9, "mask": 4}, + {"i": 98, "op": "mul", "dst": 5, "src": 4, "src2": 1, "imm": "0xeda725fa", "imm2": "0x66f7e9a2", "rot": 21, "bit": 6, "mask": 2}, + {"i": 99, "op": "sub", "dst": 2, "src": 0, "src2": 7, "imm": "0x8fb29f7d", "imm2": "0xf530eda1", "rot": 27, "bit": 30, "mask": 4}, + {"i": 100, "op": "rotl", "dst": 7, "src": 2, "src2": 0, "imm": "0x9f4de742", "imm2": "0x9b5ff871", "rot": 30, "bit": 21, "mask": 16}, + {"i": 101, "op": "add", "dst": 5, "src": 6, "src2": 7, "imm": "0x423fd9c9", "imm2": "0xbfd646cb", "rot": 17, "bit": 17, "mask": 2}, + {"i": 102, "op": "add", "dst": 7, "src": 6, "src2": 3, "imm": "0x8d3c011d", "imm2": "0x19b74a43", "rot": 12, "bit": 11, "mask": 4}, + {"i": 103, "op": "rotl", "dst": 5, "src": 6, "src2": 0, "imm": "0xcfc70303", "imm2": "0xf2b3e8ef", "rot": 6, "bit": 24, "mask": 1}, + {"i": 104, "op": "mul", "dst": 0, "src": 4, "src2": 5, "imm": "0x650475eb", "imm2": "0x11dcbd94", "rot": 15, "bit": 10, "mask": 1}, + {"i": 105, "op": "or", "dst": 0, "src": 5, "src2": 3, "imm": "0xaacaa145", "imm2": "0x9139d3fe", "rot": 4, "bit": 18, "mask": 2}, + {"i": 106, "op": "add", "dst": 0, "src": 1, "src2": 7, "imm": "0x8ce14721", "imm2": "0x7dcb7e18", "rot": 24, "bit": 15, "mask": 8}, + {"i": 107, "op": "rotl", "dst": 0, "src": 3, "src2": 3, "imm": "0xb36d6d98", "imm2": "0x2c3390c8", "rot": 15, "bit": 10, "mask": 16}, + {"i": 108, "op": "sub", "dst": 4, "src": 2, "src2": 5, "imm": "0xf6bbdaef", "imm2": "0x9db6f65e", "rot": 25, "bit": 10, "mask": 1}, + {"i": 109, "op": "mulhi", "dst": 2, "src": 0, "src2": 0, "imm": "0xb1721fd6", "imm2": "0xd96d52c9", "rot": 1, "bit": 27, "mask": 8}, + {"i": 110, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0xfb4ca37f", "imm2": "0xb6ec7dbe", "rot": 27, "bit": 12, "mask": 8}, + {"i": 111, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x2d9fc6b9", "imm2": "0x3c179ad8", "rot": 9, "bit": 28, "mask": 16}, + {"i": 112, "op": "mulhi", "dst": 2, "src": 0, "src2": 6, "imm": "0x71a9f6bd", "imm2": "0xd3417bf5", "rot": 2, "bit": 14, "mask": 8}, + {"i": 113, "op": "sub", "dst": 6, "src": 3, "src2": 5, "imm": "0xa3d19400", "imm2": "0x15df7330", "rot": 5, "bit": 2, "mask": 8}, + {"i": 114, "op": "mad", "dst": 7, "src": 6, "src2": 3, "imm": "0x1400d92e", "imm2": "0xfa4a158e", "rot": 16, "bit": 9, "mask": 1}, + {"i": 115, "op": "rotr", "dst": 5, "src": 1, "src2": 3, "imm": "0xd01684c3", "imm2": "0x6367febb", "rot": 23, "bit": 19, "mask": 2}, + {"i": 116, "op": "rotr", "dst": 6, "src": 4, "src2": 2, "imm": "0x8cd9eb96", "imm2": "0x98f33b24", "rot": 25, "bit": 1, "mask": 2}, + {"i": 117, "op": "add", "dst": 2, "src": 1, "src2": 7, "imm": "0x502138e2", "imm2": "0x47359729", "rot": 5, "bit": 22, "mask": 4}, + {"i": 118, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xd94a35c7", "imm2": "0xb83416c3", "rot": 11, "bit": 3, "mask": 4}, + {"i": 119, "op": "mul", "dst": 1, "src": 3, "src2": 6, "imm": "0x09b30cf7", "imm2": "0xef3b98e7", "rot": 17, "bit": 23, "mask": 8}, + {"i": 120, "op": "mad", "dst": 2, "src": 0, "src2": 4, "imm": "0x56416fe0", "imm2": "0x5e1dc8f3", "rot": 17, "bit": 14, "mask": 2}, + {"i": 121, "op": "mul", "dst": 0, "src": 3, "src2": 2, "imm": "0x2892697c", "imm2": "0x9cb3b14e", "rot": 29, "bit": 25, "mask": 2}, + {"i": 122, "op": "mulhi", "dst": 2, "src": 0, "src2": 3, "imm": "0xc33089a1", "imm2": "0xd6c5b530", "rot": 27, "bit": 13, "mask": 8}, + {"i": 123, "op": "mul", "dst": 5, "src": 6, "src2": 4, "imm": "0xdfe04e4a", "imm2": "0x3cc40160", "rot": 3, "bit": 14, "mask": 2}, + {"i": 124, "op": "mad", "dst": 4, "src": 2, "src2": 4, "imm": "0xb33dc1b7", "imm2": "0xab97743a", "rot": 7, "bit": 21, "mask": 4}, + {"i": 125, "op": "shfl", "dst": 4, "src": 2, "src2": 0, "imm": "0xfd469909", "imm2": "0xfc85dc55", "rot": 28, "bit": 24, "mask": 2}, + {"i": 126, "op": "xor", "dst": 2, "src": 0, "src2": 5, "imm": "0xa0094578", "imm2": "0xf1bee474", "rot": 31, "bit": 7, "mask": 2}, + {"i": 127, "op": "rotl", "dst": 1, "src": 7, "src2": 2, "imm": "0xb7ae00a0", "imm2": "0x86cce297", "rot": 7, "bit": 31, "mask": 8}, + {"i": 128, "op": "shfl", "dst": 7, "src": 2, "src2": 7, "imm": "0x019d1940", "imm2": "0x3fe9e7dd", "rot": 14, "bit": 4, "mask": 4}, + {"i": 129, "op": "rotl", "dst": 6, "src": 7, "src2": 7, "imm": "0x40a74cc4", "imm2": "0x09eb4adf", "rot": 17, "bit": 30, "mask": 1}, + {"i": 130, "op": "add", "dst": 2, "src": 5, "src2": 5, "imm": "0x33dff776", "imm2": "0x6c57e4e7", "rot": 27, "bit": 15, "mask": 4}, + {"i": 131, "op": "or", "dst": 0, "src": 3, "src2": 1, "imm": "0xe0c53bb9", "imm2": "0x124404f6", "rot": 4, "bit": 21, "mask": 16}, + {"i": 132, "op": "rotr", "dst": 5, "src": 0, "src2": 1, "imm": "0xe4353fce", "imm2": "0x559d0118", "rot": 2, "bit": 29, "mask": 4}, + {"i": 133, "op": "add", "dst": 2, "src": 3, "src2": 6, "imm": "0x5db25b34", "imm2": "0xe8212c0c", "rot": 21, "bit": 30, "mask": 1}, + {"i": 134, "op": "xor", "dst": 4, "src": 3, "src2": 6, "imm": "0x7366e50e", "imm2": "0x7cc1ffbd", "rot": 19, "bit": 18, "mask": 16}, + {"i": 135, "op": "xor", "dst": 6, "src": 1, "src2": 2, "imm": "0xa36decb7", "imm2": "0x79291734", "rot": 26, "bit": 0, "mask": 8}, + {"i": 136, "op": "sub", "dst": 1, "src": 7, "src2": 0, "imm": "0x225b03e4", "imm2": "0x7183e193", "rot": 16, "bit": 6, "mask": 2}, + {"i": 137, "op": "mad", "dst": 2, "src": 6, "src2": 2, "imm": "0x6f620d51", "imm2": "0x4e814e19", "rot": 6, "bit": 6, "mask": 2}, + {"i": 138, "op": "mulhi", "dst": 0, "src": 5, "src2": 6, "imm": "0x919d6bf3", "imm2": "0xc6240638", "rot": 17, "bit": 11, "mask": 16}, + {"i": 139, "op": "add", "dst": 2, "src": 7, "src2": 7, "imm": "0x218d4090", "imm2": "0xd44ff710", "rot": 1, "bit": 10, "mask": 16}, + {"i": 140, "op": "rotr", "dst": 1, "src": 4, "src2": 4, "imm": "0x4cbfa722", "imm2": "0x114e9564", "rot": 28, "bit": 9, "mask": 16}, + {"i": 141, "op": "shfl", "dst": 3, "src": 6, "src2": 2, "imm": "0xf702c6a1", "imm2": "0xf8f3c5d9", "rot": 7, "bit": 24, "mask": 1}, + {"i": 142, "op": "mad", "dst": 7, "src": 6, "src2": 2, "imm": "0xa2d285be", "imm2": "0x9cc94532", "rot": 15, "bit": 20, "mask": 8}, + {"i": 143, "op": "mul", "dst": 2, "src": 3, "src2": 7, "imm": "0x08b7ed80", "imm2": "0xa8abced4", "rot": 18, "bit": 10, "mask": 4}, + {"i": 144, "op": "add", "dst": 7, "src": 4, "src2": 2, "imm": "0xf4b1a8de", "imm2": "0xb98942fa", "rot": 18, "bit": 29, "mask": 8}, + {"i": 145, "op": "rotl", "dst": 7, "src": 6, "src2": 1, "imm": "0x64b6ba2d", "imm2": "0xf9e86793", "rot": 15, "bit": 24, "mask": 8}, + {"i": 146, "op": "xor", "dst": 7, "src": 5, "src2": 3, "imm": "0x41c42b5f", "imm2": "0x7c7e0e39", "rot": 8, "bit": 23, "mask": 2}, + {"i": 147, "op": "mad", "dst": 4, "src": 7, "src2": 4, "imm": "0x3caa807a", "imm2": "0x553a0cec", "rot": 11, "bit": 22, "mask": 8}, + {"i": 148, "op": "rotr", "dst": 6, "src": 5, "src2": 3, "imm": "0x3cb1289a", "imm2": "0x6b36f78a", "rot": 1, "bit": 9, "mask": 16}, + {"i": 149, "op": "mad", "dst": 1, "src": 2, "src2": 4, "imm": "0x95310ea8", "imm2": "0xc533aa6a", "rot": 16, "bit": 17, "mask": 1}, + {"i": 150, "op": "add", "dst": 1, "src": 7, "src2": 7, "imm": "0x2bef10f2", "imm2": "0x0d48ba42", "rot": 8, "bit": 17, "mask": 4}, + {"i": 151, "op": "xor", "dst": 5, "src": 4, "src2": 7, "imm": "0xda997ab2", "imm2": "0xae31d69e", "rot": 11, "bit": 31, "mask": 2}, + {"i": 152, "op": "add", "dst": 7, "src": 0, "src2": 6, "imm": "0xdc5cc080", "imm2": "0xc98dea9c", "rot": 16, "bit": 30, "mask": 2}, + {"i": 153, "op": "mul", "dst": 4, "src": 6, "src2": 7, "imm": "0xbfbf5f6c", "imm2": "0x61f611bb", "rot": 14, "bit": 22, "mask": 2}, + {"i": 154, "op": "mul", "dst": 0, "src": 2, "src2": 3, "imm": "0xa78008c3", "imm2": "0xbad5eeb1", "rot": 10, "bit": 28, "mask": 8}, + {"i": 155, "op": "xor", "dst": 6, "src": 5, "src2": 4, "imm": "0x1a73b866", "imm2": "0x1f5a62c9", "rot": 9, "bit": 27, "mask": 8}, + {"i": 156, "op": "rotr", "dst": 4, "src": 2, "src2": 0, "imm": "0x9c88500c", "imm2": "0xe25dccf9", "rot": 11, "bit": 2, "mask": 16}, + {"i": 157, "op": "rotl", "dst": 1, "src": 4, "src2": 4, "imm": "0xb05e7669", "imm2": "0x9db704b1", "rot": 11, "bit": 28, "mask": 4}, + {"i": 158, "op": "add", "dst": 5, "src": 0, "src2": 6, "imm": "0x18197438", "imm2": "0x6c752dcb", "rot": 11, "bit": 11, "mask": 2}, + {"i": 159, "op": "mad", "dst": 4, "src": 1, "src2": 5, "imm": "0x4796a65e", "imm2": "0x00e08c7a", "rot": 8, "bit": 19, "mask": 4}, + {"i": 160, "op": "rotl", "dst": 4, "src": 7, "src2": 5, "imm": "0x08a03052", "imm2": "0x0204f0ba", "rot": 26, "bit": 5, "mask": 2}, + {"i": 161, "op": "mad", "dst": 3, "src": 0, "src2": 7, "imm": "0xa0603b0e", "imm2": "0x7eee83d5", "rot": 28, "bit": 22, "mask": 16}, + {"i": 162, "op": "rotr", "dst": 3, "src": 1, "src2": 6, "imm": "0x78a3c69d", "imm2": "0x684693a0", "rot": 21, "bit": 23, "mask": 4}, + {"i": 163, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xf1c46574", "imm2": "0x8e481727", "rot": 9, "bit": 3, "mask": 4}, + {"i": 164, "op": "mulhi", "dst": 0, "src": 4, "src2": 3, "imm": "0x04644afa", "imm2": "0x64bda2b5", "rot": 26, "bit": 16, "mask": 16}, + {"i": 165, "op": "add", "dst": 2, "src": 6, "src2": 2, "imm": "0xac578137", "imm2": "0x550ab406", "rot": 13, "bit": 20, "mask": 16}, + {"i": 166, "op": "rotl", "dst": 0, "src": 4, "src2": 5, "imm": "0x7f564760", "imm2": "0xb9a8b4f8", "rot": 13, "bit": 29, "mask": 1}, + {"i": 167, "op": "add", "dst": 3, "src": 1, "src2": 0, "imm": "0xa33e6706", "imm2": "0xaebb5966", "rot": 12, "bit": 14, "mask": 16}, + {"i": 168, "op": "or", "dst": 3, "src": 5, "src2": 3, "imm": "0x65b2f3eb", "imm2": "0xb1d00d20", "rot": 12, "bit": 2, "mask": 8}, + {"i": 169, "op": "rotr", "dst": 6, "src": 2, "src2": 3, "imm": "0x7f21faf5", "imm2": "0xbbf0d3f9", "rot": 17, "bit": 13, "mask": 8}, + {"i": 170, "op": "xor", "dst": 4, "src": 6, "src2": 2, "imm": "0x162c7140", "imm2": "0x90d404ad", "rot": 26, "bit": 1, "mask": 4}, + {"i": 171, "op": "sub", "dst": 6, "src": 1, "src2": 7, "imm": "0x6ef9c76e", "imm2": "0xfb7ba272", "rot": 31, "bit": 25, "mask": 1}, + {"i": 172, "op": "rotl", "dst": 7, "src": 5, "src2": 4, "imm": "0xde04eb3b", "imm2": "0xd56caa00", "rot": 22, "bit": 21, "mask": 4}, + {"i": 173, "op": "rotl", "dst": 5, "src": 3, "src2": 5, "imm": "0xa9eac934", "imm2": "0x2c338e51", "rot": 15, "bit": 22, "mask": 2}, + {"i": 174, "op": "shfl", "dst": 7, "src": 0, "src2": 3, "imm": "0x700be4e3", "imm2": "0x4bcfc732", "rot": 19, "bit": 6, "mask": 8}, + {"i": 175, "op": "xor", "dst": 0, "src": 5, "src2": 1, "imm": "0x02ccdba9", "imm2": "0xd0915be0", "rot": 15, "bit": 2, "mask": 16}, + {"i": 176, "op": "rotl", "dst": 7, "src": 4, "src2": 1, "imm": "0x489c8165", "imm2": "0xf24b5a4f", "rot": 6, "bit": 22, "mask": 1}, + {"i": 177, "op": "sub", "dst": 7, "src": 0, "src2": 6, "imm": "0x23ad9693", "imm2": "0x9a8c2f7b", "rot": 24, "bit": 2, "mask": 2}, + {"i": 178, "op": "rotl", "dst": 3, "src": 0, "src2": 6, "imm": "0xafa72a42", "imm2": "0x371d74ee", "rot": 30, "bit": 16, "mask": 1}, + {"i": 179, "op": "mad", "dst": 7, "src": 6, "src2": 1, "imm": "0x18a2a3f3", "imm2": "0xb811b951", "rot": 2, "bit": 9, "mask": 2}, + {"i": 180, "op": "rotl", "dst": 6, "src": 4, "src2": 1, "imm": "0xe6c69c0e", "imm2": "0xfc46a951", "rot": 9, "bit": 31, "mask": 4}, + {"i": 181, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0xbd1b89e4", "imm2": "0xdf4bce5c", "rot": 15, "bit": 19, "mask": 4}, + {"i": 182, "op": "xor", "dst": 2, "src": 7, "src2": 5, "imm": "0x3dd12aed", "imm2": "0xd0756a69", "rot": 13, "bit": 16, "mask": 4}, + {"i": 183, "op": "xor", "dst": 7, "src": 2, "src2": 3, "imm": "0x77ce69d6", "imm2": "0x2b39bdf2", "rot": 8, "bit": 22, "mask": 16}, + {"i": 184, "op": "add", "dst": 1, "src": 2, "src2": 4, "imm": "0xd94d55ac", "imm2": "0x5bb7550f", "rot": 31, "bit": 21, "mask": 1}, + {"i": 185, "op": "or", "dst": 3, "src": 5, "src2": 6, "imm": "0x7b1ce846", "imm2": "0xcc3b8509", "rot": 28, "bit": 9, "mask": 4}, + {"i": 186, "op": "mulhi", "dst": 6, "src": 3, "src2": 0, "imm": "0xa5e24690", "imm2": "0x2200ba81", "rot": 26, "bit": 10, "mask": 16}, + {"i": 187, "op": "or", "dst": 4, "src": 0, "src2": 3, "imm": "0xf6efe759", "imm2": "0xae1f7118", "rot": 19, "bit": 20, "mask": 4}, + {"i": 188, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0xdb318b45", "imm2": "0xcec459c9", "rot": 20, "bit": 11, "mask": 2}, + {"i": 189, "op": "add", "dst": 6, "src": 5, "src2": 1, "imm": "0x89e747fe", "imm2": "0x2a354e2d", "rot": 22, "bit": 6, "mask": 1}, + {"i": 190, "op": "xor", "dst": 1, "src": 4, "src2": 2, "imm": "0xc379e617", "imm2": "0x75e9d63b", "rot": 23, "bit": 3, "mask": 2}, + {"i": 191, "op": "mulhi", "dst": 7, "src": 4, "src2": 3, "imm": "0x5a710287", "imm2": "0x7fe4ead6", "rot": 10, "bit": 25, "mask": 4}, + {"i": 192, "op": "rotl", "dst": 2, "src": 1, "src2": 2, "imm": "0x4d5e59a3", "imm2": "0x1e4fef28", "rot": 26, "bit": 0, "mask": 1}, + {"i": 193, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x7444c47d", "imm2": "0xdad5f8be", "rot": 8, "bit": 30, "mask": 2}, + {"i": 194, "op": "shfl", "dst": 4, "src": 5, "src2": 7, "imm": "0x6a225bbb", "imm2": "0xd6532cd7", "rot": 13, "bit": 17, "mask": 16}, + {"i": 195, "op": "xor", "dst": 4, "src": 5, "src2": 3, "imm": "0x68344b9a", "imm2": "0xcb46a38b", "rot": 1, "bit": 27, "mask": 16}, + {"i": 196, "op": "mul", "dst": 1, "src": 3, "src2": 4, "imm": "0xbebf7359", "imm2": "0x3f0890ba", "rot": 18, "bit": 12, "mask": 4}, + {"i": 197, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0xea03e8e7", "imm2": "0x10cfdc71", "rot": 31, "bit": 7, "mask": 8}, + {"i": 198, "op": "add", "dst": 7, "src": 5, "src2": 1, "imm": "0xa7ee0102", "imm2": "0x66e148d3", "rot": 12, "bit": 15, "mask": 1}, + {"i": 199, "op": "sub", "dst": 5, "src": 2, "src2": 4, "imm": "0xc215584e", "imm2": "0x55fce30f", "rot": 30, "bit": 9, "mask": 2}, + {"i": 200, "op": "shfl", "dst": 5, "src": 1, "src2": 1, "imm": "0x308f8358", "imm2": "0x489f1f93", "rot": 13, "bit": 13, "mask": 2}, + {"i": 201, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0x713f1957", "imm2": "0x2239f757", "rot": 15, "bit": 7, "mask": 8}, + {"i": 202, "op": "rotr", "dst": 4, "src": 5, "src2": 1, "imm": "0xb037b6e7", "imm2": "0x49a8b528", "rot": 27, "bit": 13, "mask": 16}, + {"i": 203, "op": "xor", "dst": 7, "src": 5, "src2": 1, "imm": "0x56110241", "imm2": "0xefc8386d", "rot": 22, "bit": 20, "mask": 1}, + {"i": 204, "op": "xor", "dst": 7, "src": 0, "src2": 0, "imm": "0x0827fcc7", "imm2": "0xf4f5dd07", "rot": 13, "bit": 7, "mask": 2}, + {"i": 205, "op": "add", "dst": 6, "src": 2, "src2": 0, "imm": "0x8379a4de", "imm2": "0x8558b619", "rot": 26, "bit": 10, "mask": 1}, + {"i": 206, "op": "rotl", "dst": 4, "src": 3, "src2": 3, "imm": "0x091ceef0", "imm2": "0x69b0f72f", "rot": 13, "bit": 7, "mask": 1}, + {"i": 207, "op": "mulhi", "dst": 1, "src": 3, "src2": 4, "imm": "0x758edac1", "imm2": "0x98dd2f21", "rot": 15, "bit": 9, "mask": 1}, + {"i": 208, "op": "mad", "dst": 1, "src": 4, "src2": 4, "imm": "0x78871a1a", "imm2": "0x5e14e1c8", "rot": 19, "bit": 6, "mask": 2}, + {"i": 209, "op": "shfl", "dst": 2, "src": 0, "src2": 2, "imm": "0xf7e0b9aa", "imm2": "0xaecfd347", "rot": 21, "bit": 9, "mask": 4}, + {"i": 210, "op": "add", "dst": 7, "src": 0, "src2": 7, "imm": "0xaa8cb14e", "imm2": "0xf4049c4c", "rot": 24, "bit": 11, "mask": 8}, + {"i": 211, "op": "shfl", "dst": 7, "src": 1, "src2": 6, "imm": "0xc230d919", "imm2": "0xf76d08fb", "rot": 21, "bit": 13, "mask": 16}, + {"i": 212, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x31a5af90", "imm2": "0x7eef58ee", "rot": 9, "bit": 12, "mask": 4}, + {"i": 213, "op": "rotl", "dst": 7, "src": 1, "src2": 6, "imm": "0x0db26138", "imm2": "0x8e3c31f9", "rot": 3, "bit": 26, "mask": 2}, + {"i": 214, "op": "rotr", "dst": 4, "src": 7, "src2": 3, "imm": "0x29558100", "imm2": "0xe4b13ad6", "rot": 29, "bit": 24, "mask": 8}, + {"i": 215, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x1b48c3d0", "imm2": "0x5c674ff6", "rot": 5, "bit": 9, "mask": 16}, + {"i": 216, "op": "or", "dst": 5, "src": 1, "src2": 0, "imm": "0xef768632", "imm2": "0x6de9d10d", "rot": 10, "bit": 4, "mask": 4}, + {"i": 217, "op": "sub", "dst": 1, "src": 2, "src2": 5, "imm": "0x88ca7f5a", "imm2": "0x24718a36", "rot": 18, "bit": 31, "mask": 1}, + {"i": 218, "op": "sub", "dst": 6, "src": 5, "src2": 0, "imm": "0xc4a06728", "imm2": "0xdc2a4fd8", "rot": 9, "bit": 9, "mask": 2}, + {"i": 219, "op": "rotl", "dst": 6, "src": 5, "src2": 7, "imm": "0xb7489e47", "imm2": "0xf13795c5", "rot": 4, "bit": 3, "mask": 8}, + {"i": 220, "op": "mulhi", "dst": 2, "src": 0, "src2": 2, "imm": "0x873cd31b", "imm2": "0x3dfbc55d", "rot": 12, "bit": 23, "mask": 8}, + {"i": 221, "op": "or", "dst": 2, "src": 0, "src2": 3, "imm": "0xdc21f099", "imm2": "0xee06f01e", "rot": 2, "bit": 17, "mask": 8}, + {"i": 222, "op": "shfl", "dst": 5, "src": 2, "src2": 6, "imm": "0x36def499", "imm2": "0xa2849d59", "rot": 23, "bit": 4, "mask": 8}, + {"i": 223, "op": "mulhi", "dst": 5, "src": 6, "src2": 7, "imm": "0xfb95fbca", "imm2": "0xc1aac427", "rot": 14, "bit": 11, "mask": 2}, + {"i": 224, "op": "sub", "dst": 0, "src": 6, "src2": 7, "imm": "0x3d9d29c4", "imm2": "0x34d0dcc0", "rot": 17, "bit": 6, "mask": 4}, + {"i": 225, "op": "rotl", "dst": 7, "src": 0, "src2": 5, "imm": "0x93b01b8e", "imm2": "0xfe1d75ac", "rot": 23, "bit": 15, "mask": 1}, + {"i": 226, "op": "or", "dst": 4, "src": 2, "src2": 4, "imm": "0xfed76e8e", "imm2": "0x1c24ecd8", "rot": 2, "bit": 6, "mask": 16}, + {"i": 227, "op": "mul", "dst": 2, "src": 4, "src2": 1, "imm": "0x5795f5b0", "imm2": "0x0566ea2a", "rot": 6, "bit": 28, "mask": 4}, + {"i": 228, "op": "rotl", "dst": 3, "src": 0, "src2": 2, "imm": "0x8c8486de", "imm2": "0xd066aa8f", "rot": 12, "bit": 20, "mask": 1}, + {"i": 229, "op": "rotr", "dst": 0, "src": 4, "src2": 0, "imm": "0x23a3e882", "imm2": "0xaca23902", "rot": 5, "bit": 22, "mask": 16}, + {"i": 230, "op": "add", "dst": 0, "src": 6, "src2": 4, "imm": "0x1d176220", "imm2": "0x2a7fecb2", "rot": 20, "bit": 16, "mask": 2}, + {"i": 231, "op": "shfl", "dst": 1, "src": 2, "src2": 0, "imm": "0x91172787", "imm2": "0xc5d7af28", "rot": 3, "bit": 24, "mask": 4}, + {"i": 232, "op": "mul", "dst": 2, "src": 1, "src2": 2, "imm": "0x0be68835", "imm2": "0xde692bdb", "rot": 30, "bit": 17, "mask": 1}, + {"i": 233, "op": "mad", "dst": 7, "src": 0, "src2": 1, "imm": "0xf90d2db5", "imm2": "0x96c4c175", "rot": 28, "bit": 7, "mask": 4}, + {"i": 234, "op": "rotl", "dst": 5, "src": 2, "src2": 1, "imm": "0x16379736", "imm2": "0x6973b905", "rot": 22, "bit": 17, "mask": 4}, + {"i": 235, "op": "rotr", "dst": 4, "src": 6, "src2": 2, "imm": "0x84292a13", "imm2": "0x0f897740", "rot": 12, "bit": 6, "mask": 8}, + {"i": 236, "op": "mad", "dst": 0, "src": 5, "src2": 1, "imm": "0xeb7de837", "imm2": "0x64f0c302", "rot": 4, "bit": 19, "mask": 1}, + {"i": 237, "op": "xor", "dst": 6, "src": 4, "src2": 4, "imm": "0x6ab4b683", "imm2": "0x20f17adb", "rot": 1, "bit": 0, "mask": 16}, + {"i": 238, "op": "xor", "dst": 4, "src": 6, "src2": 1, "imm": "0x5836b35c", "imm2": "0x3293cc4a", "rot": 16, "bit": 22, "mask": 16}, + {"i": 239, "op": "rotl", "dst": 6, "src": 1, "src2": 6, "imm": "0x769d8bc0", "imm2": "0xdc86c9cc", "rot": 18, "bit": 27, "mask": 16}, + {"i": 240, "op": "add", "dst": 4, "src": 7, "src2": 1, "imm": "0x17dafb4d", "imm2": "0xadce39f3", "rot": 12, "bit": 25, "mask": 8}, + {"i": 241, "op": "sub", "dst": 0, "src": 7, "src2": 4, "imm": "0xd4690bda", "imm2": "0xdab9b27b", "rot": 30, "bit": 21, "mask": 1}, + {"i": 242, "op": "rotr", "dst": 1, "src": 6, "src2": 2, "imm": "0x670a2d0a", "imm2": "0x0612e33c", "rot": 31, "bit": 25, "mask": 2}, + {"i": 243, "op": "add", "dst": 3, "src": 0, "src2": 2, "imm": "0xf2f77d26", "imm2": "0x0e7033b6", "rot": 27, "bit": 29, "mask": 1}, + {"i": 244, "op": "mad", "dst": 2, "src": 7, "src2": 4, "imm": "0xa9eefc9d", "imm2": "0x16166c85", "rot": 18, "bit": 23, "mask": 16}, + {"i": 245, "op": "mad", "dst": 4, "src": 0, "src2": 6, "imm": "0xb26f6c0f", "imm2": "0x0630e821", "rot": 23, "bit": 30, "mask": 4}, + {"i": 246, "op": "mul", "dst": 5, "src": 7, "src2": 2, "imm": "0x269ce4bf", "imm2": "0x1ce28d32", "rot": 30, "bit": 15, "mask": 16}, + {"i": 247, "op": "add", "dst": 3, "src": 5, "src2": 0, "imm": "0xfed2da4e", "imm2": "0x7b2ff6b7", "rot": 25, "bit": 31, "mask": 2}, + {"i": 248, "op": "add", "dst": 0, "src": 7, "src2": 5, "imm": "0x03b2891c", "imm2": "0xb5fad7b1", "rot": 2, "bit": 0, "mask": 4}, + {"i": 249, "op": "mulhi", "dst": 5, "src": 4, "src2": 6, "imm": "0xa69a1e71", "imm2": "0x15f0c0ea", "rot": 4, "bit": 1, "mask": 4}, + {"i": 250, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x042cd6e3", "imm2": "0xa7e71c2f", "rot": 24, "bit": 11, "mask": 8}, + {"i": 251, "op": "shfl", "dst": 6, "src": 1, "src2": 2, "imm": "0x89c6b683", "imm2": "0x10bbf661", "rot": 24, "bit": 5, "mask": 1}, + {"i": 252, "op": "xor", "dst": 6, "src": 1, "src2": 3, "imm": "0x265c66d6", "imm2": "0xd4a689ed", "rot": 6, "bit": 14, "mask": 8}, + {"i": 253, "op": "mul", "dst": 2, "src": 5, "src2": 5, "imm": "0x890b8201", "imm2": "0x97c36bf3", "rot": 17, "bit": 22, "mask": 4}, + {"i": 254, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0x784a302b", "imm2": "0xb83d78de", "rot": 27, "bit": 16, "mask": 4}, + {"i": 255, "op": "sub", "dst": 2, "src": 4, "src2": 0, "imm": "0x817adb38", "imm2": "0xf3a3534b", "rot": 7, "bit": 22, "mask": 4} + ]}, + "instructions": [ + {"i": 0, "op": "mad", "dst": 2, "src": 3, "src2": 4, "imm": "0xbf7b174d", "imm2": "0x337b762e", "rot": 17, "bit": 2, "mask": 2, "width": 1}, + {"i": 1, "op": "mad", "dst": 2, "src": 1, "src2": 1, "imm": "0xdd04a5da", "imm2": "0x42da7657", "rot": 15, "bit": 30, "mask": 16, "width": 1}, + {"i": 2, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0x734003fa", "imm2": "0x5bb67700", "rot": 3, "bit": 20, "mask": 1, "width": 1}, + {"i": 3, "op": "xor", "dst": 3, "src": 5, "src2": 5, "imm": "0xc55a1b1c", "imm2": "0xa19720f3", "rot": 7, "bit": 8, "mask": 1, "width": 1}, + {"i": 4, "op": "load", "dst": 7, "src": 2, "src2": 5, "imm": "0xad572dd7", "imm2": "0x9ceb3ea7", "rot": 18, "bit": 30, "mask": 2, "width": 1}, + {"i": 5, "op": "load", "dst": 5, "src": 7, "src2": 3, "imm": "0x769a53be", "imm2": "0x80f9067e", "rot": 12, "bit": 22, "mask": 1, "width": 1}, + {"i": 6, "op": "shfl", "dst": 1, "src": 4, "src2": 0, "imm": "0xd3613d88", "imm2": "0x262fb219", "rot": 10, "bit": 30, "mask": 8, "width": 1}, + {"i": 7, "op": "shfl", "dst": 7, "src": 3, "src2": 4, "imm": "0xce38e42f", "imm2": "0xb868b818", "rot": 11, "bit": 8, "mask": 8, "width": 1}, + {"i": 8, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xa5eebca5", "imm2": "0x5703a72b", "rot": 13, "bit": 13, "mask": 16, "width": 1}, + {"i": 9, "op": "rotr", "dst": 6, "src": 3, "src2": 4, "imm": "0x17a5a9c7", "imm2": "0xdcfb93a1", "rot": 20, "bit": 27, "mask": 2, "width": 1}, + {"i": 10, "op": "or", "dst": 3, "src": 4, "src2": 1, "imm": "0xccb7d785", "imm2": "0xc335364c", "rot": 14, "bit": 12, "mask": 4, "width": 1}, + {"i": 11, "op": "load", "dst": 4, "src": 3, "src2": 2, "imm": "0x88cb9af3", "imm2": "0x4e7dc10d", "rot": 24, "bit": 17, "mask": 4, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 0, "src": 4, "src2": 4, "imm": "0x45374321", "imm2": "0x3cd91989", "rot": 11, "bit": 4, "mask": 2, "width": 1}, + {"i": 13, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc7934706", "imm2": "0xd3177981", "rot": 16, "bit": 30, "mask": 2, "width": 1}, + {"i": 14, "op": "load", "dst": 0, "src": 4, "src2": 3, "imm": "0xfd7f56bb", "imm2": "0x65e14f52", "rot": 13, "bit": 22, "mask": 2, "width": 1}, + {"i": 15, "op": "sub", "dst": 2, "src": 4, "src2": 4, "imm": "0x35a80b49", "imm2": "0x060f2d13", "rot": 16, "bit": 20, "mask": 16, "width": 1}, + {"i": 16, "op": "load", "dst": 2, "src": 0, "src2": 2, "imm": "0xae0a32c2", "imm2": "0x4c2a4cfe", "rot": 8, "bit": 31, "mask": 16, "width": 1}, + {"i": 17, "op": "load", "dst": 7, "src": 2, "src2": 6, "imm": "0x82a84cc3", "imm2": "0x21a38d68", "rot": 15, "bit": 21, "mask": 2, "width": 1}, + {"i": 18, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0xa3818806", "imm2": "0x8f66b5c8", "rot": 14, "bit": 6, "mask": 4, "width": 1}, + {"i": 19, "op": "mul", "dst": 5, "src": 0, "src2": 1, "imm": "0xa00de107", "imm2": "0x77bfcaa5", "rot": 3, "bit": 10, "mask": 2, "width": 1}, + {"i": 20, "op": "shfl", "dst": 3, "src": 4, "src2": 7, "imm": "0x1d2b8cab", "imm2": "0x80b4f9a2", "rot": 14, "bit": 25, "mask": 2, "width": 1}, + {"i": 21, "op": "shfl", "dst": 2, "src": 4, "src2": 5, "imm": "0x3ac915d2", "imm2": "0x5fba7bc2", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 22, "op": "mulhi", "dst": 6, "src": 2, "src2": 0, "imm": "0xdc3ec8fd", "imm2": "0x599e2fa3", "rot": 22, "bit": 3, "mask": 2, "width": 1}, + {"i": 23, "op": "load", "dst": 6, "src": 1, "src2": 5, "imm": "0x2a6b16d5", "imm2": "0xd73e396f", "rot": 28, "bit": 29, "mask": 2, "width": 1}, + {"i": 24, "op": "mul", "dst": 5, "src": 0, "src2": 7, "imm": "0x376d0223", "imm2": "0xe1c2169a", "rot": 4, "bit": 16, "mask": 16, "width": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 7, "src2": 3, "imm": "0x78ad8c60", "imm2": "0x6f5b77d5", "rot": 19, "bit": 11, "mask": 16, "width": 1}, + {"i": 26, "op": "shfl", "dst": 7, "src": 6, "src2": 5, "imm": "0x93915b9f", "imm2": "0x1e61fb6b", "rot": 28, "bit": 23, "mask": 2, "width": 1}, + {"i": 27, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x6378fe15", "imm2": "0x66c78f42", "rot": 12, "bit": 31, "mask": 8, "width": 1}, + {"i": 28, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x20a57fda", "imm2": "0x088c848e", "rot": 16, "bit": 13, "mask": 4, "width": 1}, + {"i": 29, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x49d95fd5", "imm2": "0x1a5f946a", "rot": 6, "bit": 12, "mask": 1, "width": 1}, + {"i": 30, "op": "mul", "dst": 5, "src": 1, "src2": 7, "imm": "0x0a816217", "imm2": "0x405c4f73", "rot": 13, "bit": 27, "mask": 4, "width": 1}, + {"i": 31, "op": "load", "dst": 7, "src": 2, "src2": 2, "imm": "0x09ed045e", "imm2": "0xd69c4715", "rot": 5, "bit": 9, "mask": 2, "width": 1}, + {"i": 32, "op": "load", "dst": 1, "src": 0, "src2": 6, "imm": "0xeb79ea49", "imm2": "0xcc587f5a", "rot": 6, "bit": 8, "mask": 16, "width": 1}, + {"i": 33, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0x3027401e", "imm2": "0x5f20c27e", "rot": 18, "bit": 9, "mask": 2, "width": 1}, + {"i": 34, "op": "load", "dst": 5, "src": 1, "src2": 3, "imm": "0x0e1cab07", "imm2": "0x09356c5b", "rot": 19, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mulhi", "dst": 0, "src": 5, "src2": 2, "imm": "0x90e31357", "imm2": "0xabd32484", "rot": 26, "bit": 5, "mask": 8, "width": 1}, + {"i": 36, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xee9a955f", "imm2": "0x31b3faed", "rot": 8, "bit": 24, "mask": 4, "width": 1}, + {"i": 37, "op": "load", "dst": 7, "src": 0, "src2": 7, "imm": "0x3ba2f832", "imm2": "0x1160dcd3", "rot": 4, "bit": 29, "mask": 1, "width": 1}, + {"i": 38, "op": "add", "dst": 3, "src": 1, "src2": 7, "imm": "0x75ba2fad", "imm2": "0x230c005c", "rot": 4, "bit": 27, "mask": 1, "width": 1}, + {"i": 39, "op": "shfl", "dst": 1, "src": 5, "src2": 3, "imm": "0xdbf37e75", "imm2": "0xb5ac1969", "rot": 30, "bit": 13, "mask": 4, "width": 1}, + {"i": 40, "op": "xor", "dst": 2, "src": 5, "src2": 5, "imm": "0x47f136c5", "imm2": "0x06ce9153", "rot": 19, "bit": 10, "mask": 2, "width": 1}, + {"i": 41, "op": "mad", "dst": 3, "src": 6, "src2": 3, "imm": "0xce13eff8", "imm2": "0x04cc1d55", "rot": 3, "bit": 1, "mask": 4, "width": 1}, + {"i": 42, "op": "sub", "dst": 6, "src": 7, "src2": 1, "imm": "0x6a65ab71", "imm2": "0x8fbc1bcd", "rot": 4, "bit": 1, "mask": 8, "width": 1}, + {"i": 43, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xdaeb4928", "imm2": "0xc0423027", "rot": 24, "bit": 11, "mask": 8, "width": 1}, + {"i": 44, "op": "load", "dst": 1, "src": 7, "src2": 7, "imm": "0x778f01c9", "imm2": "0x28cedcea", "rot": 12, "bit": 4, "mask": 16, "width": 1}, + {"i": 45, "op": "mul", "dst": 2, "src": 3, "src2": 2, "imm": "0xf4264f1b", "imm2": "0x0f627d56", "rot": 5, "bit": 28, "mask": 8, "width": 1}, + {"i": 46, "op": "mulhi", "dst": 1, "src": 5, "src2": 1, "imm": "0xffb2147a", "imm2": "0xccde9b05", "rot": 13, "bit": 9, "mask": 2, "width": 1}, + {"i": 47, "op": "sub", "dst": 4, "src": 3, "src2": 5, "imm": "0x73b36234", "imm2": "0x3f5d5997", "rot": 7, "bit": 18, "mask": 2, "width": 1}, + {"i": 48, "op": "rotr", "dst": 2, "src": 6, "src2": 3, "imm": "0x3a4d9aa9", "imm2": "0x212bec7b", "rot": 4, "bit": 29, "mask": 16, "width": 1}, + {"i": 49, "op": "load", "dst": 3, "src": 5, "src2": 2, "imm": "0x626f11df", "imm2": "0x56cd5bfd", "rot": 7, "bit": 1, "mask": 1, "width": 1}, + {"i": 50, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0x81b8bc2c", "imm2": "0x1907970c", "rot": 28, "bit": 7, "mask": 4, "width": 1}, + {"i": 51, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0xa8848b30", "imm2": "0xef6ac348", "rot": 9, "bit": 15, "mask": 8, "width": 1}, + {"i": 52, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x4f92b968", "imm2": "0x699fd448", "rot": 22, "bit": 6, "mask": 4, "width": 1}, + {"i": 53, "op": "add", "dst": 1, "src": 0, "src2": 2, "imm": "0x2bb965af", "imm2": "0x77b1520d", "rot": 2, "bit": 12, "mask": 8, "width": 1}, + {"i": 54, "op": "rotl", "dst": 7, "src": 1, "src2": 0, "imm": "0x553e678b", "imm2": "0x3cc8eae0", "rot": 14, "bit": 20, "mask": 2, "width": 1}, + {"i": 55, "op": "add", "dst": 3, "src": 7, "src2": 2, "imm": "0x7b0fe07a", "imm2": "0xa54c55a0", "rot": 10, "bit": 1, "mask": 1, "width": 1}, + {"i": 56, "op": "load", "dst": 6, "src": 7, "src2": 4, "imm": "0x01eba9aa", "imm2": "0x2758c0f7", "rot": 14, "bit": 15, "mask": 4, "width": 1}, + {"i": 57, "op": "rotr", "dst": 1, "src": 5, "src2": 2, "imm": "0x1f5267b3", "imm2": "0x236f5a27", "rot": 2, "bit": 31, "mask": 16, "width": 1}, + {"i": 58, "op": "load", "dst": 5, "src": 4, "src2": 3, "imm": "0xa9954a9b", "imm2": "0x6a54d4e8", "rot": 11, "bit": 10, "mask": 16, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 2, "src2": 4, "imm": "0x9923ff88", "imm2": "0x9357254e", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 60, "op": "mad", "dst": 3, "src": 5, "src2": 0, "imm": "0xc0cc51a6", "imm2": "0x3fd7701b", "rot": 20, "bit": 1, "mask": 4, "width": 1}, + {"i": 61, "op": "add", "dst": 5, "src": 7, "src2": 7, "imm": "0xaf9dd72d", "imm2": "0xad7493e7", "rot": 7, "bit": 31, "mask": 16, "width": 1}, + {"i": 62, "op": "add", "dst": 4, "src": 6, "src2": 2, "imm": "0x89841d87", "imm2": "0x1e07c3d9", "rot": 6, "bit": 27, "mask": 1, "width": 1}, + {"i": 63, "op": "rotl", "dst": 5, "src": 4, "src2": 2, "imm": "0xae210f8d", "imm2": "0x8e499ba4", "rot": 19, "bit": 9, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/program.metal b/proto-cuda/packs-ca3-v5/v5-genesis/program.metal new file mode 100644 index 000000000..2830702a7 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/program.metal @@ -0,0 +1,368 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +inline uint rotl_imm(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 +inline uint rotr_var(uint x, uint n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +kernel void igneum_hash(device const uint* dataset [[buffer(0)]], + device ulong* out [[buffer(1)]], + constant uint& baseNonce [[buffer(2)]], + uint gid [[thread_position_in_grid]]) { + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; + { uint x = nonce ^ SEEDW[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ SEEDW[1]; } + { uint x = nonce ^ SEEDW[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ SEEDW[2]; } + { uint x = nonce ^ SEEDW[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ SEEDW[3]; } + { uint x = nonce ^ SEEDW[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ SEEDW[4]; } + { uint x = nonce ^ SEEDW[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ SEEDW[5]; } + { uint x = nonce ^ SEEDW[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ SEEDW[6]; } + { uint x = nonce ^ SEEDW[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ SEEDW[7]; } + { uint x = nonce ^ SEEDW[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ SEEDW[0]; } + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/program_bound.metal b/proto-cuda/packs-ca3-v5/v5-genesis/program_bound.metal new file mode 100644 index 000000000..7a8da2d3e --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/program_bound.metal @@ -0,0 +1,370 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +inline uint rotl_imm(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 +inline uint rotr_var(uint x, uint n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Header-bound variant: the init words come from buffer 3 (bind.rs), not from SEEDW. +kernel void igneum_hash_bound(device const uint* dataset [[buffer(0)]], + device ulong* out [[buffer(1)]], + constant uint& baseNonce [[buffer(2)]], + constant uint* initw [[buffer(3)]], + uint gid [[thread_position_in_grid]]) { + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; + { uint x = nonce ^ initw[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ initw[1]; } + { uint x = nonce ^ initw[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ initw[2]; } + { uint x = nonce ^ initw[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ initw[3]; } + { uint x = nonce ^ initw[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ initw[4]; } + { uint x = nonce ^ initw[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ initw[5]; } + { uint x = nonce ^ initw[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ initw[6]; } + { uint x = nonce ^ initw[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ initw[7]; } + { uint x = nonce ^ initw[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ initw[0]; } + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/state.igsd1 b/proto-cuda/packs-ca3-v5/v5-genesis/state.igsd1 new file mode 100644 index 000000000..928ec54c6 Binary files /dev/null and b/proto-cuda/packs-ca3-v5/v5-genesis/state.igsd1 differ diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/vectors.h b/proto-cuda/packs-ca3-v5/v5-genesis/vectors.h new file mode 100644 index 000000000..ab462d2f3 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v5, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0x18d47ad5e5f0db00ull, 0x7bad059f946abeceull, 0xf9d064d2461e84b9ull, 0x61f99855860bfaffull, 0x8ceb18caca2a28a4ull, 0xc41ef792c1cdf022ull, 0xf93fd65c90d2ca85ull, 0xe05f1fcefad6ac17ull, + 0xca75db8b288394c8ull, 0xd2d02e2f0caa3d34ull, 0x55c04b4711b654a1ull, 0x890996d07a82024bull, 0x164e27f71445256eull, 0x497e8b5c25f010b6ull, 0xed52eb402b3501c7ull, 0x36d50fd7071d18a8ull, + 0x79c86b07ec275161ull, 0xa733baccc01c31cfull, 0x3bb6114b8fab2ef3ull, 0x6ea1779241832712ull, 0xe0f4c33714f88c95ull, 0x44694fe07fbab1a2ull, 0xf0636aa8db5587f0ull, 0xcd71ffde34250e9cull, + 0x6dc59534517c4294ull, 0xb99e758e4ad5c36bull, 0xc8d1d4d008a56300ull, 0xe6d649d80def4ed8ull, 0xa57cdab360808077ull, 0xd0dfff5a39a535e9ull, 0xd384678da3eaf980ull, 0xd1b36ed0ff68e575ull + }, + { // base nonce 4096 + 0xa1f55f0b0cae0ed2ull, 0x1b9517caa131adffull, 0x91efc5437cb3bbb6ull, 0xc2ce052743beececull, 0x5edc9aeb3dc54f97ull, 0x31b6f160bd1d1069ull, 0xfffed6c944c19815ull, 0x22a0050dfebaba09ull, + 0xa171087b94b99683ull, 0x8d32395a6f126c68ull, 0xeec0403785526159ull, 0xabc12d1205374c45ull, 0xb87906912cea83deull, 0x88386c58ce5f091full, 0x61e7ffb067923f94ull, 0x401186a9fa357655ull, + 0x39fbe72c29c340b9ull, 0x2897e77944d8d42full, 0x87cfc8564541e46full, 0xc683d7424b0ce10aull, 0x625d25030154b48eull, 0x3961c5d964a147e3ull, 0x55f3fe23e0e22844ull, 0x1a5691e092b68fccull, + 0xc119ecf12deece37ull, 0x99aa6b427ad63579ull, 0x9451ee9a7508cc8eull, 0x355a57b709bc0dabull, 0x027c1d956647504dull, 0x06e5306f90bc427full, 0xf3c67bceebd4345cull, 0x8c548231ef24eb73ull + }, + { // base nonce 1000000 + 0xbd47078fc688b540ull, 0x66d5813076f1f2dbull, 0x655fa4b32caaf1abull, 0x6be8361fefdd68f3ull, 0x71f4a4d1735e79daull, 0x17c5c3ba5247e51dull, 0xb1d12aa3fc17e7adull, 0x1576d399756776c6ull, + 0x4b9b95c3019b4b19ull, 0xc9fe5e1527e928e8ull, 0x0af1872b9fae1d86ull, 0x17092a7f1d5afd2bull, 0xb2b712e94c725152ull, 0xdb63b58a81a875a1ull, 0x26a87df44930bc14ull, 0x066cfccc7dfa83daull, + 0x7a35b15e43bd2dbbull, 0x517fa402b7d84936ull, 0xcc17d5055aeb5566ull, 0xdae63cca70104625ull, 0xd0266c887d67b8ffull, 0x8414cd867c472a4cull, 0x8d8367a8733f48e4ull, 0xc891e6eb4753b730ull, + 0x99caf2139b3496d9ull, 0xb5d78553a15a7f97ull, 0x1852f74b35b6054aull, 0xe2aa737c07b8c6ecull, 0xb6b8572e8bc1727aull, 0xe4b38aa4b670aa65ull, 0x42553edecd6c5061ull, 0x01f4d9a0bef81008ull + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0x3fdb9cc7u, 0x20a68a16u, 0xf543d4a5u, 0x12b21f10u, 0x1580e7f0u, 0x5a6f4182u, 0xb164b095u, 0x33ac8b62u, + 0x29296437u, 0xaada1879u, 0xa49620d3u, 0x761db725u, 0x24a81921u, 0x45c70b8bu, 0x3a674109u, 0x62647f74u +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0x769c356du; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0xdcafdb01u, 0xc091b066u, 0x98318ab1u, 0x73662aa4u, 0xf46b46b0u, 0x91ab95d4u, 0x3a5659c2u, 0x6e81c60au, 0x3d39ce88u, 0x1f6a2b6bu, 0x017b89d2u, 0x2e1b0d2fu, 0xd0d3fdcdu, 0x65478f05u, 0x09c627c5u, 0x6a12a65fu, 0x673dfe78u, 0x5e3cb389u, 0x9b6c3ab5u, 0x7db5867eu, 0x9e4e3844u, 0x0fb8d2a7u, 0x94da7c76u, 0x9047aae4u, 0x48bc05f4u, 0x8deb15bcu, 0x9b630120u, 0x7d2ec996u, 0x9162e70bu, 0x66303b2du, 0x7b61b5ecu, 0x2c72a23du, 0x6212ac42u, 0xa4212c34u, 0x7a37c02eu, 0xeb8b8117u, 0xb05dca47u, 0x06a6da71u, 0xa0b72498u, 0xd5917506u, 0xff1a7fb9u, 0x9809a9e4u, 0x729a7cf0u, 0xa14a997eu, 0x1f4b63e5u, 0xbdc389a4u, 0xfcec4807u, 0x49f01ffeu, 0xaa064d33u, 0xf752f881u, 0x485b414du, 0x60280cbcu, 0x14bfd7ccu, 0x646f720cu, 0x18e3d162u, 0x31b6781au, 0xc240fbd7u, 0x79b9d07eu, 0x2bcb0484u, 0xf8264c4cu, 0xe7ceb1e2u, 0x9ca84419u, 0x44770a37u, 0x9521c2dbu +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca3-v5/v5-genesis/vectors.json b/proto-cuda/packs-ca3-v5/v5-genesis/vectors.json new file mode 100644 index 000000000..440018841 --- /dev/null +++ b/proto-cuda/packs-ca3-v5/v5-genesis/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v5, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0x18d47ad5e5f0db00", "0x7bad059f946abece", "0xf9d064d2461e84b9", "0x61f99855860bfaff", "0x8ceb18caca2a28a4", "0xc41ef792c1cdf022", "0xf93fd65c90d2ca85", "0xe05f1fcefad6ac17", + "0xca75db8b288394c8", "0xd2d02e2f0caa3d34", "0x55c04b4711b654a1", "0x890996d07a82024b", "0x164e27f71445256e", "0x497e8b5c25f010b6", "0xed52eb402b3501c7", "0x36d50fd7071d18a8", + "0x79c86b07ec275161", "0xa733baccc01c31cf", "0x3bb6114b8fab2ef3", "0x6ea1779241832712", "0xe0f4c33714f88c95", "0x44694fe07fbab1a2", "0xf0636aa8db5587f0", "0xcd71ffde34250e9c", + "0x6dc59534517c4294", "0xb99e758e4ad5c36b", "0xc8d1d4d008a56300", "0xe6d649d80def4ed8", "0xa57cdab360808077", "0xd0dfff5a39a535e9", "0xd384678da3eaf980", "0xd1b36ed0ff68e575" + ]}, + {"base_nonce": 4096, "expected": [ + "0xa1f55f0b0cae0ed2", "0x1b9517caa131adff", "0x91efc5437cb3bbb6", "0xc2ce052743beecec", "0x5edc9aeb3dc54f97", "0x31b6f160bd1d1069", "0xfffed6c944c19815", "0x22a0050dfebaba09", + "0xa171087b94b99683", "0x8d32395a6f126c68", "0xeec0403785526159", "0xabc12d1205374c45", "0xb87906912cea83de", "0x88386c58ce5f091f", "0x61e7ffb067923f94", "0x401186a9fa357655", + "0x39fbe72c29c340b9", "0x2897e77944d8d42f", "0x87cfc8564541e46f", "0xc683d7424b0ce10a", "0x625d25030154b48e", "0x3961c5d964a147e3", "0x55f3fe23e0e22844", "0x1a5691e092b68fcc", + "0xc119ecf12deece37", "0x99aa6b427ad63579", "0x9451ee9a7508cc8e", "0x355a57b709bc0dab", "0x027c1d956647504d", "0x06e5306f90bc427f", "0xf3c67bceebd4345c", "0x8c548231ef24eb73" + ]}, + {"base_nonce": 1000000, "expected": [ + "0xbd47078fc688b540", "0x66d5813076f1f2db", "0x655fa4b32caaf1ab", "0x6be8361fefdd68f3", "0x71f4a4d1735e79da", "0x17c5c3ba5247e51d", "0xb1d12aa3fc17e7ad", "0x1576d399756776c6", + "0x4b9b95c3019b4b19", "0xc9fe5e1527e928e8", "0x0af1872b9fae1d86", "0x17092a7f1d5afd2b", "0xb2b712e94c725152", "0xdb63b58a81a875a1", "0x26a87df44930bc14", "0x066cfccc7dfa83da", + "0x7a35b15e43bd2dbb", "0x517fa402b7d84936", "0xcc17d5055aeb5566", "0xdae63cca70104625", "0xd0266c887d67b8ff", "0x8414cd867c472a4c", "0x8d8367a8733f48e4", "0xc891e6eb4753b730", + "0x99caf2139b3496d9", "0xb5d78553a15a7f97", "0x1852f74b35b6054a", "0xe2aa737c07b8c6ec", "0xb6b8572e8bc1727a", "0xe4b38aa4b670aa65", "0x42553edecd6c5061", "0x01f4d9a0bef81008" + ]} + ], + "dataset_head": ["0x3fdb9cc7", "0x20a68a16", "0xf543d4a5", "0x12b21f10", "0x1580e7f0", "0x5a6f4182", "0xb164b095", "0x33ac8b62", "0x29296437", "0xaada1879", "0xa49620d3", "0x761db725", "0x24a81921", "0x45c70b8b", "0x3a674109", "0x62647f74"], + "dataset_last_index": 268435455, + "dataset_last": "0x769c356d", + "dataset_samples": [{"index": 59471966, "value": "0xdcafdb01"}, {"index": 217795994, "value": "0xc091b066"}, {"index": 208353206, "value": "0x98318ab1"}, {"index": 42483309, "value": "0x73662aa4"}, {"index": 172547758, "value": "0xf46b46b0"}, {"index": 148076330, "value": "0x91ab95d4"}, {"index": 183853158, "value": "0x3a5659c2"}, {"index": 214389424, "value": "0x6e81c60a"}, {"index": 267488061, "value": "0x3d39ce88"}, {"index": 169781097, "value": "0x1f6a2b6b"}, {"index": 184093494, "value": "0x017b89d2"}, {"index": 153880993, "value": "0x2e1b0d2f"}, {"index": 84977930, "value": "0xd0d3fdcd"}, {"index": 46426879, "value": "0x65478f05"}, {"index": 3093825, "value": "0x09c627c5"}, {"index": 225364072, "value": "0x6a12a65f"}, {"index": 44593546, "value": "0x673dfe78"}, {"index": 260713159, "value": "0x5e3cb389"}, {"index": 168250303, "value": "0x9b6c3ab5"}, {"index": 52384140, "value": "0x7db5867e"}, {"index": 223401610, "value": "0x9e4e3844"}, {"index": 45554030, "value": "0x0fb8d2a7"}, {"index": 95410555, "value": "0x94da7c76"}, {"index": 175039924, "value": "0x9047aae4"}, {"index": 79171087, "value": "0x48bc05f4"}, {"index": 267580473, "value": "0x8deb15bc"}, {"index": 24168642, "value": "0x9b630120"}, {"index": 37981670, "value": "0x7d2ec996"}, {"index": 171551130, "value": "0x9162e70b"}, {"index": 195559979, "value": "0x66303b2d"}, {"index": 204611762, "value": "0x7b61b5ec"}, {"index": 140997658, "value": "0x2c72a23d"}, {"index": 138925853, "value": "0x6212ac42"}, {"index": 86637313, "value": "0xa4212c34"}, {"index": 20736778, "value": "0x7a37c02e"}, {"index": 219665210, "value": "0xeb8b8117"}, {"index": 160430336, "value": "0xb05dca47"}, {"index": 264654675, "value": "0x06a6da71"}, {"index": 8013395, "value": "0xa0b72498"}, {"index": 228945585, "value": "0xd5917506"}, {"index": 213884386, "value": "0xff1a7fb9"}, {"index": 104419827, "value": "0x9809a9e4"}, {"index": 44185464, "value": "0x729a7cf0"}, {"index": 142737231, "value": "0xa14a997e"}, {"index": 99284897, "value": "0x1f4b63e5"}, {"index": 132475900, "value": "0xbdc389a4"}, {"index": 61861762, "value": "0xfcec4807"}, {"index": 132056166, "value": "0x49f01ffe"}, {"index": 262388043, "value": "0xaa064d33"}, {"index": 91878046, "value": "0xf752f881"}, {"index": 117353561, "value": "0x485b414d"}, {"index": 124768597, "value": "0x60280cbc"}, {"index": 71352993, "value": "0x14bfd7cc"}, {"index": 190698941, "value": "0x646f720c"}, {"index": 46055428, "value": "0x18e3d162"}, {"index": 55281366, "value": "0x31b6781a"}, {"index": 165145231, "value": "0xc240fbd7"}, {"index": 106810753, "value": "0x79b9d07e"}, {"index": 171985651, "value": "0x2bcb0484"}, {"index": 232085256, "value": "0xf8264c4c"}, {"index": 159510492, "value": "0xe7ceb1e2"}, {"index": 40072060, "value": "0x9ca84419"}, {"index": 209107596, "value": "0x44770a37"}, {"index": 39023794, "value": "0x9521c2db"}], + "cache_head": ["0x355a86d2", "0x7957db1c", "0xd21772af", "0x6fc1e09b", "0xd55ce61d", "0x6e6a278b", "0xd3f543ce", "0x223d8e82", "0x143ab337", "0x2e9f05bd", "0x2eb389bf", "0x0c6e449e", "0x5cfa4222", "0xba6560fe", "0x8e3e1aa4", "0xdbcc1d53"], + "cache_last_line": ["0x41190d91", "0xbd277957", "0x22ddbb49", "0x6986f207", "0xdf69a4d6", "0x26401a3a", "0x818230fb", "0xc417122d", "0x3597b211", "0xb553ce55", "0xcf39cc0d", "0x3b7fc43a", "0x3fd43b00", "0x67e1c80e", "0xffa7ea7d", "0xca2960ab"], + "cache_fnv1a64": "0x48c4f5bf24166b2e" +} diff --git a/tools/class-v5/harness-remote.sh b/tools/class-v5/harness-remote.sh new file mode 100755 index 000000000..981b08ca3 --- /dev/null +++ b/tools/class-v5/harness-remote.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# The class v5 fast-time gate on igneum-build-1 (docs/design/class-v5-stored-state.md section 10): runs one case of +# infra/fast-time/class-v5-signal.mjs on the box from this worktree's mirror there (the fork's Linux binaries in +# vendor/igneum-node-class-v5/target/release and igneum-pow's in igneum-pow/target/release, both built by +# tools/build-remote.sh), under its own data dir, and copies the summary and log back under +# docs/design/class-v5-harness/.{json,log}. A functional run (counts, ids, locks), not a measurement: it takes +# no build slot and no measure hold (the Mac rule's `run` kind). +# +# tools/class-v5/harness-remote.sh -- +# tools/class-v5/harness-remote.sh failed-case -- --signal 5,5,4 --expect flip +set -euo pipefail +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT="$(cd "$HERE/../.." && pwd)" +CASE="${1:?case name}"; shift +[ "${1:-}" = "--" ] && shift +WT="$(basename "$ROOT")" +HOST=build@188.40.146.49 +KEY="$HOME/.ssh/igneum_ed25519" +REMOTE_ROOT="/srv/builds/$WT" +REMOTE_LOG="/srv/builds/_log/v5-class/harness" +OUT="$ROOT/docs/design/class-v5-harness" +mkdir -p "$OUT" +ARGS="$*" +echo "harness-remote: case $CASE on $HOST: node $REMOTE_ROOT/infra/fast-time/class-v5-signal.mjs $ARGS" +# the harness file travels by rsync (the mirror carries HEAD; an uncommitted change rides along, re-stamped: the copied-sources rule) +rsync -a -e "ssh -i $KEY" "$ROOT/infra/fast-time/class-v5-signal.mjs" "$ROOT/infra/fast-time/override-60x.json" "$HOST:$REMOTE_ROOT/infra/fast-time/" +ssh -i "$KEY" "$HOST" "touch $REMOTE_ROOT/infra/fast-time/class-v5-signal.mjs $REMOTE_ROOT/infra/fast-time/override-60x.json; mkdir -p $REMOTE_LOG; cd $REMOTE_ROOT && IGNEUM_V5_TMP=/tmp/igneum-fast-time-v5s-$CASE IGNEUM_V5_BIN=$REMOTE_ROOT/vendor/igneum-node-class-v5/target/release IGNEUM_POW=$REMOTE_ROOT/igneum-pow/target/release/igneum-pow node infra/fast-time/class-v5-signal.mjs $ARGS > $REMOTE_LOG/$CASE.log 2>&1; rc=\$?; cp /tmp/igneum-fast-time-v5s-$CASE/summary.json $REMOTE_LOG/$CASE.json 2>/dev/null || true; echo \"harness-remote: rc \$rc\"; exit \$rc" || true +rsync -a -e "ssh -i $KEY" "$HOST:$REMOTE_LOG/$CASE.log" "$HOST:$REMOTE_LOG/$CASE.json" "$OUT/" 2>/dev/null || true +grep -E "SUMMARY|FAILED CHECK|PROGRAM ID|CLASS SWITCH" "$OUT/$CASE.log" || tail -20 "$OUT/$CASE.log"