def test_kernelDG_x86(self): # # 4 # \___>6__>7 # / # 3 # 5_______>9 # dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx) self.assertTrue(nx.algorithms.dag.is_directed_acyclic_graph(dg.dg)) self.assertEqual( len(list(dg.get_dependent_instruction_forms(line_number=3))), 1) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=3)), 6) self.assertEqual( len(list(dg.get_dependent_instruction_forms(line_number=4))), 1) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=4)), 6) self.assertEqual( len(list(dg.get_dependent_instruction_forms(line_number=5))), 1) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=5)), 9) self.assertEqual( len(list(dg.get_dependent_instruction_forms(line_number=6))), 1) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=6)), 7) self.assertEqual( len(list(dg.get_dependent_instruction_forms(line_number=7))), 0) self.assertEqual( len(list(dg.get_dependent_instruction_forms(line_number=8))), 0) with self.assertRaises(ValueError): dg.get_dependent_instruction_forms() # test dot creation dg.export_graph(filepath='/dev/null')
def test_memdependency_x86(self): dg = KernelDG(self.kernel_x86_memdep, self.parser_x86, self.machine_model_csx, self.semantics_csx) self.assertTrue(nx.algorithms.dag.is_directed_acyclic_graph(dg.dg)) self.assertEqual( set(dg.get_dependent_instruction_forms(line_number=3)), {6, 8}) self.assertEqual( set(dg.get_dependent_instruction_forms(line_number=5)), {10, 12}) with self.assertRaises(ValueError): dg.get_dependent_instruction_forms() # test dot creation dg.export_graph(filepath="/dev/null")
def test_kernelDG_AArch64(self): dg = KernelDG(self.kernel_AArch64, self.parser_AArch64, self.machine_model_tx2) self.assertTrue(nx.algorithms.dag.is_directed_acyclic_graph(dg.dg)) self.assertEqual( set(dg.get_dependent_instruction_forms(line_number=3)), {7, 8}) self.assertEqual( set(dg.get_dependent_instruction_forms(line_number=4)), {9, 10}) self.assertEqual( set(dg.get_dependent_instruction_forms(line_number=5)), {6, 7, 8}) self.assertEqual( set(dg.get_dependent_instruction_forms(line_number=6)), {9, 10}) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=7)), 13) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=8)), 14) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=9)), 16) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=10)), 17) self.assertEqual( set(dg.get_dependent_instruction_forms(line_number=11)), {13, 14}) self.assertEqual( set(dg.get_dependent_instruction_forms(line_number=12)), {16, 17}) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=13)), 15) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=14)), 15) self.assertEqual( len(list(dg.get_dependent_instruction_forms(line_number=15))), 0) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=16)), 18) self.assertEqual( next(dg.get_dependent_instruction_forms(line_number=17)), 18) self.assertEqual( len(list(dg.get_dependent_instruction_forms(line_number=18))), 0) self.assertEqual( len(list(dg.get_dependent_instruction_forms(line_number=19))), 0) self.assertEqual( len(list(dg.get_dependent_instruction_forms(line_number=20))), 0) with self.assertRaises(ValueError): dg.get_dependent_instruction_forms() # test dot creation dg.export_graph(filepath='/dev/null')
def inspect(args, output_file=sys.stdout): """ Does the actual throughput and critical path analysis of OSACA and prints it to the terminal. :param args: arguments given from :class:`~argparse.ArgumentParser` after parsing :param output_file: Define the stream for output, defaults to :class:`sys.stdout` :type output_file: stream, optional """ # Read file code = args.file.read() # Detect ISA if necessary arch = args.arch if args.arch is not None else DEFAULT_ARCHS[BaseParser.detect_ISA(code)] print_arch_warning = False if args.arch else True isa = MachineModel.get_isa_for_arch(arch) verbose = args.verbose ignore_unknown = args.ignore_unknown # Parse file parser = get_asm_parser(arch) try: parsed_code = parser.parse_file(code) except: # probably the wrong parser based on heuristic if args.arch is None: # change ISA and try again arch = DEFAULT_ARCHS['x86'] if BaseParser.detect_ISA(code) == 'aarch64' else DEFAULT_ARCHS['aarch64'] isa = MachineModel.get_isa_for_arch(arch) parser = get_asm_parser(arch) parsed_code = parser.parse_file(code) else: traceback.print_exc(file=sys.stderr) sys.exit(1) # Reduce to marked kernel or chosen section and add semantics if args.lines: line_range = get_line_range(args.lines) kernel = [line for line in parsed_code if line['line_number'] in line_range] print_length_warning = False else: kernel = reduce_to_section(parsed_code, isa) # Print warning if kernel has no markers and is larger than threshold (100) print_length_warning = True if len(kernel) == len(parsed_code) and len(kernel) > 100 else False machine_model = MachineModel(arch=arch) semantics = ArchSemantics(machine_model) semantics.add_semantics(kernel) # Do optimal schedule for kernel throughput if wished if not args.fixed: semantics.assign_optimal_throughput(kernel) # Create DiGrahps kernel_graph = KernelDG(kernel, parser, machine_model) if args.dotpath is not None: kernel_graph.export_graph(args.dotpath if args.dotpath != '.' else None) # Print analysis frontend = Frontend(args.file.name, arch=arch) print( frontend.full_analysis( kernel, kernel_graph, ignore_unknown=ignore_unknown, arch_warning=print_arch_warning, length_warning=print_length_warning, verbose=verbose ), file=output_file, )