diff --git a/.github/workflows/jupyter-test.yml b/.github/workflows/jupyter-test.yml
new file mode 100755
index 0000000000..f12cf6ad9b
--- /dev/null
+++ b/.github/workflows/jupyter-test.yml
@@ -0,0 +1,31 @@
+# on:
+# push:
+# tags:
+# - '*'
+
+# jobs:
+# test:
+# name: test-notebook-${{matrix.config.name}}
+# runs-on: ${{matrix.config.os}}
+# strategy:
+# matrix:
+# config:
+# - {name: x86_64-macos, os: macos-latest}
+# - {name: x86_64-linux, os: ubuntu-latest}
+# - {name: x86_64-windows, os: windows-latest}
+
+# steps:
+# - uses: actions/checkout@v2
+
+# - name: Setup Python
+# uses: actions/setup-python@v2
+# with:
+# python-version: 3.7
+
+# - name: Install dependencies
+# run: pip install --upgrade pip && pip install jupyterlab pytest nbmake
+
+# - name: Run tests
+# run: pytest --nbmake examples/user_guide
+# env:
+# PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION: python
\ No newline at end of file
diff --git a/README.md b/README.md
index 1467befbfe..89f05f8ef4 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,9 @@
-[![License](https://img.shields.io/badge/license-Apache%202-blue)](https://raw.githubusercontent.com/kendryte/nncase/master/LICENSE)
-[![compiler-build](https://github.com/kendryte/nncase/actions/workflows/compiler-build.yml/badge.svg)](https://github.com/kendryte/nncase/actions/workflows/compiler-build.yml)
+[![GitHub repository](https://img.shields.io/badge/github-repository-blue?logo=github&style=plastic)](https://github.com/kendryte/nncase)
+[![Gitee repository](https://img.shields.io/badge/gitee-repository-blue?logo=gitee&style=plastic)](https://gitee.com/kendryte/nncase)
+[![GitHub release](https://img.shields.io/github/v/release/kendryte/nncase?color=brightgreen&display_name=tag&logo=github&style=plastic)](https://github.com/kendryte/nncase/releases)
`nncase` is a neural network compiler for AI accelerators.
@@ -14,6 +15,7 @@
Telegram: [nncase community](https://t.me/joinchat/PPcEPZMLaTViNDI1)
## Install from binaries
+
## 从二进制安装
Download prebuilt binaries from [Release](https://github.com/kendryte/nncase/releases).
@@ -21,40 +23,47 @@ Download prebuilt binaries from [Release](https://github.com/kendryte/nncase/rel
下载预编译的二进制文件 [Release](https://github.com/kendryte/nncase/releases)。
## Build from source
+
## 从源码编译
[Build from source](./docs/build.md)
## Supported operators
+
## 支持的算子
- [TFLite ops](./docs/tflite_ops.md)
- [Caffe ops](./docs/caffe_ops.md)
- [ONNX ops](./docs/onnx_ops.md)
-
## K210/K510
+
- [Usage](https://github.com/kendryte/nncase/blob/release/1.0/docs/USAGE_EN.md)
- [FAQ](https://github.com/kendryte/nncase/blob/release/1.0/docs/FAQ_EN.md)
- [使用说明](https://github.com/kendryte/nncase/blob/release/1.0/docs/USAGE_ZH.md)
- [常见问题](https://github.com/kendryte/nncase/blob/release/1.0/docs/FAQ_ZH.md)
- [Example](https://github.com/kendryte/nncase/blob/release/1.0/examples/user_guide/)
+
## K230
+
- [Usage](./docs/USAGE_v2_EN.md)
- [FAQ](./docs/FAQ_EN.md)
+- [Example](./examples/user_guide/k230_simulate-EN.ipynb)
- [使用说明](./docs/USAGE_v2.md)
- [常见问题](./docs/FAQ_ZH.md)
-- [Example](./examples/user_guide/)
+- [示例](./examples/user_guide/k230_simulate-ZH.ipynb)
## Resources
-## 资源
+## 资源
+### K210
- [K210_Yolo_framework](https://github.com/zhen8838/K210_Yolo_framework)
-- [Shts! 's Blog (Japanese)](https://www.shtsno24.tokyo/2020/03/nncase-v020.html)
+- [Shts!'s Blog (Japanese)](https://www.shtsno24.tokyo/2020/03/nncase-v020.html)
---
## Architecture
+
## 架构
diff --git a/conanfile.py b/conanfile.py
index d4440757b9..8a3a0c72b7 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -51,6 +51,7 @@ def requirements(self):
if self.options.tests:
self.requires('gtest/1.10.0')
self.requires('ortki/0.0.2')
+ self.requires('rapidjson/1.1.x')
if self.options.python:
self.requires('pybind11/2.6.1')
diff --git a/docs/FAQ_EN.md b/docs/FAQ_EN.md
index b34319f186..3360df5da0 100644
--- a/docs/FAQ_EN.md
+++ b/docs/FAQ_EN.md
@@ -1,6 +1,6 @@
# FAQ
-[TOC]
+[toc]
## 1. Error installing `whl` package
@@ -8,9 +8,7 @@
A: Upgrade pip >= 20.3 using `pip install --upgrade pip`
-
-
-----
+---
## 2. Compile-time errors
@@ -18,7 +16,7 @@ A: Upgrade pip >= 20.3 using `pip install --upgrade pip`
#### 2.1.1 Q: Compile model reported error "System.NotSupportedException: Not Supported *** op: XXX"
-A: This exception indicates that there are operators, `XXX`, that are not yet supported. You can create a issue in [nncase Github Issue](https://github.com/kendryte/nncase/issues). In the current directory `***_ops.md`, you can view the operators already supported in each inference framework.
+A: This exception indicates that there are operators, `XXX`, that are not yet supported. You can create a issue in [nncase Github Issue](https://github.com/kendryte/nncase/issues). In the current directory `***_ops.md`, you can view the operators already supported in each inference framework.
If 'XXX' belongs to quantization-related operators such as `FAKE_QUANT`, `DEQUANTIZE`, `QUANTIZE`, it indicates that the current model is a quantized model, and 'nncase' does not currently support such models, please compile `kmodel` using a floating point model.
@@ -28,15 +26,19 @@ If 'XXX' belongs to quantization-related operators such as `FAKE_QUANT`, `DEQUAN
A: Use `sudo gedit /proc/sys/fs/inotify/max_user_instances` to change 128 to a larger value.
+### 2.3 `initialize` error
+
+#### 2.3.1 Q:"RuntimeError: Failed to initialize hostfxr" appears when compiling the kmodel.
+A1:Need to install dotnet-7.0.
-----
+---
## 3. Runtime errors
### 3.1 Q: Compiling `kmodel` is fine, but when inferring, the error `nncase.simulator.k230.sc: not found`occurs.
-A: You need to check whether the versions of `nncase` and `nncase-kpu` are the same.
+A: First, make sure that the path of the nncase installation is added to the PATH environment variable. You need to check whether the versions of `nncase` and `nncase-kpu` are the same.
```shell
root@a52f1cacf581:/mnt# pip list | grep nncase
@@ -46,9 +48,7 @@ nncase-kpu 2.1.1.20230721
If inconsistent, install the same version of the Python package `pip install nncase==x.x.x.x nncase-kpu==x.x.x.x`
-
-
-----
+---
## 4. Runtime error on k230 development board
diff --git a/docs/FAQ_ZH.md b/docs/FAQ_ZH.md
index b469d00017..04714cc500 100644
--- a/docs/FAQ_ZH.md
+++ b/docs/FAQ_ZH.md
@@ -6,9 +6,7 @@
A:升级 pip >= 20.3 `pip install --upgrade pip`
-
-
-----
+---
## 2.编译模型时报错
@@ -16,25 +14,27 @@ A:升级 pip >= 20.3 `pip install --upgrade pip`
#### 2.1.1 Q:编译模型报错“System.NotSupportedException: Not Supported *** op: XXX”。
-A:该异常表明`XXX`算子尚未支持,可以在[nncase Github Issue](https://github.com/kendryte/nncase/issues)中提需求。当前目录下 `***_ops.md`文档,可以查看各个推理框架中已经支持的算子。
+A:该异常表明 `XXX`算子尚未支持,可以在[nncase Github Issue](https://github.com/kendryte/nncase/issues)中提需求。当前目录下 `***_ops.md`文档,可以查看各个推理框架中已经支持的算子。
-如果`XXX`属于 `FAKE_QUANT`、`DEQUANTIZE`、`QUANTIZE`等量化相关的算子,表明当前模型属于量化模型,`nncase`目前不支持这类模型,请使用浮点模型来编译`kmodel`。
+如果 `XXX`属于 `FAKE_QUANT`、`DEQUANTIZE`、`QUANTIZE`等量化相关的算子,表明当前模型属于量化模型,`nncase`目前不支持这类模型,请使用浮点模型来编译 `kmodel`。
### 2.2 `System.IO.IOException`
-#### 2.2.1 Q:下载`nncase`仓库自己编译后,运行test出现这个错误"The configured user limit (128) on the number of inotify instances has been reached, or the per-process limit on the number of open file descriptors has been reached"。
+#### 2.2.1 Q:下载 `nncase`仓库自己编译后,运行test出现这个错误"The configured user limit (128) on the number of inotify instances has been reached, or the per-process limit on the number of open file descriptors has been reached"。
A1:使用 `sudo gedit /proc/sys/fs/inotify/max_user_instances`修改128为更大的值即可。
+### 2.3 `initialize`相关
+#### 2.3.1 Q:编译模型出现如下错误`RuntimeError: Failed to initialize hostfxr`
+A1:需要安装dotnet-7.0
-
-----
+---
## 3. 推理时报错
-### 3.1 Q:在编译kmodel正常, 但是推理的时候出现`nncase.simulator.k230.sc: not found`的错误。
+### 3.1 Q:在编译kmodel正常, 但是推理的时候出现 `nncase.simulator.k230.sc: not found`的错误。
-A:需要检查`nncase`和`nncase-kpu`的版本是否一致。
+A:将nncase的安装路径加入到 `PATH`环境变量中,同时检查一下nncase和nncase-kpu版本是否一致。
```shell
root@a52f1cacf581:/mnt# pip list | grep nncase
@@ -44,9 +44,7 @@ nncase-kpu 2.1.1.20230721
如果不一致,请安装相同版本的Python包 `pip install nncase==x.x.x.x nncase-kpu==x.x.x.x`。
-
-
-----
+---
## 4. k230开发板推理时报错
diff --git a/docs/USAGE_v2.md b/docs/USAGE_v2.md
index 224ebd33c5..68944d7bbf 100644
--- a/docs/USAGE_v2.md
+++ b/docs/USAGE_v2.md
@@ -46,7 +46,15 @@ Type "help", "copyright", "credits" or "license" for more information.
k230模型编译推理参考Jupyter脚本:[User_guide](../examples/user_guide/k230_simulate.ipynb),脚本中包含了单输入和多输入的示例。
-如果在Docker中运行Jupyter脚本,可以参考[配置Jupyter lab](https://github.com/kunjing96/docker-jupyterlab#32-%E9%85%8D%E7%BD%AEjupyter-lab)进行配置。
+如果在Docker中运行Jupyter脚本,可以参考以下命令,之后在浏览器窗口打开即可。
+
+```shell
+docker run -it --rm --privileged=true -p 8889:8889 --name Kendryte -v `pwd`:/mnt -w /mnt ghcr.io/kendryte/k230_sdk /bin/bash -c "/bin/bash
+
+pip install jupyterlab
+
+jupyter-lab --ip 0.0.0.0 --allow-root
+```
在执行脚本之前需要根据自身需求修改以下内容:
@@ -153,6 +161,8 @@ subgraph A
end
```
+##### 动态shape参数
+详见[动态shape参数说明](./shape_bucket.md)
#### 代码示例
diff --git a/docs/USAGE_v2_EN.md b/docs/USAGE_v2_EN.md
index 4ff2a12942..5800ccfc7e 100644
--- a/docs/USAGE_v2_EN.md
+++ b/docs/USAGE_v2_EN.md
@@ -46,7 +46,16 @@ Type "help", "copyright", "credits" or "license" for more information.
Model compilation, inference for k230 can be found in the Jupyter script [User_guide](../examples/user_guide/k230_simulate.ipynb), this script contains single and multiple input examples.
-If you run Jupyter scripts in Docker, you can refer to [Configure Jupyter lab](https://github.com/kunjing96/docker-jupyterlab#32-%E9%85%8D%E7%BD%AEjupyter-lab) to configure them.
+If you run the Jupyter script in Docker, you can refer to the command and then open it in your browser.
+
+```shell
+docker run -it --rm --privileged=true -p 8889:8889 --name Kendryte -v `pwd`:/mnt -w /mnt ghcr.io/kendryte/k230_sdk /bin/bash -c "/bin/bash
+
+pip install jupyterlab
+
+jupyter-lab --ip 0.0.0.0 --allow-root
+```
+
You need to modify the following to suit your needs before executing the script:
@@ -154,6 +163,9 @@ subgraph A
```
+##### Dynamice shape args
+Refer to[Dynamic shape args description](./shape_bucket.md)
+
#### Example
```python
diff --git a/docs/shape_bucket.md b/docs/shape_bucket.md
new file mode 100644
index 0000000000..7af9f2a459
--- /dev/null
+++ b/docs/shape_bucket.md
@@ -0,0 +1,48 @@
+# ShapeBucket使用说明
+
+ShapeBucket是针对动态shape的一种解决方案,会根据输入长度的范围以及指定的段的数量来对动态shape进行优化。该功能默认为false,需要打开对应的option才能生效,除了指定对应的字段信息,其他流程与编译静态模型没有区别。
+
+对应的不同CompileOptions中的字段
+
+| 字段名称 | 类型 | 是否必须 | 描述 |
+| --------------------------- | --------------------- | -------- | --------------------------------------------------------------- |
+| shape_bucket_enable | bool | 是 | 是否开启ShapeBucket功能,默认为False。在 `dump_ir=True`时生效 |
+| shape_bucket_range_info | Dict[str, [int, int]] | 是 | 每个输入shape维度信息中的变量的范围,最小值必须大于等于1 |
+| shape_bucket_segments_count | int | 是 | 输入变量的范围划分为几段 |
+| shape_bucket_fix_var_map | Dict[str, int] | 否 | 固定shape维度信息中的变量为特定的值 |
+
+## onnx
+
+在模型的shape中会有些维度为变量名字,这里以一个onnx模型的输入为例
+
+> tokens: int64[batch_size, tgt_seq_len]
+>
+> step: float32[seq_len, batch_size]
+
+对应这个输入有如下的配置
+
+```python
+shape_bucket_options = nncase.ShapeBucketOptions()
+shape_bucket_options.shape_bucket_enable = True
+shape_bucket_options.shape_bucket_range_info = {"seq_len":[1, 100], "tgt_seq_len":[1, 100]}
+shape_bucket_options.shape_bucket_segments_count = 2
+shape_bucket_options.shape_bucket_fix_var_map = {"batch_size" : 3}
+```
+
+shape的维度信息中存在seq_len,tgt_seq_len,batch_size这三个变量。首先是batch_size,虽然是变量的但实际应用的时候固定为3,因此在**fix_var_map**中添加batch_size = 3,在运行的时候会将这个维度固定为3。
+
+seq_len,tgt_seq_len两个是实际会发生改变的,因此需要配置这两个变量的实际范围,也就是**range_info**的信息。**segments_count**是实际分段的数量,会根据范围等分为几份,对应的编译时间也会相应增加几倍。
+
+## tflite
+
+tflite的模型与onnx不同,shape上暂未标注维度的名称,目前只支持输入中具有一个维度是动态的,并且名称统一配置为-1,配置方式如下
+
+```cpp
+shape_bucket_options = nncase.ShapeBucketOptions()
+shape_bucket_options.shape_bucket_enable = True
+shape_bucket_options.shape_bucket_range_info = {"-1":[1, 100]}
+shape_bucket_options.shape_bucket_segments_count = 2
+shape_bucket_options.shape_bucket_fix_var_map = {"batch_size" : 3}
+```
+
+配置完这些选项后整个编译的流程和静态shape一致。
diff --git a/examples/user_guide/k230_simulate-EN.ipynb b/examples/user_guide/k230_simulate-EN.ipynb
new file mode 100644
index 0000000000..a8630394df
--- /dev/null
+++ b/examples/user_guide/k230_simulate-EN.ipynb
@@ -0,0 +1,437 @@
+{
+ "cells": [
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "38c8a2f0-423b-4c62-8cf0-235e881e1d35",
+ "metadata": {},
+ "source": [
+ "If you have any questions, you can join the `QQ group:790699378`, or `create an issue` in the nncase repo:[click here](https://github.com/kendryte/nncase/issues)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "4beb4c04-ab79-4e1a-a7ad-ba53d9a9b123",
+ "metadata": {},
+ "source": [
+ "# 1. Install libs and set python env"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "82a8f9c1-c2bf-4270-9f1f-ac25c9fdd898",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "!pip install --upgrade pip\n",
+ "!pip install nncase --timeout=1000\n",
+ "!pip install nncase-kpu --timeout=1000\n",
+ "!pip install onnx onnxsim scikit-learn\n",
+ "\n",
+ "# # nncase-2.x need dotnet-7\n",
+ "# # Ubuntu use apt to install dotnet-7.0 (The docker has installed dotnet7.0)\n",
+ "!sudo apt-get install -y dotnet-sdk-7.0"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "a17fa3cf",
+ "metadata": {},
+ "source": [
+ "## auto set enviroment"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7cdadfc6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import sys\n",
+ "import subprocess\n",
+ "\n",
+ "result = subprocess.run([\"pip\", \"show\", \"nncase\"], capture_output=True)\n",
+ "\n",
+ "split_flag = \"\\n\"\n",
+ "if sys.platform == \"win32\":\n",
+ " split_flag = \"\\r\\n\"\n",
+ "\n",
+ "location_s = [i for i in result.stdout.decode().split(split_flag) if i.startswith(\"Location:\")]\n",
+ "location = location_s[0].split(\": \")[1]\n",
+ "\n",
+ "if \"PATH\" in os.environ:\n",
+ " os.environ[\"PATH\"] += os.pathsep + location\n",
+ "else:\n",
+ " os.environ[\"PATH\"] = location\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "b89f3faf-bab6-4f74-a658-1f27a0e49912",
+ "metadata": {},
+ "source": [
+ "# 2. Set compile options and PTQ options (quantize model)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "09bb9ca5-f086-45d8-9ba5-c2415f24e167",
+ "metadata": {},
+ "source": [
+ "You can find more details about [preprocess args](https://github.com/kendryte/nncase/blob/master/docs/USAGE_v2_EN.md#CompileOptions), [quantize options](https://github.com/kendryte/nncase/blob/master/docs/USAGE_v2_EN.md#PTQTensorOptions) and [Mix quantize](https://github.com/kendryte/nncase/blob/master/docs/MixQuant.md)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a7eff82e-295c-4cce-afbc-ce64c84dc40a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import nncase\n",
+ "import numpy as np\n",
+ "from nncase_base_func import *\n",
+ "\n",
+ "def compile_kmodel(model_path, dump_path, calib_data):\n",
+ " \"\"\"\n",
+ " Set compile options and ptq options.\n",
+ " Compile kmodel.\n",
+ " Dump the compile-time result to 'compile_options.dump_dir'\n",
+ " \"\"\"\n",
+ " print(\"\\n---------- compile ----------\")\n",
+ " print(\"Simplify...\")\n",
+ " model_file = model_simplify(model_path)\n",
+ "\n",
+ " print(\"Set options...\")\n",
+ " # import_options\n",
+ " import_options = nncase.ImportOptions()\n",
+ "\n",
+ " ############################################\n",
+ " # The code below, you need to modify to fit your model.\n",
+ " # You can find more details about these options in docs/USAGE_v2.md.\n",
+ " ############################################\n",
+ " # compile_options\n",
+ " compile_options = nncase.CompileOptions()\n",
+ " compile_options.target = \"k230\" #\"cpu\"\n",
+ " compile_options.dump_ir = False # if False, will not dump the compile-time result.\n",
+ " compile_options.dump_asm = True\n",
+ " compile_options.dump_dir = dump_path\n",
+ " compile_options.input_file = \"\"\n",
+ " \n",
+ " # preprocess args\n",
+ " compile_options.preprocess = False\n",
+ " if compile_options.preprocess:\n",
+ " compile_options.input_type = \"uint8\" # \"uint8\" \"float32\"\n",
+ " compile_options.input_shape = [1,224,320,3]\n",
+ " compile_options.input_range = [0,1]\n",
+ " compile_options.input_layout = \"NHWC\" # \"NHWC\"\n",
+ " compile_options.swapRB = False\n",
+ " compile_options.mean = [0,0,0]\n",
+ " compile_options.std = [1,1,1]\n",
+ " compile_options.letterbox_value = 0\n",
+ " compile_options.output_layout = \"NHWC\" # \"NHWC\"\n",
+ "\n",
+ " # quantize options\n",
+ " ptq_options = nncase.PTQTensorOptions()\n",
+ " ptq_options.quant_type = \"uint8\" # datatype : \"float32\", \"int8\", \"int16\"\n",
+ " ptq_options.w_quant_type = \"uint8\" # datatype : \"float32\", \"int8\", \"int16\"\n",
+ " ptq_options.calibrate_method = \"NoClip\" # \"Kld\"\n",
+ " ptq_options.finetune_weights_method = \"NoFineTuneWeights\"\n",
+ " ptq_options.dump_quant_error = False\n",
+ " ptq_options.dump_quant_error_symmetric_for_signed = False\n",
+ "\n",
+ " # mix quantize options\n",
+ " # more details in docs/MixQuant.md\n",
+ " ptq_options.quant_scheme = \"\"\n",
+ " ptq_options.export_quant_scheme = False\n",
+ " ptq_options.export_weight_range_by_channel = False\n",
+ " ############################################\n",
+ " \n",
+ " ptq_options.samples_count = len(calib_data[0])\n",
+ " ptq_options.set_tensor_data(calib_data)\n",
+ " \n",
+ " print(\"Compiling...\")\n",
+ " compiler = nncase.Compiler(compile_options)\n",
+ " # import\n",
+ " model_content = read_model_file(model_file)\n",
+ " if model_path.split(\".\")[-1] == \"onnx\":\n",
+ " compiler.import_onnx(model_content, import_options)\n",
+ " elif model_path.split(\".\")[-1] == \"tflite\":\n",
+ " compiler.import_tflite(model_content, import_options)\n",
+ " \n",
+ " compiler.use_ptq(ptq_options)\n",
+ " \n",
+ " # compile\n",
+ " compiler.compile()\n",
+ " kmodel = compiler.gencode_tobytes()\n",
+ " \n",
+ " kmodel_path = os.path.join(dump_path, \"test.kmodel\")\n",
+ " with open(kmodel_path, 'wb') as f:\n",
+ " f.write(kmodel)\n",
+ " print(\"----------------end-----------------\")\n",
+ " return kmodel_path\n"
+ ]
+ },
+ {
+ "attachments": {
+ "1855346b-3785-4867-9c92-0e811d00b9ab.png": {
+ "image/png": "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"
+ }
+ },
+ "cell_type": "markdown",
+ "id": "e248f46c-fb41-4efc-88b1-bd7f8adbccbb",
+ "metadata": {},
+ "source": [
+ "# 3. Compile model with a single input.\n",
+ "Before all, we need to get the input and output infos of model.
\n",
+ "Open [netron](https://netron.app), and click 'open model' to select your model.
\n",
+ "Click the input node, you will see the details of model's input and output.
\n",
+ "![image.png](attachment:1855346b-3785-4867-9c92-0e811d00b9ab.png)
\n",
+ "\n",
+ "Before compiling kmodel, we should set the `CompileOptions` and `PTQTensorOptions` to specify the attribute of kmodel.\n",
+ "\n",
+ "Then, we can set the `model_path`, `dump_path`, and `calib_data`.
\n",
+ "The calib_data format is `[[x1, x2,...]]`.
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c957fe20-99c9-4a54-bae8-38361a8f8830",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# compile kmodel single input\n",
+ "model_path = \"./test.tflite\"\n",
+ "dump_path = \"./tmp_tflite\"\n",
+ "\n",
+ "# sample_count is 2\n",
+ "calib_data = [[np.random.rand(1, 240, 320, 3).astype(np.float32), np.random.rand(1, 240, 320, 3).astype(np.float32)]]\n",
+ "\n",
+ "kmodel_path = compile_kmodel(model_path, dump_path, calib_data)\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "015b6422-3bf1-4f28-93c9-dc6ef6e27856",
+ "metadata": {},
+ "source": [
+ "# 4. Simulate kmodel with a single input.\n",
+ "Set `kmodel_path` and `input_data`. After running, it will print shape of result. And result will be stored in `dump_path`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7f617edc-781c-4b8b-b45d-fef2f0b36a46",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# run kmodel(simulate)\n",
+ "import os\n",
+ "\n",
+ "kmodel_path = \"./tmp_tflite/test.kmodel\"\n",
+ "input_data = [np.random.rand(1, 240, 320, 3).astype(np.float32)]\n",
+ "\n",
+ "result = run_kmodel(kmodel_path, input_data)\n",
+ "\n",
+ "for idx, i in enumerate(result):\n",
+ " print(i.shape)\n",
+ " i.tofile(os.path.join(dump_path,\"nncase_result_{}.bin\".format(idx)))"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "80216eab-2738-4167-ba03-7a0e218c8d5c",
+ "metadata": {},
+ "source": [
+ "# 5. Compare kmodel result and tflite result.\n",
+ "\n",
+ "Here, we will use the TensorFlow framework to infer model(`.tflite`, not kmodel). And calculate the cosine between the tflite result and kmodel result."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4003a7ba-a1b4-4488-b3ca-d9a00a55e964",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "!pip install tensorflow\n",
+ "import tensorflow as tf\n",
+ "interp = tf.lite.Interpreter(model_path=model_path)\n",
+ "\n",
+ "inputs = []\n",
+ "for idx, item in enumerate(interp.get_input_details()):\n",
+ " input_dict = {}\n",
+ " input_dict['index'] = item['index']\n",
+ " input_dict['value'] = input_data[idx]\n",
+ " inputs.append(input_dict)\n",
+ " \n",
+ "# print(input_dict)\n",
+ "\n",
+ "interp.allocate_tensors()\n",
+ "for input in inputs:\n",
+ " interp.set_tensor(input['index'], input['value'])\n",
+ "interp.invoke()\n",
+ "\n",
+ "tflite_result = []\n",
+ "for item in interp.get_output_details():\n",
+ " tflite_result.append(interp.get_tensor(item['index']))\n",
+ "\n",
+ "for index, (i, j) in enumerate(zip(tflite_result, result)):\n",
+ " print(\"result {} cosine = \".format(index), get_cosine(i, j))\n"
+ ]
+ },
+ {
+ "attachments": {
+ "562afee7-c078-4323-bc19-49e03c80d0e9.png": {
+ "image/png": "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"
+ }
+ },
+ "cell_type": "markdown",
+ "id": "905aedaf-591e-4d64-8e2c-f6cb3f1491b5",
+ "metadata": {},
+ "source": [
+ "# 6. Compile model with multiple inputs.\n",
+ "\n",
+ "After reading [Example of compiling model with a single input](#Example_of_compiling_model_with_a_single_input), you know how to set calib_data for a single input.
\n",
+ "We will show you how to create a calib_data when your model has more inputs.
\n",
+ "If model has multiple inputs, calib_data format is `[[x1, x2,...], [y1, y2,...], ...]`.
\n",
+ "```\n",
+ "e.g. Model has three inputs (x, y, z), and these inputs info are like this.\n",
+ "x:{shape: [3,100], range: [1,5], dtype: int64}\n",
+ "y:{shape: [100, 3, 192], range: [0,1), dtype: float32}\n",
+ "z:{shape: [3,100], dtype: bool}\n",
+ "\n",
+ "The calib_data will be like the one below.\n",
+ "\n",
+ "calib_data = [\n",
+ "[ np.random.randint(1, 5, size=[3,100], dtype='int64'), np.random.randint(1, 5, size=[3,100], dtype='int64')],\n",
+ "[ np.random.rand(100, 3, 192).astype(np.float32), np.random.rand(100, 3, 192).astype(np.float32)],\n",
+ "[ np.random.rand(3,100).astype(np.float32)>0.5, np.random.rand(3,100).astype(np.float32)>0.5],] # bool\n",
+ "```\n",
+ "\n",
+ "Here, we will use an easier model to show you how to do it.
\n",
+ "The model is shown below.
\n",
+ "![image.png](attachment:562afee7-c078-4323-bc19-49e03c80d0e9.png)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "73f758da-bd81-44f9-9eff-734a23c427c2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# compile kmodel multiple inputs\n",
+ "model_path = \"./test.onnx\"\n",
+ "dump_path = \"./tmp_onnx\"\n",
+ "\n",
+ "# sample_count is 2\n",
+ "calib_data = [[np.random.rand(1, 1, 1024).astype(np.float32), np.random.rand(1, 1, 1024).astype(np.float32)],\n",
+ " [np.random.rand(1, 1, 320).astype(np.float32), np.random.rand(1, 1, 320).astype(np.float32)]]\n",
+ "\n",
+ "kmodel_path = compile_kmodel(model_path, dump_path, calib_data)\n",
+ "\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "351e2e49-7869-4c86-a5be-e8b7412b4d06",
+ "metadata": {},
+ "source": [
+ "# 7. Simulate kmodel with multiple inputs.\n",
+ "\n",
+ "Simulate kmodel on PC."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8fc1f43a-99fa-463a-b1b1-c6a9174ecd7a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# run kmodel(simulate)\n",
+ "import os\n",
+ "\n",
+ "kmodel_path = \"./tmp_onnx/test.kmodel\"\n",
+ "input_data = [np.random.rand(1, 1, 1024).astype(np.float32), np.random.rand(1, 1, 320).astype(np.float32)]\n",
+ "\n",
+ "results = run_kmodel(kmodel_path, input_data)\n",
+ "\n",
+ "for idx, i in enumerate(results):\n",
+ " print(i.shape)\n",
+ " i.tofile(os.path.join(dump_path,\"nncase_result_{}.bin\".format(idx)))\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "dd5a79f4-0094-476f-ac79-6ea6b100b5fc",
+ "metadata": {},
+ "source": [
+ "# 8. Compare kmodel results and onnx results.\n",
+ "\n",
+ "Here, we will use the ONNX framework to infer model(`.onnx`, not kmodel). And calculate the cosine between the ONNX result and the kmodel result."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ee2b661d-f6eb-4dee-b014-0fd3f95d589d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "!pip install onnxruntime\n",
+ "import onnxruntime as rt\n",
+ "\n",
+ "# onnx_model = model_simplify(model_path)\n",
+ "onnx_model = model_path\n",
+ "_, input_info = parse_model_input_output(model_path)\n",
+ "onnx_sess = rt.InferenceSession(onnx_model)\n",
+ "\n",
+ "input_dict = {}\n",
+ "for i, info in enumerate(input_info):\n",
+ " print(info['shape'])\n",
+ " input_dict[info[\"name\"]] = input_data[i]\n",
+ "\n",
+ "onnx_results = onnx_sess.run(None, input_dict)\n",
+ "for index, (i, j) in enumerate(zip(onnx_results, results)):\n",
+ " print(\"result {} cosine = \".format(index), get_cosine(i, j))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.10"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/examples/user_guide/k230_simulate-ZH.ipynb b/examples/user_guide/k230_simulate-ZH.ipynb
new file mode 100644
index 0000000000..e9b9dc5329
--- /dev/null
+++ b/examples/user_guide/k230_simulate-ZH.ipynb
@@ -0,0 +1,438 @@
+{
+ "cells": [
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "809dd383-637c-4e45-a859-9c4c492f7e1a",
+ "metadata": {},
+ "source": [
+ "如果在阅读相关文档后仍然存在疑惑,可以加入nncase讨论群:`790699378`,或者在nncase的github仓库提问题[click here](https://github.com/kendryte/nncase/issues)。"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "4beb4c04-ab79-4e1a-a7ad-ba53d9a9b123",
+ "metadata": {},
+ "source": [
+ "# 1. nncase安装和环境设置"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "82a8f9c1-c2bf-4270-9f1f-ac25c9fdd898",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "!pip install --upgrade pip\n",
+ "!pip install nncase --timeout=1000\n",
+ "!pip install nncase-kpu --timeout=1000\n",
+ "!pip install onnx onnxsim scikit-learn\n",
+ "\n",
+ "# nncase-2.x need dotnet-7\n",
+ "# Ubuntu use apt to install dotnet-7.0 (The docker has installed dotnet7.0)\n",
+ "!sudo apt-get install -y dotnet-sdk-7.0"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "d8d2a6f0",
+ "metadata": {},
+ "source": [
+ "## 自动设置环境变量"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8b32a0b5-90b0-4bc7-8448-2a544b7d06e9",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import sys\n",
+ "import subprocess\n",
+ "\n",
+ "result = subprocess.run([\"pip\", \"show\", \"nncase\"], capture_output=True)\n",
+ "\n",
+ "split_flag = \"\\n\"\n",
+ "if sys.platform == \"win32\":\n",
+ " split_flag = \"\\r\\n\"\n",
+ " \n",
+ "location_s = [i for i in result.stdout.decode().split(split_flag) if i.startswith(\"Location:\")]\n",
+ "location = location_s[0].split(\": \")[1]\n",
+ "\n",
+ "if \"PATH\" in os.environ:\n",
+ " os.environ[\"PATH\"] += os.pathsep + location\n",
+ "else:\n",
+ " os.environ[\"PATH\"] = location\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "b89f3faf-bab6-4f74-a658-1f27a0e49912",
+ "metadata": {},
+ "source": [
+ "# 2. 设置编译选项和量化选项"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "09bb9ca5-f086-45d8-9ba5-c2415f24e167",
+ "metadata": {},
+ "source": [
+ "你可以在下面的链接中找到参数的详细描述 [preprocess args](https://github.com/kendryte/nncase/blob/master/docs/USAGE_v2_EN.md#CompileOptions),[quantize options](https://github.com/kendryte/nncase/blob/master/docs/USAGE_v2_EN.md#PTQTensorOptions),[Mix quantize](https://github.com/kendryte/nncase/blob/master/docs/MixQuant.md)。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a7eff82e-295c-4cce-afbc-ce64c84dc40a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import nncase\n",
+ "import numpy as np\n",
+ "from nncase_base_func import *\n",
+ "\n",
+ "def compile_kmodel(model_path, dump_path, calib_data):\n",
+ " \"\"\"\n",
+ " Set compile options and ptq options.\n",
+ " Compile kmodel.\n",
+ " Dump the compile-time result to 'compile_options.dump_dir'\n",
+ " \"\"\"\n",
+ " print(\"\\n---------- compile ----------\")\n",
+ " print(\"Simplify...\")\n",
+ " model_file = model_simplify(model_path)\n",
+ "\n",
+ " print(\"Set options...\")\n",
+ " # import_options\n",
+ " import_options = nncase.ImportOptions()\n",
+ "\n",
+ " ############################################\n",
+ " # 你需要修改下面这段代码中的参数来适配你的模型。\n",
+ " # 详细的说明可以参考docs/USAGE_v2.md.\n",
+ " ############################################\n",
+ " # compile_options\n",
+ " compile_options = nncase.CompileOptions()\n",
+ " compile_options.target = \"k230\" #\"cpu\"\n",
+ " compile_options.dump_ir = True # if False, will not dump the compile-time result.\n",
+ " compile_options.dump_asm = True\n",
+ " compile_options.dump_dir = dump_path\n",
+ " compile_options.input_file = \"\"\n",
+ " \n",
+ " # preprocess args\n",
+ " compile_options.preprocess = False\n",
+ " if compile_options.preprocess:\n",
+ " compile_options.input_type = \"uint8\" # \"uint8\" \"float32\"\n",
+ " compile_options.input_shape = [1,224,320,3]\n",
+ " compile_options.input_range = [0,1]\n",
+ " compile_options.input_layout = \"NHWC\" # \"NHWC\"\n",
+ " compile_options.swapRB = False\n",
+ " compile_options.mean = [0,0,0]\n",
+ " compile_options.std = [1,1,1]\n",
+ " compile_options.letterbox_value = 0\n",
+ " compile_options.output_layout = \"NHWC\" # \"NHWC\"\n",
+ "\n",
+ " # quantize options\n",
+ " ptq_options = nncase.PTQTensorOptions()\n",
+ " ptq_options.quant_type = \"uint8\" # datatype : \"float32\", \"int8\", \"int16\"\n",
+ " ptq_options.w_quant_type = \"uint8\" # datatype : \"float32\", \"int8\", \"int16\"\n",
+ " ptq_options.calibrate_method = \"NoClip\" # \"Kld\"\n",
+ " ptq_options.finetune_weights_method = \"NoFineTuneWeights\"\n",
+ " ptq_options.dump_quant_error = False\n",
+ " ptq_options.dump_quant_error_symmetric_for_signed = False\n",
+ "\n",
+ " # mix quantize options\n",
+ " # more details in docs/MixQuant.md\n",
+ " ptq_options.quant_scheme = \"\"\n",
+ " ptq_options.export_quant_scheme = False\n",
+ " ptq_options.export_weight_range_by_channel = False\n",
+ " ############################################\n",
+ " \n",
+ " ptq_options.samples_count = len(calib_data[0])\n",
+ " ptq_options.set_tensor_data(calib_data)\n",
+ " \n",
+ " print(\"Compiling...\")\n",
+ " compiler = nncase.Compiler(compile_options)\n",
+ " # import\n",
+ " model_content = read_model_file(model_file)\n",
+ " if model_path.split(\".\")[-1] == \"onnx\":\n",
+ " compiler.import_onnx(model_content, import_options)\n",
+ " elif model_path.split(\".\")[-1] == \"tflite\":\n",
+ " compiler.import_tflite(model_content, import_options)\n",
+ " \n",
+ " compiler.use_ptq(ptq_options)\n",
+ " \n",
+ " # compile\n",
+ " compiler.compile()\n",
+ " kmodel = compiler.gencode_tobytes()\n",
+ " \n",
+ " kmodel_path = os.path.join(dump_path, \"test.kmodel\")\n",
+ " with open(kmodel_path, 'wb') as f:\n",
+ " f.write(kmodel)\n",
+ " print(\"----------------end-----------------\")\n",
+ " return kmodel_path\n"
+ ]
+ },
+ {
+ "attachments": {
+ "1855346b-3785-4867-9c92-0e811d00b9ab.png": {
+ "image/png": "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"
+ }
+ },
+ "cell_type": "markdown",
+ "id": "e248f46c-fb41-4efc-88b1-bd7f8adbccbb",
+ "metadata": {},
+ "source": [
+ "# 3. 编译单输入模型\n",
+ "在开始之前,我们需要获取模型的输入输出信息。
\n",
+ "使用[netron](https://netron.app)进行模型可视化,将你的模型直接拖入网页即可。
\n",
+ "点击任意输入节点就可以在右侧看到模型所有的输入输出节点信息。
\n",
+ "![image.png](attachment:1855346b-3785-4867-9c92-0e811d00b9ab.png)
\n",
+ "\n",
+ "在编译`kmodel`之前,我们需要设置`CompileOptions` 和 `PTQTensorOptions`来指定`kmodel`的各个属性。
\n",
+ "\n",
+ "然后需要设置`model_path`, `dump_path`, and `calib_data`。
\n",
+ "校正集数据的格式为:`[[x1, x2,...]]`。
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c957fe20-99c9-4a54-bae8-38361a8f8830",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# compile kmodel single input\n",
+ "model_path = \"./test.tflite\"\n",
+ "dump_path = \"./tmp_tflite\"\n",
+ "\n",
+ "# 校正集的数量为2\n",
+ "calib_data = [[np.random.rand(1, 240, 320, 3).astype(np.float32), np.random.rand(1, 240, 320, 3).astype(np.float32)]]\n",
+ "\n",
+ "kmodel_path = compile_kmodel(model_path, dump_path, calib_data)\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "015b6422-3bf1-4f28-93c9-dc6ef6e27856",
+ "metadata": {},
+ "source": [
+ "# 4. PC上推理单输入kmodel\n",
+ "需要设置 `kmodel_path` 和 `input_data`。执行完毕以后,会打印出每个输出结果的shape信息,同时输出结果会保存到`dump_path`目录下。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7f617edc-781c-4b8b-b45d-fef2f0b36a46",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# run kmodel(simulate)\n",
+ "import os\n",
+ "\n",
+ "kmodel_path = \"./tmp_tflite/test.kmodel\"\n",
+ "input_data = [np.random.rand(1, 240, 320, 3).astype(np.float32)]\n",
+ "\n",
+ "result = run_kmodel(kmodel_path, input_data)\n",
+ "\n",
+ "for idx, i in enumerate(result):\n",
+ " print(i.shape)\n",
+ " i.tofile(os.path.join(dump_path,\"nncase_result_{}.bin\".format(idx)))"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "80216eab-2738-4167-ba03-7a0e218c8d5c",
+ "metadata": {},
+ "source": [
+ "# 5. 比较TF结果和kmodel的推理结果\n",
+ "\n",
+ "这里,我们使用TensorFlow框架来推理`.tflite`模型,然后计算TensorFlow输入结果和kmodel的输出结果的余弦。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4003a7ba-a1b4-4488-b3ca-d9a00a55e964",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "!pip install tensorflow\n",
+ "import tensorflow as tf\n",
+ "interp = tf.lite.Interpreter(model_path=model_path)\n",
+ "\n",
+ "inputs = []\n",
+ "for idx, item in enumerate(interp.get_input_details()):\n",
+ " input_dict = {}\n",
+ " input_dict['index'] = item['index']\n",
+ " input_dict['value'] = input_data[idx]\n",
+ " inputs.append(input_dict)\n",
+ " \n",
+ "# print(input_dict)\n",
+ "\n",
+ "interp.allocate_tensors()\n",
+ "for input in inputs:\n",
+ " interp.set_tensor(input['index'], input['value'])\n",
+ "interp.invoke()\n",
+ "\n",
+ "tflite_result = []\n",
+ "for item in interp.get_output_details():\n",
+ " tflite_result.append(interp.get_tensor(item['index']))\n",
+ "\n",
+ "for index, (i, j) in enumerate(zip(tflite_result, result)):\n",
+ " print(\"result {} cosine = \".format(index), get_cosine(i, j))\n"
+ ]
+ },
+ {
+ "attachments": {
+ "562afee7-c078-4323-bc19-49e03c80d0e9.png": {
+ "image/png": "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"
+ }
+ },
+ "cell_type": "markdown",
+ "id": "905aedaf-591e-4d64-8e2c-f6cb3f1491b5",
+ "metadata": {},
+ "source": [
+ "# 6. 编译多输入模型\n",
+ "\n",
+ "在阅读 [编译单输入模型](#编译单输入模型)之后,你已经清楚了如何设置单输入模型的校正集。
\n",
+ "这里我们会介绍如何设置多输入模型的校正集。
\n",
+ "\n",
+ "如果模型存在多个输入,那么校正集的格式就是`[[x1, x2,...], [y1, y2,...], ...]`。
\n",
+ "\n",
+ "```\n",
+ "例如,模型有三个输入,分别是(x, y, z),并且这三个输入的详细信息如下:\n",
+ "x:{shape: [3,100], range: [1,5], dtype: int64}\n",
+ "y:{shape: [100, 3, 192], range: [0,1), dtype: float32}\n",
+ "z:{shape: [3,100], dtype: bool}\n",
+ "\n",
+ "那么校正集就是下面这个样子:\n",
+ "calib_data = [\n",
+ "[ np.random.randint(1, 5, size=[3,100], dtype='int64'), np.random.randint(1, 5, size=[3,100], dtype='int64')],\n",
+ "[ np.random.rand(100, 3, 192).astype(np.float32), np.random.rand(100, 3, 192).astype(np.float32)],\n",
+ "[ np.random.rand(3,100).astype(np.float32)>0.5, np.random.rand(3,100).astype(np.float32)>0.5],] # bool\n",
+ "\n",
+ "如果你numpy有一些使用经验,想必你在看到这里已经知道如何设置正确的数据了。\n",
+ "```\n",
+ "\n",
+ "下面,我们用一个简单一点的模型来运行个示例,模型结构如下所示。\n",
+ "\n",
+ "![image.png](attachment:562afee7-c078-4323-bc19-49e03c80d0e9.png)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "73f758da-bd81-44f9-9eff-734a23c427c2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# compile kmodel multiple inputs\n",
+ "model_path = \"./test.onnx\"\n",
+ "dump_path = \"./tmp_onnx\"\n",
+ "\n",
+ "# 校正集的数量为2\n",
+ "calib_data = [[np.random.rand(1, 1, 1024).astype(np.float32), np.random.rand(1, 1, 1024).astype(np.float32)],\n",
+ " [np.random.rand(1, 1, 320).astype(np.float32), np.random.rand(1, 1, 320).astype(np.float32)]]\n",
+ "\n",
+ "kmodel_path = compile_kmodel(model_path, dump_path, calib_data)\n",
+ "\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "351e2e49-7869-4c86-a5be-e8b7412b4d06",
+ "metadata": {},
+ "source": [
+ "# 7. PC上推理多输入kmodel"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8fc1f43a-99fa-463a-b1b1-c6a9174ecd7a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# run kmodel(simulate)\n",
+ "import os\n",
+ "\n",
+ "kmodel_path = \"./tmp_onnx/test.kmodel\"\n",
+ "input_data = [np.random.rand(1, 1, 1024).astype(np.float32), np.random.rand(1, 1, 320).astype(np.float32)]\n",
+ "\n",
+ "results = run_kmodel(kmodel_path, input_data)\n",
+ "\n",
+ "for idx, i in enumerate(results):\n",
+ " print(i.shape)\n",
+ " i.tofile(os.path.join(dump_path,\"nncase_result_{}.bin\".format(idx)))\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "dd5a79f4-0094-476f-ac79-6ea6b100b5fc",
+ "metadata": {},
+ "source": [
+ "# 8. 比较ONNX结果和kmodel推理结果\n",
+ "\n",
+ "这里给出如何调用ONNX框架推理的示例代码,以及如何将ONNX的推理结果和kmodel的推理结果进行比较,该比较结果为余弦值的形式。
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ee2b661d-f6eb-4dee-b014-0fd3f95d589d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "!pip install onnxruntime\n",
+ "import onnxruntime as rt\n",
+ "\n",
+ "onnx_model = model_simplify(model_path)\n",
+ "onnx_model = model_path\n",
+ "_, input_info = parse_model_input_output(model_path)\n",
+ "onnx_sess = rt.InferenceSession(onnx_model)\n",
+ "\n",
+ "input_dict = {}\n",
+ "for i, info in enumerate(input_info):\n",
+ " print(info['shape'])\n",
+ " input_dict[info[\"name\"]] = input_data[i]\n",
+ "\n",
+ "onnx_results = onnx_sess.run(None, input_dict)\n",
+ "for index, (i, j) in enumerate(zip(onnx_results, results)):\n",
+ " print(\"result {} cosine = \".format(index), get_cosine(i, j))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.10"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/examples/user_guide/k230_simulate.ipynb b/examples/user_guide/k230_simulate.ipynb
deleted file mode 100644
index 10ef9b5bde..0000000000
--- a/examples/user_guide/k230_simulate.ipynb
+++ /dev/null
@@ -1,213 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "82a8f9c1-c2bf-4270-9f1f-ac25c9fdd898",
- "metadata": {},
- "outputs": [],
- "source": [
- "!pip install --upgrade pip\n",
- "# !pip uninstall -y nncase\n",
- "!pip install nncase --timeout=1000\n",
- "!pip install nncase-kpu --timeout=1000\n",
- "!pip install onnx onnxsim\n",
- "\n",
- "# nncase-2.x need dotnet-7\n",
- "!sudo apt-get install -y dotnet-sdk-7.0\n",
- "import _nncase\n",
- "print(_nncase.__version__)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "a7eff82e-295c-4cce-afbc-ce64c84dc40a",
- "metadata": {},
- "outputs": [],
- "source": [
- "import nncase\n",
- "import numpy as np\n",
- "from nncase_base_func import *\n",
- "\n",
- "def compile_kmodel(model_path, dump_path, calib_data):\n",
- " \"\"\"\n",
- " Set compile options and ptq options.\n",
- " Compile kmodel.\n",
- " Dump the compile-time result to 'compile_options.dump_dir'\n",
- " \"\"\"\n",
- " print(\"\\n---------- compile ----------\")\n",
- " print(\"Simplify...\")\n",
- " model_file = model_simplify(model_path)\n",
- "\n",
- " print(\"Set options...\")\n",
- " # import_options\n",
- " import_options = nncase.ImportOptions()\n",
- " \n",
- " # compile_options\n",
- " compile_options = nncase.CompileOptions()\n",
- " compile_options.target = \"k230\" #\"cpu\"\n",
- " compile_options.dump_ir = True # if False, will not dump the compile-time result.\n",
- " compile_options.dump_asm = True\n",
- " compile_options.dump_dir = dump_path\n",
- " compile_options.input_file = \"\"\n",
- " \n",
- " # preprocess args\n",
- " compile_options.preprocess = False\n",
- " if compile_options.preprocess:\n",
- " compile_options.input_type = \"uint8\" # \"uint8\" \"float32\"\n",
- " compile_options.input_shape = [1,224,320,3]\n",
- " compile_options.input_range = [0,1]\n",
- " compile_options.input_layout = \"NHWC\" # \"NHWC\"\n",
- " compile_options.swapRB = False\n",
- " compile_options.mean = [0,0,0]\n",
- " compile_options.std = [1,1,1]\n",
- " compile_options.letterbox_value = 0\n",
- " compile_options.output_layout = \"NHWC\" # \"NHWC\"\n",
- " \n",
- " # quant\n",
- " ptq_options = nncase.PTQTensorOptions()\n",
- " \n",
- " ptq_options.quant_type = \"uint8\" # datatype : \"float32\", \"int8\", \"int16\"\n",
- " ptq_options.w_quant_type = \"uint8\" # datatype : \"float32\", \"int8\", \"int16\"\n",
- " ptq_options.calibrate_method = \"NoClip\" # \"Kld\"\n",
- " ptq_options.finetune_weights_method = \"NoFineTuneWeights\"\n",
- " ptq_options.dump_quant_error = False\n",
- " ptq_options.dump_quant_error_symmetric_for_signed = False\n",
- " \n",
- " # detail in docs/MixQuant.md\n",
- " ptq_options.quant_scheme = \"\"\n",
- " ptq_options.export_quant_scheme = False\n",
- " ptq_options.export_weight_range_by_channel = False\n",
- " \n",
- " ptq_options.samples_count = len(calib_data[0])\n",
- " ptq_options.set_tensor_data(calib_data)\n",
- "\n",
- " \n",
- " print(\"Compiling...\")\n",
- " compiler = nncase.Compiler(compile_options)\n",
- " # import\n",
- " model_content = read_model_file(model_file)\n",
- " if model_path.split(\".\")[-1] == \"onnx\":\n",
- " compiler.import_onnx(model_content, import_options)\n",
- " elif model_path.split(\".\")[-1] == \"tflite\":\n",
- " compiler.import_tflite(model_content, import_options)\n",
- " \n",
- " compiler.use_ptq(ptq_options)\n",
- " \n",
- " # compile\n",
- " compiler.compile()\n",
- " kmodel = compiler.gencode_tobytes()\n",
- " \n",
- " kmodel_path = os.path.join(dump_path, \"test.kmodel\")\n",
- " with open(kmodel_path, 'wb') as f:\n",
- " f.write(kmodel)\n",
- " print(\"----------------end-----------------\")\n",
- " return kmodel_path\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "c957fe20-99c9-4a54-bae8-38361a8f8830",
- "metadata": {},
- "outputs": [],
- "source": [
- "# compile kmodel single input\n",
- "model_path = \"./test.tflite\"\n",
- "dump_path = \"./tmp_tflite\"\n",
- "\n",
- "# If model has multiple inputs, calib_data format is \"[[x1, x2,...], [y1, y2,...], ...]\"\n",
- "# e.g. Model has three inputs (x, y, z), the calib_data is '[[x1, x2, x3],[y1, y2, y3],[z1, z2, z3]]'\n",
- "\n",
- "calib_data = [[np.random.rand(1, 240, 320, 3).astype(np.float32), np.random.rand(1, 240, 320, 3).astype(np.float32)]]\n",
- "\n",
- "kmodel_path = compile_kmodel(model_path, dump_path, calib_data)\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "7f617edc-781c-4b8b-b45d-fef2f0b36a46",
- "metadata": {},
- "outputs": [],
- "source": [
- "# run kmodel(simulate)\n",
- "import os\n",
- "\n",
- "kmodel_path = \"./tmp_tflite/test.kmodel\"\n",
- "input_data = [np.random.rand(1, 240, 320, 3).astype(np.float32)]\n",
- "\n",
- "result = run_kmodel(kmodel_path, input_data)\n",
- "\n",
- "for idx, i in enumerate(result):\n",
- " print(i.shape)\n",
- " i.tofile(os.path.join(dump_path,\"nncase_result_{}.bin\".format(idx)))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "73f758da-bd81-44f9-9eff-734a23c427c2",
- "metadata": {},
- "outputs": [],
- "source": [
- "# compile kmodel multiple inputs\n",
- "model_path = \"./test.onnx\"\n",
- "dump_path = \"./tmp_onnx\"\n",
- "\n",
- "# If model has multiple inputs, calib_data format is \"[[x1, x2,...], [y1, y2,...], ...]\"\n",
- "# e.g. Model has three inputs (x, y, z), the calib_data is '[[x1, x2, x3],[y1, y2, y3],[z1, z2, z3]]'\n",
- "# calib_data = [[ np.random.randint(1, 5, size=[3,100], dtype='int64'), np.random.randint(1, 5, size=[3,100], dtype='int64')],\n",
- "# [ np.random.rand(100, 3, 192).astype(np.float32), np.random.rand(100, 3, 192).astype(np.float32)],\n",
- "# [ np.random.rand(3,100).astype(np.float32)>0.5, np.random.rand(3,100).astype(np.float32)>0.5],] # bool\n",
- "calib_data = [[np.random.rand(1, 1, 1024).astype(np.float32), np.random.rand(1, 1, 1024).astype(np.float32)],\n",
- " [np.random.rand(1, 1, 320).astype(np.float32), np.random.rand(1, 1, 320).astype(np.float32)]]\n",
- "\n",
- "kmodel_path = compile_kmodel(model_path, dump_path, calib_data)\n",
- "\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "8fc1f43a-99fa-463a-b1b1-c6a9174ecd7a",
- "metadata": {},
- "outputs": [],
- "source": [
- "# run kmodel(simulate)\n",
- "import os\n",
- "\n",
- "kmodel_path = \"./tmp_onnx/test.kmodel\"\n",
- "input_data = [np.random.rand(1, 1, 1024).astype(np.float32), np.random.rand(1, 1, 320).astype(np.float32)]\n",
- "\n",
- "result = run_kmodel(kmodel_path, input_data)\n",
- "\n",
- "for idx, i in enumerate(result):\n",
- " print(i.shape)\n",
- " i.tofile(os.path.join(dump_path,\"nncase_result_{}.bin\".format(idx)))\n"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.9"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/examples/user_guide/nncase_base_func.py b/examples/user_guide/nncase_base_func.py
index da03c92b28..e785130825 100644
--- a/examples/user_guide/nncase_base_func.py
+++ b/examples/user_guide/nncase_base_func.py
@@ -15,7 +15,6 @@ def get_cosine(vec1, vec2):
return cosine_similarity(vec1.reshape(1, -1), vec2.reshape(1, -1))
-
def read_model_file(model_file):
"""
read model
@@ -58,18 +57,18 @@ def model_simplify(model_file):
input_shapes = {}
for input in inputs:
input_shapes[input['name']] = input['shape']
-
- onnx_model, check = onnxsim.simplify(onnx_model, overwrite_input_shapes=input_shapes)
+
+ onnx_model, check = onnxsim.simplify(onnx_model, input_shapes=input_shapes)
assert check, "Simplified ONNX model could not be validated"
-
+
model_file = os.path.join(os.path.dirname(model_file), 'simplified.onnx')
onnx.save_model(onnx_model, model_file)
print("[ onnx done ]")
elif model_file.split('.')[-1] == "tflite":
- print("[ tflite pass ]")
+ print("[ tflite skip ]")
else:
raise Exception(f"Unsupport type {model_file.split('.')[-1]}")
-
+
return model_file
def run_kmodel(kmodel_path, input_data):
@@ -78,14 +77,14 @@ def run_kmodel(kmodel_path, input_data):
model_sim = nncase.Simulator()
with open(kmodel_path, 'rb') as f:
model_sim.load_model(f.read())
-
+
print("Set input data...")
for i, p_d in enumerate(input_data):
model_sim.set_input_tensor(i, nncase.RuntimeTensor.from_numpy(p_d))
-
+
print("Run...")
model_sim.run()
-
+
print("Get output result...")
all_result = []
for i in range(model_sim.outputs_size):
diff --git a/modules/Nncase.Modules.StackVM/CodeGen/StackVM/CodeGenVisitor.g.cs b/modules/Nncase.Modules.StackVM/CodeGen/StackVM/CodeGenVisitor.g.cs
index f73d629c40..b900856080 100644
--- a/modules/Nncase.Modules.StackVM/CodeGen/StackVM/CodeGenVisitor.g.cs
+++ b/modules/Nncase.Modules.StackVM/CodeGen/StackVM/CodeGenVisitor.g.cs
@@ -1,6 +1,6 @@
// Copyright (c) Canaan Inc. All rights reserved.
// Licensed under the Apache license. See LICENSE file in the project root for full license information.
-/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 15:04:16 +08:00. */
+/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 17:07:39 +08:00. */
using System;
using System.Collections.Generic;
@@ -262,6 +262,18 @@ private void EmitTensorCall(Op op)
case IR.Tensors.Where top:
Emitter.T.Where(top.IsTfWhere);
break;
+ case IR.ShapeExpr.BroadcastShape top:
+ Emitter.T.BroadcastShape();
+ break;
+ case IR.ShapeExpr.Conv2DShape top:
+ Emitter.T.Conv2DShape();
+ break;
+ case IR.ShapeExpr.Conv2DTransposeShape top:
+ Emitter.T.Conv2DTransposeShape();
+ break;
+ case IR.ShapeExpr.MatMulShape top:
+ Emitter.T.MatMulShape();
+ break;
case IR.Random.Normal top:
Emitter.T.Normal(top.Type);
break;
diff --git a/modules/Nncase.Modules.StackVM/CodeGen/StackVM/CodegenVisitor.cs b/modules/Nncase.Modules.StackVM/CodeGen/StackVM/CodegenVisitor.cs
index e382e6ab45..2b6a4e6eda 100644
--- a/modules/Nncase.Modules.StackVM/CodeGen/StackVM/CodegenVisitor.cs
+++ b/modules/Nncase.Modules.StackVM/CodeGen/StackVM/CodegenVisitor.cs
@@ -152,7 +152,7 @@ internal partial class CodeGenVisitor : ExprVisitor
private readonly BaseFunction _function;
private readonly CodeGenContext _context;
- private readonly HashSet _refTextSnippets = new();
+ private readonly List _refTextSnippets = new();
private TextSnippet? _currentTextSnippet;
private BasicBlock? _currentBasicBlock;
@@ -172,7 +172,7 @@ public CodeGenVisitor(BaseFunction function, CodeGenContext context)
private StackVMEmitter Emitter => CurrentTextSnippet.Emitter;
- public (BasicBlock BB, HashSet SnippetSet) SubBlock(Expr expr)
+ public (BasicBlock BB, List SnippetSet) SubBlock(Expr expr)
{
var visitor = new CodeGenVisitor(_function, _context);
var subBlockFirst = visitor.CurrentBasicBlock;
@@ -185,7 +185,8 @@ public CodeGenVisitor(BaseFunction function, CodeGenContext context)
visitor.Visit(expr);
var refTextSnippets = visitor._refTextSnippets;
- return (subBlockFirst, refTextSnippets);
+ var subBlockEnd = visitor.CurrentBasicBlock;
+ return (subBlockEnd, refTextSnippets);
}
protected override TextSnippet VisitLeafConst(Const expr)
@@ -389,9 +390,9 @@ protected override TextSnippet VisitLeafIf(If @if)
return endSnippet;
}
- private void MergeSnippetSet(HashSet thenSet, HashSet elseSet, TextSnippet endSnippet)
+ private void MergeSnippetSet(List thenSet, List elseSet, TextSnippet endSnippet)
{
- var useSnippetSet = thenSet.Union(elseSet).ToHashSet();
+ var useSnippetSet = thenSet.Concat(elseSet).ToHashSet();
foreach (var snippet in useSnippetSet)
{
snippet.AddUseCount();
diff --git a/modules/Nncase.Modules.StackVM/CodeGen/StackVM/StackVMEmitter.g.cs b/modules/Nncase.Modules.StackVM/CodeGen/StackVM/StackVMEmitter.g.cs
index 0e1782487f..d69739ded8 100644
--- a/modules/Nncase.Modules.StackVM/CodeGen/StackVM/StackVMEmitter.g.cs
+++ b/modules/Nncase.Modules.StackVM/CodeGen/StackVM/StackVMEmitter.g.cs
@@ -1,6 +1,6 @@
// Copyright (c) Canaan Inc. All rights reserved.
// Licensed under the Apache license. See LICENSE file in the project root for full license information.
-/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 15:04:16 +08:00. */
+/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 17:07:39 +08:00. */
using System;
using System.Collections.Generic;
@@ -678,17 +678,24 @@ public void Broadcast()
}
///.
- public void BucketPad()
+ public void BroadcastShape()
{
_emitter.Write((byte)100);
_emitter.Write((ushort)5);
}
///.
- public void Cast(DataType newType, CastMode castMode)
+ public void BucketPad()
{
_emitter.Write((byte)100);
_emitter.Write((ushort)6);
+ }
+
+ ///.
+ public void Cast(DataType newType, CastMode castMode)
+ {
+ _emitter.Write((byte)100);
+ _emitter.Write((ushort)7);
_emitter.Write(newType);
_emitter.Write((int)castMode);
}
@@ -697,21 +704,21 @@ public void Cast(DataType newType, CastMode castMode)
public void Celu()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)7);
+ _emitter.Write((ushort)8);
}
///.
public void Clamp()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)8);
+ _emitter.Write((ushort)9);
}
///.
public void Compare(CompareOp compareOp)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)9);
+ _emitter.Write((ushort)10);
_emitter.Write((byte)compareOp);
}
@@ -719,14 +726,14 @@ public void Compare(CompareOp compareOp)
public void Concat()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)10);
+ _emitter.Write((ushort)11);
}
///.
public void Condition(bool canFoldConstCall)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)11);
+ _emitter.Write((ushort)12);
_emitter.Write(canFoldConstCall);
}
@@ -734,37 +741,51 @@ public void Condition(bool canFoldConstCall)
public void ConstantOfShape()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)12);
+ _emitter.Write((ushort)13);
}
///.
public void Conv2D(PadMode padMode)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)13);
+ _emitter.Write((ushort)14);
_emitter.Write((byte)padMode);
}
+ ///.
+ public void Conv2DShape()
+ {
+ _emitter.Write((byte)100);
+ _emitter.Write((ushort)15);
+ }
+
///.
public void Conv2DTranspose(PadMode padMode)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)14);
+ _emitter.Write((ushort)16);
_emitter.Write((byte)padMode);
}
+ ///.
+ public void Conv2DTransposeShape()
+ {
+ _emitter.Write((byte)100);
+ _emitter.Write((ushort)17);
+ }
+
///.
public void CumSum()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)15);
+ _emitter.Write((ushort)18);
}
///.
public void Dequantize(DataType targetType)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)16);
+ _emitter.Write((ushort)19);
_emitter.Write(targetType);
}
@@ -772,28 +793,28 @@ public void Dequantize(DataType targetType)
public void Elu()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)17);
+ _emitter.Write((ushort)20);
}
///.
public void Erf()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)18);
+ _emitter.Write((ushort)21);
}
///.
public void Expand()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)19);
+ _emitter.Write((ushort)22);
}
///.
public void FakeDequantize(DataType targetType)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)20);
+ _emitter.Write((ushort)23);
_emitter.Write(targetType);
}
@@ -801,7 +822,7 @@ public void FakeDequantize(DataType targetType)
public void FakeQuantize(DataType targetType)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)21);
+ _emitter.Write((ushort)24);
_emitter.Write(targetType);
}
@@ -809,98 +830,98 @@ public void FakeQuantize(DataType targetType)
public void FixShape()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)22);
+ _emitter.Write((ushort)25);
}
///.
public void Flatten()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)23);
+ _emitter.Write((ushort)26);
}
///.
public void Gather()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)24);
+ _emitter.Write((ushort)27);
}
///.
public void GatherElements()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)25);
+ _emitter.Write((ushort)28);
}
///.
public void GatherND()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)26);
+ _emitter.Write((ushort)29);
}
///.
public void Gelu()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)27);
+ _emitter.Write((ushort)30);
}
///.
public void GetItem()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)28);
+ _emitter.Write((ushort)31);
}
///.
public void Hardmax()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)29);
+ _emitter.Write((ushort)32);
}
///.
public void HardSigmoid()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)30);
+ _emitter.Write((ushort)33);
}
///.
public void HardSwish()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)31);
+ _emitter.Write((ushort)34);
}
///.
public void IndexOf()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)32);
+ _emitter.Write((ushort)35);
}
///.
public void InstanceNormalization()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)33);
+ _emitter.Write((ushort)36);
}
///.
public void L2Normalization()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)34);
+ _emitter.Write((ushort)37);
}
///.
public void LayerNorm(int axis, float epsilon)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)35);
+ _emitter.Write((ushort)38);
_emitter.Write(axis);
_emitter.Write(epsilon);
}
@@ -909,35 +930,35 @@ public void LayerNorm(int axis, float epsilon)
public void LeakyRelu()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)36);
+ _emitter.Write((ushort)39);
}
///.
public void LogSoftmax()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)37);
+ _emitter.Write((ushort)40);
}
///.
public void LpNormalization()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)38);
+ _emitter.Write((ushort)41);
}
///.
public void LRN()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)39);
+ _emitter.Write((ushort)42);
}
///.
public void LSTM(LSTMDirection direction, LSTMLayout layout, string[] activations)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)40);
+ _emitter.Write((ushort)43);
_emitter.Write((int)direction);
_emitter.Write((int)layout);
_emitter.Write(activations);
@@ -947,14 +968,21 @@ public void LSTM(LSTMDirection direction, LSTMLayout layout, string[] activation
public void MatMul()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)41);
+ _emitter.Write((ushort)44);
+ }
+
+ ///.
+ public void MatMulShape()
+ {
+ _emitter.Write((byte)100);
+ _emitter.Write((ushort)45);
}
///.
public void Normal(DataType type)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)42);
+ _emitter.Write((ushort)46);
_emitter.Write(type);
}
@@ -962,7 +990,7 @@ public void Normal(DataType type)
public void NormalLike(DataType type)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)43);
+ _emitter.Write((ushort)47);
_emitter.Write(type);
}
@@ -970,7 +998,7 @@ public void NormalLike(DataType type)
public void OneHot(OneHotMode oneHotMode)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)44);
+ _emitter.Write((ushort)48);
_emitter.Write((byte)oneHotMode);
}
@@ -978,7 +1006,7 @@ public void OneHot(OneHotMode oneHotMode)
public void Pad(PadMode padMode)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)45);
+ _emitter.Write((ushort)49);
_emitter.Write((byte)padMode);
}
@@ -986,21 +1014,21 @@ public void Pad(PadMode padMode)
public void PRelu()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)46);
+ _emitter.Write((ushort)50);
}
///.
public void Prod()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)47);
+ _emitter.Write((ushort)51);
}
///.
public void Quantize(DataType targetType)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)48);
+ _emitter.Write((ushort)52);
_emitter.Write(targetType);
}
@@ -1008,7 +1036,7 @@ public void Quantize(DataType targetType)
public void QuantParamOf(QuantMode quantMode)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)49);
+ _emitter.Write((ushort)53);
_emitter.Write((int)quantMode);
}
@@ -1016,14 +1044,14 @@ public void QuantParamOf(QuantMode quantMode)
public void Range()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)50);
+ _emitter.Write((ushort)54);
}
///.
public void RangeOf(bool isRangeOfWeight)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)51);
+ _emitter.Write((ushort)55);
_emitter.Write(isRangeOfWeight);
}
@@ -1031,14 +1059,14 @@ public void RangeOf(bool isRangeOfWeight)
public void Rank()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)52);
+ _emitter.Write((ushort)56);
}
///.
public void Reduce(ReduceOp reduceOp)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)53);
+ _emitter.Write((ushort)57);
_emitter.Write((byte)reduceOp);
}
@@ -1046,7 +1074,7 @@ public void Reduce(ReduceOp reduceOp)
public void ReduceArg(ReduceArgOp reduceArgOp, DataType destType)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)54);
+ _emitter.Write((ushort)58);
_emitter.Write((byte)reduceArgOp);
_emitter.Write(destType);
}
@@ -1055,7 +1083,7 @@ public void ReduceArg(ReduceArgOp reduceArgOp, DataType destType)
public void ReduceWindow2D(ReduceOp reduceOp)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)55);
+ _emitter.Write((ushort)59);
_emitter.Write((byte)reduceOp);
}
@@ -1063,21 +1091,21 @@ public void ReduceWindow2D(ReduceOp reduceOp)
public void Relu()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)56);
+ _emitter.Write((ushort)60);
}
///.
public void Relu6()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)57);
+ _emitter.Write((ushort)61);
}
///.
public void Require(string message, bool canFoldConstCall)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)58);
+ _emitter.Write((ushort)62);
_emitter.Write(message);
_emitter.Write(canFoldConstCall);
}
@@ -1086,14 +1114,14 @@ public void Require(string message, bool canFoldConstCall)
public void Reshape()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)59);
+ _emitter.Write((ushort)63);
}
///.
public void ResizeImage(ImageResizeMode resizeMode, ImageResizeTransformationMode transformationMode, ImageResizeNearestMode nearestMode, bool isTFResize)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)60);
+ _emitter.Write((ushort)64);
_emitter.Write((byte)resizeMode);
_emitter.Write((int)transformationMode);
_emitter.Write((int)nearestMode);
@@ -1104,147 +1132,147 @@ public void ResizeImage(ImageResizeMode resizeMode, ImageResizeTransformationMod
public void ReverseSequence()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)61);
+ _emitter.Write((ushort)65);
}
///.
public void ScatterND()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)62);
+ _emitter.Write((ushort)66);
}
///.
public void Select()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)63);
+ _emitter.Write((ushort)67);
}
///.
public void Selu()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)64);
+ _emitter.Write((ushort)68);
}
///.
public void ShapeOf()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)65);
+ _emitter.Write((ushort)69);
}
///.
public void Sigmoid()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)66);
+ _emitter.Write((ushort)70);
}
///.
public void SizeOf()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)67);
+ _emitter.Write((ushort)71);
}
///.
public void Slice()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)68);
+ _emitter.Write((ushort)72);
}
///.
public void Softmax()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)69);
+ _emitter.Write((ushort)73);
}
///.
public void Softplus()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)70);
+ _emitter.Write((ushort)74);
}
///.
public void Softsign()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)71);
+ _emitter.Write((ushort)75);
}
///.
public void SpaceToBatch()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)72);
+ _emitter.Write((ushort)76);
}
///.
public void Split()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)73);
+ _emitter.Write((ushort)77);
}
///.
public void Squeeze()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)74);
+ _emitter.Write((ushort)78);
}
///.
public void Stack()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)75);
+ _emitter.Write((ushort)79);
}
///.
public void Swish()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)76);
+ _emitter.Write((ushort)80);
}
///.
public void Tile()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)77);
+ _emitter.Write((ushort)81);
}
///.
public void TopK()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)78);
+ _emitter.Write((ushort)82);
}
///.
public void Transpose()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)79);
+ _emitter.Write((ushort)83);
}
///.
public void Trilu()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)80);
+ _emitter.Write((ushort)84);
}
///.
public void Unary(UnaryOp unaryOp)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)81);
+ _emitter.Write((ushort)85);
_emitter.Write((byte)unaryOp);
}
@@ -1252,7 +1280,7 @@ public void Unary(UnaryOp unaryOp)
public void Uniform(DataType type)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)82);
+ _emitter.Write((ushort)86);
_emitter.Write(type);
}
@@ -1260,7 +1288,7 @@ public void Uniform(DataType type)
public void UniformLike(DataType type)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)83);
+ _emitter.Write((ushort)87);
_emitter.Write(type);
}
@@ -1268,14 +1296,14 @@ public void UniformLike(DataType type)
public void Unsqueeze()
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)84);
+ _emitter.Write((ushort)88);
}
///.
public void Where(bool isTfWhere)
{
_emitter.Write((byte)100);
- _emitter.Write((ushort)85);
+ _emitter.Write((ushort)89);
_emitter.Write(isTfWhere);
}
}
diff --git a/pyproject.toml b/pyproject.toml
index 180e5c44b6..04a03089f8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -24,7 +24,8 @@ dependencies = ["numpy"]
homepage = "https://github.com/kendryte/nncase"
[build-system]
-requires = ["setuptools>=42", "wheel", "conan<=1.59", "ninja"]
+requires = ["setuptools>=42", "wheel", "conan<=1.59", "ninja", "gitpython"]
+build-backend = "setuptools.build_meta"
[tool.cibuildwheel]
build = ["cp37*", "cp38*", "cp39*", "cp310*"]
diff --git a/python/nncase/__init__.py b/python/nncase/__init__.py
index 8653d3b301..5784a37915 100644
--- a/python/nncase/__init__.py
+++ b/python/nncase/__init__.py
@@ -152,6 +152,16 @@ def __init__(self, compile_options: CompileOptions) -> None:
self._compiler = self._session.compiler
self._quantize_options = None
self._shape_bucket_options = _nncase.ShapeBucketOptions()
+ self.init_shape_bucket_options(compile_options)
+
+ def init_shape_bucket_options(self, compile_options: CompileOptions) -> None:
+ self._shape_bucket_options = _nncase.ShapeBucketOptions()
+ self._shape_bucket_options.segments_count = compile_options.shape_bucket_segments_count
+ self._shape_bucket_options.enable = compile_options.shape_bucket_enable
+ self._shape_bucket_options.range_info = compile_options.shape_bucket_range_info
+ self._shape_bucket_options.segments_count = compile_options.shape_bucket_segments_count
+ self._shape_bucket_options.fix_var_map = compile_options.shape_bucket_fix_var_map
+ self._compile_options.shape_bucket_options = self._shape_bucket_options
def compile(self) -> None:
self._compiler.compile()
diff --git a/requirements.test.txt b/requirements.test.txt
index 96087104fc..5afc08e761 100644
--- a/requirements.test.txt
+++ b/requirements.test.txt
@@ -18,3 +18,5 @@ pyyaml
pythonnet==3.0.1
clr_loader==0.2.4
toml==0.10.2
+pandas
+tabulate
diff --git a/setup.py b/setup.py
index 2380f65b17..6724cbac65 100644
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,8 @@
import io
import re
import time
-
+import subprocess
+from git.repo import Repo
# See ref: https://stackoverflow.com/a/51575996
@@ -277,8 +278,19 @@ def find_version():
version_prefix = re.findall(r"NNCASE_VERSION \"(.+)\"", version_file)
if version_prefix:
+ repo_path = os.getcwd()
+ repo = Repo(repo_path)
+ if repo.tags:
+ latest_commit = subprocess.check_output(
+ ['git', 'rev-parse', 'HEAD']).decode('utf-8').strip()
+ tagged_commit = subprocess.check_output(
+ ['git', 'rev-list', '-n', '1', repo.tags[-1].name]).decode('utf-8').strip()
+ if latest_commit == tagged_commit:
+ return version_prefix[0]
+
version_suffix = time.strftime("%Y%m%d", time.localtime())
return version_prefix[0] + "." + version_suffix
+
raise RuntimeError("Unable to find version string.")
diff --git a/src/Native/include/nncase/kernels/stackvm/tensor_ops.h b/src/Native/include/nncase/kernels/stackvm/tensor_ops.h
index 8de16e8c34..db59425a29 100644
--- a/src/Native/include/nncase/kernels/stackvm/tensor_ops.h
+++ b/src/Native/include/nncase/kernels/stackvm/tensor_ops.h
@@ -1,4 +1,4 @@
-/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 15:04:16
+/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 17:07:39
* +08:00.
*
* Copyright 2019-2021 Canaan Inc.
@@ -51,6 +51,10 @@ NNCASE_API result
broadcast(value_t input, value_t shape, value_t output = nullptr,
kernel_context &context = default_kernel_context());
+NNCASE_API result
+broadcast_shape(value_t inputs, value_t output = nullptr,
+ kernel_context &context = default_kernel_context());
+
NNCASE_API result
bucket_pad(value_t input, value_t shape, value_t output = nullptr,
kernel_context &context = default_kernel_context());
@@ -92,6 +96,11 @@ conv2d(runtime::stackvm::pad_mode_t pad_mode, value_t input, value_t weights,
value_t groups, value_t fused_clamp, value_t output = nullptr,
kernel_context &context = default_kernel_context());
+NNCASE_API result
+conv2d_shape(value_t input, value_t weights, value_t padding, value_t stride,
+ value_t dilation, value_t groups, value_t output = nullptr,
+ kernel_context &context = default_kernel_context());
+
NNCASE_API result
conv2d_transpose(runtime::stackvm::pad_mode_t pad_mode, value_t input,
value_t weights, value_t bias, value_t output_shape,
@@ -100,6 +109,13 @@ conv2d_transpose(runtime::stackvm::pad_mode_t pad_mode, value_t input,
value_t output = nullptr,
kernel_context &context = default_kernel_context());
+NNCASE_API result
+conv2d_transpose_shape(value_t input, value_t weights, value_t stride,
+ value_t dilation, value_t padding,
+ value_t output_padding, value_t groups,
+ value_t output = nullptr,
+ kernel_context &context = default_kernel_context());
+
NNCASE_API result
cum_sum(value_t input, value_t axis, value_t exclusive, value_t reverse,
value_t output = nullptr,
@@ -225,6 +241,10 @@ NNCASE_API result
mat_mul(value_t lhs, value_t rhs, value_t output = nullptr,
kernel_context &context = default_kernel_context());
+NNCASE_API result
+mat_mul_shape(value_t lhs, value_t rhs, value_t output = nullptr,
+ kernel_context &context = default_kernel_context());
+
NNCASE_API result
normal(typecode_t type, value_t mean, value_t scale, value_t seed,
value_t shape, value_t output = nullptr,
diff --git a/src/Native/include/nncase/runtime/bfloat16.h b/src/Native/include/nncase/runtime/bfloat16.h
index 4d15803a44..b97a4e7c3c 100644
--- a/src/Native/include/nncase/runtime/bfloat16.h
+++ b/src/Native/include/nncase/runtime/bfloat16.h
@@ -61,6 +61,8 @@ struct bfloat16 {
explicit bfloat16(const T &val) noexcept
: bfloat16(static_cast(val)) {}
+ bfloat16(int &&val) noexcept : bfloat16(static_cast(val)) {}
+
constexpr bfloat16(from_raw_t, uint16_t value) noexcept : value_(value) {}
operator float() const noexcept {
@@ -153,6 +155,10 @@ struct bfloat16 {
return (value_ & 0x7FFF) == ZERO_VALUE;
}
+ void operator=(const float &v) noexcept {
+ value_ = (round_to_bfloat16(v).value_);
+ }
+
private:
uint16_t value_;
};
diff --git a/src/Native/include/nncase/runtime/half.h b/src/Native/include/nncase/runtime/half.h
index 8ee136e471..2a53417192 100644
--- a/src/Native/include/nncase/runtime/half.h
+++ b/src/Native/include/nncase/runtime/half.h
@@ -59,6 +59,8 @@ struct half {
std::is_floating_point::value>>
explicit half(const T &val) noexcept : half(static_cast(val)) {}
+ half(int &&val) noexcept : half(static_cast(val)) {}
+
constexpr half(fp16_from_raw_t, uint16_t value) noexcept : value_(value) {}
operator float() const noexcept {
@@ -156,6 +158,10 @@ struct half {
return (value_ & 0x7FFF) == ZERO_VALUE;
}
+ void operator=(const float &v) noexcept {
+ value_ = (round_to_half(v).value_);
+ }
+
private:
uint16_t value_;
};
diff --git a/src/Native/include/nncase/runtime/stackvm/op_reader.h b/src/Native/include/nncase/runtime/stackvm/op_reader.h
index 0ba037d227..5de273cab1 100644
--- a/src/Native/include/nncase/runtime/stackvm/op_reader.h
+++ b/src/Native/include/nncase/runtime/stackvm/op_reader.h
@@ -1,4 +1,4 @@
-/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 15:04:16
+/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 17:07:39
* +08:00.
*
* Copyright 2019-2021 Canaan Inc.
@@ -786,6 +786,14 @@ template <> struct tensor_op_reader {
}
};
+template <> struct tensor_op_reader {
+ tensor_broadcast_shape_op_t
+ operator()(NNCASE_UNUSED span_reader &reader) const {
+ tensor_broadcast_shape_op_t op;
+ return op;
+ }
+};
+
template <> struct tensor_op_reader {
tensor_bucket_pad_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
tensor_bucket_pad_op_t op;
@@ -857,6 +865,14 @@ template <> struct tensor_op_reader {
}
};
+template <> struct tensor_op_reader {
+ tensor_conv2d_shape_op_t
+ operator()(NNCASE_UNUSED span_reader &reader) const {
+ tensor_conv2d_shape_op_t op;
+ return op;
+ }
+};
+
template <> struct tensor_op_reader {
tensor_conv2d_transpose_op_t
operator()(NNCASE_UNUSED span_reader &reader) const {
@@ -866,6 +882,14 @@ template <> struct tensor_op_reader {
}
};
+template <> struct tensor_op_reader {
+ tensor_conv2d_transpose_shape_op_t
+ operator()(NNCASE_UNUSED span_reader &reader) const {
+ tensor_conv2d_transpose_shape_op_t op;
+ return op;
+ }
+};
+
template <> struct tensor_op_reader {
tensor_cum_sum_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
tensor_cum_sum_op_t op;
@@ -1076,6 +1100,14 @@ template <> struct tensor_op_reader {
}
};
+template <> struct tensor_op_reader {
+ tensor_mat_mul_shape_op_t
+ operator()(NNCASE_UNUSED span_reader &reader) const {
+ tensor_mat_mul_shape_op_t op;
+ return op;
+ }
+};
+
template <> struct tensor_op_reader {
tensor_normal_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
tensor_normal_op_t op;
@@ -1449,6 +1481,10 @@ class NNCASE_API tensor_op_visitor {
return default_visit(tensor_function_t::broadcast, &op);
}
virtual result
+ visit(NNCASE_UNUSED const tensor_broadcast_shape_op_t &op) noexcept {
+ return default_visit(tensor_function_t::broadcast_shape, &op);
+ }
+ virtual result
visit(NNCASE_UNUSED const tensor_bucket_pad_op_t &op) noexcept {
return default_visit(tensor_function_t::bucket_pad, &op);
}
@@ -1485,10 +1521,18 @@ class NNCASE_API tensor_op_visitor {
return default_visit(tensor_function_t::conv2d, &op);
}
virtual result
+ visit(NNCASE_UNUSED const tensor_conv2d_shape_op_t &op) noexcept {
+ return default_visit(tensor_function_t::conv2d_shape, &op);
+ }
+ virtual result
visit(NNCASE_UNUSED const tensor_conv2d_transpose_op_t &op) noexcept {
return default_visit(tensor_function_t::conv2d_transpose, &op);
}
virtual result
+ visit(NNCASE_UNUSED const tensor_conv2d_transpose_shape_op_t &op) noexcept {
+ return default_visit(tensor_function_t::conv2d_transpose_shape, &op);
+ }
+ virtual result
visit(NNCASE_UNUSED const tensor_cum_sum_op_t &op) noexcept {
return default_visit(tensor_function_t::cum_sum, &op);
}
@@ -1597,6 +1641,10 @@ class NNCASE_API tensor_op_visitor {
return default_visit(tensor_function_t::mat_mul, &op);
}
virtual result
+ visit(NNCASE_UNUSED const tensor_mat_mul_shape_op_t &op) noexcept {
+ return default_visit(tensor_function_t::mat_mul_shape, &op);
+ }
+ virtual result
visit(NNCASE_UNUSED const tensor_normal_op_t &op) noexcept {
return default_visit(tensor_function_t::normal, &op);
}
diff --git a/src/Native/include/nncase/runtime/stackvm/opcode.h b/src/Native/include/nncase/runtime/stackvm/opcode.h
index dfc066b913..26e98927f1 100644
--- a/src/Native/include/nncase/runtime/stackvm/opcode.h
+++ b/src/Native/include/nncase/runtime/stackvm/opcode.h
@@ -1,4 +1,4 @@
-/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 15:04:15
+/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 17:07:38
* +08:00.
*
* Copyright 2019-2021 Canaan Inc.
@@ -130,90 +130,94 @@ enum class opcode_t : uint8_t {
enum class tensor_function_t : uint16_t {
batch_normalization = 0,
batch_to_space = 1,
- celu = 7,
- conv2d = 13,
- conv2d_transpose = 14,
- elu = 17,
- erf = 18,
- gelu = 27,
- hardmax = 29,
- hard_sigmoid = 30,
- hard_swish = 31,
- instance_normalization = 33,
- l2_normalization = 34,
- layer_norm = 35,
- leaky_relu = 36,
- log_softmax = 37,
- lp_normalization = 38,
- lrn = 39,
- one_hot = 44,
- pad = 45,
- prelu = 46,
- reduce_window2d = 55,
- relu = 56,
- relu6 = 57,
- selu = 64,
- sigmoid = 66,
- softmax = 69,
- softplus = 70,
- softsign = 71,
- space_to_batch = 72,
- swish = 76,
+ celu = 8,
+ conv2d = 14,
+ conv2d_transpose = 16,
+ elu = 20,
+ erf = 21,
+ gelu = 30,
+ hardmax = 32,
+ hard_sigmoid = 33,
+ hard_swish = 34,
+ instance_normalization = 36,
+ l2_normalization = 37,
+ layer_norm = 38,
+ leaky_relu = 39,
+ log_softmax = 40,
+ lp_normalization = 41,
+ lrn = 42,
+ one_hot = 48,
+ pad = 49,
+ prelu = 50,
+ reduce_window2d = 59,
+ relu = 60,
+ relu6 = 61,
+ selu = 68,
+ sigmoid = 70,
+ softmax = 73,
+ softplus = 74,
+ softsign = 75,
+ space_to_batch = 76,
+ swish = 80,
binary = 2,
- clamp = 8,
- compare = 9,
- condition = 11,
- cum_sum = 15,
- dequantize = 16,
- fake_dequantize = 20,
- fake_quantize = 21,
- mat_mul = 41,
- quantize = 48,
- quant_param_of = 49,
- range_of = 51,
- reduce = 53,
- reduce_arg = 54,
- require = 58,
- select = 63,
- unary = 81,
+ clamp = 9,
+ compare = 10,
+ condition = 12,
+ cum_sum = 18,
+ dequantize = 19,
+ fake_dequantize = 23,
+ fake_quantize = 24,
+ mat_mul = 44,
+ quantize = 52,
+ quant_param_of = 53,
+ range_of = 55,
+ reduce = 57,
+ reduce_arg = 58,
+ require = 62,
+ select = 67,
+ unary = 85,
bitcast = 3,
broadcast = 4,
- bucket_pad = 5,
- cast = 6,
- concat = 10,
- constant_of_shape = 12,
- expand = 19,
- fix_shape = 22,
- flatten = 23,
- gather = 24,
- gather_elements = 25,
- gather_nd = 26,
- get_item = 28,
- index_of = 32,
- lstm = 40,
- prod = 47,
- range = 50,
- rank = 52,
- reshape = 59,
- reverse_sequence = 61,
- scatter_nd = 62,
- shape_of = 65,
- size_of = 67,
- slice = 68,
- split = 73,
- squeeze = 74,
- stack = 75,
- tile = 77,
- top_k = 78,
- transpose = 79,
- trilu = 80,
- unsqueeze = 84,
- where = 85,
- normal = 42,
- normal_like = 43,
- uniform = 82,
- uniform_like = 83,
- resize_image = 60,
+ bucket_pad = 6,
+ cast = 7,
+ concat = 11,
+ constant_of_shape = 13,
+ expand = 22,
+ fix_shape = 25,
+ flatten = 26,
+ gather = 27,
+ gather_elements = 28,
+ gather_nd = 29,
+ get_item = 31,
+ index_of = 35,
+ lstm = 43,
+ prod = 51,
+ range = 54,
+ rank = 56,
+ reshape = 63,
+ reverse_sequence = 65,
+ scatter_nd = 66,
+ shape_of = 69,
+ size_of = 71,
+ slice = 72,
+ split = 77,
+ squeeze = 78,
+ stack = 79,
+ tile = 81,
+ top_k = 82,
+ transpose = 83,
+ trilu = 84,
+ unsqueeze = 88,
+ where = 89,
+ broadcast_shape = 5,
+ conv2d_shape = 15,
+ conv2d_transpose_shape = 17,
+ mat_mul_shape = 45,
+ normal = 46,
+ normal_like = 47,
+ uniform = 86,
+ uniform_like = 87,
+ resize_image = 64,
};
enum class binary_op_t : uint8_t {
@@ -588,6 +592,8 @@ struct tensor_bitcast_op_t {
struct tensor_broadcast_op_t {};
+struct tensor_broadcast_shape_op_t {};
+
struct tensor_bucket_pad_op_t {};
struct tensor_cast_op_t {
@@ -615,10 +621,14 @@ struct tensor_conv2d_op_t {
pad_mode_t pad_mode;
};
+struct tensor_conv2d_shape_op_t {};
+
struct tensor_conv2d_transpose_op_t {
pad_mode_t pad_mode;
};
+struct tensor_conv2d_transpose_shape_op_t {};
+
struct tensor_cum_sum_op_t {};
struct tensor_dequantize_op_t {
@@ -686,6 +696,8 @@ struct tensor_lstm_op_t {
struct tensor_mat_mul_op_t {};
+struct tensor_mat_mul_shape_op_t {};
+
struct tensor_normal_op_t {
typecode_t type;
};
@@ -975,6 +987,14 @@ inline std::string to_string(tensor_function_t tensor_funct) {
return "unsqueeze";
case tensor_function_t::where:
return "where";
+ case tensor_function_t::broadcast_shape:
+ return "broadcast_shape";
+ case tensor_function_t::conv2d_shape:
+ return "conv2d_shape";
+ case tensor_function_t::conv2d_transpose_shape:
+ return "conv2d_transpose_shape";
+ case tensor_function_t::mat_mul_shape:
+ return "mat_mul_shape";
case tensor_function_t::normal:
return "normal";
case tensor_function_t::normal_like:
diff --git a/src/Native/include/nncase/runtime/util.h b/src/Native/include/nncase/runtime/util.h
index 8740233cbc..68bd808025 100644
--- a/src/Native/include/nncase/runtime/util.h
+++ b/src/Native/include/nncase/runtime/util.h
@@ -468,6 +468,10 @@ inline bool is_contiguous(tensor tensor) {
switch (_typecode) { \
case dt_float32: \
_impl(float); \
+ case dt_float16: \
+ _impl(half); \
+ case dt_bfloat16: \
+ _impl(bfloat16); \
case dt_int8: \
_impl(int8_t); \
case dt_int16: \
diff --git a/src/Native/src/kernels/stackvm/optimized/dequantize.cpp b/src/Native/src/kernels/stackvm/optimized/dequantize.cpp
index 84a63b3dfc..b60862d2e3 100644
--- a/src/Native/src/kernels/stackvm/optimized/dequantize.cpp
+++ b/src/Native/src/kernels/stackvm/optimized/dequantize.cpp
@@ -75,5 +75,6 @@ result optimized::dequantize(
NNCASE_UNUSED kernel_context &context) noexcept {
DEQUANTIZE_IMPL(uint8_t, float)
DEQUANTIZE_IMPL(int8_t, float)
+ DEQUANTIZE_IMPL(int16_t, float)
return err(std::errc::not_supported);
}
diff --git a/src/Native/src/kernels/stackvm/optimized/quantize.cpp b/src/Native/src/kernels/stackvm/optimized/quantize.cpp
index 81efee18aa..ff7960cdda 100644
--- a/src/Native/src/kernels/stackvm/optimized/quantize.cpp
+++ b/src/Native/src/kernels/stackvm/optimized/quantize.cpp
@@ -88,5 +88,6 @@ result optimized::quantize(
NNCASE_UNUSED kernel_context &context) noexcept {
QUANTIZE_IMPL(float, uint8_t)
QUANTIZE_IMPL(float, int8_t)
+ QUANTIZE_IMPL(float, int16_t)
return err(std::errc::not_supported);
}
\ No newline at end of file
diff --git a/src/Native/src/kernels/stackvm/optimized/resize_image.cpp b/src/Native/src/kernels/stackvm/optimized/resize_image.cpp
index 603d95e8ab..57d87462d4 100644
--- a/src/Native/src/kernels/stackvm/optimized/resize_image.cpp
+++ b/src/Native/src/kernels/stackvm/optimized/resize_image.cpp
@@ -221,7 +221,10 @@ inline result resize_bilinear_impl(
auto a3 = (in_y - in_y0) * (in_x - in_x0);
*output_ptr = bfloat16::round_to_bfloat16(
- v0 * a0 + v1 * a1 + v2 * a2 + v3 * a3);
+ static_cast(v0) * a0 +
+ static_cast(v1) * a1 +
+ static_cast(v2) * a2 +
+ static_cast(v3) * a3);
++output_ptr;
}
}
diff --git a/src/Native/src/kernels/stackvm/optimized/riscv64/unary.cpp b/src/Native/src/kernels/stackvm/optimized/riscv64/unary.cpp
index 78b3c95cfe..b83cbbbf36 100644
--- a/src/Native/src/kernels/stackvm/optimized/riscv64/unary.cpp
+++ b/src/Native/src/kernels/stackvm/optimized/riscv64/unary.cpp
@@ -171,57 +171,68 @@ result optimized::unary(typecode_t dtype, runtime::stackvm::unary_op_t op,
gsl::span out_shape,
gsl::span out_strides,
kernel_context &context) noexcept {
+ if (dtype == dt_float32) {
#if __riscv_vector
- auto *input = IN_CAST(float, in);
- auto *output = OUT_CAST(float, out);
- switch (op) {
- case unary_op_t::abs: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::ceil: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::cos: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::exp: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::floor: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::log: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::neg: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::round: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::rsqrt: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::sign: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::sin: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::sqrt: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::square: {
- return optimized_unary_impl(input, output, shape);
- }
- case unary_op_t::tanh: {
- return optimized_unary_impl(input, output, shape);
- }
- default:;
- // std::cout << "Unsupported unary op: " + unary_op_to_string(op)
- // + " for optimizing, fallback to reference" << std::endl;
- }
+ auto *input = IN_CAST(float, in);
+ auto *output = OUT_CAST(float, out);
+ switch (op) {
+ case unary_op_t::abs: {
+ return optimized_unary_impl(input, output, shape);
+ }
+ case unary_op_t::ceil: {
+ return optimized_unary_impl(input, output,
+ shape);
+ }
+ case unary_op_t::cos: {
+ return optimized_unary_impl(input, output, shape);
+ }
+ case unary_op_t::exp: {
+ return optimized_unary_impl(input, output, shape);
+ }
+ case unary_op_t::floor: {
+ return optimized_unary_impl(input, output,
+ shape);
+ }
+ case unary_op_t::log: {
+ return optimized_unary_impl(input, output, shape);
+ }
+ case unary_op_t::neg: {
+ return optimized_unary_impl(input, output, shape);
+ }
+ case unary_op_t::round: {
+ return optimized_unary_impl(input, output,
+ shape);
+ }
+ case unary_op_t::rsqrt: {
+ return optimized_unary_impl(input, output,
+ shape);
+ }
+ case unary_op_t::sign: {
+ return optimized_unary_impl(input, output,
+ shape);
+ }
+ case unary_op_t::sin: {
+ return optimized_unary_impl(input, output, shape);
+ }
+ case unary_op_t::sqrt: {
+ return optimized_unary_impl(input, output,
+ shape);
+ }
+ case unary_op_t::square: {
+ return optimized_unary_impl(input, output,
+ shape);
+ }
+ case unary_op_t::tanh: {
+ return optimized_unary_impl(input, output,
+ shape);
+ }
+ default:;
+ // std::cout << "Unsupported unary op: " +
+ // unary_op_to_string(op)
+ // + " for optimizing, fallback to reference" << std::endl;
+ }
#endif
+ }
return stackvm::reference::unary(dtype, op, in, out, shape, in_strides,
out_shape, out_strides, context);
}
\ No newline at end of file
diff --git a/src/Native/src/kernels/stackvm/optimized/x86_64/unary.cpp b/src/Native/src/kernels/stackvm/optimized/x86_64/unary.cpp
index 78bedf4457..01d5d1af4e 100644
--- a/src/Native/src/kernels/stackvm/optimized/x86_64/unary.cpp
+++ b/src/Native/src/kernels/stackvm/optimized/x86_64/unary.cpp
@@ -104,13 +104,30 @@ struct unary_op_neg {
}
};
+static float round_onnx(float v) {
+ if (v > 0 && v - (int32_t)v == 0.5) {
+ float result = (int32_t)v + 1.0;
+ if ((int32_t)result % 2 == 0)
+ return result;
+ else
+ return result - 1;
+ } else if (v < 0 && (int32_t)v - v == 0.5) {
+ float result = (int32_t)v + 1.0;
+ if ((int32_t)result % 2 == 0)
+ return result;
+ else
+ return result - 1;
+ } else
+ return roundf(v);
+}
+
struct unary_op_round {
- float operator()(float x) const { return roundf(x); }
+ float operator()(float x) const { return round_onnx(x); }
void pack(const float *a, float *b) {
__m256 vector_a = _mm256_loadu_ps(a);
__m256 dst_a = _mm256_round_ps(
- vector_a, (_MM_FROUND_CUR_DIRECTION | _MM_FROUND_NO_EXC));
+ vector_a, (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
_mm256_storeu_ps(b, dst_a);
}
};
diff --git a/src/Native/src/kernels/stackvm/reference/CMakeLists.txt b/src/Native/src/kernels/stackvm/reference/CMakeLists.txt
index e7a2f660fb..84dd07203c 100644
--- a/src/Native/src/kernels/stackvm/reference/CMakeLists.txt
+++ b/src/Native/src/kernels/stackvm/reference/CMakeLists.txt
@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.13)
set(SRCS ../tensor_ops.cpp
+ ../shape_ops.cpp
activation.cpp
batchnorm.cpp
batch_to_space.cpp
diff --git a/src/Native/src/kernels/stackvm/reference/activation.cpp b/src/Native/src/kernels/stackvm/reference/activation.cpp
index b0b468305d..af96c6639c 100644
--- a/src/Native/src/kernels/stackvm/reference/activation.cpp
+++ b/src/Native/src/kernels/stackvm/reference/activation.cpp
@@ -29,30 +29,30 @@ using namespace nncase::runtime::stackvm;
using namespace nncase::kernels;
using namespace nncase::kernels::stackvm;
-FLOAT_UNARY_TEMPLATE(relu, std::max((float)0, x))
-FLOAT_UNARY_TEMPLATE(softsign, x / (1 + std::abs(x)))
-FLOAT_UNARY_TEMPLATE(softplus, std::log(1 + std::exp(x)))
-FLOAT_UNARY_TEMPLATE(sigmoid, 1 / (1 + exp(-x)))
-FLOAT_UNARY_TEMPLATE(swish, x / (1 + exp(-x)))
-FLOAT_UNARY_TEMPLATE(hard_swish,
- x *std::max(0.f, std::min((float)1.f,
- (float)(1.f / 6 * x + 0.5))))
-FLOAT_UNARY_TEMPLATE(erf, erff(x)) // for k510 toolchain
-FLOAT_UNARY_WITH_MUL_TEMPLATE(elu, alpha, x < 0 ? alpha * (exp(x) - 1) : x)
+UNARY_TEMPLATE(relu, std::max((double)0, x))
+UNARY_TEMPLATE(softsign, x / (1 + std::abs(x)))
+UNARY_TEMPLATE(softplus, std::log(1 + std::exp(x)))
+UNARY_TEMPLATE(sigmoid, 1 / (1 + exp(-x)))
+UNARY_TEMPLATE(swish, x / (1 + exp(-x)))
+UNARY_TEMPLATE(hard_swish,
+ x *std::max((double)0.f,
+ std::min((double)1.f, (double)(1.f / 6 * x + 0.5))))
+UNARY_TEMPLATE(erf, erff(x)) // for k510 toolchain
+UNARY_WITH_MUL_TEMPLATE_V2(elu, alpha, x < 0 ? alpha * (exp(x) - 1) : x)
// FLOAT_UNARY_WITH_MUL_TEMPLATE(prelu, slope, x < 0 ? slope * x : x)
-FLOAT_UNARY_WITH_MUL_TEMPLATE(
- celu, alpha,
- std::max((float)0, x) +
- std::min((float)0, (float)(alpha *(exp(x / alpha) - 1))))
-FLOAT_UNARY_WITH_MUL_TEMPLATE(leaky_relu, alpha, x < 0 ? alpha * x : x)
-FLOAT_UNARY_WITH_MUL_TEMPLATE(gelu, alpha,
- 0.5f * (alpha * x) *
- (1.f + erff(alpha * x / sqrtf(2.f))))
-FLOAT_ACTIVATION_TEMPLATE(selu,
- x <= 0 ? gamma * (alpha * std::exp(x) - alpha)
- : x * gamma,
- alpha, gamma)
-FLOAT_ACTIVATION_TEMPLATE(hard_sigmoid,
- std::max((float)0,
- std::min((float)1, x *alpha + beta)),
- alpha, beta)
\ No newline at end of file
+UNARY_WITH_MUL_TEMPLATE_V2(celu, alpha,
+ std::max((double)0, x) +
+ std::min((double)0,
+ (double)(alpha *(exp(x / alpha) - 1))))
+UNARY_WITH_MUL_TEMPLATE_V2(leaky_relu, alpha, x < 0 ? alpha * x : x)
+UNARY_WITH_MUL_TEMPLATE_V2(gelu, alpha,
+ 0.5f * (alpha * x) *
+ (1.f + erff(alpha * x / sqrtf(2.f))))
+ACTIVATION_TEMPLATE_V2(selu,
+ x <= 0 ? gamma * (alpha * std::exp(x) - alpha)
+ : x * gamma,
+ alpha, gamma)
+ACTIVATION_TEMPLATE_V2(hard_sigmoid,
+ std::max((double)0,
+ std::min((double)1, x *alpha + gamma)),
+ alpha, gamma)
\ No newline at end of file
diff --git a/src/Native/src/kernels/stackvm/reference/batch_to_space.cpp b/src/Native/src/kernels/stackvm/reference/batch_to_space.cpp
index 12df871f8f..d113cba4a6 100644
--- a/src/Native/src/kernels/stackvm/reference/batch_to_space.cpp
+++ b/src/Native/src/kernels/stackvm/reference/batch_to_space.cpp
@@ -103,8 +103,13 @@ batch_to_space_impl(datatype_t type, const gsl::byte *input, gsl::byte *output,
dims_t infer_shape(gsl::span origin_in_shape,
gsl::span block_shape,
const paddings_t &crops) {
- auto in_shape = kernels::stackvm::transpose_infer_shape(
- origin_in_shape, fixed_dims(0, 2, 3, 1));
+ auto d4 = fixed_dims(0, 2, 3, 1);
+ auto d3 = fixed_dims(0, 2, 1);
+ auto inPerm = origin_in_shape.size() == 4
+ ? gsl::span{d4.data(), d4.size()}
+ : gsl::span{d3.data(), d3.size()};
+ auto in_shape =
+ kernels::stackvm::transpose_infer_shape(origin_in_shape, inPerm);
auto batch = in_shape[0] / compute_size(block_shape);
auto out_shape = dims_t{batch};
auto m = block_shape.size();
@@ -117,8 +122,12 @@ dims_t infer_shape(gsl::span origin_in_shape,
out_shape.insert(out_shape.end(), in_shape.end() - remain_size,
in_shape.end());
}
- return kernels::stackvm::transpose_infer_shape(out_shape,
- fixed_dims(0, 3, 1, 2));
+ auto outd4 = fixed_dims(0, 3, 1, 2);
+ auto outd3 = fixed_dims(0, 2, 1);
+ auto outPerm = origin_in_shape.size() == 4
+ ? gsl::span{outd4.data(), outd4.size()}
+ : gsl::span{outd3.data(), outd3.size()};
+ return kernels::stackvm::transpose_infer_shape(out_shape, outPerm);
}
result kernels::stackvm::batch_to_space(value_t input,
diff --git a/src/Native/src/kernels/stackvm/reference/clamp.cpp b/src/Native/src/kernels/stackvm/reference/clamp.cpp
index c9d42450e8..eb3bdfc72f 100644
--- a/src/Native/src/kernels/stackvm/reference/clamp.cpp
+++ b/src/Native/src/kernels/stackvm/reference/clamp.cpp
@@ -34,7 +34,9 @@ result clamp_impl(const T *input, T min, T max, T *output,
NNCASE_UNUSED kernel_context &context) {
return apply(in_shape, [&](gsl::span index) -> result {
const auto v = input[offset(index, in_strides)];
- output[offset(index, out_strides)] = std::min(std::max(v, min), max);
+ output[offset(index, out_strides)] = static_cast(
+ std::min(std::max(static_cast(v), static_cast(min)),
+ static_cast(max)));
return ok();
});
}
diff --git a/src/Native/src/kernels/stackvm/reference/dequantize.cpp b/src/Native/src/kernels/stackvm/reference/dequantize.cpp
index 3ee7202804..3c799b5a16 100644
--- a/src/Native/src/kernels/stackvm/reference/dequantize.cpp
+++ b/src/Native/src/kernels/stackvm/reference/dequantize.cpp
@@ -55,5 +55,6 @@ result nncase::kernels::stackvm::reference::dequantize(
float scale, float bias, kernel_context &context) noexcept {
DEQUANTIZE_IMPL(uint8_t, float);
DEQUANTIZE_IMPL(int8_t, float);
+ DEQUANTIZE_IMPL(int16_t, float);
return err(std::errc::not_supported);
}
\ No newline at end of file
diff --git a/src/Native/src/kernels/stackvm/reference/kernel_template.h b/src/Native/src/kernels/stackvm/reference/kernel_template.h
index b636007284..f01fc7a339 100644
--- a/src/Native/src/kernels/stackvm/reference/kernel_template.h
+++ b/src/Native/src/kernels/stackvm/reference/kernel_template.h
@@ -16,7 +16,7 @@
#include
-#define FLOAT_UNARY_IMPL_TEMPLATE(_name, _compute) \
+#define UNARY_IMPL_TEMPLATE(_name, _compute) \
template \
result _name##_impl( \
const T *input, T *output, gsl::span in_shape, \
@@ -30,8 +30,8 @@
kernels::detail::get_reduced_offset(index, in_shape); \
auto src_idx = offset(input_strides, in_index); \
auto dst_idx = offset(out_strides, in_index); \
- auto x = input[src_idx]; \
- output[dst_idx] = _compute; \
+ auto x = static_cast(input[src_idx]); \
+ output[dst_idx] = static_cast(_compute); \
return ok(); \
}); \
} \
@@ -43,34 +43,62 @@
[[maybe_unused]] gsl::span out_strides, \
NNCASE_UNUSED kernel_context &context) noexcept { \
for (int i = 0; i < compute_size(in_shape); ++i) { \
- auto x = input[i]; \
- output[i] = _compute; \
+ auto x = static_cast(input[i]); \
+ output[i] = static_cast(_compute); \
} \
return ok(); \
}
-#define FLOAT_UNARY_OP_TEMPLATE(_name) \
+#define UNARY_OP_TEMPLATE(_name) \
result nncase::kernels::stackvm::_name( \
value_t input, value_t output, kernel_context &context) { \
- try_f32_input(input_mem, input); \
+ try_input(input_mem, input); \
auto dtype = input_tensor->dtype(); \
- try_f32_output(out_mem, output, input_tensor->shape()); \
+ try_output_like_input(output_mem, output, input_tensor); \
+ try_var(typecode, to_typecode(input_tensor->dtype())); \
if (is_contiguous(input_tensor)) { \
- try_(_name##_opt_impl(input_mem, out_mem, input_tensor->shape(), \
- input_tensor->strides(), \
- output_tensor->shape(), \
- output_tensor->strides(), context)); \
+ try_(UNARY_WITH_DISPTCH(_name##_opt_impl)); \
} else { \
- try_(_name##_impl(input_mem, out_mem, input_tensor->shape(), \
- input_tensor->strides(), output_tensor->shape(), \
- output_tensor->strides(), context)); \
+ try_(UNARY_WITH_DISPTCH(_name##_impl)); \
} \
return ok(output); \
}
-#define FLOAT_UNARY_TEMPLATE(_name, _compute) \
- FLOAT_UNARY_IMPL_TEMPLATE(_name, _compute) \
- FLOAT_UNARY_OP_TEMPLATE(_name)
+#define UNARY_TEMPLATE(_name, _compute) \
+ UNARY_IMPL_TEMPLATE(_name, _compute) \
+ UNARY_WITH_DISPTCH_OP_TEMPLATE_V2(_name##_opt_impl) \
+ UNARY_WITH_DISPTCH_OP_TEMPLATE_V2(_name##_impl) \
+ UNARY_OP_TEMPLATE(_name)
+
+#define UNARY_WITH_DISPTCH(_impl_func) \
+ _impl_func##_disptch(typecode, input_mem, output_mem, \
+ input_tensor->shape(), input_tensor->strides(), \
+ output_tensor->shape(), output_tensor->strides(), \
+ context)
+
+#define UNARY_WITH_DISPTCH_OP_TEMPLATE_V2(_impl_func) \
+ result _impl_func##_disptch( \
+ typecode_t type, const gsl::byte *input, gsl::byte *output, \
+ gsl::span in_shape, gsl::span in_strides, \
+ gsl::span out_shape, \
+ gsl::span out_strides, \
+ NNCASE_UNUSED kernel_context &context) noexcept { \
+ TYPE_SELECT_WITH_IMPL(type, UNARY_IMPL_FUNC_WRAPPER_V2, _impl_func); \
+ }
+
+#define UNARY_WITH_DISPTCH_OP_TEMPLATE_V2(_impl_func) \
+ result _impl_func##_disptch( \
+ typecode_t type, const gsl::byte *input, gsl::byte *output, \
+ gsl::span in_shape, gsl::span in_strides, \
+ gsl::span out_shape, \
+ gsl::span out_strides, \
+ NNCASE_UNUSED kernel_context &context) noexcept { \
+ TYPE_SELECT_WITH_IMPL(type, UNARY_IMPL_FUNC_WRAPPER_V2, _impl_func); \
+ }
+
+#define UNARY_IMPL_FUNC_WRAPPER_V2(_impl_func, type) \
+ return _impl_func(IN_CAST(type, input), OUT_CAST(type, output), in_shape, \
+ in_strides, out_shape, out_strides, context)
#define FLOAT_UNARY_WITH_MUL_IMPL_TEMPLATE(_name, _alpha_name, _compute) \
template \
@@ -107,38 +135,119 @@
return ok(); \
}
-#define FLOAT_UNARY_WITH_MUL_OP_TEMPLATE(_name, _alpha_name) \
- result _name##_impl(const float *input, float *output, \
- gsl::span input_shape, \
- gsl::span input_strides, \
- gsl::span out_shape, \
- gsl::span out_strides, \
- NNCASE_UNUSED kernel_context &context); \
+#define UNARY_WITH_MUL_IMPL_TEMPLATE_V2(_name, _alpha_name, _compute) \
+ template \
+ result _name##_impl( \
+ const T *input, T *output, T _alpha_name, \
+ gsl::span in_shape, \
+ gsl::span input_strides, \
+ gsl::span out_shape, \
+ gsl::span out_strides, \
+ NNCASE_UNUSED kernel_context &context) noexcept { \
+ return apply( \
+ out_shape, [&](gsl::span index) -> result { \
+ const auto in_index = \
+ kernels::detail::get_reduced_offset(index, in_shape); \
+ auto src_idx = offset(input_strides, in_index); \
+ auto dst_idx = offset(out_strides, in_index); \
+ const auto alpha = static_cast(_alpha_name); \
+ const auto x = static_cast(input[src_idx]); \
+ output[dst_idx] = static_cast(_compute); \
+ return ok(); \
+ }); \
+ } \
+ template \
+ result _name##_contiguous_impl( \
+ const T *input, T *output, T _alpha_name, \
+ gsl::span in_shape, \
+ [[maybe_unused]] gsl::span input_strides, \
+ [[maybe_unused]] gsl::span out_shape, \
+ [[maybe_unused]] gsl::span out_strides, \
+ NNCASE_UNUSED kernel_context &context) noexcept { \
+ for (int i = 0; i < compute_size(in_shape); ++i) { \
+ const auto alpha = static_cast(_alpha_name); \
+ const auto x = static_cast(input[i]); \
+ output[i] = static_cast(_compute); \
+ } \
+ return ok(); \
+ }
+
+#define UNARY_IMPL_FUNC_WRAPPER(_impl_func, type) \
+ return _impl_func(IN_CAST(type, input), OUT_CAST(type, output), \
+ *IN_CAST(type, _alpha), in_shape, in_strides, out_shape, \
+ out_strides, context)
+
+#define TYPE_SELECT_WITH_IMPL(_typecode, _impl, _impl_func) \
+ switch (_typecode) { \
+ case dt_float32: \
+ _impl(_impl_func, float); \
+ case dt_float16: \
+ _impl(_impl_func, half); \
+ case dt_bfloat16: \
+ _impl(_impl_func, bfloat16); \
+ case dt_int8: \
+ _impl(_impl_func, int8_t); \
+ case dt_int16: \
+ _impl(_impl_func, int16_t); \
+ case dt_int32: \
+ _impl(_impl_func, int32_t); \
+ case dt_int64: \
+ _impl(_impl_func, int64_t); \
+ case dt_uint8: \
+ _impl(_impl_func, uint8_t); \
+ case dt_uint16: \
+ _impl(_impl_func, uint16_t); \
+ case dt_uint32: \
+ _impl(_impl_func, uint32_t); \
+ case dt_uint64: \
+ _impl(_impl_func, uint64_t); \
+ case dt_float64: \
+ _impl(_impl_func, double); \
+ case dt_boolean: \
+ _impl(_impl_func, uint8_t); \
+ default: \
+ return err(std::errc::not_supported); \
+ }
+
+#define UNARY_WITH_MUL_DISPTCH_OP_TEMPLATE_V2(_impl_func) \
+ result _impl_func##_disptch( \
+ typecode_t type, const gsl::byte *input, gsl::byte *output, \
+ const gsl::byte *_alpha, gsl::span in_shape, \
+ gsl::span in_strides, gsl::span out_shape, \
+ gsl::span out_strides, \
+ NNCASE_UNUSED kernel_context &context) noexcept { \
+ TYPE_SELECT_WITH_IMPL(type, UNARY_IMPL_FUNC_WRAPPER, _impl_func); \
+ }
+
+#define UNARY_WITH_MUL_DISPTCH(_impl_func) \
+ _impl_func##_disptch(typecode, input_mem, output_mem, _alpha_name_mem, \
+ input_tensor->shape(), input_tensor->strides(), \
+ output_tensor->shape(), output_tensor->strides(), \
+ context)
+
+#define UNARY_WITH_MUL_OP_TEMPLATE_V2(_name, _alpha_name) \
result nncase::kernels::stackvm::_name( \
value_t input, value_t _alpha_name, value_t output, \
kernel_context &context) { \
- try_f32_input(input_mem, input); \
- try_to_scalar(_alpha_name##_value, _alpha_name, float); \
+ try_input(input_mem, input); \
+ try_input(_alpha_name_mem, _alpha_name); \
auto dtype = input_tensor->dtype(); \
- try_f32_output(out_mem, output, input_tensor->shape()); \
+ try_output_like_input(output_mem, output, input_tensor); \
+ try_var(typecode, to_typecode(input_tensor->dtype())); \
if (is_contiguous(input_tensor)) { \
- try_(_name##_contiguous_impl( \
- input_mem, out_mem, _alpha_name##_value, \
- input_tensor->shape(), input_tensor->strides(), \
- output_tensor->shape(), output_tensor->strides(), context)); \
+ try_(UNARY_WITH_MUL_DISPTCH(_name##_contiguous_impl)); \
} else { \
- try_(_name##_impl(input_mem, out_mem, _alpha_name##_value, \
- input_tensor->shape(), input_tensor->strides(), \
- output_tensor->shape(), \
- output_tensor->strides(), context)); \
+ try_(UNARY_WITH_MUL_DISPTCH(_name##_impl)); \
} \
return ok(output); \
}
// _alpha_name is a var used in kernel
-#define FLOAT_UNARY_WITH_MUL_TEMPLATE(_name, _alpha_name, _compute) \
- FLOAT_UNARY_WITH_MUL_IMPL_TEMPLATE(_name, _alpha_name, _compute) \
- FLOAT_UNARY_WITH_MUL_OP_TEMPLATE(_name, _alpha_name)
+#define UNARY_WITH_MUL_TEMPLATE_V2(_name, _alpha_name, _compute) \
+ UNARY_WITH_MUL_IMPL_TEMPLATE_V2(_name, _alpha_name##_arg, _compute) \
+ UNARY_WITH_MUL_DISPTCH_OP_TEMPLATE_V2(_name##_contiguous_impl) \
+ UNARY_WITH_MUL_DISPTCH_OP_TEMPLATE_V2(_name##_impl) \
+ UNARY_WITH_MUL_OP_TEMPLATE_V2(_name, _alpha_name)
#define MKFNS(fn, ...) \
MKFN_N(fn, ##__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)(__VA_ARGS__)
@@ -179,6 +288,29 @@
}); \
}
+#define ACTIVATION_IMPL_TEMPLATE_V2(_name, _compute, _alpha_name, _gamma_name) \
+ template \
+ result _name##_impl( \
+ const T *input, T *output, T _alpha_name, T _gamma_name, \
+ gsl::span in_shape, \
+ gsl::span input_strides, \
+ gsl::span out_shape, \
+ gsl::span out_strides, \
+ NNCASE_UNUSED kernel_context &context) noexcept { \
+ return apply( \
+ out_shape, [&](gsl::span index) -> result { \
+ const auto in_index = \
+ kernels::detail::get_reduced_offset(index, in_shape); \
+ auto src_idx = offset(input_strides, in_index); \
+ auto dst_idx = offset(out_strides, in_index); \
+ auto x = static_cast(input[src_idx]); \
+ const auto alpha = static_cast(_alpha_name); \
+ const auto gamma = static_cast(_gamma_name); \
+ output[dst_idx] = static_cast(_compute); \
+ return ok(); \
+ }); \
+ }
+
#define VALUE_ARGS_EXPAND(...) MKFNS(VALUE_ARGS_EXPAND, ##__VA_ARGS__)
#define VALUE_ARGS_EXPAND0(_a) value_t _a
@@ -236,10 +368,52 @@
return ok(output); \
}
+#define UNARY_WITH_DISPTCH_V2(_impl_func) \
+ _impl_func##_disptch(typecode, input_mem, output_mem, _alpha_name_mem, \
+ _gamma_name_mem, input_tensor->shape(), \
+ input_tensor->strides(), output_tensor->shape(), \
+ output_tensor->strides(), context)
+
+#define ACTIVATION_OP_TEMPLATE_V2(_name, _alpha_name, _gamma_name) \
+ result nncase::kernels::stackvm::_name( \
+ value_t input, value_t _alpha_name, value_t _gamma_name, \
+ value_t output, kernel_context &context) { \
+ try_input(input_mem, input); \
+ auto dtype = input_tensor->dtype(); \
+ try_input(_alpha_name_mem, _alpha_name); \
+ try_input(_gamma_name_mem, _gamma_name); \
+ try_var(typecode, to_typecode(input_tensor->dtype())); \
+ try_output_like_input(output_mem, output, input_tensor); \
+ try_(UNARY_WITH_DISPTCH_V2(_name##_impl)); \
+ return ok(output); \
+ }
+
+#define UNARY_IMPL_FUNC_WRAPPER_V3(_impl_func, type) \
+ return _impl_func(IN_CAST(type, input), OUT_CAST(type, output), \
+ *IN_CAST(type, _alpha), *IN_CAST(type, _gamma), \
+ in_shape, in_strides, out_shape, out_strides, context)
+
+#define UNARY_WITH_MUL_DISPTCH_OP_ACTIVATION_OP_TEMPLATE_V2(_impl_func) \
+ result _impl_func##_disptch( \
+ typecode_t type, const gsl::byte *input, gsl::byte *output, \
+ const gsl::byte *_alpha, const gsl::byte *_gamma, \
+ gsl::span in_shape, gsl::span in_strides, \
+ gsl::span out_shape, \
+ gsl::span out_strides, \
+ NNCASE_UNUSED kernel_context &context) noexcept { \
+ TYPE_SELECT_WITH_IMPL(type, UNARY_IMPL_FUNC_WRAPPER_V3, _impl_func); \
+ }
+
#define FLOAT_ACTIVATION_TEMPLATE(_name, _compute, ...) \
FLOAT_ACTIVATION_IMPL_TEMPLATE(_name, _compute, __VA_ARGS__) \
FLOAT_ACTIVATION_OP_TEMPLATE(_name, __VA_ARGS__)
+#define ACTIVATION_TEMPLATE_V2(_name, _compute, _alpha_name, _gamma_name) \
+ ACTIVATION_IMPL_TEMPLATE_V2(_name, _compute, _alpha_name##arg, \
+ _gamma_name##arg) \
+ UNARY_WITH_MUL_DISPTCH_OP_ACTIVATION_OP_TEMPLATE_V2(_name##_impl) \
+ ACTIVATION_OP_TEMPLATE_V2(_name, _alpha_name, _gamma_name)
+
#define BASIC_PARAM \
const gsl::byte *input, gsl::byte *output, \
gsl::span in_shape, gsl::span out_shape, \
diff --git a/src/Native/src/kernels/stackvm/reference/matmul.cpp b/src/Native/src/kernels/stackvm/reference/matmul.cpp
index 52d6088f16..670e702503 100644
--- a/src/Native/src/kernels/stackvm/reference/matmul.cpp
+++ b/src/Native/src/kernels/stackvm/reference/matmul.cpp
@@ -52,8 +52,17 @@ result matmul_unit_impl(const T *input_a, const T *input_b, T *output,
template
result matmul_impl(const T *input_a, const T *input_b, T *output,
- gsl::span in_a_shape,
- gsl::span in_b_shape) noexcept {
+ gsl::span in_a_shape_,
+ gsl::span in_b_shape_) noexcept {
+ dims_t in_a_shape = in_a_shape_;
+ dims_t in_b_shape = in_b_shape_;
+ if (in_a_shape.size() == 1) {
+ in_a_shape.insert(in_a_shape.begin(), 1);
+ }
+
+ if (in_b_shape.size() == 1) {
+ in_b_shape.insert(in_b_shape.end(), 1);
+ }
auto new_a_shape = to_4d(in_a_shape);
auto new_b_shape = to_4d(in_b_shape);
auto a_unit_size = new_a_shape[2] * new_a_shape[3];
diff --git a/src/Native/src/kernels/stackvm/reference/pad.cpp b/src/Native/src/kernels/stackvm/reference/pad.cpp
index db7bf2999c..0f11590fb4 100644
--- a/src/Native/src/kernels/stackvm/reference/pad.cpp
+++ b/src/Native/src/kernels/stackvm/reference/pad.cpp
@@ -208,8 +208,9 @@ result nncase::kernels::stackvm::reference::pad(
kernel_context &context) noexcept {
auto unit = runtime::get_bytes(type);
bool padding_before_is_zero =
- std::all_of(paddings.begin(), paddings.end(),
- [](const padding &p) { return p.before == 0; }) &&
+ std::all_of(
+ paddings.begin(), paddings.end(),
+ [](const padding &p) { return p.before == 0 && p.after >= 0; }) &&
mode == pad_mode_t::constant && in_shape.size() >= 3;
if (std::all_of(paddings.begin(), paddings.end(),
diff --git a/src/Native/src/kernels/stackvm/reference/quantize.cpp b/src/Native/src/kernels/stackvm/reference/quantize.cpp
index 4754661899..0bd62af45f 100644
--- a/src/Native/src/kernels/stackvm/reference/quantize.cpp
+++ b/src/Native/src/kernels/stackvm/reference/quantize.cpp
@@ -59,5 +59,6 @@ result nncase::kernels::stackvm::reference::quantize(
float scale, float bias, kernel_context &context) noexcept {
QUANTIZE_IMPL(float, uint8_t);
QUANTIZE_IMPL(float, int8_t);
+ QUANTIZE_IMPL(float, int16_t);
return err(std::errc::not_supported);
}
\ No newline at end of file
diff --git a/src/Native/src/kernels/stackvm/reference/reduce_arg.cpp b/src/Native/src/kernels/stackvm/reference/reduce_arg.cpp
index 6322017fe6..74cd0bd0de 100644
--- a/src/Native/src/kernels/stackvm/reference/reduce_arg.cpp
+++ b/src/Native/src/kernels/stackvm/reference/reduce_arg.cpp
@@ -60,10 +60,8 @@ result reduce_arg_impl(TReducer &&reducer, T init_value, const T *input,
out_map[out_idx].clear();
out_map[out_idx].push_back(index[axes[0]]);
dst = src;
- } else if constexpr (std::is_same_v) {
- if (fabs(src - dst) < epsilon) {
- out_map[out_idx].push_back(index[axes[0]]);
- }
+ } else if (std::fabs(src - dst) < epsilon) {
+ out_map[out_idx].push_back(index[axes[0]]);
}
return ok();
}));
diff --git a/src/Native/src/kernels/stackvm/reference/unary.cpp b/src/Native/src/kernels/stackvm/reference/unary.cpp
index 8af2011926..f9da11ba02 100644
--- a/src/Native/src/kernels/stackvm/reference/unary.cpp
+++ b/src/Native/src/kernels/stackvm/reference/unary.cpp
@@ -45,6 +45,23 @@ result unary_impl(TOp &&op, const T *input, T *output,
return unary_impl(funct, input, output, input_shape, input_strides, \
out_shape, out_strides, context)
+static float round_onnx(float v) {
+ if (v > 0 && v - (int32_t)v == 0.5) {
+ float result = (int32_t)v + 1.0;
+ if ((int32_t)result % 2 == 0)
+ return result;
+ else
+ return result - 1;
+ } else if (v < 0 && (int32_t)v - v == 0.5) {
+ float result = (int32_t)v + 1.0;
+ if ((int32_t)result % 2 == 0)
+ return result;
+ else
+ return result - 1;
+ } else
+ return roundf(v);
+}
+
template
result unary_impl(unary_op_t op, const T *input, T *output,
gsl::span input_shape,
@@ -66,7 +83,7 @@ result unary_impl(unary_op_t op, const T *input, T *output,
UNARY_IMPL_OP(log, logf);
UNARY_IMPL_OP(logical_not, [](float v) { return !v; });
UNARY_IMPL_OP(neg, std::negate());
- UNARY_IMPL_OP(round, roundf);
+ UNARY_IMPL_OP(round, [](float v) { return round_onnx(v); });
UNARY_IMPL_OP(rsqrt, [](float v) { return 1.f / sqrtf(v); });
UNARY_IMPL_OP(sign, [](float v) { return (0.f < v) - (v < 0.f); });
UNARY_IMPL_OP(sin, sinf);
@@ -93,6 +110,8 @@ result nncase::kernels::stackvm::reference::unary(
kernel_context &context) noexcept {
switch (dtype) {
UNARY_IMPL_DTYPE(dt_float32, float)
+ UNARY_IMPL_DTYPE(dt_float16, half)
+ // UNARY_IMPL_DTYPE(dt_bfloat16, bfloat16)
UNARY_IMPL_DTYPE(dt_float64, double)
UNARY_IMPL_DTYPE(dt_int32, int32_t)
UNARY_IMPL_DTYPE(dt_int64, int64_t)
diff --git a/src/Native/src/kernels/stackvm/shape_infer.h b/src/Native/src/kernels/stackvm/shape_infer.h
index 01c5591b1e..d88a5378b6 100644
--- a/src/Native/src/kernels/stackvm/shape_infer.h
+++ b/src/Native/src/kernels/stackvm/shape_infer.h
@@ -287,13 +287,24 @@ inline dims_t onehot_infer_shape(gsl::span indices_shape,
return new_shape;
}
-inline result matmul_infer_shape(gsl::span lhs_shape,
- gsl::span rhs_shape) {
+inline result matmul_infer_shape(gsl::span lhs_shape_,
+ gsl::span rhs_shape_) {
+ dims_t lhs_shape = lhs_shape_;
+ dims_t rhs_shape = rhs_shape_;
+
if (lhs_shape.size() == 2 && rhs_shape.size() == 2) {
auto new_shape = dims_t{lhs_shape[0], rhs_shape[1]};
return ok(new_shape);
}
+ if (lhs_shape.size() == 1) {
+ lhs_shape.insert(lhs_shape.begin(), 1);
+ }
+
+ if (rhs_shape.size() == 1) {
+ rhs_shape.insert(rhs_shape.end(), 1);
+ }
+
auto new_a_shape = runtime::to_4d(lhs_shape);
auto new_b_shape = runtime::to_4d(rhs_shape);
auto big_shape = std::max(lhs_shape.size(), rhs_shape.size());
@@ -304,6 +315,14 @@ inline result matmul_infer_shape(gsl::span lhs_shape,
}
new_shape.push_back(lhs_shape[lhs_shape.size() - 2]);
new_shape.push_back(rhs_shape.back());
+ if (lhs_shape_.size() == 1) {
+ new_shape.erase(new_shape.begin() + big_shape - 2);
+ big_shape--;
+ }
+
+ if (rhs_shape_.size() == 1) {
+ new_shape.erase(new_shape.begin() + big_shape - 1);
+ }
return ok(new_shape);
}
diff --git a/src/Native/src/kernels/stackvm/shape_ops.cpp b/src/Native/src/kernels/stackvm/shape_ops.cpp
new file mode 100644
index 0000000000..7677b10c2b
--- /dev/null
+++ b/src/Native/src/kernels/stackvm/shape_ops.cpp
@@ -0,0 +1,121 @@
+#include "shape_infer.h"
+#include
+
+using namespace nncase;
+using namespace nncase::kernels;
+using namespace nncase::kernels::stackvm;
+using namespace nncase::runtime;
+using namespace nncase::runtime::stackvm;
+
+result nncase::kernels::stackvm::conv2d_shape(
+ value_t input, value_t weights, value_t padding, value_t stride,
+ value_t dilation, [[maybe_unused]] value_t groups, value_t output,
+ kernel_context &) {
+ try_dims(in_shape, input);
+ try_dims(w_shape, weights);
+ try_strides(strides_value, stride);
+ try_paddings(pads, padding);
+ try_strides(strides, stride);
+ try_strides(dilations, dilation);
+ try_output(out_mem, output, dt_int64, dims_t{4});
+ auto out_shape =
+ conv2d_infer_shape(in_shape, w_shape, strides_value, dilations, pads);
+ for (int i = 0; i < 4; ++i) {
+ OUT_CAST(int64_t, out_mem)[i] = out_shape[i];
+ }
+ KERNEL_FINISH;
+}
+
+size_t compute_out_size(int input_size, int weights_size,
+ const strides_t &strides, dims_t out_paddings,
+ paddings_t paddings, const strides_t &dilations,
+ int offset) {
+ return (strides[offset] * (input_size - 1L)) + out_paddings[offset] +
+ (((weights_size - 1L) * dilations[offset]) + 1L) -
+ paddings[offset].before - paddings[offset].after;
+}
+
+dims_t conv2d_transpose_infer_shape(gsl::span in_shape,
+ gsl::span w_shape,
+ const strides_t &strides,
+ paddings_t paddings,
+ const dims_t &outPadding,
+ const strides_t &dilations, int group) {
+ auto in = in_shape[0];
+ auto ih = in_shape[2];
+ auto iw = in_shape[3];
+ auto oc = w_shape[0] * group;
+ auto wh = w_shape[2];
+ auto ww = w_shape[3];
+
+ auto oh =
+ compute_out_size(ih, wh, strides, outPadding, paddings, dilations, 0);
+ auto ow =
+ compute_out_size(iw, ww, strides, outPadding, paddings, dilations, 1);
+ auto out_shape = dims_t{in, oc, oh, ow};
+ return out_shape;
+}
+
+result nncase::kernels::stackvm::conv2d_transpose_shape(
+ value_t input, value_t weights, value_t stride, value_t dilation,
+ value_t padding, value_t output_padding, value_t groups, value_t output,
+ kernel_context &) {
+ try_dims(input_shape, input);
+ try_dims(weights_shape, weights);
+ try_strides(strides_value, stride);
+ try_paddings(pads, padding);
+ try_dims(out_padding, output_padding);
+ try_to_integer(groups_value, groups);
+ try_strides(strides, stride);
+ try_strides(dilations, dilation);
+
+ auto out_shape =
+ conv2d_transpose_infer_shape(input_shape, weights_shape, strides, pads,
+ out_padding, dilations, groups_value);
+ try_output(out_mem, output, dt_int64, dims_t{4});
+ for (int i = 0; i < 4; ++i) {
+ OUT_CAST(int64_t, out_mem)[i] = out_shape[i];
+ }
+ KERNEL_FINISH;
+}
+
+result to_dims(tensor shape) {
+ try_dims(shape_value, shape);
+ return ok(shape_value);
+}
+
+result nncase::kernels::stackvm::broadcast_shape(value_t inputs,
+ value_t output,
+ kernel_context &) {
+ try_tuple_input(tuple_mem, inputs);
+ auto begin = inputs_tuple->fields().begin();
+ auto out_shape = std::accumulate(
+ std::next(begin), inputs_tuple->fields().end(),
+ to_dims(begin->as().unwrap()).unwrap(),
+ [&](auto sum, auto field) {
+ auto shape = to_dims(field.template as().unwrap()).unwrap();
+ auto result = kernels::detail::get_binary_output_shape(shape, sum);
+
+ return dims_t(result.begin(), result.end());
+ });
+ try_output(out_mem, output, dt_int64, dims_t{out_shape.size()});
+ for (int i = 0; i < out_shape.size(); ++i) {
+ OUT_CAST(int64_t, out_mem)[i] = out_shape[i];
+ }
+
+ KERNEL_FINISH;
+}
+
+result nncase::kernels::stackvm::mat_mul_shape(value_t lhs,
+ value_t rhs,
+ value_t output,
+ kernel_context &) {
+ try_dims(lhs_shape, lhs);
+ try_dims(rhs_shape, rhs);
+ try_var(out_shape, matmul_infer_shape(lhs_shape, rhs_shape));
+ try_output(out_mem, output, dt_int64, dims_t{out_shape.size()});
+ for (int i = 0; i < out_shape.size(); ++i) {
+ OUT_CAST(int64_t, out_mem)[i] = out_shape[i];
+ }
+ KERNEL_FINISH;
+}
\ No newline at end of file
diff --git a/src/Native/src/kernels/stackvm/tensor_ops.cpp b/src/Native/src/kernels/stackvm/tensor_ops.cpp
index 0658fe6e35..7f668492c3 100644
--- a/src/Native/src/kernels/stackvm/tensor_ops.cpp
+++ b/src/Native/src/kernels/stackvm/tensor_ops.cpp
@@ -27,7 +27,7 @@ using namespace nncase::kernels::stackvm;
using namespace nncase::runtime;
using namespace nncase::runtime::stackvm;
-//#define ENABLE_NOP
+// #define ENABLE_NOP
result nncase::kernels::stackvm::batch_normalization(
value_t input, value_t scale, value_t bias, value_t input_mean,
@@ -1233,6 +1233,13 @@ result kernels::stackvm::unary(unary_op_t unary_op, value_t input,
auto dtype = input_tensor->dtype();
try_output(out_mem, output, dtype, input_tensor->shape());
+ if (typoecode != dt_float32) {
+ try_(reference::unary(typoecode, unary_op, input_mem, out_mem,
+ input_tensor->shape(), input_tensor->strides(),
+ output_tensor->shape(), output_tensor->strides(),
+ context));
+ return ok(output);
+ }
CONTIGUOUS_KERNEL(unary, input_tensor, typoecode, unary_op, input_mem,
out_mem, input_tensor->shape(), input_tensor->strides(),
output_tensor->shape(), output_tensor->strides(),
diff --git a/src/Native/src/runtime/stackvm/op_reader.cpp b/src/Native/src/runtime/stackvm/op_reader.cpp
index f430b1c64b..04776e0f7d 100644
--- a/src/Native/src/runtime/stackvm/op_reader.cpp
+++ b/src/Native/src/runtime/stackvm/op_reader.cpp
@@ -1,4 +1,4 @@
-/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 15:04:16
+/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 17:07:39
* +08:00.
*
* Copyright 2019-2021 Canaan Inc.
@@ -36,6 +36,9 @@ result tensor_op_visitor::visit(tensor_function_t tensor_funct,
return visit(tensor_op_reader()(reader));
case tensor_function_t::broadcast:
return visit(tensor_op_reader()(reader));
+ case tensor_function_t::broadcast_shape:
+ return visit(
+ tensor_op_reader()(reader));
case tensor_function_t::bucket_pad:
return visit(tensor_op_reader()(reader));
case tensor_function_t::cast:
@@ -55,9 +58,16 @@ result tensor_op_visitor::visit(tensor_function_t tensor_funct,
tensor_op_reader()(reader));
case tensor_function_t::conv2d:
return visit(tensor_op_reader()(reader));
+ case tensor_function_t::conv2d_shape:
+ return visit(
+ tensor_op_reader()(reader));
case tensor_function_t::conv2d_transpose:
return visit(
tensor_op_reader()(reader));
+ case tensor_function_t::conv2d_transpose_shape:
+ return visit(
+ tensor_op_reader()(
+ reader));
case tensor_function_t::cum_sum:
return visit(tensor_op_reader()(reader));
case tensor_function_t::dequantize:
@@ -121,6 +131,9 @@ result tensor_op_visitor::visit(tensor_function_t tensor_funct,
return visit(tensor_op_reader()(reader));
case tensor_function_t::mat_mul:
return visit(tensor_op_reader()(reader));
+ case tensor_function_t::mat_mul_shape:
+ return visit(
+ tensor_op_reader()(reader));
case tensor_function_t::normal:
return visit(tensor_op_reader()(reader));
case tensor_function_t::normal_like:
diff --git a/src/Native/src/runtime/stackvm/ops/tensor.cpp b/src/Native/src/runtime/stackvm/ops/tensor.cpp
index 92bbe33a21..0439e7887c 100644
--- a/src/Native/src/runtime/stackvm/ops/tensor.cpp
+++ b/src/Native/src/runtime/stackvm/ops/tensor.cpp
@@ -1,4 +1,4 @@
-/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 15:04:16
+/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 17:07:39
* +08:00.
*
* Copyright 2019-2021 Canaan Inc.
@@ -120,6 +120,18 @@ result stackvm_runtime_function::visit(
return ok();
}
+result stackvm_runtime_function::visit(
+ [[maybe_unused]] const tensor_broadcast_shape_op_t &op) noexcept {
+ dump_op("broadcast_shape");
+ try_var(inputs, pop_value());
+ dump_input(inputs);
+ try_var(output, kernels::stackvm::broadcast_shape(
+ inputs, nullptr, module().kernel_context()));
+ dump_output(output);
+ stack_.push(std::move(output));
+ return ok();
+}
+
result stackvm_runtime_function::visit(
[[maybe_unused]] const tensor_bucket_pad_op_t &op) noexcept {
dump_op("bucket_pad");
@@ -261,6 +273,29 @@ result stackvm_runtime_function::visit(
return ok();
}
+result stackvm_runtime_function::visit(
+ [[maybe_unused]] const tensor_conv2d_shape_op_t &op) noexcept {
+ dump_op("conv2d_shape");
+ try_var(input, pop_value());
+ dump_input(input);
+ try_var(weights, pop_value());
+ dump_input(weights);
+ try_var(padding, pop_value());
+ dump_input(padding);
+ try_var(stride, pop_value());
+ dump_input(stride);
+ try_var(dilation, pop_value());
+ dump_input(dilation);
+ try_var(groups, pop_value());
+ dump_input(groups);
+ try_var(output, kernels::stackvm::conv2d_shape(
+ input, weights, padding, stride, dilation, groups,
+ nullptr, module().kernel_context()));
+ dump_output(output);
+ stack_.push(std::move(output));
+ return ok();
+}
+
result stackvm_runtime_function::visit(
[[maybe_unused]] const tensor_conv2d_transpose_op_t &op) noexcept {
dump_op("conv2d_transpose");
@@ -293,6 +328,32 @@ result stackvm_runtime_function::visit(
return ok();
}
+result stackvm_runtime_function::visit(
+ [[maybe_unused]] const tensor_conv2d_transpose_shape_op_t &op) noexcept {
+ dump_op("conv2d_transpose_shape");
+ try_var(input, pop_value());
+ dump_input(input);
+ try_var(weights, pop_value());
+ dump_input(weights);
+ try_var(stride, pop_value());
+ dump_input(stride);
+ try_var(dilation, pop_value());
+ dump_input(dilation);
+ try_var(padding, pop_value());
+ dump_input(padding);
+ try_var(output_padding, pop_value());
+ dump_input(output_padding);
+ try_var(groups, pop_value());
+ dump_input(groups);
+ try_var(output,
+ kernels::stackvm::conv2d_transpose_shape(
+ input, weights, stride, dilation, padding, output_padding,
+ groups, nullptr, module().kernel_context()));
+ dump_output(output);
+ stack_.push(std::move(output));
+ return ok();
+}
+
result stackvm_runtime_function::visit(
[[maybe_unused]] const tensor_cum_sum_op_t &op) noexcept {
dump_op("cum_sum");
@@ -727,6 +788,20 @@ result stackvm_runtime_function::visit(
return ok();
}
+result stackvm_runtime_function::visit(
+ [[maybe_unused]] const tensor_mat_mul_shape_op_t &op) noexcept {
+ dump_op("mat_mul_shape");
+ try_var(lhs, pop_value());
+ dump_input(lhs);
+ try_var(rhs, pop_value());
+ dump_input(rhs);
+ try_var(output, kernels::stackvm::mat_mul_shape(lhs, rhs, nullptr,
+ module().kernel_context()));
+ dump_output(output);
+ stack_.push(std::move(output));
+ return ok();
+}
+
result stackvm_runtime_function::visit(
[[maybe_unused]] const tensor_normal_op_t &op) noexcept {
dump_op("normal");
diff --git a/src/Native/src/runtime/stackvm/runtime_function_ops.h b/src/Native/src/runtime/stackvm/runtime_function_ops.h
index 8a5b37d76c..02841ebe35 100644
--- a/src/Native/src/runtime/stackvm/runtime_function_ops.h
+++ b/src/Native/src/runtime/stackvm/runtime_function_ops.h
@@ -1,4 +1,4 @@
-/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 15:04:16
+/* This file is generated by tools/stackvm_gen/IsaGen at 2023/7/12 17:07:39
* +08:00.
*
* Copyright 2019-2021 Canaan Inc.
@@ -21,6 +21,7 @@ result visit(const tensor_batch_to_space_op_t &op) noexcept override;
result visit(const tensor_binary_op_t &op) noexcept override;
result visit(const tensor_bitcast_op_t &op) noexcept override;
result visit(const tensor_broadcast_op_t &op) noexcept override;
+result visit(const tensor_broadcast_shape_op_t &op) noexcept override;
result visit(const tensor_bucket_pad_op_t &op) noexcept override;
result visit(const tensor_cast_op_t &op) noexcept override;
result visit(const tensor_celu_op_t &op) noexcept override;
@@ -30,7 +31,10 @@ result visit(const tensor_concat_op_t &op) noexcept override;
result visit(const tensor_condition_op_t &op) noexcept override;
result visit(const tensor_constant_of_shape_op_t &op) noexcept override;
result visit(const tensor_conv2d_op_t &op) noexcept override;
+result visit(const tensor_conv2d_shape_op_t &op) noexcept override;
result visit(const tensor_conv2d_transpose_op_t &op) noexcept override;
+result