mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2025-12-16 09:00:05 +01:00
enhanced YAML output to include all kernel objects and no ruamel.yaml-specific data types
This commit is contained in:
@@ -8,6 +8,7 @@ import re
|
|||||||
from datetime import datetime as dt
|
from datetime import datetime as dt
|
||||||
|
|
||||||
from osaca.semantics import INSTR_FLAGS, ArchSemantics, KernelDG, MachineModel
|
from osaca.semantics import INSTR_FLAGS, ArchSemantics, KernelDG, MachineModel
|
||||||
|
from osaca.parser import AttrDict
|
||||||
|
|
||||||
|
|
||||||
def _get_version(*file_paths):
|
def _get_version(*file_paths):
|
||||||
@@ -209,6 +210,23 @@ class Frontend(object):
|
|||||||
length_warning=False,
|
length_warning=False,
|
||||||
lcd_warning=False,
|
lcd_warning=False,
|
||||||
):
|
):
|
||||||
|
"""
|
||||||
|
Create a dictionary of the full analysis for machine-readable output.
|
||||||
|
|
||||||
|
:param kernel: kernel to report on
|
||||||
|
:type kernel: list
|
||||||
|
:param kernel_dg: directed graph containing CP and LCD
|
||||||
|
:type kernel_dg: :class:`~osaca.semantics.KernelDG`
|
||||||
|
:param arch_warning: flag for additional user warning to specify micro-arch
|
||||||
|
:type arch_warning: boolean, optional
|
||||||
|
:param length_warning: flag for additional user warning to specify kernel length with
|
||||||
|
--lines
|
||||||
|
:type length_warning: boolean, optional
|
||||||
|
:param lcd_warning: flag for additional user warning due to LCD analysis timed out
|
||||||
|
:type lcd_warning: boolean, optional
|
||||||
|
|
||||||
|
:returns: dict -- a dict of the analysis
|
||||||
|
"""
|
||||||
warnings = []
|
warnings = []
|
||||||
|
|
||||||
if arch_warning:
|
if arch_warning:
|
||||||
@@ -218,7 +236,7 @@ class Frontend(object):
|
|||||||
warnings.append("LengthWarning")
|
warnings.append("LengthWarning")
|
||||||
|
|
||||||
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")
|
||||||
@@ -231,21 +249,24 @@ class Frontend(object):
|
|||||||
if dep_dict:
|
if dep_dict:
|
||||||
longest_lcd = max(dep_dict, key=lambda ln: dep_dict[ln]["latency"])
|
longest_lcd = max(dep_dict, key=lambda ln: dep_dict[ln]["latency"])
|
||||||
lcd_sum = dep_dict[longest_lcd]["latency"]
|
lcd_sum = dep_dict[longest_lcd]["latency"]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"Header": self._header_report_dict(),
|
"Header": self._header_report_dict(),
|
||||||
"Warnings": warnings,
|
"Warnings": warnings,
|
||||||
"Kernel": [
|
"Kernel": [
|
||||||
{
|
{
|
||||||
"Line": re.sub(r"\s+", " ", x["line"].strip()),
|
"Line": re.sub(r"\s+", " ", x["line"].strip()),
|
||||||
|
"LineNumber": x["line_number"],
|
||||||
"Flags": list(x["flags"]),
|
"Flags": list(x["flags"]),
|
||||||
"Instruction": x["instruction"],
|
"Instruction": x["instruction"],
|
||||||
|
"Operands": AttrDict.get_dict(x["operands"]),
|
||||||
|
"SemanticOperands": AttrDict.get_dict(x["semantic_operands"]),
|
||||||
"Label": x["label"],
|
"Label": x["label"],
|
||||||
"Latency": x["latency"],
|
"Directive": x["directive"],
|
||||||
"LatencyCP": x["latency_cp"],
|
"Latency": float(x["latency"]),
|
||||||
"LatencyLCD": x["latency_lcd"],
|
"LatencyCP": float(x["latency_cp"]),
|
||||||
|
"LatencyLCD": float(x["latency_lcd"]),
|
||||||
"Throughput": float(x["throughput"]),
|
"Throughput": float(x["throughput"]),
|
||||||
"LatencyWithoutLoad": x["latency_wo_load"],
|
"LatencyWithoutLoad": float(x["latency_wo_load"]),
|
||||||
"PortPressure": {
|
"PortPressure": {
|
||||||
self._machine_model.get_ports()[i]: v
|
self._machine_model.get_ports()[i]: v
|
||||||
for i, v in enumerate(x["port_pressure"])
|
for i, v in enumerate(x["port_pressure"])
|
||||||
@@ -257,6 +278,7 @@ class Frontend(object):
|
|||||||
}
|
}
|
||||||
for y in x["port_uops"]
|
for y in x["port_uops"]
|
||||||
],
|
],
|
||||||
|
"Comment": x["comment"],
|
||||||
}
|
}
|
||||||
for x in kernel
|
for x in kernel
|
||||||
],
|
],
|
||||||
@@ -526,6 +548,7 @@ class Frontend(object):
|
|||||||
return {
|
return {
|
||||||
"Version": _get_version("__init__.py"),
|
"Version": _get_version("__init__.py"),
|
||||||
"FileName": self._filename,
|
"FileName": self._filename,
|
||||||
|
"Architecture": self._arch,
|
||||||
"Timestamp": dt.utcnow().strftime("%Y-%m-%d %H:%M:%S"),
|
"Timestamp": dt.utcnow().strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ def create_parser(parser=None):
|
|||||||
default=None,
|
default=None,
|
||||||
dest="yaml_out",
|
dest="yaml_out",
|
||||||
type=argparse.FileType("w"),
|
type=argparse.FileType("w"),
|
||||||
help="Write YAML analysis to this file",
|
help="Write analysis as YAML representation to this file",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"file",
|
"file",
|
||||||
|
|||||||
@@ -27,3 +27,27 @@ class AttrDict(dict):
|
|||||||
dictionary[key] = [AttrDict.convert_dict(x) for x in entry]
|
dictionary[key] = [AttrDict.convert_dict(x) for x in entry]
|
||||||
return AttrDict(dictionary)
|
return AttrDict(dictionary)
|
||||||
return dictionary
|
return dictionary
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_dict(attrdict):
|
||||||
|
"""
|
||||||
|
Convert given `AttrDict` to a standard dictionary.
|
||||||
|
|
||||||
|
:param attrdict: `AttrDict` to be converted
|
||||||
|
:type attrdict: `AttrDict`
|
||||||
|
:returns: `dict` representation of ``AttrDict``
|
||||||
|
"""
|
||||||
|
if isinstance(attrdict, type(list())):
|
||||||
|
return [AttrDict.get_dict(x) for x in attrdict]
|
||||||
|
if isinstance(attrdict, type(AttrDict())):
|
||||||
|
newdict = {}
|
||||||
|
for key in list(attrdict.keys()):
|
||||||
|
entry = attrdict[key]
|
||||||
|
if isinstance(entry, type(dict())) or isinstance(entry, type(AttrDict())):
|
||||||
|
newdict[key] = AttrDict.get_dict(attrdict[key])
|
||||||
|
elif isinstance(entry, type(list())):
|
||||||
|
newdict[key] = [AttrDict.get_dict(x) for x in entry]
|
||||||
|
else:
|
||||||
|
newdict[key] = entry
|
||||||
|
return newdict
|
||||||
|
return attrdict
|
||||||
|
|||||||
Reference in New Issue
Block a user