Skip to content

Commit

Permalink
Record some environment info, fix #10
Browse files Browse the repository at this point in the history
  • Loading branch information
Johannes Bechberger committed Aug 14, 2020
1 parent 6e757e0 commit 8e7e855
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 7 deletions.
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
'rainbow_logging_handler',
'tablib',
'pyyaml',
'seaborn', 'matplotlib'
'seaborn', 'matplotlib',
'psutil'
],
tests_require=['pytest'],
license='GPLv3',
Expand Down
13 changes: 13 additions & 0 deletions temci/report/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ def report(self):
<p/>
"""
inner_html += self._comparison_for_prop(prop)

for single in self.stats.singles:
inner_html += """<div class="block">"""
inner_html += self._extended_summary(single, with_title=True, title_level=2,
Expand All @@ -436,6 +437,7 @@ def report(self):
inner_html += """<div class="block">"""
inner_html += self._extended_summary(pair, with_title=True, title_level=2,
title_class="page-header") + """</div>"""
inner_html += self._format_hw_info()
self._write(html.format(timespan=hf.format_timespan(time.time() - start_time), **locals()))
logging.info("Finished generating html")
logging.info("Generate images...")
Expand Down Expand Up @@ -498,6 +500,17 @@ def _format_excluded_data_warnings(self):
descr)
return html

def _format_hw_info(self) -> str:
def format_hw_info_section(name: str, content: t.List[t.Tuple[str, str]]) -> str:
return """<h3>{}</h3>
<table class="table">{}</table>"""\
.format(name, "\n".join("<tr><th>{}</th><td>{}</td></tr>".format(n.upper(), v) for n, v in content))
if self.stats_helper.env_info:
return """<h2 id="hw_info" class="page-header">Hardware info</h2>
{}
""".format("\n".join(format_hw_info_section(name, content) for name, content in self.stats_helper.env_info))
return ""

def _full_single_property_comp_table(self, property: str = None) -> '_Table':
header_cells = []
for single in self.stats.singles:
Expand Down
30 changes: 24 additions & 6 deletions temci/report/rundata.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from temci.report.testers import Tester, TesterRegistry
from temci.run.run_driver import filter_runs
from temci.utils.config_utils import ATTRIBUTES_TYPE
from temci.utils.envinfo import FORMATTED_ENV_INFO, format_env_info
from temci.utils.typecheck import *
from temci.utils.settings import Settings
import temci.utils.util as util
Expand Down Expand Up @@ -97,6 +98,9 @@ class RunData(object):
"property_descriptions": NonExistent() |
Dict(key_type=Str(), value_type=Str(), unknown_keys=True)})

env_info_scheme = Dict({
"env_info": NonExistent() | List(Tuple(Str(), List(Tuple(Str(), Str()))))})

def __init__(self, data: t.Dict[str, t.List[Number]] = None, attributes: t.Dict[str, str] = None,
recorded_error: RecordedError = None,
external: bool = False):
Expand Down Expand Up @@ -300,7 +304,7 @@ class RunDataStatsHelper(object):
def __init__(self, runs: t.List[RunData], tester: Tester = None, external_count: int = 0,
property_descriptions: t.Dict[str, str] = None,
errorneous_runs: t.List[RunData] = None,
included_blocks: str = None):
included_blocks: str = None, env_info: FORMATTED_ENV_INFO = None):
"""
Don't use the constructor use init_from_dicts if possible.
Expand All @@ -311,6 +315,7 @@ def __init__(self, runs: t.List[RunData], tester: Tester = None, external_count:
:param property_descriptions: mapping of some properties to their descriptions or longer versions
:param errorneous_runs: runs that resulted in errors
:param included_blocks: include query
:param env_info: formatted environment info
"""
self.tester = tester or TesterRegistry.get_for_name(TesterRegistry.get_used(),
Settings()["stats/uncertainty_range"]) # type: Tester
Expand All @@ -325,6 +330,7 @@ def __init__(self, runs: t.List[RunData], tester: Tester = None, external_count:
Number of external program blocks (blocks for which the data was obtained in a different benchmarking session)
"""
self.property_descriptions = property_descriptions or {} # type: t.Dict[str, str]
self.env_info = env_info or []

def clone(self, runs: t.List[RunData] = None, tester: Tester = None, external_count: int = None,
property_descriptions: t.Dict[str, str] = None) -> 'RunDataStatsHelper':
Expand All @@ -343,7 +349,7 @@ def alt(new, old):
return RunDataStatsHelper(runs=alt(runs, self.runs), tester=alt(tester, self.tester),
external_count=alt(external_count, self.external_count),
property_descriptions=alt(property_descriptions, self.property_descriptions),
errorneous_runs=self.errorneous_runs)
errorneous_runs=self.errorneous_runs, env_info=self.env_info)

def make_descriptions_distinct(self):
"""
Expand Down Expand Up @@ -442,7 +448,9 @@ def init_from_dicts(cls, runs: t.List[t.Union[t.Dict[str, str], t.Dict[str, t.Li
"data": {"__ov-time": [...], ...},
"error": {"return_code": …, "output": "…", "error_output": "…"},
"internal_error": {"message": "…"} (either "error" or "internal_error" might be present)
["property_descriptions": {"__ov-time": "Overall time"}]},
["property_descriptions": {"__ov-time": "Overall time", …}]
["env_info": … ]
},
...
]
Expand All @@ -459,15 +467,19 @@ def init_from_dicts(cls, runs: t.List[t.Union[t.Dict[str, str], t.Dict[str, t.Li
"run_config": Dict(unknown_keys=True)
}, unknown_keys=True) |
RunData.block_type_scheme |
RunData.property_descriptions_scheme),
RunData.property_descriptions_scheme |
RunData.env_info_scheme),
value_name="runs parameter")
run_datas = []
runs = runs or [] # type: t.List[dict]
prop_descrs = {} # type: t.Dict[str, str]
env_info = []
for run in runs:
props = {}
if "property_descriptions" in run:
prop_descrs.update(run["property_descriptions"])
elif "env_info" in run:
env_info = run["env_info"]
else:
if "data" not in run:
run["data"] = {}
Expand All @@ -480,7 +492,8 @@ def init_from_dicts(cls, runs: t.List[t.Union[t.Dict[str, str], t.Dict[str, t.Li
run_datas.append(RunData(run["data"], run["attributes"] if "attributes" in run else {}, recorded_error=error,
external=external))
return RunDataStatsHelper(run_datas, external_count=len(run_datas) if external else 0,
property_descriptions=prop_descrs, included_blocks=included_blocks)
property_descriptions=prop_descrs, included_blocks=included_blocks,
env_info=env_info)

def _is_uncertain(self, property: str, data1: RunData, data2: RunData) -> bool:
return self.tester.is_uncertain(data1[property], data2[property])
Expand Down Expand Up @@ -681,7 +694,7 @@ def get_evaluation(self, with_equal: bool, with_unequal: bool, with_uncertain: b
})
return arr

def serialize(self) -> t.List[t.Union[t.Dict[str, str], t.Dict[str, t.List[Number]]]]:
def serialize(self) -> t.List[t.Union[t.Dict[str, str], t.Dict[str, t.List[Number]], FORMATTED_ENV_INFO]]:
"""
Serialize this instance into a data structure that is accepted by the ``init_from_dicts`` method.
"""
Expand All @@ -693,6 +706,7 @@ def serialize(self) -> t.List[t.Union[t.Dict[str, str], t.Dict[str, t.List[Numbe
if prop in self.property_descriptions:
ps[prop] = self.property_descriptions[prop]
ret.append({"property_descriptions": ps})
ret.append({"env_info": self.env_info})
return ret

def valid_runs(self) -> t.List[RunData]:
Expand Down Expand Up @@ -774,6 +788,10 @@ def long_properties(self, property_format: str = "[{}]") -> t.Tuple['RunDataStat

return self.clone(runs=runs), formatted_properties

def update_env_info(self):
""" Obtain the environment information for the current system and store it """
self.env_info = format_env_info()


class ExcludedInvalidData:
"""
Expand Down
1 change: 1 addition & 0 deletions temci/run/run_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ def store(self):
if (len(self.stats_helper.valid_runs()) > 0 and all(x.benchmarks() > 0 for x in self.stats_helper.valid_runs())) \
or Settings()["run/record_errors_in_file"]:
with open(Settings()["run/out"], "w") as f:
self.stats_helper.update_env_info(),
f.write(yaml.dump(self.stats_helper.serialize()))
chown(f)

Expand Down
1 change: 1 addition & 0 deletions temci/utils/util.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Utility functions and classes that don't depend on the rest of the temci code base.
"""
import enum
import functools
import os
import resource
Expand Down
4 changes: 4 additions & 0 deletions tests/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,7 @@ def test_per_block_runs_issue_113():
}
]
}).yaml_contents["run_output.yaml"][0]["data"]["stime"]) == 1


def test_envinfo_in_result():
assert any("env_info" in v for v in run_temci("short exec ls").yaml_contents["run_output.yaml"])

0 comments on commit 8e7e855

Please sign in to comment.