diff --git a/apps/README.md b/apps/README.md
index cad9b30220730..bf8d95276af39 100644
--- a/apps/README.md
+++ b/apps/README.md
@@ -26,4 +26,4 @@ If you are interested in writing optimized kernels with TVM, checkout [TOPI: TVM
- [android_rpc](android_rpc) Android RPC server.
- [benchmark](benchmark) Example end to end compilation benchmarks
- [howto_deploy](howto_deploy) Tutorial on how to deploy TVM with minimum code dependency.
-- [wasm-dlbackend-tvm](wasm-dlbackend-tvm) WebAssembly backend for deep learning framework with TVM runtime.
+- [wasm-graphcompiler-tvm](wasm-graphcompiler-tvm) WebAssembly graph compiler for deep learning framework with TVM runtime.
diff --git a/apps/wasm-dlbackend-tvm/README.md b/apps/wasm-dlbackend-tvm/README.md
deleted file mode 100644
index 42e29081606a8..0000000000000
--- a/apps/wasm-dlbackend-tvm/README.md
+++ /dev/null
@@ -1,137 +0,0 @@
-# WebAssembly Backend for Deep Learning Framework with TVM Runtime
-
-#### Experimental notice: This project is still *experimental* and only serves as a proof of concept for running deep learning frameworks (such like [MindSpore](https://github.com/mindspore-ai/mindspore)) on [WebAssembly runtime](https://github.com/bytecodealliance/wasmtime) with [TVM stack](https://tvm.apache.org/).
-
-- [WebAssembly Backend for Deep Learning Framework with TVM Runtime](#webassembly-backend-for-deep-learning-framework-with-tvm-runtime)
- - [Motivation](#motivation)
- - [Framework Landscape](#framework-landscape)
- - [Project Status](#project-status)
- - [PoC Guidelines](#poc-guidelines)
- - [Pre-installation](#pre-installation)
- - [Build wasm-dlbackend-tvm package](#build-wasm-dlbackend-tvm-package)
- - [Test](#test)
- - [Future Work](#future-work)
- - [Operator enhancement](#operator-enhancement)
- - [Performance benchmark](#performance-benchmark)
- - [Native TVM Rust runtime support](#native-tvm-rust-runtime-support)
- - [Appendix](#appendix)
- - [System packages install](#system-packages-install)
- - [Contribution](#contribution)
-
-## Motivation
-
-
-
-As demonstrated in TVM runtime [tutorials](https://tvm.apache.org/docs/tutorials/relay_quick_start.html), TVM already supports WASM as the optional hardware backend, so we can leverage the features of WebAssembly (portability, security) and TVM runtime (domain-specific, optimization) to build a flexible and auto-optimized operator backend for all deep learning frameworks.
-
-## Framework Landscape
-
-The figure below demonstrates the whole landscape of running deep learning framework on WASM runtime with TVM compiler stack.
-```
- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
-| | _ _ _ _ _ _ _ _ _ _ _
-| Framework Frontend Expression | | |
-|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _| | TVM (TE) Python API |
- || |_ _ _ _ _ _ _ _ _ _ _|
- \/ ||
- _ _ _ _ _ _ _ _ _ _ _ _ _ _ \/
- | | _ _ _ _ _ _ _ _ _ _ _
- | Framework WASM Backend | | |
- | (WASM runtime) | | TVM Compiler Stack |
- |_ _ _ _ _ _ _ _ _ _ _ _ _ _| |_ _ _ _ _ _ _ _ _ _ _|
- || ||
- \/ \/
- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
- | | | | llvm-ar | |
- | TVM Runtime | <--- | libops_wasm32.a | <------- | add.o sub.o |
- |_ _ _ _ _ _ _ _| |_ _ _ _ _ _ _ _ _| |_ _ _ _ _ _ _|
-```
-
-## Project Status
-
-This project should be considered **experimental** at the very early stage, all rich features are under active development. Here is the current operator support matrix:
-
-| Operator Name | FP32 | INT32 | INT8 |
-| ------------- | ---- | ----- | ---- |
-| Add | ✔️ |
— | — |
-| Sub | ✔️ | — | — |
-
-**NOTICE**: Currently this project is ONLY tested on Ubuntu system, so `Ubuntu 16.04+` should be prepared as the testing environment.
-
-## PoC Guidelines
-
-### Pre-installation
-
-* Rust
-
- Before running this demo, please make sure [Rust](#system-packages-install) has been installed.
-
- After Rust installed, execute the code below to add `wasm32-wasi` target:
- ```shell
- rustup target add wasm32-wasi
- cargo install cargo-wasi
- ```
-
-* TVM
-
- Please follow TVM [installations](https://tvm.apache.org/docs/install/index.html), `export TVM_HOME=/path/to/tvm` and add `libtvm_runtime` to your `LD_LIBRARY_PATH`.
-
- *Note:* To run the end-to-end examples and tests, `tvm` and `topi` need to be added to your `PYTHONPATH` or it's automatic via an Anaconda environment when it is installed individually.
-
-### Build wasm-dlbackend-tvm package
-
-```shell
-cd wasm-dlbackend-tvm && cargo wasi build --release
-```
-
-### Test
-
-Run the command below to install the frontend package for testing (`rust` REQUIRED):
-```shell
-cd wasm-dlfrontend/ && cargo build --release
-cp ./target/release/wasm-dlfrontend /usr/local/bin/
-```
-
-Check the usage of `wasm-dlfrontend`:
-
-```shell
-~# wasm-dlfrontend -h
-
-Usage: wasm-dlfrontend [options]
-
-Options:
- -c, --ms-backend-config FILE_PATH
- set wasm backend config file
- -o, --op-type VALUE set the operator type, currently ONLY support Add and
- Sub, default: Add.
- -h, --help print this help menu
-```
-
-## Future Work
-
-### Operator enhancement
-TODO
-
-### Performance benchmark
-TODO
-
-### Native TVM Rust runtime support
-TODO
-
-## Appendix
-
-### System packages install
-
-* Rust (latest version)
-
- If you are running Windows, to install Rust, download and run the [RUST-INIT.EXE](https://win.rustup.rs/), and then follow the onscreen instructions.
-
- If you are a Linux user, run the following in your terminal, then follow the on-screen instructions to install Rust.
-
- ```shell
- curl https://sh.rustup.rs -sSf | sh
- ```
-
-## Contribution
-
-Lastly very thanks [@kazum](https://github.com/kazum) for having offered a lot of help when implementing this project.
diff --git a/apps/wasm-dlbackend-tvm/build.rs b/apps/wasm-dlbackend-tvm/build.rs
deleted file mode 100644
index 20507fd0dd545..0000000000000
--- a/apps/wasm-dlbackend-tvm/build.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use std::{path::PathBuf, process::Command};
-
-fn main() {
- let mut out_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
- out_dir.push("lib");
-
- if !out_dir.is_dir() {
- std::fs::create_dir(&out_dir).unwrap();
- }
-
- Command::new(concat!(
- env!("CARGO_MANIFEST_DIR"),
- "/tools/build_ops_lib.py"
- ))
- .arg(&out_dir)
- .output()
- .expect("Failed to execute command!");
-
- let ar = option_env!("LLVM_AR").unwrap_or("llvm-ar-10");
- let add_obj_file = out_dir.join("add.o");
- let sub_obj_file = out_dir.join("sub.o");
- let lib_file = out_dir.join("libops_wasm32.a");
- Command::new(ar)
- .arg("rcs")
- .arg(&lib_file)
- .arg(&add_obj_file)
- .arg(&sub_obj_file)
- .output()
- .expect("Failed to execute command!");
-
- println!("cargo:rustc-link-search=native={}", out_dir.display());
-}
diff --git a/apps/wasm-dlbackend-tvm/src/lib.rs b/apps/wasm-dlbackend-tvm/src/lib.rs
deleted file mode 100644
index acc1937da4153..0000000000000
--- a/apps/wasm-dlbackend-tvm/src/lib.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-#[macro_use]
-extern crate serde_derive;
-#[macro_use]
-extern crate tvm_runtime;
-
-mod ops;
-use ops::types::Status;
-mod utils;
-
-#[no_mangle]
-pub extern "C" fn run(op_type: i32, in_addr: i32, in_size: i32, out_addr: i32) -> i32 {
- let inputs = utils::load_inputs(in_addr, in_size as usize);
- if ops::validate_inputs(&inputs) != Status::Succeed {
- return 0i32;
- }
-
- let op_instance = ops::operator_instantiate(op_type);
- let (a_shape, b_shape, c_shape) = ops::parse_inputs_shape(&inputs);
- if op_instance.init(a_shape, b_shape, c_shape) != Status::Succeed {
- return 0i32;
- };
-
- let (in_tensors, out_tensor) = ops::parse_inputs_tensor(&inputs);
- let (stat, output) = op_instance.launch(in_tensors, out_tensor);
- if stat != Status::Succeed {
- return 0i32;
- }
-
- let out_size = utils::store_output(out_addr, output);
- out_size as i32
-}
diff --git a/apps/wasm-dlbackend-tvm/src/ops/add.rs b/apps/wasm-dlbackend-tvm/src/ops/add.rs
deleted file mode 100644
index cf9320be691ec..0000000000000
--- a/apps/wasm-dlbackend-tvm/src/ops/add.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-use super::types::*;
-use tvm_runtime::{Module as _, SystemLibModule};
-
-extern "C" {
- fn __wasm_call_ctors();
-}
-
-pub struct TVMAddOp {}
-
-impl TVMAddOp {
- pub fn new() -> Self {
- Self {}
- }
-}
-
-impl Operator for TVMAddOp {
- fn init(&self, a_shape: Vec, b_shape: Vec, c_shape: Vec) -> Status {
- if !((a_shape.len() == b_shape.len()
- && a_shape
- .iter()
- .zip(&b_shape)
- .filter(|&(a, b)| a == b)
- .count()
- == a_shape.len())
- && (b_shape.len() == c_shape.len()
- && b_shape
- .iter()
- .zip(&c_shape)
- .filter(|&(b, c)| b == c)
- .count()
- == c_shape.len()))
- {
- println!("Both dimension size and shape for Add operator should be equal!");
- return Status::InitFailed;
- }
-
- println!("TVM Add operator init success!");
- Status::Succeed
- }
-
- fn launch(&self, mut inputs: Vec, output: Tensor) -> (Status, Tensor) {
- if inputs.len() != 2 {
- println!("Inputs tensor length should be 2!");
- return (Status::LaunchFailed, Tensor::default());
- }
- let mut l_tensor = inputs.get_mut(0).unwrap().as_dltensor();
- let mut r_tensor = inputs.get_mut(1).unwrap().as_dltensor();
- let mut out_tensor = output.as_dltensor();
-
- unsafe {
- // This is necessary to invoke TVMBackendRegisterSystemLibSymbol
- // API calls.
- __wasm_call_ctors();
- }
- let syslib = SystemLibModule::default();
- let add = syslib.get_function("add").expect("add function not found!");
- call_packed!(add, &mut l_tensor, &mut r_tensor, &mut out_tensor).unwrap();
-
- let output: Tensor = out_tensor.into();
- println!("TVM Add operator run success!");
- (Status::Succeed, output)
- }
-}
diff --git a/apps/wasm-dlbackend-tvm/src/ops/mod.rs b/apps/wasm-dlbackend-tvm/src/ops/mod.rs
deleted file mode 100644
index c4188b46fcafc..0000000000000
--- a/apps/wasm-dlbackend-tvm/src/ops/mod.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-mod add;
-use add::TVMAddOp;
-mod sub;
-use sub::TVMSubOp;
-pub mod types;
-use types::*;
-
-use std::boxed::Box;
-
-pub fn operator_instantiate(op_type: i32) -> Box {
- match OpType::from(op_type) {
- OpType::Add => Box::new(TVMAddOp::new()),
- OpType::Sub => Box::new(TVMSubOp::new()),
- }
-}
-
-pub fn validate_inputs(inputs: &Vec) -> Status {
- if (inputs.len() == 3
- && !(inputs[0].dtype() == inputs[1].dtype() && inputs[0].dtype() == inputs[2].dtype()))
- || (inputs.len() == 2 && inputs[0].dtype() != inputs[1].dtype())
- {
- println!("The dtype of inputs and outputs is not equal!");
- Status::ValidateFailed
- } else {
- Status::Succeed
- }
-}
-
-pub fn parse_inputs_shape(inputs: &Vec) -> (Vec, Vec, Vec) {
- if inputs.len() == 3 {
- (inputs[0].shape(), inputs[1].shape(), inputs[2].shape())
- } else {
- (inputs[0].shape(), inputs[1].shape(), Vec::new())
- }
-}
-
-pub fn parse_inputs_tensor(inputs: &Vec) -> (Vec, Tensor) {
- if inputs.len() == 3 {
- (
- vec![inputs[0].clone(), inputs[1].clone()],
- inputs[2].clone(),
- )
- } else {
- (vec![inputs[0].clone()], inputs[1].clone())
- }
-}
diff --git a/apps/wasm-dlbackend-tvm/src/ops/sub.rs b/apps/wasm-dlbackend-tvm/src/ops/sub.rs
deleted file mode 100644
index 6e1f3aac78c9e..0000000000000
--- a/apps/wasm-dlbackend-tvm/src/ops/sub.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-use super::types::*;
-use tvm_runtime::{Module as _, SystemLibModule};
-
-extern "C" {
- fn __wasm_call_ctors();
-}
-
-pub struct TVMSubOp {}
-
-impl TVMSubOp {
- pub fn new() -> Self {
- Self {}
- }
-}
-
-impl Operator for TVMSubOp {
- fn init(&self, a_shape: Vec, b_shape: Vec, c_shape: Vec) -> Status {
- if !((a_shape.len() == b_shape.len()
- && a_shape
- .iter()
- .zip(&b_shape)
- .filter(|&(a, b)| a == b)
- .count()
- == a_shape.len())
- && (b_shape.len() == c_shape.len()
- && b_shape
- .iter()
- .zip(&c_shape)
- .filter(|&(b, c)| b == c)
- .count()
- == c_shape.len()))
- {
- println!("Both dimension size and shape for Sub operator should be equal!");
- return Status::InitFailed;
- }
-
- println!("TVM Sub operator init success!");
- Status::Succeed
- }
-
- fn launch(&self, mut inputs: Vec, output: Tensor) -> (Status, Tensor) {
- if inputs.len() != 2 {
- println!("Inputs tensor length should be 2!");
- return (Status::LaunchFailed, Tensor::default());
- }
- let mut l_tensor = inputs.get_mut(0).unwrap().as_dltensor();
- let mut r_tensor = inputs.get_mut(1).unwrap().as_dltensor();
- let mut out_tensor = output.as_dltensor();
-
- unsafe {
- // This is necessary to invoke TVMBackendRegisterSystemLibSymbol
- // API calls.
- __wasm_call_ctors();
- }
- let syslib = SystemLibModule::default();
- let sub = syslib.get_function("sub").expect("sub function not found!");
- call_packed!(sub, &mut l_tensor, &mut r_tensor, &mut out_tensor).unwrap();
-
- let output: Tensor = out_tensor.into();
- println!("TVM Sub operator run success!");
- (Status::Succeed, output)
- }
-}
diff --git a/apps/wasm-dlbackend-tvm/tools/build_ops_lib.py b/apps/wasm-dlbackend-tvm/tools/build_ops_lib.py
deleted file mode 100644
index e7a85ea1adc73..0000000000000
--- a/apps/wasm-dlbackend-tvm/tools/build_ops_lib.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env python3
-"""Prepares a simple TVM library for operators."""
-
-from os import path as osp
-import sys
-
-import tvm
-from tvm import te
-
-
-def add():
- n = te.var('n')
- A = te.placeholder((n,), name='A')
- B = te.placeholder((n,), name='B')
- C = te.compute(A.shape, lambda *i: A(*i) + B(*i), name='C')
- s = tvm.te.create_schedule(C.op)
- s[C].parallel(s[C].op.axis[0])
- m = tvm.lower(s, [A, B, C], name="add", simple_mode=True)
- tvm.build(m, target="llvm -target=wasm32-unknown-unknown --system-lib").save(osp.join(sys.argv[1], 'add.o'))
-
-
-def sub():
- n = te.var('n')
- A = te.placeholder((n,), name='A')
- B = te.placeholder((n,), name='B')
- C = te.compute(A.shape, lambda *i: A(*i) - B(*i), name='C')
- s = tvm.te.create_schedule(C.op)
- s[C].parallel(s[C].op.axis[0])
- m = tvm.lower(s, [A, B, C], name="sub", simple_mode=True)
- tvm.build(m, target="llvm -target=wasm32-unknown-unknown --system-lib").save(osp.join(sys.argv[1], 'sub.o'))
-
-
-if __name__ == '__main__':
- add()
- sub()
diff --git a/apps/wasm-dlbackend-tvm/wasm-dlfrontend/Cargo.toml b/apps/wasm-dlbackend-tvm/wasm-dlfrontend/Cargo.toml
deleted file mode 100644
index e5174f91e065c..0000000000000
--- a/apps/wasm-dlbackend-tvm/wasm-dlfrontend/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "wasm-dlfrontend"
-version = "0.1.0"
-authors = ["leonwanghui "]
-edition = "2018"
-
-[dependencies]
-wasmtime = "0.17.0"
-wasmtime-wasi = "0.17.0"
-anyhow = "1.0.30"
-serde = "1.0.53"
-serde_json = "1.0.53"
-serde_derive = "1.0.53"
-getopts = "0.2.21"
-ndarray = "0.12"
diff --git a/apps/wasm-dlbackend-tvm/wasm-dlfrontend/src/main.rs b/apps/wasm-dlbackend-tvm/wasm-dlfrontend/src/main.rs
deleted file mode 100644
index 0c4cc5f4f9564..0000000000000
--- a/apps/wasm-dlbackend-tvm/wasm-dlfrontend/src/main.rs
+++ /dev/null
@@ -1,132 +0,0 @@
-#[macro_use]
-extern crate serde_derive;
-
-pub mod types;
-use types::*;
-
-use anyhow::Result;
-use getopts::Options;
-use ndarray::Array;
-use serde_json;
-use std::env;
-use wasmtime::*;
-use wasmtime_wasi::{Wasi, WasiCtx};
-
-fn print_usage(program: &str, opts: Options) {
- let brief = format!("Usage: {} [options]", program);
- print!("{}", opts.usage(&brief));
-}
-
-fn main() {
- let args: Vec = env::args().collect();
- let program = args[0].clone();
-
- let mut opts = Options::new();
- opts.optopt(
- "c",
- "ms-backend-config",
- "set wasm backend config file",
- "FILE_PATH",
- );
- opts.optopt(
- "o",
- "op-type",
- "set the operator type, currently ONLY support Add and Sub, default: Add.",
- "VALUE",
- );
-
- opts.optflag("h", "help", "print this help menu");
- let matches = match opts.parse(&args[1..]) {
- Ok(m) => m,
- Err(f) => panic!(f.to_string()),
- };
- if matches.opt_present("h") {
- print_usage(&program, opts);
- return;
- }
- let wasm_backend_file: String = match matches.opt_str("c") {
- Some(s) => s,
- None => String::from("/opt/ms-backend-wasm/wasm_backend_tvm.wasi.wasm"),
- };
- let op_type_str: String = match matches.opt_str("o") {
- Some(s) => s,
- None => String::from("Add"),
- };
- let op_type: i32 = match op_type_str.as_str() {
- "Add" => 0,
- "Sub" => 1,
- _ => 0,
- };
- let a = Array::from_vec(vec![1f32, 2., 3., 4.]);
- let b = Array::from_vec(vec![1f32; 4]);
- let c = Array::from_vec(vec![0f32; 4]);
- let a_tensor: Tensor = a.into();
- let b_tensor: Tensor = b.into();
- let c_tensor: Tensor = c.into();
-
- let result: Tensor = match execute(
- wasm_backend_file,
- op_type,
- vec![a_tensor, b_tensor, c_tensor],
- ) {
- Ok(m) => m,
- Err(f) => panic!(f.to_string()),
- };
- println!(
- "{}",
- serde_json::to_string_pretty(&result.to_vec::()).unwrap()
- );
-}
-
-fn execute(wasm_backend_file: String, op_type: i32, input_data: Vec) -> Result {
- let store = Store::default();
-
- // First set up our linker which is going to be linking modules together. We
- // want our linker to have wasi available, so we set that up here as well.
- let mut linker = Linker::new(&store);
- // Create an instance of `Wasi` which contains a `WasiCtx`. Note that
- // `WasiCtx` provides a number of ways to configure what the target program
- // will have access to.
- let wasi = Wasi::new(&store, WasiCtx::new(std::env::args())?);
- wasi.add_to_linker(&mut linker)?;
-
- let module = Module::from_file(store.engine(), &wasm_backend_file)?;
- let instance = linker.instantiate(&module)?;
- let memory = instance
- .get_memory("memory")
- .ok_or(anyhow::format_err!("failed to find `memory` export"))?;
-
- // Specify the input address and output address to access the wasm memory.
- let in_addr = 0x1000;
- let out_addr = 0x2000;
-
- // Serialize the data into a JSON string.
- let in_data = serde_json::to_vec(&input_data)?;
- let in_size = in_data.len();
- // Insert the input data into wasm memory.
- for i in 0..in_size {
- unsafe {
- memory.data_unchecked_mut()[in_addr + i] = *in_data.get(i).unwrap();
- }
- }
-
- // Invoke `run` export
- let run = instance
- .get_func("run")
- .ok_or(anyhow::format_err!("failed to find `run` function export!"))?
- .get4::()?;
-
- let out_size = run(
- op_type.clone() as i32,
- in_addr as i32,
- in_size as i32,
- out_addr as i32,
- )?;
- if out_size == 0 {
- panic!("Opeartor {:?} run failed!", op_type);
- }
-
- let out_data = unsafe { &memory.data_unchecked()[out_addr..][..out_size as usize] };
- let out_vec: Tensor = serde_json::from_slice(out_data).unwrap();
- Ok(out_vec.clone())
-}
diff --git a/apps/wasm-dlbackend-tvm/.gitignore b/apps/wasm-graphcompiler-tvm/.gitignore
similarity index 100%
rename from apps/wasm-dlbackend-tvm/.gitignore
rename to apps/wasm-graphcompiler-tvm/.gitignore
diff --git a/apps/wasm-graphcompiler-tvm/README.md b/apps/wasm-graphcompiler-tvm/README.md
new file mode 100644
index 0000000000000..2555ba3da0af5
--- /dev/null
+++ b/apps/wasm-graphcompiler-tvm/README.md
@@ -0,0 +1,203 @@
+# WebAssembly GraphCompiler for Deep Learning Framework with TVM Runtime
+
+#### Experimental notice: This project is still *experimental* and only serves as a proof of concept for running deep learning frameworks (such like [MindSpore](https://github.com/mindspore-ai/mindspore)) on [WebAssembly runtime](https://github.com/bytecodealliance/wasmtime) with [TVM stack](https://tvm.apache.org/).
+
+- [WebAssembly GraphCompiler for Deep Learning Framework with TVM Runtime](#webassembly-graphcompiler-for-deep-learning-framework-with-tvm-runtime)
+ - [Motivation](#motivation)
+ - [Framework Landscape](#framework-landscape)
+ - [Project Status](#project-status)
+ - [PoC Guidelines](#poc-guidelines)
+ - [Pre-installation](#pre-installation)
+ - [Build ResNet50 model](#build-resnet50-model)
+ - [Build wasm-graphcompiler-tvm package](#build-wasm-graphcompiler-tvm-package)
+ - [Test](#test)
+ - [Future Work](#future-work)
+ - [Operator enhancement](#operator-enhancement)
+ - [Performance benchmark](#performance-benchmark)
+ - [Native TVM Rust runtime support](#native-tvm-rust-runtime-support)
+ - [Appendix](#appendix)
+ - [System packages install](#system-packages-install)
+ - [Contribution](#contribution)
+
+## Motivation
+
+
+
+As demonstrated in TVM runtime [tutorials](https://tvm.apache.org/docs/tutorials/relay_quick_start.html), TVM already supports WASM as the optional hardware backend, so we can leverage the features of WebAssembly (portability, security) and TVM runtime (domain-specific, optimization) to build a flexible and auto-optimized graph compiler for all deep learning frameworks.
+
+## Framework Landscape
+
+The figures below demonstrate the whole landscape of running deep learning frameworks on WASM runtime with TVM compiler stack.
+
+* WASM graph compiler stack
+ ```
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ | | | | | |
+ | Framework Model | ---> | ONNX Model | ---> | TVM Relay Python API |
+ |_ _ _ _ _ _ _ _ _ _| |_ _ _ _ _ _ _| |_ _ _ _ _ _ _ _ _ _ _ _|
+ ||
+ \/
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ | | | |
+ | WASM Graph Compiler | | TVM Compiler Stack |
+ | (TVM runtime) | |_ _ _ _ _ _ _ _ _ _ _|
+ |_ _ _ _ _ _ _ _ _ _ _| ||
+ || \/
+ _ _ _ _ _ _ _ _ || _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ | | \/ | | llvm-ar | |
+ | *.wasi.wasm | <--- | libgraph_wasm32.a | <------- | graph.o |
+ |_ _ _ _ _ _ _ _| |_ _ _ _ _ _ _ _ _ _| |_ _ _ _ _|
+ ```
+
+* WASM graph runtime
+ ```
+ _ _ _ _ _ _ _ _ _ _ _
+ | |
+ | WASM Graph Runtime |
+ | (WASM runtime) |
+ |_ _ _ _ _ _ _ _ _ _ _|
+ ||
+ _ _ _ _\/_ _ _ _
+ | |
+ | *.wasi.wasm |
+ |_ _ _ _ _ _ _ _ |
+ ```
+
+## Project Status
+
+This project should be considered **experimental** at the very early stage, all rich features are under active development. Here is the current operator support matrix:
+
+| Model Name | Status |
+| ---------- | ------ |
+| ResNet50 | ✔️ |
+| LeNet | — |
+
+**NOTICE**: Currently this project is ONLY tested on Ubuntu system, so `Ubuntu 16.04+` should be prepared as the testing environment.
+
+## PoC Guidelines
+
+### Pre-installation
+
+* Rust
+
+ Before running this demo, please make sure [Rust](#system-packages-install) has been installed.
+
+ After Rust installed, execute the code below to add `wasm32-wasi` target:
+ ```shell
+ rustup target add wasm32-wasi
+ cargo install cargo-wasi
+ ```
+
+* Wasmtime
+
+ Please NOTICE that [Wasmtime](#system-packages-install) should be installed in advance.
+
+* TVM
+
+ Please follow TVM [installations](https://tvm.apache.org/docs/install/index.html), `export TVM_HOME=/path/to/tvm` and add `libtvm_runtime` to your `LD_LIBRARY_PATH`.
+
+ *Note:* To run the end-to-end examples and tests, `tvm` and `topi` need to be added to your `PYTHONPATH` or it's automatic via an Anaconda environment when it is installed individually.
+
+* LLVM
+
+ `LLVM 10.0` or later is REQUIRED.
+
+### Build ResNet50 model
+
+- Build DL library in the WebAssembly format.
+
+ - Download model
+
+ ```
+ cd wasm-graphcompiler/tools && wget https://s3.amazonaws.com/onnx-model-zoo/resnet/resnet50v1/resnet50v1.onnx
+ ```
+
+ - Compile
+
+ ```
+ LLVM_AR=llvm-ar-10 python ./build_graph_lib.py -O3 ./resnet50v1.onnx
+ ```
+
+### Build wasm-graphcompiler-tvm package
+
+```shell
+cd wasm-graphcompiler && cargo wasi build --release
+cp ./target/wasm32-wasi/release/wasm_graphcompiler_tvm.wasi.wasm ../wasm-graphruntime/tools/
+```
+
+### Test
+
+Before running this demo, please make sure [`Rust`](#system-packages-install) has been installed.
+
+Next run the command below to install the runtime package for testing (`rust` REQUIRED):
+
+```shell
+cd wasm-graphruntime/ && cargo build --release
+cp ./target/release/wasm-graphruntime /usr/local/bin/
+```
+
+Check the usage of `wasm-graphruntime`:
+
+```shell
+~# wasm-graphruntime -h
+
+Usage: wasm-graphruntime [options]
+
+Options:
+ -c, --ms-backend-config FILE_PATH
+ set wasm backend config file
+ -i, --input-data-file FILE_PATH
+ set the path to input image file
+ -h, --help print this help menu
+```
+
+Next perform model inference using these commands below:
+```
+$ cd wasm-graphruntime/tools && wget -O cat.png https://github.com/dmlc/mxnet.js/blob/master/data/cat.png?raw=true
+$ wasm-graphruntime -c ./wasm_graphcompiler_tvm.wasi.wasm -i ./cat.png
+original image dimensions: (256, 256)
+resized image dimensions: (224, 224)
+input image belongs to the class `tabby, tabby cat`
+```
+
+## Future Work
+
+### More networks support
+TODO
+
+### Performance benchmark
+
+We are working on several improvements on performances:
+* WebAssembly SIMD support
+* Auto-tvm enhancement for llvm target
+
+### Native TVM Rust runtime support
+TODO
+
+## Appendix
+
+### System packages install
+
+* Rust (latest version)
+
+ If you are running Windows, to install Rust, download and run the [RUST-INIT.EXE](https://win.rustup.rs/), and then follow the onscreen instructions.
+
+ If you are a Linux user, run the following in your terminal, then follow the on-screen instructions to install Rust.
+
+ ```shell
+ curl https://sh.rustup.rs -sSf | sh
+ ```
+
+* wasmtime (latest version)
+
+ If you are running Windows 64-bit, download and run [Wasmtime Installer](https://github.com/CraneStation/wasmtime/releases/download/dev/wasmtime-dev-x86_64-windows.msi) then follow the onscreen instructions.
+
+ If you're a Linux user run the following in your terminal, then follow the onscreen instructions to install `wasmtime`:
+
+ ```shell
+ curl https://wasmtime.dev/install.sh -sSf | bash
+ ```
+
+## Contribution
+
+Lastly very thanks [@kazum](https://github.com/kazum) for having offered a lot of help when implementing this project.
diff --git a/apps/wasm-dlbackend-tvm/.cargo/config b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/.cargo/config
similarity index 85%
rename from apps/wasm-dlbackend-tvm/.cargo/config
rename to apps/wasm-graphcompiler-tvm/wasm-graphcompiler/.cargo/config
index e17b808e4b074..b01a37beeb907 100644
--- a/apps/wasm-dlbackend-tvm/.cargo/config
+++ b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/.cargo/config
@@ -1,3 +1,3 @@
[build]
target = "wasm32-wasi"
-rustflags = ["-C", "link-arg=--whole-archive", "-C", "link-arg=-lops_wasm32"]
+rustflags = ["-C", "link-arg=--whole-archive", "-C", "link-arg=-lgraph_wasm32"]
diff --git a/apps/wasm-dlbackend-tvm/Cargo.toml b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/Cargo.toml
similarity index 65%
rename from apps/wasm-dlbackend-tvm/Cargo.toml
rename to apps/wasm-graphcompiler-tvm/wasm-graphcompiler/Cargo.toml
index 596890354f8f5..cfa046f2ba994 100644
--- a/apps/wasm-dlbackend-tvm/Cargo.toml
+++ b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/Cargo.toml
@@ -1,9 +1,9 @@
[package]
-name = "wasm-dlbackend-tvm"
+name = "wasm-graphcompiler-tvm"
version = "0.1.0"
authors = ["leonwanghui "]
edition = "2018"
-description = "WebAssembly backend to deep learning framework using TVM runtime"
+description = "WebAssembly graph compiler to deep learning frameworks using TVM"
readme = "README.md"
repository = "https://github.com/apache/incubator-tvm"
license = "Apache-2.0"
@@ -26,5 +26,6 @@ serde = "1.0.53"
serde_derive = "1.0.53"
serde_json = "1.0.53"
ndarray = "0.12"
-tvm-common = { version = "0.1", path = "../../rust/common" }
-tvm-runtime = { version = "0.1", path = "../../rust/runtime" }
+tvm-common = { version = "0.1", path = "../../../rust/common" }
+tvm-runtime = { version = "0.1", path = "../../../rust/runtime" }
+lazy_static = "1.1.1"
diff --git a/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/build.rs b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/build.rs
new file mode 100644
index 0000000000000..553a017131fed
--- /dev/null
+++ b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/build.rs
@@ -0,0 +1,8 @@
+use std::path::PathBuf;
+
+fn main() {
+ let mut out_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
+ out_dir.push("lib");
+
+ println!("cargo:rustc-link-search=native={}", out_dir.display());
+}
diff --git a/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/src/lib.rs b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/src/lib.rs
new file mode 100644
index 0000000000000..11722695cd374
--- /dev/null
+++ b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/src/lib.rs
@@ -0,0 +1,64 @@
+#[macro_use]
+extern crate lazy_static;
+#[macro_use]
+extern crate serde_derive;
+extern crate ndarray;
+extern crate tvm_runtime;
+
+mod types;
+use types::Tensor;
+mod utils;
+
+use std::{collections::HashMap, convert::TryFrom, env, sync::Mutex};
+use tvm_runtime::{Graph, GraphExecutor, SystemLibModule, Tensor as TVMTensor};
+
+extern "C" {
+ fn __wasm_call_ctors();
+}
+
+lazy_static! {
+ static ref SYSLIB: SystemLibModule = SystemLibModule::default();
+ static ref GRAPH_EXECUTOR: Mutex> = {
+ unsafe {
+ // This is necessary to invoke TVMBackendRegisterSystemLibSymbol
+ // API calls.
+ __wasm_call_ctors();
+ }
+ let graph = Graph::try_from(include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/lib/graph.json"
+ )))
+ .unwrap();
+ let params_bytes =
+ include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/lib/graph.params"));
+ let params = tvm_runtime::load_param_dict(params_bytes)
+ .unwrap()
+ .into_iter()
+ .map(|(k, v)| (k, v.to_owned()))
+ .collect::>>();
+
+ let mut exec = GraphExecutor::new(graph, &*SYSLIB).unwrap();
+ exec.load_params(params);
+
+ Mutex::new(exec)
+ };
+}
+
+#[no_mangle]
+pub extern "C" fn run(wasm_addr: i32, in_size: i32) -> i32 {
+ let in_tensor = utils::load_input(wasm_addr, in_size as usize);
+ let input: TVMTensor = in_tensor.as_dltensor().into();
+
+ GRAPH_EXECUTOR.lock().unwrap().set_input("data", input);
+ GRAPH_EXECUTOR.lock().unwrap().run();
+ let output = GRAPH_EXECUTOR
+ .lock()
+ .unwrap()
+ .get_output(0)
+ .unwrap()
+ .as_dltensor(false);
+
+ let out_tensor: Tensor = output.into();
+ let out_size = utils::store_output(wasm_addr, out_tensor);
+ out_size as i32
+}
diff --git a/apps/wasm-dlbackend-tvm/src/ops/types.rs b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/src/types.rs
similarity index 88%
rename from apps/wasm-dlbackend-tvm/src/ops/types.rs
rename to apps/wasm-graphcompiler-tvm/wasm-graphcompiler/src/types.rs
index b87fa0de0c7a5..8f7d8e42cf5c1 100644
--- a/apps/wasm-dlbackend-tvm/src/ops/types.rs
+++ b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/src/types.rs
@@ -9,36 +9,6 @@ use tvm_common::ffi::{
DLContext, DLDataType, DLDataTypeCode_kDLFloat, DLDataTypeCode_kDLInt, DLDeviceType_kDLCPU,
};
-pub trait Operator {
- fn init(&self, a_shape: Vec, b_shape: Vec, c_shape: Vec) -> Status;
-
- fn launch(&self, inputs: Vec, output: Tensor) -> (Status, Tensor);
-}
-
-#[derive(Debug, PartialEq)]
-pub enum Status {
- Succeed,
- ValidateFailed,
- InitFailed,
- LaunchFailed,
-}
-
-#[derive(Debug, PartialEq, Clone)]
-pub enum OpType {
- Add,
- Sub,
-}
-
-impl From for OpType {
- fn from(op_type: i32) -> Self {
- match op_type {
- 0i32 => OpType::Add,
- 1i32 => OpType::Sub,
- _ => OpType::Add,
- }
- }
-}
-
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub enum DataType {
FP32,
diff --git a/apps/wasm-dlbackend-tvm/src/utils.rs b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/src/utils.rs
similarity index 76%
rename from apps/wasm-dlbackend-tvm/src/utils.rs
rename to apps/wasm-graphcompiler-tvm/wasm-graphcompiler/src/utils.rs
index 05050981f4760..76380103484d3 100644
--- a/apps/wasm-dlbackend-tvm/src/utils.rs
+++ b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/src/utils.rs
@@ -1,17 +1,17 @@
-use super::ops::types::*;
+use super::types::*;
use serde_json;
use std::ptr;
-pub fn load_inputs(in_addr: i32, in_size: usize) -> Vec {
+pub fn load_input(in_addr: i32, in_size: usize) -> Tensor {
let in_addr = in_addr as *mut u8;
let mut data_vec = Vec::new();
for i in 0..in_size {
data_vec.push(unsafe { ptr::read(in_addr.offset(i as isize)) });
}
- let inputs: Vec = serde_json::from_slice(&data_vec).unwrap();
+ let input: Tensor = serde_json::from_slice(&data_vec).unwrap();
- inputs
+ input
}
pub fn store_output(out_addr: i32, output: Tensor) -> usize {
diff --git a/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/tools/build_graph_lib.py b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/tools/build_graph_lib.py
new file mode 100644
index 0000000000000..73b1895562a80
--- /dev/null
+++ b/apps/wasm-graphcompiler-tvm/wasm-graphcompiler/tools/build_graph_lib.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+# 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.
+
+"""Builds a simple graph for testing."""
+import argparse
+import os
+import subprocess
+import sys
+
+import onnx
+import tvm
+from tvm import relay
+
+
+def _get_mod_and_params(model_file):
+ onnx_model = onnx.load(model_file)
+ shape_dict = {}
+ for input in onnx_model.graph.input:
+ shape_dict[input.name] = [dim.dim_value for dim in input.type.tensor_type.shape.dim]
+
+ return relay.frontend.from_onnx(onnx_model, shape_dict)
+
+
+def build_graph_lib(model_file, opt_level):
+ """Compiles the pre-trained model with TVM"""
+ out_dir = os.path.join(sys.path[0], "../lib")
+ if not os.path.exists(out_dir):
+ os.makedirs(out_dir)
+
+ # Compile the relay mod
+ mod, params = _get_mod_and_params(model_file)
+ with tvm.transform.PassContext(opt_level=opt_level):
+ graph_json, lib, params = relay.build(
+ mod, target="llvm -target=wasm32-unknown-unknown --system-lib", params=params)
+
+ # Save the model artifacts to obj_file
+ obj_file = os.path.join(out_dir, 'graph.o')
+ lib.save(obj_file)
+ # Run llvm-ar to archive obj_file into lib_file
+ lib_file = os.path.join(out_dir, 'libgraph_wasm32.a')
+ cmds = [os.environ.get("LLVM_AR", "llvm-ar-10"), 'rcs', lib_file, obj_file]
+ subprocess.run(cmds)
+
+ with open(os.path.join(out_dir, 'graph.json'), 'w') as f_graph:
+ f_graph.write(graph_json)
+
+ with open(os.path.join(out_dir, 'graph.params'), 'wb') as f_params:
+ f_params.write(relay.save_param_dict(params))
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='ONNX ResNet50 model build example')
+ parser.add_argument('model_file', type=str, help='the path of onnx model file')
+ parser.add_argument('-O', '--opt-level', type=int, default=0,
+ help='level of optimization. 0 is unoptimized and 3 is the highest level')
+ args = parser.parse_args()
+
+ build_graph_lib(args.model_file, args.opt_level)
diff --git a/apps/wasm-graphcompiler-tvm/wasm-graphruntime/Cargo.toml b/apps/wasm-graphcompiler-tvm/wasm-graphruntime/Cargo.toml
new file mode 100644
index 0000000000000..294bdd74a72e1
--- /dev/null
+++ b/apps/wasm-graphcompiler-tvm/wasm-graphruntime/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "wasm-graphruntime"
+version = "0.1.0"
+authors = ["leonwanghui "]
+edition = "2018"
+description = "WebAssembly graph runtime to deep learning frameworks using wasmtime"
+license = "Apache-2.0"
+keywords = ["wasm", "machine learning", "wasmtime"]
+
+[dependencies]
+wasmtime = "0.18.0"
+wasmtime-wasi = "0.18.0"
+anyhow = "1.0.31"
+serde = "1.0.53"
+serde_json = "1.0.53"
+serde_derive = "1.0.53"
+getopts = "0.2.21"
+ndarray = "0.12"
+csv = "1.1"
+image = "0.20"
diff --git a/apps/wasm-graphcompiler-tvm/wasm-graphruntime/src/main.rs b/apps/wasm-graphcompiler-tvm/wasm-graphruntime/src/main.rs
new file mode 100644
index 0000000000000..179859d04c0eb
--- /dev/null
+++ b/apps/wasm-graphcompiler-tvm/wasm-graphruntime/src/main.rs
@@ -0,0 +1,173 @@
+#[macro_use]
+extern crate serde_derive;
+extern crate csv;
+extern crate image;
+
+mod types;
+use types::Tensor;
+
+use anyhow::Result;
+use getopts::Options;
+use image::{FilterType, GenericImageView};
+use ndarray::Array;
+use serde_json;
+use std::{collections::HashMap, env};
+use wasmtime::*;
+use wasmtime_wasi::{Wasi, WasiCtx};
+
+const IMG_HEIGHT: usize = 224;
+const IMG_WIDTH: usize = 224;
+
+fn print_usage(program: &str, opts: Options) {
+ let brief = format!("Usage: {} [options]", program);
+ print!("{}", opts.usage(&brief));
+}
+
+fn main() {
+ let args: Vec = env::args().collect();
+ let program = args[0].clone();
+
+ let mut opts = Options::new();
+ opts.optopt(
+ "c",
+ "ms-backend-config",
+ "set wasm backend config file",
+ "FILE_PATH",
+ );
+ opts.optopt(
+ "i",
+ "input-data-file",
+ "set the path to input image file",
+ "FILE_PATH",
+ );
+ opts.optflag("h", "help", "print this help menu");
+ let matches = match opts.parse(&args[1..]) {
+ Ok(m) => m,
+ Err(f) => panic!(f.to_string()),
+ };
+ if matches.opt_present("h") {
+ print_usage(&program, opts);
+ return;
+ }
+ let wasm_backend_file = matches.opt_str("c").unwrap();
+ let input_data_file = matches.opt_str("i").unwrap();
+ let img = image::open(input_data_file).unwrap();
+ let input = data_preprocess(img);
+
+ let output: Tensor = match execute(wasm_backend_file, input) {
+ Ok(m) => m,
+ Err(f) => panic!(f.to_string()),
+ };
+ output_assert(output);
+}
+
+fn data_preprocess(img: image::DynamicImage) -> Tensor {
+ println!("original image dimensions: {:?}", img.dimensions());
+ let img = img
+ .resize_exact(IMG_HEIGHT as u32, IMG_WIDTH as u32, FilterType::Nearest)
+ .to_rgb();
+ println!("resized image dimensions: {:?}", img.dimensions());
+ let mut pixels: Vec = vec![];
+ for pixel in img.pixels() {
+ let tmp = pixel.data;
+ // normalize the RGB channels using mean, std of imagenet1k
+ let tmp = [
+ (tmp[0] as f32 - 123.0) / 58.395, // R
+ (tmp[1] as f32 - 117.0) / 57.12, // G
+ (tmp[2] as f32 - 104.0) / 57.375, // B
+ ];
+ for e in &tmp {
+ pixels.push(*e);
+ }
+ }
+
+ // (H,W,C) -> (C,H,W)
+ let arr = Array::from_shape_vec((IMG_HEIGHT, IMG_WIDTH, 3), pixels).unwrap();
+ let arr = arr.permuted_axes([2, 0, 1]);
+ let arr = Array::from_iter(arr.into_iter().map(|&v| v));
+
+ return Tensor::from(arr);
+}
+
+fn execute(wasm_backend_file: String, input_data: Tensor) -> Result {
+ let store = Store::default();
+
+ // First set up our linker which is going to be linking modules together. We
+ // want our linker to have wasi available, so we set that up here as well.
+ let mut linker = Linker::new(&store);
+ // Create an instance of `Wasi` which contains a `WasiCtx`. Note that
+ // `WasiCtx` provides a number of ways to configure what the target program
+ // will have access to.
+ let wasi = Wasi::new(&store, WasiCtx::new(env::args())?);
+ wasi.add_to_linker(&mut linker)?;
+
+ let module = Module::from_file(store.engine(), &wasm_backend_file)?;
+ let instance = linker.instantiate(&module)?;
+ let memory = instance
+ .get_memory("memory")
+ .ok_or(anyhow::format_err!("failed to find `memory` export"))?;
+
+ // Specify the wasm address to access the wasm memory.
+ let wasm_addr = memory.data_size();
+ // Serialize the data into a JSON string.
+ let in_data = serde_json::to_vec(&input_data)?;
+ let in_size = in_data.len();
+ // Grow up memory size according to in_size to avoid memory leak.
+ memory.grow((in_size >> 16) as u32 + 1)?;
+
+ // Insert the input data into wasm memory.
+ for i in 0..in_size {
+ unsafe {
+ memory.data_unchecked_mut()[wasm_addr + i] = *in_data.get(i).unwrap();
+ }
+ }
+
+ // Invoke `run` export.
+ let run = instance
+ .get_func("run")
+ .ok_or(anyhow::format_err!("failed to find `run` function export!"))?
+ .get2::()?;
+
+ let out_size = run(wasm_addr as i32, in_size as i32)?;
+ if out_size == 0 {
+ panic!("graph run failed!");
+ }
+
+ let out_data = unsafe { &memory.data_unchecked()[wasm_addr..][..out_size as usize] };
+ let out_vec: Tensor = serde_json::from_slice(out_data).unwrap();
+ Ok(out_vec)
+}
+
+fn output_assert(out_tensor: Tensor) {
+ let output = out_tensor.to_vec::();
+
+ // Find the maximum entry in the output and its index.
+ let mut argmax = -1;
+ let mut max_prob = 0.;
+ for i in 0..output.len() {
+ if output[i] > max_prob {
+ max_prob = output[i];
+ argmax = i as i32;
+ }
+ }
+
+ // Create a hash map of (class id, class name)
+ let mut synset: HashMap = HashMap::new();
+ let mut rdr = csv::ReaderBuilder::new().from_reader(
+ include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/tools/synset.csv")).as_bytes(),
+ );
+
+ for result in rdr.records() {
+ let record = result.unwrap();
+ let id: i32 = record[0].parse().unwrap();
+ let cls = record[1].to_string();
+ synset.insert(id, cls);
+ }
+
+ println!(
+ "input image belongs to the class `{}`",
+ synset
+ .get(&argmax)
+ .expect("cannot find the class id for argmax")
+ );
+}
diff --git a/apps/wasm-dlbackend-tvm/wasm-dlfrontend/src/types.rs b/apps/wasm-graphcompiler-tvm/wasm-graphruntime/src/types.rs
similarity index 100%
rename from apps/wasm-dlbackend-tvm/wasm-dlfrontend/src/types.rs
rename to apps/wasm-graphcompiler-tvm/wasm-graphruntime/src/types.rs
diff --git a/apps/wasm-graphcompiler-tvm/wasm-graphruntime/tools/synset.csv b/apps/wasm-graphcompiler-tvm/wasm-graphruntime/tools/synset.csv
new file mode 100644
index 0000000000000..d733178f43b4d
--- /dev/null
+++ b/apps/wasm-graphcompiler-tvm/wasm-graphruntime/tools/synset.csv
@@ -0,0 +1,1000 @@
+0,"tench, Tinca tinca"
+1,"goldfish, Carassius auratus"
+2,"great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias"
+3,"tiger shark, Galeocerdo cuvieri"
+4,"hammerhead, hammerhead shark"
+5,"electric ray, crampfish, numbfish, torpedo"
+6,stingray
+7,cock
+8,hen
+9,"ostrich, Struthio camelus"
+10,"brambling, Fringilla montifringilla"
+11,"goldfinch, Carduelis carduelis"
+12,"house finch, linnet, Carpodacus mexicanus"
+13,"junco, snowbird"
+14,"indigo bunting, indigo finch, indigo bird, Passerina cyanea"
+15,"robin, American robin, Turdus migratorius"
+16,bulbul
+17,jay
+18,magpie
+19,chickadee
+20,"water ouzel, dipper"
+21,kite
+22,"bald eagle, American eagle, Haliaeetus leucocephalus"
+23,vulture
+24,"great grey owl, great gray owl, Strix nebulosa"
+25,"European fire salamander, Salamandra salamandra"
+26,"common newt, Triturus vulgaris"
+27,eft
+28,"spotted salamander, Ambystoma maculatum"
+29,"axolotl, mud puppy, Ambystoma mexicanum"
+30,"bullfrog, Rana catesbeiana"
+31,"tree frog, tree-frog"
+32,"tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui"
+33,"loggerhead, loggerhead turtle, Caretta caretta"
+34,"leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea"
+35,mud turtle
+36,terrapin
+37,"box turtle, box tortoise"
+38,banded gecko
+39,"common iguana, iguana, Iguana iguana"
+40,"American chameleon, anole, Anolis carolinensis"
+41,"whiptail, whiptail lizard"
+42,agama
+43,"frilled lizard, Chlamydosaurus kingi"
+44,alligator lizard
+45,"Gila monster, Heloderma suspectum"
+46,"green lizard, Lacerta viridis"
+47,"African chameleon, Chamaeleo chamaeleon"
+48,"Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis"
+49,"African crocodile, Nile crocodile, Crocodylus niloticus"
+50,"American alligator, Alligator mississipiensis"
+51,triceratops
+52,"thunder snake, worm snake, Carphophis amoenus"
+53,"ringneck snake, ring-necked snake, ring snake"
+54,"hognose snake, puff adder, sand viper"
+55,"green snake, grass snake"
+56,"king snake, kingsnake"
+57,"garter snake, grass snake"
+58,water snake
+59,vine snake
+60,"night snake, Hypsiglena torquata"
+61,"boa constrictor, Constrictor constrictor"
+62,"rock python, rock snake, Python sebae"
+63,"Indian cobra, Naja naja"
+64,green mamba
+65,sea snake
+66,"horned viper, cerastes, sand viper, horned asp, Cerastes cornutus"
+67,"diamondback, diamondback rattlesnake, Crotalus adamanteus"
+68,"sidewinder, horned rattlesnake, Crotalus cerastes"
+69,trilobite
+70,"harvestman, daddy longlegs, Phalangium opilio"
+71,scorpion
+72,"black and gold garden spider, Argiope aurantia"
+73,"barn spider, Araneus cavaticus"
+74,"garden spider, Aranea diademata"
+75,"black widow, Latrodectus mactans"
+76,tarantula
+77,"wolf spider, hunting spider"
+78,tick
+79,centipede
+80,black grouse
+81,ptarmigan
+82,"ruffed grouse, partridge, Bonasa umbellus"
+83,"prairie chicken, prairie grouse, prairie fowl"
+84,peacock
+85,quail
+86,partridge
+87,"African grey, African gray, Psittacus erithacus"
+88,macaw
+89,"sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita"
+90,lorikeet
+91,coucal
+92,bee eater
+93,hornbill
+94,hummingbird
+95,jacamar
+96,toucan
+97,drake
+98,"red-breasted merganser, Mergus serrator"
+99,goose
+100,"black swan, Cygnus atratus"
+101,tusker
+102,"echidna, spiny anteater, anteater"
+103,"platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus"
+104,"wallaby, brush kangaroo"
+105,"koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus"
+106,wombat
+107,jellyfish
+108,"sea anemone, anemone"
+109,brain coral
+110,"flatworm, platyhelminth"
+111,"nematode, nematode worm, roundworm"
+112,conch
+113,snail
+114,slug
+115,"sea slug, nudibranch"
+116,"chiton, coat-of-mail shell, sea cradle, polyplacophore"
+117,"chambered nautilus, pearly nautilus, nautilus"
+118,"Dungeness crab, Cancer magister"
+119,"rock crab, Cancer irroratus"
+120,fiddler crab
+121,"king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica"
+122,"American lobster, Northern lobster, Maine lobster, Homarus americanus"
+123,"spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish"
+124,"crayfish, crawfish, crawdad, crawdaddy"
+125,hermit crab
+126,isopod
+127,"white stork, Ciconia ciconia"
+128,"black stork, Ciconia nigra"
+129,spoonbill
+130,flamingo
+131,"little blue heron, Egretta caerulea"
+132,"American egret, great white heron, Egretta albus"
+133,bittern
+134,crane
+135,"limpkin, Aramus pictus"
+136,"European gallinule, Porphyrio porphyrio"
+137,"American coot, marsh hen, mud hen, water hen, Fulica americana"
+138,bustard
+139,"ruddy turnstone, Arenaria interpres"
+140,"red-backed sandpiper, dunlin, Erolia alpina"
+141,"redshank, Tringa totanus"
+142,dowitcher
+143,"oystercatcher, oyster catcher"
+144,pelican
+145,"king penguin, Aptenodytes patagonica"
+146,"albatross, mollymawk"
+147,"grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus"
+148,"killer whale, killer, orca, grampus, sea wolf, Orcinus orca"
+149,"dugong, Dugong dugon"
+150,sea lion
+151,Chihuahua
+152,Japanese spaniel
+153,"Maltese dog, Maltese terrier, Maltese"
+154,"Pekinese, Pekingese, Peke"
+155,Shih-Tzu
+156,Blenheim spaniel
+157,papillon
+158,toy terrier
+159,Rhodesian ridgeback
+160,"Afghan hound, Afghan"
+161,"basset, basset hound"
+162,beagle
+163,"bloodhound, sleuthhound"
+164,bluetick
+165,black-and-tan coonhound
+166,"Walker hound, Walker foxhound"
+167,English foxhound
+168,redbone
+169,"borzoi, Russian wolfhound"
+170,Irish wolfhound
+171,Italian greyhound
+172,whippet
+173,"Ibizan hound, Ibizan Podenco"
+174,"Norwegian elkhound, elkhound"
+175,"otterhound, otter hound"
+176,"Saluki, gazelle hound"
+177,"Scottish deerhound, deerhound"
+178,Weimaraner
+179,"Staffordshire bullterrier, Staffordshire bull terrier"
+180,"American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier"
+181,Bedlington terrier
+182,Border terrier
+183,Kerry blue terrier
+184,Irish terrier
+185,Norfolk terrier
+186,Norwich terrier
+187,Yorkshire terrier
+188,wire-haired fox terrier
+189,Lakeland terrier
+190,"Sealyham terrier, Sealyham"
+191,"Airedale, Airedale terrier"
+192,"cairn, cairn terrier"
+193,Australian terrier
+194,"Dandie Dinmont, Dandie Dinmont terrier"
+195,"Boston bull, Boston terrier"
+196,miniature schnauzer
+197,giant schnauzer
+198,standard schnauzer
+199,"Scotch terrier, Scottish terrier, Scottie"
+200,"Tibetan terrier, chrysanthemum dog"
+201,"silky terrier, Sydney silky"
+202,soft-coated wheaten terrier
+203,West Highland white terrier
+204,"Lhasa, Lhasa apso"
+205,flat-coated retriever
+206,curly-coated retriever
+207,golden retriever
+208,Labrador retriever
+209,Chesapeake Bay retriever
+210,German short-haired pointer
+211,"vizsla, Hungarian pointer"
+212,English setter
+213,"Irish setter, red setter"
+214,Gordon setter
+215,Brittany spaniel
+216,"clumber, clumber spaniel"
+217,"English springer, English springer spaniel"
+218,Welsh springer spaniel
+219,"cocker spaniel, English cocker spaniel, cocker"
+220,Sussex spaniel
+221,Irish water spaniel
+222,kuvasz
+223,schipperke
+224,groenendael
+225,malinois
+226,briard
+227,kelpie
+228,komondor
+229,"Old English sheepdog, bobtail"
+230,"Shetland sheepdog, Shetland sheep dog, Shetland"
+231,collie
+232,Border collie
+233,"Bouvier des Flandres, Bouviers des Flandres"
+234,Rottweiler
+235,"German shepherd, German shepherd dog, German police dog, alsatian"
+236,"Doberman, Doberman pinscher"
+237,miniature pinscher
+238,Greater Swiss Mountain dog
+239,Bernese mountain dog
+240,Appenzeller
+241,EntleBucher
+242,boxer
+243,bull mastiff
+244,Tibetan mastiff
+245,French bulldog
+246,Great Dane
+247,"Saint Bernard, St Bernard"
+248,"Eskimo dog, husky"
+249,"malamute, malemute, Alaskan malamute"
+250,Siberian husky
+251,"dalmatian, coach dog, carriage dog"
+252,"affenpinscher, monkey pinscher, monkey dog"
+253,basenji
+254,"pug, pug-dog"
+255,Leonberg
+256,"Newfoundland, Newfoundland dog"
+257,Great Pyrenees
+258,"Samoyed, Samoyede"
+259,Pomeranian
+260,"chow, chow chow"
+261,keeshond
+262,Brabancon griffon
+263,"Pembroke, Pembroke Welsh corgi"
+264,"Cardigan, Cardigan Welsh corgi"
+265,toy poodle
+266,miniature poodle
+267,standard poodle
+268,Mexican hairless
+269,"timber wolf, grey wolf, gray wolf, Canis lupus"
+270,"white wolf, Arctic wolf, Canis lupus tundrarum"
+271,"red wolf, maned wolf, Canis rufus, Canis niger"
+272,"coyote, prairie wolf, brush wolf, Canis latrans"
+273,"dingo, warrigal, warragal, Canis dingo"
+274,"dhole, Cuon alpinus"
+275,"African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus"
+276,"hyena, hyaena"
+277,"red fox, Vulpes vulpes"
+278,"kit fox, Vulpes macrotis"
+279,"Arctic fox, white fox, Alopex lagopus"
+280,"grey fox, gray fox, Urocyon cinereoargenteus"
+281,"tabby, tabby cat"
+282,tiger cat
+283,Persian cat
+284,"Siamese cat, Siamese"
+285,Egyptian cat
+286,"cougar, puma, catamount, mountain lion, painter, panther, Felis concolor"
+287,"lynx, catamount"
+288,"leopard, Panthera pardus"
+289,"snow leopard, ounce, Panthera uncia"
+290,"jaguar, panther, Panthera onca, Felis onca"
+291,"lion, king of beasts, Panthera leo"
+292,"tiger, Panthera tigris"
+293,"cheetah, chetah, Acinonyx jubatus"
+294,"brown bear, bruin, Ursus arctos"
+295,"American black bear, black bear, Ursus americanus, Euarctos americanus"
+296,"ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus"
+297,"sloth bear, Melursus ursinus, Ursus ursinus"
+298,mongoose
+299,"meerkat, mierkat"
+300,tiger beetle
+301,"ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle"
+302,"ground beetle, carabid beetle"
+303,"long-horned beetle, longicorn, longicorn beetle"
+304,"leaf beetle, chrysomelid"
+305,dung beetle
+306,rhinoceros beetle
+307,weevil
+308,fly
+309,bee
+310,"ant, emmet, pismire"
+311,"grasshopper, hopper"
+312,cricket
+313,"walking stick, walkingstick, stick insect"
+314,"cockroach, roach"
+315,"mantis, mantid"
+316,"cicada, cicala"
+317,leafhopper
+318,"lacewing, lacewing fly"
+319,"dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk"
+320,damselfly
+321,admiral
+322,"ringlet, ringlet butterfly"
+323,"monarch, monarch butterfly, milkweed butterfly, Danaus plexippus"
+324,cabbage butterfly
+325,"sulphur butterfly, sulfur butterfly"
+326,"lycaenid, lycaenid butterfly"
+327,"starfish, sea star"
+328,sea urchin
+329,"sea cucumber, holothurian"
+330,"wood rabbit, cottontail, cottontail rabbit"
+331,hare
+332,"Angora, Angora rabbit"
+333,hamster
+334,"porcupine, hedgehog"
+335,"fox squirrel, eastern fox squirrel, Sciurus niger"
+336,marmot
+337,beaver
+338,"guinea pig, Cavia cobaya"
+339,sorrel
+340,zebra
+341,"hog, pig, grunter, squealer, Sus scrofa"
+342,"wild boar, boar, Sus scrofa"
+343,warthog
+344,"hippopotamus, hippo, river horse, Hippopotamus amphibius"
+345,ox
+346,"water buffalo, water ox, Asiatic buffalo, Bubalus bubalis"
+347,bison
+348,"ram, tup"
+349,"bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis"
+350,"ibex, Capra ibex"
+351,hartebeest
+352,"impala, Aepyceros melampus"
+353,gazelle
+354,"Arabian camel, dromedary, Camelus dromedarius"
+355,llama
+356,weasel
+357,mink
+358,"polecat, fitch, foulmart, foumart, Mustela putorius"
+359,"black-footed ferret, ferret, Mustela nigripes"
+360,otter
+361,"skunk, polecat, wood pussy"
+362,badger
+363,armadillo
+364,"three-toed sloth, ai, Bradypus tridactylus"
+365,"orangutan, orang, orangutang, Pongo pygmaeus"
+366,"gorilla, Gorilla gorilla"
+367,"chimpanzee, chimp, Pan troglodytes"
+368,"gibbon, Hylobates lar"
+369,"siamang, Hylobates syndactylus, Symphalangus syndactylus"
+370,"guenon, guenon monkey"
+371,"patas, hussar monkey, Erythrocebus patas"
+372,baboon
+373,macaque
+374,langur
+375,"colobus, colobus monkey"
+376,"proboscis monkey, Nasalis larvatus"
+377,marmoset
+378,"capuchin, ringtail, Cebus capucinus"
+379,"howler monkey, howler"
+380,"titi, titi monkey"
+381,"spider monkey, Ateles geoffroyi"
+382,"squirrel monkey, Saimiri sciureus"
+383,"Madagascar cat, ring-tailed lemur, Lemur catta"
+384,"indri, indris, Indri indri, Indri brevicaudatus"
+385,"Indian elephant, Elephas maximus"
+386,"African elephant, Loxodonta africana"
+387,"lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens"
+388,"giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca"
+389,"barracouta, snoek"
+390,eel
+391,"coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch"
+392,"rock beauty, Holocanthus tricolor"
+393,anemone fish
+394,sturgeon
+395,"gar, garfish, garpike, billfish, Lepisosteus osseus"
+396,lionfish
+397,"puffer, pufferfish, blowfish, globefish"
+398,abacus
+399,abaya
+400,"academic gown, academic robe, judge's robe"
+401,"accordion, piano accordion, squeeze box"
+402,acoustic guitar
+403,"aircraft carrier, carrier, flattop, attack aircraft carrier"
+404,airliner
+405,"airship, dirigible"
+406,altar
+407,ambulance
+408,"amphibian, amphibious vehicle"
+409,analog clock
+410,"apiary, bee house"
+411,apron
+412,"ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin"
+413,"assault rifle, assault gun"
+414,"backpack, back pack, knapsack, packsack, rucksack, haversack"
+415,"bakery, bakeshop, bakehouse"
+416,"balance beam, beam"
+417,balloon
+418,"ballpoint, ballpoint pen, ballpen, Biro"
+419,Band Aid
+420,banjo
+421,"bannister, banister, balustrade, balusters, handrail"
+422,barbell
+423,barber chair
+424,barbershop
+425,barn
+426,barometer
+427,"barrel, cask"
+428,"barrow, garden cart, lawn cart, wheelbarrow"
+429,baseball
+430,basketball
+431,bassinet
+432,bassoon
+433,"bathing cap, swimming cap"
+434,bath towel
+435,"bathtub, bathing tub, bath, tub"
+436,"beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon"
+437,"beacon, lighthouse, beacon light, pharos"
+438,beaker
+439,"bearskin, busby, shako"
+440,beer bottle
+441,beer glass
+442,"bell cote, bell cot"
+443,bib
+444,"bicycle-built-for-two, tandem bicycle, tandem"
+445,"bikini, two-piece"
+446,"binder, ring-binder"
+447,"binoculars, field glasses, opera glasses"
+448,birdhouse
+449,boathouse
+450,"bobsled, bobsleigh, bob"
+451,"bolo tie, bolo, bola tie, bola"
+452,"bonnet, poke bonnet"
+453,bookcase
+454,"bookshop, bookstore, bookstall"
+455,bottlecap
+456,bow
+457,"bow tie, bow-tie, bowtie"
+458,"brass, memorial tablet, plaque"
+459,"brassiere, bra, bandeau"
+460,"breakwater, groin, groyne, mole, bulwark, seawall, jetty"
+461,"breastplate, aegis, egis"
+462,broom
+463,"bucket, pail"
+464,buckle
+465,bulletproof vest
+466,"bullet train, bullet"
+467,"butcher shop, meat market"
+468,"cab, hack, taxi, taxicab"
+469,"caldron, cauldron"
+470,"candle, taper, wax light"
+471,cannon
+472,canoe
+473,"can opener, tin opener"
+474,cardigan
+475,car mirror
+476,"carousel, carrousel, merry-go-round, roundabout, whirligig"
+477,"carpenter's kit, tool kit"
+478,carton
+479,car wheel
+480,"cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM"
+481,cassette
+482,cassette player
+483,castle
+484,catamaran
+485,CD player
+486,"cello, violoncello"
+487,"cellular telephone, cellular phone, cellphone, cell, mobile phone"
+488,chain
+489,chainlink fence
+490,"chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour"
+491,"chain saw, chainsaw"
+492,chest
+493,"chiffonier, commode"
+494,"chime, bell, gong"
+495,"china cabinet, china closet"
+496,Christmas stocking
+497,"church, church building"
+498,"cinema, movie theater, movie theatre, movie house, picture palace"
+499,"cleaver, meat cleaver, chopper"
+500,cliff dwelling
+501,cloak
+502,"clog, geta, patten, sabot"
+503,cocktail shaker
+504,coffee mug
+505,coffeepot
+506,"coil, spiral, volute, whorl, helix"
+507,combination lock
+508,"computer keyboard, keypad"
+509,"confectionery, confectionary, candy store"
+510,"container ship, containership, container vessel"
+511,convertible
+512,"corkscrew, bottle screw"
+513,"cornet, horn, trumpet, trump"
+514,cowboy boot
+515,"cowboy hat, ten-gallon hat"
+516,cradle
+517,crane
+518,crash helmet
+519,crate
+520,"crib, cot"
+521,Crock Pot
+522,croquet ball
+523,crutch
+524,cuirass
+525,"dam, dike, dyke"
+526,desk
+527,desktop computer
+528,"dial telephone, dial phone"
+529,"diaper, nappy, napkin"
+530,digital clock
+531,digital watch
+532,"dining table, board"
+533,"dishrag, dishcloth"
+534,"dishwasher, dish washer, dishwashing machine"
+535,"disk brake, disc brake"
+536,"dock, dockage, docking facility"
+537,"dogsled, dog sled, dog sleigh"
+538,dome
+539,"doormat, welcome mat"
+540,"drilling platform, offshore rig"
+541,"drum, membranophone, tympan"
+542,drumstick
+543,dumbbell
+544,Dutch oven
+545,"electric fan, blower"
+546,electric guitar
+547,electric locomotive
+548,entertainment center
+549,envelope
+550,espresso maker
+551,face powder
+552,"feather boa, boa"
+553,"file, file cabinet, filing cabinet"
+554,fireboat
+555,"fire engine, fire truck"
+556,"fire screen, fireguard"
+557,"flagpole, flagstaff"
+558,"flute, transverse flute"
+559,folding chair
+560,football helmet
+561,forklift
+562,fountain
+563,fountain pen
+564,four-poster
+565,freight car
+566,"French horn, horn"
+567,"frying pan, frypan, skillet"
+568,fur coat
+569,"garbage truck, dustcart"
+570,"gasmask, respirator, gas helmet"
+571,"gas pump, gasoline pump, petrol pump, island dispenser"
+572,goblet
+573,go-kart
+574,golf ball
+575,"golfcart, golf cart"
+576,gondola
+577,"gong, tam-tam"
+578,gown
+579,"grand piano, grand"
+580,"greenhouse, nursery, glasshouse"
+581,"grille, radiator grille"
+582,"grocery store, grocery, food market, market"
+583,guillotine
+584,hair slide
+585,hair spray
+586,half track
+587,hammer
+588,hamper
+589,"hand blower, blow dryer, blow drier, hair dryer, hair drier"
+590,"hand-held computer, hand-held microcomputer"
+591,"handkerchief, hankie, hanky, hankey"
+592,"hard disc, hard disk, fixed disk"
+593,"harmonica, mouth organ, harp, mouth harp"
+594,harp
+595,"harvester, reaper"
+596,hatchet
+597,holster
+598,"home theater, home theatre"
+599,honeycomb
+600,"hook, claw"
+601,"hoopskirt, crinoline"
+602,"horizontal bar, high bar"
+603,"horse cart, horse-cart"
+604,hourglass
+605,iPod
+606,"iron, smoothing iron"
+607,jack-o'-lantern
+608,"jean, blue jean, denim"
+609,"jeep, landrover"
+610,"jersey, T-shirt, tee shirt"
+611,jigsaw puzzle
+612,"jinrikisha, ricksha, rickshaw"
+613,joystick
+614,kimono
+615,knee pad
+616,knot
+617,"lab coat, laboratory coat"
+618,ladle
+619,"lampshade, lamp shade"
+620,"laptop, laptop computer"
+621,"lawn mower, mower"
+622,"lens cap, lens cover"
+623,"letter opener, paper knife, paperknife"
+624,library
+625,lifeboat
+626,"lighter, light, igniter, ignitor"
+627,"limousine, limo"
+628,"liner, ocean liner"
+629,"lipstick, lip rouge"
+630,Loafer
+631,lotion
+632,"loudspeaker, speaker, speaker unit, loudspeaker system, speaker system"
+633,"loupe, jeweler's loupe"
+634,"lumbermill, sawmill"
+635,magnetic compass
+636,"mailbag, postbag"
+637,"mailbox, letter box"
+638,maillot
+639,"maillot, tank suit"
+640,manhole cover
+641,maraca
+642,"marimba, xylophone"
+643,mask
+644,matchstick
+645,maypole
+646,"maze, labyrinth"
+647,measuring cup
+648,"medicine chest, medicine cabinet"
+649,"megalith, megalithic structure"
+650,"microphone, mike"
+651,"microwave, microwave oven"
+652,military uniform
+653,milk can
+654,minibus
+655,"miniskirt, mini"
+656,minivan
+657,missile
+658,mitten
+659,mixing bowl
+660,"mobile home, manufactured home"
+661,Model T
+662,modem
+663,monastery
+664,monitor
+665,moped
+666,mortar
+667,mortarboard
+668,mosque
+669,mosquito net
+670,"motor scooter, scooter"
+671,"mountain bike, all-terrain bike, off-roader"
+672,mountain tent
+673,"mouse, computer mouse"
+674,mousetrap
+675,moving van
+676,muzzle
+677,nail
+678,neck brace
+679,necklace
+680,nipple
+681,"notebook, notebook computer"
+682,obelisk
+683,"oboe, hautboy, hautbois"
+684,"ocarina, sweet potato"
+685,"odometer, hodometer, mileometer, milometer"
+686,oil filter
+687,"organ, pipe organ"
+688,"oscilloscope, scope, cathode-ray oscilloscope, CRO"
+689,overskirt
+690,oxcart
+691,oxygen mask
+692,packet
+693,"paddle, boat paddle"
+694,"paddlewheel, paddle wheel"
+695,padlock
+696,paintbrush
+697,"pajama, pyjama, pj's, jammies"
+698,palace
+699,"panpipe, pandean pipe, syrinx"
+700,paper towel
+701,"parachute, chute"
+702,"parallel bars, bars"
+703,park bench
+704,parking meter
+705,"passenger car, coach, carriage"
+706,"patio, terrace"
+707,"pay-phone, pay-station"
+708,"pedestal, plinth, footstall"
+709,"pencil box, pencil case"
+710,pencil sharpener
+711,"perfume, essence"
+712,Petri dish
+713,photocopier
+714,"pick, plectrum, plectron"
+715,pickelhaube
+716,"picket fence, paling"
+717,"pickup, pickup truck"
+718,pier
+719,"piggy bank, penny bank"
+720,pill bottle
+721,pillow
+722,ping-pong ball
+723,pinwheel
+724,"pirate, pirate ship"
+725,"pitcher, ewer"
+726,"plane, carpenter's plane, woodworking plane"
+727,planetarium
+728,plastic bag
+729,plate rack
+730,"plow, plough"
+731,"plunger, plumber's helper"
+732,"Polaroid camera, Polaroid Land camera"
+733,pole
+734,"police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria"
+735,poncho
+736,"pool table, billiard table, snooker table"
+737,"pop bottle, soda bottle"
+738,"pot, flowerpot"
+739,potter's wheel
+740,power drill
+741,"prayer rug, prayer mat"
+742,printer
+743,"prison, prison house"
+744,"projectile, missile"
+745,projector
+746,"puck, hockey puck"
+747,"punching bag, punch bag, punching ball, punchball"
+748,purse
+749,"quill, quill pen"
+750,"quilt, comforter, comfort, puff"
+751,"racer, race car, racing car"
+752,"racket, racquet"
+753,radiator
+754,"radio, wireless"
+755,"radio telescope, radio reflector"
+756,rain barrel
+757,"recreational vehicle, RV, R.V."
+758,reel
+759,reflex camera
+760,"refrigerator, icebox"
+761,"remote control, remote"
+762,"restaurant, eating house, eating place, eatery"
+763,"revolver, six-gun, six-shooter"
+764,rifle
+765,"rocking chair, rocker"
+766,rotisserie
+767,"rubber eraser, rubber, pencil eraser"
+768,rugby ball
+769,"rule, ruler"
+770,running shoe
+771,safe
+772,safety pin
+773,"saltshaker, salt shaker"
+774,sandal
+775,sarong
+776,"sax, saxophone"
+777,scabbard
+778,"scale, weighing machine"
+779,school bus
+780,schooner
+781,scoreboard
+782,"screen, CRT screen"
+783,screw
+784,screwdriver
+785,"seat belt, seatbelt"
+786,sewing machine
+787,"shield, buckler"
+788,"shoe shop, shoe-shop, shoe store"
+789,shoji
+790,shopping basket
+791,shopping cart
+792,shovel
+793,shower cap
+794,shower curtain
+795,ski
+796,ski mask
+797,sleeping bag
+798,"slide rule, slipstick"
+799,sliding door
+800,"slot, one-armed bandit"
+801,snorkel
+802,snowmobile
+803,"snowplow, snowplough"
+804,soap dispenser
+805,soccer ball
+806,sock
+807,"solar dish, solar collector, solar furnace"
+808,sombrero
+809,soup bowl
+810,space bar
+811,space heater
+812,space shuttle
+813,spatula
+814,speedboat
+815,"spider web, spider's web"
+816,spindle
+817,"sports car, sport car"
+818,"spotlight, spot"
+819,stage
+820,steam locomotive
+821,steel arch bridge
+822,steel drum
+823,stethoscope
+824,stole
+825,stone wall
+826,"stopwatch, stop watch"
+827,stove
+828,strainer
+829,"streetcar, tram, tramcar, trolley, trolley car"
+830,stretcher
+831,"studio couch, day bed"
+832,"stupa, tope"
+833,"submarine, pigboat, sub, U-boat"
+834,"suit, suit of clothes"
+835,sundial
+836,sunglass
+837,"sunglasses, dark glasses, shades"
+838,"sunscreen, sunblock, sun blocker"
+839,suspension bridge
+840,"swab, swob, mop"
+841,sweatshirt
+842,"swimming trunks, bathing trunks"
+843,swing
+844,"switch, electric switch, electrical switch"
+845,syringe
+846,table lamp
+847,"tank, army tank, armored combat vehicle, armoured combat vehicle"
+848,tape player
+849,teapot
+850,"teddy, teddy bear"
+851,"television, television system"
+852,tennis ball
+853,"thatch, thatched roof"
+854,"theater curtain, theatre curtain"
+855,thimble
+856,"thresher, thrasher, threshing machine"
+857,throne
+858,tile roof
+859,toaster
+860,"tobacco shop, tobacconist shop, tobacconist"
+861,toilet seat
+862,torch
+863,totem pole
+864,"tow truck, tow car, wrecker"
+865,toyshop
+866,tractor
+867,"trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi"
+868,tray
+869,trench coat
+870,"tricycle, trike, velocipede"
+871,trimaran
+872,tripod
+873,triumphal arch
+874,"trolleybus, trolley coach, trackless trolley"
+875,trombone
+876,"tub, vat"
+877,turnstile
+878,typewriter keyboard
+879,umbrella
+880,"unicycle, monocycle"
+881,"upright, upright piano"
+882,"vacuum, vacuum cleaner"
+883,vase
+884,vault
+885,velvet
+886,vending machine
+887,vestment
+888,viaduct
+889,"violin, fiddle"
+890,volleyball
+891,waffle iron
+892,wall clock
+893,"wallet, billfold, notecase, pocketbook"
+894,"wardrobe, closet, press"
+895,"warplane, military plane"
+896,"washbasin, handbasin, washbowl, lavabo, wash-hand basin"
+897,"washer, automatic washer, washing machine"
+898,water bottle
+899,water jug
+900,water tower
+901,whiskey jug
+902,whistle
+903,wig
+904,window screen
+905,window shade
+906,Windsor tie
+907,wine bottle
+908,wing
+909,wok
+910,wooden spoon
+911,"wool, woolen, woollen"
+912,"worm fence, snake fence, snake-rail fence, Virginia fence"
+913,wreck
+914,yawl
+915,yurt
+916,"web site, website, internet site, site"
+917,comic book
+918,"crossword puzzle, crossword"
+919,street sign
+920,"traffic light, traffic signal, stoplight"
+921,"book jacket, dust cover, dust jacket, dust wrapper"
+922,menu
+923,plate
+924,guacamole
+925,consomme
+926,"hot pot, hotpot"
+927,trifle
+928,"ice cream, icecream"
+929,"ice lolly, lolly, lollipop, popsicle"
+930,French loaf
+931,"bagel, beigel"
+932,pretzel
+933,cheeseburger
+934,"hotdog, hot dog, red hot"
+935,mashed potato
+936,head cabbage
+937,broccoli
+938,cauliflower
+939,"zucchini, courgette"
+940,spaghetti squash
+941,acorn squash
+942,butternut squash
+943,"cucumber, cuke"
+944,"artichoke, globe artichoke"
+945,bell pepper
+946,cardoon
+947,mushroom
+948,Granny Smith
+949,strawberry
+950,orange
+951,lemon
+952,fig
+953,"pineapple, ananas"
+954,banana
+955,"jackfruit, jak, jack"
+956,custard apple
+957,pomegranate
+958,hay
+959,carbonara
+960,"chocolate sauce, chocolate syrup"
+961,dough
+962,"meat loaf, meatloaf"
+963,"pizza, pizza pie"
+964,potpie
+965,burrito
+966,red wine
+967,espresso
+968,cup
+969,eggnog
+970,alp
+971,bubble
+972,"cliff, drop, drop-off"
+973,coral reef
+974,geyser
+975,"lakeside, lakeshore"
+976,"promontory, headland, head, foreland"
+977,"sandbar, sand bar"
+978,"seashore, coast, seacoast, sea-coast"
+979,"valley, vale"
+980,volcano
+981,"ballplayer, baseball player"
+982,"groom, bridegroom"
+983,scuba diver
+984,rapeseed
+985,daisy
+986,"yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum"
+987,corn
+988,acorn
+989,"hip, rose hip, rosehip"
+990,"buckeye, horse chestnut, conker"
+991,coral fungus
+992,agaric
+993,gyromitra
+994,"stinkhorn, carrion fungus"
+995,earthstar
+996,"hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa"
+997,bolete
+998,"ear, spike, capitulum"
+999,"toilet tissue, toilet paper, bathroom tissue"
diff --git a/rust/runtime/src/array.rs b/rust/runtime/src/array.rs
index c38b3ff8e527f..896812a02bbbb 100644
--- a/rust/runtime/src/array.rs
+++ b/rust/runtime/src/array.rs
@@ -279,7 +279,7 @@ impl<'a> Tensor<'a> {
}
}
- pub(crate) fn as_dltensor(&self, flatten: bool) -> DLTensor {
+ pub fn as_dltensor(&self, flatten: bool) -> DLTensor {
assert!(!flatten || self.is_contiguous());
DLTensor {
data: unsafe { self.data.as_mut_ptr().offset(self.byte_offset) } as *mut c_void,