float-chains.tri (6042B)
1 -- Chain benchmark over canonical 64-bit words and private caches. 2 -- Input (initialWord, (operandPool, [(opcode,poolIndex), ...])). Opcodes 0..3. 3 -- Output (finalWord, OR of all five flags); round after every operation. 4 !import native_math as N 5 !import kernels as K 6 !import layouts as L 7 !import fast as F 8 !import adders as A 9 !import finite as B 10 !import product_quotient as P 11 !import ieee as I 12 !export * 13 drop2 x = K.tail (K.tail x) 14 drop3 x = K.tail (drop2 x) 15 drop4 x = K.tail (drop3 x) 16 flagsOr a b = t (K.either (K.head a) (K.head b)) 17 (t (K.either (K.head (K.tail a)) (K.head (K.tail b))) 18 (t (K.either (K.head (drop2 a)) (K.head (drop2 b))) 19 (t (K.either (K.head (drop3 a)) (K.head (drop3 b))) 20 (K.either (drop4 a) (drop4 b))))) 21 at index xs = K.lazy (_ : K.head xs) (_ : at (N.predecessor index) (K.tail xs)) (N.zero index) 22 wordOp op a b = K.lazy (_ : I.add t a b) 23 (_ : K.lazy (_ : I.add (t t) a b) 24 (_ : K.lazy (_ : I.multiply a b) (_ : I.divide a b) (N.equal op 2)) (N.equal op 1)) (N.zero op) 25 checkedStep op a b = K.tail (I.checked (wordOp op) a b) 26 trustedStep op a b = K.lazy (_ : I.nanResult a b) (_ : wordOp op a b) 27 (K.either (I.nanBit a) (I.nanBit b)) 28 wordWalk step pool instructions reply = K.triage reply (_ : reply) 29 (instruction rest : let next = step (K.head instruction) (K.head reply) (at (K.tail instruction) pool) in 30 wordWalk step pool rest (t (K.head next) (flagsOr (K.tail reply) (K.tail next)))) instructions 31 wordChain step input = let initial = K.head input in let rest = K.tail input in 32 wordWalk step (K.head rest) (K.tail rest) (I.exact initial) 33 checked input = wordChain checkedStep input 34 trusted input = wordChain trustedStep input 35 -- Private lazy record: (word,(isNaN,(isInf,(isZero,normalizedRecord)))). 36 -- Word, exponent, fraction and normalized fields are shared within the record. 37 prepare word = let e = B.exponent word in let f = L.low52 word in 38 let special = N.equal e 2047 in let zeroFraction = N.zero f in 39 t word (t (K.both special (K.not zeroFraction)) 40 (t (K.both special zeroFraction) 41 (t (K.both (N.zero e) zeroFraction) 42 (t (B.signBit word) (K.lazy (_ : B.subnormal f) 43 (_ : t (N.add e 1229) (F.pack 1 word)) (N.zero e)))))) 44 word x = K.head x 45 nan x = K.head (K.tail x) 46 inf x = K.head (drop2 x) 47 zero x = K.head (drop3 x) 48 decoded x = drop4 x 49 sign x = B.sign (decoded x) 50 finiteAdd subtract a b = let da = decoded a in let originalB = decoded b in 51 let db = t (K.xor subtract (B.sign originalB)) (K.tail originalB) in K.lazy 52 (_ : K.lazy (_ : I.exact (I.zero (K.both (B.sign da) (B.sign db)))) 53 (_ : I.exact (K.choose (B.flip (word b)) (word b) subtract)) (zero b)) 54 (_ : K.lazy (_ : I.exact (word a)) 55 (_ : I.lift (K.lazy (_ : B.ordered da db) (_ : B.ordered db da) (B.dominates da db))) 56 (zero b)) (zero a) 57 finiteProduct a b = let da = decoded a in let db = decoded b in 58 let negative = K.xor (B.sign da) (B.sign db) in K.lazy 59 (_ : I.exact (I.zero negative)) 60 (_ : B.signed negative (I.quantize (N.subtract (N.add (B.scale da) (B.scale db)) 2304) 61 (A.orderedMultiply (B.mant da) (B.mant db)))) (K.either (zero a) (zero b)) 62 finiteQuotient a b = let da = decoded a in let db = decoded b in 63 let negative = K.xor (B.sign da) (B.sign db) in K.lazy 64 (_ : I.exact (I.zero negative)) 65 (_ : B.signed negative (I.quantize (N.subtract (N.add 2248 (B.scale da)) (B.scale db)) 66 (P.jam (P.boundedQuotient (B.mant da) (B.mant db))))) (zero a) 67 add subtract a b = let sa = sign a in let sb = K.xor subtract (sign b) in K.lazy 68 (_ : K.lazy (_ : I.invalidResult) (_ : I.exact (I.infinity (K.choose sa sb (inf a)))) 69 (K.both (K.both (inf a) (inf b)) (K.xor sa sb))) 70 (_ : finiteAdd subtract a b) (K.either (inf a) (inf b)) 71 multiply a b = let negative = K.xor (sign a) (sign b) in K.lazy 72 (_ : K.lazy (_ : I.invalidResult) (_ : I.exact (I.infinity negative)) (K.either (zero a) (zero b))) 73 (_ : finiteProduct a b) (K.either (inf a) (inf b)) 74 divide a b = let negative = K.xor (sign a) (sign b) in K.lazy 75 (_ : K.lazy (_ : I.invalidResult) (_ : I.exact (I.infinity negative)) (inf b)) 76 (_ : K.lazy (_ : I.exact (I.zero negative)) 77 (_ : K.lazy (_ : K.lazy (_ : I.invalidResult) 78 (_ : I.answer (I.infinity negative) t (t t) t t t) (zero a)) 79 (_ : finiteQuotient a b) (zero b)) (inf b)) (inf a) 80 cachedOp op a b = K.lazy (_ : add t a b) 81 (_ : K.lazy (_ : add (t t) a b) 82 (_ : K.lazy (_ : multiply a b) (_ : divide a b) (N.equal op 2)) (N.equal op 1)) (N.zero op) 83 cachedStep op a b = K.lazy (_ : I.nanResult (word a) (word b)) (_ : cachedOp op a b) 84 (K.either (nan a) (nan b)) 85 cachedWalk lookup pool instructions state flags = K.triage (t (word state) flags) (_ : t (word state) flags) 86 (instruction rest : let next = cachedStep (K.head instruction) state (lookup (K.tail instruction) pool) in 87 cachedWalk lookup pool rest (prepare (K.head next)) (flagsOr flags (K.tail next))) instructions 88 cached input = let initial = K.head input in let rest = K.tail input in 89 cachedWalk at (K.map prepare (K.head rest)) (K.tail rest) (prepare initial) (K.tail (I.exact initial)) 90 freshLookup index pool = prepare (at index pool) 91 fresh input = let initial = K.head input in let rest = K.tail input in 92 cachedWalk freshLookup (K.head rest) (K.tail rest) (prepare initial) (K.tail (I.exact initial)) 93 freshBatch xs = K.map fresh xs 94 -- Cache only within each operation: isolates cross-operation pool reuse. 95 localStep op a b = cachedStep op (prepare a) (prepare b) 96 local input = wordChain localStep input 97 checkedBatch xs = K.map checked xs 98 trustedBatch xs = K.map trusted xs 99 localBatch xs = K.map local xs 100 cachedBatch xs = K.map cached xs 101 spin x = spin x 102 emptyChecked x = checked (t 9223372036854775808 (t (spin x) t)) 103 emptyCached x = cached (t 9223372036854775808 (t (spin x) t)) 104 unusedPool x = cached (t 4607182418800017408 (t (t 0 (spin x)) (t (t 0 0) t))) 105 flagsOne x = flagsOr (K.head x) (K.tail x) 106 mergeFlags xs = K.map flagsOne xs 107 flagDemand x = K.head (flagsOr (t (t t) (spin x)) (t (spin x) (spin x)))