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 _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()
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 if op == "bfloat16.mul": pytest.skip("We don't have correct CW BFloat implementation yet")
# # floating point # 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)