tricu

A lazy functional language based on Tree Calculus
Log | Files | Refs | README | LICENSE

float-quantize.tri (2393B)


      1 -- Positive binary64 quantization benchmark.
      2 -- Exact input n * 2^(scale-2304), n and scale canonical naturals.
      3 -- RNE output: (IEEE magnitude bits, (inexact, storedTiny)).
      4 -- storedTiny means inexact with a stored zero/subnormal magnitude.
      5 !import native_math as N
      6 !import kernels as K
      7 !import pipelines as P
      8 !export *
      9 max a b = K.choose a b (N.gte a b)
     10 min a b = K.choose a b (N.lte a b)
     11 answer bits inexact tiny = t bits (t inexact (K.both inexact tiny))
     12 infinity = 9218868437227405312
     13 encode scale m inexact = K.lazy
     14   (_ : answer infinity (t t) t)
     15   (_ : K.lazy (_ : answer m inexact (t t))
     16     (_ : answer (N.add (P.shiftLeft 52 (N.successor (N.subtract scale 1230)))
     17                        (N.subtract m 4503599627370496)) inexact t)
     18     (N.lt m 4503599627370496)) (N.gt scale 3275)
     19 normalize scale m inexact = K.lazy
     20   (_ : answer 0 inexact (t t))
     21   (_ : let pad = min (N.subtract 53 (K.width m)) (N.subtract scale 1230) in
     22     encode (N.subtract scale pad) (P.shiftLeft pad m) inexact) (N.zero m)
     23 carry scale m inexact = K.lazy
     24   (_ : normalize (N.successor scale) (K.tail m) inexact)
     25   (_ : normalize scale m inexact) (N.gt (K.width m) 53)
     26 quantize scale n = K.lazy (_ : answer 0 t (t t))
     27   (_ : let cut = max (N.subtract (K.width n) 53) (N.subtract 1230 scale) in
     28     let rounded = K.roundL cut n in
     29     carry (N.add scale cut) (K.head rounded) (K.tail rounded)) (N.zero n)
     30 one x = quantize (K.head x) (K.tail x)
     31 quantized xs = K.map one xs
     32 -- Demand control: a zero result is independent of scale.
     33 spin x = spin x
     34 zeroDemand x = quantize (spin x) 0
     35 -- Near alignment passes the EXACT intermediate directly to the quantizer.
     36 -- Preconditions: normalized a,b; gap 0..54; a>=b for gap-zero subtraction.
     37 nearAdd x = let scale = K.head x in let rest = K.tail x in
     38   let gap = K.head rest in let ab = K.tail rest in
     39   quantize scale (N.add (P.shiftLeft gap (K.head ab)) (K.tail ab))
     40 nearSubtract x = let scale = K.head x in let rest = K.tail x in
     41   let gap = K.head rest in let ab = K.tail rest in
     42   quantize scale (N.subtract (P.shiftLeft gap (K.head ab)) (K.tail ab))
     43 nearAdds xs = K.map nearAdd xs
     44 nearSubtracts xs = K.map nearSubtract xs
     45 -- Negative rounding control: apply separate precision and quantum cuts.
     46 doubleRoundOne x = let first = P.finishL (K.tail x) in
     47   quantize (N.add (K.head x) (K.head first)) (K.head (K.tail first))
     48 doubleRoundControl xs = K.map doubleRoundOne xs