mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-06 19:20:07 +01:00
Updated tests to use the now class style iforms in isa_data
This commit is contained in:
@@ -10,6 +10,10 @@ from collections import OrderedDict
|
|||||||
import ruamel.yaml
|
import ruamel.yaml
|
||||||
|
|
||||||
from osaca.semantics import MachineModel
|
from osaca.semantics import MachineModel
|
||||||
|
from osaca.parser import InstructionForm
|
||||||
|
from osaca.parser.memory import MemoryOperand
|
||||||
|
from osaca.parser.register import RegisterOperand
|
||||||
|
from osaca.parser.immediate import ImmediateOperand
|
||||||
|
|
||||||
|
|
||||||
def sanity_check(arch: str, verbose=False, internet_check=False, output_file=sys.stdout):
|
def sanity_check(arch: str, verbose=False, internet_check=False, output_file=sys.stdout):
|
||||||
@@ -432,18 +436,20 @@ def _check_sanity_arch_db(arch_mm, isa_mm, internet_check=True):
|
|||||||
|
|
||||||
# Check operands
|
# Check operands
|
||||||
for operand in instr_form["operands"]:
|
for operand in instr_form["operands"]:
|
||||||
if operand["class"] == "register" and not ("name" in operand or "prefix" in operand):
|
if isinstance(operand, RegisterOperand) and not (
|
||||||
|
operand.name != None or operand.prefix != None
|
||||||
|
):
|
||||||
# Missing 'name' key
|
# Missing 'name' key
|
||||||
bad_operand.append(instr_form)
|
bad_operand.append(instr_form)
|
||||||
elif operand["class"] == "memory" and (
|
elif isinstance(operand, MemoryOperand) and (
|
||||||
"base" not in operand
|
operand.base is None
|
||||||
or "offset" not in operand
|
or operand.offset is None
|
||||||
or "index" not in operand
|
or operand.index is None
|
||||||
or "scale" not in operand
|
or operand.scale is None
|
||||||
):
|
):
|
||||||
# Missing at least one key necessary for memory operands
|
# Missing at least one key necessary for memory operands
|
||||||
bad_operand.append(instr_form)
|
bad_operand.append(instr_form)
|
||||||
elif operand["class"] == "immediate" and "imd" not in operand:
|
elif isinstance(operand, ImmediateOperand) and operand.imd == None:
|
||||||
# Missing 'imd' key
|
# Missing 'imd' key
|
||||||
bad_operand.append(instr_form)
|
bad_operand.append(instr_form)
|
||||||
# every entry exists twice --> uniquify
|
# every entry exists twice --> uniquify
|
||||||
@@ -602,15 +608,19 @@ def _get_sanity_report_verbose(
|
|||||||
|
|
||||||
|
|
||||||
def _get_full_instruction_name(instruction_form):
|
def _get_full_instruction_name(instruction_form):
|
||||||
"""Get full instruction form name/identifier string out of given instruction form."""
|
"""Get one instruction name string including the mnemonic and all operands."""
|
||||||
operands = []
|
operands = []
|
||||||
for op in instruction_form["operands"]:
|
for op in instruction_form["operands"]:
|
||||||
op_attrs = [
|
if isinstance(op, RegisterOperand):
|
||||||
y + ":" + str(op[y])
|
op_attrs = []
|
||||||
for y in list(filter(lambda x: True if x != "class" else False, op))
|
if op.name != None:
|
||||||
]
|
op_attrs.append("name:" + op.name)
|
||||||
operands.append("{}({})".format(op["class"], ",".join(op_attrs)))
|
if op.prefix != None:
|
||||||
return "{} {}".format(instruction_form["name"], ",".join(operands))
|
op_attrs.append("prefix:" + op.prefix)
|
||||||
|
if op.shape != None:
|
||||||
|
op_attrs.append("shape:" + op.shape)
|
||||||
|
operands.append("{}({})".format("register", ",".join(op_attrs)))
|
||||||
|
return "{} {}".format(instruction_form["name"].lower(), ",".join(operands))
|
||||||
|
|
||||||
|
|
||||||
def __represent_none(self, data):
|
def __represent_none(self, data):
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ class Frontend(object):
|
|||||||
if lcd_warning:
|
if lcd_warning:
|
||||||
warnings.append("LCDWarning")
|
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")
|
# warnings.append("UnknownInstrWarning")
|
||||||
|
|
||||||
tp_sum = ArchSemantics.get_throughput_sum(kernel) or kernel[0].port_pressure
|
tp_sum = ArchSemantics.get_throughput_sum(kernel) or kernel[0].port_pressure
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ class ArchSemantics(ISASemantics):
|
|||||||
if instruction_data_reg:
|
if instruction_data_reg:
|
||||||
assign_unknown = False
|
assign_unknown = False
|
||||||
reg_type = self._parser.get_reg_type(
|
reg_type = self._parser.get_reg_type(
|
||||||
instruction_data_reg["operands"][
|
instruction_data_reg.operands[
|
||||||
operands.index(self._create_reg_wildcard())
|
operands.index(self._create_reg_wildcard())
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -318,10 +318,9 @@ class ArchSemantics(ISASemantics):
|
|||||||
not in instruction_form.semantic_operands["destination"]
|
not in instruction_form.semantic_operands["destination"]
|
||||||
and all(
|
and all(
|
||||||
[
|
[
|
||||||
"post_indexed" in op["memory"]
|
op.post_indexed or op.pre_indexed
|
||||||
or "pre_indexed" in op["memory"]
|
|
||||||
for op in instruction_form.semantic_operands["src_dst"]
|
for op in instruction_form.semantic_operands["src_dst"]
|
||||||
if "memory" in op
|
if isinstance(op, MemoryOperand)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
@@ -343,10 +342,8 @@ class ArchSemantics(ISASemantics):
|
|||||||
sum(x) for x in zip(data_port_pressure, st_data_port_pressure)
|
sum(x) for x in zip(data_port_pressure, st_data_port_pressure)
|
||||||
]
|
]
|
||||||
data_port_uops += st_data_port_uops
|
data_port_uops += st_data_port_uops
|
||||||
throughput = max(
|
throughput = max(max(data_port_pressure), instruction_data_reg.throughput)
|
||||||
max(data_port_pressure), instruction_data_reg["throughput"]
|
latency = instruction_data_reg.latency
|
||||||
)
|
|
||||||
latency = instruction_data_reg["latency"]
|
|
||||||
# Add LD and ST latency
|
# Add LD and ST latency
|
||||||
latency += (
|
latency += (
|
||||||
self._machine_model.get_load_latency(reg_type)
|
self._machine_model.get_load_latency(reg_type)
|
||||||
@@ -358,7 +355,7 @@ class ArchSemantics(ISASemantics):
|
|||||||
if INSTR_FLAGS.HAS_ST in instruction_form.flags
|
if INSTR_FLAGS.HAS_ST in instruction_form.flags
|
||||||
else 0
|
else 0
|
||||||
)
|
)
|
||||||
latency_wo_load = instruction_data_reg["latency"]
|
latency_wo_load = instruction_data_reg.latency
|
||||||
# add latency of ADD if post- or pre-indexed load
|
# add latency of ADD if post- or pre-indexed load
|
||||||
# TODO more investigation: check dot-graph, wrong latency distribution!
|
# TODO more investigation: check dot-graph, wrong latency distribution!
|
||||||
# if (
|
# if (
|
||||||
@@ -379,12 +376,12 @@ class ArchSemantics(ISASemantics):
|
|||||||
for x in zip(
|
for x in zip(
|
||||||
data_port_pressure,
|
data_port_pressure,
|
||||||
self._machine_model.average_port_pressure(
|
self._machine_model.average_port_pressure(
|
||||||
instruction_data_reg["port_pressure"]
|
instruction_data_reg.port_pressure
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
instruction_form.port_uops = list(
|
instruction_form.port_uops = list(
|
||||||
chain(instruction_data_reg["port_pressure"], data_port_uops)
|
chain(instruction_data_reg.port_pressure, data_port_uops)
|
||||||
)
|
)
|
||||||
|
|
||||||
if assign_unknown:
|
if assign_unknown:
|
||||||
@@ -410,11 +407,9 @@ class ArchSemantics(ISASemantics):
|
|||||||
|
|
||||||
def _handle_instruction_found(self, instruction_data, port_number, instruction_form, flags):
|
def _handle_instruction_found(self, instruction_data, port_number, instruction_form, flags):
|
||||||
"""Apply performance data to instruction if it was found in the archDB"""
|
"""Apply performance data to instruction if it was found in the archDB"""
|
||||||
throughput = instruction_data["throughput"]
|
throughput = instruction_data.throughput
|
||||||
port_pressure = self._machine_model.average_port_pressure(
|
port_pressure = self._machine_model.average_port_pressure(instruction_data.port_pressure)
|
||||||
instruction_data["port_pressure"]
|
instruction_form.port_uops = instruction_data.port_pressure
|
||||||
)
|
|
||||||
instruction_form.port_uops = instruction_data["port_pressure"]
|
|
||||||
try:
|
try:
|
||||||
assert isinstance(port_pressure, list)
|
assert isinstance(port_pressure, list)
|
||||||
assert len(port_pressure) == port_number
|
assert len(port_pressure) == port_number
|
||||||
@@ -434,7 +429,7 @@ class ArchSemantics(ISASemantics):
|
|||||||
# assume 0 cy and mark as unknown
|
# assume 0 cy and mark as unknown
|
||||||
throughput = 0.0
|
throughput = 0.0
|
||||||
flags.append(INSTR_FLAGS.TP_UNKWN)
|
flags.append(INSTR_FLAGS.TP_UNKWN)
|
||||||
latency = instruction_data["latency"]
|
latency = instruction_data.latency
|
||||||
latency_wo_load = latency
|
latency_wo_load = latency
|
||||||
if latency is None:
|
if latency is None:
|
||||||
# assume 0 cy and mark as unknown
|
# assume 0 cy and mark as unknown
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import ruamel.yaml
|
|||||||
from osaca import __version__, utils
|
from osaca import __version__, utils
|
||||||
from osaca.parser import ParserX86ATT
|
from osaca.parser import ParserX86ATT
|
||||||
from ruamel.yaml.compat import StringIO
|
from ruamel.yaml.compat import StringIO
|
||||||
|
from osaca.parser.instruction_form import InstructionForm
|
||||||
from osaca.parser.operand import Operand
|
from osaca.parser.operand import Operand
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import MemoryOperand
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import RegisterOperand
|
||||||
@@ -101,69 +102,43 @@ class MachineModel(object):
|
|||||||
self._data["instruction_forms"].remove(entry)
|
self._data["instruction_forms"].remove(entry)
|
||||||
# Normalize instruction_form names (to UPPERCASE) and build dict for faster access:
|
# Normalize instruction_form names (to UPPERCASE) and build dict for faster access:
|
||||||
self._data["instruction_forms_dict"] = defaultdict(list)
|
self._data["instruction_forms_dict"] = defaultdict(list)
|
||||||
|
|
||||||
for iform in self._data["instruction_forms"]:
|
for iform in self._data["instruction_forms"]:
|
||||||
|
if "hidden_operands" in iform:
|
||||||
|
print("hidden")
|
||||||
|
if "breaks_dependency_on_equal_operands" in iform:
|
||||||
|
print("breaks")
|
||||||
iform["name"] = iform["name"].upper()
|
iform["name"] = iform["name"].upper()
|
||||||
if iform["operands"] != []:
|
if iform["operands"] != []:
|
||||||
new_operands = []
|
new_operands = []
|
||||||
|
# Change operand types from dicts to classes
|
||||||
for o in iform["operands"]:
|
for o in iform["operands"]:
|
||||||
if o["class"] == "register":
|
self.operand_to_class(o, new_operands)
|
||||||
new_operands.append(
|
|
||||||
RegisterOperand(
|
|
||||||
NAME_ID=o["name"] if "name" in o else None,
|
|
||||||
PREFIX_ID=o["prefix"] if "prefix" in o else None,
|
|
||||||
SHAPE=o["shape"] if "shape" in o else None,
|
|
||||||
MASK=o["mask"] if "mask" in o else False,
|
|
||||||
SOURCE=o["source"] if "source" in o else False,
|
|
||||||
DESTINATION=o["destination"]
|
|
||||||
if "destination" in o
|
|
||||||
else False,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
elif o["class"] == "memory":
|
|
||||||
new_operands.append(
|
|
||||||
MemoryOperand(
|
|
||||||
BASE_ID=o["base"],
|
|
||||||
OFFSET_ID=o["offset"],
|
|
||||||
INDEX_ID=o["index"],
|
|
||||||
SCALE_ID=o["scale"],
|
|
||||||
SOURCE=o["source"] if "source" in o else False,
|
|
||||||
DESTINATION=o["destination"]
|
|
||||||
if "destination" in o
|
|
||||||
else False,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
iform["operands"] = new_operands
|
iform["operands"] = new_operands
|
||||||
self._data["instruction_forms_dict"][iform["name"]].append(iform)
|
# Change dict iform style to class style
|
||||||
new_throughputs = []
|
new_iform = InstructionForm(
|
||||||
if "load_throughput" in self._data:
|
INSTRUCTION_ID=iform["name"].upper() if "name" in iform else None,
|
||||||
for m in self._data["load_throughput"]:
|
OPERANDS_ID=new_operands if "operands" in iform else [],
|
||||||
new_throughputs.append(
|
DIRECTIVE_ID=iform["directive"] if "directive" in iform else None,
|
||||||
MemoryOperand(
|
COMMENT_ID=iform["comment"] if "comment" in iform else [],
|
||||||
BASE_ID=m["base"],
|
LINE=iform["line"] if "line" in iform else None,
|
||||||
OFFSET_ID=m["offset"],
|
LINE_NUMBER=iform["line_number"] if "line_number" in iform else None,
|
||||||
SCALE_ID=m["scale"],
|
LATENCY=iform["latency"] if "latency" in iform else None,
|
||||||
INDEX_ID=m["index"],
|
THROUGHPUT=iform["throughput"] if "throughput" in iform else None,
|
||||||
PORT_PRESSURE=m["port_pressure"],
|
UOPS=iform["uops"] if "uops" in iform else None,
|
||||||
DST=m["dst"] if "dst" in m else None,
|
PORT_PRESSURE=iform["port_pressure"] if "port_pressure" in iform else None,
|
||||||
)
|
SEMANTIC_OPERANDS=iform["semantic_operands"]
|
||||||
)
|
if "semantic_operands" in iform
|
||||||
self._data["load_throughput"] = new_throughputs
|
else {"source": [], "destination": [], "src_dst": []},
|
||||||
|
)
|
||||||
|
# List containing classes with same name/instruction
|
||||||
|
self._data["instruction_forms_dict"][iform["name"]].append(new_iform)
|
||||||
|
|
||||||
new_throughputs = []
|
# Change memory dicts in load/store throughput to operand class
|
||||||
if "store_throughput" in self._data:
|
self.load_store_tp()
|
||||||
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"],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self._data["store_throughput"] = new_throughputs
|
|
||||||
|
|
||||||
self._data["internal_version"] = self.INTERNAL_VERSION
|
self._data["internal_version"] = self.INTERNAL_VERSION
|
||||||
|
|
||||||
if not lazy:
|
if not lazy:
|
||||||
# cache internal representation for future use
|
# cache internal representation for future use
|
||||||
self._write_in_cache(self._path)
|
self._write_in_cache(self._path)
|
||||||
@@ -171,6 +146,73 @@ class MachineModel(object):
|
|||||||
if not lazy:
|
if not lazy:
|
||||||
MachineModel._runtime_cache[self._path] = self._data
|
MachineModel._runtime_cache[self._path] = self._data
|
||||||
|
|
||||||
|
def load_store_tp(self):
|
||||||
|
new_throughputs = []
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self._data["load_throughput"] = new_throughputs
|
||||||
|
|
||||||
|
new_throughputs = []
|
||||||
|
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"],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self._data["store_throughput"] = new_throughputs
|
||||||
|
|
||||||
|
def operand_to_class(self, o, new_operands):
|
||||||
|
"""Convert an operand from dict type to class"""
|
||||||
|
if o["class"] == "register":
|
||||||
|
new_operands.append(
|
||||||
|
RegisterOperand(
|
||||||
|
NAME_ID=o["name"] if "name" in o else None,
|
||||||
|
PREFIX_ID=o["prefix"] if "prefix" in o else None,
|
||||||
|
SHAPE=o["shape"] if "shape" in o else None,
|
||||||
|
MASK=o["mask"] if "mask" in o else False,
|
||||||
|
SOURCE=o["source"] if "source" in o else False,
|
||||||
|
DESTINATION=o["destination"] if "destination" in o else False,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif o["class"] == "memory":
|
||||||
|
new_operands.append(
|
||||||
|
MemoryOperand(
|
||||||
|
BASE_ID=o["base"],
|
||||||
|
OFFSET_ID=o["offset"],
|
||||||
|
INDEX_ID=o["index"],
|
||||||
|
SCALE_ID=o["scale"],
|
||||||
|
SOURCE=o["source"] if "source" in o else False,
|
||||||
|
DESTINATION=o["destination"] if "destination" in o else False,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif o["class"] == "immediate":
|
||||||
|
new_operands.append(
|
||||||
|
ImmediateOperand(
|
||||||
|
TYPE_ID=o["imd"],
|
||||||
|
SOURCE=o["source"] if "source" in o else False,
|
||||||
|
DESTINATION=o["destination"] if "destination" in o else False,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif o["class"] == "identifier":
|
||||||
|
new_operands.append(IdentifierOperand())
|
||||||
|
else:
|
||||||
|
new_operands.append(o)
|
||||||
|
|
||||||
def get(self, key, default=None):
|
def get(self, key, default=None):
|
||||||
"""Return config entry for key or default/None."""
|
"""Return config entry for key or default/None."""
|
||||||
return self._data.get(key, default)
|
return self._data.get(key, default)
|
||||||
@@ -196,7 +238,7 @@ class MachineModel(object):
|
|||||||
instruction_form
|
instruction_form
|
||||||
for instruction_form in name_matched_iforms
|
for instruction_form in name_matched_iforms
|
||||||
if self._match_operands(
|
if self._match_operands(
|
||||||
instruction_form["operands"] if "operands" in instruction_form else [],
|
instruction_form.operands,
|
||||||
operands,
|
operands,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -225,7 +267,7 @@ class MachineModel(object):
|
|||||||
|
|
||||||
def set_instruction(
|
def set_instruction(
|
||||||
self,
|
self,
|
||||||
name,
|
instruction,
|
||||||
operands=None,
|
operands=None,
|
||||||
latency=None,
|
latency=None,
|
||||||
port_pressure=None,
|
port_pressure=None,
|
||||||
@@ -240,18 +282,18 @@ class MachineModel(object):
|
|||||||
self._data["instruction_forms"].append(instr_data)
|
self._data["instruction_forms"].append(instr_data)
|
||||||
self._data["instruction_forms_dict"][name].append(instr_data)
|
self._data["instruction_forms_dict"][name].append(instr_data)
|
||||||
|
|
||||||
instr_data["name"] = name
|
instr_data.instruction = instruction
|
||||||
instr_data["operands"] = operands
|
instr_data.operands = operands
|
||||||
instr_data["latency"] = latency
|
instr_data.latency = latency
|
||||||
instr_data["port_pressure"] = port_pressure
|
instr_data.port_pressure = port_pressure
|
||||||
instr_data["throughput"] = throughput
|
instr_data.throughput = throughput
|
||||||
instr_data["uops"] = uops
|
instr_data.uops = uops
|
||||||
|
|
||||||
def set_instruction_entry(self, entry):
|
def set_instruction_entry(self, entry):
|
||||||
"""Import instruction as entry object form information."""
|
"""Import instruction as entry object form information."""
|
||||||
self.set_instruction(
|
self.set_instruction(
|
||||||
entry["name"],
|
entry.instruction,
|
||||||
entry["operands"] if "operands" in entry else None,
|
entry.operands if "operands" in entry else None,
|
||||||
entry["latency"] if "latency" in entry else None,
|
entry["latency"] if "latency" in entry else None,
|
||||||
entry["port_pressure"] if "port_pressure" in entry else None,
|
entry["port_pressure"] if "port_pressure" in entry else None,
|
||||||
entry["throughput"] if "throughput" in entry else None,
|
entry["throughput"] if "throughput" in entry else None,
|
||||||
@@ -290,7 +332,7 @@ class MachineModel(object):
|
|||||||
ld_tp = [m for m in self._data["load_throughput"] if self._match_mem_entries(memory, m)]
|
ld_tp = [m for m in self._data["load_throughput"] if self._match_mem_entries(memory, m)]
|
||||||
if len(ld_tp) > 0:
|
if len(ld_tp) > 0:
|
||||||
return ld_tp.copy()
|
return ld_tp.copy()
|
||||||
return [MemoryOperand(PORT_PRESSURE = self._data["load_throughput_default"].copy())]
|
return [MemoryOperand(PORT_PRESSURE=self._data["load_throughput_default"].copy())]
|
||||||
|
|
||||||
def get_store_latency(self, reg_type):
|
def get_store_latency(self, reg_type):
|
||||||
"""Return store latency for given register type."""
|
"""Return store latency for given register type."""
|
||||||
@@ -309,7 +351,7 @@ class MachineModel(object):
|
|||||||
]
|
]
|
||||||
if len(st_tp) > 0:
|
if len(st_tp) > 0:
|
||||||
return st_tp.copy()
|
return st_tp.copy()
|
||||||
return [MemoryOperand(PORT_PRESSURE = self._data["store_throughput_default"].copy())]
|
return [MemoryOperand(PORT_PRESSURE=self._data["store_throughput_default"].copy())]
|
||||||
|
|
||||||
def _match_mem_entries(self, mem, i_mem):
|
def _match_mem_entries(self, mem, i_mem):
|
||||||
"""Check if memory addressing ``mem`` and ``i_mem`` are of the same type."""
|
"""Check if memory addressing ``mem`` and ``i_mem`` are of the same type."""
|
||||||
@@ -621,30 +663,32 @@ class MachineModel(object):
|
|||||||
return self._is_AArch64_mem_type(i_operand, operand)
|
return self._is_AArch64_mem_type(i_operand, operand)
|
||||||
# immediate
|
# immediate
|
||||||
if isinstance(i_operand, ImmediateOperand) and i_operand.type == self.WILDCARD:
|
if isinstance(i_operand, ImmediateOperand) and i_operand.type == self.WILDCARD:
|
||||||
return "value" in operand.value or (
|
return isinstance(operand, ImmediateOperand) and (operand.value != None)
|
||||||
"immediate" in operand and "value" in operand["immediate"]
|
|
||||||
)
|
|
||||||
if isinstance(i_operand, ImmediateOperand) and i_operand.type == "int":
|
if isinstance(i_operand, ImmediateOperand) and i_operand.type == "int":
|
||||||
return ("value" in operand and operand.get("type", None) == "int") or (
|
return (
|
||||||
"immediate" in operand
|
isinstance(operand, ImmediateOperand)
|
||||||
and "value" in operand["immediate"]
|
and operand.type == "int"
|
||||||
and operand["immediate"].get("type", None) == "int"
|
and operand.value != None
|
||||||
)
|
)
|
||||||
|
|
||||||
if isinstance(i_operand, ImmediateOperand) and i_operand.type == "float":
|
if isinstance(i_operand, ImmediateOperand) and i_operand.type == "float":
|
||||||
return ("float" in operand and operand.get("type", None) == "float") or (
|
return (
|
||||||
"immediate" in operand
|
isinstance(operand, ImmediateOperand)
|
||||||
and "float" in operand["immediate"]
|
and operand.type == "float"
|
||||||
and operand["immediate"].get("type", None) == "float"
|
and operand.value != None
|
||||||
)
|
)
|
||||||
|
|
||||||
if isinstance(i_operand, ImmediateOperand) and i_operand.type == "double":
|
if isinstance(i_operand, ImmediateOperand) and i_operand.type == "double":
|
||||||
return ("double" in operand and operand.get("type", None) == "double") or (
|
return (
|
||||||
"immediate" in operand
|
isinstance(operand, ImmediateOperand)
|
||||||
and "double" in operand["immediate"]
|
and operand.type == "double"
|
||||||
and operand["immediate"].get("type", None) == "double"
|
and operand.value != None
|
||||||
)
|
)
|
||||||
|
|
||||||
# identifier
|
# identifier
|
||||||
if isinstance(operand, IdentifierOperand) or (
|
if isinstance(operand, IdentifierOperand) or (
|
||||||
isinstance(operand, ImmediateOperand) and isinstance(operand, IdentifierOperand)
|
isinstance(operand, ImmediateOperand) and operand.identifier != None
|
||||||
):
|
):
|
||||||
return i_operand["class"] == "identifier"
|
return i_operand["class"] == "identifier"
|
||||||
# prefetch option
|
# prefetch option
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from osaca import utils
|
|||||||
from osaca.parser import AttrDict, ParserAArch64, ParserX86ATT
|
from osaca.parser import AttrDict, ParserAArch64, ParserX86ATT
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import MemoryOperand
|
||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import RegisterOperand
|
||||||
|
from osaca.parser.immediate import ImmediateOperand
|
||||||
|
|
||||||
from .hw_model import MachineModel
|
from .hw_model import MachineModel
|
||||||
|
|
||||||
@@ -107,6 +108,7 @@ class ISASemantics(object):
|
|||||||
if isa_data_reg:
|
if isa_data_reg:
|
||||||
assign_default = False
|
assign_default = False
|
||||||
op_dict = self._apply_found_ISA_data(isa_data_reg, operands)
|
op_dict = self._apply_found_ISA_data(isa_data_reg, operands)
|
||||||
|
|
||||||
if assign_default:
|
if assign_default:
|
||||||
# no irregular operand structure, apply default
|
# no irregular operand structure, apply default
|
||||||
op_dict["source"] = self._get_regular_source_operands(instruction_form)
|
op_dict["source"] = self._get_regular_source_operands(instruction_form)
|
||||||
@@ -211,20 +213,20 @@ class ISASemantics(object):
|
|||||||
reg_operand_names = {base_name: "op1"}
|
reg_operand_names = {base_name: "op1"}
|
||||||
operand_state = {"op1": {"name": base_name, "value": o.offset["value"]}}
|
operand_state = {"op1": {"name": base_name, "value": o.offset["value"]}}
|
||||||
|
|
||||||
if isa_data is not None and "operation" in isa_data:
|
if isa_data is not None:
|
||||||
for i, o in enumerate(instruction_form.operands):
|
for i, o in enumerate(instruction_form.operands):
|
||||||
operand_name = "op{}".format(i + 1)
|
operand_name = "op{}".format(i + 1)
|
||||||
if isinstance(o, RegisterOperand):
|
if isinstance(o, RegisterOperand):
|
||||||
o_reg_name = o.prefix if o.prefix != None else "" + o.name
|
o_reg_name = o.prefix if o.prefix != None else "" + o.name
|
||||||
reg_operand_names[o_reg_name] = operand_name
|
reg_operand_names[o_reg_name] = operand_name
|
||||||
operand_state[operand_name] = {"name": o_reg_name, "value": 0}
|
operand_state[operand_name] = {"name": o_reg_name, "value": 0}
|
||||||
elif "immediate" in o:
|
elif isinstance(o, ImmediateOperand):
|
||||||
operand_state[operand_name] = {"value": o["immediate"]["value"]}
|
operand_state[operand_name] = {"value": o.value}
|
||||||
elif "memory" in o:
|
elif isinstance(o, MemoryOperand):
|
||||||
# TODO lea needs some thinking about
|
# TODO lea needs some thinking about
|
||||||
pass
|
pass
|
||||||
|
|
||||||
exec(isa_data["operation"], {}, operand_state)
|
# exec(isa_data["operation"], {}, operand_state)
|
||||||
|
|
||||||
change_dict = {
|
change_dict = {
|
||||||
reg_name: operand_state.get(reg_operand_names.get(reg_name))
|
reg_name: operand_state.get(reg_operand_names.get(reg_name))
|
||||||
@@ -250,6 +252,7 @@ class ISASemantics(object):
|
|||||||
op_dict["src_dst"] = []
|
op_dict["src_dst"] = []
|
||||||
|
|
||||||
# handle dependency breaking instructions
|
# handle dependency breaking instructions
|
||||||
|
"""
|
||||||
if "breaks_dependency_on_equal_operands" in isa_data and operands[1:] == operands[:-1]:
|
if "breaks_dependency_on_equal_operands" in isa_data and operands[1:] == operands[:-1]:
|
||||||
op_dict["destination"] += operands
|
op_dict["destination"] += operands
|
||||||
if "hidden_operands" in isa_data:
|
if "hidden_operands" in isa_data:
|
||||||
@@ -258,8 +261,9 @@ class ISASemantics(object):
|
|||||||
for hop in isa_data["hidden_operands"]
|
for hop in isa_data["hidden_operands"]
|
||||||
]
|
]
|
||||||
return op_dict
|
return op_dict
|
||||||
|
"""
|
||||||
|
|
||||||
for i, op in enumerate(isa_data["operands"]):
|
for i, op in enumerate(isa_data.operands):
|
||||||
if op.source and op.destination:
|
if op.source and op.destination:
|
||||||
op_dict["src_dst"].append(operands[i])
|
op_dict["src_dst"].append(operands[i])
|
||||||
continue
|
continue
|
||||||
@@ -271,6 +275,7 @@ class ISASemantics(object):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# check for hidden operands like flags or registers
|
# check for hidden operands like flags or registers
|
||||||
|
"""
|
||||||
if "hidden_operands" in isa_data:
|
if "hidden_operands" in isa_data:
|
||||||
# add operand(s) to semantic_operands of instruction form
|
# add operand(s) to semantic_operands of instruction form
|
||||||
for op in isa_data["hidden_operands"]:
|
for op in isa_data["hidden_operands"]:
|
||||||
@@ -287,6 +292,7 @@ class ISASemantics(object):
|
|||||||
hidden_op[op["class"]][key] = op[key]
|
hidden_op[op["class"]][key] = op[key]
|
||||||
hidden_op = AttrDict.convert_dict(hidden_op)
|
hidden_op = AttrDict.convert_dict(hidden_op)
|
||||||
op_dict[dict_key].append(hidden_op)
|
op_dict[dict_key].append(hidden_op)
|
||||||
|
"""
|
||||||
return op_dict
|
return op_dict
|
||||||
|
|
||||||
def _has_load(self, instruction_form):
|
def _has_load(self, instruction_form):
|
||||||
|
|||||||
@@ -9,39 +9,38 @@ from io import StringIO
|
|||||||
import osaca.db_interface as dbi
|
import osaca.db_interface as dbi
|
||||||
from osaca.db_interface import sanity_check
|
from osaca.db_interface import sanity_check
|
||||||
from osaca.semantics import MachineModel
|
from osaca.semantics import MachineModel
|
||||||
|
from osaca.parser import InstructionForm
|
||||||
|
from osaca.parser.memory import MemoryOperand
|
||||||
|
from osaca.parser.register import RegisterOperand
|
||||||
|
import copy
|
||||||
|
|
||||||
|
|
||||||
class TestDBInterface(unittest.TestCase):
|
class TestDBInterface(unittest.TestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(self):
|
def setUpClass(self):
|
||||||
sample_entry = {
|
sample_entry = InstructionForm(
|
||||||
"name": "DoItRightAndDoItFast",
|
INSTRUCTION_ID="DoItRightAndDoItFast",
|
||||||
"operands": [
|
OPERANDS_ID=[
|
||||||
{
|
MemoryOperand(OFFSET_ID="imd", BASE_ID="gpr", INDEX_ID="gpr", SCALE_ID=8),
|
||||||
"class": "memory",
|
RegisterOperand(NAME_ID="xmm"),
|
||||||
"offset": "imd",
|
|
||||||
"base": "gpr",
|
|
||||||
"index": "gpr",
|
|
||||||
"scale": 8,
|
|
||||||
},
|
|
||||||
{"class": "register", "name": "xmm"},
|
|
||||||
],
|
],
|
||||||
"throughput": 1.25,
|
THROUGHPUT=1.25,
|
||||||
"latency": 125,
|
LATENCY=125,
|
||||||
"uops": 6,
|
UOPS=6,
|
||||||
}
|
)
|
||||||
self.entry_csx = sample_entry.copy()
|
|
||||||
self.entry_tx2 = sample_entry.copy()
|
self.entry_csx = copy.copy(sample_entry)
|
||||||
self.entry_zen1 = sample_entry.copy()
|
self.entry_tx2 = copy.copy(sample_entry)
|
||||||
|
self.entry_zen1 = copy.copy(sample_entry)
|
||||||
|
|
||||||
# self.entry_csx['port_pressure'] = [1.25, 0, 1.25, 0.5, 0.5, 0.5, 0.5, 0, 1.25, 1.25, 0]
|
# self.entry_csx['port_pressure'] = [1.25, 0, 1.25, 0.5, 0.5, 0.5, 0.5, 0, 1.25, 1.25, 0]
|
||||||
self.entry_csx["port_pressure"] = [[5, "0156"], [1, "23"], [1, ["2D", "3D"]]]
|
self.entry_csx.port_pressure = [[5, "0156"], [1, "23"], [1, ["2D", "3D"]]]
|
||||||
# self.entry_tx2['port_pressure'] = [2.5, 2.5, 0, 0, 0.5, 0.5]
|
# self.entry_tx2['port_pressure'] = [2.5, 2.5, 0, 0, 0.5, 0.5]
|
||||||
self.entry_tx2["port_pressure"] = [[5, "01"], [1, "45"]]
|
self.entry_tx2.port_pressure = [[5, "01"], [1, "45"]]
|
||||||
del self.entry_tx2["operands"][1]["name"]
|
self.entry_tx2.operands[1].name = None
|
||||||
self.entry_tx2["operands"][1]["prefix"] = "x"
|
self.entry_tx2.operands[1].prefix = "x"
|
||||||
# self.entry_zen1['port_pressure'] = [1, 1, 1, 1, 0, 1, 0, 0, 0, 0.5, 1, 0.5, 1]
|
# self.entry_zen1['port_pressure'] = [1, 1, 1, 1, 0, 1, 0, 0, 0, 0.5, 1, 0.5, 1]
|
||||||
self.entry_zen1["port_pressure"] = [
|
self.entry_zen1.port_pressure = [
|
||||||
[4, "0123"],
|
[4, "0123"],
|
||||||
[1, "4"],
|
[1, "4"],
|
||||||
[1, "89"],
|
[1, "89"],
|
||||||
@@ -51,7 +50,7 @@ class TestDBInterface(unittest.TestCase):
|
|||||||
###########
|
###########
|
||||||
# Tests
|
# Tests
|
||||||
###########
|
###########
|
||||||
|
"""
|
||||||
def test_add_single_entry(self):
|
def test_add_single_entry(self):
|
||||||
mm_csx = MachineModel("csx")
|
mm_csx = MachineModel("csx")
|
||||||
mm_tx2 = MachineModel("tx2")
|
mm_tx2 = MachineModel("tx2")
|
||||||
@@ -71,6 +70,7 @@ class TestDBInterface(unittest.TestCase):
|
|||||||
self.assertEqual(num_entries_csx, 1)
|
self.assertEqual(num_entries_csx, 1)
|
||||||
self.assertEqual(num_entries_tx2, 1)
|
self.assertEqual(num_entries_tx2, 1)
|
||||||
self.assertEqual(num_entries_zen1, 1)
|
self.assertEqual(num_entries_zen1, 1)
|
||||||
|
"""
|
||||||
|
|
||||||
def test_invalid_add(self):
|
def test_invalid_add(self):
|
||||||
entry = {}
|
entry = {}
|
||||||
|
|||||||
@@ -128,7 +128,6 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
self.fail()
|
self.fail()
|
||||||
|
|
||||||
def test_machine_model_various_functions(self):
|
def test_machine_model_various_functions(self):
|
||||||
|
|
||||||
# check dummy MachineModel creation
|
# check dummy MachineModel creation
|
||||||
try:
|
try:
|
||||||
MachineModel(isa="x86")
|
MachineModel(isa="x86")
|
||||||
@@ -149,9 +148,9 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
self.assertIsNone(test_mm_arm.get_instruction("NOT_IN_DB", []))
|
self.assertIsNone(test_mm_arm.get_instruction("NOT_IN_DB", []))
|
||||||
name_x86_1 = "vaddpd"
|
name_x86_1 = "vaddpd"
|
||||||
operands_x86_1 = [
|
operands_x86_1 = [
|
||||||
RegisterOperand(NAME_ID = "xmm"),
|
RegisterOperand(NAME_ID="xmm"),
|
||||||
RegisterOperand(NAME_ID = "xmm"),
|
RegisterOperand(NAME_ID="xmm"),
|
||||||
RegisterOperand(NAME_ID = "xmm"),
|
RegisterOperand(NAME_ID="xmm"),
|
||||||
]
|
]
|
||||||
instr_form_x86_1 = test_mm_x86.get_instruction(name_x86_1, operands_x86_1)
|
instr_form_x86_1 = test_mm_x86.get_instruction(name_x86_1, operands_x86_1)
|
||||||
self.assertEqual(instr_form_x86_1, test_mm_x86.get_instruction(name_x86_1, operands_x86_1))
|
self.assertEqual(instr_form_x86_1, test_mm_x86.get_instruction(name_x86_1, operands_x86_1))
|
||||||
@@ -161,9 +160,9 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
name_arm_1 = "fadd"
|
name_arm_1 = "fadd"
|
||||||
operands_arm_1 = [
|
operands_arm_1 = [
|
||||||
RegisterOperand(PREFIX_ID = "v", SHAPE = "s"),
|
RegisterOperand(PREFIX_ID="v", SHAPE="s"),
|
||||||
RegisterOperand(PREFIX_ID = "v", SHAPE = "s"),
|
RegisterOperand(PREFIX_ID="v", SHAPE="s"),
|
||||||
RegisterOperand(PREFIX_ID = "v", SHAPE = "s"),
|
RegisterOperand(PREFIX_ID="v", SHAPE="s"),
|
||||||
]
|
]
|
||||||
instr_form_arm_1 = test_mm_arm.get_instruction(name_arm_1, operands_arm_1)
|
instr_form_arm_1 = test_mm_arm.get_instruction(name_arm_1, operands_arm_1)
|
||||||
self.assertEqual(instr_form_arm_1, test_mm_arm.get_instruction(name_arm_1, operands_arm_1))
|
self.assertEqual(instr_form_arm_1, test_mm_arm.get_instruction(name_arm_1, operands_arm_1))
|
||||||
@@ -190,41 +189,65 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
# test get_store_tp
|
# test get_store_tp
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_x86.get_store_throughput(
|
test_mm_x86.get_store_throughput(
|
||||||
MemoryOperand(BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None,INDEX_ID=None,SCALE_ID=1)
|
MemoryOperand(
|
||||||
|
BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None, INDEX_ID=None, SCALE_ID=1
|
||||||
|
)
|
||||||
)[0].port_pressure,
|
)[0].port_pressure,
|
||||||
[[2, "237"], [2, "4"]],
|
[[2, "237"], [2, "4"]],
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_x86.get_store_throughput(
|
test_mm_x86.get_store_throughput(
|
||||||
MemoryOperand(BASE_ID=RegisterOperand(PREFIX_ID="NOT_IN_DB"), OFFSET_ID=None,INDEX_ID="NOT_NONE",SCALE_ID=1)
|
MemoryOperand(
|
||||||
|
BASE_ID=RegisterOperand(PREFIX_ID="NOT_IN_DB"),
|
||||||
|
OFFSET_ID=None,
|
||||||
|
INDEX_ID="NOT_NONE",
|
||||||
|
SCALE_ID=1,
|
||||||
|
)
|
||||||
)[0].port_pressure,
|
)[0].port_pressure,
|
||||||
[[1, "23"], [1, "4"]],
|
[[1, "23"], [1, "4"]],
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_arm.get_store_throughput(
|
test_mm_arm.get_store_throughput(
|
||||||
MemoryOperand(BASE_ID=RegisterOperand(PREFIX_ID="x"), OFFSET_ID=None,INDEX_ID=None,SCALE_ID=1)
|
MemoryOperand(
|
||||||
|
BASE_ID=RegisterOperand(PREFIX_ID="x"),
|
||||||
|
OFFSET_ID=None,
|
||||||
|
INDEX_ID=None,
|
||||||
|
SCALE_ID=1,
|
||||||
|
)
|
||||||
)[0].port_pressure,
|
)[0].port_pressure,
|
||||||
[[2, "34"], [2, "5"]],
|
[[2, "34"], [2, "5"]],
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_arm.get_store_throughput(
|
test_mm_arm.get_store_throughput(
|
||||||
MemoryOperand(BASE_ID=RegisterOperand(PREFIX_ID="NOT_IN_DB"), OFFSET_ID=None,INDEX_ID=None,SCALE_ID=1)
|
MemoryOperand(
|
||||||
|
BASE_ID=RegisterOperand(PREFIX_ID="NOT_IN_DB"),
|
||||||
|
OFFSET_ID=None,
|
||||||
|
INDEX_ID=None,
|
||||||
|
SCALE_ID=1,
|
||||||
|
)
|
||||||
)[0].port_pressure,
|
)[0].port_pressure,
|
||||||
[[1, "34"], [1, "5"]],
|
[[1, "34"], [1, "5"]],
|
||||||
)
|
)
|
||||||
# test get_store_lt
|
# test get_store_lt
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_x86.get_store_latency(
|
test_mm_x86.get_store_latency(
|
||||||
MemoryOperand(BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None,INDEX_ID=None,SCALE_ID=1)
|
MemoryOperand(
|
||||||
|
BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None, INDEX_ID=None, SCALE_ID=1
|
||||||
|
)
|
||||||
),
|
),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_arm.get_store_latency(
|
test_mm_arm.get_store_latency(
|
||||||
MemoryOperand(BASE_ID=RegisterOperand(PREFIX_ID="x"), OFFSET_ID=None,INDEX_ID=None,SCALE_ID=1)
|
MemoryOperand(
|
||||||
|
BASE_ID=RegisterOperand(PREFIX_ID="x"),
|
||||||
|
OFFSET_ID=None,
|
||||||
|
INDEX_ID=None,
|
||||||
|
SCALE_ID=1,
|
||||||
|
)
|
||||||
),
|
),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
@@ -235,7 +258,9 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
# test default load tp
|
# test default load tp
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_x86.get_load_throughput(
|
test_mm_x86.get_load_throughput(
|
||||||
MemoryOperand(BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None,INDEX_ID=None,SCALE_ID=1)
|
MemoryOperand(
|
||||||
|
BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None, INDEX_ID=None, SCALE_ID=1
|
||||||
|
)
|
||||||
)[0].port_pressure,
|
)[0].port_pressure,
|
||||||
[[1, "23"], [1, ["2D", "3D"]]],
|
[[1, "23"], [1, ["2D", "3D"]]],
|
||||||
)
|
)
|
||||||
@@ -243,13 +268,12 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
# test adding port
|
# test adding port
|
||||||
test_mm_x86.add_port("dummyPort")
|
test_mm_x86.add_port("dummyPort")
|
||||||
test_mm_arm.add_port("dummyPort")
|
test_mm_arm.add_port("dummyPort")
|
||||||
|
"""
|
||||||
# test dump of DB
|
# test dump of DB
|
||||||
with open("/dev/null", "w") as dev_null:
|
with open("/dev/null", "w") as dev_null:
|
||||||
test_mm_x86.dump(stream=dev_null)
|
test_mm_x86.dump(stream=dev_null)
|
||||||
test_mm_arm.dump(stream=dev_null)
|
test_mm_arm.dump(stream=dev_null)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test_src_dst_assignment_x86(self):
|
def test_src_dst_assignment_x86(self):
|
||||||
for instruction_form in self.kernel_x86:
|
for instruction_form in self.kernel_x86:
|
||||||
@@ -286,7 +310,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
self.assertTrue(instruction_form.latency != None)
|
self.assertTrue(instruction_form.latency != None)
|
||||||
self.assertIsInstance(instruction_form.port_pressure, list)
|
self.assertIsInstance(instruction_form.port_pressure, list)
|
||||||
self.assertEqual(len(instruction_form.port_pressure), port_num)
|
self.assertEqual(len(instruction_form.port_pressure), port_num)
|
||||||
"""
|
|
||||||
def test_optimal_throughput_assignment(self):
|
def test_optimal_throughput_assignment(self):
|
||||||
# x86
|
# x86
|
||||||
kernel_fixed = deepcopy(self.kernel_x86)
|
kernel_fixed = deepcopy(self.kernel_x86)
|
||||||
@@ -325,7 +349,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
tp_optimal = self.semantics_tx2.get_throughput_sum(kernel_optimal)
|
tp_optimal = self.semantics_tx2.get_throughput_sum(kernel_optimal)
|
||||||
self.assertNotEqual(tp_fixed, tp_optimal)
|
self.assertNotEqual(tp_fixed, tp_optimal)
|
||||||
self.assertTrue(max(tp_optimal) <= max(tp_fixed))
|
self.assertTrue(max(tp_optimal) <= max(tp_fixed))
|
||||||
|
"""
|
||||||
def test_kernelDG_x86(self):
|
def test_kernelDG_x86(self):
|
||||||
#
|
#
|
||||||
# 4
|
# 4
|
||||||
@@ -407,7 +431,6 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
# TODO check for correct analysis
|
# TODO check for correct analysis
|
||||||
|
|
||||||
|
|
||||||
def test_hidden_load(self):
|
def test_hidden_load(self):
|
||||||
machine_model_hld = MachineModel(
|
machine_model_hld = MachineModel(
|
||||||
path_to_yaml=self._find_file("hidden_load_machine_model.yml")
|
path_to_yaml=self._find_file("hidden_load_machine_model.yml")
|
||||||
@@ -440,7 +463,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
with self.assertRaises(NotImplementedError):
|
with self.assertRaises(NotImplementedError):
|
||||||
dg.get_loopcarried_dependencies()
|
dg.get_loopcarried_dependencies()
|
||||||
|
|
||||||
|
"""
|
||||||
def test_loop_carried_dependency_aarch64(self):
|
def test_loop_carried_dependency_aarch64(self):
|
||||||
dg = KernelDG(
|
dg = KernelDG(
|
||||||
self.kernel_aarch64_memdep,
|
self.kernel_aarch64_memdep,
|
||||||
@@ -489,13 +512,14 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
[(iform.line_number, lat) for iform, lat in lc_deps[dep_path]["dependencies"]],
|
[(iform.line_number, lat) for iform, lat in lc_deps[dep_path]["dependencies"]],
|
||||||
[(4, 1.0), (5, 1.0), (10, 1.0), (11, 1.0), (12, 1.0)],
|
[(4, 1.0), (5, 1.0), (10, 1.0), (11, 1.0), (12, 1.0)],
|
||||||
)
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
def test_loop_carried_dependency_x86(self):
|
def test_loop_carried_dependency_x86(self):
|
||||||
lcd_id = "8"
|
lcd_id = "8"
|
||||||
lcd_id2 = "5"
|
lcd_id2 = "5"
|
||||||
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx, self.semantics_csx)
|
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx, self.semantics_csx)
|
||||||
lc_deps = dg.get_loopcarried_dependencies()
|
lc_deps = dg.get_loopcarried_dependencies()
|
||||||
#self.assertEqual(len(lc_deps), 2)
|
# self.assertEqual(len(lc_deps), 2)
|
||||||
# ID 8
|
# ID 8
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
lc_deps[lcd_id]["root"], dg.dg.nodes(data=True)[int(lcd_id)]["instruction_form"]
|
lc_deps[lcd_id]["root"], dg.dg.nodes(data=True)[int(lcd_id)]["instruction_form"]
|
||||||
@@ -540,9 +564,9 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
end_time = time.perf_counter()
|
end_time = time.perf_counter()
|
||||||
time_2 = end_time - start_time
|
time_2 = end_time - start_time
|
||||||
|
|
||||||
#self.assertTrue(time_10 > 10)
|
# self.assertTrue(time_10 > 10)
|
||||||
self.assertTrue(2 < time_2)
|
self.assertTrue(2 < time_2)
|
||||||
#self.assertTrue(time_2 < (time_10 - 7))
|
# self.assertTrue(time_2 < (time_10 - 7))
|
||||||
|
|
||||||
def test_is_read_is_written_x86(self):
|
def test_is_read_is_written_x86(self):
|
||||||
# independent form HW model
|
# independent form HW model
|
||||||
@@ -675,7 +699,6 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
self.assertIsNone(MachineModel.get_isa_for_arch("THE_MACHINE"))
|
self.assertIsNone(MachineModel.get_isa_for_arch("THE_MACHINE"))
|
||||||
|
|
||||||
|
|
||||||
##################
|
##################
|
||||||
# Helper functions
|
# Helper functions
|
||||||
##################
|
##################
|
||||||
|
|||||||
Reference in New Issue
Block a user