def test_fp_mul(): # Regression test for https://github.com/StanfordAHA/lassen/issues/111 inst = asm.fp_mul() data0 = Data(0x4040) data1 = Data(0x4049) res, res_p, _ = pe(inst, data0, data1) if CAD_ENV: rtl_tester(inst, data0, data1, res=res) else: pytest.skip("Skipping since DW not available")
def __call__(self, in0: Data, in1: Data) -> Data: inst1 = asm.fgetmant() inst2 = asm.fsubexp() inst3 = asm.fp_mul() rom_instr = mem_asm.rom([TLUT.div_lut(i) for i in range(0, 128)] + [0x0000] * (depth - 128)) op_a = in0 op_b = in1 mant, _, _ = self.pe_get_mant(inst1, op_b, Data(0)) lookup_result = self.rom(rom_instr, mant, Data(0)) scaled_result, _, _ = self.pe_scale_res(inst2, lookup_result, op_b) result, _, _ = self.pe_mult(inst3, scaled_result, op_a) return result
def __call__(self, in0: Data) -> Data: inst1 = asm.fgetmant() inst2 = asm.fcnvexp2f() inst3 = asm.fp_mul() inst4 = asm.fp_add() rom_instr = mem_asm.rom([TLUT.ln_lut(i) for i in range(0, 128)] + [0x0000] * (depth - 128)) op_a = in0 ln2 = math.log(2) ln2_bf = int(float2bfbin(ln2), 2) const_ln2 = Data(ln2_bf) mant, _, _ = self.pe_get_mant(inst1, op_a, Data(0)) fexp, _, _ = self.pe_get_exp(inst2, op_a, Data(0)) lookup_result = self.rom(rom_instr, mant, Data(0)) mult, _, _ = self.pe_mult(inst3, fexp, const_ln2) result, _, _ = self.pe_mult(inst4, lookup_result, mult) return result
def __call__(self, in0: Data) -> Data: # Perform op_a/ln(2) inst1 = asm.fp_mul() # Compute 2**op_a inst2 = asm.fgetfint() inst3 = asm.fgetffrac() inst4 = asm.and_() inst5 = asm.faddiexp() rom_instr = mem_asm.rom([TLUT.exp_lut(i) for i in range(0, 128)] + [TLUT.exp_lut(i) for i in range(-128, 0)] + [0x0000] * (depth - 256)) op_a = in0 ln2_inv = 1.0 / math.log(2) ln2_inv_bf = int(float2bfbin(ln2_inv), 2) const_ln2_inv = Data(ln2_inv_bf) div_res, _, _ = self.pe_div_mult(inst1, const_ln2_inv, op_a) fint, _, _ = self.pe_get_int(inst2, div_res, Data(0)) ffrac, _, _ = self.pe_get_frac(inst3, div_res, Data(0)) idx, _, _ = self.pe_rom_idx(inst4, ffrac, Data(0xFF)) lookup_result = self.rom(rom_instr, idx, Data(0)) result, _, _ = self.pe_incr_exp(inst5, lookup_result, fint) return result
def _make_random(cls): if issubclass(cls, hwtypes.BitVector): return cls.random(len(cls)) if issubclass(cls, hwtypes.FPVector): while True: val = cls.random() if val.fp_is_normal(): return val.reinterpret_as_bv() return NotImplemented _CAD_DIR = "/cad/synopsys/syn/P-2019.03/dw/sim_ver/" _EXPENSIVE = { "bits32.mul": ((umult0(),), "magma_Bits_32_mul_inst0", hwtypes.UIntVector[16]), # noqa "bfloat16.mul": ((fp_mul(),), "magma_BFloat_16_mul_inst0", BFloat16_fc(PyFamily())), # noqa "bfloat16.add": ((fp_add(),), "magma_BFloat_16_add_inst0", BFloat16_fc(PyFamily())), # noqa } @pytest.mark.parametrize("op", list(_EXPENSIVE.keys())) def test_pe_data_gate(op, dw_files): instrs, fu, BV = _EXPENSIVE[op] is_float = issubclass(BV, hwtypes.FPVector) if not irun_available() and is_float: pytest.skip("Need irun to test fp ops") core = PeakCore(PE_fc) core.name = lambda: "PECore" circuit = core.circuit()
def _make_random(cls): if issubclass(cls, hwtypes.BitVector): return cls.random(len(cls)) if issubclass(cls, hwtypes.FPVector): while True: val = cls.random() if val.fp_is_normal(): return val.reinterpret_as_bv() return NotImplemented _EXPENSIVE = { "bits32.mul": ((umult0(), ), "magma_Bits_32_mul_inst0", hwtypes.UIntVector[16]), # noqa "bfloat16.mul": ((fp_mul(), ), "magma_BFloat_16_mul_inst0", BFloat16_fc(PyFamily())), # noqa "bfloat16.add": ((fp_add(), ), "magma_BFloat_16_add_inst0", BFloat16_fc(PyFamily())), # noqa } @pytest.mark.parametrize("op", list(_EXPENSIVE.keys())) def test_pe_data_gate(op, run_tb): instrs, fu, BV = _EXPENSIVE[op] is_float = issubclass(BV, hwtypes.FPVector) if not irun_available() and is_float: pytest.skip("Need irun to test fp ops") # note to skip mul since CW BFloat is faulty
# def BV(val): return BFloat16(val) fp_sign_vec = [BV(2.0), BV(-2.0), BV(3.0), BV(-3.0)] fp_zero_vec = [BV(0.0), BV('-0.0')] fp_inf_vec = [BV('inf'), BV('-inf')] @pytest.mark.parametrize("op", [ op(asm.fp_add(), lambda x, y: x + y), op(asm.fp_sub(), lambda x, y: x - y), op(asm.fp_mul(), lambda x, y: x * y) ]) @pytest.mark.parametrize( "args", [(BFloat16.random(), BFloat16.random()) for _ in range(NTESTS)] + list(product(fp_sign_vec + fp_zero_vec, fp_sign_vec + fp_zero_vec))) def test_fp_binary_op(op, args): inst = op.inst in0 = args[0] in1 = args[1] out = op.func(in0, in1) data0 = BFloat16.reinterpret_as_bv(in0) data1 = BFloat16.reinterpret_as_bv(in1) res, res_p, _ = pe(inst, data0, data1) assert res == BFloat16.reinterpret_as_bv(out) if CAD_ENV: rtl_tester(op, data0, data1, res=res)