diff --git a/README.rst b/README.rst index 51d4deb..1efc795 100644 --- a/README.rst +++ b/README.rst @@ -87,7 +87,7 @@ The usage of OSACA can be listed as: .. code:: bash - osaca [-h] [-V] [--arch ARCH] [--fixed] [--lines lineS] + osaca [-h] [-V] [--arch ARCH] [--fixed] [--lines LINES] [--ignore-unknown] [--lcd-timeout SECONDS] [--db-check] [--import MICROBENCH] [--insert-marker] [--export-graph GRAPHNAME] [--consider-flag-deps] diff --git a/osaca/frontend.py b/osaca/frontend.py index 974ee9e..839d115 100644 --- a/osaca/frontend.py +++ b/osaca/frontend.py @@ -7,7 +7,7 @@ import os import re from datetime import datetime as dt -from osaca.semantics import INSTR_flags, ArchSemantics, KernelDG, MachineModel +from osaca.semantics import INSTR_FLAGS, ArchSemantics, KernelDG, MachineModel def _get_version(*file_paths): @@ -116,7 +116,7 @@ class Frontend(object): separator, instruction_form.latency_cp, separator, - "X" if INSTR_flags.LT_UNKWN in instruction_form.flags else " ", + "X" if INSTR_FLAGS.LT_UNKWN in instruction_form.flags else " ", separator, instruction_form.line, ) @@ -237,7 +237,7 @@ class Frontend(object): if lcd_warning: warnings.append("LCDWarning") - # if INSTR_flags.TP_UNKWN in [flag for instr in kernel for flag in instr.flags]: + # if INSTR_FLAGS.TP_UNKWN in [flag for instr in kernel for flag in instr.flags]: # warnings.append("UnknownInstrWarning") tp_sum = ArchSemantics.get_throughput_sum(kernel) or kernel[0].port_pressure @@ -373,11 +373,11 @@ class Frontend(object): ) s += "\n" # check for unknown instructions and throw warning if called without --ignore-unknown - if not ignore_unknown and INSTR_flags.TP_UNKWN in [ + if not ignore_unknown and INSTR_FLAGS.TP_UNKWN in [ flag for instr in kernel for flag in instr.flags ]: num_missing = len( - [instr.flags for instr in kernel if INSTR_flags.TP_UNKWN in instr.flags] + [instr.flags for instr in kernel if INSTR_FLAGS.TP_UNKWN in instr.flags] ) s += self._missing_instruction_error(num_missing) else: @@ -471,9 +471,9 @@ class Frontend(object): def _get_flag_symbols(self, flag_obj): """Returns flags for a flag object of an instruction""" string_result = "" - string_result += "*" if INSTR_flags.NOT_BOUND in flag_obj else "" - string_result += "X" if INSTR_flags.TP_UNKWN in flag_obj else "" - string_result += "P" if INSTR_flags.HIDDEN_LD in flag_obj else "" + string_result += "*" if INSTR_FLAGS.NOT_BOUND in flag_obj else "" + string_result += "X" if INSTR_FLAGS.TP_UNKWN in flag_obj else "" + string_result += "P" if INSTR_FLAGS.HIDDEN_LD in flag_obj else "" # TODO add other flags string_result += " " if len(string_result) == 0 else "" return string_result @@ -554,10 +554,10 @@ class Frontend(object): def _symbol_map(self): """Prints instruction flag map.""" symbol_dict = { - INSTR_flags.NOT_BOUND: "Instruction micro-ops not bound to a port", - INSTR_flags.TP_UNKWN: "No throughput/latency information for this instruction in " + INSTR_FLAGS.NOT_BOUND: "Instruction micro-ops not bound to a port", + INSTR_FLAGS.TP_UNKWN: "No throughput/latency information for this instruction in " + "data file", - INSTR_flags.HIDDEN_LD: "Throughput of LOAD operation can be hidden behind a past " + INSTR_FLAGS.HIDDEN_LD: "Throughput of LOAD operation can be hidden behind a past " + "or future STORE instruction", } symbol_map = "" diff --git a/osaca/osaca.py b/osaca/osaca.py index d69f8ae..308957f 100644 --- a/osaca/osaca.py +++ b/osaca/osaca.py @@ -13,7 +13,7 @@ from osaca.db_interface import import_benchmark_output, sanity_check from osaca.frontend import Frontend from osaca.parser import BaseParser, ParserAArch64, ParserX86ATT from osaca.semantics import ( - INSTR_flags, + INSTR_FLAGS, ArchSemantics, KernelDG, MachineModel, @@ -431,7 +431,7 @@ def get_unmatched_instruction_ratio(kernel): """Return ratio of unmatched from total instructions in kernel.""" unmatched_counter = 0 for instruction in kernel: - if INSTR_flags.TP_UNKWN in instruction.flags and INSTR_flags.LT_UNKWN in instruction.flags: + if INSTR_FLAGS.TP_UNKWN in instruction.flags and INSTR_FLAGS.LT_UNKWN in instruction.flags: unmatched_counter += 1 return unmatched_counter / len(kernel) diff --git a/osaca/semantics/__init__.py b/osaca/semantics/__init__.py index 5e1ceb9..8a0b000 100644 --- a/osaca/semantics/__init__.py +++ b/osaca/semantics/__init__.py @@ -3,7 +3,7 @@ Tools for semantic analysis of parser result. Only the classes below will be exported, so please add new semantic tools to __all__. """ -from .isa_semantics import ISASemantics, INSTR_flags +from .isa_semantics import ISASemantics, INSTR_FLAGS from .arch_semantics import ArchSemantics from .hw_model import MachineModel from .kernel_dg import KernelDG @@ -16,7 +16,7 @@ __all__ = [ "reduce_to_section", "ArchSemantics", "ISASemantics", - "INSTR_flags", + "INSTR_FLAGS", "find_basic_blocks", "find_basic_loop_bodies", "find_jump_labels", diff --git a/osaca/semantics/arch_semantics.py b/osaca/semantics/arch_semantics.py index 5e5ed12..966816b 100644 --- a/osaca/semantics/arch_semantics.py +++ b/osaca/semantics/arch_semantics.py @@ -8,7 +8,7 @@ from operator import itemgetter from copy import deepcopy from .hw_model import MachineModel -from .isa_semantics import INSTR_flags, ISASemantics +from .isa_semantics import INSTR_FLAGS, ISASemantics from osaca.parser.memory import MemoryOperand from osaca.parser.register import RegisterOperand @@ -137,8 +137,8 @@ class ArchSemantics(ISASemantics): def set_hidden_loads(self, kernel): """Hide loads behind stores if architecture supports hidden loads (depricated)""" - loads = [instr for instr in kernel if INSTR_flags.HAS_LD in instr.flags] - stores = [instr for instr in kernel if INSTR_flags.HAS_ST in instr.flags] + loads = [instr for instr in kernel if INSTR_FLAGS.HAS_LD in instr.flags] + stores = [instr for instr in kernel if INSTR_FLAGS.HAS_ST in instr.flags] # Filter instructions including load and store load_ids = [instr.line_number for instr in loads] store_ids = [instr.line_number for instr in stores] @@ -152,7 +152,7 @@ class ArchSemantics(ISASemantics): if len(loads) <= len(stores): # Hide all loads for load in loads: - load.flags += [INSTR_flags.HIDDEN_LD] + load.flags += [INSTR_FLAGS.HIDDEN_LD] load.port_pressure = self._nullify_data_ports(load.port_pressure) else: for store in stores: @@ -164,12 +164,12 @@ class ArchSemantics(ISASemantics): load_instr.line_number, ) for load_instr in loads - if INSTR_flags.HIDDEN_LD not in load_instr.flags + if INSTR_FLAGS.HIDDEN_LD not in load_instr.flags ] ) load = [instr for instr in kernel if instr.line_number == min_distance_load[1]][0] # Hide load - load.flags += [INSTR_flags.HIDDEN_LD] + load.flags += [INSTR_FLAGS.HIDDEN_LD] load.port_pressure = self._nullify_data_ports(load.port_pressure) # get parser result and assign throughput and latency value to instruction form @@ -223,8 +223,8 @@ class ArchSemantics(ISASemantics): assign_unknown = True # check for equivalent register-operands DB entry if LD if ( - INSTR_flags.HAS_LD in instruction_form.flags - or INSTR_flags.HAS_ST in instruction_form.flags + INSTR_FLAGS.HAS_LD in instruction_form.flags + or INSTR_FLAGS.HAS_ST in instruction_form.flags ): # dynamically combine LD/ST and reg form of instruction form # substitute mem and look for reg-only variant @@ -262,7 +262,7 @@ class ArchSemantics(ISASemantics): dummy_reg = RegisterOperand(name=reg_type) data_port_pressure = [0.0 for _ in range(port_number)] data_port_uops = [] - if INSTR_flags.HAS_LD in instruction_form.flags: + if INSTR_FLAGS.HAS_LD in instruction_form.flags: # LOAD performance data load_perf_data = self._machine_model.get_load_throughput( [ @@ -293,7 +293,7 @@ class ArchSemantics(ISASemantics): reg_type ] data_port_pressure = [pp * multiplier for pp in data_port_pressure] - if INSTR_flags.HAS_ST in instruction_form.flags: + if INSTR_FLAGS.HAS_ST in instruction_form.flags: # STORE performance data destinations = ( instruction_form.semantic_operands["destination"] @@ -324,7 +324,7 @@ class ArchSemantics(ISASemantics): ) ): st_data_port_uops = [] - instruction_form.flags.remove(INSTR_flags.HAS_ST) + instruction_form.flags.remove(INSTR_FLAGS.HAS_ST) # sum up all data ports in case for LOAD and STORE st_data_port_pressure = self._machine_model.average_port_pressure( @@ -346,12 +346,12 @@ class ArchSemantics(ISASemantics): # Add LD and ST latency latency += ( self._machine_model.get_load_latency(reg_type) - if INSTR_flags.HAS_LD in instruction_form.flags + if INSTR_FLAGS.HAS_LD in instruction_form.flags else 0 ) latency += ( self._machine_model.get_store_latency(reg_type) - if INSTR_flags.HAS_ST in instruction_form.flags + if INSTR_FLAGS.HAS_ST in instruction_form.flags else 0 ) latency_wo_load = instruction_data_reg.latency @@ -390,7 +390,7 @@ class ArchSemantics(ISASemantics): latency_wo_load = latency instruction_form.port_pressure = [0.0 for i in range(port_number)] # instruction_formport_uops = [] - flags += [INSTR_flags.TP_UNKWN, INSTR_flags.LT_UNKWN] + flags += [INSTR_FLAGS.TP_UNKWN, INSTR_FLAGS.LT_UNKWN] # flatten flag list flags = list(set(flags)) if instruction_form.flags == []: @@ -415,7 +415,7 @@ class ArchSemantics(ISASemantics): instruction_form.port_pressure = port_pressure if sum(port_pressure) == 0 and throughput is not None: # port pressure on all ports 0 --> not bound to a port - flags.append(INSTR_flags.NOT_BOUND) + flags.append(INSTR_FLAGS.NOT_BOUND) except AssertionError: warnings.warn( "Port pressure could not be imported correctly from database. " @@ -423,20 +423,20 @@ class ArchSemantics(ISASemantics): ) instruction_form.port_pressure = [0.0 for i in range(port_number)] instruction_form.port_uops = [] - flags.append(INSTR_flags.TP_UNKWN) + flags.append(INSTR_FLAGS.TP_UNKWN) if throughput is None: # assume 0 cy and mark as unknown throughput = 0.0 - flags.append(INSTR_flags.TP_UNKWN) + flags.append(INSTR_FLAGS.TP_UNKWN) latency = instruction_data.latency latency_wo_load = latency if latency is None: # assume 0 cy and mark as unknown latency = 0.0 latency_wo_load = latency - flags.append(INSTR_flags.LT_UNKWN) - if INSTR_flags.HAS_LD in instruction_form.flags: - flags.append(INSTR_flags.LD) + flags.append(INSTR_FLAGS.LT_UNKWN) + if INSTR_FLAGS.HAS_LD in instruction_form.flags: + flags.append(INSTR_FLAGS.LD) return throughput, port_pressure, latency, latency_wo_load def convert_op_to_reg(self, reg_type, reg_id="0"): diff --git a/osaca/semantics/isa_semantics.py b/osaca/semantics/isa_semantics.py index 183dc5c..a0eb1d2 100644 --- a/osaca/semantics/isa_semantics.py +++ b/osaca/semantics/isa_semantics.py @@ -11,7 +11,7 @@ from osaca.parser.immediate import ImmediateOperand from .hw_model import MachineModel -class INSTR_flags: +class INSTR_FLAGS: """ Flags used for unknown or special instructions """ @@ -150,9 +150,9 @@ class ISASemantics(object): # ) if self._has_load(instruction_form): - instruction_form.flags += [INSTR_flags.HAS_LD] + instruction_form.flags += [INSTR_FLAGS.HAS_LD] if self._has_store(instruction_form): - instruction_form.flags += [INSTR_flags.HAS_ST] + instruction_form.flags += [INSTR_FLAGS.HAS_ST] def get_reg_changes(self, instruction_form, only_postindexed=False): """ diff --git a/osaca/semantics/kernel_dg.py b/osaca/semantics/kernel_dg.py index 454bf5d..7737f56 100644 --- a/osaca/semantics/kernel_dg.py +++ b/osaca/semantics/kernel_dg.py @@ -8,7 +8,7 @@ from itertools import chain from multiprocessing import Manager, Process, cpu_count import networkx as nx -from osaca.semantics import INSTR_flags, ArchSemantics, MachineModel +from osaca.semantics import INSTR_FLAGS, ArchSemantics, MachineModel from osaca.parser.memory import MemoryOperand from osaca.parser.register import RegisterOperand from osaca.parser.immediate import ImmediateOperand @@ -67,8 +67,8 @@ class KernelDG(nx.DiGraph): dg.nodes[instruction_form.line_number]["instruction_form"] = instruction_form # add load as separate node if existent if ( - INSTR_flags.HAS_LD in instruction_form.flags - and INSTR_flags.LD not in instruction_form.flags + INSTR_FLAGS.HAS_LD in instruction_form.flags + and INSTR_FLAGS.LD not in instruction_form.flags ): # add new node dg.add_node(instruction_form.line_number + 0.1) diff --git a/tests/test_semantics.py b/tests/test_semantics.py index 92ff0b6..1b0a357 100755 --- a/tests/test_semantics.py +++ b/tests/test_semantics.py @@ -12,7 +12,7 @@ import networkx as nx from osaca.osaca import get_unmatched_instruction_ratio from osaca.parser import ParserAArch64, ParserX86ATT from osaca.semantics import ( - INSTR_flags, + INSTR_FLAGS, ArchSemantics, ISASemantics, KernelDG, @@ -116,9 +116,9 @@ class TestSemanticTools(unittest.TestCase): cls.semantics_a64fx.assign_src_dst(cls.kernel_aarch64_deps[i]) cls.semantics_a64fx.assign_tp_lt(cls.kernel_aarch64_deps[i]) - ########### - # Tests - ########### + ########### + # Tests + ########### def test_creation_by_name(self): try: @@ -446,9 +446,9 @@ class TestSemanticTools(unittest.TestCase): semantics_hld.add_semantics(kernel_hld_2) semantics_hld.add_semantics(kernel_hld_3) - num_hidden_loads = len([x for x in kernel_hld if INSTR_flags.HIDDEN_LD in x.flags]) - num_hidden_loads_2 = len([x for x in kernel_hld_2 if INSTR_flags.HIDDEN_LD in x.flags]) - num_hidden_loads_3 = len([x for x in kernel_hld_3 if INSTR_flags.HIDDEN_LD in x.flags]) + num_hidden_loads = len([x for x in kernel_hld if INSTR_FLAGS.HIDDEN_LD in x.flags]) + num_hidden_loads_2 = len([x for x in kernel_hld_2 if INSTR_FLAGS.HIDDEN_LD in x.flags]) + num_hidden_loads_3 = len([x for x in kernel_hld_3 if INSTR_FLAGS.HIDDEN_LD in x.flags]) self.assertEqual(num_hidden_loads, 1) self.assertEqual(num_hidden_loads_2, 0) self.assertEqual(num_hidden_loads_3, 1)