Black formatting

This commit is contained in:
stefandesouza
2023-09-12 12:45:28 +02:00
parent a8e5a6ad46
commit 42f96753c1
10 changed files with 200 additions and 152 deletions

View File

@@ -16,7 +16,7 @@ class MemoryOperand(Operand):
POST_INDEXED=False,
INDEXED_VAL=None,
PORT_PRESSURE=[],
DST=None
DST=None,
):
super().__init__("memory")
self._OFFSET_ID = OFFSET_ID

View File

@@ -422,7 +422,12 @@ class ParserAArch64(BaseParser):
if "shift" in memory_address["index"]:
if memory_address["index"]["shift_op"].lower() in valid_shift_ops:
scale = 2 ** int(memory_address["index"]["shift"][0]["value"])
new_dict = MemoryOperand(OFFSET_ID=offset, BASE_ID=RegisterOperand(NAME_ID = base["name"], PREFIX_ID = base["prefix"]), INDEX_ID=index, SCALE_ID=scale)
new_dict = MemoryOperand(
OFFSET_ID=offset,
BASE_ID=RegisterOperand(NAME_ID=base["name"], PREFIX_ID=base["prefix"]),
INDEX_ID=index,
SCALE_ID=scale,
)
if "pre_indexed" in memory_address:
new_dict.pre_indexed = True
if "post_indexed" in memory_address:

View File

@@ -338,10 +338,16 @@ class ParserX86ATT(BaseParser):
elif offset is not None and "value" in offset:
offset["value"] = int(offset["value"], 0)
if base != None:
baseOp = RegisterOperand(NAME_ID=base['name'],PREFIX_ID=base['prefix'] if 'prefix' in base else None)
baseOp = RegisterOperand(
NAME_ID=base["name"], PREFIX_ID=base["prefix"] if "prefix" in base else None
)
if index != None:
indexOp = RegisterOperand(NAME_ID=index['name'],PREFIX_ID=index['prefix'] if 'prefix' in index else None)
new_dict = MemoryOperand(OFFSET_ID=offset, BASE_ID=baseOp, INDEX_ID=indexOp, SCALE_ID=scale)
indexOp = RegisterOperand(
NAME_ID=index["name"], PREFIX_ID=index["prefix"] if "prefix" in index else None
)
new_dict = MemoryOperand(
OFFSET_ID=offset, BASE_ID=baseOp, INDEX_ID=indexOp, SCALE_ID=scale
)
# Add segmentation extension if existing
if self.SEGMENT_EXT_ID in memory_address:
new_dict.segment_ext_id = memory_address[self.SEGMENT_EXT_ID]

View File

@@ -169,9 +169,7 @@ class ArchSemantics(ISASemantics):
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
]
load = [instr for instr in kernel if instr.line_number == min_distance_load[1]][0]
# Hide load
load.flags += [INSTR_FLAGS.HIDDEN_LD]
load.port_pressure = self._nullify_data_ports(load.port_pressure)
@@ -305,7 +303,8 @@ class ArchSemantics(ISASemantics):
+ instruction_form.semantic_operands["src_dst"]
)
store_perf_data = self._machine_model.get_store_throughput(
[x for x in destinations if isinstance(x,MemoryOperand)][0], dummy_reg
[x for x in destinations if isinstance(x, MemoryOperand)][0],
dummy_reg,
)
st_data_port_uops = store_perf_data[0].port_pressure

View File

@@ -20,6 +20,7 @@ from osaca.parser.register import RegisterOperand
from osaca.parser.immediate import ImmediateOperand
from osaca.parser.identifier import IdentifierOperand
class MachineModel(object):
WILDCARD = "*"
INTERNAL_VERSION = 1 # increase whenever self._data format changes to invalidate cache!
@@ -106,28 +107,51 @@ class MachineModel(object):
new_operands = []
for o in iform["operands"]:
if o["class"] == "register":
new_operands.append(RegisterOperand(NAME_ID=o["name"] if "name" in o else None,
new_operands.append(
RegisterOperand(
NAME_ID=o["name"] if "name" in o else None,
PREFIX_ID=o["prefix"] if "prefix" in o else None,
MASK=o["mask"] if "mask" in o else False)
MASK=o["mask"] if "mask" in o else False,
)
)
elif o["class"] == "memory":
new_operands.append(MemoryOperand(BASE_ID=o["base"],
new_operands.append(
MemoryOperand(
BASE_ID=o["base"],
OFFSET_ID=o["offset"],
INDEX_ID=o["index"],
SCALE_ID=o["scale"])
SCALE_ID=o["scale"],
)
)
iform["operands"] = new_operands
self._data["instruction_forms_dict"][iform["name"]].append(iform)
new_throughputs = []
if 'load_throughput' in self._data:
if "load_throughput" in self._data:
for m in self._data["load_throughput"]:
new_throughputs.append(MemoryOperand(BASE_ID=m['base'],OFFSET_ID=m['offset'],SCALE_ID=m['scale'],INDEX_ID=m['index'],PORT_PRESSURE=m['port_pressure'],DST=m['dst'] if 'dst' in m else None))
new_throughputs.append(
MemoryOperand(
BASE_ID=m["base"],
OFFSET_ID=m["offset"],
SCALE_ID=m["scale"],
INDEX_ID=m["index"],
PORT_PRESSURE=m["port_pressure"],
DST=m["dst"] if "dst" in m else None,
)
)
self._data["load_throughput"] = new_throughputs
new_throughputs = []
if 'store_throughput' in self._data:
if "store_throughput" in self._data:
for m in self._data["store_throughput"]:
new_throughputs.append(MemoryOperand(BASE_ID=m['base'],OFFSET_ID=m['offset'],SCALE_ID=m['scale'],INDEX_ID=m['index'],PORT_PRESSURE=m['port_pressure']))
new_throughputs.append(
MemoryOperand(
BASE_ID=m["base"],
OFFSET_ID=m["offset"],
SCALE_ID=m["scale"],
INDEX_ID=m["index"],
PORT_PRESSURE=m["port_pressure"],
)
)
self._data["store_throughput"] = new_throughputs
self._data["internal_version"] = self.INTERNAL_VERSION
@@ -493,12 +517,14 @@ class MachineModel(object):
elif operand.startswith("v"):
return RegisterOperand(PREFIX_ID="v", SHAPE=operand[1:2])
elif operand.startswith("m"):
return MemoryOperand(BASE_ID = "x" if "b" in operand else None,
return MemoryOperand(
BASE_ID="x" if "b" in operand else None,
OFFSET_ID="imd" if "o" in operand else None,
INDEX_ID="gpr" if "i" in operand else None,
SCALE_ID=8 if "s" in operand else 1,
PRE_INDEXED=True if "r" in operand else False,
POST_INDEXED = True if "p" in operand else False)
POST_INDEXED=True if "p" in operand else False,
)
else:
raise ValueError("Parameter {} is not a valid operand code".format(operand))
@@ -511,10 +537,12 @@ class MachineModel(object):
elif operand == "i":
return ImmediateOperand(TYPE_ID="int")
elif operand.startswith("m"):
return MemoryOperand(BASE_ID = "gpr" if "b" in operand else None,
return MemoryOperand(
BASE_ID="gpr" if "b" in operand else None,
OFFSET_ID="imd" if "o" in operand else None,
INDEX_ID="gpr" if "i" in operand else None,
SCALE_ID = 8 if "s" in operand else 1,)
SCALE_ID=8 if "s" in operand else 1,
)
else:
raise ValueError("Parameter {} is not a valid operand code".format(operand))
@@ -553,10 +581,10 @@ class MachineModel(object):
def _check_operands(self, i_operand, operand):
"""Check if the types of operand ``i_operand`` and ``operand`` match."""
# check for wildcard
if (isinstance(operand, Operand) and operand.name == self.WILDCARD) or (not isinstance(operand, Operand) and self.WILDCARD in operand):
if (
isinstance(i_operand, RegisterOperand)
if (isinstance(operand, Operand) and operand.name == self.WILDCARD) or (
not isinstance(operand, Operand) and self.WILDCARD in operand
):
if isinstance(i_operand, RegisterOperand):
return True
else:
return False
@@ -733,10 +761,7 @@ class MachineModel(object):
# one instruction is missing zeroing while the other has it
zero_ok = False
# check for wildcard
if (
i_reg.zeroing == self.WILDCARD
or reg.zeroing == self.WILDCARD
):
if i_reg.zeroing == self.WILDCARD or reg.zeroing == self.WILDCARD:
zero_ok = True
if not mask_ok or not zero_ok:
return False
@@ -766,11 +791,7 @@ class MachineModel(object):
and "identifier" in mem.offset
and i_mem.offset == "identifier"
)
or (
mem.offset is not None
and "value" in mem.offset
and i_mem.offset == "imd"
)
or (mem.offset is not None and "value" in mem.offset and i_mem.offset == "imd")
)
# check index
and (
@@ -790,8 +811,7 @@ class MachineModel(object):
)
# check pre-indexing
and (
i_mem.pre-indexed == self.WILDCARD
or (mempre-indexed) == (i_mem.pre-indexed)
i_mem.pre - indexed == self.WILDCARD or (mempre - indexed) == (i_mem.pre - indexed)
)
# check post-indexing
and (
@@ -828,11 +848,7 @@ class MachineModel(object):
or (i_mem.offset is None and mem.offset["value"] == "0")
)
)
or (
mem.offset is not None
and "identifier" in mem.offset
and i_mem.offset == "id"
)
or (mem.offset is not None and "identifier" in mem.offset and i_mem.offset == "id")
)
# check index
and (

View File

@@ -182,7 +182,7 @@ class ISASemantics(object):
isa_data = self._isa_model.get_instruction(
instruction_form.instruction[:suffix_start], instruction_form.operands
)
'''
"""
if only_postindexed:
for o in instruction_form.operands:
if isinstance(o, MemoryOperand) and o.base!=None:
@@ -194,7 +194,7 @@ class ISASemantics(object):
}
}
return {}
'''
"""
reg_operand_names = {} # e.g., {'rax': 'op1'}
operand_state = {} # e.g., {'op1': {'name': 'rax', 'value': 0}} 0 means unchanged

View File

@@ -13,6 +13,7 @@ from osaca.parser.memory import MemoryOperand
from osaca.parser.register import RegisterOperand
from osaca.parser.immediate import ImmediateOperand
class KernelDG(nx.DiGraph):
# threshold for checking dependency graph sequential or in parallel
INSTRUCTION_THRESHOLD = 50
@@ -421,12 +422,19 @@ class KernelDG(nx.DiGraph):
if mem.base and src.base:
base_change = register_changes.get(
src.base.prefix if src.base.prefix != None else "" + src.base.name,
{"name": src.base.prefix if src.base.prefix!=None else "" + src.base.name, "value": 0},
{
"name": src.base.prefix if src.base.prefix != None else "" + src.base.name,
"value": 0,
},
)
if base_change is None:
# Unknown change occurred
continue
if mem.base.prefix if mem.base.prefix!=None else "" + mem.base.name != base_change["name"]:
if (
mem.base.prefix
if mem.base.prefix != None
else "" + mem.base.name != base_change["name"]
):
# base registers do not match
continue
addr_change += base_change["value"]
@@ -444,7 +452,11 @@ class KernelDG(nx.DiGraph):
if mem.scale != src.scale:
# scale factors do not match
continue
if mem.index.prefix if mem.index.prefix!=None else "" + mem.index.name != index_change["name"]:
if (
mem.index.prefix
if mem.index.prefix != None
else "" + mem.index.name != index_change["name"]
):
# index registers do not match
continue
addr_change += index_change["value"] * src.scale

View File

@@ -113,7 +113,7 @@ class TestParserAArch64(unittest.TestCase):
self.assertEqual(parsed_1.comment, "12.27")
self.assertEqual(parsed_2.instruction, "b.lo")
self.assertEqual(parsed_2.operands[0]['identifier']['name'], "..B1.4")
self.assertEqual(parsed_2.operands[0]["identifier"]["name"], "..B1.4")
self.assertEqual(len(parsed_2.operands), 1)
self.assertIsNone(parsed_2.comment)
@@ -127,8 +127,8 @@ class TestParserAArch64(unittest.TestCase):
self.assertIsNone(parsed_4.operands[1].offset)
self.assertEqual(parsed_4.operands[1].base.name, "sp")
self.assertEqual(parsed_4.operands[1].base.prefix, "x")
self.assertEqual(parsed_4.operands[1].index['name'], "1")
self.assertEqual(parsed_4.operands[1].index['prefix'], "x")
self.assertEqual(parsed_4.operands[1].index["name"], "1")
self.assertEqual(parsed_4.operands[1].index["prefix"], "x")
self.assertEqual(parsed_4.operands[1].scale, 16)
self.assertEqual(parsed_4.operands[0].name, "28")
self.assertEqual(parsed_4.operands[0].prefix, "x")
@@ -137,8 +137,8 @@ class TestParserAArch64(unittest.TestCase):
self.assertEqual(parsed_5.instruction, "ldr")
self.assertEqual(parsed_5.operands[0].name, "0")
self.assertEqual(parsed_5.operands[0].prefix, "x")
self.assertEqual(parsed_5.operands[1].offset['identifier']['name'], "q2c")
self.assertEqual(parsed_5.operands[1].offset['identifier']['relocation'], ":got_lo12:")
self.assertEqual(parsed_5.operands[1].offset["identifier"]["name"], "q2c")
self.assertEqual(parsed_5.operands[1].offset["identifier"]["relocation"], ":got_lo12:")
self.assertEqual(parsed_5.operands[1].base.name, "0")
self.assertEqual(parsed_5.operands[1].base.prefix, "x")
self.assertIsNone(parsed_5.operands[1].index)
@@ -147,8 +147,8 @@ class TestParserAArch64(unittest.TestCase):
self.assertEqual(parsed_6.instruction, "adrp")
self.assertEqual(parsed_6.operands[0].name, "0")
self.assertEqual(parsed_6.operands[0].prefix, "x")
self.assertEqual(parsed_6.operands[1]['identifier']['relocation'], ":got:")
self.assertEqual(parsed_6.operands[1]['identifier']['name'], "visited")
self.assertEqual(parsed_6.operands[1]["identifier"]["relocation"], ":got:")
self.assertEqual(parsed_6.operands[1]["identifier"]["name"], "visited")
self.assertEqual(parsed_7.instruction, "fadd")
self.assertEqual(parsed_7.operands[0].name, "17")
@@ -168,8 +168,7 @@ class TestParserAArch64(unittest.TestCase):
self.assertEqual(parsed_9.instruction, "ccmp")
self.assertEqual(parsed_9.operands[0].name, "0")
self.assertEqual(parsed_9.operands[0].prefix, "x")
self.assertEqual(parsed_9.operands[3]['condition'], "CC")
self.assertEqual(parsed_9.operands[3]["condition"], "CC")
def test_parse_line(self):
line_comment = "// -- Begin main"
@@ -338,7 +337,6 @@ class TestParserAArch64(unittest.TestCase):
self.assertEqual(parsed_8, instruction_form_8)
self.assertEqual(parsed_9, instruction_form_9)
def test_parse_file(self):
parsed = self.parser.parse_file(self.triad_code)
self.assertEqual(parsed[0].line_number, 1)

View File

@@ -22,6 +22,7 @@ from osaca.semantics import (
from osaca.parser.register import RegisterOperand
from osaca.parser.memory import MemoryOperand
class TestSemanticTools(unittest.TestCase):
MODULE_DATA_DIR = os.path.join(
os.path.dirname(os.path.split(os.path.abspath(__file__))[0]), "osaca/data/"
@@ -124,7 +125,7 @@ class TestSemanticTools(unittest.TestCase):
ArchSemantics(tmp_mm)
except ValueError:
self.fail()
'''
"""
def test_machine_model_various_functions(self):
# check dummy MachineModel creation
try:
@@ -184,8 +185,9 @@ class TestSemanticTools(unittest.TestCase):
"fadd register(prefix:v,shape:s),register(prefix:v,shape:s),"
+ "register(prefix:v,shape:s)",
)
'''
'''
"""
"""
# test get_store_tp
self.assertEqual(
test_mm_x86.get_store_throughput(
@@ -246,7 +248,8 @@ class TestSemanticTools(unittest.TestCase):
with open("/dev/null", "w") as dev_null:
test_mm_x86.dump(stream=dev_null)
test_mm_arm.dump(stream=dev_null)
'''
"""
def test_src_dst_assignment_x86(self):
for instruction_form in self.kernel_x86:
with self.subTest(instruction_form=instruction_form):
@@ -282,7 +285,8 @@ class TestSemanticTools(unittest.TestCase):
self.assertTrue(instruction_form.latency != None)
self.assertIsInstance(instruction_form.port_pressure, list)
self.assertEqual(len(instruction_form.port_pressure), port_num)
'''
"""
def test_optimal_throughput_assignment(self):
# x86
kernel_fixed = deepcopy(self.kernel_x86)
@@ -392,7 +396,8 @@ class TestSemanticTools(unittest.TestCase):
dg.get_dependent_instruction_forms()
# test dot creation
dg.export_graph(filepath="/dev/null")
'''
"""
def test_kernelDG_SVE(self):
KernelDG(
self.kernel_aarch64_SVE,
@@ -432,7 +437,8 @@ class TestSemanticTools(unittest.TestCase):
dg.get_critical_path()
with self.assertRaises(NotImplementedError):
dg.get_loopcarried_dependencies()
'''
"""
def test_loop_carried_dependency_aarch64(self):
dg = KernelDG(
self.kernel_aarch64_memdep,
@@ -534,7 +540,8 @@ class TestSemanticTools(unittest.TestCase):
self.assertTrue(time_10 > 10)
self.assertTrue(2 < time_2)
self.assertTrue(time_2 < (time_10 - 7))
'''
"""
def test_is_read_is_written_x86(self):
# independent form HW model
dag = KernelDG(self.kernel_x86, self.parser_x86, None, None)
@@ -638,7 +645,12 @@ class TestSemanticTools(unittest.TestCase):
def test_MachineModel_getter(self):
sample_operands = [
MemoryOperand(OFFSET_ID=None,BASE_ID=RegisterOperand(NAME_ID = "r12"), INDEX_ID=RegisterOperand(NAME_ID="rcx"),SCALE_ID=8)
MemoryOperand(
OFFSET_ID=None,
BASE_ID=RegisterOperand(NAME_ID="r12"),
INDEX_ID=RegisterOperand(NAME_ID="rcx"),
SCALE_ID=8,
)
]
self.assertIsNone(self.machine_model_csx.get_instruction("GETRESULT", sample_operands))
self.assertIsNone(self.machine_model_tx2.get_instruction("GETRESULT", sample_operands))