mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-04 10:10:08 +01:00
migrate code style to Black
This commit is contained in:
@@ -30,10 +30,10 @@ def sanity_check(arch: str, verbose=False, internet_check=False, output_file=sys
|
||||
"""
|
||||
# load arch machine model
|
||||
arch_mm = MachineModel(arch=arch)
|
||||
data = arch_mm['instruction_forms']
|
||||
data = arch_mm["instruction_forms"]
|
||||
# load isa machine model
|
||||
isa = arch_mm.get_ISA()
|
||||
isa_mm = MachineModel(arch='isa/{}'.format(isa))
|
||||
isa_mm = MachineModel(arch="isa/{}".format(isa))
|
||||
num_of_instr = len(data)
|
||||
|
||||
# check arch DB entries
|
||||
@@ -79,17 +79,17 @@ def import_benchmark_output(arch, bench_type, filepath, output=sys.stdout):
|
||||
:param output: output stream to dump, defaults to sys.stdout
|
||||
:type output: stream
|
||||
"""
|
||||
supported_bench_outputs = ['ibench', 'asmbench']
|
||||
supported_bench_outputs = ["ibench", "asmbench"]
|
||||
assert os.path.exists(filepath)
|
||||
if bench_type not in supported_bench_outputs:
|
||||
raise ValueError('Benchmark type is not supported.')
|
||||
with open(filepath, 'r') as f:
|
||||
raise ValueError("Benchmark type is not supported.")
|
||||
with open(filepath, "r") as f:
|
||||
input_data = f.readlines()
|
||||
db_entries = None
|
||||
mm = MachineModel(arch)
|
||||
if bench_type == 'ibench':
|
||||
if bench_type == "ibench":
|
||||
db_entries = _get_ibench_output(input_data, mm.get_ISA())
|
||||
elif bench_type == 'asmbench':
|
||||
elif bench_type == "asmbench":
|
||||
db_entries = _get_asmbench_output(input_data, mm.get_ISA())
|
||||
# write entries to DB
|
||||
for entry in db_entries:
|
||||
@@ -122,34 +122,34 @@ def _get_asmbench_output(input_data, isa):
|
||||
"""
|
||||
db_entries = {}
|
||||
for i in range(0, len(input_data), 4):
|
||||
if input_data[i + 3].strip() != '':
|
||||
print('asmbench output not in the correct format! Format must be: ', file=sys.stderr)
|
||||
if input_data[i + 3].strip() != "":
|
||||
print("asmbench output not in the correct format! Format must be: ", file=sys.stderr)
|
||||
print(
|
||||
'-------------\nMNEMONIC[-OP1[_OP2][...]]\nLatency: X cycles\n'
|
||||
'Throughput: Y cycles\n\n-------------',
|
||||
"-------------\nMNEMONIC[-OP1[_OP2][...]]\nLatency: X cycles\n"
|
||||
"Throughput: Y cycles\n\n-------------",
|
||||
file=sys.stderr,
|
||||
)
|
||||
print(
|
||||
'Entry {} and all further entries won\'t be added.'.format((i / 4) + 1),
|
||||
"Entry {} and all further entries won't be added.".format((i / 4) + 1),
|
||||
file=sys.stderr,
|
||||
)
|
||||
break
|
||||
else:
|
||||
i_form = input_data[i].strip()
|
||||
mnemonic = i_form.split('-')[0]
|
||||
operands = i_form.split('-')[1].split('_')
|
||||
mnemonic = i_form.split("-")[0]
|
||||
operands = i_form.split("-")[1].split("_")
|
||||
operands = [_create_db_operand(op, isa) for op in operands]
|
||||
entry = {
|
||||
'name': mnemonic,
|
||||
'operands': operands,
|
||||
'throughput': _validate_measurement(float(input_data[i + 2].split()[1]), 'tp'),
|
||||
'latency': _validate_measurement(float(input_data[i + 1].split()[1]), 'lt'),
|
||||
'port_pressure': None,
|
||||
"name": mnemonic,
|
||||
"operands": operands,
|
||||
"throughput": _validate_measurement(float(input_data[i + 2].split()[1]), "tp"),
|
||||
"latency": _validate_measurement(float(input_data[i + 1].split()[1]), "lt"),
|
||||
"port_pressure": None,
|
||||
}
|
||||
if not entry['throughput'] or not entry['latency']:
|
||||
if not entry["throughput"] or not entry["latency"]:
|
||||
warnings.warn(
|
||||
'Your measurement for {} looks suspicious'.format(i_form)
|
||||
+ ' and was not added. Please inspect your benchmark.'
|
||||
"Your measurement for {} looks suspicious".format(i_form)
|
||||
+ " and was not added. Please inspect your benchmark."
|
||||
)
|
||||
db_entries[i_form] = entry
|
||||
return db_entries
|
||||
@@ -159,37 +159,37 @@ def _get_ibench_output(input_data, isa):
|
||||
"""Parse the standard output of ibench and add instructions to DB."""
|
||||
db_entries = {}
|
||||
for line in input_data:
|
||||
if 'Using frequency' in line or len(line) == 0:
|
||||
if "Using frequency" in line or len(line) == 0:
|
||||
continue
|
||||
instruction = line.split(':')[0]
|
||||
key = '-'.join(instruction.split('-')[:2])
|
||||
instruction = line.split(":")[0]
|
||||
key = "-".join(instruction.split("-")[:2])
|
||||
if key in db_entries:
|
||||
# add only TP/LT value
|
||||
entry = db_entries[key]
|
||||
else:
|
||||
mnemonic = instruction.split('-')[0]
|
||||
operands = instruction.split('-')[1].split('_')
|
||||
mnemonic = instruction.split("-")[0]
|
||||
operands = instruction.split("-")[1].split("_")
|
||||
operands = [_create_db_operand(op, isa) for op in operands]
|
||||
entry = {
|
||||
'name': mnemonic,
|
||||
'operands': operands,
|
||||
'throughput': None,
|
||||
'latency': None,
|
||||
'port_pressure': None,
|
||||
"name": mnemonic,
|
||||
"operands": operands,
|
||||
"throughput": None,
|
||||
"latency": None,
|
||||
"port_pressure": None,
|
||||
}
|
||||
if 'TP' in instruction:
|
||||
entry['throughput'] = _validate_measurement(float(line.split()[1]), 'tp')
|
||||
if not entry['throughput']:
|
||||
if "TP" in instruction:
|
||||
entry["throughput"] = _validate_measurement(float(line.split()[1]), "tp")
|
||||
if not entry["throughput"]:
|
||||
warnings.warn(
|
||||
'Your THROUGHPUT measurement for {} looks suspicious'.format(key)
|
||||
+ ' and was not added. Please inspect your benchmark.'
|
||||
"Your THROUGHPUT measurement for {} looks suspicious".format(key)
|
||||
+ " and was not added. Please inspect your benchmark."
|
||||
)
|
||||
elif 'LT' in instruction:
|
||||
entry['latency'] = _validate_measurement(float(line.split()[1]), 'lt')
|
||||
if not entry['latency']:
|
||||
elif "LT" in instruction:
|
||||
entry["latency"] = _validate_measurement(float(line.split()[1]), "lt")
|
||||
if not entry["latency"]:
|
||||
warnings.warn(
|
||||
'Your LATENCY measurement for {} looks suspicious'.format(key)
|
||||
+ ' and was not added. Please inspect your benchmark.'
|
||||
"Your LATENCY measurement for {} looks suspicious".format(key)
|
||||
+ " and was not added. Please inspect your benchmark."
|
||||
)
|
||||
db_entries[key] = entry
|
||||
return db_entries
|
||||
@@ -200,7 +200,7 @@ def _validate_measurement(measurement, mode):
|
||||
Check if latency has a maximum deviation of 0.05% and throughput is a reciprocal of a
|
||||
an integer number.
|
||||
"""
|
||||
if mode == 'lt':
|
||||
if mode == "lt":
|
||||
if (
|
||||
math.floor(measurement) * 1.05 >= measurement
|
||||
or math.ceil(measurement) * 0.95 <= measurement
|
||||
@@ -208,7 +208,7 @@ def _validate_measurement(measurement, mode):
|
||||
# Value is probably correct, so round it to the estimated value
|
||||
return float(round(measurement))
|
||||
# Check reciprocal only if it is a throughput value
|
||||
elif mode == 'tp':
|
||||
elif mode == "tp":
|
||||
reciprocals = [1 / x for x in range(1, 11)]
|
||||
for reci in reciprocals:
|
||||
if reci * 0.95 <= measurement <= reci * 1.05:
|
||||
@@ -221,56 +221,56 @@ def _validate_measurement(measurement, mode):
|
||||
|
||||
def _create_db_operand(operand, isa):
|
||||
"""Get DB operand by input string and ISA."""
|
||||
if isa == 'aarch64':
|
||||
if isa == "aarch64":
|
||||
return _create_db_operand_aarch64(operand)
|
||||
elif isa == 'x86':
|
||||
elif isa == "x86":
|
||||
return _create_db_operand_x86(operand)
|
||||
|
||||
|
||||
def _create_db_operand_aarch64(operand):
|
||||
"""Get DB operand for AArch64 by operand string."""
|
||||
if operand == 'i':
|
||||
return {'class': 'immediate', 'imd': 'int'}
|
||||
elif operand in 'wxbhsdq':
|
||||
return {'class': 'register', 'prefix': operand}
|
||||
elif operand.startswith('v'):
|
||||
if operand == "i":
|
||||
return {"class": "immediate", "imd": "int"}
|
||||
elif operand in "wxbhsdq":
|
||||
return {"class": "register", "prefix": operand}
|
||||
elif operand.startswith("v"):
|
||||
return {
|
||||
'class': 'register',
|
||||
'prefix': 'v',
|
||||
'shape': operand[1:2] if operand[1:2] != '' else 'd',
|
||||
"class": "register",
|
||||
"prefix": "v",
|
||||
"shape": operand[1:2] if operand[1:2] != "" else "d",
|
||||
}
|
||||
elif operand.startswith('m'):
|
||||
elif operand.startswith("m"):
|
||||
return {
|
||||
'class': 'memory',
|
||||
'base': 'x' if 'b' in operand else None,
|
||||
'offset': 'imd' if 'o' in operand else None,
|
||||
'index': 'gpr' if 'i' in operand else None,
|
||||
'scale': 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,
|
||||
"class": "memory",
|
||||
"base": "x" if "b" in operand else None,
|
||||
"offset": "imd" if "o" in operand else None,
|
||||
"index": "gpr" if "i" in operand else None,
|
||||
"scale": 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,
|
||||
}
|
||||
else:
|
||||
raise ValueError('Parameter {} is not a valid operand code'.format(operand))
|
||||
raise ValueError("Parameter {} is not a valid operand code".format(operand))
|
||||
|
||||
|
||||
def _create_db_operand_x86(operand):
|
||||
"""Get DB operand for AArch64 by operand string."""
|
||||
if operand == 'r':
|
||||
return {'class': 'register', 'name': 'gpr'}
|
||||
elif operand in 'xyz':
|
||||
return {'class': 'register', 'name': operand + 'mm'}
|
||||
elif operand == 'i':
|
||||
return {'class': 'immediate', 'imd': 'int'}
|
||||
elif operand.startswith('m'):
|
||||
if operand == "r":
|
||||
return {"class": "register", "name": "gpr"}
|
||||
elif operand in "xyz":
|
||||
return {"class": "register", "name": operand + "mm"}
|
||||
elif operand == "i":
|
||||
return {"class": "immediate", "imd": "int"}
|
||||
elif operand.startswith("m"):
|
||||
return {
|
||||
'class': 'memory',
|
||||
'base': 'gpr' if 'b' in operand else None,
|
||||
'offset': 'imd' if 'o' in operand else None,
|
||||
'index': 'gpr' if 'i' in operand else None,
|
||||
'scale': 8 if 's' in operand else 1,
|
||||
"class": "memory",
|
||||
"base": "gpr" if "b" in operand else None,
|
||||
"offset": "imd" if "o" in operand else None,
|
||||
"index": "gpr" if "i" in operand else None,
|
||||
"scale": 8 if "s" in operand else 1,
|
||||
}
|
||||
else:
|
||||
raise ValueError('Parameter {} is not a valid operand code'.format(operand))
|
||||
raise ValueError("Parameter {} is not a valid operand code".format(operand))
|
||||
|
||||
|
||||
########################
|
||||
@@ -286,14 +286,14 @@ def _scrape_from_felixcloutier(mnemonic):
|
||||
from bs4 import BeautifulSoup
|
||||
except ImportError:
|
||||
print(
|
||||
'Module BeautifulSoup not installed. Fetching instruction form information '
|
||||
'online requires BeautifulSoup.\nUse \'pip install bs4\' for installation.',
|
||||
"Module BeautifulSoup not installed. Fetching instruction form information "
|
||||
"online requires BeautifulSoup.\nUse 'pip install bs4' for installation.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
index = 'https://www.felixcloutier.com/x86/index.html'
|
||||
base_url = 'https://www.felixcloutier.com/x86/'
|
||||
index = "https://www.felixcloutier.com/x86/index.html"
|
||||
base_url = "https://www.felixcloutier.com/x86/"
|
||||
url = base_url + mnemonic.lower()
|
||||
|
||||
suspicious = True
|
||||
@@ -303,8 +303,8 @@ def _scrape_from_felixcloutier(mnemonic):
|
||||
r = requests.get(url=url)
|
||||
if r.status_code == 200:
|
||||
# Found result
|
||||
operand_enc = BeautifulSoup(r.text, 'html.parser').find(
|
||||
'h2', attrs={'id': 'instruction-operand-encoding'}
|
||||
operand_enc = BeautifulSoup(r.text, "html.parser").find(
|
||||
"h2", attrs={"id": "instruction-operand-encoding"}
|
||||
)
|
||||
if operand_enc:
|
||||
# operand encoding found, otherwise, no need to mark as suspicous
|
||||
@@ -312,37 +312,35 @@ def _scrape_from_felixcloutier(mnemonic):
|
||||
operands = _get_src_dst_from_table(table)
|
||||
elif r.status_code == 404:
|
||||
# Check for alternative href
|
||||
index = BeautifulSoup(requests.get(url=index).text, 'html.parser')
|
||||
alternatives = [ref for ref in index.findAll('a') if ref.text == mnemonic.upper()]
|
||||
index = BeautifulSoup(requests.get(url=index).text, "html.parser")
|
||||
alternatives = [ref for ref in index.findAll("a") if ref.text == mnemonic.upper()]
|
||||
if len(alternatives) > 0:
|
||||
# alternative(s) found, take first one
|
||||
url = base_url + alternatives[0].attrs['href'][2:]
|
||||
operand_enc = BeautifulSoup(requests.get(url=url).text, 'html.parser').find(
|
||||
'h2', attrs={'id': 'instruction-operand-encoding'}
|
||||
url = base_url + alternatives[0].attrs["href"][2:]
|
||||
operand_enc = BeautifulSoup(requests.get(url=url).text, "html.parser").find(
|
||||
"h2", attrs={"id": "instruction-operand-encoding"}
|
||||
)
|
||||
if operand_enc:
|
||||
# operand encoding found, otherwise, no need to mark as suspicous
|
||||
table = (
|
||||
operand_enc.findNextSibling()
|
||||
)
|
||||
table = operand_enc.findNextSibling()
|
||||
operands = _get_src_dst_from_table(table)
|
||||
if operands:
|
||||
# Found src/dst assignment for NUM_OPERANDS
|
||||
if not any(['r' in x and 'w' in x for x in operands]):
|
||||
if not any(["r" in x and "w" in x for x in operands]):
|
||||
suspicious = False
|
||||
return (suspicious, ' '.join(operands))
|
||||
return (suspicious, " ".join(operands))
|
||||
|
||||
|
||||
def _get_src_dst_from_table(table, num_operands=2):
|
||||
"""Prettify bs4 table object to string for user"""
|
||||
# Parse table
|
||||
header = [''.join(x.string.lower().split()) for x in table.find('tr').findAll('td')]
|
||||
data = table.findAll('tr')[1:]
|
||||
header = ["".join(x.string.lower().split()) for x in table.find("tr").findAll("td")]
|
||||
data = table.findAll("tr")[1:]
|
||||
data_dict = OrderedDict()
|
||||
for i, row in enumerate(data):
|
||||
data_dict[i] = {}
|
||||
for j, col in enumerate(row.findAll('td')):
|
||||
if col.string != 'NA':
|
||||
for j, col in enumerate(row.findAll("td")):
|
||||
if col.string != "NA":
|
||||
data_dict[i][header[j]] = col.string
|
||||
# Get only the instruction forms with 2 operands
|
||||
num_ops = [_get_number_of_operands(row) for _, row in data_dict.items()]
|
||||
@@ -350,12 +348,12 @@ def _get_src_dst_from_table(table, num_operands=2):
|
||||
row = data_dict[num_ops.index(num_operands)]
|
||||
reads_writes = []
|
||||
for i in range(1, num_operands + 1):
|
||||
m = re.search(r'(\([^\(\)]+\))', row['operand{}'.format(i)])
|
||||
m = re.search(r"(\([^\(\)]+\))", row["operand{}".format(i)])
|
||||
if not m:
|
||||
# no parentheses (probably immediate operand), assume READ
|
||||
reads_writes.append('(r)')
|
||||
reads_writes.append("(r)")
|
||||
continue
|
||||
reads_writes.append(''.join(m.group(0).split()))
|
||||
reads_writes.append("".join(m.group(0).split()))
|
||||
# reverse reads_writes for AT&T syntax
|
||||
reads_writes.reverse()
|
||||
return reads_writes
|
||||
@@ -366,7 +364,7 @@ def _get_number_of_operands(data_dict_row):
|
||||
"""Return the number of `Operand [X]` attributes in row"""
|
||||
num = 0
|
||||
for i in range(1, 5):
|
||||
if 'operand{}'.format(i) in [''.join(x.split()).lower() for x in data_dict_row]:
|
||||
if "operand{}".format(i) in ["".join(x.split()).lower() for x in data_dict_row]:
|
||||
num += 1
|
||||
return num
|
||||
|
||||
@@ -374,12 +372,12 @@ def _get_number_of_operands(data_dict_row):
|
||||
def _check_sanity_arch_db(arch_mm, isa_mm, internet_check=True):
|
||||
"""Do sanity check for ArchDB by given ISA."""
|
||||
# prefixes of instruction forms which we assume to have non-default operands
|
||||
suspicious_prefixes_x86 = ['vfm', 'fm']
|
||||
suspicious_prefixes_arm = ['fml', 'ldp', 'stp', 'str']
|
||||
suspicious_prefixes_x86 = ["vfm", "fm"]
|
||||
suspicious_prefixes_arm = ["fml", "ldp", "stp", "str"]
|
||||
# already known to be default-operand instruction forms with 2 operands
|
||||
if arch_mm.get_ISA().lower() == 'aarch64':
|
||||
if arch_mm.get_ISA().lower() == "aarch64":
|
||||
suspicious_prefixes = suspicious_prefixes_arm
|
||||
if arch_mm.get_ISA().lower() == 'x86':
|
||||
if arch_mm.get_ISA().lower() == "x86":
|
||||
suspicious_prefixes = suspicious_prefixes_x86
|
||||
|
||||
# returned lists
|
||||
@@ -391,57 +389,56 @@ def _check_sanity_arch_db(arch_mm, isa_mm, internet_check=True):
|
||||
duplicate_strings = []
|
||||
bad_operand = []
|
||||
|
||||
for instr_form in arch_mm['instruction_forms']:
|
||||
for instr_form in arch_mm["instruction_forms"]:
|
||||
# check value in DB entry
|
||||
if instr_form['throughput'] is None:
|
||||
if instr_form["throughput"] is None:
|
||||
missing_throughput.append(instr_form)
|
||||
if instr_form['latency'] is None:
|
||||
if instr_form["latency"] is None:
|
||||
missing_latency.append(instr_form)
|
||||
if instr_form['port_pressure'] is None:
|
||||
if instr_form["port_pressure"] is None:
|
||||
missing_port_pressure.append(instr_form)
|
||||
# check entry against ISA DB
|
||||
for prefix in suspicious_prefixes:
|
||||
if instr_form['name'].lower().startswith(prefix):
|
||||
if instr_form["name"].lower().startswith(prefix):
|
||||
# check if instruction in ISA DB
|
||||
if isa_mm.get_instruction(instr_form['name'], instr_form['operands']) is None:
|
||||
if isa_mm.get_instruction(instr_form["name"], instr_form["operands"]) is None:
|
||||
# if not, mark them as suspicious and print it on the screen
|
||||
suspicious_instructions.append(instr_form)
|
||||
# instr forms with less than 3 operands might need an ISA DB entry due to src_reg operands
|
||||
if (
|
||||
len(instr_form['operands']) < 3
|
||||
and len(instr_form['operands']) > 1
|
||||
and 'mov' not in instr_form['name'].lower()
|
||||
and not instr_form['name'].lower().startswith('j')
|
||||
len(instr_form["operands"]) < 3
|
||||
and len(instr_form["operands"]) > 1
|
||||
and "mov" not in instr_form["name"].lower()
|
||||
and not instr_form["name"].lower().startswith("j")
|
||||
and instr_form not in suspicious_instructions
|
||||
and isa_mm.get_instruction(instr_form['name'], instr_form['operands']) is None
|
||||
and isa_mm.get_instruction(instr_form["name"], instr_form["operands"]) is None
|
||||
):
|
||||
# validate with data from internet if connected flag is set
|
||||
if internet_check:
|
||||
is_susp, info_string = _scrape_from_felixcloutier(instr_form['name'])
|
||||
is_susp, info_string = _scrape_from_felixcloutier(instr_form["name"])
|
||||
if is_susp:
|
||||
instr_form['note'] = info_string
|
||||
instr_form["note"] = info_string
|
||||
suspicious_instructions.append(instr_form)
|
||||
else:
|
||||
suspicious_instructions.append(instr_form)
|
||||
# check for duplicates in DB
|
||||
if arch_mm._check_for_duplicate(instr_form['name'], instr_form['operands']):
|
||||
if arch_mm._check_for_duplicate(instr_form["name"], instr_form["operands"]):
|
||||
duplicate_instr_arch.append(instr_form)
|
||||
|
||||
|
||||
# Check operands
|
||||
for operand in instr_form['operands']:
|
||||
if operand['class'] == 'register' and not (
|
||||
'name' in operand or
|
||||
'prefix' in operand):
|
||||
for operand in instr_form["operands"]:
|
||||
if operand["class"] == "register" and not ("name" in operand or "prefix" in operand):
|
||||
# Missing 'name' key
|
||||
bad_operand.append(instr_form)
|
||||
elif operand['class'] == 'memory' and (
|
||||
'base' not in operand or
|
||||
'offset' not in operand or
|
||||
'index' not in operand or
|
||||
'scale' not in operand):
|
||||
elif operand["class"] == "memory" and (
|
||||
"base" not in operand
|
||||
or "offset" not in operand
|
||||
or "index" not in operand
|
||||
or "scale" not in operand
|
||||
):
|
||||
# Missing at least one key necessary for memory operands
|
||||
bad_operand.append(instr_form)
|
||||
elif operand['class'] == 'immediate' and 'imd' not in operand:
|
||||
elif operand["class"] == "immediate" and "imd" not in operand:
|
||||
# Missing 'imd' key
|
||||
bad_operand.append(instr_form)
|
||||
# every entry exists twice --> uniquify
|
||||
@@ -468,12 +465,12 @@ def _check_sanity_isa_db(arch_mm, isa_mm):
|
||||
duplicate_instr_isa = []
|
||||
only_in_isa = []
|
||||
|
||||
for instr_form in isa_mm['instruction_forms']:
|
||||
for instr_form in isa_mm["instruction_forms"]:
|
||||
# check if instr is missing in arch DB
|
||||
if arch_mm.get_instruction(instr_form['name'], instr_form['operands']) is None:
|
||||
if arch_mm.get_instruction(instr_form["name"], instr_form["operands"]) is None:
|
||||
only_in_isa.append(instr_form)
|
||||
# check for duplicates
|
||||
if isa_mm._check_for_duplicate(instr_form['name'], instr_form['operands']):
|
||||
if isa_mm._check_for_duplicate(instr_form["name"], instr_form["operands"]):
|
||||
duplicate_instr_isa.append(instr_form)
|
||||
# every entry exists twice --> uniquify
|
||||
tmp_list = []
|
||||
@@ -486,82 +483,102 @@ def _check_sanity_isa_db(arch_mm, isa_mm):
|
||||
return duplicate_instr_isa, only_in_isa
|
||||
|
||||
|
||||
def _get_sanity_report(total, m_tp, m_l, m_pp, suspic_instr, dup_arch, dup_isa, only_isa,
|
||||
bad_operands, verbose=False, colors=False):
|
||||
def _get_sanity_report(
|
||||
total,
|
||||
m_tp,
|
||||
m_l,
|
||||
m_pp,
|
||||
suspic_instr,
|
||||
dup_arch,
|
||||
dup_isa,
|
||||
only_isa,
|
||||
bad_operands,
|
||||
verbose=False,
|
||||
colors=False,
|
||||
):
|
||||
"""Get sanity summary report."""
|
||||
s = ''
|
||||
s = ""
|
||||
# non-verbose summary
|
||||
s += 'SUMMARY\n----------------------\n'
|
||||
s += '{}% ({}/{}) of instruction forms have no throughput value.\n'.format(
|
||||
s += "SUMMARY\n----------------------\n"
|
||||
s += "{}% ({}/{}) of instruction forms have no throughput value.\n".format(
|
||||
round(100 * len(m_tp) / total), len(m_tp), total
|
||||
)
|
||||
s += '{}% ({}/{}) of instruction forms have no latency value.\n'.format(
|
||||
s += "{}% ({}/{}) of instruction forms have no latency value.\n".format(
|
||||
round(100 * len(m_l) / total), len(m_l), total
|
||||
)
|
||||
s += '{}% ({}/{}) of instruction forms have no port pressure assignment.\n'.format(
|
||||
s += "{}% ({}/{}) of instruction forms have no port pressure assignment.\n".format(
|
||||
round(100 * len(m_pp) / total), len(m_pp), total
|
||||
)
|
||||
s += '{}% ({}/{}) of instruction forms might miss an ISA DB entry.\n'.format(
|
||||
s += "{}% ({}/{}) of instruction forms might miss an ISA DB entry.\n".format(
|
||||
round(100 * len(suspic_instr) / total), len(suspic_instr), total
|
||||
)
|
||||
s += '{} duplicate instruction forms in uarch DB.\n'.format(len(dup_arch))
|
||||
s += '{} duplicate instruction forms in ISA DB.\n'.format(len(dup_isa))
|
||||
s += "{} duplicate instruction forms in uarch DB.\n".format(len(dup_arch))
|
||||
s += "{} duplicate instruction forms in ISA DB.\n".format(len(dup_isa))
|
||||
s += (
|
||||
'{} instruction forms in ISA DB are not referenced by instruction '.format(len(only_isa))
|
||||
+ 'forms in uarch DB.\n'
|
||||
"{} instruction forms in ISA DB are not referenced by instruction ".format(len(only_isa))
|
||||
+ "forms in uarch DB.\n"
|
||||
)
|
||||
s += '{} bad operands found in uarch DB\n'.format(len(bad_operands))
|
||||
s += '----------------------\n'
|
||||
s += "{} bad operands found in uarch DB\n".format(len(bad_operands))
|
||||
s += "----------------------\n"
|
||||
# verbose version
|
||||
if verbose:
|
||||
s += _get_sanity_report_verbose(
|
||||
total, m_tp, m_l, m_pp, suspic_instr, dup_arch, dup_isa, only_isa, bad_operands,
|
||||
colors=colors
|
||||
total,
|
||||
m_tp,
|
||||
m_l,
|
||||
m_pp,
|
||||
suspic_instr,
|
||||
dup_arch,
|
||||
dup_isa,
|
||||
only_isa,
|
||||
bad_operands,
|
||||
colors=colors,
|
||||
)
|
||||
return s
|
||||
|
||||
|
||||
def _get_sanity_report_verbose(total, m_tp, m_l, m_pp, suspic_instr, dup_arch, dup_isa, only_isa,
|
||||
bad_operands, colors=False):
|
||||
def _get_sanity_report_verbose(
|
||||
total, m_tp, m_l, m_pp, suspic_instr, dup_arch, dup_isa, only_isa, bad_operands, colors=False
|
||||
):
|
||||
"""Get the verbose part of the sanity report with all missing instruction forms."""
|
||||
BRIGHT_CYAN = '\033[1;36;1m' if colors else ''
|
||||
BRIGHT_BLUE = '\033[1;34;1m' if colors else ''
|
||||
BRIGHT_RED = '\033[1;31;1m' if colors else ''
|
||||
BRIGHT_MAGENTA = '\033[1;35;1m' if colors else ''
|
||||
BRIGHT_YELLOW = '\033[1;33;1m' if colors else ''
|
||||
CYAN = '\033[36m' if colors else ''
|
||||
YELLOW = '\033[33m' if colors else ''
|
||||
WHITE = '\033[0m' if colors else ''
|
||||
BRIGHT_CYAN = "\033[1;36;1m" if colors else ""
|
||||
BRIGHT_BLUE = "\033[1;34;1m" if colors else ""
|
||||
BRIGHT_RED = "\033[1;31;1m" if colors else ""
|
||||
BRIGHT_MAGENTA = "\033[1;35;1m" if colors else ""
|
||||
BRIGHT_YELLOW = "\033[1;33;1m" if colors else ""
|
||||
CYAN = "\033[36m" if colors else ""
|
||||
YELLOW = "\033[33m" if colors else ""
|
||||
WHITE = "\033[0m" if colors else ""
|
||||
|
||||
s = 'Instruction forms without throughput value:\n' if m_tp else ''
|
||||
for instr_form in sorted(m_tp, key=lambda i: i['name']):
|
||||
s += '{}{}{}\n'.format(BRIGHT_BLUE, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += 'Instruction forms without latency value:\n' if m_l else ''
|
||||
for instr_form in sorted(m_l, key=lambda i: i['name']):
|
||||
s += '{}{}{}\n'.format(BRIGHT_RED, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += 'Instruction forms without port pressure assignment:\n' if m_pp else ''
|
||||
for instr_form in sorted(m_pp, key=lambda i: i['name']):
|
||||
s += '{}{}{}\n'.format(BRIGHT_MAGENTA, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += 'Instruction forms which might miss an ISA DB entry:\n' if suspic_instr else ''
|
||||
for instr_form in sorted(suspic_instr, key=lambda i: i['name']):
|
||||
s += '{}{}{}{}\n'.format(
|
||||
s = "Instruction forms without throughput value:\n" if m_tp else ""
|
||||
for instr_form in sorted(m_tp, key=lambda i: i["name"]):
|
||||
s += "{}{}{}\n".format(BRIGHT_BLUE, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += "Instruction forms without latency value:\n" if m_l else ""
|
||||
for instr_form in sorted(m_l, key=lambda i: i["name"]):
|
||||
s += "{}{}{}\n".format(BRIGHT_RED, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += "Instruction forms without port pressure assignment:\n" if m_pp else ""
|
||||
for instr_form in sorted(m_pp, key=lambda i: i["name"]):
|
||||
s += "{}{}{}\n".format(BRIGHT_MAGENTA, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += "Instruction forms which might miss an ISA DB entry:\n" if suspic_instr else ""
|
||||
for instr_form in sorted(suspic_instr, key=lambda i: i["name"]):
|
||||
s += "{}{}{}{}\n".format(
|
||||
BRIGHT_CYAN,
|
||||
_get_full_instruction_name(instr_form),
|
||||
' -- ' + instr_form['note'] if 'note' in instr_form else '',
|
||||
" -- " + instr_form["note"] if "note" in instr_form else "",
|
||||
WHITE,
|
||||
)
|
||||
s += 'Duplicate instruction forms in uarch DB:\n' if dup_arch else ''
|
||||
for instr_form in sorted(dup_arch, key=lambda i: i['name']):
|
||||
s += '{}{}{}\n'.format(YELLOW, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += 'Duplicate instruction forms in ISA DB:\n' if dup_isa else ''
|
||||
for instr_form in sorted(dup_isa, key=lambda i: i['name']):
|
||||
s += '{}{}{}\n'.format(BRIGHT_YELLOW, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += 'Instruction forms existing in ISA DB but not in uarch DB:\n' if only_isa else ''
|
||||
for instr_form in sorted(only_isa, key=lambda i: i['name']):
|
||||
s += '{}{}{}\n'.format(CYAN, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += '{} bad operands found in uarch DB:\n'.format(len(bad_operands)) if bad_operands else ''
|
||||
for instr_form in sorted(bad_operands, key=lambda i: i['name']):
|
||||
s += '{}{}{}\n'.format(BRIGHT_RED, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += "Duplicate instruction forms in uarch DB:\n" if dup_arch else ""
|
||||
for instr_form in sorted(dup_arch, key=lambda i: i["name"]):
|
||||
s += "{}{}{}\n".format(YELLOW, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += "Duplicate instruction forms in ISA DB:\n" if dup_isa else ""
|
||||
for instr_form in sorted(dup_isa, key=lambda i: i["name"]):
|
||||
s += "{}{}{}\n".format(BRIGHT_YELLOW, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += "Instruction forms existing in ISA DB but not in uarch DB:\n" if only_isa else ""
|
||||
for instr_form in sorted(only_isa, key=lambda i: i["name"]):
|
||||
s += "{}{}{}\n".format(CYAN, _get_full_instruction_name(instr_form), WHITE)
|
||||
s += "{} bad operands found in uarch DB:\n".format(len(bad_operands)) if bad_operands else ""
|
||||
for instr_form in sorted(bad_operands, key=lambda i: i["name"]):
|
||||
s += "{}{}{}\n".format(BRIGHT_RED, _get_full_instruction_name(instr_form), WHITE)
|
||||
return s
|
||||
|
||||
|
||||
@@ -573,18 +590,18 @@ def _get_sanity_report_verbose(total, m_tp, m_l, m_pp, suspic_instr, dup_arch, d
|
||||
def _get_full_instruction_name(instruction_form):
|
||||
"""Get full instruction form name/identifier string out of given instruction form."""
|
||||
operands = []
|
||||
for op in instruction_form['operands']:
|
||||
for op in instruction_form["operands"]:
|
||||
op_attrs = [
|
||||
y + ':' + str(op[y])
|
||||
for y in list(filter(lambda x: True if x != 'class' else False, op))
|
||||
y + ":" + str(op[y])
|
||||
for y in list(filter(lambda x: True if x != "class" else False, op))
|
||||
]
|
||||
operands.append('{}({})'.format(op['class'], ','.join(op_attrs)))
|
||||
return '{} {}'.format(instruction_form['name'], ','.join(operands))
|
||||
operands.append("{}({})".format(op["class"], ",".join(op_attrs)))
|
||||
return "{} {}".format(instruction_form["name"], ",".join(operands))
|
||||
|
||||
|
||||
def __represent_none(self, data):
|
||||
"""Get YAML None representation."""
|
||||
return self.represent_scalar(u'tag:yaml.org,2002:null', u'~')
|
||||
return self.represent_scalar(u"tag:yaml.org,2002:null", u"~")
|
||||
|
||||
|
||||
def _create_yaml_object():
|
||||
@@ -598,17 +615,17 @@ def __dump_data_to_yaml(filepath, data):
|
||||
"""Dump data to YAML file at given filepath."""
|
||||
# first add 'normal' meta data in the right order (no ordered dict yet)
|
||||
meta_data = dict(data)
|
||||
del meta_data['instruction_forms']
|
||||
del meta_data['port_model_scheme']
|
||||
with open(filepath, 'w') as f:
|
||||
del meta_data["instruction_forms"]
|
||||
del meta_data["port_model_scheme"]
|
||||
with open(filepath, "w") as f:
|
||||
ruamel.yaml.dump(meta_data, f, allow_unicode=True)
|
||||
with open(filepath, 'a') as f:
|
||||
with open(filepath, "a") as f:
|
||||
# now add port model scheme in |-scheme for better readability
|
||||
ruamel.yaml.dump(
|
||||
{'port_model_scheme': data['port_model_scheme']},
|
||||
{"port_model_scheme": data["port_model_scheme"]},
|
||||
f,
|
||||
allow_unicode=True,
|
||||
default_style='|',
|
||||
default_style="|",
|
||||
)
|
||||
# finally, add instruction forms
|
||||
ruamel.yaml.dump({'instruction_forms': data['instruction_forms']}, f, allow_unicode=True)
|
||||
ruamel.yaml.dump({"instruction_forms": data["instruction_forms"]}, f, allow_unicode=True)
|
||||
|
||||
Reference in New Issue
Block a user