Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements experiments to run and time traced and untraced versions of all binaries in a project #588

Open
wants to merge 46 commits into
base: vara-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
928308e
Small refactoring for fm provider
vulder Nov 23, 2021
3a70322
Adds project for FeaturePerfCS repo
vulder Nov 23, 2021
724d158
Cleans up compiler handling for lrzip
vulder Nov 23, 2021
aa39871
Adds initial draft of feature perf runner
vulder Nov 23, 2021
9ff98d2
Adds exception should a FM not be found
vulder Nov 23, 2021
7394108
Implements core report discovery
vulder Nov 24, 2021
7e87e2a
Small clean up
vulder Nov 24, 2021
2115e2b
Implements report for trace event format
vulder Nov 24, 2021
60471b0
Merge branch 'vara-dev' into f-FeaturePerfMeasure
vulder Dec 26, 2021
9ff38ae
Ensure type conversions from json
vulder Dec 26, 2021
a150bc5
Add doc string and desc to exec step
vulder Dec 26, 2021
4bf78a2
Fixes type error
vulder Dec 26, 2021
704fd53
premerge
niomate Jan 19, 2022
761f5dc
resolve merge conflicts
niomate Jan 19, 2022
004b7ef
Adapts variant calculation to be experiment specific
vulder Jan 19, 2022
9213d3f
Ports code to consider all reports not just the main report
vulder Jan 19, 2022
042ab2e
Removes error check
vulder Jan 19, 2022
4f63fe5
Merge branch 'vara-dev' into f-FixVariantRedLookup
vulder Jan 20, 2022
b79167d
Merge remote-tracking branch 'origin/f-FixVariantRedLookup' into ma-g…
niomate Jan 20, 2022
851556f
Merge branch 'vara-dev' into ma-gusenburger
niomate Jan 20, 2022
56060eb
first naive implementation of RunTraced and RunUntraced experiments
niomate Jan 21, 2022
a8e0440
implemented common base class for evaluation experiments
niomate Jan 24, 2022
1a547e4
Merge branch 'vara-dev' into ma-gusenburger
vulder Feb 2, 2022
fa125a1
implemented some of the suggested changes
niomate Feb 8, 2022
146c8a8
Merge branch 'ma-gusenburger' of github.com:se-passau/VaRA-Tool-Suite…
niomate Feb 8, 2022
87b2c13
Merge remote-tracking branch 'origin/vara-dev' into ma-gusenburger
niomate Mar 2, 2022
375a0a9
fix: now passing correct CLI args to clang in RunTimeTraced to proper…
niomate Apr 11, 2022
1be8aa0
merged with dev branch
niomate Apr 11, 2022
e5e9b05
Merge branch 'vara-dev' into ma-gusenburger
niomate Apr 15, 2022
2858825
fix: removed type ignore comments
niomate Apr 15, 2022
1d45644
merged vara-dev into branch
niomate Jan 5, 2023
1a2728a
Merge remote-tracking branch 'origin/vara-dev' into ma-gusenburger
niomate Jan 17, 2023
ed9a39c
updated experiments
niomate Jan 20, 2023
8a5cea5
Merge remote-tracking branch 'origin/vara-dev' into ma-gusenburger
niomate Jan 20, 2023
125970a
added workloads to bzip2 and lrzip, rewrote instrumentation stats to …
niomate Apr 10, 2023
4f018c1
added dynamic overhead analysis (WIP)
niomate Apr 10, 2023
adce0dd
merged with vara-dev
niomate Apr 10, 2023
9b3d995
implemented multicompileexperiment
niomate May 4, 2023
9982927
added multiple budget experiment to instrumentation verifier
niomate May 16, 2023
ff9a904
reverse compability to python 3.9.x
May 17, 2023
11cb37c
separated implementations for RunTraced for VaryingBudget and regular…
niomate May 18, 2023
a729e2b
InstrVerifierReport should not produce useful results for experiments…
niomate Jun 9, 2023
68aa7d7
updating
niomate Oct 5, 2023
9bba9c4
resolved merge conflicts
niomate Oct 5, 2023
b0113aa
updates
niomate Oct 9, 2023
5f07720
final commit
niomate Oct 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion tests/data/test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class TestFileStatusExtension(unittest.TestCase):
"""Test basic FileStatusExtension functionality."""

def test_status_extension(self):
""""""
"""Tests if we convert a FSE to it's string representation."""
self.assertEqual(
FileStatusExtension.SUCCESS.get_status_extension(), "success"
)
Expand Down Expand Up @@ -62,6 +62,11 @@ def test_wrong_status_lookup(self):
class TestReportFilename(unittest.TestCase):
"""Test basic TestReportFilename functionality."""

correct_UUID: str
raw_filename: str
report_filename: ReportFilename
broken_report_filename: ReportFilename

@classmethod
def setUpClass(cls):
"""Setup file and CommitReport."""
Expand Down Expand Up @@ -151,6 +156,10 @@ def test_get_uuid(self):
class TestBaseReport(unittest.TestCase):
"""Test basic BaseReport functionality."""

success_filename_cr: str
success_filename: str
fail_filename: str

@classmethod
def setUpClass(cls):
"""Setup report file paths."""
Expand Down
235 changes: 235 additions & 0 deletions tests/report/test_tef_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
"""Test TEFReport."""

import json
import unittest
from pathlib import Path
from unittest import mock

from varats.report.tef_report import TEFReport, TraceEvent, TraceEventType

TRACE_EVENT_FORMAT_OUTPUT = """{
"traceEvents": [{
"name": "Base",
"cat": "Feature",
"ph": "B",
"ts": 1637675320727304236,
"pid": 91098,
"tid": 91098
}, {
"name": "Foo",
"cat": "Feature",
"ph": "B",
"ts": 1637675320727316656,
"pid": 91098,
"tid": 91098
}, {
"name": "Foo",
"cat": "Feature",
"ph": "E",
"ts": 1637675325727410375,
"pid": 91098,
"tid": 91098
}, {
"name": "Bar",
"cat": "Feature",
"ph": "B",
"ts": 1637675328727504858,
"pid": 91098,
"tid": 91098
}, {
"name": "Bar",
"cat": "Feature",
"ph": "E",
"ts": 1637675331727788401,
"pid": 91098,
"tid": 91098
}, {
"name": "Foo_2",
"cat": "Feature",
"ph": "B",
"ts": 1637675335727890982,
"pid": 91098,
"tid": 91098
}, {
"name": "Foo_2",
"cat": "Feature",
"ph": "E",
"ts": 1637675341728002649,
"pid": 91098,
"tid": 91098
}, {
"name": "Base",
"cat": "Feature",
"ph": "E",
"ts": 1637675341728008439,
"pid": 91098,
"tid": 91098
} ],
"displayTimeUnit": "ns",
"stackFrames": {}
}
"""


class TestTraceEventType(unittest.TestCase):
"""Test if we can correclty parse TraceEventTypes."""

def test_parse_duration_events(self) -> None:
"""Test if we correctly parse duration event types."""
self.assertEqual(
TraceEventType.parse_event_type("B"),
TraceEventType.DURATION_EVENT_BEGIN
)
self.assertEqual(
TraceEventType.parse_event_type("E"),
TraceEventType.DURATION_EVENT_END
)

def test_parse_async_events(self) -> None:
"""Test if we correctly parse async event types."""
self.assertEqual(
TraceEventType.parse_event_type("b"),
TraceEventType.ASYNC_EVENT_START
)
self.assertEqual(
TraceEventType.parse_event_type("n"),
TraceEventType.ASYNC_EVENT_INSTANT
)
self.assertEqual(
TraceEventType.parse_event_type("e"), TraceEventType.ASYNC_EVENT_END
)

def test_parse_flow_events(self) -> None:
"""Test if we correctly parse flow event types."""
self.assertEqual(
TraceEventType.parse_event_type("s"),
TraceEventType.FLOW_EVENT_START
)
self.assertEqual(
TraceEventType.parse_event_type("t"), TraceEventType.FLOW_EVENT_STEP
)
self.assertEqual(
TraceEventType.parse_event_type("f"), TraceEventType.FLOW_EVENT_END
)

def test_parse_other_events(self) -> None:
"""Test if we correctly parse other event types."""
self.assertEqual(
TraceEventType.parse_event_type("X"), TraceEventType.COMPLETE_EVENT
)
self.assertEqual(
TraceEventType.parse_event_type("i"), TraceEventType.INSTANT_EVENT
)
self.assertEqual(
TraceEventType.parse_event_type("C"), TraceEventType.COUNTER_EVENT
)
self.assertEqual(
TraceEventType.parse_event_type("P"), TraceEventType.SAMPLE_EVENT
)

def test_fail_at_wrong_event_string(self) -> None:
"""Test if we fail should an event type not match."""
self.assertRaises(LookupError, TraceEventType.parse_event_type, "42")
self.assertRaises(LookupError, TraceEventType.parse_event_type, "I")
self.assertRaises(LookupError, TraceEventType.parse_event_type, "D")
self.assertRaises(LookupError, TraceEventType.parse_event_type, "d")


SINGLE_TRACE_EVENT = """{
"name": "Base",
"cat": "Feature",
"ph": "E",
"ts": 1637675341728008439,
"pid": 91098,
"tid": 91099
}
"""


class TestTraceEvent(unittest.TestCase):
"""Test if we can correctly load trace events and parse values."""

trace_event: TraceEvent

@classmethod
def setUpClass(cls):
"""Load trace event."""
cls.trace_event = TraceEvent(json.loads(SINGLE_TRACE_EVENT))

def test_name_parsing(self):
"""Test if we can correctly parse event names."""
self.assertEqual(self.trace_event.name, "Base")
self.assertNotEqual(self.trace_event.name, "Foo")

def test_category_parsing(self):
"""Test if we can correctly parse event categories."""
self.assertEqual(self.trace_event.category, "Feature")
self.assertNotEqual(self.trace_event.name, "Foo")

def test_event_type_parsing(self):
"""Test if we can correctly parse event type."""
self.assertEqual(
self.trace_event.event_type, TraceEventType.DURATION_EVENT_END
)
self.assertIsInstance(self.trace_event.event_type, TraceEventType)
self.assertNotEqual(
self.trace_event.event_type, TraceEventType.DURATION_EVENT_BEGIN
)

def test_timestamp_parsing(self):
"""Test if we can correctly parse event timestamps."""
self.assertEqual(self.trace_event.timestamp, 1637675341728008439)
self.assertIsInstance(self.trace_event.timestamp, int)

self.assertNotEqual(self.trace_event.name, 1637675341728008438)
self.assertNotEqual(self.trace_event.name, 0)

def test_pid_parsing(self):
"""Test if we can correctly parse event pid."""
self.assertEqual(self.trace_event.pid, 91098)
self.assertIsInstance(self.trace_event.pid, int)

self.assertNotEqual(self.trace_event.name, 91099)
self.assertNotEqual(self.trace_event.name, 91097)
self.assertNotEqual(self.trace_event.name, 0)

def test_tid_parsing(self):
"""Test if we can correctly parse event tid."""
self.assertEqual(self.trace_event.tid, 91099)
self.assertIsInstance(self.trace_event.tid, int)

self.assertNotEqual(self.trace_event.name, 91100)
self.assertNotEqual(self.trace_event.name, 91098)
self.assertNotEqual(self.trace_event.name, 0)


class TestTEFReportParser(unittest.TestCase):
"""Tests if the trace-event-format report can be parsed correctly."""

report: TEFReport

@classmethod
def setUpClass(cls):
"""Load and prepare TEF report."""
with mock.patch(
'builtins.open',
new=mock.mock_open(read_data=TRACE_EVENT_FORMAT_OUTPUT)
):
cls.report = TEFReport(Path("fake_file_path"))

def test_parse_time_unit(self) -> None:
"""Test if the time unit field is correclty parsed."""
self.assertEqual(self.report.display_time_unit, "ns")
self.assertNotEqual(self.report.display_time_unit, "ms")

def test_parse_trace_events(self) -> None:
"""Test if we correctly parse the listed trace events."""
self.assertEqual(len(self.report.trace_events), 8)

self.assertEqual(self.report.trace_events[0].name, "Base")

def test_parse_stack_frames(self) -> None:
"""Test if we correctly parse stack frames."""
# Currently, not implemented so we should get an exception.
with self.assertRaises(NotImplementedError):
_ = self.report.stack_frames
17 changes: 16 additions & 1 deletion varats-core/varats/provider/feature/feature_model_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@
from varats.provider.provider import Provider


class FeatureModelNotFound(FileNotFoundError):
"""Exception raised when the specified feature model could not be found."""

def __init__(self, project: Project, fm_path: tp.Optional[Path]) -> None:
err_msg = f"Could not find feature model for project {project.name}!\n"
if fm_path:
err_msg += f"No file at: {fm_path}."
else:
err_msg += "Got no feature-model path."

super().__init__(err_msg)


class FeatureModelProvider(Provider):
"""Provider for accessing project related FeatureModels."""

Expand Down Expand Up @@ -57,10 +70,12 @@ def get_feature_model_path(
"""
project_name = self.project.NAME.lower()

fully_qualified_fm_name = "FeatureModel"

for project_dir in self._get_feature_model_repository_path().iterdir():
if project_dir.name.lower() == project_name:
for poss_fm_file in project_dir.iterdir():
if poss_fm_file.stem == "FeatureModel":
if poss_fm_file.stem == fully_qualified_fm_name:
return poss_fm_file

return None
Expand Down
16 changes: 16 additions & 0 deletions varats-core/varats/report/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""Auto discover all core reports in subfolders."""

import importlib
import pkgutil


def discover() -> None:
"""Auto import all core varats reports."""
__all__ = []
for _, module_name, _ in pkgutil.walk_packages(
__path__, # type: ignore
'varats.report.'
):
__all__.append(module_name)
_module = importlib.import_module(module_name)
globals()[module_name] = _module
Loading