TVMC - a command line driver for TVM (#6112)
authorLeandro Nunes <leandro.nunes@arm.com>
Sun, 16 Aug 2020 17:45:44 +0000 (18:45 +0100)
committerGitHub <noreply@github.com>
Sun, 16 Aug 2020 17:45:44 +0000 (10:45 -0700)
* Introduce a command line driver to compile, run and tune models, using TVM graph runtime
 * Include tvmc tests and integrate tvmc with linting, testing and CI
 * RFC: https://discuss.tvm.ai/t/rfc-a-tvm-command-line-interface/5165

Co-authored-by: Marcus Shawcroft <marcus.shawcroft@arm.com>
Co-authored-by: Matthew Barrett <Matthew.Barrett@arm.com>
Co-authored-by: Dmitriy Smirnov <dmitriy.smirnov@arm.com>
Co-authored-by: Luke Hutton <luke.hutton@arm.com>
Co-authored-by: Giuseppe Rossini <giuseppe.rossini@arm.com>
Co-authored-by: Matthew Barrett <matthew.barrett@arm.com>
Co-authored-by: Elen Kalda <elen.kalda@arm.com>
Co-authored-by: Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
Co-authored-by: Jeremy Johnson <jeremy.johnson@arm.com>
Co-authored-by: Ina Dobreva <Ina.Dobreva@arm.com>
Co-authored-by: Marcus Shawcroft <marcus.shawcroft@arm.com>
Co-authored-by: Matthew Barrett <Matthew.Barrett@arm.com>
Co-authored-by: Dmitriy Smirnov <dmitriy.smirnov@arm.com>
Co-authored-by: Luke Hutton <luke.hutton@arm.com>
Co-authored-by: Giuseppe Rossini <giuseppe.rossini@arm.com>
Co-authored-by: Elen Kalda <elen.kalda@arm.com>
Co-authored-by: Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
Co-authored-by: Jeremy Johnson <jeremy.johnson@arm.com>
Co-authored-by: Ina Dobreva <Ina.Dobreva@arm.com>
python/setup.py
python/tvm/driver/tvmc/__init__.py [new file with mode: 0644]
python/tvm/driver/tvmc/__main__.py [new file with mode: 0644]
python/tvm/driver/tvmc/common.py [new file with mode: 0644]
python/tvm/driver/tvmc/main.py [new file with mode: 0644]

index 3205a7c..79d7a81 100644 (file)
@@ -154,6 +154,7 @@ setup(name='tvm',
       version=__version__,
       description="TVM: An End to End Tensor IR/DSL Stack for Deep Learning Systems",
       zip_safe=False,
+      entry_points={"console_scripts": ["tvmc = tvm.driver.tvmc.main:main"]},
       install_requires=[
         'numpy',
         'scipy',
diff --git a/python/tvm/driver/tvmc/__init__.py b/python/tvm/driver/tvmc/__init__.py
new file mode 100644 (file)
index 0000000..13a8339
--- /dev/null
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/python/tvm/driver/tvmc/__main__.py b/python/tvm/driver/tvmc/__main__.py
new file mode 100644 (file)
index 0000000..f72e9f4
--- /dev/null
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""
+TVMC - TVM driver command-line interface
+"""
+
+from .main import main
+
+if __name__ == "__main__":
+    main()
diff --git a/python/tvm/driver/tvmc/common.py b/python/tvm/driver/tvmc/common.py
new file mode 100644 (file)
index 0000000..c9353d4
--- /dev/null
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""
+Common utility functions shared by TVMC modules.
+"""
+
+class TVMCException(Exception):
+    """TVMC Exception"""
diff --git a/python/tvm/driver/tvmc/main.py b/python/tvm/driver/tvmc/main.py
new file mode 100644 (file)
index 0000000..d8083e3
--- /dev/null
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""
+TVMC - TVM driver command-line interface
+"""
+import argparse
+import logging
+import sys
+
+import pkg_resources
+
+from tvm.driver.tvmc.common import TVMCException
+
+
+REGISTERED_PARSER = []
+
+
+def register_parser(make_subparser):
+    """
+    Utility function to register a subparser for tvmc.
+
+    Functions decorated with `tvm.driver.tvmc.main.register_parser` will be invoked
+    with a parameter containing the subparser instance they need to add itself to,
+    as a parser.
+
+    Example
+    -------
+
+        @register_parser
+        def _example_parser(main_subparser):
+            subparser = main_subparser.add_parser('example', help='...')
+            ...
+
+    """
+    REGISTERED_PARSER.append(make_subparser)
+    return make_subparser
+
+
+def _main(argv):
+    """ TVM command line interface. """
+
+    parser = argparse.ArgumentParser(
+        prog='tvmc',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description="TVM compiler driver",
+        epilog=__doc__,
+    )
+    parser.add_argument(
+        "-v", "--verbose", action="count", default=0, help="increase verbosity"
+    )
+    parser.add_argument(
+        "--version", action="store_true", help="print the version and exit"
+    )
+
+    subparser = parser.add_subparsers(title="commands")
+    for make_subparser in REGISTERED_PARSER:
+        make_subparser(subparser)
+
+    args = parser.parse_args(argv)
+    if args.verbose > 4:
+        args.verbose = 4
+
+    logging.getLogger().setLevel(40 - args.verbose * 10)
+
+    if args.version:
+        version = pkg_resources.get_distribution("tvm").version
+        sys.stdout.write("%s\n" % version)
+        return 0
+
+    assert hasattr(args, "func"), "Error: missing 'func' attribute for subcommand {0}".format(argv)
+
+    try:
+        return args.func(args)
+    except TVMCException as err:
+        sys.stderr.write("Error: %s\n" % err)
+        return 4
+
+def main():
+    sys.exit(_main(sys.argv[1:]))
+
+if __name__ == "__main__":
+    main()