Skip to content

Commit 05de8c0

Browse files
committed
Addressed review comments.
Signed-off-by: L Lakshmanan <s2760012@ed.ac.uk>
1 parent f532247 commit 05de8c0

File tree

14 files changed

+72
-90
lines changed

14 files changed

+72
-90
lines changed

.github/workflows/tools-tests.yaml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,19 @@ jobs:
6464

6565
- name: Profile load check
6666
run: |
67-
tar -xzvf tools/mapper/profile.tar.gz -C tools/mapper/
67+
gzip -d tools/mapper/profile.json.gz -c > tools/mapper/profile.json
6868
python3 -c "import json; json.load(open('tools/mapper/profile.json'))"
6969
7070
- name: Test traces load check
7171
run: |
72-
tar -xzvf tools/mapper/test_files/trace.tar.gz -C tools/mapper/test_files/
7372
python3 tools/mapper/trace_load_test.py -t tools/mapper/test_files/extremes/
7473
7574
- name: Extreme mapping tests
7675
run: |
7776
python3 tools/mapper/mapper.py -t tools/mapper/test_files/extremes -p tools/mapper/profile.json
77+
diff tools/mapper/test_files/extremes/mapper_output.json tools/mapper/test_files/extremes/correct_mapper_output.json
7878
79-
- name: Run mapper tool on sample trace
79+
- name: Run mapper tool on example trace
8080
run: |
81-
python3 tools/mapper/mapper.py -t tools/mapper/test_files/20 -p tools/mapper/profile.json
81+
python3 tools/mapper/mapper.py -t data/traces/example -p tools/mapper/profile.json
82+
diff data/traces/example/mapper_output.json data/traces/example/correct_mapper_output.json
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"c13acdc7567b225971cef2416a3a2b03c8a4d8d154df48afe75834e2f5c59ddfc455703077a17a9b8d0fc655d939fcc6d24d819fa9a1066b74f710c35a43cbc868baea05aa0c3619b6feb78c80a07e27e4e68f921d714b8125f916c3b3370bf2": {
3+
"proxy-function": "video-processing-python-10"
4+
},
5+
"a2faad786b3c813b12ce57d349d5e62f6d0f22ceecfa86cd72a962853383b600d7028b01f2422ea9d4f695cae4085800eb34540674081a46bb4e4388e7995f7ac8b8b9160f181010f509ee0af3266cbcb5a5f4c7700ba8d4396f1147e1ad3bbd": {
6+
"proxy-function": "image-rotate-go-11"
7+
},
8+
"7dc5aeabc131669912e8c793c8925cc9928321f45f13a4af031592b4611630d70728f480194febeddbc0d2a69a2cb38344e495f264d52c62102e7bd99505dbf22cc1c836a3b32265b4a36b6e6f56b2d7c0588a926df5d03a76b7b4388cbf2258": {
9+
"proxy-function": "video-processing-python-100"
10+
},
11+
"ae8a1640fa932024f59b38a0b001808b5c64612bd60c6f3eb80ba9461ba2d09101d1a13d091b0cfc764a125ead054ad6a720cb29b0b1fc2c187e9be3311f09fe90ba6ab2b1b9f5b5925d1e9ee6242d0f840ebcfb3221567bc2b5f24cb864b016": {
12+
"proxy-function": "video-processing-python-10"
13+
}
14+
}

docs/mapper.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Use the mapper tool to map functions in a specific trace directory (with memory and duration traces) to proxy functions in the [`vSwarm`](https://github.com/vhive-serverless/vSwarm/tree/main/) benchmark suite. The benchmarks in the vSwarm suite have been profiled, and their memory utilization and duration traces are stored in the `profile.json` file. The tool maps each function in the trace to its closest proxy in the benchmark suite based on memory and duration correlation.
44

5-
The [`profiler` tool](https://github.com/vhive-serverless/vSwarm/tree/load-generator/tools/profiler#profiler) generates the `profile.json` JSON output file to profile the benchmark suite functions.
5+
The [`profiler` tool](https://github.com/vhive-serverless/vSwarm/tree/load-generator/tools/profiler#profiler) generates the `profile.json` JSON output file to profile the benchmark suite functions. We provide the `profile.json` file as a compressed file in the `tools/mapper` directory.
66

77
### Usage
88

@@ -63,7 +63,7 @@ For every function in the trace, the tool sets the closest function in the [`vSw
6363

6464
vSwarm currently *does not* fully cover the Azure trace functions. To avoid high error in function mapping, we set a hard threshold of 40% as the maximum absolute error (from the actual trace function duration) that a proxy function can have to be mapped to a trace function. If no eligible function is found for mapping from vSwarm, we use standard InVitro trace functions for those functions alone.
6565

66-
The mapper requires the profiles of the vSwarm benchmark functions to identify proxies. The tool uses the `profile.json` JSON output file generated by the [`profiler` tool](https://github.com/vhive-serverless/vSwarm/tree/load-generator/tools/profiler#profiler) to obtain the profile of the benchmark suite functions. We provide a profile file in the `tools/mapper` directory as a tarball and once unzipped, this is used as the default profile. Users can configure the path of the profile file to be used through the `-p` (or `--profile-filepath`) flag.
66+
The mapper requires the profiles of the vSwarm benchmark functions to identify proxies. The tool uses the `profile.json` JSON output file generated by the [`profiler` tool](https://github.com/vhive-serverless/vSwarm/tree/load-generator/tools/profiler#profiler) to obtain the profile of the benchmark suite functions. We provide a profile file in the `tools/mapper` directory as a compressed file and once decompressed, this is used as the default profile. Users can configure the path of the profile file to be used through the `-p` (or `--profile-filepath`) flag.
6767

6868
An example of a generated output file is as follows:
6969

docs/mapper_cdf.png

1.37 KB
Loading

tools/mapper/.gitattributes

Lines changed: 0 additions & 1 deletion
This file was deleted.

tools/mapper/find_proxy_function.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,24 +58,29 @@ def get_closest_proxy_function(
5858
proxy_list.append(proxy_functions[function_name])
5959
proxy_functions[function_name]["index"] = len(proxy_list) - 1
6060

61-
for function_name in trace_functions:
61+
for id in trace_functions:
6262
min_error = math.inf
6363
min_error_index = -1
6464
for i in range(0, len(proxy_list)):
65-
error = get_error(trace_functions[function_name], proxy_list[i])
65+
error = get_error(trace_functions[id], proxy_list[i])
6666
if error < min_error:
6767
min_error = error
6868
min_error_index = i
6969

7070
if min_error == math.inf:
71-
log.warning(f"Proxy function for function {function_name} not found. Using InVitro trace function.")
72-
trace_functions[function_name]["proxy-function"] = "trace-func-go"
71+
log.warning(f"Proxy function for unique id (HashFunction + HashOwner + HashApp) {id} not found. Using InVitro trace function.")
72+
trace_functions[id]["proxy-function"] = "trace-func-go"
7373
continue
7474

75-
trace_functions[function_name]["proxy-function"] = proxy_list[
75+
trace_functions[id]["proxy-function"] = proxy_list[
7676
min_error_index
7777
]["name"]
7878

79+
if abs(trace_functions[id]["duration"]["50-percentile"] - proxy_functions[trace_functions[id]["proxy-function"]]["duration"]["50-percentile"]) > 0.4*trace_functions[id]["duration"]["50-percentile"]:
80+
log.warning(f"Duration error for id {id} above 40%. Using InVitro trace function.")
81+
trace_functions[id]["proxy-function"] = "trace-func-go"
82+
continue
83+
7984
for function_name in proxy_functions:
8085
del proxy_functions[function_name]["index"]
8186

tools/mapper/mapper.py

Lines changed: 18 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -55,52 +55,16 @@ def load_trace(trace_directorypath):
5555
trace_functions = {}
5656

5757
for _, row in duration_info.iterrows():
58-
hash_function = row["HashFunction"]
59-
trace_functions[hash_function] = {}
60-
trace_functions[hash_function]["duration"] = row
58+
unique_id = row["HashFunction"] + row["HashOwner"] + row["HashApp"]
59+
trace_functions[unique_id] = {}
60+
trace_functions[unique_id]["duration"] = row
6161

6262
for _, row in memory_info.iterrows():
63-
hash_function = row["HashFunction"]
64-
trace_functions[hash_function]["memory"] = row
63+
unique_id = row["HashFunction"] + row["HashOwner"] + row["HashApp"]
64+
trace_functions[unique_id]["memory"] = row
6565

6666
return trace_functions, 0
6767

68-
def generate_plot(trace_directorypath, trace_functions, proxy_functions, mapped_trace, invocation_statistics=True):
69-
70-
if invocation_statistics:
71-
invocations = pd.read_csv(trace_directorypath+"/invocations.csv")
72-
inv_df = {}
73-
for i in range(len(invocations)):
74-
inv_df[invocations["HashFunction"][i]] = sum([invocations[col][i] if col not in invocations.columns[0:INVOCATION_COLUMN] else 0 for col in invocations.columns])
75-
76-
trace_durations = []
77-
mapped_durations = []
78-
dropped_functions, dropped_invocations, total_invocations = 0, 0, 0
79-
for trace in trace_functions:
80-
duration = trace_functions[trace]["duration"]["50-percentile"]
81-
if duration > VSWARM_MAX_DUR:
82-
dropped_functions += 1
83-
dropped_invocations += inv_df[trace]
84-
continue
85-
total_invocations += inv_df[trace]
86-
proxy_name = mapped_trace[trace]["proxy-function"]
87-
profile_duration = proxy_functions[proxy_name]["duration"]["50-percentile"]
88-
trace_durations.append(duration)
89-
mapped_durations.append(profile_duration)
90-
return trace_durations, mapped_durations, dropped_functions, (dropped_invocations/total_invocations)*100
91-
else:
92-
trace_durations = []
93-
mapped_durations = []
94-
for trace in trace_functions:
95-
duration = trace_functions[trace]["duration"]["50-percentile"]
96-
if duration > VSWARM_MAX_DUR:
97-
continue
98-
proxy_name = mapped_trace[trace]["proxy-function"]
99-
profile_duration = proxy_functions[proxy_name]["duration"]["50-percentile"]
100-
trace_durations.append(duration)
101-
mapped_durations.append(profile_duration)
102-
return trace_durations, mapped_durations
103-
10468
def main():
10569
# Parse the arguments
10670
parser = argparse.ArgumentParser(description="Mapper")
@@ -160,9 +124,9 @@ def main():
160124

161125
# Only give function name and proxy name
162126
trace_json = {}
163-
for function in trace_functions:
164-
trace_json[function] = {}
165-
trace_json[function]["proxy-function"] = trace_functions[function]["proxy-function"]
127+
for id in trace_functions:
128+
trace_json[id] = {}
129+
trace_json[id]["proxy-function"] = trace_functions[id]["proxy-function"]
166130

167131
try:
168132
with open(output_filepath, "w") as jf:
@@ -173,15 +137,7 @@ def main():
173137
return
174138

175139
log.info(f"Output file {output_filepath} written")
176-
log.info(f"Preliminary load Generation successful. Checking error levels in mapping...")
177-
178-
# Read the mapper output
179-
try:
180-
with open(output_filepath, "r") as jf:
181-
mapper_output = json.load(jf)
182-
except Exception as e:
183-
log.critical(f"Error in loading mapper output file {e}")
184-
return
140+
log.info(f"Load Generation successful. Mapper output generated.")
185141

186142
# Check the memory and duration errors
187143

@@ -195,11 +151,14 @@ def main():
195151
abs_rel_mem_error = 0
196152
abs_rel_dur_error = 0
197153
zero_duration = 0
198-
for function in mapper_output:
199-
trace_mem = trace_functions[function]["memory"]["50-percentile"]
200-
trace_dur = trace_functions[function]["duration"]["50-percentile"]
201-
proxy_dur = proxy_functions[mapper_output[function]["proxy-function"]]["duration"]["50-percentile"]
202-
proxy_mem = proxy_functions[mapper_output[function]["proxy-function"]]["memory"]["50-percentile"]
154+
for id in trace_functions:
155+
if trace_functions[id]["proxy-function"] == "trace-func-go":
156+
dur_count += 1
157+
continue
158+
trace_mem = trace_functions[id]["memory"]["50-percentile"]
159+
trace_dur = trace_functions[id]["duration"]["50-percentile"]
160+
proxy_dur = proxy_functions[trace_functions[id]["proxy-function"]]["duration"]["50-percentile"]
161+
proxy_mem = proxy_functions[trace_functions[id]["proxy-function"]]["memory"]["50-percentile"]
203162
mem_error += trace_mem - proxy_mem
204163
rel_mem_error += (trace_mem - proxy_mem)/trace_mem
205164
abs_mem_error += abs(trace_mem - proxy_mem)
@@ -211,11 +170,8 @@ def main():
211170
else:
212171
rel_dur_error += (trace_dur - proxy_dur)/trace_dur
213172
abs_rel_dur_error += abs((trace_dur - proxy_dur)/trace_dur)
214-
if abs(trace_dur - proxy_dur) > 0.4*trace_dur:
215-
mapper_output[function]["proxy-function"] = "trace-func-go"
216-
dur_count += 1
217173

218-
total_functions = len(mapper_output)
174+
total_functions = len(trace_functions)
219175
log.info(f"Average memory error: {mem_error/total_functions} MB per invocation")
220176
log.info(f"Average duration error: {dur_error/total_functions} ms per invocation")
221177
log.info(f"Average absolute memory error: {abs_mem_error/total_functions} MB per invocation")
@@ -227,18 +183,5 @@ def main():
227183
log.info(f"Duration errors: {dur_count}")
228184
log.info(f"Functions with 0 duration: {zero_duration}")
229185

230-
log.info(f"Replacing the functions with high duration error with invitro functions.")
231-
232-
## Write the updated mapper output
233-
234-
try:
235-
with open(output_filepath, "w") as jf:
236-
json.dump(mapper_output, jf, indent=4)
237-
log.info(f"Updated output file {output_filepath} written. Load generated.")
238-
except Exception as e:
239-
log.critical(f"Output file {output_filepath} cannot be written. Error: {e}")
240-
log.critical(f"Load Generation failed")
241-
return
242-
243186
if __name__ == "__main__":
244187
main()

tools/mapper/profile.json.gz

43.5 KB
Binary file not shown.

tools/mapper/profile.tar.gz

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"fdd2e3c3758d30f677499f1ba3b6c39eb0d7df625a947568503e46e2e60b94e5cf6b17f1e703bc9aa5dde7707333a17f94bf48c2f73c5a37ad046b81e552d2617668725e5528728a76d7e74849fb7c9db7e37c6ba196d294ec53c35887758d0f": {
3+
"proxy-function": "trace-func-go"
4+
},
5+
"f8620c125fb6e77e03d179c91045ae6b1bb69d6a692e75766b5959bff7f7e595215b790f4b1b38b801826384739038dd419f60f8cab9d677e16a628f53848d5082ace503c9cd11b2a34ee63767b2587b15c43ad4c2a60db4d4a038831f3dc009": {
6+
"proxy-function": "fibonacci-nodejs-100000-101000"
7+
},
8+
"4dd18b8612337a03958c30308bd81a96b46d24dc6ef32f60eb1cb687f6291f50710c5bac43705eb08b3434a2d00984a77710c6c19208a73ec62f8680d98a11b213a2239a8f7a35fe6aeda427c30cb982d928922e9366c2b2b4f00cfe9ccb8e35": {
9+
"proxy-function": "fibonacci-nodejs-10000-10100"
10+
}
11+
}

0 commit comments

Comments
 (0)