From a6309ad64515dbf688c71eeedca6f116fba8e2da Mon Sep 17 00:00:00 2001
From: Yifan Zhao <yifanz16@illinois.edu>
Date: Wed, 27 Jan 2021 22:03:49 -0600
Subject: [PATCH] Improved torch2hpvm setup script

---
 hpvm/projects/torch2hpvm/.gitignore           |   3 +-
 hpvm/projects/torch2hpvm/env.yaml             |  10 --
 hpvm/projects/torch2hpvm/main.py              | 107 ------------------
 hpvm/projects/torch2hpvm/setup.py             |  16 +--
 .../torch2hpvm/torch2hpvm/__init__.py         |   2 +
 .../torch2hpvm/torch2hpvm/__main__.py         |  55 +++++++++
 .../projects/torch2hpvm/torch2hpvm/compile.py |  52 +++++++++
 7 files changed, 118 insertions(+), 127 deletions(-)
 delete mode 100644 hpvm/projects/torch2hpvm/env.yaml
 delete mode 100644 hpvm/projects/torch2hpvm/main.py
 create mode 100644 hpvm/projects/torch2hpvm/torch2hpvm/__main__.py
 create mode 100644 hpvm/projects/torch2hpvm/torch2hpvm/compile.py

diff --git a/hpvm/projects/torch2hpvm/.gitignore b/hpvm/projects/torch2hpvm/.gitignore
index 2f4db75f1d..25aacffde0 100644
--- a/hpvm/projects/torch2hpvm/.gitignore
+++ b/hpvm/projects/torch2hpvm/.gitignore
@@ -1,4 +1,3 @@
 build/
 dist/
-onnx2hpvm.egg-info/
-.ipynb_checkpoints/
+*.egg-info/
diff --git a/hpvm/projects/torch2hpvm/env.yaml b/hpvm/projects/torch2hpvm/env.yaml
deleted file mode 100644
index d04bb1b503..0000000000
--- a/hpvm/projects/torch2hpvm/env.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: onnxfront
-channels:
-  - defaults
-dependencies:
-  - pip
-  - python=3.8.5=h7579374_1
-  - jinja2
-  - networkx
-  - pip:
-    - onnx==1.8.0
diff --git a/hpvm/projects/torch2hpvm/main.py b/hpvm/projects/torch2hpvm/main.py
deleted file mode 100644
index 7dc23d4873..0000000000
--- a/hpvm/projects/torch2hpvm/main.py
+++ /dev/null
@@ -1,107 +0,0 @@
-from pathlib import Path
-from typing import Optional
-
-import onnx
-
-
-def check_version(model, new_version):
-    try:
-        opset = model.opset_import[0].version if model.opset_import else 1
-    except AttributeError:
-        opset = 1  # default opset version set to 1 if not specified
-    if opset != new_version:
-        from onnx import version_converter
-
-        try:
-            converted_model = version_converter.convert_version(model, new_version)
-            return converted_model
-        except RuntimeError as e:
-            raise RuntimeError(
-                f"Current version {opset} of ONNX model not supported!\n"
-                f"Conversion failed with message below: \n{e}"
-            )
-    return model
-
-
-def compile(
-    onnx_file: Path,
-    output_dir: Path,
-    input_size: int,
-    prefix: Optional[str],
-    batch_size: Optional[int],
-    opset: Optional[int],
-    hpvmc: bool,
-):
-    from frontend.graph_builder import DFG
-    from frontend.codegen_tensor import TensorCodeGen
-    from frontend.codegen_hpvm import HpvmCodeGen
-
-    model = onnx.load(onnx_file)
-    if opset is not None:
-        model = check_version(model, opset)
-    model = onnx.shape_inference.infer_shapes(model)
-    dfg = DFG(model.graph)
-    if hpvmc:
-        hpvm_code_gen = HpvmCodeGen(dfg, output_dir, input_size, batch_size, prefix)
-        hpvm_code_gen.compile()
-    else:
-        tensor_code_gen = TensorCodeGen(dfg, output_dir, input_size, batch_size, prefix)
-        tensor_code_gen.compile()
-    dfg.dump_weights(output_dir)
-
-
-def parse_args():
-    import argparse
-
-    parser = argparse.ArgumentParser(description="ONNX to HPVM-C")
-    parser.add_argument("onnx_file", type=Path, help="Path to input ONNX file")
-    parser.add_argument(
-        "output_dir",
-        type=Path,
-        help="Output folder where source file and weight files are generated",
-    )
-    parser.add_argument(
-        "input_size", type=int, help="Size of input dataset",
-    )
-    parser.add_argument(
-        "-p",
-        "--prefix",
-        type=str,
-        help="Prefix in generated code; will be attached before name of weight/input files. "
-        "Defaults to output_dir.",
-    )
-    parser.add_argument(
-        "-b",
-        "--batch-size",
-        type=int,
-        help="Batch size to be used in the generated code. "
-        "Defaults to input size (i.e., not using batch).",
-    )
-    parser.add_argument("--opset", type=int, help="ONNX opset version (enforced)")
-    parser.add_argument(
-        "-c",
-        "--compile-mode",
-        type=str,
-        choices=["tensor", "hpvmc"],
-        default="hpvmc",
-        help="""Output mode.
-tensor: HPVM Tensor Runtime;
-hpvmc: HPVM C Interface. Default value is hpvmc.""",
-    )
-
-    args = parser.parse_args()
-    args.hpvmc = args.compile_mode == "hpvmc"
-    delattr(args, "compile_mode")
-    return args
-
-
-def main():
-    import os
-
-    args = parse_args()
-    os.makedirs(args.output_dir, exist_ok=True)
-    compile(**vars(args))
-
-
-if __name__ == "__main__":
-    main()
diff --git a/hpvm/projects/torch2hpvm/setup.py b/hpvm/projects/torch2hpvm/setup.py
index 37dcf5f039..fd21f8b59d 100644
--- a/hpvm/projects/torch2hpvm/setup.py
+++ b/hpvm/projects/torch2hpvm/setup.py
@@ -1,12 +1,12 @@
-
 from setuptools import setup
 
 setup(
-    name='torch2hpvm',
-    version='1.0',
-    description='PyTorch frontend for HPVM',
-    author='Yuanjing Shi, Yifan Zhao',
-    author_email='ys26@illinois.edu, yifanz16@illinois.edu',
-    packages=['torch2hpvm'],
-    install_requires=[],
+    name="torch2hpvm",
+    version="1.0",
+    description="PyTorch frontend for HPVM",
+    author="Yuanjing Shi, Yifan Zhao",
+    author_email="ys26@illinois.edu, yifanz16@illinois.edu",
+    packages=["torch2hpvm"],
+    install_requires=["jinja2>=2.11", "networkx>=2.5", "onnx>=1.8.0"],
+    entry_points={"console_scripts": ["torch2hpvm=torch2hpvm:main"]},
 )
diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/__init__.py b/hpvm/projects/torch2hpvm/torch2hpvm/__init__.py
index e69de29bb2..8e7de3cf9a 100644
--- a/hpvm/projects/torch2hpvm/torch2hpvm/__init__.py
+++ b/hpvm/projects/torch2hpvm/torch2hpvm/__init__.py
@@ -0,0 +1,2 @@
+from .compile import compile
+from .__main__ import main
diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/__main__.py b/hpvm/projects/torch2hpvm/torch2hpvm/__main__.py
new file mode 100644
index 0000000000..8eae267f47
--- /dev/null
+++ b/hpvm/projects/torch2hpvm/torch2hpvm/__main__.py
@@ -0,0 +1,55 @@
+import os
+from pathlib import Path
+
+from .compile import compile
+
+
+def parse_args():
+    import argparse
+
+    parser = argparse.ArgumentParser(description="ONNX to HPVM-C")
+    parser.add_argument("onnx_file", type=Path, help="Path to input ONNX file")
+    parser.add_argument(
+        "output_dir",
+        type=Path,
+        help="Output folder where source file and weight files are generated",
+    )
+    parser.add_argument(
+        "input_size", type=int, help="Size of input dataset",
+    )
+    parser.add_argument(
+        "-p",
+        "--prefix",
+        type=str,
+        help="Prefix in generated code; will be attached before name of weight/input files. "
+        "Defaults to output_dir.",
+    )
+    parser.add_argument(
+        "-b",
+        "--batch-size",
+        type=int,
+        help="Batch size to be used in the generated code. "
+        "Defaults to input size (i.e., not using batch).",
+    )
+    parser.add_argument("--opset", type=int, help="ONNX opset version (enforced)")
+    parser.add_argument(
+        "-c",
+        "--compile-mode",
+        type=str,
+        choices=["tensor", "hpvmc"],
+        default="hpvmc",
+        help="""Output mode.
+tensor: HPVM Tensor Runtime;
+hpvmc: HPVM C Interface. Default value is hpvmc.""",
+    )
+
+    args = parser.parse_args()
+    args.hpvmc = args.compile_mode == "hpvmc"
+    delattr(args, "compile_mode")
+    return args
+
+
+def main():
+    args = parse_args()
+    os.makedirs(args.output_dir, exist_ok=True)
+    compile(**vars(args))
diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/compile.py b/hpvm/projects/torch2hpvm/torch2hpvm/compile.py
new file mode 100644
index 0000000000..694e5f6231
--- /dev/null
+++ b/hpvm/projects/torch2hpvm/torch2hpvm/compile.py
@@ -0,0 +1,52 @@
+from pathlib import Path
+from typing import Optional, Union
+
+import onnx
+from onnx import version_converter
+
+from .codegen_hpvm import HpvmCodeGen
+from .codegen_tensor import TensorCodeGen
+from .graph_builder import DFG
+
+PathLike = Union[Path, str]
+
+
+def check_version(model, new_version):
+    try:
+        opset = model.opset_import[0].version if model.opset_import else 1
+    except AttributeError:
+        opset = 1  # default opset version set to 1 if not specified
+    if opset != new_version:
+
+        try:
+            converted_model = version_converter.convert_version(model, new_version)
+            return converted_model
+        except RuntimeError as e:
+            raise RuntimeError(
+                f"Current version {opset} of ONNX model not supported!\n"
+                f"Conversion failed with message below: \n{e}"
+            )
+    return model
+
+
+def compile(
+    onnx_file: Path,
+    output_dir: Path,
+    input_size: int,
+    prefix: Optional[str],
+    batch_size: Optional[int],
+    opset: Optional[int],
+    hpvmc: bool,
+):
+    model = onnx.load(onnx_file)
+    if opset is not None:
+        model = check_version(model, opset)
+    model = onnx.shape_inference.infer_shapes(model)
+    dfg = DFG(model.graph)
+    if hpvmc:
+        hpvm_code_gen = HpvmCodeGen(dfg, output_dir, input_size, batch_size, prefix)
+        hpvm_code_gen.compile()
+    else:
+        tensor_code_gen = TensorCodeGen(dfg, output_dir, input_size, batch_size, prefix)
+        tensor_code_gen.compile()
+    dfg.dump_weights(output_dir)
-- 
GitLab