Skip to content

Commit a23efef

Browse files
wenyuzhaocaizixian
andauthored
Run minheap with retry (#25)
* Run minheap with retry * Adjustable retry threshold and add documentation Co-authored-by: Zixian Cai <u5937495@anu.edu.au>
1 parent 3a94a1e commit a23efef

File tree

3 files changed

+57
-19
lines changed

3 files changed

+57
-19
lines changed

config/base/minheap.yml

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ includes:
44
- "./modifiers.yml"
55

66
maxheap: 4096
7+
retries: 1

docs/src/commands/minheap.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,14 @@ dacapochopin-69a704e:
4747

4848
## Usage
4949
```console
50-
minheap [-h|--help] CONFIG RESULT
50+
minheap [-h] [-r|--retries RETRIES] CONFIG RESULT
5151
```
5252

5353
`-h`: print help message.
5454

55+
`-r` (preview ⚠️): set the number of retries.
56+
Overrides `retries` in the config file.
57+
5558
`CONFIG`: the path to the configuration file.
5659
This is required.
5760

@@ -62,3 +65,7 @@ This is required.
6265

6366
## Keys
6467
`maxheap`: the upper bound of the search.
68+
69+
`retries` (preview ⚠️): the maximum number of retries before a heap size is deemed too small.
70+
Note that this is only meant to be a workaround of occasional crashes, rather than OOMs.
71+
If an invocation fails with OOM, the respective heap size will be considered as too small immediately.

running/command/minheap.py

+48-18
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import yaml
1111
from running.suite import is_dry_run
1212
from collections import defaultdict
13+
from enum import Enum
1314

1415
configuration: Configuration
1516

@@ -19,9 +20,39 @@ def setup_parser(subparsers):
1920
f.set_defaults(which="minheap")
2021
f.add_argument("CONFIG", type=Path)
2122
f.add_argument("RESULT", type=Path)
23+
f.add_argument("-r", "--retries", type=int)
2224

2325

24-
def minheap_one_bm(suite: JavaBenchmarkSuite, runtime: Runtime, bm: JavaBenchmark, heap: int, minheap_dir: Path) -> float:
26+
class RunResult(Enum):
27+
Passed = 1
28+
FailedWithOOM = 2
29+
Failed = 3
30+
31+
def is_passed(self) -> bool:
32+
return self == RunResult.Passed
33+
34+
35+
def run_bm_with_retry(suite: JavaBenchmarkSuite, runtime: Runtime, bm_with_heapsize: JavaBenchmark, minheap_dir: Path, retries: int) -> RunResult:
36+
def log(s):
37+
return print(s, end="", flush=True)
38+
39+
log(" ")
40+
for _ in range(retries):
41+
output, _ = bm_with_heapsize.run(runtime, cwd=minheap_dir)
42+
if suite.is_passed(output):
43+
log("o ")
44+
return RunResult.Passed
45+
elif suite.is_oom(output):
46+
log("x ")
47+
return RunResult.FailedWithOOM
48+
else:
49+
log(".")
50+
continue
51+
log(" ")
52+
return RunResult.Failed
53+
54+
55+
def minheap_one_bm(suite: JavaBenchmarkSuite, runtime: Runtime, bm: JavaBenchmark, heap: int, minheap_dir: Path, retries: int) -> float:
2556
lo = 2
2657
hi = heap
2758
mid = (lo + hi) // 2
@@ -31,24 +62,19 @@ def minheap_one_bm(suite: JavaBenchmarkSuite, runtime: Runtime, bm: JavaBenchmar
3162
size_str = "{}M".format(mid)
3263
print(size_str, end="", flush=True)
3364
bm_with_heapsize = bm.attach_modifiers([heapsize])
34-
output, _ = bm_with_heapsize.run(
35-
runtime, cwd=minheap_dir)
36-
if suite.is_passed(output):
37-
print(" o ", end="", flush=True)
65+
result = run_bm_with_retry(
66+
suite, runtime, bm_with_heapsize, minheap_dir, retries)
67+
if result.is_passed():
3868
minh = mid
3969
hi = mid
4070
mid = (lo + hi) // 2
4171
else:
42-
if suite.is_oom(output):
43-
print(" x ", end="", flush=True)
44-
else:
45-
print(" ? ", end="", flush=True)
4672
lo = mid
4773
mid = (lo + hi) // 2
4874
return minh
4975

5076

51-
def run_with_persistence(result: Dict[str, Any], minheap_dir: Path, result_file: Optional[Path]):
77+
def run_with_persistence(result: Dict[str, Any], minheap_dir: Path, result_file: Optional[Path], retries: int):
5278
suites = configuration.get("suites")
5379
maxheap = configuration.get("maxheap")
5480
for c in configuration.get("configs"):
@@ -72,7 +98,7 @@ def run_with_persistence(result: Dict[str, Any], minheap_dir: Path, result_file:
7298
print("\t {}-{} ".format(b.suite_name, b.name), end="")
7399
mod_b = b.attach_modifiers(mods)
74100
minheap = minheap_one_bm(
75-
suite, runtime, mod_b, maxheap, minheap_dir)
101+
suite, runtime, mod_b, maxheap, minheap_dir, retries)
76102
print("minheap {}".format(minheap))
77103
result[c_encoded][suite_name][b.name] = minheap
78104
if result_file:
@@ -98,11 +124,12 @@ def print_best(result: Dict[str, Dict[str, Dict[str, float]]]):
98124
for benchmark, best_config in benchmark_configs.items():
99125
config_best_count[best_config] += 1
100126

101-
config, count = max(config_best_count.items(), key=lambda x: x[1])
102-
print("{} obtained the most number of smallest minheap sizes: {}".format(
103-
config, count))
104-
print("Minheap configuration to be copied to runbms config files")
105-
print(yaml.dump(result[config]))
127+
if config_best_count.items():
128+
config, count = max(config_best_count.items(), key=lambda x: x[1])
129+
print("{} obtained the most number of smallest minheap sizes: {}".format(
130+
config, count))
131+
print("Minheap configuration to be copied to runbms config files")
132+
print(yaml.dump(result[config]))
106133

107134

108135
def run(args):
@@ -119,11 +146,14 @@ def run(args):
119146
result = {}
120147
else:
121148
result = {}
149+
retries = configuration.get("retries")
150+
if args.get("retries"):
151+
retries = args.get("retries")
122152
with tempfile.TemporaryDirectory(prefix="minheap-") as minheap_dir:
123153
logging.info("Temporary directory: {}".format(minheap_dir))
124154
if is_dry_run():
125-
run_with_persistence(result, minheap_dir, None)
155+
run_with_persistence(result, minheap_dir, None, retries)
126156
else:
127-
run_with_persistence(result, minheap_dir, result_file)
157+
run_with_persistence(result, minheap_dir, result_file, retries)
128158
print_best(result)
129159
return True

0 commit comments

Comments
 (0)