diff options
author | Joshua Bakita <jbakita@cs.unc.edu> | 2020-10-16 16:55:14 -0400 |
---|---|---|
committer | Joshua Bakita <jbakita@cs.unc.edu> | 2020-10-16 16:55:14 -0400 |
commit | 6ea9939e0610a809f6f47d13ec68df00d1ca0afc (patch) | |
tree | fe4a2eee3ddcf77e2367309dcd75a232b76dcd62 /dis/gen_input.py | |
parent | e9285d0cdea756a2830f0ace378e4197b36869aa (diff) |
Move the DIS benchmarks up a directory and update hardcoded paths
Note that this repo does not attempt to keep a copy of the original
DIS benchmark distributions. UNC real-time has another repo for that.
Diffstat (limited to 'dis/gen_input.py')
-rwxr-xr-x | dis/gen_input.py | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/dis/gen_input.py b/dis/gen_input.py new file mode 100755 index 0000000..c7821b0 --- /dev/null +++ b/dis/gen_input.py | |||
@@ -0,0 +1,113 @@ | |||
1 | #!/usr/bin/python3 | ||
2 | ##### | ||
3 | # Copyright 2020 Joshua Bakita | ||
4 | # | ||
5 | # This program generates input data for the DIS benchmark suite on stdout | ||
6 | # given a requested working set size. | ||
7 | ##### | ||
8 | |||
9 | |||
10 | from ctypes import sizeof, c_double, c_int, c_short | ||
11 | from math import sqrt, floor | ||
12 | import sys # For argv and stderr | ||
13 | |||
14 | USAGE = """Usage: {} <benchmark> <template> <WSS in bytes>""" | ||
15 | |||
16 | # Check input | ||
17 | if (len(sys.argv) < 4): | ||
18 | print(USAGE.format(sys.argv[0]), file=sys.stderr) | ||
19 | exit(1); | ||
20 | |||
21 | # Don't try to understand the logic in these functions, see WSS_DOCS.md | ||
22 | def setup_field(params, wss): | ||
23 | params[0] = wss | ||
24 | return params | ||
25 | |||
26 | def setup_matrix(params, wss): | ||
27 | nnZR = 0.08 # 8% seems average | ||
28 | # This formula is out of a solver | ||
29 | si = sizeof(c_int) | ||
30 | sd = sizeof(c_double) | ||
31 | d = (sqrt((si**2) * (-(nnZR-1)) - si*sd*(nnZR-9) + si*wss*nnZR + sd*(25*sd+wss*nnZR+wss)) - si - 5*sd) / (si*nnZR + sd*nnZR + sd) | ||
32 | params[1] = floor(d); | ||
33 | params[2] = floor(d*d*nnZR); | ||
34 | if params[1] <= 0 or params[2] <= 0: | ||
35 | raise Exception("WSS too small for matrix benchmark!") | ||
36 | return params | ||
37 | |||
38 | def setup_neighborhood(params, wss): | ||
39 | bitDepth = 8 | ||
40 | bitDepthAlloc = sizeof(c_int) * (2**(bitDepth + 1) - 1) | ||
41 | dim = sqrt((wss - bitDepthAlloc) / sizeof(c_short)) | ||
42 | params[1] = bitDepth | ||
43 | params[2] = floor(dim) | ||
44 | if params[1] <= 0 or params[2] <= 0: | ||
45 | raise Exception("WSS too small for neighborhood benchmark!") | ||
46 | # Cap maximum line thinkness to the image size | ||
47 | params[5] = min(params[2]-1, int(params[5])) | ||
48 | # Cap line lengths to the image size | ||
49 | params[6] = min(params[2]-1, int(params[6])) | ||
50 | params[7] = min(params[2]-1, int(params[7])) | ||
51 | return params | ||
52 | |||
53 | def setup_pointer(params, wss): | ||
54 | n = 10; | ||
55 | f = (wss - sizeof(c_int) * 4 * n) / sizeof(c_int) | ||
56 | params[0] = floor(f) | ||
57 | params[4] = floor(n) | ||
58 | if params[0] <= 0 or params[4] <= 0: | ||
59 | raise Exception("WSS too small for pointer benchmark!") | ||
60 | return params | ||
61 | |||
62 | def setup_transitive(params, wss): | ||
63 | n = sqrt(wss / (sizeof(c_int) * 2)) | ||
64 | params[0] = floor(n) | ||
65 | # Fix edges at 50% | ||
66 | params[1] = floor(params[0] * 0.5) | ||
67 | if params[0] <= 0: | ||
68 | raise Exception("WSS too small for transitive benchmark!") | ||
69 | return params | ||
70 | |||
71 | def setup_update(params, wss): | ||
72 | f = wss / sizeof(c_int) | ||
73 | params[0] = floor(f) | ||
74 | if params[0] <= 0: | ||
75 | raise Exception("WSS too small for update benchmark!") | ||
76 | # Don't do more than 100M hops (keeps time array feasible) | ||
77 | params[2] = min(100000000, int(params[2])) | ||
78 | # Enforce size requirements | ||
79 | params[4] = min(params[0]-1, int(params[4])) | ||
80 | params[5] = min(params[0]-1, int(params[5])) | ||
81 | params[6] = min(params[0]-1, int(params[6])) | ||
82 | return params | ||
83 | |||
84 | def setup_random_walk(params, wss): | ||
85 | params[0] = wss | ||
86 | return params | ||
87 | |||
88 | BENCH_TO_PARAMS = {"field":setup_field, "matrix":setup_matrix, "neighborhood":setup_neighborhood, "pointer":setup_pointer, "transitive":setup_transitive, "update":setup_update, "random_walk":setup_random_walk} | ||
89 | |||
90 | # Main logic | ||
91 | benchmark_name = sys.argv[1] | ||
92 | if benchmark_name not in BENCH_TO_PARAMS.keys(): | ||
93 | print("Invalid benchmark name.", file=sys.stderr) | ||
94 | exit(2) | ||
95 | |||
96 | wss = int(sys.argv[3]) | ||
97 | if wss <= 0: | ||
98 | print("Invalid working set size", file=sys.stderr) | ||
99 | exit(3) | ||
100 | |||
101 | with open(sys.argv[2], "r") as template: | ||
102 | # We expect the initialization params to all be on the first line | ||
103 | params = template.readline().split() | ||
104 | mutated_params = BENCH_TO_PARAMS[benchmark_name](params, wss); | ||
105 | print(" ".join(map(lambda x: str(x), mutated_params))) | ||
106 | print(" ".join(map(lambda x: str(x), mutated_params)), file=sys.stderr) | ||
107 | if benchmark_name == "pointer": | ||
108 | # Clone the data format used in the template | ||
109 | for i in range(0,10): | ||
110 | print("10 " + str(mutated_params[0]-10) + " " + str(mutated_params[0]-10)) | ||
111 | else: | ||
112 | print(template.read()) | ||
113 | |||