Skip to content
Snippets Groups Projects
Commit 24c665b4 authored by Elizabeth's avatar Elizabeth
Browse files

Modified parsing and source code gen to work with new configuration

parent c272c647
No related branches found
No related tags found
No related merge requests found
...@@ -10,6 +10,12 @@ import sys ...@@ -10,6 +10,12 @@ import sys
import os import os
import re import re
class Approx:
FP32 = 0
FP16 = 1
PERF = 2
SAMP = 3
class KnobConfiguration: class KnobConfiguration:
''' '''
Stores the configurations as well as other useful information for each knob configuration Stores the configurations as well as other useful information for each knob configuration
...@@ -24,12 +30,45 @@ class KnobConfiguration: ...@@ -24,12 +30,45 @@ class KnobConfiguration:
Args: raw_config = line of configuration file to parse Args: raw_config = line of configuration file to parse
''' '''
line_as_lst = raw_config.strip().split() line_as_lst = raw_config.strip().split()
# approx,<id> knob1,knob2,etc IGNORE old_fun_name new_fun_name
approx_id_lst = line_as_lst[0].split(',')
assert len(approx_id_lst) == 2
self.id = int(approx_id_lst[1])
if approx_id_lst[0] == "fp32":
self.approx = Approx.FP32
return # special case
elif approx_id_lst[0] == "fp16":
self.approx = Approx.FP16
return # special case
elif approx_id_lst[0] == "perf":
self.approx = Approx.PERF
elif approx_id_lst[0] == "samp":
self.approx = Approx.SAMP
self.orig_func_name = line_as_lst[-2] # Second to last element
self.modified_func_name = line_as_lst[-1] # Last element
self.params = line_as_lst[1].split(",") # First element = knob configuration
# DEBUG
def __repr__(self):
if self.approx == Approx.FP32:
return "FP32"
elif self.approx == Approx.FP16:
return "FP16"
approx_type = None
if self.approx == Approx.PERF:
approx_type = "PERF"
elif self.approx == Approx.SAMP:
approx_type = "SAMP"
return "Approx: %s, ID: %d, Orig func nane: %s, Modified func nane: %s, Params: %s" \
% (approx_type, self.id, self.orig_func_name, self.modified_func_name, \
', '.join(self.params))
self.id = int(line_as_lst[0])
self.orig_func_name = line_as_lst[-2]
self.modified_func_name = line_as_lst[-1]
self.params = line_as_lst[1:-2]
def get_new_path(old_path, orig_source_code_dir): def get_new_path(old_path, orig_source_code_dir):
''' '''
...@@ -74,6 +113,47 @@ def get_new_function_calls(complete_line, knob_config): ...@@ -74,6 +113,47 @@ def get_new_function_calls(complete_line, knob_config):
#print(new_line) #print(new_line)
return ''.join(new_line) return ''.join(new_line)
def generate_fp32_source(knob_config, new_file, source_file):
pass
def generate_fp16_source(knob_config, new_file, source_file):
pass
def generate_approx_source(knob_config, new_file, source_file, filename_dir):
new_file_contents = []
# Store complete line to handle cases where one line of code is split into two lines
complete_line = ""
for line in source_file:
# Replace the current path of the local include with a path that's compatible
# with the location of the generated source code
if line.startswith("#"):
include_file = line.split()[1]
if include_file.startswith("\""):
new_include_path = get_new_path(include_file.replace("\"", ""), filename_dir.replace("\"", ""))
new_file_contents.append("#include \"%s\"\n" % new_include_path)
else:
new_file_contents.append(line)
continue
# Handles case where 1 actual line of code is split into 2 lines
elif line.find("}") != -1 or line.find("{") != -1:
complete_line += line
new_file_contents.append(complete_line)
complete_line = ""
continue
elif line.find(";") == -1: # Last char is always \n
complete_line += line
continue
complete_line += line
orig_func_ind = complete_line.find(knob_config.orig_func_name)
if orig_func_ind != -1:
new_file_contents.append(get_new_function_calls(complete_line, knob_config))
else:
new_file_contents.append(complete_line)
complete_line = ""
new_file.write(''.join(new_file_contents))
def generate_source_code(table, dir_name, filename, source_name): def generate_source_code(table, dir_name, filename, source_name):
''' '''
...@@ -84,50 +164,21 @@ def generate_source_code(table, dir_name, filename, source_name): ...@@ -84,50 +164,21 @@ def generate_source_code(table, dir_name, filename, source_name):
filename: Filename of original source filename: Filename of original source
source_name: Filename without the file extension (ex: foo/blah.cc --> blah) source_name: Filename without the file extension (ex: foo/blah.cc --> blah)
''' '''
file_comment = "// AUTO-GENERATED SOURCE CODE. REPLACED ALL INSTANCES OF %s WITH %s\n"
source_file = open(filename, "r") source_file = open(filename, "r")
filename_dir = os.path.dirname(filename) filename_dir = os.path.dirname(filename)
for knob_config in table: for knob_config in table:
source_file.seek(0, 0) source_file.seek(0, 0)
new_file_contents = [file_comment % (knob_config.orig_func_name, knob_config.modified_func_name)]
# Store complete line to handle cases where one line of code is split into two lines
complete_line = ""
for line in source_file:
# Replace the current path of the local include with a path that's compatible
# with the location of the generated source code
if line.startswith("#"):
include_file = line.split()[1]
if include_file.startswith("\""):
new_include_path = get_new_path(include_file.replace("\"", ""), filename_dir.replace("\"", ""))
new_file_contents.append("#include \"%s\"\n" % new_include_path)
else:
new_file_contents.append(line)
continue
# Handles case where 1 actual line of code is split into 2 lines
elif line.find("}") != -1 or line.find("{") != -1:
complete_line += line
new_file_contents.append(complete_line)
complete_line = ""
continue
elif line.find(";") == -1: # Last char is always \n
complete_line += line
continue
complete_line += line
orig_func_ind = complete_line.find(knob_config.orig_func_name)
if orig_func_ind != -1:
new_file_contents.append(get_new_function_calls(complete_line, knob_config))
else:
new_file_contents.append(complete_line)
complete_line = ""
new_filename = os.path.join(dir_name, "%s_%s.cc" % (source_name, knob_config.id)) new_filename = os.path.join(dir_name, "%s_%s.cc" % (source_name, knob_config.id))
new_file = open(new_filename, "w") new_file = open(new_filename, "w")
new_file.write(''.join(new_file_contents))
if knob_config.approx == Approx.FP16:
pass
elif knob_config.approx == Approx.FP32:
pass
else:
generate_approx_source(knob_config, new_file, source_file, filename_dir)
new_file.close() new_file.close()
print("Generated source code as %s" % new_filename) print("Generated source code as %s" % new_filename)
source_file.close() source_file.close()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment