igneum/proto-cuda/packs-ca2-mixer/mx8-devnet-epoch0/program_bound.metal

111 lines
5.3 KiB
Metal

#include <metal_stdlib>
using namespace metal;
#define MASK 0x0fffffffu
constant uint SEEDW[8] = { 0x667d0fbdu, 0x7b8e5963u, 0x31c67e5eu, 0x4529ddc6u, 0xef19d6d8u, 0xaccf6211u, 0xda0aed32u, 0xabc6df31u };
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;
r4 = r4 + r5 + select(0xea86e152u, 0x5810667au, ((sel >> 13u) & 1u) != 0u); // 0
r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // 1
r3 = r3 + r2 + select(0x2cccb6cau, 0x642e66dbu, ((sel >> 10u) & 1u) != 0u); // 2
r0 = rotl_imm(r0, 19u); // 3
r7 = rotr_var(r7, r6); // 4
r7 = r7 + r4 + select(0xee02465fu, 0xc1535555u, ((sel >> 21u) & 1u) != 0u); // 5
r1 = mulhi(r1, r7); // 6
r4 = r4 ^ dataset[r2 & MASK]; // 7
r7 = r7 ^ dataset[r4 & MASK]; // 8
r0 = r0 ^ dataset[r3 & MASK]; // 9
r5 = r5 ^ dataset[r1 & MASK]; // 10
r1 = r1 ^ dataset[r5 & MASK]; // 11
r3 = mulhi(r3, r5); // 12
r1 = r1 ^ dataset[r3 & MASK]; // 13
r0 = r0 - r3; // 14
r5 = r1 * r3 + r5; // 15
r6 = mulhi(r6, r1); // 16
r5 = r5 + r2 + select(0x697b3d00u, 0x8b965b57u, ((sel >> 28u) & 1u) != 0u); // 17
r0 = mulhi(r0, r6); // 18
r5 = rotr_var(r5, r3); // 19
r5 = mulhi(r5, r2); // 20
r1 = r1 + r0 + select(0xebcf247au, 0x6d7e8d05u, ((sel >> 1u) & 1u) != 0u); // 21
r7 = r7 + r5 + select(0xf66e7017u, 0xb9e3577eu, ((sel >> 12u) & 1u) != 0u); // 22
r1 = mulhi(r1, r5); // 23
r2 = r2 - r5; // 24
r7 = r7 + r4 + select(0x08ffa6c7u, 0x699ef1bbu, ((sel >> 2u) & 1u) != 0u); // 25
r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 26
r7 = r7 + r1 + select(0xe60fea84u, 0xb4ead2fbu, ((sel >> 14u) & 1u) != 0u); // 27
r3 = r3 + r1 + select(0x65c76dabu, 0x8f30d21du, ((sel >> 6u) & 1u) != 0u); // 28
r2 = r2 ^ dataset[r1 & MASK]; // 29
r5 = r5 ^ dataset[r7 & MASK]; // 30
r2 = r2 ^ dataset[r5 & MASK]; // 31
r1 = r1 ^ simd_shuffle_xor(r7, (ushort)4); // 32
r4 = r5 * r7 + r4; // 33
r4 = r4 + r2 + select(0x0480debeu, 0xc7ce690cu, ((sel >> 21u) & 1u) != 0u); // 34
r3 = r3 ^ simd_shuffle_xor(r7, (ushort)8); // 35
r7 = r7 + r1 + select(0xc53b542eu, 0xe10c2c95u, ((sel >> 2u) & 1u) != 0u); // 36
r5 = r5 ^ r7; // 37
r2 = r2 | r1; // 38
r1 = mulhi(r1, r0); // 39
r6 = rotl_imm(r6, 19u); // 40
r4 = mulhi(r4, r6); // 41
r6 = r6 - r0; // 42
r6 = r6 ^ simd_shuffle_xor(r3, (ushort)4); // 43
r4 = r4 ^ dataset[r2 & MASK]; // 44
r1 = r1 ^ r3; // 45
r7 = r7 ^ dataset[r0 & MASK]; // 46
r3 = r3 ^ dataset[r1 & MASK]; // 47
r5 = r5 * r3; // 48
r1 = r1 - r5; // 49
r2 = rotl_imm(r2, 8u); // 50
r1 = r1 + r5 + select(0xa900fec4u, 0x77b9bd43u, ((sel >> 23u) & 1u) != 0u); // 51
r4 = r4 ^ dataset[r7 & MASK]; // 52
r2 = r2 - r7; // 53
r4 = r4 ^ r0; // 54
r1 = r1 + r6 + select(0xe09f54e9u, 0x83e825bfu, ((sel >> 14u) & 1u) != 0u); // 55
r2 = r2 ^ dataset[r4 & MASK]; // 56
r0 = r1 * r4 + r0; // 57
r3 = r3 ^ dataset[r5 & MASK]; // 58
r5 = r5 | r6; // 59
r6 = r5 * r7 + r6; // 60
r4 = rotl_imm(r4, 28u); // 61
r5 = mulhi(r5, r0); // 62
r3 = r3 ^ dataset[r6 & MASK]; // 63
}
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;
}