From 0ecc55fc41ccf995b37dd33fd5d70ae065e643b7 Mon Sep 17 00:00:00 2001
From: Yifan Zhao <yifanz16@illinois.edu>
Date: Mon, 1 Feb 2021 22:53:04 -0600
Subject: [PATCH] Fixed some bug and passed frontend -> binary test

---
 .../projects/torch2hpvm/torch2hpvm/compile.py |  2 +-
 .../torch2hpvm/template_hpvm.cpp.in           | 26 ++++++----
 .../torch2hpvm/template_tensor.cpp.in         | 22 ++++++---
 .../dnn_benchmarks/pytorch/test_frontend.py   | 49 ++++++++++++-------
 4 files changed, 66 insertions(+), 33 deletions(-)

diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/compile.py b/hpvm/projects/torch2hpvm/torch2hpvm/compile.py
index 59925541bb..a94c16e6d4 100644
--- a/hpvm/projects/torch2hpvm/torch2hpvm/compile.py
+++ b/hpvm/projects/torch2hpvm/torch2hpvm/compile.py
@@ -63,7 +63,7 @@ class ModelExporter:
         self.weight_dir.mkdir(exist_ok=True)
 
         flavor = HpvmCodeGen if hpvmc else TensorCodeGen
-        self.codegen = flavor(self.dfg, output_dir, self.dataset_size)
+        self.codegen = flavor(self.dfg, self.weight_dir, self.dataset_size)
 
     def export_source_code(self, output: PathLike, batch_size: Optional[int] = None):
         self.codegen.compile(output, batch_size)
diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm.cpp.in b/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm.cpp.in
index a7534a7854..d7d62e4216 100644
--- a/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm.cpp.in
+++ b/hpvm/projects/torch2hpvm/torch2hpvm/template_hpvm.cpp.in
@@ -2,7 +2,6 @@
 #include <hpvm.h>
 #include <tensorTypes.h>
 #include <tensorUtils.h>
-#include <config.h>
 
 {% for node in nodes %}
 void var_{{node.idx}}_node(
@@ -22,7 +21,7 @@ t{{n}}{{", " if not loop.last}}
 
 {% endfor -%}
 
-void root(void *__output, {%- for n in root_inputs -%}
+void root({%- for n in root_inputs -%}
 void *{{n}}, size_t {{n}}_bytes{{", " if not loop.last}}
 {%- endfor %}) {
   __hpvm__hint(hpvm::CPU_TARGET);
@@ -34,8 +33,8 @@ void *{{n}}, size_t {{n}}_bytes{{", " if not loop.last}}
   void* var_{{node.idx}} = __hpvm__createNodeND(0, var_{{node.idx}}_node);
 {% for edge in node.edges %}
 {% if edge.is_bindin %}
-  __hpvm__bindIn(var_{{node.idx}}, {{edge.input_idx * 2 + 1}}, {{edge.edge_idx * 2}}, 0);
-  __hpvm__bindIn(var_{{node.idx}}, {{edge.input_idx * 2 + 2}}, {{edge.edge_idx * 2 + 1}}, 0);
+  __hpvm__bindIn(var_{{node.idx}}, {{edge.input_idx * 2}}, {{edge.edge_idx * 2}}, 0);
+  __hpvm__bindIn(var_{{node.idx}}, {{edge.input_idx * 2 + 1}}, {{edge.edge_idx * 2 + 1}}, 0);
 {% else %}
   __hpvm__edge(var_{{edge.input_node}}, var_{{node.idx}}, 1, 0, {{edge.edge_idx * 2}}, 0);
   __hpvm__edge(var_{{edge.input_node}}, var_{{node.idx}}, 1, 1, {{edge.edge_idx * 2 + 1}}, 0);
@@ -53,7 +52,6 @@ struct ret_t {
 };
 
 typedef struct __attribute__((__packed__)) {
-  void *__output;
 {% for n in root_inputs %}
   void *{{n}};
   size_t {{n}}_bytes;
@@ -64,10 +62,20 @@ typedef struct __attribute__((__packed__)) {
 
 const int batch_size = {{batch_size}}, input_size = {{input_size}}, batch_count = input_size / batch_size;
 
-int main(){
+int main(int argc, char *argv[]){
+  if (argc != 2) {
+    std::cout << "Usage: " << argv[0] << " {tune|test}\n";
+    return 1;
+  }
+  std::string arg1 = argv[1];
+  if (arg1 != "tune" && arg1 != "test") {
+    std::cout << "Usage: " << argv[0] << " {tune|test}\n";
+    return 1;
+  }
+
   std::string dir_prefix = "{{prefix}}/";
-  std::string input_path = dir_prefix + "input.bin";
-  std::string labels_path = dir_prefix + "labels32.bin";
+  std::string input_path = dir_prefix + arg1 + "_input.bin";
+  std::string labels_path = dir_prefix + arg1 + "_labels.bin";
 {% for w in weights %}
   std::string {{w.name}}_path = dir_prefix + "{{w.filename}}";
   void* {{w.name}} = readTrainedWeights({{w.name}}_path.c_str(), 0, {{w.shape|join(', ')}});
@@ -88,7 +96,7 @@ int main(){
 
     void* dfg = __hpvm__launch(0, root, (void*) args);
     __hpvm__wait(dfg);
-    void *result = static_cast<RootIn*>(args)->__output;
+    void *result = static_cast<RootIn*>(args)->r.tensor;
     hpvm_request_tensor(result, 0);
 
     uint32_t* labels = readLabelsBatch3(labels_path.c_str(), start, end);
diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/template_tensor.cpp.in b/hpvm/projects/torch2hpvm/torch2hpvm/template_tensor.cpp.in
index 948bba9321..02dff0eb02 100644
--- a/hpvm/projects/torch2hpvm/torch2hpvm/template_tensor.cpp.in
+++ b/hpvm/projects/torch2hpvm/torch2hpvm/template_tensor.cpp.in
@@ -7,13 +7,23 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include "../../tensor_runtime/include/tensor_runtime.h"
-#include "../include/utils.h"
+#include "tensor_runtime.h"
+#include "utils.h"
 
-int main() {
-  std::string dir_prefix = "{{prefix}}";
-  std::string input_path = dir_prefix + "input.bin";
-  std::string labels_path = dir_prefix + "labels.bin";
+int main(int argc, char *argv[]){
+  if (argc != 2) {
+    std::cout << "Usage: " << argv[0] << " {tune|test}\n";
+    return 1;
+  }
+  std::string arg1 = argv[1];
+  if (arg1 != "tune" && arg1 != "test") {
+    std::cout << "Usage: " << argv[0] << " {tune|test}\n";
+    return 1;
+  }
+
+  std::string dir_prefix = "{{prefix}}/";
+  std::string input_path = dir_prefix + arg1 + "_input.bin";
+  std::string labels_path = dir_prefix + arg1 + "_labels.bin";
 {% for w in weights %}
   std::string {{w.name}}_path = dir_prefix + std::string("{{w.filename}}");
   void* {{w.name}} = readTrainedWeights({{w.name}}_path.c_str(), 0, {{w.shape|join(', ')}});
diff --git a/hpvm/test/dnn_benchmarks/pytorch/test_frontend.py b/hpvm/test/dnn_benchmarks/pytorch/test_frontend.py
index 1ca46cd702..96de3db2ed 100644
--- a/hpvm/test/dnn_benchmarks/pytorch/test_frontend.py
+++ b/hpvm/test/dnn_benchmarks/pytorch/test_frontend.py
@@ -1,31 +1,34 @@
 import os
+import shutil
 import site
 from pathlib import Path
-import shutil
+from subprocess import run
+import torch
 
 from torch2hpvm import BinDataset, ModelExporter
+from torch.nn import Module
 
 site.addsitedir(os.path.dirname(__file__))
 import dnn
 
 benchmarks = [
-    (dnn.LeNet, 1, 28, "lenet_mnist"),
-    (dnn.AlexNet, 3, 32, "alexnet_cifar10"),
-    (dnn.AlexNet2, 3, 32, "alexnet2_cifar10"),
-    (dnn.AlexNetImageNet, 3, 224, "alexnet_imagenet"),
-    (dnn.MobileNet, 3, 32, "mobilenet_cifar10"),
-    (dnn.ResNet18, 3, 32, "resnet18_cifar10"),
-    (dnn.ResNet50, 3, 224, "resnet50_imagenet"),
-    (dnn.VGG16Cifar10, 3, 32, "vgg16_cifar10"),
-    (dnn.VGG16Cifar100, 3, 32, "vgg16_cifar100"),
-    (dnn.VGG16ImageNet, 3, 224, "vgg16_imagenet"),
+    (dnn.LeNet, 1, 28, 5000, "lenet_mnist"),
+    (dnn.AlexNet, 3, 32, 5000, "alexnet_cifar10"),
+    (dnn.AlexNet2, 3, 32, 5000, "alexnet2_cifar10"),
+    (dnn.AlexNetImageNet, 3, 224, 500, "alexnet_imagenet"),
+    (dnn.MobileNet, 3, 32, 5000, "mobilenet_cifar10"),
+    (dnn.ResNet18, 3, 32, 5000, "resnet18_cifar10"),
+    (dnn.ResNet50, 3, 224, 100, "resnet50_imagenet"),
+    (dnn.VGG16Cifar10, 3, 32, 5000, "vgg16_cifar10"),
+    (dnn.VGG16Cifar100, 3, 32, 5000, "vgg16_cifar100"),
+    (dnn.VGG16ImageNet, 3, 224, 100, "vgg16_imagenet"),
 ]
 self_folder = Path(__file__).parent
-for model_cls, nch, img_size, pathname in benchmarks:
-    target = Path(f"/tmp/{pathname}")
-    print(f"Generating {pathname} to {target}")
-    if target.exists():
-        shutil.rmtree(target)
+for model_cls, nch, img_size, batch_size, pathname in benchmarks:
+    codegen_dir = Path(f"/tmp/{pathname}")
+    print(f"Generating {pathname} to {codegen_dir}")
+    if codegen_dir.exists():
+        shutil.rmtree(codegen_dir)
     prefix = self_folder / "../model_params" / pathname
     dataset_shape = 5000, nch, img_size, img_size
     bin_tuneset = BinDataset(
@@ -34,4 +37,16 @@ for model_cls, nch, img_size, pathname in benchmarks:
     bin_testset = BinDataset(
         prefix / "test_input.bin", prefix / "test_labels.bin", dataset_shape
     )
-    ModelExporter(model_cls(), bin_tuneset, bin_testset, target, True).export_all()
+    model: Module = model_cls()
+    checkpoint = self_folder / "../model_params" / f"{pathname}.pth.tar"
+    model.load_state_dict(torch.load(checkpoint.as_posix()))
+    exporter = ModelExporter(model, bin_tuneset, bin_testset, codegen_dir, True)
+    exporter.export_all(batch_size=batch_size)
+    build_dir = codegen_dir / "build"
+    target_binary = build_dir / pathname
+    run([
+        "approxhpvm.py", str(codegen_dir / ModelExporter.source_file_name), str(target_binary),
+        "-d", str(build_dir),
+        "-t", "cudnn"
+    ], check=True)
+    run([str(target_binary), "test"], check=True)
-- 
GitLab