Skip to content

Commit 0f96ef3

Browse files
committed
Added docstrings
1 parent 2dd8269 commit 0f96ef3

File tree

1 file changed

+80
-1
lines changed

1 file changed

+80
-1
lines changed

bench_kernel.py

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
#! /usr/bin/env python3
22

3+
"""GCC per-function phase reorder benchmark kernel
4+
5+
This script serves as a layer between gcc compilation calls
6+
(with phase reorder plugin) and several CompilerGym gcc-multienv environments.
7+
"""
8+
39
import logging
410
import socket
511
from pathlib import Path
@@ -17,6 +23,7 @@
1723

1824

1925
def sigterm_handler(sig, frame):
26+
"""SystemExit exception is then caught to guarantee temporary directory removal"""
2027
exit(1)
2128

2229

@@ -26,6 +33,35 @@ def sigterm_handler(sig, frame):
2633

2734
class MultienvBenchKernel:
2835
def __init__(self, env_socket, gcc_socket):
36+
"""
37+
Parses command-line arguments and initializes kernel instance
38+
39+
Function arguments:
40+
env_socket, gcc_socket -- UNIX datagram socket instances (not bound)
41+
42+
Command line arguments:
43+
-r, --run
44+
Arguments to pass to bench when running it
45+
46+
-b, --build
47+
Additional arguments to pass to GCC
48+
49+
-n, --name
50+
Name of the benchmark, impacts socket names (<name>:backend_<instance>)
51+
52+
-i, --instance
53+
Instance number of benchmark, impacts socket names (<name>:backend_<instance>)
54+
55+
--repeats
56+
Number of times that benchmark is run to profile for runtimes
57+
58+
-p, --plugin
59+
Path to phase reorder plugin .so
60+
61+
Kernel expects all files required for benchmark build and run to already be placed into working dir
62+
It also parses benchmark_info.txt file to get all possible symbol names
63+
(used when checking for alive, but afk environments)
64+
"""
2965
logging.debug("KERNEL: init start")
3066
self.parser = argparse.ArgumentParser()
3167
self.parser.add_argument(
@@ -95,6 +131,10 @@ def __init__(self, env_socket, gcc_socket):
95131
logging.debug("KERNEL: init end")
96132

97133
def final_cleanup(self, e):
134+
"""
135+
Function that removes working directory (only if /tmp or /run)
136+
and prints all pass lists if exited with error or on signal
137+
"""
98138
if isinstance(e, SystemExit) and e.code == 1:
99139
print(self.active_funcs_lists, file=sys.stderr, flush=True)
100140
if self.gcc_instance != None:
@@ -109,6 +149,10 @@ def final_cleanup(self, e):
109149
os.unlink(self.socket_name)
110150

111151
def sendout_profiles(self):
152+
"""
153+
Send collected embeddings, size and runtime data to environments that have provided
154+
lists before compilation start
155+
"""
112156
for fun_name in self.active_funcs_lists:
113157
func_env_address = (
114158
f"\0{self.args.bench_name}:{fun_name}_{self.args.instance}"
@@ -140,6 +184,9 @@ def sendout_profiles(self):
140184
)
141185

142186
def get_sizes(self):
187+
"""
188+
Parses nm output to get symbol sizes
189+
"""
143190
size_info = (
144191
run(
145192
"${AARCH_PREFIX}nm --print-size --size-sort --radix=d main.elf",
@@ -155,6 +202,10 @@ def get_sizes(self):
155202
self.sizes[self.encode_fun_name(pieces[3])] = int(pieces[1])
156203

157204
def get_runtimes(self):
205+
"""
206+
Runs instrumented benchmarks, sums their runtime data using gprof
207+
and parses its output for runtime information
208+
"""
158209
run(
159210
"${AARCH_PREFIX}nm --extern-only --defined-only -v --print-file-name pg_main.elf > symtab",
160211
shell=True,
@@ -201,6 +252,10 @@ def get_runtimes(self):
201252
)
202253

203254
def compile_instrumented(self):
255+
"""
256+
Compiles benchmarks using received lists and with enabled -pg flag
257+
(for per-function runtime profiling)
258+
"""
204259
self.gcc_instance = Popen(
205260
self.gprof_build_str, shell=True
206261
) # Compile with gprof to get per-function runtime info
@@ -242,6 +297,10 @@ def compile_instrumented(self):
242297
exit(1)
243298

244299
def encode_fun_name(self, fun_name):
300+
"""
301+
If needed, hashes symbol name and encodes it in base64 to fit into
302+
108 characters socket addr length limitation
303+
"""
245304
fun_name = fun_name.partition(".")[0]
246305
avail_length = (
247306
107 - len(self.args.bench_name) - len(str(self.args.instance)) - 2
@@ -255,6 +314,9 @@ def encode_fun_name(self, fun_name):
255314
return fun_name
256315

257316
def validate_addr(self, parsed_addr):
317+
"""
318+
Checks if addres matches kernel benchmark name, instance number and symbol list
319+
"""
258320
if parsed_addr[1] != self.args.bench_name:
259321
print(
260322
f"Got message from env with incorrect bench name. "
@@ -278,11 +340,21 @@ def validate_addr(self, parsed_addr):
278340
exit(1)
279341

280342
def add_env_to_list(self, pass_list, addr):
343+
"""
344+
Parses address, validates it and adds received pass list to
345+
dictionary of lists to be used during next compilation cycle
346+
"""
281347
parsed_addr = re.match("\0(.*):(.*)_(\d*)", addr.decode("utf-8"))
282348
self.validate_addr(parsed_addr)
283349
self.active_funcs_lists[parsed_addr[2]] = pass_list
284350

285351
def gather_active_envs(self):
352+
"""
353+
Receives pass lists from envs and closes kernel if no active envs were detected after a minute delay
354+
355+
When the first list is received, sets 5 second socket timeout to
356+
give other envs a chance to send their lists and returns after no new lists were received in this timeout
357+
"""
286358
while True:
287359
self.active_funcs_lists = {}
288360

@@ -320,8 +392,10 @@ def gather_active_envs(self):
320392
exit(0)
321393

322394
def compile_for_size(self):
395+
"""
396+
Compiles benchmark with received lists and record embeddings
397+
"""
323398
self.embeddings = {}
324-
325399
self.gcc_instance = Popen(
326400
self.build_str, shell=True
327401
) # Compile without gprof do all the compilation stuff
@@ -371,6 +445,11 @@ def compile_for_size(self):
371445
exit(1)
372446

373447
def kernel_loop(self):
448+
"""
449+
Main kernel loop, which also catches exceptions
450+
(including SystemExit, KeyboardInterrupt and that from SIGTERM signal)
451+
and calls final_cleanup() when exception is caught
452+
"""
374453
try:
375454
while True:
376455
logging.debug("KERNEL: compilation cucle")

0 commit comments

Comments
 (0)