| """
|
| MACROGROK Q-format simulator — matches infer4.asm semantics.
|
| Q1.14: 1 sign + 1 int + 14 frac (range [-2, 2) but used as [-1,1) for INPUT)
|
| Q3.12: 3 int + 12 frac, Q7.24 32-bit ACC.
|
| """
|
| WEIGHTS_Q1_14 = [2458, -1638, 819, 3277]
|
| BIAS_Q3_12 = -256
|
| ALPHA_Q1_14 = 12288
|
|
|
| def q1_14_to_float(x): return x / 16384.0
|
| def float_to_q1_14(f): return max(-16384, min(16383, int(round(f*16384))))
|
| def q3_12_to_float(x): return x / 4096.0
|
|
|
| def infer4(input_q1_14):
|
| assert len(input_q1_14)==4
|
|
|
| acc = 0
|
| for w, inp in zip(WEIGHTS_Q1_14, input_q1_14):
|
| prod = w * inp
|
| prod_q3_24 = prod >> 4
|
| acc += prod_q3_24
|
|
|
| tmp0 = acc >> 12
|
| tmp0 = tmp0 + BIAS_Q3_12
|
|
|
| sat = False
|
| if tmp0 < -8192: tmp0=-8192; sat=True
|
| if tmp0 > 8191: tmp0=8191; sat=True
|
| tmp1 = 16384 if tmp0 >=0 else -16384
|
| flags = 0
|
| if tmp0>=0: flags|=0x4
|
| if sat: flags|=0x2
|
|
|
| global STATE
|
| try: STATE
|
| except NameError: globals()['STATE']=0
|
| STATE = (3*STATE + tmp1)//4
|
| flags|=0x1
|
| return STATE, tmp0, flags
|
|
|
| if __name__=="__main__":
|
| for vec in [[16384,0,0,0],[0,16384,0,0],[-16384,-16384,0,0],[8192,8192,8192,8192]]:
|
| out, score, flags = infer4(vec)
|
| print(f"in={[q1_14_to_float(x) for x in vec]} -> score Q3.12 {score} ({q3_12_to_float(score):.3f}) out Q1.14 {out} ({q1_14_to_float(out):.3f}) flags {flags:03b}")
|
|
|