Skip to content

Commit 3816227

Browse files
authored
Merge PR #202: Make gauge adapter names in configuration case insensitive
2 parents 08c736b + cddb626 commit 3816227

File tree

5 files changed

+69
-19
lines changed

5 files changed

+69
-19
lines changed

docs/extensions.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ ReBench currently provides builtin support for the following benchmark harnesses
1616
- `ValidationLog`: the format used by [SOMns](https://github.com/smarr/SOMns)'s ImpactHarness
1717
- `Time`: a harness that uses `/usr/bin/time` automatically
1818

19+
1920
### `PlainSecondsLog`
2021

2122
This adapter attempts to read every line of program output as a millisecond
@@ -35,6 +36,7 @@ Implementation Notes:
3536

3637
- Python's `float()` function is used for parsing
3738

39+
3840
### `ReBenchLog`
3941

4042
The ReBenchLog parser is the most commonly used and has most features.
@@ -80,6 +82,24 @@ Implementation Notes:
8082
the following regular expression should match
8183
`r"^(?:.*: )?([^\s]+): ([^:]{1,30}):\s*([0-9]+)([a-zA-Z]+)")`
8284

85+
86+
## `Time`
87+
88+
The `Time` adapter uses Unix's `/usr/bin/time` command.
89+
On Linux, or more generally the platforms that support it, it will also use the
90+
`-f` switch of the `time` command to record the maximum resident set size,
91+
i.e., the maximum amount of memory the program used.
92+
93+
Example configuration for a suite:
94+
95+
```yaml
96+
Suite:
97+
gauge_adapter: Time
98+
benchmarks:
99+
- Bench1
100+
```
101+
102+
83103
## Supporting other Benchmark Harnesses
84104
85105
To add support for your own harness, check the `rebench.interop` module.

rebench/executor.py

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,13 @@
2424
from math import floor
2525
from multiprocessing import cpu_count
2626
import os
27-
import pkgutil
2827
import random
2928
import subprocess
30-
import sys
3129
from threading import Thread, RLock
3230
from time import time
3331

3432
from . import subprocess_with_timeout as subprocess_timeout
35-
from .interop.adapter import ExecutionDeliveredNoResults
33+
from .interop.adapter import ExecutionDeliveredNoResults, instantiate_adapter
3634
from .ui import escape_braces
3735

3836

@@ -444,22 +442,7 @@ def execute_run(self, run_id):
444442
return terminate
445443

446444
def _get_gauge_adapter_instance(self, adapter_name):
447-
adapter_name += "Adapter"
448-
449-
root = sys.modules['rebench.interop'].__path__
450-
451-
for _, name, _ in pkgutil.walk_packages(root):
452-
# depending on how ReBench was executed, name might one of the two
453-
try:
454-
mod = __import__("rebench.interop." + name, fromlist=adapter_name)
455-
except ImportError:
456-
try:
457-
mod = __import__("interop." + name, fromlist=adapter_name)
458-
except ImportError:
459-
mod = None
460-
if mod is not None and hasattr(mod, adapter_name):
461-
return getattr(mod, adapter_name)(self._include_faulty, self)
462-
return None
445+
return instantiate_adapter(adapter_name, self._include_faulty, self)
463446

464447
def _generate_data_point(self, cmdline, gauge_adapter, run_id,
465448
termination_check):

rebench/interop/adapter.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1919
# THE SOFTWARE.
2020
import re
21+
import pkgutil
22+
import sys
2123

2224

2325
class GaugeAdapter(object):
@@ -78,3 +80,24 @@ class OutputNotParseable(ExecutionDeliveredNoResults):
7880

7981
class ResultsIndicatedAsInvalid(ExecutionDeliveredNoResults):
8082
pass
83+
84+
85+
def instantiate_adapter(name, include_faulty, executor):
86+
adapter_name = name + "Adapter"
87+
root = sys.modules['rebench.interop'].__path__
88+
89+
for _, module_name, _ in pkgutil.walk_packages(root):
90+
# depending on how ReBench was executed, name might one of the two
91+
try:
92+
mod = __import__("rebench.interop." + module_name, fromlist=adapter_name)
93+
except ImportError:
94+
try:
95+
mod = __import__("interop." + module_name, fromlist=adapter_name)
96+
except ImportError:
97+
mod = None
98+
if mod is not None:
99+
for key in dir(mod):
100+
if key.lower() == adapter_name.lower():
101+
return getattr(mod, key)(include_faulty, executor)
102+
103+
return None

rebench/interop/rebench_log_adapter.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class RebenchLogAdapter(GaugeAdapter):
3030
"""RebenchLogPerformance is the standard log parser of ReBench.
3131
It reads a simple log format, which includes the number of iterations of
3232
a benchmark and its runtime in microseconds.
33+
34+
Note: regular expressions are documented in /docs/extensions.md
3335
"""
3436
re_log_line = re.compile(
3537
r"^(?:.*: )?([^\s]+)( [\w\.]+)?: iterations=([0-9]+) runtime: ([0-9]+)([mu])s")

rebench/tests/interop/adapter_test.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from unittest import TestCase
2+
from ...interop.adapter import instantiate_adapter
3+
4+
5+
class AdapterTest(TestCase):
6+
def test_load_all_known_adapters(self):
7+
self.assertIsNotNone(instantiate_adapter("JMH", False, None))
8+
self.assertIsNotNone(instantiate_adapter("Multivariate", False, None))
9+
self.assertIsNotNone(instantiate_adapter("Perf", False, None))
10+
self.assertIsNotNone(instantiate_adapter("PlainSecondsLog", False, None))
11+
self.assertIsNotNone(instantiate_adapter("RebenchLog", False, None))
12+
self.assertIsNotNone(instantiate_adapter("SavinaLog", False, None))
13+
self.assertIsNotNone(instantiate_adapter("Test", False, None))
14+
self.assertIsNotNone(instantiate_adapter("TestExecutor", False, None))
15+
self.assertIsNotNone(instantiate_adapter("Time", False, None))
16+
self.assertIsNotNone(instantiate_adapter("ValidationLog", False, None))
17+
18+
def test_case_insensitive_names(self):
19+
self.assertIsNotNone(instantiate_adapter("RebenchLog", False, None))
20+
self.assertIsNotNone(instantiate_adapter("ReBenchLog", False, None))
21+
self.assertIsNotNone(instantiate_adapter("rebenchlog", False, None))
22+
self.assertIsNotNone(instantiate_adapter("REBENCHLOG", False, None))

0 commit comments

Comments
 (0)