Skip to content

Commit a908dfc

Browse files
committed
Move changes to collect_results.py.
1 parent a42f0a4 commit a908dfc

File tree

4 files changed

+80
-53
lines changed

4 files changed

+80
-53
lines changed

C/Savina/src/micro/PingPong.lf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ reactor Ping(count:int(1000000)) {
5050
=}
5151
reaction (receive) -> serve, finished {=
5252
if (self->pingsLeft > 0) {
53-
schedule(serve, 0);
53+
lf_schedule(serve, 0);
5454
} else {
5555
// reset pingsLeft for next iteration
5656
self->pingsLeft = self->count;

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ A second script called `collect_results.py` provides a convenient way for collec
121121
```
122122
collects all results from the particular multirun and stores the merged data structure in out.csv. `collect_results.py` not only merges the results, but it also calculates minimum, maximum and median execution time for each individual run. The resulting CSV does not contain the measured values of individual iterations anymore and only contains a single row per run. This behavior can be disabled with the `--raw` command line flag. With the flag set, the results from all runs are merged as say are and the resulting file contains rows for all individual runs, but no minimum, maximum and median values.
123123

124+
As a shortcut, you may alternatively use
125+
```
126+
./collect_results.py latest out.csv
127+
```
128+
to write the latest multirun results to `out.csv`.
124129

125130
## How it works
126131

runner/collect_results.py

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33

44
import argparse
5+
import functools
6+
from itertools import product
57
import pandas as pd
68
import pathlib
79
import os
10+
import json
811

912

1013
def dir_path(string):
@@ -16,14 +19,18 @@ def dir_path(string):
1619

1720
def main():
1821
parser = argparse.ArgumentParser()
19-
parser.add_argument("src_path", type=dir_path)
22+
parser.add_argument("src_path")
2023
parser.add_argument("out_file")
2124
parser.add_argument("--raw", dest="raw", action="store_true")
2225
args = parser.parse_args()
2326

2427
# collect data from all runs
28+
src_path = (
29+
args.src_path if args.src_path != "latest"
30+
else latest_subdirectory(latest_subdirectory("./multirun"))
31+
)
2532
data_frames = []
26-
for path in pathlib.Path(args.src_path).rglob("results.csv"):
33+
for path in pathlib.Path(src_path).rglob("results.csv"):
2734
data_frames.append(pd.read_csv(path.as_posix()))
2835

2936
# determine min, max and median
@@ -42,8 +49,50 @@ def main():
4249
concat = pd.concat(data_frames, ignore_index=True)
4350

4451
# write the concatenated results
45-
concat.to_csv(args.out_file)
52+
if args.out_file.endswith(".json"):
53+
with open(args.out_file, "w") as f:
54+
json.dump((create_json(concat)), f, indent=4)
55+
else:
56+
concat.to_csv(args.out_file)
57+
58+
def create_json(all_data: pd.DataFrame) -> str:
59+
group_by = ["benchmark", "target", "threads", "scheduler"]
60+
name_computer = lambda group: group[0] + " (" + ", ".join(
61+
f"{group_by[i]}={p}"
62+
for i, p in enumerate(group_by[1:])
63+
if len(all_data[p].unique()) > 1
64+
) + ")"
65+
is_correct_group = lambda group: functools.reduce(
66+
lambda a, b: a & b,
67+
[all_data[group_by[i]].values == v for i, v in enumerate(group)]
68+
)
69+
return [
70+
{
71+
"name": name_computer(group),
72+
"unit": "ms",
73+
"value": all_data[is_correct_group(group)].mean_time_ms.mean(),
74+
"extra": f"Target: {group[0]}"
75+
f"\nTotal Iterations: {all_data[is_correct_group(group)].total_iterations.iloc[0]}"
76+
f"\nThreads: {group[2]}"
77+
f"\nScheduler: {group[-1]}"
78+
}
79+
for group in product(*[all_data[p].unique() for p in group_by])
80+
]
81+
82+
def latest_subdirectory(parent):
83+
if parent is None:
84+
raise Exception(f"{parent} does not exist.")
85+
subdirectories = os.listdir(parent)
86+
subdirectories.sort(key=functools.cmp_to_key(compare_dirnames))
87+
if not subdirectories:
88+
raise Exception(f"{parent} is empty.")
89+
return os.path.join(parent, subdirectories[-1])
4690

91+
def compare_dirnames(s0, s1):
92+
for number0, number1 in zip(s0.split("-"), s1.split("-")):
93+
if int(number0) != int(number1):
94+
return number0 - number1
95+
return 0
4796

4897
if __name__ == "__main__":
4998
main()

runner/run_benchmark.py

Lines changed: 22 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import multiprocessing
77
import omegaconf
88
import subprocess
9-
import json
9+
1010

1111
log = logging.getLogger("run_benchmark")
1212

@@ -166,55 +166,28 @@ def execute_command(command):
166166

167167

168168
def write_results(times, cfg):
169-
if not cfg["json"]:
170-
row = {
171-
"benchmark": cfg["benchmark"]["name"],
172-
"target": cfg["target"]["name"],
173-
"total_iterations": cfg["iterations"],
174-
"threads": cfg["threads"],
175-
"iteration": None,
176-
"time_ms": None,
177-
}
178-
# also add all parameters and their values
179-
row.update(cfg["benchmark"]["params"])
180-
if "params" in cfg["target"]:
181-
row.update(cfg["target"]["params"])
182-
183-
with open("results.csv", "w", newline="") as csvfile:
184-
writer = csv.DictWriter(csvfile, fieldnames=row.keys())
185-
writer.writeheader()
186-
i = 0
187-
for t in times:
188-
row["iteration"] = i
189-
row["time_ms"] = t
190-
writer.writerow(row)
191-
i += 1
192-
else:
193-
total_time = 0
169+
row = {
170+
"benchmark": cfg["benchmark"]["name"],
171+
"target": cfg["target"]["name"],
172+
"total_iterations": cfg["iterations"],
173+
"threads": cfg["threads"],
174+
"iteration": None,
175+
"time_ms": None,
176+
}
177+
# also add all parameters and their values
178+
row.update(cfg["benchmark"]["params"])
179+
if "params" in cfg["target"]:
180+
row.update(cfg["target"]["params"])
181+
182+
with open("results.csv", "w", newline="") as csvfile:
183+
writer = csv.DictWriter(csvfile, fieldnames=row.keys())
184+
writer.writeheader()
185+
i = 0
194186
for t in times:
195-
total_time += t
196-
total_time /= cfg["iterations"]
197-
data = {
198-
"name": cfg["benchmark"]["name"],
199-
"unit": "ms",
200-
"value": total_time,
201-
"extra": f"Target: {cfg['target']['name']}\nTotal Iterations: {cfg['iterations']}\nThreads: {cfg['threads']}"
202-
}
203-
204-
try:
205-
with open("../../../benchmark_result.json", "r+") as outfile:
206-
# benchmark_result.json file should be in the multirun directory
207-
# update existing file
208-
contents = json.load(outfile)
209-
contents.append(data)
210-
outfile.seek(0)
211-
json.dump(contents, outfile, indent=4)
212-
213-
except FileNotFoundError:
214-
with open("../../../benchmark_result.json", "w+") as outfile:
215-
# create new file
216-
json.dump([data], outfile, indent=4)
217-
187+
row["iteration"] = i
188+
row["time_ms"] = t
189+
writer.writerow(row)
190+
i += 1
218191

219192

220193
if __name__ == "__main__":

0 commit comments

Comments
 (0)