From e5939060bc78a5104ba74dbb7001a30bf359b9f3 Mon Sep 17 00:00:00 2001
From: Hashim Sharif <hsharif3@miranda.cs.illinois.edu>
Date: Sun, 14 Mar 2021 03:28:41 -0500
Subject: [PATCH] First Compiling Tuner HPVM-C

---
 .../keras/frontend/hpvm_dfg_translator.py     | 119 ++++++++++++++----
 1 file changed, 93 insertions(+), 26 deletions(-)

diff --git a/hpvm/projects/keras/frontend/hpvm_dfg_translator.py b/hpvm/projects/keras/frontend/hpvm_dfg_translator.py
index 7402bd7492..c631b605cb 100644
--- a/hpvm/projects/keras/frontend/hpvm_dfg_translator.py
+++ b/hpvm/projects/keras/frontend/hpvm_dfg_translator.py
@@ -1,4 +1,5 @@
 
+import os
 import sys
 from frontend.utils import *
 from frontend.hpvm_intrinsics import *
@@ -627,12 +628,12 @@ class HPVMTranslator:
 
 
 
-  def genBatchLoop(self, test_data, batch_size):
+  def genBatchLoop(self, data_shape, batch_size):
 
-    chans = test_data.shape[1]
-    width = test_data.shape[2]
-    height = test_data.shape[3]    
-    test_input_size = test_data.shape[0]
+    chans = data_shape[1]
+    width = data_shape[2]
+    height = data_shape[3]    
+    test_input_size = data_shape[0]
 
     func_str = "unsigned int batch_size = " + str(batch_size) + "; \n"
     func_str += "unsigned int test_input_size = " +  str(test_input_size) +  "; \n"
@@ -646,8 +647,17 @@ class HPVMTranslator:
 
     func_str += "unsigned int start = i * batch_size; \n"
     func_str += "unsigned int end = (i + 1) * batch_size;  \n"
-   
-    func_str += "void* input = readInputBatch(input_path.c_str(), 0, start, end," + str(chans) + "," + str(width) + "," + str(height) +  ");  \n\n"
+
+    return func_str 
+    
+
+  def genBatchInput(self, data_shape, input_pth):
+
+    chans = data_shape[1]
+    width = data_shape[2]
+    height = data_shape[3]    
+
+    func_str = "void* input = readInputBatch(" + input_pth + ".c_str(), 0, start, end," + str(chans) + "," + str(width) + "," + str(height) +  ");  \n\n"
    
     func_str += "args->input = input;  \n"
     func_str += "args->input_bytes = 0; \n\n"
@@ -665,7 +675,7 @@ class HPVMTranslator:
 
     return func_str
 
-  # FIXIT
+  
   def handleTuneTestData(self):
 
     input_str = "void* input = test_input; \n"
@@ -696,7 +706,8 @@ class HPVMTranslator:
        main_func_str += "args->" + f_name + " = " + f_name + "; \n"
        main_func_str += "args->" + f_name + "_bytes = 0; \n"       
     
-     main_func_str += self.genBatchLoop(test_data, batch_size)
+     main_func_str += self.genBatchLoop(test_data.shape, batch_size)
+     main_func_str += self.genBatchInput(test_data.shape, "input_path")
     
      main_func_str += "void* dfg = " + HPVM_launch + "(0, root, (void*) args); \n\n"
      main_func_str += HPVM_wait + "(dfg); \n\n"
@@ -712,7 +723,6 @@ class HPVMTranslator:
      main_func_str += self.endBatchLoop()
      main_func_str += HPVM_cleanup + "(); \n "
   
-     ####main_func_str += "computeAccuracy3(labels, result); \n"    
      main_func_str += "return 0; \n\n"
      main_func_str += "} \n"    
     
@@ -720,9 +730,7 @@ class HPVMTranslator:
 
 
 
-
-
-  def genTunerMainFunction(self, test_data, batch_size):
+  def genTunerMainFunction(self, src_dir, test_data, batch_size):    
 
      tuner_main_func_str = "int main(int argc, char* argv[]){ \n\n"
      tuner_main_func_str += self.weight_str
@@ -734,11 +742,19 @@ class HPVMTranslator:
      for f_name in self.filter_names:    
        tuner_main_func_str += "args->" + f_name + " = " + f_name + "; \n"
        tuner_main_func_str += "args->" + f_name + "_bytes = 0; \n"       
-    
-     tuner_main_func_str += self.genBatchLoop(test_data, batch_size)
 
-     tuner_main_func_str += "\n" + HPVM_init + "(); \n"
-     
+     tuner_main_func_str += "\nint ret = 0; \n"
+     tuner_main_func_str += "while ((ret = fifo_wait())) { \n"
+     tuner_main_func_str += "\n" + HPVM_init + "(); \n\n"
+     tuner_main_func_str += "std::string input_pth = (ret == 1 ? test_input_path : tune_input_path); \n"
+     tuner_main_func_str += "std::string labels_pth = (ret == 1 ? test_labels_path : tune_labels_path); \n"
+
+     abs_src_path = str(os.getcwd()) + "/" + src_dir 
+     tuner_main_func_str += "auto* fp = open_fifo(\"" + abs_src_path + "/hpvm_fifo_w\", \"wb\"); \n\n"
+
+     tuner_main_func_str += self.genBatchLoop(test_data.shape, batch_size)
+     tuner_main_func_str += self.genBatchInput(test_data.shape, "input_pth")
+
      tuner_main_func_str += "void* dfg = " + HPVM_launch + "(0, root, (void*) args); \n\n"
      tuner_main_func_str += HPVM_wait + "(dfg); \n\n"
 
@@ -748,20 +764,69 @@ class HPVMTranslator:
        tuner_main_func_str += "void *result = static_cast<RootIn *>(args)->r.tensor; \n"
     
      tuner_main_func_str += "hpvm_request_tensor(result, 0); \n\n"
-     tuner_main_func_str += "uint32_t* labels = readLabelsBatch3(labels_path.c_str(), start, end); \n"
+     tuner_main_func_str += "uint32_t* labels = readLabelsBatch3(labels_pth.c_str(), start, end); \n"
      tuner_main_func_str += "computeAccuracy3(labels, result); \n"
-     tuner_main_func_str += HPVM_cleanup + "(); \n "
-  
+
+     tuner_main_func_str += "\nfifo_write_batch(fp, result); \n"     
+
      tuner_main_func_str += self.endBatchLoop()
+    
+     tuner_main_func_str += HPVM_cleanup + "(); \n "
+
+     tuner_main_func_str += "\n}\n\n"  # End of FIFO loop
   
      tuner_main_func_str += "return 0; \n\n"
      tuner_main_func_str += "} \n"    
     
      self.tuner_main_func_str += tuner_main_func_str
+     
 
+  def addFIFORoutines(self, src_dir):
+
+    FIFO_str = """
+   
+ FILE *open_fifo(const char *path, const char *mode) { 
+  auto* fd = fopen(path, mode);
+  if (!fd) {
+    std::cerr << \"Error opening FIFO file: \" << strerror(errno);
+    abort(); 
+  }
+
+   return fd;
+}
+
+
+int fifo_wait() {
+    auto* fp = open_fifo(\"/tmp/lenet_mnist_tune/hpvm_fifo_r\", \"r\");
+    const int maxn = 100;
+    char linebuf[maxn];
+    fgets(linebuf, maxn, fp);
+    fclose(fp);
+    std::string line(linebuf);
+    if (line == \"test\")
+      return 1;
+    if (line == \"tune\")
+      return 2;
+    if (line == \"stop\")
+      return 0;
+    std::cerr << \"Invalid fifo file content \" << line;
+    abort();
+}
+
+void fifo_write_batch(FILE *fp, void *output_ptr) {
+    auto *output = (Tensor *) output_ptr;
+    const auto &dim = output->dims;
+    size_t num_dims = dim.num_dims;
+    fwrite(&num_dims, sizeof(size_t), 1, fp);
+    fwrite(dim.dim_sizes, sizeof(size_t), dim.num_dims, fp);
+    fwrite(output->host_data, 1, output->size_in_bytes, fp);
+}
+
+"""
+
+    return FIFO_str
+  
 
-     
-    
 
   def generateTestProgram(self, dir_prefix):
     
@@ -776,9 +841,9 @@ class HPVMTranslator:
 
 
 
-  def generateTunerProgram(self, dir_prefix):
+  def generateTunerProgram(self, dir_prefix, FIFO_str):
     
-    program_str = self.file_header_str + self.node_str + self.root_str
+    program_str = self.file_header_str + FIFO_str + self.node_str + self.root_str
     program_str += self.root_struct_str + self.tuner_main_func_str
 
     DEBUG (program_str)
@@ -800,10 +865,12 @@ class HPVMTranslator:
     self.genRootNodeFooter()
     
     self.genMainFunction(test_data, batch_size)
-    self.genTunerMainFunction(test_data, batch_size)
+    self.genTunerMainFunction(src_dir, test_data, batch_size)
 
     # dump generated program string to source file
     self.generateTestProgram(src_dir)
-    self.generateTunerProgram(src_dir)
+
+    FIFO_str = self.addFIFORoutines(src_dir)
+    self.generateTunerProgram(src_dir, FIFO_str)
   
 
-- 
GitLab