diff --git a/hpvm/projects/keras/frontend/hpvm_dfg_translator.py b/hpvm/projects/keras/frontend/hpvm_dfg_translator.py
index 4a3c44a24b393914e17901dc6e214d1cc58046f9..7402bd74925ece9413fa459564238753b8bc91eb 100644
--- a/hpvm/projects/keras/frontend/hpvm_dfg_translator.py
+++ b/hpvm/projects/keras/frontend/hpvm_dfg_translator.py
@@ -17,6 +17,7 @@ class HPVMTranslator:
     self.root_str = ""
     self.root_struct_str = ""
     self.main_func_str = ""
+    self.tuner_main_func_str = ""
     self.file_header_str = ""
     self.hpvm_node_names = {}
     
@@ -709,7 +710,6 @@ class HPVMTranslator:
      main_func_str += "llvm_hpvm_invokeRtControl(result, labels_path.c_str(), start, end); \n"
   
      main_func_str += self.endBatchLoop()
-
      main_func_str += HPVM_cleanup + "(); \n "
   
      ####main_func_str += "computeAccuracy3(labels, result); \n"    
@@ -719,10 +719,51 @@ class HPVMTranslator:
      self.main_func_str += main_func_str
 
 
+
+
+
+  def genTunerMainFunction(self, test_data, batch_size):
+
+     tuner_main_func_str = "int main(int argc, char* argv[]){ \n\n"
+     tuner_main_func_str += self.weight_str
+     tuner_main_func_str += self.input_str
+     tuner_main_func_str += "RootIn* args = static_cast<RootIn*>(malloc(sizeof(RootIn))); \n\n"
+
+     tuner_main_func_str += self.handleTuneTestData()  
+ 
+     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 += "void* dfg = " + HPVM_launch + "(0, root, (void*) args); \n\n"
+     tuner_main_func_str += HPVM_wait + "(dfg); \n\n"
+
+     if LLVM_4_BRANCH:
+       tuner_main_func_str += "void *result = static_cast<RootIn*>(args)->input; \n"
+     elif LLVM_9_BRANCH:
+       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 += "computeAccuracy3(labels, result); \n"
+     tuner_main_func_str += HPVM_cleanup + "(); \n "
   
+     tuner_main_func_str += self.endBatchLoop()
+  
+     tuner_main_func_str += "return 0; \n\n"
+     tuner_main_func_str += "} \n"    
+    
+     self.tuner_main_func_str += tuner_main_func_str
+
+
+     
     
 
-  def generateSourceProgram(self, dir_prefix):
+  def generateTestProgram(self, dir_prefix):
     
     program_str = self.file_header_str + self.node_str + self.root_str
     program_str += self.root_struct_str + self.main_func_str
@@ -733,19 +774,36 @@ class HPVMTranslator:
     f.write(program_str)
     f.close()
 
+
+
+  def generateTunerProgram(self, dir_prefix):
+    
+    program_str = self.file_header_str + self.node_str + self.root_str
+    program_str += self.root_struct_str + self.tuner_main_func_str
+
+    DEBUG (program_str)
+    
+    f = open(dir_prefix + "/approxhpvm_tuner_src.cc", "w+")
+    f.write(program_str)
+    f.close()
+
     
   
   def translate(self, model, src_dir, test_data, tuner_data, batch_size):
 
     self.genFileHeader()
+    
     self.genRootNodeHeader()
     self.genRootStructure()
+    
     self.codegen(self.dfg)
     self.genRootNodeFooter()
+    
     self.genMainFunction(test_data, batch_size)
+    self.genTunerMainFunction(test_data, batch_size)
 
     # dump generated program string to source file
-    self.generateSourceProgram(src_dir)
-    
+    self.generateTestProgram(src_dir)
+    self.generateTunerProgram(src_dir)