From 24c665b4d1b3d6ccb8af56a72d4c6bbd5e71edc7 Mon Sep 17 00:00:00 2001
From: Elizabeth <hashim.sharif91@gmail.com>
Date: Sun, 27 Oct 2019 21:51:28 -0500
Subject: [PATCH] Modified parsing and source code gen to work with new
 configuration

---
 .../source_code_autogenerator.py              | 135 ++++++++++++------
 1 file changed, 93 insertions(+), 42 deletions(-)

diff --git a/llvm/projects/hpvm-tensor-rt/code_autogenerators/source_code_autogenerator.py b/llvm/projects/hpvm-tensor-rt/code_autogenerators/source_code_autogenerator.py
index 0ee30bf36d..91b605f5ab 100644
--- a/llvm/projects/hpvm-tensor-rt/code_autogenerators/source_code_autogenerator.py
+++ b/llvm/projects/hpvm-tensor-rt/code_autogenerators/source_code_autogenerator.py
@@ -10,6 +10,12 @@ import sys
 import os
 import re
 
+class Approx:
+    FP32 = 0
+    FP16 = 1
+    PERF = 2
+    SAMP = 3
+
 class KnobConfiguration:
     '''
     Stores the configurations as well as other useful information for each knob configuration
@@ -24,12 +30,45 @@ class KnobConfiguration:
         Args: raw_config = line of configuration file to parse
         '''
         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):
     '''
@@ -74,6 +113,47 @@ def get_new_function_calls(complete_line, knob_config):
     #print(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):
     '''
@@ -84,50 +164,21 @@ def generate_source_code(table, dir_name, filename, source_name):
         filename: Filename of original source
         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") 
     filename_dir = os.path.dirname(filename)
 
     for knob_config in table:
         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_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()
         print("Generated source code as %s" % new_filename)
     source_file.close()
-- 
GitLab