def __init__(self, peak_fc: tp.Callable): if not isinstance(peak_fc, family_closure): raise ValueError( f"family closure {peak_fc} needs to be decorated with @family_closure" ) Peak_cls = _get_peak_cls(peak_fc(family.SMTFamily())) try: input_t = Peak_cls.input_t output_t = Peak_cls.output_t except AttributeError: raise ValueError("Need to use gen_input_t and gen_output_t") stripped_input_t = strip_modifiers(input_t) stripped_output_t = strip_modifiers(output_t) input_aadt_t = family.SMTFamily().get_adt_t(stripped_input_t) output_aadt_t = family.SMTFamily().get_adt_t(stripped_output_t) input_forms, input_varmap = SMTForms()(input_aadt_t) #output_form = output_forms[input_form_idx][output_form_idx] output_forms = [] for input_form in input_forms: inputs = aadt_product_to_dict(input_form.value) #Construct output_aadt value outputs = Peak_cls()(**inputs) output_value = wrap_outputs(outputs, output_aadt_t) forms, output_varmap = SMTForms()(output_aadt_t, value=output_value) #Check consistency of SMTForms for f in forms: assert f.value == output_value output_forms.append(forms) num_input_forms = len(output_forms) num_output_forms = len(output_forms[0]) #verify same number of output forms assert all(num_output_forms == len(forms) for forms in output_forms) self.peak_fc = peak_fc self.input_form_var = SBV[num_input_forms]() self.output_form_var = SBV[num_output_forms]() self.input_forms = input_forms self.output_forms = output_forms self.num_output_forms = num_output_forms self.num_input_forms = num_input_forms self.input_varmap = input_varmap
def verify(self, solver_name: str = "z3") -> tp.Union[None, "CounterExample"]: # create free variable for each ir_val ir_path_types = _create_path_to_adt( strip_modifiers(self.ir_fc(family.SMTFamily()).input_t)) ir_vars = { path: _free_var_from_t(ir_path_types[path]) for path in self.ir_bounded } ir_inputs = self.build_ir_input(ir_vars, family.SMTFamily()) arch_inputs = self.build_arch_input(ir_vars, family.SMTFamily()) ir = self.ir_fc(family.SMTFamily())() arch = self.arch_fc(family.SMTFamily())() ir_out_values = self.parse_ir_output(ir(**ir_inputs)) arch_out_values = self.parse_arch_output(arch(**arch_inputs)) outputs = [] for ir_path, arch_path in self.obinding: if ir_path not in ir_out_values: raise ValueError(f"{ir_path} is not valid") if arch_path not in arch_out_values: raise ValueError(f"{arch_path} is not valid") outputs.append( ir_out_values[ir_path] != arch_out_values[arch_path]) formula = or_reduce(outputs) with smt.Solver(solver_name, logic=BV) as solver: solver.add_assertion(formula.value) verified = not solver.solve() if verified: return None else: return { path: solved_to_bv(var, solver) for path, var in ir_vars.items() }
def adtify(t_): if hwtypes.is_adt_type(t_): return self.get_adt_t(strip_modifiers(t_)) elif isinstance(t_, tuple): return tuple(adtify(t__) for t__ in t_) else: return t_
def test_ta_strip(): class Ta(TaggedUnion, cache=True): a = int b = int c = str class B(Ta): pass class C(B): pass M0 = make_modifier("M0") C_stripped = strip_modifiers(M0(C)) assert C == C_stripped
def __init__(self, peak_generator): pe = peak_generator(PyFamily()) assert issubclass(pe, peak.Peak) self._model = pe() #Lassen's name for the ISA is 'inst', so this is hardcoded self.__instr_name = 'inst' self.__instr_type = strip_modifiers(pe.input_t.field_dict['inst']) self.__inputs = OrderedDict(pe.input_t.field_dict) del self.__inputs['inst'] self.__outputs = OrderedDict(pe.output_t.field_dict) circuit = peak_generator(MagmaFamily()) self.__asm = Assembler(self.__instr_type) instr_magma_type = type(circuit.interface.ports[self.__instr_name]) self.__circuit = peak.wrap_with_disassembler( circuit, self.__asm.disassemble, self.__asm.width, HashableDict(self.__asm.layout), instr_magma_type) data_gate(self.__circuit)
def test_strip(): M0 = make_modifier("M0") M1 = make_modifier("M1") M2 = make_modifier("M2") BV = BitVector class E(Enum): a = 1 b = 2 class A(Product, cache=True): b = M0(Sum[Bit, M1(BV[6]), M2(E)]) c = M1(E) d = M2(Tuple[M0(BV[3]), M1(M0(Bit))]) A_stripped = strip_modifiers(A) assert A_stripped.b is Sum[Bit, BV[6], E] assert A_stripped.c is E assert A_stripped.d is Tuple[BV[3], Bit]
def _input_aadt_t(fc, family): bv = fc(family) input_aadt_t = AssembledADT[strip_modifiers(bv.input_t), Assembler, family.BitVector] return input_aadt_t
def path_to_adt(self, input, family, strip=False): cls = self.peak_fc(family) adt = cls.input_t if input else cls.output_t if strip: adt = strip_modifiers(adt) return _create_path_to_adt(adt)