From 1ba46da7c98a4dcdc78aa7a52ca24280b9541fc8 Mon Sep 17 00:00:00 2001 From: JanLJL Date: Fri, 6 Nov 2020 15:06:36 +0100 Subject: [PATCH] minor bugfix in HW model and added user warnings for more insight --- osaca/frontend.py | 28 +++++++++++++++++++++++++++- osaca/osaca.py | 11 ++++++++++- osaca/semantics/hw_model.py | 4 ++++ tests/test_cli.py | 19 +++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/osaca/frontend.py b/osaca/frontend.py index e0f517f..e12590c 100755 --- a/osaca/frontend.py +++ b/osaca/frontend.py @@ -144,7 +144,7 @@ class Frontend(object): ) return s - def full_analysis(self, kernel, kernel_dg: KernelDG, ignore_unknown=False, verbose=False): + def full_analysis(self, kernel, kernel_dg: KernelDG, ignore_unknown=False, arch_warning=False, length_warning=False, verbose=False): """ Build the full analysis report including header, the symbol map, the combined TP/CP/LCD view and the list based LCD view. @@ -156,11 +156,16 @@ class Frontend(object): :param ignore_unknown: flag for ignore warning if performance data is missing, defaults to `False` :type ignore_unknown: boolean, optional + :param print_arch_warning: flag for additional user warning to specify micro-arch + :type print_arch_warning: boolean, optional + :param print_length_warning: flag for additional user warning to specify kernel length with --lines + :type print_length_warning: boolean, optional :param verbose: flag for verbosity level, defaults to False :type verbose: boolean, optional """ return ( self._header_report() + + self._user_warnings(arch_warning, length_warning) + self._symbol_map() + self.combined_view( kernel, @@ -285,6 +290,27 @@ class Frontend(object): ).format(amount, '-' * len(str(amount))) return s + def _user_warnings(self, arch_warning, length_warning): + """Returns warning texts for giving the user more insight in what he is doing.""" + arch_text = ( + 'WARNING: No micro-architecture was specified and a default uarch was used.\n' + ' Specify the uarch with --arch. See --help for more information.\n' + ) + length_text = ( + 'WARNING: You are analyzing a large amount of instruction forms. Analyses ' + 'across loops/block boundaries often do not make much sense.\n' + ' Specify the kernel length with --length. See --help for more ' + 'information.\n' + ' If this is intentional, you can safely ignore this message.\n' + ) + + warnings = '' + warnings += arch_text if arch_warning else '' + warnings += length_text if length_warning else '' + warnings += '\n' + return warnings + + def _get_separator_list(self, separator, separator_2=' '): """Creates column view for seperators in the TP/combined view.""" separator_list = [] diff --git a/osaca/osaca.py b/osaca/osaca.py index d50f694..6646cd3 100755 --- a/osaca/osaca.py +++ b/osaca/osaca.py @@ -259,6 +259,7 @@ def inspect(args, output_file=sys.stdout): # 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 @@ -283,8 +284,11 @@ def inspect(args, output_file=sys.stdout): 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 is larger than threshold + print_length_warning = True if len(kernel) > 200 else False machine_model = MachineModel(arch=arch) semantics = ArchSemantics(machine_model) semantics.add_semantics(kernel) @@ -300,7 +304,12 @@ def inspect(args, output_file=sys.stdout): frontend = Frontend(args.file.name, arch=arch) print( frontend.full_analysis( - kernel, kernel_graph, ignore_unknown=ignore_unknown, verbose=verbose + kernel, + kernel_graph, + ignore_unknown=ignore_unknown, + arch_warning=print_arch_warning, + length_warning=print_length_warning, + verbose=verbose ), file=output_file, ) diff --git a/osaca/semantics/hw_model.py b/osaca/semantics/hw_model.py index c742be4..0ae0698 100755 --- a/osaca/semantics/hw_model.py +++ b/osaca/semantics/hw_model.py @@ -601,6 +601,10 @@ class MachineModel(object): def _is_x86_reg_type(self, i_reg, reg, consider_masking=False): """Check if register type match.""" i_reg_name = i_reg['name'] if i_reg and 'name' in i_reg else i_reg + if reg is None: + if i_reg is None: + return True + return False # check for wildcards if i_reg_name == self.WILDCARD or reg['name'] == self.WILDCARD: return True diff --git a/tests/test_cli.py b/tests/test_cli.py index a3ee2f1..8611d13 100755 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -165,6 +165,25 @@ class TestCLI(unittest.TestCase): kernel_aarch64 = 'kernel_aarch64.s' args = parser.parse_args([self._find_test_file(kernel_aarch64)]) osaca.run(args, output_file=output) + + def test_user_warnings(self): + parser = osaca.create_parser() + kernel = 'triad_x86_unmarked.s' + args = parser.parse_args( + ['--arch', 'csx', '--ignore-unknown', self._find_test_file(kernel)] + ) + output = StringIO() + osaca.run(args, output_file=output) + # WARNING for length + self.assertTrue(output.getvalue().count('WARNING') == 1) + args = parser.parse_args( + ['--lines', '100-299', '--ignore-unknown', self._find_test_file(kernel)] + ) + output = StringIO() + osaca.run(args, output_file=output) + # WARNING for arch + self.assertTrue(output.getvalue().count('WARNING') == 1) + def test_lines_arg(self): # Run tests with --lines option