def import_benchmark_output(arch, bench_type, filepath, output=sys.stdout): """ Import benchmark results from micro-benchmarks. :param arch: target architecture key :type arch: str :param bench_type: key for defining type of benchmark output :type bench_type: str :param filepath: filepath to the output file :type filepath: str :param output: output stream to dump, defaults to sys.stdout :type output: stream """ supported_bench_outputs = ["ibench", "asmbench"] assert os.path.exists(filepath) if bench_type not in supported_bench_outputs: raise ValueError("Benchmark type is not supported.") with open(filepath, "r") as f: input_data = f.readlines() db_entries = None mm = MachineModel(arch) if bench_type == "ibench": db_entries = _get_ibench_output(input_data, mm.get_ISA()) elif bench_type == "asmbench": db_entries = _get_asmbench_output(input_data, mm.get_ISA()) # write entries to DB for entry in db_entries: mm.set_instruction_entry(db_entries[entry]) if output is None: print(mm.dump()) else: mm.dump(stream=output)
class KerncraftAPI(object): def __init__(self, arch, code): self.machine_model = MachineModel(arch=arch) self.semantics = ArchSemantics(self.machine_model) isa = self.machine_model.get_ISA().lower() if isa == 'aarch64': self.parser = ParserAArch64() elif isa == 'x86': self.parser = ParserX86ATT() parsed_code = self.parser.parse_file(code) self.kernel = reduce_to_section(parsed_code, self.machine_model.get_ISA()) self.semantics.add_semantics(self.kernel) def create_output(self, verbose=False): kernel_graph = KernelDG(self.kernel, self.parser, self.machine_model) frontend = Frontend(arch=self.machine_model.get_arch()) return frontend.full_analysis(self.kernel, kernel_graph, verbose=verbose) def get_unmatched_instruction_ratio(self): unmatched_counter = 0 for instruction in self.kernel: if (INSTR_FLAGS.TP_UNKWN in instruction['flags'] and INSTR_FLAGS.LT_UNKWN in instruction['flags']): unmatched_counter += 1 return unmatched_counter / len(self.kernel) def get_port_occupation_cycles(self): throughput_values = self.semantics.get_throughput_sum(self.kernel) port_names = self.machine_model['ports'] return collections.OrderedDict(list(zip(port_names, throughput_values))) def get_total_throughput(self): return max(self.semantics.get_throughput_sum(self.kernel)) def get_latency(self): return (self.get_lcd(), self.get_cp()) def get_cp(self): kernel_graph = KernelDG(self.kernel, self.parser, self.machine_model) kernel_cp = kernel_graph.get_critical_path() return sum([x['latency_cp'] for x in kernel_cp]) def get_lcd(self): kernel_graph = KernelDG(self.kernel, self.parser, self.machine_model) lcd_dict = kernel_graph.get_loopcarried_dependencies() lcd = 0.0 for dep in lcd_dict: lcd_tmp = sum( [x['latency_lcd'] for x in lcd_dict[dep]['dependencies']]) lcd = lcd_tmp if lcd_tmp > lcd else lcd return lcd
def sanity_check(arch: str, verbose=False, internet_check=False, output_file=sys.stdout): """ Checks the database for missing TP/LT values, instructions might missing int the ISA DB and duplicate instructions. :param arch: micro-arch key to define DB to check :type arch: str :param verbose: verbose output flag, defaults to `False` :type verbose: bool, optional :param internet_check: indicates if OSACA should try to look up the src/dst distribution in the internet, defaults to False :type internet_check: boolean, optional :param output_file: output stream specifying where to write output, defaults to :class:`sys.stdout` :type output_file: stream, optional :return: True if everything checked out """ # load arch machine model arch_mm = MachineModel(arch=arch) data = arch_mm["instruction_forms"] # load isa machine model isa = arch_mm.get_ISA() isa_mm = MachineModel(arch="isa/{}".format(isa)) num_of_instr = len(data) # check arch DB entries ( missing_throughput, missing_latency, missing_port_pressure, suspicious_instructions, duplicate_instr_arch, bad_operand, ) = _check_sanity_arch_db(arch_mm, isa_mm, internet_check=internet_check) # check ISA DB entries duplicate_instr_isa, only_in_isa = _check_sanity_isa_db(arch_mm, isa_mm) report = _get_sanity_report( num_of_instr, missing_throughput, missing_latency, missing_port_pressure, suspicious_instructions, duplicate_instr_arch, duplicate_instr_isa, only_in_isa, bad_operand, verbose=verbose, colors=True if output_file == sys.stdout else False, ) print(report, file=output_file) return not any([missing_port_pressure, bad_operand])