From 6fb59b9313b42f1b8469bfad0182bf8c8d030886 Mon Sep 17 00:00:00 2001 From: dkk0918 <13262679180@163.com> Date: Mon, 6 Sep 2021 21:50:44 +0800 Subject: [PATCH 1/2] add onnx pack --- components/ai/onnx/README.md | 95 + .../onnx/examples/mnist_float/mnist_float.h | 41 + components/ai/onnx/examples/mnist_int/mnist.c | 226 + .../ai/onnx/examples/mnist_int/mnist_int.h | 73 + .../ai/onnx/examples/model/mnist-lg.onnx | Bin 0 -> 5826 bytes .../ai/onnx/examples/model/mnist-sm.onnx | Bin 0 -> 3734 bytes .../ai/onnx/operator_float/mnist_float.c | 125 + .../ai/onnx/operator_float/mnist_float.h | 48 + components/ai/onnx/operator_int/add.c | 35 + components/ai/onnx/operator_int/conv2d.c | 113 + components/ai/onnx/operator_int/dense.c | 19 + components/ai/onnx/operator_int/info.c | 25 + components/ai/onnx/operator_int/matmul.c | 63 + components/ai/onnx/operator_int/maxpool.c | 96 + components/ai/onnx/operator_int/model.c | 84 + components/ai/onnx/operator_int/onnx-parser.c | 284 ++ components/ai/onnx/operator_int/onnx-parser.h | 27 + components/ai/onnx/operator_int/onnx.h | 95 + components/ai/onnx/operator_int/relu.c | 27 + components/ai/onnx/operator_int/softmax.c | 57 + .../ai/onnx/operator_int/tencentos_libc.c | 26 + components/ai/onnx/operator_int/transpose.c | 97 + .../platflorm/imx6ull/tencentos_libc_malloc.c | 26 + components/ai/onnx/protobuf/onnx.pb-c.c | 1780 ++++++++ components/ai/onnx/protobuf/onnx.pb-c.h | 981 +++++ components/ai/onnx/protobuf/protobuf-c.c | 3666 +++++++++++++++++ components/ai/onnx/protobuf/protobuf-c.h | 1106 +++++ 27 files changed, 9215 insertions(+) create mode 100644 components/ai/onnx/README.md create mode 100644 components/ai/onnx/examples/mnist_float/mnist_float.h create mode 100644 components/ai/onnx/examples/mnist_int/mnist.c create mode 100644 components/ai/onnx/examples/mnist_int/mnist_int.h create mode 100644 components/ai/onnx/examples/model/mnist-lg.onnx create mode 100644 components/ai/onnx/examples/model/mnist-sm.onnx create mode 100644 components/ai/onnx/operator_float/mnist_float.c create mode 100644 components/ai/onnx/operator_float/mnist_float.h create mode 100644 components/ai/onnx/operator_int/add.c create mode 100644 components/ai/onnx/operator_int/conv2d.c create mode 100644 components/ai/onnx/operator_int/dense.c create mode 100644 components/ai/onnx/operator_int/info.c create mode 100644 components/ai/onnx/operator_int/matmul.c create mode 100644 components/ai/onnx/operator_int/maxpool.c create mode 100644 components/ai/onnx/operator_int/model.c create mode 100644 components/ai/onnx/operator_int/onnx-parser.c create mode 100644 components/ai/onnx/operator_int/onnx-parser.h create mode 100644 components/ai/onnx/operator_int/onnx.h create mode 100644 components/ai/onnx/operator_int/relu.c create mode 100644 components/ai/onnx/operator_int/softmax.c create mode 100644 components/ai/onnx/operator_int/tencentos_libc.c create mode 100644 components/ai/onnx/operator_int/transpose.c create mode 100644 components/ai/onnx/platflorm/imx6ull/tencentos_libc_malloc.c create mode 100644 components/ai/onnx/protobuf/onnx.pb-c.c create mode 100644 components/ai/onnx/protobuf/onnx.pb-c.h create mode 100644 components/ai/onnx/protobuf/protobuf-c.c create mode 100644 components/ai/onnx/protobuf/protobuf-c.h diff --git a/components/ai/onnx/README.md b/components/ai/onnx/README.md new file mode 100644 index 00000000..7c574824 --- /dev/null +++ b/components/ai/onnx/README.md @@ -0,0 +1,95 @@ +![](https://raw.githubusercontent.com/onnx/onnx/master/docs/ONNX_logo_main.png) + +# ONNX + +**通用神经网络模型推理框架 onnx 在 TencentOS-tiny 上的移植** + +[ONNX](https://onnx.ai/) (Open Neural Network Exchange) 是机器学习模型的通用格式,可以融合不同机器学习框架的模型。 + +ONNX是一个用于表示深度学习模型的标准,可使模型在不同框架之间进行转移。Tensorflow, Keras, Pytorch, Caffe2, mxnet等知名深度学习框架训练的模型可以转化为onnx格式,于是便可以在RTOS上运行。 + + +## 支持算子 + +- Conv2D +- Relu +- Maxpool +- Softmax +- Matmul +- Add +- Flatten +- Transpose + +## mnist例程 + +当前有两个手写体识别的例程: + +mnist_int 和 mnist_float + +分别适用用于整形推理和浮点推理,根据平台不同而定,其中mnist_int在imx6ull上通过验证,mnist_float在stm32L4上通过验证。最小的 demo 只需要 16KB 内存,因此在STM32F103C8T6 上也可以运行,其中mnist_int相当于是做了int32的量化,针对归一化后的浮点double型参数乘以1000倍,并修改了softmax层的算子,最后可以完成速度更快的整形数推理: + +| 例程文件 | 说明 | +| ------------- | ---------------------------------------- | +| mnist_int.c | 整形推理,模型参数保存在 mnist_int.h | +| mnist_float.c | 浮点推理,模型参数保存在mnist_float.h | + +#### 模型结构 + +``` +_________________________________________________________________ +Layer (type) Output Shape Param # +================================================================= +conv2d_5 (Conv2D) (None, 28, 28, 2) 20 +_________________________________________________________________ +max_pooling2d_5 (MaxPooling2 (None, 14, 14, 2) 0 +_________________________________________________________________ +dropout_5 (Dropout) (None, 14, 14, 2) 0 +_________________________________________________________________ +conv2d_6 (Conv2D) (None, 14, 14, 2) 38 +_________________________________________________________________ +max_pooling2d_6 (MaxPooling2 (None, 7, 7, 2) 0 +_________________________________________________________________ +dropout_6 (Dropout) (None, 7, 7, 2) 0 +_________________________________________________________________ +flatten_3 (Flatten) (None, 98) 0 +_________________________________________________________________ +dense_5 (Dense) (None, 4) 396 +_________________________________________________________________ +dense_6 (Dense) (None, 10) 50 +================================================================= +Total params: 504 +Trainable params: 504 +Non-trainable params: 0 +_________________________________________________________________ + +``` +推理测试 + +![mnist_test](../../../pic/mnist_test.png) + + + +## 注意事项 + +由于 onnx 的模型是 Google Protobuf v3 的格式,所以在protobuf文件夹中也包含了模型解析部分,可以配合文件系统进行模型读取。 + +- protobuf-c +- onnx-pb-c + +在 platform 中是对于不同平台的特殊适配,比如malloc、free的实现等 + +- tencentos_libc_malloc + + +## Todo List + +- 解析更加复杂的模型 +- 针对不同硬件适配加速算子 + +## 参考 +https://github.com/wuhanstudio/onnx-backend +## 联系方式 + +- 维护:derek +- 邮箱:dkeji627@gmail.com + diff --git a/components/ai/onnx/examples/mnist_float/mnist_float.h b/components/ai/onnx/examples/mnist_float/mnist_float.h new file mode 100644 index 00000000..3c6d20b0 --- /dev/null +++ b/components/ai/onnx/examples/mnist_float/mnist_float.h @@ -0,0 +1,41 @@ +#ifndef __MNIST_H__ +#define __MNIST_H__ + +#include +#include + +#define IMG0 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3803922, 0.37647063, 0.3019608, 0.46274513, 0.2392157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3529412, 0.5411765, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9843138, 0.9843138, 0.9725491, 0.9960785, 0.9607844, 0.9215687, 0.74509805, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.54901963, 0.9843138, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.7411765, 0.09019608, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8862746, 0.9960785, 0.81568635, 0.7803922, 0.7803922, 0.7803922, 0.7803922, 0.54509807, 0.2392157, 0.2392157, 0.2392157, 0.2392157, 0.2392157, 0.5019608, 0.8705883, 0.9960785, 0.9960785, 0.7411765, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14901961, 0.32156864, 0.050980397, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.13333334, 0.8352942, 0.9960785, 0.9960785, 0.45098042, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4156863, 0.6156863, 0.9960785, 0.9960785, 0.95294124, 0.20000002, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.098039225, 0.45882356, 0.8941177, 0.8941177, 0.8941177, 0.9921569, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.94117653, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.26666668, 0.4666667, 0.86274517, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.5568628, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14509805, 0.73333335, 0.9921569, 0.9960785, 0.9960785, 0.9960785, 0.8745099, 0.8078432, 0.8078432, 0.29411766, 0.26666668, 0.8431373, 0.9960785, 0.9960785, 0.45882356, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4431373, 0.8588236, 0.9960785, 0.9490197, 0.89019614, 0.45098042, 0.34901962, 0.121568635, 0.0, 0.0, 0.0, 0.0, 0.7843138, 0.9960785, 0.9450981, 0.16078432, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6627451, 0.9960785, 0.6901961, 0.24313727, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.18823531, 0.9058824, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07058824, 0.48627454, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.6509804, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.54509807, 0.9960785, 0.9333334, 0.22352943, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8235295, 0.9803922, 0.9960785, 0.65882355, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9490197, 0.9960785, 0.93725497, 0.22352943, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.34901962, 0.9843138, 0.9450981, 0.3372549, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.019607844, 0.8078432, 0.96470594, 0.6156863, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.015686275, 0.45882356, 0.27058825, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0} +#define IMG0_LABEL 7 + +#define IMG1 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.121568635, 0.5176471, 0.9960785, 0.9921569, 0.9960785, 0.8352942, 0.32156864, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.5568628, 0.91372555, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.98823535, 0.8745099, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.48235297, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.87843144, 0.7960785, 0.7960785, 0.8745099, 1.0, 0.8352942, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7960785, 0.9921569, 0.98823535, 0.9921569, 0.8313726, 0.078431375, 0.0, 0.0, 0.2392157, 0.9921569, 0.98823535, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 0.95294124, 0.87843144, 0.7960785, 0.7176471, 0.16078432, 0.59607846, 0.11764707, 0.0, 0.0, 1.0, 0.9921569, 0.40000004, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15686275, 0.078431375, 0.0, 0.0, 0.40000004, 0.9921569, 0.19607845, 0.0, 0.32156864, 0.9921569, 0.98823535, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32156864, 0.83921576, 0.121568635, 0.4431373, 0.91372555, 0.9960785, 0.91372555, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.40000004, 0.32156864, 0.16078432, 0.9921569, 0.909804, 0.9921569, 0.98823535, 0.91372555, 0.19607845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.59607846, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.91372555, 0.48235297, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.59607846, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.98823535, 0.75294125, 0.19607845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.7176471, 0.7960785, 0.95294124, 0.9960785, 0.9921569, 0.24313727, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15686275, 0.6745098, 0.98823535, 0.7960785, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7176471, 0.9960785, 0.43921572, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.7960785, 0.6392157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2392157, 0.9921569, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.83921576, 0.75294125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.043137256, 0.8352942, 0.9960785, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.40000004, 0.9921569, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 0.8352942, 0.98823535, 0.9921569, 0.43529415, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 1.0, 0.8352942, 0.36078432, 0.20000002, 0.0, 0.0, 0.121568635, 0.36078432, 0.6784314, 0.9921569, 0.9960785, 0.9921569, 0.5568628, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6745098, 0.98823535, 0.9921569, 0.98823535, 0.7960785, 0.7960785, 0.91372555, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.50980395, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.7960785, 1.0, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.9568628, 0.7960785, 0.32156864, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.078431375, 0.5921569, 0.5921569, 0.9921569, 0.67058825, 0.5921569, 0.5921569, 0.15686275, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0} +#define IMG1_LABEL 3 + +#define TOTAL_IMAGE 2 + + +static const signed char label[] = {IMG0_LABEL, IMG1_LABEL}; + +static const float W3[] = {-0.3233681, -0.4261553, -0.6519891, 0.79061985, -0.2210753, 0.037107922, 0.3984157, 0.22128074, 0.7975414, 0.2549885, 0.3076058, 0.62500215, -0.58958095, 0.20375429, -0.06477713, -1.566038, -0.37670124, -0.6443057}; +static const float B3[] = {-0.829373, -0.14096421}; + +static const float W2[] = {0.0070440695, 0.23192555, 0.036849476, -0.14687373, -0.15593372, 0.0044246824, 0.27322513, -0.027562773, 0.23404223, -0.6354651, -0.55645454, -0.77057034, 0.15603222, 0.71015775, 0.23954256, 1.8201442, -0.018377468, 1.5745461, 1.7230825, -0.59662616, 1.3997843, 0.33511618, 0.56846994, 0.3797911, 0.035079807, -0.18287429, -0.032232445, 0.006910181, -0.0026898328, -0.0057844054, 0.29354542, 0.13796881, 0.3558416, 0.0022847173, 0.0025906325, -0.022641085}; +static const float B2[] = {-0.11655525, -0.0036503011}; + +static const float W1[] = {0.15791991, -0.22649878, 0.021204736, 0.025593571, 0.008755621, -0.775102, -0.41594088, -0.12580238, -0.3963741, 0.33545518, -0.631953, -0.028754484, -0.50668705, -0.3574023, -3.7807872, -0.8261617, 0.102246165, 0.571127, -0.6256297, 0.06698781, 0.55969477, 0.25374785, -3.075965, -0.6959133, 0.2531965, 0.31739804, -0.8664238, 0.12750633, 0.83136076, 0.2666574, -2.5865922, -0.572031, 0.29743987, 0.16238026, -0.99154145, 0.077973805, 0.8913329, 0.16854058, -2.5247803, -0.5639109, 0.41671264, -0.10801031, -1.0229865, 0.2062031, 0.39889312, -0.16026731, -1.9185526, -0.48375717, 0.057339806, -1.2573057, -0.23117211, 1.051854, -0.7981992, -1.6263007, -0.26003376, -0.07649365, -0.4646075, 0.755821, 0.13187818, 0.24743222, -1.5276812, 0.1636555, -0.075465426, -0.058517877, -0.33852127, 1.3052516, 0.14443535, 0.44080895, -0.31031442, 0.15416017, 0.0053661224, -0.03175326, -0.15991405, 0.66121936, 0.0832211, 0.2651985, -0.038445678, 0.18054117, -0.0073251156, 0.054193687, -0.014296916, 0.30657783, 0.006181963, 0.22319937, 0.030315898, 0.12695274, -0.028179673, 0.11189027, 0.035358384, 0.046855893, -0.026528472, 0.26450494, 0.069981076, 0.107152134, -0.030371506, 0.09524366, 0.24802336, -0.36496836, -0.102762334, 0.49609017, 0.04002767, 0.020934932, -0.054773595, 0.05412083, -0.071876526, -1.5381132, -0.2356421, 1.5890793, -0.023087852, -0.24933836, 0.018771818, 0.08040064, 0.051946845, 0.6141782, 0.15780787, 0.12887044, -0.8691056, 1.3761537, 0.43058, 0.13476849, -0.14973496, 0.4542634, 0.13077497, 0.23117822, 0.003657386, 0.42742714, 0.23396699, 0.09209521, -0.060258932, 0.4642852, 0.10395402, 0.25047097, -0.05326261, 0.21466804, 0.11694269, 0.22402634, 0.12639907, 0.23495848, 0.12770525, 0.3324459, 0.0140223345, 0.106348366, 0.10877733, 0.30522102, 0.31412345, -0.07164018, 0.13483422, 0.45414954, 0.054698735, 0.07451815, 0.097312905, 0.27480683, 0.4866108, -0.43636885, -0.13586079, 0.5724732, 0.13595985, -0.0074526076, 0.11859829, 0.24481037, -0.37537888, -0.46877658, -0.5648533, 0.86578417, 0.3407381, -0.17214134, 0.040683553, 0.3630519, 0.089548275, -0.4989473, 0.47688767, 0.021731026, 0.2856471, 0.6174715, 0.7059148, -0.30635756, -0.5705427, -0.20692639, 0.041900065, 0.23040071, -0.1790487, -0.023751246, 0.14114629, 0.02345284, -0.64177734, -0.069909826, -0.08587972, 0.16460821, -0.53466517, -0.10163383, -0.13119817, 0.14908728, -0.63503706, -0.098961875, -0.23248474, 0.15406314, -0.48586813, -0.1904713, -0.20466608, 0.10629631, -0.5291871, -0.17358926, -0.36273107, 0.12225631, -0.38659447, -0.24787207, -0.25225234, 0.102635615, -0.14507034, -0.10110793, 0.043757595, -0.17158166, -0.031343404, -0.30139172, -0.09401665, 0.06986169, -0.54915506, 0.66843456, 0.14574362, -0.737502, 0.7700305, -0.4125441, 0.10115133, 0.05281194, 0.25467375, 0.22757779, -0.030224197, -0.0832025, -0.66385627, 0.51225215, -0.121023245, -0.3340579, -0.07505331, -0.09820366, -0.016041134, -0.03187605, -0.43589246, 0.094394326, -0.04983066, -0.0777906, -0.12822862, -0.089667186, -0.07014707, -0.010794195, -0.29095307, -0.01319235, -0.039757702, -0.023403417, -0.15530063, -0.052093383, -0.1477549, -0.07557954, -0.2686017, -0.035220042, -0.095615104, -0.015471024, -0.03906604, 0.024237331, -0.19604297, -0.19998372, -0.20302829, -0.04267139, -0.18774728, -0.045169186, -0.010131819, 0.14829905, -0.117015064, -0.4180649, -0.20680964, -0.024034742, -0.15787442, -0.055698488, -0.09037726, 0.40253848, -0.35745984, -0.786149, -0.0799551, 0.16205557, -0.14461482, -0.2749642, 0.2683253, 0.6881363, -0.064145364, 0.11361358, 0.59981894, 1.2947721, -1.2500908, 0.6082035, 0.12344158, 0.15808935, -0.17505693, 0.03425684, 0.39107767, 0.23190938, -0.7568858, 0.20042256, 0.079169095, 0.014275463, -0.12135842, 0.008516737, 0.26897284, 0.05706199, -0.52615446, 0.12489152, 0.08065737, -0.038548164, -0.08894516, 7.250979E-4, 0.28635752, -0.010820533, -0.39301336, 0.11144395, 0.06563818, -0.033744805, -0.07450528, -0.027328406, 0.3002447, 0.0029921278, -0.47954947, -0.04527057, -0.010289918, 0.039380465, -0.09236952, -0.1924659, 0.15401903, 0.21237805, -0.38984418, -0.37384143, -0.20648403, 0.29201767, -0.1299253, -0.36048025, -0.5544466, 0.45723814, -0.35266167, -0.94797707, -1.2481197, 0.88701195, 0.33620682, 0.0035414647, -0.22769359, 1.4563162, 0.54950374, 0.38396382, -0.41196275, 0.3758704, 0.17687413, 0.038129736, 0.16358295, 0.70515764, 0.055063568, 0.6445265, -0.2072113, 0.14618243, 0.10311305, 0.1971523, 0.174206, 0.36578146, -0.09782787, 0.5229244, -0.18459272, -0.0013945608, 0.08863555, 0.24184574, 0.15541393, 0.1722381, -0.10531331, 0.38215113, -0.30659106, -0.16298945, 0.11549875, 0.30750987, 0.1586183, -0.017728966, -0.050216004, 0.26232007, -1.2994286, -0.22700997, 0.108534105, 0.7447398, -0.39803517, 0.016863048, 0.10067235, -0.16355589, -0.64953077, -0.5674107, 0.017935256, 0.98968256, -1.395801, 0.44127485, 0.16644385, -0.19195901}; +static const float B1[] = {1.2019119, -1.1770505, 2.1698284, -1.9615222}; + +static const float W[] = {0.55808353, 0.78707385, -0.040990848, -0.122510895, -0.41261443, -0.036044, 0.1691557, -0.14711425, -0.016407091, -0.28058195, 0.018765535, 0.062936015, 0.49562064, 0.33931744, -0.47547337, -0.1405672, -0.88271654, 0.18359914, 0.020887045, -0.13782434, -0.052250575, 0.67922074, -0.28022966, -0.31278887, 0.44416663, -0.26106882, -0.32219923, 1.0321393, -0.1444394, 0.5221766, 0.057590708, -0.96547794, -0.3051688, 0.16859075, -0.5320585, 0.42684716, -0.5434046, 0.014693736, 0.26795483, 0.15921915}; +static const float B[] = {0.041442648, 1.461427, 0.07154641, -1.2774754, 0.80927604, -1.6933714, -0.29740578, -0.11774022, 0.3292682, 0.6596958}; + + + + + +// ASCII lib from (https://www.jianshu.com/p/1f58a0ebf5d9) + + + + +int mnist(void); + +#endif //__MNIST_H__ diff --git a/components/ai/onnx/examples/mnist_int/mnist.c b/components/ai/onnx/examples/mnist_int/mnist.c new file mode 100644 index 00000000..3a8a9c51 --- /dev/null +++ b/components/ai/onnx/examples/mnist_int/mnist.c @@ -0,0 +1,226 @@ +//#include "tos_k.h" +#include +#include +//#include +//#include +//#include + +//#include "mnist.h" +#include "mnist_int.h" +#include "onnx.h" + +static const char codeLib[] = "@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. "; +int data[5]={1.5 , 2.5 , 3.5 , 4.5 , 5.5}; +//static const int img[2][784] = {IMG0, IMG1}; +static const int img[2][784] = {IMG0, IMG1}; +//static const int imgint[2][784] = {IMG0_INT, IMG1_INT}; + +static const int img1[784] = {1,2,3,4,5}; + +int hello() +{ + printf("hello\r\n"); + return 0; +} + +//void print_img(void) +void print_img(void * buf) +{ + int index = 0; + //char ch = '@'; + int x = 0; + int y = 0; + + printf("test2\r\n"); + + for(y = 0; y < 28; y++) + { + for (x = 0; x < 28; x++) + { + + index = 0; + //if(img[0][y*28+x] > 600) + if(((int*)buf)[y*28+x] > 600) + //if(data[0] > 0.6) + { + index =69; + //ch = ' '; + } + if(index < 0) + { + index = 0; + //ch = ' '; + } + + + printf("%c",codeLib[index]); + printf("%c",codeLib[index]); + + + //printf("%c",ch); + //printf("%c",ch); + + } + printf("\r\n"); + } +} + +int mnist() +{ + printf("test1\r\n"); + int img_index = 1; + /* + if(argc == 2) + { + img_index = atoi(argv[1]); + } + */ + + //print_img(); + print_img(img[img_index]); + + printf("img ok\r\n"); + + // 1. Conv2D + int64_t shapeW3[] = {2, 1, 3, 3}; + int64_t dimW3 = 4; + int64_t permW3_t[] = { 0, 2, 3, 1}; + int* W3_t = transpose(W3, shapeW3, dimW3, permW3_t); + + printf("transpose ok\r\n"); + + int* conv1 = (int*) malloc(sizeof(int)*28*28*2); + memset(conv1, 0, sizeof(sizeof(int)*28*28*2)); + + conv2D(img[img_index], 28, 28, 1, W3, 2, 3, 3, 1, 1, 1, 1, B3, conv1, 28, 28); + + free(W3_t); + + printf("Conv2D ok \r\n"); + + // 2. Relu + int* relu1 = (int*) malloc(sizeof(int)*28*28*2); + relu(conv1, 28*28*2, relu1); + + free(conv1); + + printf("Relu ok\r\n"); + + // 3. Maxpool + int* maxpool1 = (int*) malloc(sizeof(int)*14*14*2); + memset(maxpool1, 0, sizeof(sizeof(int)*14*14*2)); + maxpool(relu1, 28, 28, 2, 2, 2, 0, 0, 2, 2, 14, 14, maxpool1); + + free(relu1); + + printf("Maxpool ok\r\n"); + + // 4. Conv2D + int64_t shapeW2[] = {2, 2, 3, 3}; + int64_t dimW2 = 4; + int64_t perm_t[] = { 0, 2, 3, 1}; + int* W2_t = transpose(W2, shapeW2, dimW2, perm_t); + + int* conv2 = (int*) malloc(sizeof(int)*14*14*2); + memset(conv2, 0, sizeof(sizeof(int)*14*14*2)); + conv2D(maxpool1, 14, 14, 2, W2_t, 2, 3, 3, 1, 1, 1, 1, B2, conv2, 14, 14); + + free(W2_t); + free(maxpool1); + + printf("Conv2D ok\r\n"); + + // 5. Relu + int* relu2 = (int*) malloc(sizeof(int)*14*14*2); + relu(conv2, 14*14*2, relu2); + + free(conv2); + + printf("Relu ok\r\n"); + + // 6. Maxpool + int* maxpool2 = (int*) malloc(sizeof(int)*7*7*2); + memset(maxpool2, 0, sizeof(sizeof(int)*7*7*2)); + maxpool(relu2, 14, 14, 2, 2, 2, 0, 0, 2, 2, 7, 7, maxpool2); + + free(relu2); + + printf("Maxpool ok\r\n"); + + // Flatten NOT REQUIRED + + // 7. Dense + int64_t shapeW1[] = {98, 4}; + int64_t dimW1 = 2; + int64_t permW1_t[] = { 1, 0}; + int* W1_t = transpose(W1, shapeW1, dimW1, permW1_t); + + int* dense1 = (int*) malloc(sizeof(int)*4); + memset(dense1, 0, sizeof(sizeof(int)*4)); + dense(maxpool2, W1_t, 98, 4, B1, dense1); + + free(W1_t); + free(maxpool2); + + printf("Dense ok\r\n"); + + // 8. Dense + int64_t shapeW[] = {4, 10}; + int64_t dimW = 2; + int64_t permW_t[] = { 1, 0}; + int* W_t = transpose(W, shapeW, dimW, permW_t); + + int* dense2 = (int*) malloc(sizeof(int)*10); + memset(dense2, 0, sizeof(sizeof(int)*10)); + dense(dense1, W_t, 4, 10, B, dense2); + + free(W_t); + free(dense1); + + printf("Dense ok\r\n"); + + // 9. Softmax + int* output = (int*) malloc(sizeof(int)*10); + memset(output, 0, sizeof(sizeof(int)*10)); + softmax(dense2, 10, output); + + printf("Softmax ok\r\n"); + + // 10. Result + /* + printf("\n\rdense2: \n\r"); + for(int i = 0; i < 10; i++) + printf("%d ", dense2[i]); + */ + + + int max = 0; + int min = output[0]; + int max_index = 0; + int min_index = 0; + printf("\n\rPredictions: \n\r"); + for(int i = 0; i < 10; i++) + { + printf("%d ", output[i]); + if(output[i] > max) + { + max = output[i]; + max_index = i; + } + if(output[i] < min) + { + min = output[i]; + min_index = i; + } + } + printf("\n\r"); + printf("\n\rThe number is %d\n\r", min_index); + + free(dense2); + free(output); + + printf("Result ok\r\n"); + + return 0; +} +//MSH_CMD_EXPORT(mnist, mnist simple example) diff --git a/components/ai/onnx/examples/mnist_int/mnist_int.h b/components/ai/onnx/examples/mnist_int/mnist_int.h new file mode 100644 index 00000000..460dfc9f --- /dev/null +++ b/components/ai/onnx/examples/mnist_int/mnist_int.h @@ -0,0 +1,73 @@ +#ifndef __MNIST_INT_H__ +#define __MNIST_INT_H__ + +#include +#include + + +#define IMG0 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,380,376,301,462,239,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,352,541,921,921,921,921,921,921,984,984,972,996,960,921,745,82,0,0,0,0,0,0,0,0,0,0,0,549,984,996,996,996,996,996,996,996,996,996,996,996,996,996,996,741,90,0,0,0,0,0,0,0,0,0,0,886,996,815,780,780,780,780,545,239,239,239,239,239,501,870,996,996,741,82,0,0,0,0,0,0,0,0,0,149,321,50,0,0,0,0,0,0,0,0,0,0,0,133,835,996,996,450,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,329,996,996,917,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,329,996,996,917,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,415,615,996,996,952,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,98,458,894,894,894,992,996,996,996,996,941,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,266,466,862,996,996,996,996,996,996,996,996,996,556,0,0,0,0,0,0,0,0,0,0,0,0,0,145,733,992,996,996,996,874,807,807,294,266,843,996,996,458,0,0,0,0,0,0,0,0,0,0,0,0,443,858,996,949,890,450,349,121,0,0,0,0,784,996,945,160,0,0,0,0,0,0,0,0,0,0,0,0,662,996,690,243,0,0,0,0,0,0,0,188,905,996,917,0,0,0,0,0,0,0,0,0,0,0,0,0,70,486,0,0,0,0,0,0,0,0,0,329,996,996,650,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,545,996,933,223,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,823,980,996,658,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,949,996,937,223,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,349,984,945,337,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,807,964,615,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,458,270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} +#define IMG0_LABEL 7 + + + +#define IMG1 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,121,517,996,992,996,835,321,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,82,556,913,988,992,988,992,988,874,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,482,996,992,996,992,878,796,796,874,1000,835,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,796,992,988,992,831,78,0,0,239,992,988,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,952,878,796,717,160,596,117,0,0,1000,992,400,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,78,0,0,400,992,196,0,321,992,988,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,321,839,121,443,913,996,913,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,243,400,321,160,992,909,992,988,913,196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,596,992,996,992,996,992,996,913,482,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,596,988,992,988,992,988,752,196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,243,717,796,952,996,992,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,674,988,796,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,82,0,0,0,0,0,0,0,0,0,717,996,439,0,0,0,0,0,0,0,0,0,0,0,0,0,0,243,796,639,0,0,0,0,0,0,0,0,239,992,592,0,0,0,0,0,0,0,0,0,0,0,0,0,82,839,752,0,0,0,0,0,0,0,0,43,835,996,592,0,0,0,0,0,0,0,0,0,0,0,0,0,400,992,592,0,0,0,0,0,0,0,160,835,988,992,435,0,0,0,0,0,0,0,0,0,0,0,0,0,160,1000,835,360,200,0,0,121,360,678,992,996,992,556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,674,988,992,988,796,796,913,988,992,988,992,509,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,82,796,1000,992,996,992,996,992,956,796,321,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,78,592,592,992,670,592,592,156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} +#define IMG1_LABEL 3 + +#define TOTAL_IMAGE 2 + + +static const signed char label[] = {IMG0_LABEL, IMG1_LABEL}; + + + +static const int W3[] = {-323,-426,-651,790,-221,37,398,221,797,254,307,625,-589,203,-64,-1566,-376,-644}; +static const int B3[] = {-829,-140}; + +static const int W2[] = {7,231,36,-146,-155,4,273,-27,234,-635,-556,-770,156,710,239,1820,-18,1574,1723,-596,1399,335,568,379,35,-182,-32,6,-2,-5,293,137,355,2,2,-22}; +static const int B2[] = {-116,-3}; + +static const int W1[] = {157,-226,21,25,8,-775,-415,-125,-396,335,-631,-28,-506,-357,-3780,-826,102,571,-625,66,559,253,-3075,-695,253,317,-866,127,831,266,-2586,-572,297,162,-991,77,891,168,-2524,-563,416,-108,-1022,206,398,-160,-1918,-483,57,-1257,-231,1051,-798,-1626,-260,-76,-464,755,131,247,-1527,163,-75,-58,-338,1305,144,440,-310,154,5,-31,-159,661,83,265,-38,180,-7,54,-14,306,6,223,30,126,-28,111,35,46,-26,264,69,107,-30,95,248,-364,-102,496,40,20,-54,54,-71,-1538,-235,1589,-23,-249,18,80,51,614,157,128,-869,1376,430,134,-149,454,130,231,3,427,233,92,-60,464,103,250,-53,214,116,224,126,234,127,332,14,106,108,305,314,-71,134,454,54,74,97,274,486,-436,-135,572,135,-7,118,244,-375,-468,-564,865,340,-172,40,363,89,-498,476,21,285,617,705,-306,-570,-206,41,230,-179,-23,141,23,-641,-69,-85,164,-534,-101,-131,149,-635,-98,-232,154,-485,-190,-204,106,-529,-173,-362,122,-386,-247,-252,102,-145,-101,43,-171,-31,-301,-94,69,-549,668,145,-737,770,-412,101,52,254,227,-30,-83,-663,512,-121,-334,-75,-98,-16,-31,-435,94,-49,-77,-128,-89,-70,-10,-290,-13,-39,-23,-155,-52,-147,-75,-268,-35,-95,-15,-39,24,-196,-199,-203,-42,-187,-45,-10,148,-117,-418,-206,-24,-157,-55,-90,402,-357,-786,-79,162,-144,-274,268,688,-64,113,599,1294,-1250,608,123,158,-175,34,391,231,-756,200,79,14,-121,8,268,57,-526,124,80,-38,-88,0,286,-10,-393,111,65,-33,-74,-27,300,2,-479,-45,-10,39,-92,-192,154,212,-389,-373,-206,292,-129,-360,-554,457,-352,-947,-1248,887,336,3,-227,1456,549,383,-411,375,176,38,163,705,55,644,-207,146,103,197,174,365,-97,522,-184,-1,88,241,155,172,-105,382,-306,-162,115,307,158,-17,-50,262,-1299,-227,108,744,-398,16,100,-163,-649,-567,17,989,-1395,441,166,-191}; +static const int B1[] = {1201,-1177,2169,-1961}; + +static const int W[] = {558,787,-40,-122,-412,-36,169,-147,-16,-280,18,62,495,339,-475,-140,-882,183,20,-137,-52,679,-280,-312,444,-261,-322,1032,-144,522,57,-965,-305,168,-532,426,-543,14,267,159}; +static const int B[] = {41,1461,71,-1277,809,-1693,-297,-117,329,659}; + + + +/* + +#define IMG0 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3803,3764,3019,4627,2392,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3529,5411,9215,9215,9215,9215,9215,9215,9843,9843,9725,9960,9607,9215,7450,823,0,0,0,0,0,0,0,0,0,0,0,5490,9843,9960,9960,9960,9960,9960,9960,9960,9960,9960,9960,9960,9960,9960,9960,7411,901,0,0,0,0,0,0,0,0,0,0,8862,9960,8156,7803,7803,7803,7803,5450,2392,2392,2392,2392,2392,5019,8705,9960,9960,7411,823,0,0,0,0,0,0,0,0,0,1490,3215,509,0,0,0,0,0,0,0,0,0,0,0,1333,8352,9960,9960,4509,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3294,9960,9960,9176,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3294,9960,9960,9176,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4156,6156,9960,9960,9529,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,980,4588,8941,8941,8941,9921,9960,9960,9960,9960,9411,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2666,4666,8627,9960,9960,9960,9960,9960,9960,9960,9960,9960,5568,0,0,0,0,0,0,0,0,0,0,0,0,0,1450,7333,9921,9960,9960,9960,8745,8078,8078,2941,2666,8431,9960,9960,4588,0,0,0,0,0,0,0,0,0,0,0,0,4431,8588,9960,9490,8901,4509,3490,1215,0,0,0,0,7843,9960,9450,1607,0,0,0,0,0,0,0,0,0,0,0,0,6627,9960,6901,2431,0,0,0,0,0,0,0,1882,9058,9960,9176,0,0,0,0,0,0,0,0,0,0,0,0,0,705,4862,0,0,0,0,0,0,0,0,0,3294,9960,9960,6509,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5450,9960,9333,2235,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8235,9803,9960,6588,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9490,9960,9372,2235,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3490,9843,9450,3372,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,196,8078,9647,6156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,4588,2705,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} +#define IMG0_LABEL 7 + + + +#define IMG1 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1215,5176,9960,9921,9960,8352,3215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,823,5568,9137,9882,9921,9882,9921,9882,8745,784,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4823,9960,9921,9960,9921,8784,7960,7960,8745,10000,8352,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7960,9921,9882,9921,8313,784,0,0,2392,9921,9882,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1607,9529,8784,7960,7176,1607,5960,1176,0,0,10000,9921,4000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1568,784,0,0,4000,9921,1960,0,3215,9921,9882,784,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3215,8392,1215,4431,9137,9960,9137,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2431,4000,3215,1607,9921,9098,9921,9882,9137,1960,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5960,9921,9960,9921,9960,9921,9960,9137,4823,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5960,9882,9921,9882,9921,9882,7529,1960,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2431,7176,7960,9529,9960,9921,2431,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1568,6745,9882,7960,784,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,823,0,0,0,0,0,0,0,0,0,7176,9960,4392,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2431,7960,6392,0,0,0,0,0,0,0,0,2392,9921,5921,0,0,0,0,0,0,0,0,0,0,0,0,0,823,8392,7529,0,0,0,0,0,0,0,0,431,8352,9960,5921,0,0,0,0,0,0,0,0,0,0,0,0,0,4000,9921,5921,0,0,0,0,0,0,0,1607,8352,9882,9921,4352,0,0,0,0,0,0,0,0,0,0,0,0,0,1607,10000,8352,3607,2000,0,0,1215,3607,6784,9921,9960,9921,5568,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6745,9882,9921,9882,7960,7960,9137,9882,9921,9882,9921,5098,784,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,823,7960,10000,9921,9960,9921,9960,9921,9568,7960,3215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,784,5921,5921,9921,6705,5921,5921,1568,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} +#define IMG1_LABEL 3 + +#define TOTAL_IMAGE 2 + + +static const signed char label[] = {IMG0_LABEL, IMG1_LABEL}; + + + +static const int W3[] = {-3233,-4261,-6519,7906,-2210,371,3984,2212,7975,2549,3076,6250,-5895,2037,-647,-15660,-3767,-6443}; +static const int B3[] = {-8293,-1409}; + +static const int W2[] = {70,2319,368,-1468,-1559,44,2732,-275,2340,-6354,-5564,-7705,1560,7101,2395,18201,-183,15745,17230,-5966,13997,3351,5684,3797,350,-1828,-322,69,-26,-57,2935,1379,3558,22,25,-226}; +static const int B2[] = {-1165,-36}; + +static const int W1[] = {1579,-2264,212,255,87,-7751,-4159,-1258,-3963,3354,-6319,-287,-5066,-3574,-37807,-8261,1022,5711,-6256,669,5596,2537,-30759,-6959,2531,3173,-8664,1275,8313,2666,-25865,-5720,2974,1623,-9915,779,8913,1685,-25247,-5639,4167,-1080,-10229,2062,3988,-1602,-19185,-4837,573,-12573,-2311,10518,-7981,-16263,-2600,-764,-4646,7558,1318,2474,-15276,1636,-754,-585,-3385,13052,1444,4408,-3103,1541,53,-317,-1599,6612,832,2651,-384,1805,-73,541,-142,3065,61,2231,303,1269,-281,1118,353,468,-265,2645,699,1071,-303,952,2480,-3649,-1027,4960,400,209,-547,541,-718,-15381,-2356,15890,-230,-2493,187,804,519,6141,1578,1288,-8691,13761,4305,1347,-1497,4542,1307,2311,36,4274,2339,920,-602,4642,1039,2504,-532,2146,1169,2240,1263,2349,1277,3324,140,1063,1087,3052,3141,-716,1348,4541,546,745,973,2748,4866,-4363,-1358,5724,1359,-74,1185,2448,-3753,-4687,-5648,8657,3407,-1721,406,3630,895,-4989,4768,217,2856,6174,7059,-3063,-5705,-2069,419,2304,-1790,-237,1411,234,-6417,-699,-858,1646,-5346,-1016,-1311,1490,-6350,-989,-2324,1540,-4858,-1904,-2046,1062,-5291,-1735,-3627,1222,-3865,-2478,-2522,1026,-1450,-1011,437,-1715,-313,-3013,-940,698,-5491,6684,1457,-7375,7700,-4125,1011,528,2546,2275,-302,-832,-6638,5122,-1210,-3340,-750,-982,-160,-318,-4358,943,-498,-777,-1282,-896,-701,-107,-2909,-131,-397,-234,-1553,-520,-1477,-755,-2686,-352,-956,-154,-390,242,-1960,-1999,-2030,-426,-1877,-451,-101,1482,-1170,-4180,-2068,-240,-1578,-556,-903,4025,-3574,-7861,-799,1620,-1446,-2749,2683,6881,-641,1136,5998,12947,-12500,6082,1234,1580,-1750,342,3910,2319,-7568,2004,791,142,-1213,85,2689,570,-5261,1248,806,-385,-889,7,2863,-108,-3930,1114,656,-337,-745,-273,3002,29,-4795,-452,-102,393,-923,-1924,1540,2123,-3898,-3738,-2064,2920,-1299,-3604,-5544,4572,-3526,-9479,-12481,8870,3362,35,-2276,14563,5495,3839,-4119,3758,1768,381,1635,7051,550,6445,-2072,1461,1031,1971,1742,3657,-978,5229,-1845,-13,886,2418,1554,1722,-1053,3821,-3065,-1629,1154,3075,1586,-177,-502,2623,-12994,-2270,1085,7447,-3980,168,1006,-1635,-6495,-5674,179,9896,-13958,4412,1664,-1919}; +static const int B1[] = {12019,-11770,21698,-19615}; + +static const int W[] = {5580,7870,-409,-1225,-4126,-360,1691,-1471,-164,-2805,187,629,4956,3393,-4754,-1405,-8827,1835,208,-1378,-522,6792,-2802,-3127,4441,-2610,-3221,10321,-1444,5221,575,-9654,-3051,1685,-5320,4268,-5434,146,2679,1592}; +static const int B[] = {414,14614,715,-12774,8092,-16933,-2974,-1177,3292,6596}; + +*/ + + + + +int mnist(void); + +#endif //__MNIST_INT_H__ diff --git a/components/ai/onnx/examples/model/mnist-lg.onnx b/components/ai/onnx/examples/model/mnist-lg.onnx new file mode 100644 index 0000000000000000000000000000000000000000..3474f9172d9485e5a60c7027a698aac6ddc7532a GIT binary patch literal 5826 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 literal 0 HcmV?d00001 diff --git a/components/ai/onnx/operator_float/mnist_float.c b/components/ai/onnx/operator_float/mnist_float.c new file mode 100644 index 00000000..5ba6a2ff --- /dev/null +++ b/components/ai/onnx/operator_float/mnist_float.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#include + +#include "mnist.h" +#include "onnx.h" + +int mnist(int argc, char const *argv[]) +{ + int img_index = 0; + if(argc == 2) + { + img_index = atoi(argv[1]); + } + print_img(img[img_index]); + + // 1. Conv2D + int64_t shapeW3[] = {2, 1, 3, 3}; + int64_t dimW3 = 4; + int64_t permW3_t[] = { 0, 2, 3, 1}; + float* W3_t = transpose(W3, shapeW3, dimW3, permW3_t); + + float* conv1 = (float*) malloc(sizeof(float)*28*28*2); + memset(conv1, 0, sizeof(sizeof(float)*28*28*2)); + conv2D(img[img_index], 28, 28, 1, W3, 2, 3, 3, 1, 1, 1, 1, B3, conv1, 28, 28); + + free(W3_t); + + // 2. Relu + float* relu1 = (float*) malloc(sizeof(float)*28*28*2); + relu(conv1, 28*28*2, relu1); + + free(conv1); + + // 3. Maxpool + float* maxpool1 = (float*) malloc(sizeof(float)*14*14*2); + memset(maxpool1, 0, sizeof(sizeof(float)*14*14*2)); + maxpool(relu1, 28, 28, 2, 2, 2, 0, 0, 2, 2, 14, 14, maxpool1); + + free(relu1); + + // 4. Conv2D + int64_t shapeW2[] = {2, 2, 3, 3}; + int64_t dimW2 = 4; + int64_t perm_t[] = { 0, 2, 3, 1}; + float* W2_t = transpose(W2, shapeW2, dimW2, perm_t); + + float* conv2 = (float*) malloc(sizeof(float)*14*14*2); + memset(conv2, 0, sizeof(sizeof(float)*14*14*2)); + conv2D(maxpool1, 14, 14, 2, W2_t, 2, 3, 3, 1, 1, 1, 1, B2, conv2, 14, 14); + + free(W2_t); + free(maxpool1); + + // 5. Relu + float* relu2 = (float*) malloc(sizeof(float)*14*14*2); + relu(conv2, 14*14*2, relu2); + + free(conv2); + + // 6. Maxpool + float* maxpool2 = (float*) malloc(sizeof(float)*7*7*2); + memset(maxpool2, 0, sizeof(sizeof(float)*7*7*2)); + maxpool(relu2, 14, 14, 2, 2, 2, 0, 0, 2, 2, 7, 7, maxpool2); + + free(relu2); + + // Flatten NOT REQUIRED + + // 7. Dense + int64_t shapeW1[] = {98, 4}; + int64_t dimW1 = 2; + int64_t permW1_t[] = { 1, 0}; + float* W1_t = transpose(W1, shapeW1, dimW1, permW1_t); + + float* dense1 = (float*) malloc(sizeof(float)*4); + memset(dense1, 0, sizeof(sizeof(float)*4)); + dense(maxpool2, W1_t, 98, 4, B1, dense1); + + free(W1_t); + free(maxpool2); + + // 8. Dense + int64_t shapeW[] = {4, 10}; + int64_t dimW = 2; + int64_t permW_t[] = { 1, 0}; + float* W_t = transpose(W, shapeW, dimW, permW_t); + + float* dense2 = (float*) malloc(sizeof(float)*10); + memset(dense2, 0, sizeof(sizeof(float)*10)); + dense(dense1, W_t, 4, 10, B, dense2); + + free(W_t); + free(dense1); + + // 9. Softmax + float* output = (float*) malloc(sizeof(float)*10); + memset(output, 0, sizeof(sizeof(float)*10)); + softmax(dense2, 10, output); + + // 10. Result + float max = 0; + int max_index = 0; + printf("\nPredictions: \n"); + for(int i = 0; i < 10; i++) + { + printf("%f ", output[i]); + if(output[i] > max) + { + max = output[i]; + max_index = i; + } + } + printf("\n"); + printf("\nThe number is %d\n", max_index); + + free(dense2); + free(output); + + return 0; +} +MSH_CMD_EXPORT(mnist, mnist simple example) diff --git a/components/ai/onnx/operator_float/mnist_float.h b/components/ai/onnx/operator_float/mnist_float.h new file mode 100644 index 00000000..f5f57d90 --- /dev/null +++ b/components/ai/onnx/operator_float/mnist_float.h @@ -0,0 +1,48 @@ +#ifndef __MNIST_H__ +#define __MNIST_H__ + +#include +#include + +#define IMG0 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3803922, 0.37647063, 0.3019608, 0.46274513, 0.2392157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3529412, 0.5411765, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9843138, 0.9843138, 0.9725491, 0.9960785, 0.9607844, 0.9215687, 0.74509805, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.54901963, 0.9843138, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.7411765, 0.09019608, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8862746, 0.9960785, 0.81568635, 0.7803922, 0.7803922, 0.7803922, 0.7803922, 0.54509807, 0.2392157, 0.2392157, 0.2392157, 0.2392157, 0.2392157, 0.5019608, 0.8705883, 0.9960785, 0.9960785, 0.7411765, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14901961, 0.32156864, 0.050980397, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.13333334, 0.8352942, 0.9960785, 0.9960785, 0.45098042, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4156863, 0.6156863, 0.9960785, 0.9960785, 0.95294124, 0.20000002, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.098039225, 0.45882356, 0.8941177, 0.8941177, 0.8941177, 0.9921569, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.94117653, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.26666668, 0.4666667, 0.86274517, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.5568628, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14509805, 0.73333335, 0.9921569, 0.9960785, 0.9960785, 0.9960785, 0.8745099, 0.8078432, 0.8078432, 0.29411766, 0.26666668, 0.8431373, 0.9960785, 0.9960785, 0.45882356, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4431373, 0.8588236, 0.9960785, 0.9490197, 0.89019614, 0.45098042, 0.34901962, 0.121568635, 0.0, 0.0, 0.0, 0.0, 0.7843138, 0.9960785, 0.9450981, 0.16078432, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6627451, 0.9960785, 0.6901961, 0.24313727, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.18823531, 0.9058824, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07058824, 0.48627454, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.6509804, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.54509807, 0.9960785, 0.9333334, 0.22352943, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8235295, 0.9803922, 0.9960785, 0.65882355, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9490197, 0.9960785, 0.93725497, 0.22352943, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.34901962, 0.9843138, 0.9450981, 0.3372549, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.019607844, 0.8078432, 0.96470594, 0.6156863, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.015686275, 0.45882356, 0.27058825, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0} +#define IMG0_LABEL 7 + +#define IMG1 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.121568635, 0.5176471, 0.9960785, 0.9921569, 0.9960785, 0.8352942, 0.32156864, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.5568628, 0.91372555, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.98823535, 0.8745099, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.48235297, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.87843144, 0.7960785, 0.7960785, 0.8745099, 1.0, 0.8352942, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7960785, 0.9921569, 0.98823535, 0.9921569, 0.8313726, 0.078431375, 0.0, 0.0, 0.2392157, 0.9921569, 0.98823535, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 0.95294124, 0.87843144, 0.7960785, 0.7176471, 0.16078432, 0.59607846, 0.11764707, 0.0, 0.0, 1.0, 0.9921569, 0.40000004, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15686275, 0.078431375, 0.0, 0.0, 0.40000004, 0.9921569, 0.19607845, 0.0, 0.32156864, 0.9921569, 0.98823535, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32156864, 0.83921576, 0.121568635, 0.4431373, 0.91372555, 0.9960785, 0.91372555, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.40000004, 0.32156864, 0.16078432, 0.9921569, 0.909804, 0.9921569, 0.98823535, 0.91372555, 0.19607845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.59607846, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.91372555, 0.48235297, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.59607846, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.98823535, 0.75294125, 0.19607845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.7176471, 0.7960785, 0.95294124, 0.9960785, 0.9921569, 0.24313727, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15686275, 0.6745098, 0.98823535, 0.7960785, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7176471, 0.9960785, 0.43921572, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.7960785, 0.6392157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2392157, 0.9921569, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.83921576, 0.75294125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.043137256, 0.8352942, 0.9960785, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.40000004, 0.9921569, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 0.8352942, 0.98823535, 0.9921569, 0.43529415, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 1.0, 0.8352942, 0.36078432, 0.20000002, 0.0, 0.0, 0.121568635, 0.36078432, 0.6784314, 0.9921569, 0.9960785, 0.9921569, 0.5568628, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6745098, 0.98823535, 0.9921569, 0.98823535, 0.7960785, 0.7960785, 0.91372555, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.50980395, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.7960785, 1.0, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.9568628, 0.7960785, 0.32156864, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.078431375, 0.5921569, 0.5921569, 0.9921569, 0.67058825, 0.5921569, 0.5921569, 0.15686275, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0} +#define IMG1_LABEL 3 + +#define TOTAL_IMAGE 2 + +static const float img[][784] = {IMG0, IMG1}; +static const signed char label[] = {IMG0_LABEL, IMG1_LABEL}; + +static const float W3[] = {-0.3233681, -0.4261553, -0.6519891, 0.79061985, -0.2210753, 0.037107922, 0.3984157, 0.22128074, 0.7975414, 0.2549885, 0.3076058, 0.62500215, -0.58958095, 0.20375429, -0.06477713, -1.566038, -0.37670124, -0.6443057}; +static const float B3[] = {-0.829373, -0.14096421}; + +static const float W2[] = {0.0070440695, 0.23192555, 0.036849476, -0.14687373, -0.15593372, 0.0044246824, 0.27322513, -0.027562773, 0.23404223, -0.6354651, -0.55645454, -0.77057034, 0.15603222, 0.71015775, 0.23954256, 1.8201442, -0.018377468, 1.5745461, 1.7230825, -0.59662616, 1.3997843, 0.33511618, 0.56846994, 0.3797911, 0.035079807, -0.18287429, -0.032232445, 0.006910181, -0.0026898328, -0.0057844054, 0.29354542, 0.13796881, 0.3558416, 0.0022847173, 0.0025906325, -0.022641085}; +static const float B2[] = {-0.11655525, -0.0036503011}; + +static const float W1[] = {0.15791991, -0.22649878, 0.021204736, 0.025593571, 0.008755621, -0.775102, -0.41594088, -0.12580238, -0.3963741, 0.33545518, -0.631953, -0.028754484, -0.50668705, -0.3574023, -3.7807872, -0.8261617, 0.102246165, 0.571127, -0.6256297, 0.06698781, 0.55969477, 0.25374785, -3.075965, -0.6959133, 0.2531965, 0.31739804, -0.8664238, 0.12750633, 0.83136076, 0.2666574, -2.5865922, -0.572031, 0.29743987, 0.16238026, -0.99154145, 0.077973805, 0.8913329, 0.16854058, -2.5247803, -0.5639109, 0.41671264, -0.10801031, -1.0229865, 0.2062031, 0.39889312, -0.16026731, -1.9185526, -0.48375717, 0.057339806, -1.2573057, -0.23117211, 1.051854, -0.7981992, -1.6263007, -0.26003376, -0.07649365, -0.4646075, 0.755821, 0.13187818, 0.24743222, -1.5276812, 0.1636555, -0.075465426, -0.058517877, -0.33852127, 1.3052516, 0.14443535, 0.44080895, -0.31031442, 0.15416017, 0.0053661224, -0.03175326, -0.15991405, 0.66121936, 0.0832211, 0.2651985, -0.038445678, 0.18054117, -0.0073251156, 0.054193687, -0.014296916, 0.30657783, 0.006181963, 0.22319937, 0.030315898, 0.12695274, -0.028179673, 0.11189027, 0.035358384, 0.046855893, -0.026528472, 0.26450494, 0.069981076, 0.107152134, -0.030371506, 0.09524366, 0.24802336, -0.36496836, -0.102762334, 0.49609017, 0.04002767, 0.020934932, -0.054773595, 0.05412083, -0.071876526, -1.5381132, -0.2356421, 1.5890793, -0.023087852, -0.24933836, 0.018771818, 0.08040064, 0.051946845, 0.6141782, 0.15780787, 0.12887044, -0.8691056, 1.3761537, 0.43058, 0.13476849, -0.14973496, 0.4542634, 0.13077497, 0.23117822, 0.003657386, 0.42742714, 0.23396699, 0.09209521, -0.060258932, 0.4642852, 0.10395402, 0.25047097, -0.05326261, 0.21466804, 0.11694269, 0.22402634, 0.12639907, 0.23495848, 0.12770525, 0.3324459, 0.0140223345, 0.106348366, 0.10877733, 0.30522102, 0.31412345, -0.07164018, 0.13483422, 0.45414954, 0.054698735, 0.07451815, 0.097312905, 0.27480683, 0.4866108, -0.43636885, -0.13586079, 0.5724732, 0.13595985, -0.0074526076, 0.11859829, 0.24481037, -0.37537888, -0.46877658, -0.5648533, 0.86578417, 0.3407381, -0.17214134, 0.040683553, 0.3630519, 0.089548275, -0.4989473, 0.47688767, 0.021731026, 0.2856471, 0.6174715, 0.7059148, -0.30635756, -0.5705427, -0.20692639, 0.041900065, 0.23040071, -0.1790487, -0.023751246, 0.14114629, 0.02345284, -0.64177734, -0.069909826, -0.08587972, 0.16460821, -0.53466517, -0.10163383, -0.13119817, 0.14908728, -0.63503706, -0.098961875, -0.23248474, 0.15406314, -0.48586813, -0.1904713, -0.20466608, 0.10629631, -0.5291871, -0.17358926, -0.36273107, 0.12225631, -0.38659447, -0.24787207, -0.25225234, 0.102635615, -0.14507034, -0.10110793, 0.043757595, -0.17158166, -0.031343404, -0.30139172, -0.09401665, 0.06986169, -0.54915506, 0.66843456, 0.14574362, -0.737502, 0.7700305, -0.4125441, 0.10115133, 0.05281194, 0.25467375, 0.22757779, -0.030224197, -0.0832025, -0.66385627, 0.51225215, -0.121023245, -0.3340579, -0.07505331, -0.09820366, -0.016041134, -0.03187605, -0.43589246, 0.094394326, -0.04983066, -0.0777906, -0.12822862, -0.089667186, -0.07014707, -0.010794195, -0.29095307, -0.01319235, -0.039757702, -0.023403417, -0.15530063, -0.052093383, -0.1477549, -0.07557954, -0.2686017, -0.035220042, -0.095615104, -0.015471024, -0.03906604, 0.024237331, -0.19604297, -0.19998372, -0.20302829, -0.04267139, -0.18774728, -0.045169186, -0.010131819, 0.14829905, -0.117015064, -0.4180649, -0.20680964, -0.024034742, -0.15787442, -0.055698488, -0.09037726, 0.40253848, -0.35745984, -0.786149, -0.0799551, 0.16205557, -0.14461482, -0.2749642, 0.2683253, 0.6881363, -0.064145364, 0.11361358, 0.59981894, 1.2947721, -1.2500908, 0.6082035, 0.12344158, 0.15808935, -0.17505693, 0.03425684, 0.39107767, 0.23190938, -0.7568858, 0.20042256, 0.079169095, 0.014275463, -0.12135842, 0.008516737, 0.26897284, 0.05706199, -0.52615446, 0.12489152, 0.08065737, -0.038548164, -0.08894516, 7.250979E-4, 0.28635752, -0.010820533, -0.39301336, 0.11144395, 0.06563818, -0.033744805, -0.07450528, -0.027328406, 0.3002447, 0.0029921278, -0.47954947, -0.04527057, -0.010289918, 0.039380465, -0.09236952, -0.1924659, 0.15401903, 0.21237805, -0.38984418, -0.37384143, -0.20648403, 0.29201767, -0.1299253, -0.36048025, -0.5544466, 0.45723814, -0.35266167, -0.94797707, -1.2481197, 0.88701195, 0.33620682, 0.0035414647, -0.22769359, 1.4563162, 0.54950374, 0.38396382, -0.41196275, 0.3758704, 0.17687413, 0.038129736, 0.16358295, 0.70515764, 0.055063568, 0.6445265, -0.2072113, 0.14618243, 0.10311305, 0.1971523, 0.174206, 0.36578146, -0.09782787, 0.5229244, -0.18459272, -0.0013945608, 0.08863555, 0.24184574, 0.15541393, 0.1722381, -0.10531331, 0.38215113, -0.30659106, -0.16298945, 0.11549875, 0.30750987, 0.1586183, -0.017728966, -0.050216004, 0.26232007, -1.2994286, -0.22700997, 0.108534105, 0.7447398, -0.39803517, 0.016863048, 0.10067235, -0.16355589, -0.64953077, -0.5674107, 0.017935256, 0.98968256, -1.395801, 0.44127485, 0.16644385, -0.19195901}; +static const float B1[] = {1.2019119, -1.1770505, 2.1698284, -1.9615222}; + +static const float W[] = {0.55808353, 0.78707385, -0.040990848, -0.122510895, -0.41261443, -0.036044, 0.1691557, -0.14711425, -0.016407091, -0.28058195, 0.018765535, 0.062936015, 0.49562064, 0.33931744, -0.47547337, -0.1405672, -0.88271654, 0.18359914, 0.020887045, -0.13782434, -0.052250575, 0.67922074, -0.28022966, -0.31278887, 0.44416663, -0.26106882, -0.32219923, 1.0321393, -0.1444394, 0.5221766, 0.057590708, -0.96547794, -0.3051688, 0.16859075, -0.5320585, 0.42684716, -0.5434046, 0.014693736, 0.26795483, 0.15921915}; +static const float B[] = {0.041442648, 1.461427, 0.07154641, -1.2774754, 0.80927604, -1.6933714, -0.29740578, -0.11774022, 0.3292682, 0.6596958}; + +// ASCII lib from (https://www.jianshu.com/p/1f58a0ebf5d9) +static const char codeLib[] = "@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. "; +static void print_img(const float * buf) +{ + for(int y = 0; y < 28; y++) + { + for (int x = 0; x < 28; x++) + { + int index = 0; + if(buf[y*28+x] > 0.6f) index =69; + if(index < 0) index = 0; + printf("%c",codeLib[index]); + printf("%c",codeLib[index]); + } + printf("\n"); + } +} + +#endif //__MNIST_H__ diff --git a/components/ai/onnx/operator_int/add.c b/components/ai/onnx/operator_int/add.c new file mode 100644 index 00000000..e69ee173 --- /dev/null +++ b/components/ai/onnx/operator_int/add.c @@ -0,0 +1,35 @@ +#include "onnx.h" + +void add(const int *input, // pointer to vector + const int *bias, // pointer to matrix + const uint16_t dim_vec, // length of the vector + int *output) +{ + for (int i = 0; i < dim_vec; i++) + { + output[i] = input[i] + bias[i]; + } +} + +int* add_layer(Onnx__GraphProto* graph, const int *input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name) +{ + //assert(graph != NULL && input != NULL && layer_name != "" ); + + Onnx__NodeProto* node = onnx_graph_get_node_by_name(graph, layer_name); + const char* bias = node->input[1]; + + int* B = onnx_graph_get_weights_by_name(graph, bias); + int64_t* shapeB = onnx_graph_get_dims_by_name(graph, bias); + if(shapeB == NULL) + { + return NULL; + } + + int* output = (int*) malloc(sizeof(int)*shapeB[0]); + memset(output, 0, sizeof(sizeof(int)*shapeB[0])); + add(input, B, shapeB[0], output); + + memcpy(shapeInput, shapeOutput, sizeof(int64_t)*3); + + return output; +} diff --git a/components/ai/onnx/operator_int/conv2d.c b/components/ai/onnx/operator_int/conv2d.c new file mode 100644 index 00000000..20a817c6 --- /dev/null +++ b/components/ai/onnx/operator_int/conv2d.c @@ -0,0 +1,113 @@ +#include "onnx.h" + +void conv2D(const int *input, // input image + const uint16_t dim_im_in_x, // input image dimention x + const uint16_t dim_im_in_y, // input image dimention y + const uint16_t ch_im_in, // number of input image channels + const int *weight, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel_x, // filter kernel size x + const uint16_t dim_kernel_y, // filter kernel size y + const uint16_t padding_x, // padding sizes x + const uint16_t padding_y, // padding sizes y + const uint16_t stride_x, // stride x + const uint16_t stride_y, // stride y + const int *bias, // bias + int *output, // output image + const uint16_t dim_im_out_x, // output image dimension x + const uint16_t dim_im_out_y // output image dimension y +) +{ + int i, j, k, l, m, n; + int conv_out = 0.0f; + int in_row, in_col; + + // For each filter + for (i = 0; i < ch_im_out; i++) + { + // For each image dimension + for (j = 0; j < dim_im_out_y; j++) + { + for (k = 0; k < dim_im_out_x; k++) + { + conv_out = bias[i]; + // For each kernel dimension + for (m = 0; m < dim_kernel_y; m++) + { + for (n = 0; n < dim_kernel_x; n++) + { + // if-for implementation + in_row = stride_y * j + m - padding_y; + in_col = stride_x * k + n - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + // For each input channel + for (l = 0; l < ch_im_in; l++) + { + conv_out += input[(in_row * dim_im_in_x + in_col) * ch_im_in + l] * + weight[i * ch_im_in * dim_kernel_y * dim_kernel_x + (m * dim_kernel_x + n) * ch_im_in + + l]; + } + } + } + } + output[i + (j * dim_im_out_x + k) * ch_im_out] = conv_out; + } + } + } +} + +int* conv2D_layer(Onnx__GraphProto* graph, const int *input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name) +{ + //assert(graph != NULL && input != NULL && layer_name != "" ); + + Onnx__NodeProto* node = onnx_graph_get_node_by_name(graph, layer_name); + if(node == NULL) + { + // layer not found + return NULL; + } + const char* weight = node->input[1]; + const char* bias = node->input[2]; + + // Get weight shape + int64_t* shapeW = onnx_graph_get_dims_by_name(graph, weight); + if(shapeW == NULL) + { + return NULL; + } + int64_t dimW = onnx_graph_get_dim_by_name(graph, weight); + if(dimW < 0) + { + return NULL; + } + + // Get weights + // NCWH --> NWHC + int64_t permW_t[] = { 0, 2, 3, 1}; + int* W = onnx_graph_get_weights_by_name(graph, weight); + if(W == NULL) + { + return NULL; + } + int* W_t = transpose(W, shapeW, dimW, permW_t); + + // Get bias + int* B = onnx_graph_get_weights_by_name(graph, bias); + if(B == NULL) + { + return NULL; + } + + int* output = (int*) malloc(sizeof(int)*shapeW[0]*shapeInput[W_INDEX]*shapeInput[H_INDEX]); + memset(output, 0, sizeof(sizeof(int)*shapeW[0]*shapeInput[W_INDEX]*shapeInput[H_INDEX])); + conv2D(input, shapeInput[W_INDEX], shapeInput[H_INDEX], shapeW[1], W_t, shapeW[0], shapeW[2], shapeW[3], 1, 1, 1, 1, B, output, shapeInput[W_INDEX], shapeInput[H_INDEX]); + + shapeOutput[W_INDEX] = shapeInput[W_INDEX]; + shapeOutput[H_INDEX] = shapeInput[H_INDEX]; + shapeOutput[C_INDEX] = shapeW[0]; + + free(W_t); + + return output; +} diff --git a/components/ai/onnx/operator_int/dense.c b/components/ai/onnx/operator_int/dense.c new file mode 100644 index 00000000..c3c6cf22 --- /dev/null +++ b/components/ai/onnx/operator_int/dense.c @@ -0,0 +1,19 @@ +#include "onnx.h" + +void dense(const int *input, // pointer to vector + const int *weight, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const int *bias, + int *output) // output operand +{ + for (int i = 0; i < num_of_rows; i++) + { + int ip_out = bias[i]; + for (int j = 0; j < dim_vec; j++) + { + ip_out += input[j] * weight[i * dim_vec + j]; + } + output[i] = ip_out; + } +} diff --git a/components/ai/onnx/operator_int/info.c b/components/ai/onnx/operator_int/info.c new file mode 100644 index 00000000..1537ad8c --- /dev/null +++ b/components/ai/onnx/operator_int/info.c @@ -0,0 +1,25 @@ +#include "onnx.h" + +void onnx_tensor_info(const int* A, int64_t* shape, int64_t dim) +{ + int elem = 1; + for(int i = 0; i < dim; i++) + { + elem = elem * shape[i]; + } + + printf("Array size: %d\n", elem); + for(int i = 0; i < elem; i++) + { + printf( "%f ", A[i] ); + int split = 1; + for(int j = dim-1; j > 0; j--) + { + split = split * shape[j]; + if( (i+1) % split == 0) + { + printf("\n"); + } + } + } +} diff --git a/components/ai/onnx/operator_int/matmul.c b/components/ai/onnx/operator_int/matmul.c new file mode 100644 index 00000000..d6d60c8c --- /dev/null +++ b/components/ai/onnx/operator_int/matmul.c @@ -0,0 +1,63 @@ +#include "onnx.h" + +void matmul(const int *input, // pointer to vector + const int *weight, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + int *output) +{ + for (int i = 0; i < num_of_rows; i++) + { + int ip_out = 0; + for (int j = 0; j < dim_vec; j++) + { + ip_out += input[j] * weight[i * dim_vec + j]; + } + output[i] = ip_out; + } +} + +int* matmul_layer(Onnx__GraphProto* graph, const int *input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name) +{ + //assert(graph != NULL && input != NULL && layer_name != "" ); + + Onnx__NodeProto* node = onnx_graph_get_node_by_name(graph, layer_name); + const char* weight = node->input[1]; + + int64_t* shapeW = onnx_graph_get_dims_by_name(graph, weight); + if(shapeW == NULL) + { + return NULL; + } + int64_t dimW = onnx_graph_get_dim_by_name(graph, weight); + if(dimW < 0) + { + return NULL; + } + + //assert(shapeW[0] == shapeInput[1]); + + int64_t permW_t[] = {1, 0}; + int* W = onnx_graph_get_weights_by_name(graph, weight); + if(W == NULL) + { + return NULL; + } + int* W_t = transpose(W, shapeW, dimW, permW_t); + + int* output = (int*) malloc(sizeof(int)*shapeW[1]); + if(output == NULL) + { + // No memory + return NULL; + } + memset(output, 0, sizeof(sizeof(int)*shapeW[1])); + matmul(input, W_t, shapeW[0], shapeW[1], output); + + shapeOutput[0] = shapeInput[0]; + shapeOutput[1] = shapeW[1]; + + free(W_t); + + return output; +} diff --git a/components/ai/onnx/operator_int/maxpool.c b/components/ai/onnx/operator_int/maxpool.c new file mode 100644 index 00000000..ad9556c4 --- /dev/null +++ b/components/ai/onnx/operator_int/maxpool.c @@ -0,0 +1,96 @@ +#include "onnx.h" + +void maxpool(const int *input, + const uint16_t dim_im_in_x, // input image dimension x or W + const uint16_t dim_im_in_y, // input image dimension y or H + const uint16_t ch_im_in, // number of input image channels + const uint16_t dim_kernel_x, // window kernel size + const uint16_t dim_kernel_y, // window kernel size + const uint16_t padding_x, // padding sizes + const uint16_t padding_y, // padding sizes + const uint16_t stride_x, // stride + const uint16_t stride_y, // stride + const uint16_t dim_im_out_x, // output image dimension x or W + const uint16_t dim_im_out_y, // output image dimension y or H + int *output) +{ + int16_t i_ch_in, i_x, i_y; + int16_t k_x, k_y; + + for (i_ch_in = 0; i_ch_in < ch_im_in; i_ch_in++) + { + for (i_y = 0; i_y < dim_im_out_y; i_y++) + { + for (i_x = 0; i_x < dim_im_out_x; i_x++) + { + //int max = FLT_MIN; + int max = 0; + for (k_y = i_y * stride_y - padding_y; k_y < i_y * stride_y - padding_y + dim_kernel_y; k_y++) + { + for (k_x = i_x * stride_x - padding_x; k_x < i_x * stride_x - padding_x + dim_kernel_x; k_x++) + { + if (k_y >= 0 && k_x >= 0 && k_y < dim_im_in_y && k_x < dim_im_in_x) + { + if (input[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in_x)] > max) + { + max = input[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in_x)]; + } + } + } + } + output[i_ch_in + ch_im_in * (i_x + i_y * dim_im_out_x)] = max; + } + } + } +} + +int* maxpool_layer(Onnx__GraphProto* graph, int* input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name) +{ + //assert(graph != NULL && input != NULL && layer_name != "" ); + + Onnx__NodeProto* node = onnx_graph_get_node_by_name(graph, layer_name); + if(node == NULL) + { + // layer not found + return NULL; + } + + uint16_t kernel_x = 1; + uint16_t kernel_y = 1; + uint16_t padding_x = 0; + uint16_t padding_y = 0; + uint16_t stride_x = 1; + uint16_t stride_y = 1; + + for(int i = 0; i < node->n_attribute; i++) + { + if( strcmp(node->attribute[i]->name, "kernel_shape") == 0 ) + { + kernel_x = node->attribute[i]->ints[0]; + kernel_y = node->attribute[i]->ints[1]; + } + if( strcmp(node->attribute[i]->name, "strides") == 0 ) + { + stride_x = node->attribute[i]->ints[0]; + stride_y = node->attribute[i]->ints[1]; + } + } + + uint16_t out_x = (shapeInput[W_INDEX] - kernel_x + 2 * padding_x) / stride_x + 1; + uint16_t out_y = (shapeInput[H_INDEX] - kernel_y + 2 * padding_y) / stride_y + 1; + + int* output = (int*) malloc(sizeof(int)*out_x*out_y*shapeInput[C_INDEX]); + if(output == NULL) + { + // No memory + return NULL; + } + memset(output, 0, sizeof(sizeof(int)*out_x*out_y*shapeInput[C_INDEX])); + maxpool(input, shapeInput[W_INDEX], shapeInput[H_INDEX], shapeInput[C_INDEX], kernel_x, kernel_y, padding_x, padding_y, stride_x, stride_y, out_x, out_y, output); + + shapeOutput[W_INDEX] = out_x; + shapeOutput[H_INDEX] = out_y; + shapeOutput[C_INDEX] = shapeInput[C_INDEX]; + + return output; +} diff --git a/components/ai/onnx/operator_int/model.c b/components/ai/onnx/operator_int/model.c new file mode 100644 index 00000000..a36d7466 --- /dev/null +++ b/components/ai/onnx/operator_int/model.c @@ -0,0 +1,84 @@ +#include +#include "onnx.h" + +int* onnx_model_run(Onnx__ModelProto* model, int* input, int64_t* shapeInput) +{ + int64_t* shapeOutput = (int64_t*) malloc(sizeof(int64_t)*3); + shapeOutput[0] = -1; shapeOutput[1] = -1; shapeOutput[2] = -1; + + Onnx__NodeProto* node = onnx_graph_get_node_by_input(model->graph, model->graph->input[0]->name); + + int i = 0; + int* output; + while(node != NULL) + { + printf("[%2d] %-10s %-20s ", i++, node->op_type, node->name); + if(strcmp(node->op_type, "Conv") == 0) + { + output = conv2D_layer(model->graph, input, shapeInput, shapeOutput, node->name); + } + else if(strcmp(node->op_type, "Relu") == 0) + { + output = relu_layer(model->graph, input, shapeInput, shapeOutput, node->name); + } + else if(strcmp(node->op_type, "MaxPool") == 0) + { + output = maxpool_layer(model->graph, input, shapeInput, shapeOutput, node->name); + } + else if(strcmp(node->op_type, "Softmax") == 0) + { + output = softmax_layer(model->graph, input, shapeInput, shapeOutput, node->name); + } + else if(strcmp(node->op_type, "MatMul") == 0) + { + output = matmul_layer(model->graph, input, shapeInput, shapeOutput, node->name); + } + else if(strcmp(node->op_type, "Add") == 0) + { + output = add_layer(model->graph, input, shapeInput, shapeOutput, node->name); + } + else if(strcmp(node->op_type, "Identity") == 0) + { + node = onnx_graph_get_node_by_input(model->graph, node->output[0]); + printf("\n"); + + continue; + } + else if(strcmp(node->op_type, "Transpose") == 0) + { + node = onnx_graph_get_node_by_input(model->graph, node->output[0]); + printf("\n"); + + continue; + } + else if(strcmp(node->op_type, "Reshape") == 0) + { + shapeOutput[1] = shapeOutput[0] * shapeOutput[1] * shapeOutput[2]; + shapeOutput[2] = 1; + shapeOutput[0] = 1; + printf("[%2" PRId64 ", %2" PRId64 ", %2" PRId64 "] --> [%2" PRId64 ", %2" PRId64 ", %2" PRId64 "]\n", shapeInput[0], shapeInput[1], shapeInput[2], shapeOutput[0], shapeOutput[1], shapeOutput[2]); + + // free(input); + // input = output; + memcpy(shapeInput, shapeOutput, sizeof(int64_t)*3); + + node = onnx_graph_get_node_by_input(model->graph, node->output[0]); + continue; + } + else + { + printf("Unsupported operand: %s\n", node->op_type); + } + printf("[%2" PRId64 ", %2" PRId64 ", %2" PRId64 "] --> [%2" PRId64 ", %2" PRId64 ", %2" PRId64 "]\n", shapeInput[0], shapeInput[1], shapeInput[2], shapeOutput[0], shapeOutput[1], shapeOutput[2]); + + free(input); + input = output; + memcpy(shapeInput, shapeOutput, sizeof(int64_t)*3); + + node = onnx_graph_get_node_by_input(model->graph, node->output[0]); + } + output = input; + free(shapeOutput); + + return output; +} diff --git a/components/ai/onnx/operator_int/onnx-parser.c b/components/ai/onnx/operator_int/onnx-parser.c new file mode 100644 index 00000000..91ffbc8c --- /dev/null +++ b/components/ai/onnx/operator_int/onnx-parser.c @@ -0,0 +1,284 @@ +#include "onnx-parser.h" + +const char* onnx_tensor_proto_data_type[] = { + "Undefined", + "FLOAT", + "UINT8", + "INT8", + "UINT16", + "INT16", + "INT32", + "INT64", + "STRING", + "BOOL", + "FLOAT16", + "DOUBLE", + "UINT32", + "UINT64", + "COMPLEX64", + "COMPLEX128" +}; +/* +Onnx__ModelProto* onnx_load_model(const char* onnx_file_name) +{ + unsigned char* buffer; + FILE *fp; + + // Get File Size + fp = fopen(onnx_file_name,"rb"); + fseek(fp, 0L, SEEK_END); + int sz = ftell(fp); + fseek(fp, 0L, SEEK_SET); + // printf("File size %s is %d\n", onnx_file_name, sz); + + // Read File + buffer = (unsigned char*) malloc(sizeof(unsigned char) * sz); + if(buffer == NULL) + { + printf("Failed to malloc %d bytes memory for %s\n", sz, onnx_file_name); + return NULL; + } + fread(buffer, sz, 1, fp); + + Onnx__ModelProto* model = onnx__model_proto__unpack(NULL, sz, buffer); + free(buffer); + fclose(fp); + + return model; +} +*/ +void onnx_model_info(Onnx__ModelProto* model) +{ + printf("---- Model info ----\n"); + printf("IR Version is %ld\n", model->ir_version); + printf("Produceer name is %s\n", model->producer_name); + printf("Produceer version is %s\n", model->producer_version); + printf("Produceer version is %s\n", model->domain); +} + +void onnx_graph_info(Onnx__GraphProto* graph) +{ + printf("---- Graph Info ----\n"); + + // Input + printf("---- Graph Input Info ----\n"); + printf("Graph inputs number: %ld\n", graph->n_input); + for(int i = 0; i < graph->n_input; i++) + { + onnx_graph_input_info(graph->input[i]); + } + + // Output + printf("---- Graph Output Info ----\n"); + printf("Graph outputs number: %ld\n", graph->n_output); + for(int i = 0; i < graph->n_output; i++) + { + onnx_graph_output_info(graph->output[i]); + } + + // Nodes + printf("---- Graph Node Info ----\n"); + printf("Graph nodes number: %ld\n", graph->n_node); + for(int i = 0; i < graph->n_node; i++) + { + onnx_graph_node_info(graph->node[i]); + } +} + +void onnx_graph_info_sorted(Onnx__GraphProto* graph) +{ + printf("---- Graph Info ----\n"); + + // Input + printf("---- Graph Input Info ----\n"); + printf("Graph inputs number: %ld\n", graph->n_input); + for(int i = 0; i < graph->n_input; i++) + { + onnx_graph_input_info(graph->input[i]); + } + + // Output + printf("---- Graph Output Info ----\n"); + printf("Graph outputs number: %ld\n", graph->n_output); + for(int i = 0; i < graph->n_output; i++) + { + onnx_graph_output_info(graph->output[i]); + } + + // Nodes + printf("---- Graph Node Info ----\n"); + printf("Graph nodes number: %ld\n", graph->n_node); + Onnx__NodeProto* node = onnx_graph_get_node_by_input(graph, graph->input[0]->name); + + while(node != NULL) + { + onnx_graph_node_info(node); + node = onnx_graph_get_node_by_input(graph, node->output[0]); + } + +} + +void onnx_graph_input_info(Onnx__ValueInfoProto* input) +{ + printf("Input name %s\n", input->name); + + Onnx__TypeProto* type = input->type; + Onnx__TypeProto__Tensor* tensor_type = type->tensor_type; + Onnx__TensorShapeProto* shape = tensor_type->shape; + + printf("Input type %s\n", onnx_tensor_proto_data_type[tensor_type->elem_type]); + printf("Input dimension %ld\n", shape->n_dim); + + for(int i = 0; i < shape->n_dim; i++) + { + onnx_graph_value_tensor_shape_dimension_info(shape->dim[i]); + if( i != shape->n_dim - 1) + { + printf(" x "); + } + } + printf("\n"); +} + +void onnx_graph_value_tensor_shape_dimension_info(Onnx__TensorShapeProto__Dimension* dim) +{ + + switch (dim->value_case) + { + case ONNX__TENSOR_SHAPE_PROTO__DIMENSION__VALUE__NOT_SET: + printf("?"); + break; + case ONNX__TENSOR_SHAPE_PROTO__DIMENSION__VALUE_DIM_VALUE: + printf("%ld",dim->dim_value); + break; + case ONNX__TENSOR_SHAPE_PROTO__DIMENSION__VALUE_DIM_PARAM: + printf("%s",dim->dim_param); + break; + default: + printf("?"); + break; + } +} + +void onnx_graph_output_info(Onnx__ValueInfoProto* output) +{ + printf("Output name %s\n", output->name); + + Onnx__TypeProto* type = output->type; + Onnx__TypeProto__Tensor* tensor_type = type->tensor_type; + Onnx__TensorShapeProto* shape = tensor_type->shape; + + printf("Output type %s\n", onnx_tensor_proto_data_type[tensor_type->elem_type]); + printf("Output dimension %ld\n", shape->n_dim); + + for(int i = 0; i < shape->n_dim; i++) + { + onnx_graph_value_tensor_shape_dimension_info(shape->dim[i]); + if( i != shape->n_dim - 1) + { + printf(" x "); + } + } + printf("\n"); +} + +void onnx_graph_initializer_info(Onnx__TensorProto* initializer) +{ + printf("%s: [", initializer->name); + for(int i = 0; i < initializer->n_dims; i++) + { + printf("%ld, ", initializer->dims[i]); + } + printf("]\n"); + + printf("%s: [", initializer->name); + for(int i = 0; i < initializer->n_float_data; i++) + { + printf("%f, ", initializer->float_data[i]); + } + printf("]\n"); +} + +Onnx__NodeProto* onnx_graph_get_node_by_name(Onnx__GraphProto* graph, const char* node_name) +{ + for(int i = 0; i < graph->n_node; i++) + { + Onnx__NodeProto* node = graph->node[i]; + for(int j = 0; j < node->n_input; j++) + { + if( strcmp(node->name, node_name) == 0) + { + return node; + } + } + } + + return NULL; +} + +Onnx__NodeProto* onnx_graph_get_node_by_input(Onnx__GraphProto* graph, const char* input_name) +{ + for(int i = 0; i < graph->n_node; i++) + { + Onnx__NodeProto* node = graph->node[i]; + for(int j = 0; j < node->n_input; j++) + { + if( strcmp(node->input[j], input_name) == 0) + { + return node; + } + } + } + + return NULL; +} + +int* onnx_graph_get_weights_by_name(Onnx__GraphProto* graph, const char* node_name) +{ + Onnx__TensorProto** initializer = graph->initializer; + + for(int i = 0; i < graph->n_initializer; i++) + { + if( strcmp(graph->initializer[i]->name, node_name) == 0) + { + return graph->initializer[i]->float_data; + } + } + + return NULL; +} + +long* onnx_graph_get_dims_by_name(Onnx__GraphProto* graph, const char* node_name) +{ + Onnx__TensorProto** initializer = graph->initializer; + + for(int i = 0; i < graph->n_initializer; i++) + { + if( strcmp(graph->initializer[i]->name, node_name) == 0) + { + return graph->initializer[i]->dims; + } + } + + return NULL; +} + +long onnx_graph_get_dim_by_name(Onnx__GraphProto* graph, const char* node_name) +{ + Onnx__TensorProto** initializer = graph->initializer; + + for(int i = 0; i < graph->n_initializer; i++) + { + if( strcmp(graph->initializer[i]->name, node_name) == 0) + { + return graph->initializer[i]->n_dims; + } + } + + return -1; +} + +void onnx_graph_node_info(Onnx__NodeProto* node) +{ + printf("%-12s: %-30s -> %-30s [%s]\n", node->op_type, node->input[0], node->output[0], node->name); +} diff --git a/components/ai/onnx/operator_int/onnx-parser.h b/components/ai/onnx/operator_int/onnx-parser.h new file mode 100644 index 00000000..2399978b --- /dev/null +++ b/components/ai/onnx/operator_int/onnx-parser.h @@ -0,0 +1,27 @@ +#ifndef __ONNX_PARSER_H__ +#define __ONNX_PARSER_H__ + +#include +#include +#include + +#include "onnx.pb-c.h" + +Onnx__ModelProto* onnx_load_model(const char* onnx_file_name); +void onnx_model_info(Onnx__ModelProto* model); +void onnx_graph_info(Onnx__GraphProto* graph); +void onnx_graph_info_sorted(Onnx__GraphProto* graph); +void onnx_graph_input_info(Onnx__ValueInfoProto* input); +void onnx_graph_output_info(Onnx__ValueInfoProto* output); +void onnx_graph_node_info(Onnx__NodeProto* node); +void onnx_graph_initializer_info(Onnx__TensorProto* initializer); + +Onnx__NodeProto* onnx_graph_get_node_by_name(Onnx__GraphProto* graph, const char* node_name); +Onnx__NodeProto* onnx_graph_get_node_by_input(Onnx__GraphProto* graph, const char* input_name); +long* onnx_graph_get_dims_by_name(Onnx__GraphProto* graph, const char* node_name); +long onnx_graph_get_dim_by_name(Onnx__GraphProto* graph, const char* node_name); +int* onnx_graph_get_weights_by_name(Onnx__GraphProto* graph, const char* node_name); + +void onnx_graph_value_tensor_shape_dimension_info(Onnx__TensorShapeProto__Dimension* dim); + +#endif //__ONNX_PARSER_H__ diff --git a/components/ai/onnx/operator_int/onnx.h b/components/ai/onnx/operator_int/onnx.h new file mode 100644 index 00000000..80b2c493 --- /dev/null +++ b/components/ai/onnx/operator_int/onnx.h @@ -0,0 +1,95 @@ +#ifndef __ONNX_H__ +#define __ONNX_H__ + +#include +#include +#include +//#include +#include + +#include + +#define ONNX_USE_NWHC + +#ifdef ONNX_USE_NWHC + // NWHC + #define W_INDEX 0 + #define H_INDEX 1 + #define C_INDEX 2 +#else + // NCWH + #define C_INDEX 0 + #define W_INDEX 1 + #define H_INDEX 2 +#endif + +// Model +void onnx_tensor_info(const int* A, int64_t* shape, int64_t dim); +int* onnx_model_run(Onnx__ModelProto* model, int* input, int64_t* shapeInput); + +// Layers +int* conv2D_layer(Onnx__GraphProto* graph, const int *input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name); +int* relu_layer(Onnx__GraphProto* graph, const int *input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name); +int* maxpool_layer(Onnx__GraphProto* graph, int* input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name); +int* matmul_layer(Onnx__GraphProto* graph, const int *input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name); +int* add_layer(Onnx__GraphProto* graph, const int *input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name); +int* softmax_layer(Onnx__GraphProto* graph, const int *input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name); + +// Operators +int* transpose(const int* A, int64_t* shape, int64_t dim, int64_t* perm); + +void conv2D(const int *input, // input image + const uint16_t dim_im_in_x, // input image dimention x + const uint16_t dim_im_in_y, // input image dimention y + const uint16_t ch_im_in, // number of input image channels + const int *weight, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel_x, // filter kernel size x + const uint16_t dim_kernel_y, // filter kernel size y + const uint16_t padding_x, // padding sizes x + const uint16_t padding_y, // padding sizes y + const uint16_t stride_x, // stride x + const uint16_t stride_y, // stride y + const int *bias, // bias + int *output, // output image + const uint16_t dim_im_out_x, // output image dimension x + const uint16_t dim_im_out_y // output image dimension y +); + +void relu(const int *input, uint32_t size, int* output); + +void maxpool(const int *input, + const uint16_t dim_im_in_x, // input image dimension x or W + const uint16_t dim_im_in_y, // input image dimension y or H + const uint16_t ch_im_in, // number of input image channels + const uint16_t dim_kernel_x, // window kernel size + const uint16_t dim_kernel_y, // window kernel size + const uint16_t padding_x, // padding sizes + const uint16_t padding_y, // padding sizes + const uint16_t stride_x, // stride + const uint16_t stride_y, // stride + const uint16_t dim_im_out_x, // output image dimension x or W + const uint16_t dim_im_out_y, // output image dimension y or H + int *output); + +void matmul(const int *input, // pointer to vector + const int *weight, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + int *output); + +void add(const int *input, // pointer to vector + const int *bias, // pointer to matrix + const uint16_t dim_vec, // length of the vector + int *output); + +void dense(const int *input, // pointer to vector + const int *weight, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const int *bias, + int *output); + +void softmax(const int *input, const uint32_t dim_vec, int *output); + +#endif // __ONNX_H__ diff --git a/components/ai/onnx/operator_int/relu.c b/components/ai/onnx/operator_int/relu.c new file mode 100644 index 00000000..1c800a39 --- /dev/null +++ b/components/ai/onnx/operator_int/relu.c @@ -0,0 +1,27 @@ +#include "onnx.h" + +void relu(const int *input, uint32_t size, int* output) +{ + uint32_t i; + memcpy(output, input, sizeof(int) * size); + for (i = 0; i < size; i++) + { + if (output[i] < 0) + output[i] = 0; + } +} + +int* relu_layer(Onnx__GraphProto* graph, const int *input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name) +{ + //assert(graph != NULL && input != NULL && layer_name != "" ); + + int64_t len = shapeInput[0] * shapeInput[1] * shapeInput[2]; + int* output = (int*) malloc(sizeof(int)*len); + memset(output, 0, sizeof(sizeof(int)*len)); + + relu(input, len, output); + + memcpy(shapeInput, shapeOutput, sizeof(int64_t)*3); + + return output; +} diff --git a/components/ai/onnx/operator_int/softmax.c b/components/ai/onnx/operator_int/softmax.c new file mode 100644 index 00000000..aa9b63b4 --- /dev/null +++ b/components/ai/onnx/operator_int/softmax.c @@ -0,0 +1,57 @@ +#include "onnx.h" +//#include + + +int abs_core(int x) +{ + return x > 0?x:-x; +} + +int exp_core(int x) +{ + x = 1 + (x << 8); + + x *= x; x *= x; x *= x; x *= x; + + x *= x; x *= x; x *= x; x *= x; + + return x; + +} + +void softmax(const int *input, const uint32_t dim_vec, int *output) +{ + long long sum = 0; + + for(int i = 0; i < dim_vec; i++) + { + output[i] = input[i] >> 16; + } + + /* + for(int i = 0; i < dim_vec; i++) + { + output[i] = abs_core(input[i] >> 16); + sum = sum + (output[i]); + } + printf("sum = %ld\r\n" , sum); + for(int i = 0; i < dim_vec; i++) + { + //output[i] = output[i] / (sum); + output[i] = sum / output[i]; + //output[i] = output[i]; + }*/ +} + +int* softmax_layer(Onnx__GraphProto* graph, const int *input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name) +{ + //assert(graph != NULL && input != NULL && layer_name != "" && shapeInput[1] > 0); + + int* output = (int*) malloc(sizeof(int)*shapeInput[1]); + memset(output, 0, sizeof(sizeof(int)*shapeInput[1])); + softmax(input, shapeInput[1], output); + + memcpy(shapeInput, shapeOutput, sizeof(int64_t)*3); + + return output; +} diff --git a/components/ai/onnx/operator_int/tencentos_libc.c b/components/ai/onnx/operator_int/tencentos_libc.c new file mode 100644 index 00000000..07ac206e --- /dev/null +++ b/components/ai/onnx/operator_int/tencentos_libc.c @@ -0,0 +1,26 @@ +#include "tos_k.h" + +#ifdef __CC_ARM +/* avoid the heap and heap-using library functions supplied by arm */ +#pragma import(__use_no_heap) +#endif + +void *malloc(size_t n) +{ + return tos_mmheap_alloc(n); +} + +void *realloc(void *rmem, size_t newsize) +{ + return tos_mmheap_realloc(rmem, newsize); +} + +void *calloc(size_t nelem, size_t elsize) +{ + return tos_mmheap_calloc(nelem, elsize); +} + +void free(void *rmem) +{ + tos_mmheap_free(rmem); +} \ No newline at end of file diff --git a/components/ai/onnx/operator_int/transpose.c b/components/ai/onnx/operator_int/transpose.c new file mode 100644 index 00000000..b2a8ea87 --- /dev/null +++ b/components/ai/onnx/operator_int/transpose.c @@ -0,0 +1,97 @@ +#include "onnx.h" + +int* transpose(const int* A, int64_t* shape, int64_t dim, int64_t* perm) +{ + // Get array size + int elem = 1; + for(int i = 0; i < dim; i++) + { + elem = elem * shape[i]; + } + + // Malloc memory for B + int* B = malloc(sizeof(int) * elem); + if(B == NULL) + { + return NULL; + } + // Malloc memory for shapeB + int* shapeB = malloc(sizeof(int) * dim); + if( shapeB == NULL) + { + return NULL; + } + for(int i = 0; i < dim; i++) + { + shapeB[i] = shape[perm[i]]; + } + // Transpose + for(int src = 0; src < elem; src++) + { + // Get transposed B array + // A[1][0][3] -> B[3][1][0] + int temp = src; + int* indexA = malloc(sizeof(int) * dim); + if(indexA == NULL) + { + return NULL; + } + int* indexB = malloc(sizeof(int) * dim); + if(indexB == NULL) + { + return NULL; + } + for(int i = dim-1; i >= 0; i--) + { + indexA[i] = temp % shape[i]; + temp = temp / shape[i]; + } + for(int i = 0; i < dim; i++) + { + indexB[i] = indexA[perm[i]]; + } + + // Get transposed B index + // #15 A[1][0][3] -> B[3][1][0] #21 + int dst = 0; + temp = 1; + for(int i = dim - 1; i >= 0; i--) + { + dst = dst + indexB[i] * temp; + temp = temp * shapeB[i]; + } + + B[dst] = A[src]; + + free(indexA); + free(indexB); + } + + free(shapeB); + return B; +} + +int* transpose_layer(Onnx__GraphProto* graph, const int *input, int64_t* shapeInput, int64_t* shapeOutput, const char* layer_name) +{ + //assert(graph != NULL && input != NULL && layer_name != "" ); + + Onnx__NodeProto* node = onnx_graph_get_node_by_name(graph, layer_name); + if(node == NULL) + { + return NULL; + } + + int64_t perm_t[3]; + int64_t* perm = node->attribute[0]->ints; + perm_t[0] = perm[1] - 1; + perm_t[1] = perm[2] - 1; + perm_t[2] = perm[3] - 1; + + int* output = transpose(input, shapeInput, 3, perm_t); + + shapeOutput[0] = shapeInput[perm_t[0]]; + shapeOutput[1] = shapeInput[perm_t[1]]; + shapeOutput[2] = shapeInput[perm_t[2]]; + + return output; +} diff --git a/components/ai/onnx/platflorm/imx6ull/tencentos_libc_malloc.c b/components/ai/onnx/platflorm/imx6ull/tencentos_libc_malloc.c new file mode 100644 index 00000000..07ac206e --- /dev/null +++ b/components/ai/onnx/platflorm/imx6ull/tencentos_libc_malloc.c @@ -0,0 +1,26 @@ +#include "tos_k.h" + +#ifdef __CC_ARM +/* avoid the heap and heap-using library functions supplied by arm */ +#pragma import(__use_no_heap) +#endif + +void *malloc(size_t n) +{ + return tos_mmheap_alloc(n); +} + +void *realloc(void *rmem, size_t newsize) +{ + return tos_mmheap_realloc(rmem, newsize); +} + +void *calloc(size_t nelem, size_t elsize) +{ + return tos_mmheap_calloc(nelem, elsize); +} + +void free(void *rmem) +{ + tos_mmheap_free(rmem); +} \ No newline at end of file diff --git a/components/ai/onnx/protobuf/onnx.pb-c.c b/components/ai/onnx/protobuf/onnx.pb-c.c new file mode 100644 index 00000000..c727de72 --- /dev/null +++ b/components/ai/onnx/protobuf/onnx.pb-c.c @@ -0,0 +1,1780 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: src/onnx.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "onnx.pb-c.h" +void onnx__attribute_proto__init + (Onnx__AttributeProto *message) +{ + static Onnx__AttributeProto init_value = ONNX__ATTRIBUTE_PROTO__INIT; + *message = init_value; +} +size_t onnx__attribute_proto__get_packed_size + (const Onnx__AttributeProto *message) +{ + ////assert(message->base.descriptor == &onnx__attribute_proto__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t onnx__attribute_proto__pack + (const Onnx__AttributeProto *message, + uint8_t *out) +{ + ////assert(message->base.descriptor == &onnx__attribute_proto__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t onnx__attribute_proto__pack_to_buffer + (const Onnx__AttributeProto *message, + ProtobufCBuffer *buffer) +{ + ////assert(message->base.descriptor == &onnx__attribute_proto__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Onnx__AttributeProto * + onnx__attribute_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Onnx__AttributeProto *) + protobuf_c_message_unpack (&onnx__attribute_proto__descriptor, + allocator, len, data); +} +void onnx__attribute_proto__free_unpacked + (Onnx__AttributeProto *message, + ProtobufCAllocator *allocator) +{ + ////assert(message->base.descriptor == &onnx__attribute_proto__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void onnx__value_info_proto__init + (Onnx__ValueInfoProto *message) +{ + static Onnx__ValueInfoProto init_value = ONNX__VALUE_INFO_PROTO__INIT; + *message = init_value; +} +size_t onnx__value_info_proto__get_packed_size + (const Onnx__ValueInfoProto *message) +{ + ////assert(message->base.descriptor == &onnx__value_info_proto__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t onnx__value_info_proto__pack + (const Onnx__ValueInfoProto *message, + uint8_t *out) +{ + ////assert(message->base.descriptor == &onnx__value_info_proto__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t onnx__value_info_proto__pack_to_buffer + (const Onnx__ValueInfoProto *message, + ProtobufCBuffer *buffer) +{ + ////assert(message->base.descriptor == &onnx__value_info_proto__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Onnx__ValueInfoProto * + onnx__value_info_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Onnx__ValueInfoProto *) + protobuf_c_message_unpack (&onnx__value_info_proto__descriptor, + allocator, len, data); +} +void onnx__value_info_proto__free_unpacked + (Onnx__ValueInfoProto *message, + ProtobufCAllocator *allocator) +{ + ////assert(message->base.descriptor == &onnx__value_info_proto__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void onnx__node_proto__init + (Onnx__NodeProto *message) +{ + static Onnx__NodeProto init_value = ONNX__NODE_PROTO__INIT; + *message = init_value; +} +size_t onnx__node_proto__get_packed_size + (const Onnx__NodeProto *message) +{ + ////assert(message->base.descriptor == &onnx__node_proto__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t onnx__node_proto__pack + (const Onnx__NodeProto *message, + uint8_t *out) +{ + ////assert(message->base.descriptor == &onnx__node_proto__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t onnx__node_proto__pack_to_buffer + (const Onnx__NodeProto *message, + ProtobufCBuffer *buffer) +{ + ////assert(message->base.descriptor == &onnx__node_proto__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Onnx__NodeProto * + onnx__node_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Onnx__NodeProto *) + protobuf_c_message_unpack (&onnx__node_proto__descriptor, + allocator, len, data); +} +void onnx__node_proto__free_unpacked + (Onnx__NodeProto *message, + ProtobufCAllocator *allocator) +{ + ////assert(message->base.descriptor == &onnx__node_proto__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void onnx__model_proto__init + (Onnx__ModelProto *message) +{ + static Onnx__ModelProto init_value = ONNX__MODEL_PROTO__INIT; + *message = init_value; +} +size_t onnx__model_proto__get_packed_size + (const Onnx__ModelProto *message) +{ + ////assert(message->base.descriptor == &onnx__model_proto__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t onnx__model_proto__pack + (const Onnx__ModelProto *message, + uint8_t *out) +{ + ////assert(message->base.descriptor == &onnx__model_proto__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t onnx__model_proto__pack_to_buffer + (const Onnx__ModelProto *message, + ProtobufCBuffer *buffer) +{ + ////assert(message->base.descriptor == &onnx__model_proto__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Onnx__ModelProto * + onnx__model_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Onnx__ModelProto *) + protobuf_c_message_unpack (&onnx__model_proto__descriptor, + allocator, len, data); +} +void onnx__model_proto__free_unpacked + (Onnx__ModelProto *message, + ProtobufCAllocator *allocator) +{ + ////assert(message->base.descriptor == &onnx__model_proto__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void onnx__string_string_entry_proto__init + (Onnx__StringStringEntryProto *message) +{ + static Onnx__StringStringEntryProto init_value = ONNX__STRING_STRING_ENTRY_PROTO__INIT; + *message = init_value; +} +size_t onnx__string_string_entry_proto__get_packed_size + (const Onnx__StringStringEntryProto *message) +{ + ////assert(message->base.descriptor == &onnx__string_string_entry_proto__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t onnx__string_string_entry_proto__pack + (const Onnx__StringStringEntryProto *message, + uint8_t *out) +{ + ////assert(message->base.descriptor == &onnx__string_string_entry_proto__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t onnx__string_string_entry_proto__pack_to_buffer + (const Onnx__StringStringEntryProto *message, + ProtobufCBuffer *buffer) +{ + ////assert(message->base.descriptor == &onnx__string_string_entry_proto__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Onnx__StringStringEntryProto * + onnx__string_string_entry_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Onnx__StringStringEntryProto *) + protobuf_c_message_unpack (&onnx__string_string_entry_proto__descriptor, + allocator, len, data); +} +void onnx__string_string_entry_proto__free_unpacked + (Onnx__StringStringEntryProto *message, + ProtobufCAllocator *allocator) +{ + ////assert(message->base.descriptor == &onnx__string_string_entry_proto__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void onnx__graph_proto__init + (Onnx__GraphProto *message) +{ + static Onnx__GraphProto init_value = ONNX__GRAPH_PROTO__INIT; + *message = init_value; +} +size_t onnx__graph_proto__get_packed_size + (const Onnx__GraphProto *message) +{ + ////assert(message->base.descriptor == &onnx__graph_proto__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t onnx__graph_proto__pack + (const Onnx__GraphProto *message, + uint8_t *out) +{ + ////assert(message->base.descriptor == &onnx__graph_proto__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t onnx__graph_proto__pack_to_buffer + (const Onnx__GraphProto *message, + ProtobufCBuffer *buffer) +{ + ////assert(message->base.descriptor == &onnx__graph_proto__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Onnx__GraphProto * + onnx__graph_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Onnx__GraphProto *) + protobuf_c_message_unpack (&onnx__graph_proto__descriptor, + allocator, len, data); +} +void onnx__graph_proto__free_unpacked + (Onnx__GraphProto *message, + ProtobufCAllocator *allocator) +{ + ////assert(message->base.descriptor == &onnx__graph_proto__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void onnx__tensor_proto__segment__init + (Onnx__TensorProto__Segment *message) +{ + static Onnx__TensorProto__Segment init_value = ONNX__TENSOR_PROTO__SEGMENT__INIT; + *message = init_value; +} +void onnx__tensor_proto__init + (Onnx__TensorProto *message) +{ + static Onnx__TensorProto init_value = ONNX__TENSOR_PROTO__INIT; + *message = init_value; +} +size_t onnx__tensor_proto__get_packed_size + (const Onnx__TensorProto *message) +{ + ////assert(message->base.descriptor == &onnx__tensor_proto__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t onnx__tensor_proto__pack + (const Onnx__TensorProto *message, + uint8_t *out) +{ + ////assert(message->base.descriptor == &onnx__tensor_proto__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t onnx__tensor_proto__pack_to_buffer + (const Onnx__TensorProto *message, + ProtobufCBuffer *buffer) +{ + ////assert(message->base.descriptor == &onnx__tensor_proto__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Onnx__TensorProto * + onnx__tensor_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Onnx__TensorProto *) + protobuf_c_message_unpack (&onnx__tensor_proto__descriptor, + allocator, len, data); +} +void onnx__tensor_proto__free_unpacked + (Onnx__TensorProto *message, + ProtobufCAllocator *allocator) +{ + ////assert(message->base.descriptor == &onnx__tensor_proto__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void onnx__tensor_shape_proto__dimension__init + (Onnx__TensorShapeProto__Dimension *message) +{ + static Onnx__TensorShapeProto__Dimension init_value = ONNX__TENSOR_SHAPE_PROTO__DIMENSION__INIT; + *message = init_value; +} +void onnx__tensor_shape_proto__init + (Onnx__TensorShapeProto *message) +{ + static Onnx__TensorShapeProto init_value = ONNX__TENSOR_SHAPE_PROTO__INIT; + *message = init_value; +} +size_t onnx__tensor_shape_proto__get_packed_size + (const Onnx__TensorShapeProto *message) +{ + ////assert(message->base.descriptor == &onnx__tensor_shape_proto__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t onnx__tensor_shape_proto__pack + (const Onnx__TensorShapeProto *message, + uint8_t *out) +{ + ////assert(message->base.descriptor == &onnx__tensor_shape_proto__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t onnx__tensor_shape_proto__pack_to_buffer + (const Onnx__TensorShapeProto *message, + ProtobufCBuffer *buffer) +{ + ////assert(message->base.descriptor == &onnx__tensor_shape_proto__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Onnx__TensorShapeProto * + onnx__tensor_shape_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Onnx__TensorShapeProto *) + protobuf_c_message_unpack (&onnx__tensor_shape_proto__descriptor, + allocator, len, data); +} +void onnx__tensor_shape_proto__free_unpacked + (Onnx__TensorShapeProto *message, + ProtobufCAllocator *allocator) +{ + ////assert(message->base.descriptor == &onnx__tensor_shape_proto__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void onnx__type_proto__tensor__init + (Onnx__TypeProto__Tensor *message) +{ + static Onnx__TypeProto__Tensor init_value = ONNX__TYPE_PROTO__TENSOR__INIT; + *message = init_value; +} +void onnx__type_proto__init + (Onnx__TypeProto *message) +{ + static Onnx__TypeProto init_value = ONNX__TYPE_PROTO__INIT; + *message = init_value; +} +size_t onnx__type_proto__get_packed_size + (const Onnx__TypeProto *message) +{ + ////assert(message->base.descriptor == &onnx__type_proto__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t onnx__type_proto__pack + (const Onnx__TypeProto *message, + uint8_t *out) +{ + ////assert(message->base.descriptor == &onnx__type_proto__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t onnx__type_proto__pack_to_buffer + (const Onnx__TypeProto *message, + ProtobufCBuffer *buffer) +{ + ////assert(message->base.descriptor == &onnx__type_proto__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Onnx__TypeProto * + onnx__type_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Onnx__TypeProto *) + protobuf_c_message_unpack (&onnx__type_proto__descriptor, + allocator, len, data); +} +void onnx__type_proto__free_unpacked + (Onnx__TypeProto *message, + ProtobufCAllocator *allocator) +{ + ////assert(message->base.descriptor == &onnx__type_proto__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void onnx__operator_set_id_proto__init + (Onnx__OperatorSetIdProto *message) +{ + static Onnx__OperatorSetIdProto init_value = ONNX__OPERATOR_SET_ID_PROTO__INIT; + *message = init_value; +} +size_t onnx__operator_set_id_proto__get_packed_size + (const Onnx__OperatorSetIdProto *message) +{ + ////assert(message->base.descriptor == &onnx__operator_set_id_proto__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t onnx__operator_set_id_proto__pack + (const Onnx__OperatorSetIdProto *message, + uint8_t *out) +{ + //////assert(message->base.descriptor == &onnx__operator_set_id_proto__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t onnx__operator_set_id_proto__pack_to_buffer + (const Onnx__OperatorSetIdProto *message, + ProtobufCBuffer *buffer) +{ + ////assert(message->base.descriptor == &onnx__operator_set_id_proto__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Onnx__OperatorSetIdProto * + onnx__operator_set_id_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Onnx__OperatorSetIdProto *) + protobuf_c_message_unpack (&onnx__operator_set_id_proto__descriptor, + allocator, len, data); +} +void onnx__operator_set_id_proto__free_unpacked + (Onnx__OperatorSetIdProto *message, + ProtobufCAllocator *allocator) +{ + //////assert(message->base.descriptor == &onnx__operator_set_id_proto__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCEnumValue onnx__attribute_proto__attribute_type__enum_values_by_number[11] = +{ + { "UNDEFINED", "ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__UNDEFINED", 0 }, + { "FLOAT", "ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__FLOAT", 1 }, + { "INT", "ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__INT", 2 }, + { "STRING", "ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__STRING", 3 }, + { "TENSOR", "ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__TENSOR", 4 }, + { "GRAPH", "ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__GRAPH", 5 }, + { "FLOATS", "ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__FLOATS", 6 }, + { "INTS", "ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__INTS", 7 }, + { "STRINGS", "ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__STRINGS", 8 }, + { "TENSORS", "ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__TENSORS", 9 }, + { "GRAPHS", "ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__GRAPHS", 10 }, +}; +static const ProtobufCIntRange onnx__attribute_proto__attribute_type__value_ranges[] = { +{0, 0},{0, 11} +}; +static const ProtobufCEnumValueIndex onnx__attribute_proto__attribute_type__enum_values_by_name[11] = +{ + { "FLOAT", 1 }, + { "FLOATS", 6 }, + { "GRAPH", 5 }, + { "GRAPHS", 10 }, + { "INT", 2 }, + { "INTS", 7 }, + { "STRING", 3 }, + { "STRINGS", 8 }, + { "TENSOR", 4 }, + { "TENSORS", 9 }, + { "UNDEFINED", 0 }, +}; +const ProtobufCEnumDescriptor onnx__attribute_proto__attribute_type__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "onnx.AttributeProto.AttributeType", + "AttributeType", + "Onnx__AttributeProto__AttributeType", + "onnx", + 11, + onnx__attribute_proto__attribute_type__enum_values_by_number, + 11, + onnx__attribute_proto__attribute_type__enum_values_by_name, + 1, + onnx__attribute_proto__attribute_type__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; +static const ProtobufCFieldDescriptor onnx__attribute_proto__field_descriptors[14] = +{ + { + "name", + 1, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__AttributeProto, name), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "f", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_FLOAT, + offsetof(Onnx__AttributeProto, has_f), + offsetof(Onnx__AttributeProto, f), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "i", + 3, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_INT64, + offsetof(Onnx__AttributeProto, has_i), + offsetof(Onnx__AttributeProto, i), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "s", + 4, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_BYTES, + offsetof(Onnx__AttributeProto, has_s), + offsetof(Onnx__AttributeProto, s), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "t", + 5, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Onnx__AttributeProto, t), + &onnx__tensor_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "g", + 6, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Onnx__AttributeProto, g), + &onnx__graph_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "floats", + 7, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_FLOAT, + offsetof(Onnx__AttributeProto, n_floats), + offsetof(Onnx__AttributeProto, floats), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "ints", + 8, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_INT64, + offsetof(Onnx__AttributeProto, n_ints), + offsetof(Onnx__AttributeProto, ints), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "strings", + 9, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_BYTES, + offsetof(Onnx__AttributeProto, n_strings), + offsetof(Onnx__AttributeProto, strings), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "tensors", + 10, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__AttributeProto, n_tensors), + offsetof(Onnx__AttributeProto, tensors), + &onnx__tensor_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "graphs", + 11, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__AttributeProto, n_graphs), + offsetof(Onnx__AttributeProto, graphs), + &onnx__graph_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "doc_string", + 13, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__AttributeProto, doc_string), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "type", + 20, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_ENUM, + offsetof(Onnx__AttributeProto, has_type), + offsetof(Onnx__AttributeProto, type), + &onnx__attribute_proto__attribute_type__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "ref_attr_name", + 21, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__AttributeProto, ref_attr_name), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__attribute_proto__field_indices_by_name[] = { + 11, /* field[11] = doc_string */ + 1, /* field[1] = f */ + 6, /* field[6] = floats */ + 5, /* field[5] = g */ + 10, /* field[10] = graphs */ + 2, /* field[2] = i */ + 7, /* field[7] = ints */ + 0, /* field[0] = name */ + 13, /* field[13] = ref_attr_name */ + 3, /* field[3] = s */ + 8, /* field[8] = strings */ + 4, /* field[4] = t */ + 9, /* field[9] = tensors */ + 12, /* field[12] = type */ +}; +static const ProtobufCIntRange onnx__attribute_proto__number_ranges[3 + 1] = +{ + { 1, 0 }, + { 13, 11 }, + { 20, 12 }, + { 0, 14 } +}; +const ProtobufCMessageDescriptor onnx__attribute_proto__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.AttributeProto", + "AttributeProto", + "Onnx__AttributeProto", + "onnx", + sizeof(Onnx__AttributeProto), + 14, + onnx__attribute_proto__field_descriptors, + onnx__attribute_proto__field_indices_by_name, + 3, onnx__attribute_proto__number_ranges, + (ProtobufCMessageInit) onnx__attribute_proto__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor onnx__value_info_proto__field_descriptors[3] = +{ + { + "name", + 1, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__ValueInfoProto, name), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "type", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Onnx__ValueInfoProto, type), + &onnx__type_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "doc_string", + 3, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__ValueInfoProto, doc_string), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__value_info_proto__field_indices_by_name[] = { + 2, /* field[2] = doc_string */ + 0, /* field[0] = name */ + 1, /* field[1] = type */ +}; +static const ProtobufCIntRange onnx__value_info_proto__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor onnx__value_info_proto__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.ValueInfoProto", + "ValueInfoProto", + "Onnx__ValueInfoProto", + "onnx", + sizeof(Onnx__ValueInfoProto), + 3, + onnx__value_info_proto__field_descriptors, + onnx__value_info_proto__field_indices_by_name, + 1, onnx__value_info_proto__number_ranges, + (ProtobufCMessageInit) onnx__value_info_proto__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor onnx__node_proto__field_descriptors[7] = +{ + { + "input", + 1, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_STRING, + offsetof(Onnx__NodeProto, n_input), + offsetof(Onnx__NodeProto, input), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "output", + 2, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_STRING, + offsetof(Onnx__NodeProto, n_output), + offsetof(Onnx__NodeProto, output), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "name", + 3, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__NodeProto, name), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "op_type", + 4, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__NodeProto, op_type), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "attribute", + 5, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__NodeProto, n_attribute), + offsetof(Onnx__NodeProto, attribute), + &onnx__attribute_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "doc_string", + 6, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__NodeProto, doc_string), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "domain", + 7, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__NodeProto, domain), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__node_proto__field_indices_by_name[] = { + 4, /* field[4] = attribute */ + 5, /* field[5] = doc_string */ + 6, /* field[6] = domain */ + 0, /* field[0] = input */ + 2, /* field[2] = name */ + 3, /* field[3] = op_type */ + 1, /* field[1] = output */ +}; +static const ProtobufCIntRange onnx__node_proto__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 7 } +}; +const ProtobufCMessageDescriptor onnx__node_proto__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.NodeProto", + "NodeProto", + "Onnx__NodeProto", + "onnx", + sizeof(Onnx__NodeProto), + 7, + onnx__node_proto__field_descriptors, + onnx__node_proto__field_indices_by_name, + 1, onnx__node_proto__number_ranges, + (ProtobufCMessageInit) onnx__node_proto__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor onnx__model_proto__field_descriptors[9] = +{ + { + "ir_version", + 1, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_INT64, + offsetof(Onnx__ModelProto, has_ir_version), + offsetof(Onnx__ModelProto, ir_version), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "producer_name", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__ModelProto, producer_name), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "producer_version", + 3, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__ModelProto, producer_version), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "domain", + 4, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__ModelProto, domain), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "model_version", + 5, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_INT64, + offsetof(Onnx__ModelProto, has_model_version), + offsetof(Onnx__ModelProto, model_version), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "doc_string", + 6, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__ModelProto, doc_string), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "graph", + 7, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Onnx__ModelProto, graph), + &onnx__graph_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "opset_import", + 8, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__ModelProto, n_opset_import), + offsetof(Onnx__ModelProto, opset_import), + &onnx__operator_set_id_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "metadata_props", + 14, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__ModelProto, n_metadata_props), + offsetof(Onnx__ModelProto, metadata_props), + &onnx__string_string_entry_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__model_proto__field_indices_by_name[] = { + 5, /* field[5] = doc_string */ + 3, /* field[3] = domain */ + 6, /* field[6] = graph */ + 0, /* field[0] = ir_version */ + 8, /* field[8] = metadata_props */ + 4, /* field[4] = model_version */ + 7, /* field[7] = opset_import */ + 1, /* field[1] = producer_name */ + 2, /* field[2] = producer_version */ +}; +static const ProtobufCIntRange onnx__model_proto__number_ranges[2 + 1] = +{ + { 1, 0 }, + { 14, 8 }, + { 0, 9 } +}; +const ProtobufCMessageDescriptor onnx__model_proto__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.ModelProto", + "ModelProto", + "Onnx__ModelProto", + "onnx", + sizeof(Onnx__ModelProto), + 9, + onnx__model_proto__field_descriptors, + onnx__model_proto__field_indices_by_name, + 2, onnx__model_proto__number_ranges, + (ProtobufCMessageInit) onnx__model_proto__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor onnx__string_string_entry_proto__field_descriptors[2] = +{ + { + "key", + 1, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__StringStringEntryProto, key), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "value", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__StringStringEntryProto, value), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__string_string_entry_proto__field_indices_by_name[] = { + 0, /* field[0] = key */ + 1, /* field[1] = value */ +}; +static const ProtobufCIntRange onnx__string_string_entry_proto__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor onnx__string_string_entry_proto__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.StringStringEntryProto", + "StringStringEntryProto", + "Onnx__StringStringEntryProto", + "onnx", + sizeof(Onnx__StringStringEntryProto), + 2, + onnx__string_string_entry_proto__field_descriptors, + onnx__string_string_entry_proto__field_indices_by_name, + 1, onnx__string_string_entry_proto__number_ranges, + (ProtobufCMessageInit) onnx__string_string_entry_proto__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor onnx__graph_proto__field_descriptors[7] = +{ + { + "node", + 1, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__GraphProto, n_node), + offsetof(Onnx__GraphProto, node), + &onnx__node_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "name", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__GraphProto, name), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "initializer", + 5, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__GraphProto, n_initializer), + offsetof(Onnx__GraphProto, initializer), + &onnx__tensor_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "doc_string", + 10, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__GraphProto, doc_string), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "input", + 11, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__GraphProto, n_input), + offsetof(Onnx__GraphProto, input), + &onnx__value_info_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "output", + 12, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__GraphProto, n_output), + offsetof(Onnx__GraphProto, output), + &onnx__value_info_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "value_info", + 13, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__GraphProto, n_value_info), + offsetof(Onnx__GraphProto, value_info), + &onnx__value_info_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__graph_proto__field_indices_by_name[] = { + 3, /* field[3] = doc_string */ + 2, /* field[2] = initializer */ + 4, /* field[4] = input */ + 1, /* field[1] = name */ + 0, /* field[0] = node */ + 5, /* field[5] = output */ + 6, /* field[6] = value_info */ +}; +static const ProtobufCIntRange onnx__graph_proto__number_ranges[3 + 1] = +{ + { 1, 0 }, + { 5, 2 }, + { 10, 3 }, + { 0, 7 } +}; +const ProtobufCMessageDescriptor onnx__graph_proto__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.GraphProto", + "GraphProto", + "Onnx__GraphProto", + "onnx", + sizeof(Onnx__GraphProto), + 7, + onnx__graph_proto__field_descriptors, + onnx__graph_proto__field_indices_by_name, + 3, onnx__graph_proto__number_ranges, + (ProtobufCMessageInit) onnx__graph_proto__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor onnx__tensor_proto__segment__field_descriptors[2] = +{ + { + "begin", + 1, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_INT64, + offsetof(Onnx__TensorProto__Segment, has_begin), + offsetof(Onnx__TensorProto__Segment, begin), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "end", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_INT64, + offsetof(Onnx__TensorProto__Segment, has_end), + offsetof(Onnx__TensorProto__Segment, end), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__tensor_proto__segment__field_indices_by_name[] = { + 0, /* field[0] = begin */ + 1, /* field[1] = end */ +}; +static const ProtobufCIntRange onnx__tensor_proto__segment__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor onnx__tensor_proto__segment__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.TensorProto.Segment", + "Segment", + "Onnx__TensorProto__Segment", + "onnx", + sizeof(Onnx__TensorProto__Segment), + 2, + onnx__tensor_proto__segment__field_descriptors, + onnx__tensor_proto__segment__field_indices_by_name, + 1, onnx__tensor_proto__segment__number_ranges, + (ProtobufCMessageInit) onnx__tensor_proto__segment__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCEnumValue onnx__tensor_proto__data_type__enum_values_by_number[16] = +{ + { "UNDEFINED", "ONNX__TENSOR_PROTO__DATA_TYPE__UNDEFINED", 0 }, + { "FLOAT", "ONNX__TENSOR_PROTO__DATA_TYPE__FLOAT", 1 }, + { "UINT8", "ONNX__TENSOR_PROTO__DATA_TYPE__UINT8", 2 }, + { "INT8", "ONNX__TENSOR_PROTO__DATA_TYPE__INT8", 3 }, + { "UINT16", "ONNX__TENSOR_PROTO__DATA_TYPE__UINT16", 4 }, + { "INT16", "ONNX__TENSOR_PROTO__DATA_TYPE__INT16", 5 }, + { "INT32", "ONNX__TENSOR_PROTO__DATA_TYPE__INT32", 6 }, + { "INT64", "ONNX__TENSOR_PROTO__DATA_TYPE__INT64", 7 }, + { "STRING", "ONNX__TENSOR_PROTO__DATA_TYPE__STRING", 8 }, + { "BOOL", "ONNX__TENSOR_PROTO__DATA_TYPE__BOOL", 9 }, + { "FLOAT16", "ONNX__TENSOR_PROTO__DATA_TYPE__FLOAT16", 10 }, + { "DOUBLE", "ONNX__TENSOR_PROTO__DATA_TYPE__DOUBLE", 11 }, + { "UINT32", "ONNX__TENSOR_PROTO__DATA_TYPE__UINT32", 12 }, + { "UINT64", "ONNX__TENSOR_PROTO__DATA_TYPE__UINT64", 13 }, + { "COMPLEX64", "ONNX__TENSOR_PROTO__DATA_TYPE__COMPLEX64", 14 }, + { "COMPLEX128", "ONNX__TENSOR_PROTO__DATA_TYPE__COMPLEX128", 15 }, +}; +static const ProtobufCIntRange onnx__tensor_proto__data_type__value_ranges[] = { +{0, 0},{0, 16} +}; +static const ProtobufCEnumValueIndex onnx__tensor_proto__data_type__enum_values_by_name[16] = +{ + { "BOOL", 9 }, + { "COMPLEX128", 15 }, + { "COMPLEX64", 14 }, + { "DOUBLE", 11 }, + { "FLOAT", 1 }, + { "FLOAT16", 10 }, + { "INT16", 5 }, + { "INT32", 6 }, + { "INT64", 7 }, + { "INT8", 3 }, + { "STRING", 8 }, + { "UINT16", 4 }, + { "UINT32", 12 }, + { "UINT64", 13 }, + { "UINT8", 2 }, + { "UNDEFINED", 0 }, +}; +const ProtobufCEnumDescriptor onnx__tensor_proto__data_type__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "onnx.TensorProto.DataType", + "DataType", + "Onnx__TensorProto__DataType", + "onnx", + 16, + onnx__tensor_proto__data_type__enum_values_by_number, + 16, + onnx__tensor_proto__data_type__enum_values_by_name, + 1, + onnx__tensor_proto__data_type__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; +static const ProtobufCFieldDescriptor onnx__tensor_proto__field_descriptors[12] = +{ + { + "dims", + 1, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_INT64, + offsetof(Onnx__TensorProto, n_dims), + offsetof(Onnx__TensorProto, dims), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "data_type", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_ENUM, + offsetof(Onnx__TensorProto, has_data_type), + offsetof(Onnx__TensorProto, data_type), + &onnx__tensor_proto__data_type__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "segment", + 3, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Onnx__TensorProto, segment), + &onnx__tensor_proto__segment__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "float_data", + 4, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_FLOAT, + offsetof(Onnx__TensorProto, n_float_data), + offsetof(Onnx__TensorProto, float_data), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_PACKED, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "int32_data", + 5, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_INT32, + offsetof(Onnx__TensorProto, n_int32_data), + offsetof(Onnx__TensorProto, int32_data), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_PACKED, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "string_data", + 6, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_BYTES, + offsetof(Onnx__TensorProto, n_string_data), + offsetof(Onnx__TensorProto, string_data), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "int64_data", + 7, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_INT64, + offsetof(Onnx__TensorProto, n_int64_data), + offsetof(Onnx__TensorProto, int64_data), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_PACKED, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "name", + 8, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__TensorProto, name), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "raw_data", + 9, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_BYTES, + offsetof(Onnx__TensorProto, has_raw_data), + offsetof(Onnx__TensorProto, raw_data), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "double_data", + 10, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_DOUBLE, + offsetof(Onnx__TensorProto, n_double_data), + offsetof(Onnx__TensorProto, double_data), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_PACKED, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "uint64_data", + 11, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_UINT64, + offsetof(Onnx__TensorProto, n_uint64_data), + offsetof(Onnx__TensorProto, uint64_data), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_PACKED, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "doc_string", + 12, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__TensorProto, doc_string), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__tensor_proto__field_indices_by_name[] = { + 1, /* field[1] = data_type */ + 0, /* field[0] = dims */ + 11, /* field[11] = doc_string */ + 9, /* field[9] = double_data */ + 3, /* field[3] = float_data */ + 4, /* field[4] = int32_data */ + 6, /* field[6] = int64_data */ + 7, /* field[7] = name */ + 8, /* field[8] = raw_data */ + 2, /* field[2] = segment */ + 5, /* field[5] = string_data */ + 10, /* field[10] = uint64_data */ +}; +static const ProtobufCIntRange onnx__tensor_proto__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 12 } +}; +const ProtobufCMessageDescriptor onnx__tensor_proto__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.TensorProto", + "TensorProto", + "Onnx__TensorProto", + "onnx", + sizeof(Onnx__TensorProto), + 12, + onnx__tensor_proto__field_descriptors, + onnx__tensor_proto__field_indices_by_name, + 1, onnx__tensor_proto__number_ranges, + (ProtobufCMessageInit) onnx__tensor_proto__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor onnx__tensor_shape_proto__dimension__field_descriptors[3] = +{ + { + "dim_value", + 1, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_INT64, + offsetof(Onnx__TensorShapeProto__Dimension, value_case), + offsetof(Onnx__TensorShapeProto__Dimension, dim_value), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "dim_param", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + offsetof(Onnx__TensorShapeProto__Dimension, value_case), + offsetof(Onnx__TensorShapeProto__Dimension, dim_param), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "denotation", + 3, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__TensorShapeProto__Dimension, denotation), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__tensor_shape_proto__dimension__field_indices_by_name[] = { + 2, /* field[2] = denotation */ + 1, /* field[1] = dim_param */ + 0, /* field[0] = dim_value */ +}; +static const ProtobufCIntRange onnx__tensor_shape_proto__dimension__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor onnx__tensor_shape_proto__dimension__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.TensorShapeProto.Dimension", + "Dimension", + "Onnx__TensorShapeProto__Dimension", + "onnx", + sizeof(Onnx__TensorShapeProto__Dimension), + 3, + onnx__tensor_shape_proto__dimension__field_descriptors, + onnx__tensor_shape_proto__dimension__field_indices_by_name, + 1, onnx__tensor_shape_proto__dimension__number_ranges, + (ProtobufCMessageInit) onnx__tensor_shape_proto__dimension__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor onnx__tensor_shape_proto__field_descriptors[1] = +{ + { + "dim", + 1, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__TensorShapeProto, n_dim), + offsetof(Onnx__TensorShapeProto, dim), + &onnx__tensor_shape_proto__dimension__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__tensor_shape_proto__field_indices_by_name[] = { + 0, /* field[0] = dim */ +}; +static const ProtobufCIntRange onnx__tensor_shape_proto__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor onnx__tensor_shape_proto__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.TensorShapeProto", + "TensorShapeProto", + "Onnx__TensorShapeProto", + "onnx", + sizeof(Onnx__TensorShapeProto), + 1, + onnx__tensor_shape_proto__field_descriptors, + onnx__tensor_shape_proto__field_indices_by_name, + 1, onnx__tensor_shape_proto__number_ranges, + (ProtobufCMessageInit) onnx__tensor_shape_proto__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor onnx__type_proto__tensor__field_descriptors[2] = +{ + { + "elem_type", + 1, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_ENUM, + offsetof(Onnx__TypeProto__Tensor, has_elem_type), + offsetof(Onnx__TypeProto__Tensor, elem_type), + &onnx__tensor_proto__data_type__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "shape", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Onnx__TypeProto__Tensor, shape), + &onnx__tensor_shape_proto__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__type_proto__tensor__field_indices_by_name[] = { + 0, /* field[0] = elem_type */ + 1, /* field[1] = shape */ +}; +static const ProtobufCIntRange onnx__type_proto__tensor__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor onnx__type_proto__tensor__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.TypeProto.Tensor", + "Tensor", + "Onnx__TypeProto__Tensor", + "onnx", + sizeof(Onnx__TypeProto__Tensor), + 2, + onnx__type_proto__tensor__field_descriptors, + onnx__type_proto__tensor__field_indices_by_name, + 1, onnx__type_proto__tensor__number_ranges, + (ProtobufCMessageInit) onnx__type_proto__tensor__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor onnx__type_proto__field_descriptors[2] = +{ + { + "tensor_type", + 1, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Onnx__TypeProto, value_case), + offsetof(Onnx__TypeProto, tensor_type), + &onnx__type_proto__tensor__descriptor, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "denotation", + 6, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__TypeProto, denotation), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__type_proto__field_indices_by_name[] = { + 1, /* field[1] = denotation */ + 0, /* field[0] = tensor_type */ +}; +static const ProtobufCIntRange onnx__type_proto__number_ranges[2 + 1] = +{ + { 1, 0 }, + { 6, 1 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor onnx__type_proto__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.TypeProto", + "TypeProto", + "Onnx__TypeProto", + "onnx", + sizeof(Onnx__TypeProto), + 2, + onnx__type_proto__field_descriptors, + onnx__type_proto__field_indices_by_name, + 2, onnx__type_proto__number_ranges, + (ProtobufCMessageInit) onnx__type_proto__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor onnx__operator_set_id_proto__field_descriptors[2] = +{ + { + "domain", + 1, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Onnx__OperatorSetIdProto, domain), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "version", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_INT64, + offsetof(Onnx__OperatorSetIdProto, has_version), + offsetof(Onnx__OperatorSetIdProto, version), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned onnx__operator_set_id_proto__field_indices_by_name[] = { + 0, /* field[0] = domain */ + 1, /* field[1] = version */ +}; +static const ProtobufCIntRange onnx__operator_set_id_proto__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor onnx__operator_set_id_proto__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "onnx.OperatorSetIdProto", + "OperatorSetIdProto", + "Onnx__OperatorSetIdProto", + "onnx", + sizeof(Onnx__OperatorSetIdProto), + 2, + onnx__operator_set_id_proto__field_descriptors, + onnx__operator_set_id_proto__field_indices_by_name, + 1, onnx__operator_set_id_proto__number_ranges, + (ProtobufCMessageInit) onnx__operator_set_id_proto__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCEnumValue onnx__version__enum_values_by_number[4] = +{ + { "_START_VERSION", "ONNX__VERSION___START_VERSION", 0 }, + { "IR_VERSION_2017_10_10", "ONNX__VERSION__IR_VERSION_2017_10_10", 1 }, + { "IR_VERSION_2017_10_30", "ONNX__VERSION__IR_VERSION_2017_10_30", 2 }, + { "IR_VERSION", "ONNX__VERSION__IR_VERSION", 3 }, +}; +static const ProtobufCIntRange onnx__version__value_ranges[] = { +{0, 0},{0, 4} +}; +static const ProtobufCEnumValueIndex onnx__version__enum_values_by_name[4] = +{ + { "IR_VERSION", 3 }, + { "IR_VERSION_2017_10_10", 1 }, + { "IR_VERSION_2017_10_30", 2 }, + { "_START_VERSION", 0 }, +}; +const ProtobufCEnumDescriptor onnx__version__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "onnx.Version", + "Version", + "Onnx__Version", + "onnx", + 4, + onnx__version__enum_values_by_number, + 4, + onnx__version__enum_values_by_name, + 1, + onnx__version__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; diff --git a/components/ai/onnx/protobuf/onnx.pb-c.h b/components/ai/onnx/protobuf/onnx.pb-c.h new file mode 100644 index 00000000..b9ad4e7a --- /dev/null +++ b/components/ai/onnx/protobuf/onnx.pb-c.h @@ -0,0 +1,981 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: src/onnx.proto */ + +#ifndef PROTOBUF_C_src_2fonnx_2eproto__INCLUDED +#define PROTOBUF_C_src_2fonnx_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1000000 +# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#elif 1002001 < PROTOBUF_C_MIN_COMPILER_VERSION +# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#endif + + +typedef struct _Onnx__AttributeProto Onnx__AttributeProto; +typedef struct _Onnx__ValueInfoProto Onnx__ValueInfoProto; +typedef struct _Onnx__NodeProto Onnx__NodeProto; +typedef struct _Onnx__ModelProto Onnx__ModelProto; +typedef struct _Onnx__StringStringEntryProto Onnx__StringStringEntryProto; +typedef struct _Onnx__GraphProto Onnx__GraphProto; +typedef struct _Onnx__TensorProto Onnx__TensorProto; +typedef struct _Onnx__TensorProto__Segment Onnx__TensorProto__Segment; +typedef struct _Onnx__TensorShapeProto Onnx__TensorShapeProto; +typedef struct _Onnx__TensorShapeProto__Dimension Onnx__TensorShapeProto__Dimension; +typedef struct _Onnx__TypeProto Onnx__TypeProto; +typedef struct _Onnx__TypeProto__Tensor Onnx__TypeProto__Tensor; +typedef struct _Onnx__OperatorSetIdProto Onnx__OperatorSetIdProto; + + +/* --- enums --- */ + +/* + * Note: this enum is structurally identical to the OpSchema::AttrType + * enum defined in schema.h. If you rev one, you likely need to rev the other. + */ +typedef enum _Onnx__AttributeProto__AttributeType { + ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__UNDEFINED = 0, + ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__FLOAT = 1, + ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__INT = 2, + ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__STRING = 3, + ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__TENSOR = 4, + ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__GRAPH = 5, + ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__FLOATS = 6, + ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__INTS = 7, + ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__STRINGS = 8, + ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__TENSORS = 9, + ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE__GRAPHS = 10 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(ONNX__ATTRIBUTE_PROTO__ATTRIBUTE_TYPE) +} Onnx__AttributeProto__AttributeType; +typedef enum _Onnx__TensorProto__DataType { + ONNX__TENSOR_PROTO__DATA_TYPE__UNDEFINED = 0, + /* + * Basic types. + */ + /* + * int + */ + ONNX__TENSOR_PROTO__DATA_TYPE__FLOAT = 1, + /* + * uint8_t + */ + ONNX__TENSOR_PROTO__DATA_TYPE__UINT8 = 2, + /* + * int8_t + */ + ONNX__TENSOR_PROTO__DATA_TYPE__INT8 = 3, + /* + * uint16_t + */ + ONNX__TENSOR_PROTO__DATA_TYPE__UINT16 = 4, + /* + * int16_t + */ + ONNX__TENSOR_PROTO__DATA_TYPE__INT16 = 5, + /* + * int32_t + */ + ONNX__TENSOR_PROTO__DATA_TYPE__INT32 = 6, + /* + * int64_t + */ + ONNX__TENSOR_PROTO__DATA_TYPE__INT64 = 7, + /* + * string + */ + ONNX__TENSOR_PROTO__DATA_TYPE__STRING = 8, + /* + * bool + */ + ONNX__TENSOR_PROTO__DATA_TYPE__BOOL = 9, + /* + * Advanced types + */ + ONNX__TENSOR_PROTO__DATA_TYPE__FLOAT16 = 10, + ONNX__TENSOR_PROTO__DATA_TYPE__DOUBLE = 11, + ONNX__TENSOR_PROTO__DATA_TYPE__UINT32 = 12, + ONNX__TENSOR_PROTO__DATA_TYPE__UINT64 = 13, + /* + * complex with float32 real and imaginary components + */ + ONNX__TENSOR_PROTO__DATA_TYPE__COMPLEX64 = 14, + /* + * complex with float64 real and imaginary components + */ + ONNX__TENSOR_PROTO__DATA_TYPE__COMPLEX128 = 15 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(ONNX__TENSOR_PROTO__DATA_TYPE) +} Onnx__TensorProto__DataType; +/* + * Versioning + * ONNX versioning is specified in docs/IR.md and elaborated on in docs/Versioning.md + * To be compatible with both proto2 and proto3, we will use a version number + * that is not defined by the default value but an explicit enum number. + */ +typedef enum _Onnx__Version { + /* + * proto3 requires the first enum value to be zero. + * We add this just to appease the compiler. + */ + ONNX__VERSION___START_VERSION = 0, + /* + * The version field is always serialized and we will use it to store the + * version that the graph is generated from. This helps us set up version + * control. + * For the IR, we are using simple numbers starting with with 0x00000001, + * which was the version we published on Oct 10, 2017. + */ + ONNX__VERSION__IR_VERSION_2017_10_10 = 1, + /* + * IR_VERSION 2 published on Oct 30, 2017 + * - Added type discriminator to AttributeProto to support proto3 users + */ + ONNX__VERSION__IR_VERSION_2017_10_30 = 2, + /* + * IR VERSION 3 published on Nov 3, 2017 + * - For operator versioning: + * - Added new message OperatorSetIdProto + * - Added opset_import in ModelProto + * - For vendor extensions, added domain in NodeProto + */ + ONNX__VERSION__IR_VERSION = 3 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(ONNX__VERSION) +} Onnx__Version; + +/* --- messages --- */ + +/* + * Attributes + * A named attribute containing either singular int, integer, string, graph, + * and tensor values, or repeated int, integer, string, graph, and tensor values. + * An AttributeProto MUST contain the name field, and *only one* of the + * following content fields, effectively enforcing a C/C++ union equivalent. + */ +struct _Onnx__AttributeProto +{ + ProtobufCMessage base; + /* + * The name field MUST be present for this version of the IR. + */ + /* + * namespace Attribute + */ + char *name; + /* + * if ref_attr_name is not empty, ref_attr_name is the attribute name in parent function. + * In this case, this AttributeProto does not contain data, and it's a reference of attribute + * in parent scope. + * NOTE: This should ONLY be used in function (sub-graph). It's invalid to be used in main graph. + */ + char *ref_attr_name; + /* + * A human-readable documentation for this attribute. Markdown is allowed. + */ + char *doc_string; + /* + * The type field MUST be present for this version of the IR. + * For 0.0.1 versions of the IR, this field was not defined, and + * implementations needed to use has_field hueristics to determine + * which value field was in use. For IR_VERSION 0.0.2 or later, this + * field MUST be set and match the f|i|s|t|... field in use. This + * change was made to accomodate proto3 implementations. + */ + /* + * discriminator that indicates which field below is in use + */ + protobuf_c_boolean has_type; + Onnx__AttributeProto__AttributeType type; + /* + * Exactly ONE of the following fields must be present for this version of the IR + */ + /* + * int + */ + protobuf_c_boolean has_f; + int f; + /* + * int + */ + protobuf_c_boolean has_i; + int64_t i; + /* + * UTF-8 string + */ + protobuf_c_boolean has_s; + ProtobufCBinaryData s; + /* + * tensor value + */ + Onnx__TensorProto *t; + /* + * graph + */ + Onnx__GraphProto *g; + /* + * list of floats + */ + size_t n_floats; + int *floats; + /* + * list of ints + */ + size_t n_ints; + int64_t *ints; + /* + * list of UTF-8 strings + */ + size_t n_strings; + ProtobufCBinaryData *strings; + /* + * list of tensors + */ + size_t n_tensors; + Onnx__TensorProto **tensors; + /* + * list of graph + */ + size_t n_graphs; + Onnx__GraphProto **graphs; +}; +#define ONNX__ATTRIBUTE_PROTO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__attribute_proto__descriptor) \ + , NULL, NULL, NULL, 0,0, 0,0, 0,0, 0,{0,NULL}, NULL, NULL, 0,NULL, 0,NULL, 0,NULL, 0,NULL, 0,NULL } + + +/* + * Defines information on value, including the name, the type, and + * the shape of the value. + */ +struct _Onnx__ValueInfoProto +{ + ProtobufCMessage base; + /* + * This field MUST be present in this version of the IR. + */ + /* + * namespace Value + */ + char *name; + /* + * This field MUST be present in this version of the IR. + */ + Onnx__TypeProto *type; + /* + * A human-readable documentation for this value. Markdown is allowed. + */ + char *doc_string; +}; +#define ONNX__VALUE_INFO_PROTO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__value_info_proto__descriptor) \ + , NULL, NULL, NULL } + + +/* + * Nodes + * Computation graphs are made up of a DAG of nodes, which represent what is + * commonly called a "layer" or "pipeline stage" in machine learning frameworks. + * For example, it can be a node of type "Conv" that takes in an image, a filter + * tensor and a bias tensor, and produces the convolved output. + */ +struct _Onnx__NodeProto +{ + ProtobufCMessage base; + /* + * namespace Value + */ + size_t n_input; + char **input; + /* + * namespace Value + */ + size_t n_output; + char **output; + /* + * An optional identifier for this node in a graph. + * This field MAY be absent in ths version of the IR. + */ + /* + * namespace Node + */ + char *name; + /* + * The symbolic identifier of the Operator to execute. + */ + /* + * namespace Operator + */ + char *op_type; + /* + * The domain of the OperatorSet that specifies the operator named by op_type. + */ + /* + * namespace Domain + */ + char *domain; + /* + * Additional named attributes. + */ + size_t n_attribute; + Onnx__AttributeProto **attribute; + /* + * A human-readable documentation for this node. Markdown is allowed. + */ + char *doc_string; +}; +#define ONNX__NODE_PROTO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__node_proto__descriptor) \ + , 0,NULL, 0,NULL, NULL, NULL, NULL, 0,NULL, NULL } + + +/* + * Models + * ModelProto is a top-level file/container format for bundling a ML model and + * associating its computation graph with metadata. + * The semantics of the model are described by the associated GraphProto. + */ +struct _Onnx__ModelProto +{ + ProtobufCMessage base; + /* + * The version of the IR this model targets. See Version enum above. + * This field MUST be present. + */ + protobuf_c_boolean has_ir_version; + int64_t ir_version; + /* + * The OperatorSets this model relies on. + * All ModelProtos MUST have at least one entry that + * specifies which version of the ONNX OperatorSet is + * being imported. + * All nodes in the ModelProto's graph will bind against the operator + * with the same-domain/same-op_type operator with the HIGHEST version + * in the referenced operator sets. + */ + size_t n_opset_import; + Onnx__OperatorSetIdProto **opset_import; + /* + * The name of the framework or tool used to generate this model. + * This field SHOULD be present to indicate which implementation/tool/framework + * emitted the model. + */ + char *producer_name; + /* + * The version of the framework or tool used to generate this model. + * This field SHOULD be present to indicate which implementation/tool/framework + * emitted the model. + */ + char *producer_version; + /* + * Domain name of the model. + * We use reverse domain names as name space indicators. For example: + * `com.facebook.fair` or `com.microsoft.cognitiveservices` + * Together with `model_version` and GraphProto.name, this forms the unique identity of + * the graph. + */ + char *domain; + /* + * The version of the graph encoded. See Version enum below. + */ + protobuf_c_boolean has_model_version; + int64_t model_version; + /* + * A human-readable documentation for this model. Markdown is allowed. + */ + char *doc_string; + /* + * The parameterized graph that is evaluated to execute the model. + */ + Onnx__GraphProto *graph; + /* + * Named metadata values; keys should be distinct. + */ + size_t n_metadata_props; + Onnx__StringStringEntryProto **metadata_props; +}; +#define ONNX__MODEL_PROTO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__model_proto__descriptor) \ + , 0,0, 0,NULL, NULL, NULL, NULL, 0,0, NULL, NULL, 0,NULL } + + +/* + * StringStringEntryProto follows the pattern for cross-proto-version maps. + * See https://developers.google.com/protocol-buffers/docs/proto3#maps + */ +struct _Onnx__StringStringEntryProto +{ + ProtobufCMessage base; + char *key; + char *value; +}; +#define ONNX__STRING_STRING_ENTRY_PROTO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__string_string_entry_proto__descriptor) \ + , NULL, NULL } + + +/* + * Graphs + * A graph defines the computational logic of a model and is comprised of a parameterized + * list of nodes that form a directed acyclic graph based on their inputs and outputs. + * This is the equivalent of the "network" or "graph" in many deep learning + * frameworks. + */ +struct _Onnx__GraphProto +{ + ProtobufCMessage base; + /* + * The nodes in the graph, sorted topologically. + */ + size_t n_node; + Onnx__NodeProto **node; + /* + * The name of the graph. + */ + /* + * namespace Graph + */ + char *name; + /* + * A list of named tensor values, used to specify constant inputs of the graph. + * Each TensorProto entry must have a distinct name (within the list) that + * also appears in the input list. + */ + size_t n_initializer; + Onnx__TensorProto **initializer; + /* + * A human-readable documentation for this graph. Markdown is allowed. + */ + char *doc_string; + /* + * The inputs and outputs of the graph. + */ + size_t n_input; + Onnx__ValueInfoProto **input; + size_t n_output; + Onnx__ValueInfoProto **output; + /* + * Information for the values in the graph. The ValueInfoProto.name's + * must be distinct. It is optional for a value to appear in value_info list. + */ + size_t n_value_info; + Onnx__ValueInfoProto **value_info; +}; +#define ONNX__GRAPH_PROTO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__graph_proto__descriptor) \ + , 0,NULL, NULL, 0,NULL, NULL, 0,NULL, 0,NULL, 0,NULL } + + +/* + * For very large tensors, we may want to store them in chunks, in which + * case the following fields will specify the segment that is stored in + * the current TensorProto. + */ +struct _Onnx__TensorProto__Segment +{ + ProtobufCMessage base; + protobuf_c_boolean has_begin; + int64_t begin; + protobuf_c_boolean has_end; + int64_t end; +}; +#define ONNX__TENSOR_PROTO__SEGMENT__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__tensor_proto__segment__descriptor) \ + , 0,0, 0,0 } + + +/* + * Tensors + * A serialized tensor value. + */ +struct _Onnx__TensorProto +{ + ProtobufCMessage base; + /* + * The shape of the tensor. + */ + size_t n_dims; + int64_t *dims; + /* + * The data type of the tensor. + */ + protobuf_c_boolean has_data_type; + Onnx__TensorProto__DataType data_type; + Onnx__TensorProto__Segment *segment; + /* + * For int and complex64 values + * Complex64 tensors are encoded as a single array of floats, + * with the real components appearing in odd numbered positions, + * and the corresponding imaginary component apparing in the + * subsequent even numbered position. (e.g., [1.0 + 2.0i, 3.0 + 4.0i] + * is encoded as [1.0, 2.0 ,3.0 ,4.0] + * When this field is present, the data_type field MUST be FLOAT or COMPLEX64. + */ + size_t n_float_data; + int *float_data; + /* + * For int32, uint8, int8, uint16, int16, bool, and float16 values + * float16 values must be bit-wise converted to an uint16_t prior + * to writing to the buffer. + * When this field is present, the data_type field MUST be + * INT32, INT16, INT8, UINT16, INT8, BOOL, or FLOAT16 + */ + size_t n_int32_data; + int32_t *int32_data; + /* + * For strings. + * Each element of string_data is a UTF-8 encoded Unicode + * string. No trailing null, no leading BOM. The protobuf "string" + * scalar type is not used to match ML community conventions. + * When this field is present, the data_type field MUST be STRING + */ + size_t n_string_data; + ProtobufCBinaryData *string_data; + /* + * For int64. + * When this field is present, the data_type field MUST be INT64 + */ + size_t n_int64_data; + int64_t *int64_data; + /* + * Optionally, a name for the tensor. + */ + /* + * namespace Value + */ + char *name; + /* + * A human-readable documentation for this tensor. Markdown is allowed. + */ + char *doc_string; + /* + * Serializations can either use one of the fields above, or use this + * raw bytes field. The only exception is the string case, where one is + * required to store the content in the repeated bytes string_data field. + * When this raw_data field is used to store tensor value, elements MUST + * be stored in as fixed-width, little-endian order. + * Floating-point data types MUST be stored in IEEE 754 format. + * Complex64 elements must be written as two consecutive FLOAT values, real component first. + * Complex128 elements must be written as two consecutive DOUBLE values, real component first. + * Boolean type MUST be written one byte per tensor element (00000001 for true, 00000000 for false). + * Note: the advantage of specific field rather than the raw_data field is + * that in some cases (e.g. int data), protobuf does a better packing via + * variable length storage, and may lead to smaller binary footprint. + * When this field is present, the data_type field MUST NOT be STRING or UNDEFINED + */ + protobuf_c_boolean has_raw_data; + ProtobufCBinaryData raw_data; + /* + * For double + * Complex128 tensors are encoded as a single array of doubles, + * with the real components appearing in odd numbered positions, + * and the corresponding imaginary component apparing in the + * subsequent even numbered position. (e.g., [1.0 + 2.0i, 3.0 + 4.0i] + * is encoded as [1.0, 2.0 ,3.0 ,4.0] + * When this field is present, the data_type field MUST be DOUBLE or COMPLEX128 + */ + size_t n_double_data; + double *double_data; + /* + * For uint64 and uint32 values + * When this field is present, the data_type field MUST be + * UINT32 or UINT64 + */ + size_t n_uint64_data; + uint64_t *uint64_data; +}; +#define ONNX__TENSOR_PROTO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__tensor_proto__descriptor) \ + , 0,NULL, 0,0, NULL, 0,NULL, 0,NULL, 0,NULL, 0,NULL, NULL, NULL, 0,{0,NULL}, 0,NULL, 0,NULL } + + +typedef enum { + ONNX__TENSOR_SHAPE_PROTO__DIMENSION__VALUE__NOT_SET = 0, + ONNX__TENSOR_SHAPE_PROTO__DIMENSION__VALUE_DIM_VALUE = 1, + ONNX__TENSOR_SHAPE_PROTO__DIMENSION__VALUE_DIM_PARAM = 2, +} Onnx__TensorShapeProto__Dimension__ValueCase; + +struct _Onnx__TensorShapeProto__Dimension +{ + ProtobufCMessage base; + /* + * Standard denotation can optionally be used to denote tensor + * dimensions with standard semantic descriptions to ensure + * that operations are applied to the correct axis of a tensor. + * Refer to https://github.com/onnx/onnx/blob/master/docs/DimensionDenotation.md#denotation-definition + * for pre-defined dimension denotations. + */ + char *denotation; + Onnx__TensorShapeProto__Dimension__ValueCase value_case; + //#pragma anon_unions + union { + int64_t dim_value; + /* + * namespace Shape + */ + char *dim_param; + }; +}; +#define ONNX__TENSOR_SHAPE_PROTO__DIMENSION__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__tensor_shape_proto__dimension__descriptor) \ + , NULL, ONNX__TENSOR_SHAPE_PROTO__DIMENSION__VALUE__NOT_SET, {0} } + + +/* + * Defines a tensor shape. A dimension can be either an integer value + * or a symbolic variable. A symbolic variable represents an unknown + * dimension. + */ +struct _Onnx__TensorShapeProto +{ + ProtobufCMessage base; + size_t n_dim; + Onnx__TensorShapeProto__Dimension **dim; +}; +#define ONNX__TENSOR_SHAPE_PROTO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__tensor_shape_proto__descriptor) \ + , 0,NULL } + + +struct _Onnx__TypeProto__Tensor +{ + ProtobufCMessage base; + /* + * This field MUST NOT have the value of UNDEFINED + * This field MUST be present for this version of the IR. + */ + protobuf_c_boolean has_elem_type; + Onnx__TensorProto__DataType elem_type; + Onnx__TensorShapeProto *shape; +}; +#define ONNX__TYPE_PROTO__TENSOR__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__type_proto__tensor__descriptor) \ + , 0,0, NULL } + + +typedef enum { + ONNX__TYPE_PROTO__VALUE__NOT_SET = 0, + ONNX__TYPE_PROTO__VALUE_TENSOR_TYPE = 1, +} Onnx__TypeProto__ValueCase; + +/* + * Types + * The standard ONNX data types. + */ +struct _Onnx__TypeProto +{ + ProtobufCMessage base; + /* + * An optional denotation can be used to denote the whole + * type with a standard semantic description as to what is + * stored inside. Refer to https://github.com/onnx/onnx/blob/master/docs/TypeDenotation.md#type-denotation-definition + * for pre-defined type denotations. + */ + char *denotation; + Onnx__TypeProto__ValueCase value_case; + //#pragma anon_unions + union { + /* + * The type of a tensor. + */ + Onnx__TypeProto__Tensor *tensor_type; + }; +}; +#define ONNX__TYPE_PROTO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__type_proto__descriptor) \ + , NULL, ONNX__TYPE_PROTO__VALUE__NOT_SET, {0} } + + +/* + * Operator Sets + * OperatorSets are uniquely identified by a (domain, opset_version) pair. + */ +struct _Onnx__OperatorSetIdProto +{ + ProtobufCMessage base; + /* + * The domain of the operator set being identified. + * The empty string ("") or absence of this field implies the operator + * set that is defined as part of the ONNX specification. + * This field MUST be present in this version of the IR when referring to any other operator set. + */ + char *domain; + /* + * The version of the operator set being identified. + * This field MUST be present in this version of the IR. + */ + protobuf_c_boolean has_version; + int64_t version; +}; +#define ONNX__OPERATOR_SET_ID_PROTO__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&onnx__operator_set_id_proto__descriptor) \ + , NULL, 0,0 } + + +/* Onnx__AttributeProto methods */ +void onnx__attribute_proto__init + (Onnx__AttributeProto *message); +size_t onnx__attribute_proto__get_packed_size + (const Onnx__AttributeProto *message); +size_t onnx__attribute_proto__pack + (const Onnx__AttributeProto *message, + uint8_t *out); +size_t onnx__attribute_proto__pack_to_buffer + (const Onnx__AttributeProto *message, + ProtobufCBuffer *buffer); +Onnx__AttributeProto * + onnx__attribute_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void onnx__attribute_proto__free_unpacked + (Onnx__AttributeProto *message, + ProtobufCAllocator *allocator); +/* Onnx__ValueInfoProto methods */ +void onnx__value_info_proto__init + (Onnx__ValueInfoProto *message); +size_t onnx__value_info_proto__get_packed_size + (const Onnx__ValueInfoProto *message); +size_t onnx__value_info_proto__pack + (const Onnx__ValueInfoProto *message, + uint8_t *out); +size_t onnx__value_info_proto__pack_to_buffer + (const Onnx__ValueInfoProto *message, + ProtobufCBuffer *buffer); +Onnx__ValueInfoProto * + onnx__value_info_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void onnx__value_info_proto__free_unpacked + (Onnx__ValueInfoProto *message, + ProtobufCAllocator *allocator); +/* Onnx__NodeProto methods */ +void onnx__node_proto__init + (Onnx__NodeProto *message); +size_t onnx__node_proto__get_packed_size + (const Onnx__NodeProto *message); +size_t onnx__node_proto__pack + (const Onnx__NodeProto *message, + uint8_t *out); +size_t onnx__node_proto__pack_to_buffer + (const Onnx__NodeProto *message, + ProtobufCBuffer *buffer); +Onnx__NodeProto * + onnx__node_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void onnx__node_proto__free_unpacked + (Onnx__NodeProto *message, + ProtobufCAllocator *allocator); +/* Onnx__ModelProto methods */ +void onnx__model_proto__init + (Onnx__ModelProto *message); +size_t onnx__model_proto__get_packed_size + (const Onnx__ModelProto *message); +size_t onnx__model_proto__pack + (const Onnx__ModelProto *message, + uint8_t *out); +size_t onnx__model_proto__pack_to_buffer + (const Onnx__ModelProto *message, + ProtobufCBuffer *buffer); +Onnx__ModelProto * + onnx__model_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void onnx__model_proto__free_unpacked + (Onnx__ModelProto *message, + ProtobufCAllocator *allocator); +/* Onnx__StringStringEntryProto methods */ +void onnx__string_string_entry_proto__init + (Onnx__StringStringEntryProto *message); +size_t onnx__string_string_entry_proto__get_packed_size + (const Onnx__StringStringEntryProto *message); +size_t onnx__string_string_entry_proto__pack + (const Onnx__StringStringEntryProto *message, + uint8_t *out); +size_t onnx__string_string_entry_proto__pack_to_buffer + (const Onnx__StringStringEntryProto *message, + ProtobufCBuffer *buffer); +Onnx__StringStringEntryProto * + onnx__string_string_entry_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void onnx__string_string_entry_proto__free_unpacked + (Onnx__StringStringEntryProto *message, + ProtobufCAllocator *allocator); +/* Onnx__GraphProto methods */ +void onnx__graph_proto__init + (Onnx__GraphProto *message); +size_t onnx__graph_proto__get_packed_size + (const Onnx__GraphProto *message); +size_t onnx__graph_proto__pack + (const Onnx__GraphProto *message, + uint8_t *out); +size_t onnx__graph_proto__pack_to_buffer + (const Onnx__GraphProto *message, + ProtobufCBuffer *buffer); +Onnx__GraphProto * + onnx__graph_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void onnx__graph_proto__free_unpacked + (Onnx__GraphProto *message, + ProtobufCAllocator *allocator); +/* Onnx__TensorProto__Segment methods */ +void onnx__tensor_proto__segment__init + (Onnx__TensorProto__Segment *message); +/* Onnx__TensorProto methods */ +void onnx__tensor_proto__init + (Onnx__TensorProto *message); +size_t onnx__tensor_proto__get_packed_size + (const Onnx__TensorProto *message); +size_t onnx__tensor_proto__pack + (const Onnx__TensorProto *message, + uint8_t *out); +size_t onnx__tensor_proto__pack_to_buffer + (const Onnx__TensorProto *message, + ProtobufCBuffer *buffer); +Onnx__TensorProto * + onnx__tensor_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void onnx__tensor_proto__free_unpacked + (Onnx__TensorProto *message, + ProtobufCAllocator *allocator); +/* Onnx__TensorShapeProto__Dimension methods */ +void onnx__tensor_shape_proto__dimension__init + (Onnx__TensorShapeProto__Dimension *message); +/* Onnx__TensorShapeProto methods */ +void onnx__tensor_shape_proto__init + (Onnx__TensorShapeProto *message); +size_t onnx__tensor_shape_proto__get_packed_size + (const Onnx__TensorShapeProto *message); +size_t onnx__tensor_shape_proto__pack + (const Onnx__TensorShapeProto *message, + uint8_t *out); +size_t onnx__tensor_shape_proto__pack_to_buffer + (const Onnx__TensorShapeProto *message, + ProtobufCBuffer *buffer); +Onnx__TensorShapeProto * + onnx__tensor_shape_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void onnx__tensor_shape_proto__free_unpacked + (Onnx__TensorShapeProto *message, + ProtobufCAllocator *allocator); +/* Onnx__TypeProto__Tensor methods */ +void onnx__type_proto__tensor__init + (Onnx__TypeProto__Tensor *message); +/* Onnx__TypeProto methods */ +void onnx__type_proto__init + (Onnx__TypeProto *message); +size_t onnx__type_proto__get_packed_size + (const Onnx__TypeProto *message); +size_t onnx__type_proto__pack + (const Onnx__TypeProto *message, + uint8_t *out); +size_t onnx__type_proto__pack_to_buffer + (const Onnx__TypeProto *message, + ProtobufCBuffer *buffer); +Onnx__TypeProto * + onnx__type_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void onnx__type_proto__free_unpacked + (Onnx__TypeProto *message, + ProtobufCAllocator *allocator); +/* Onnx__OperatorSetIdProto methods */ +void onnx__operator_set_id_proto__init + (Onnx__OperatorSetIdProto *message); +size_t onnx__operator_set_id_proto__get_packed_size + (const Onnx__OperatorSetIdProto *message); +size_t onnx__operator_set_id_proto__pack + (const Onnx__OperatorSetIdProto *message, + uint8_t *out); +size_t onnx__operator_set_id_proto__pack_to_buffer + (const Onnx__OperatorSetIdProto *message, + ProtobufCBuffer *buffer); +Onnx__OperatorSetIdProto * + onnx__operator_set_id_proto__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void onnx__operator_set_id_proto__free_unpacked + (Onnx__OperatorSetIdProto *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Onnx__AttributeProto_Closure) + (const Onnx__AttributeProto *message, + void *closure_data); +typedef void (*Onnx__ValueInfoProto_Closure) + (const Onnx__ValueInfoProto *message, + void *closure_data); +typedef void (*Onnx__NodeProto_Closure) + (const Onnx__NodeProto *message, + void *closure_data); +typedef void (*Onnx__ModelProto_Closure) + (const Onnx__ModelProto *message, + void *closure_data); +typedef void (*Onnx__StringStringEntryProto_Closure) + (const Onnx__StringStringEntryProto *message, + void *closure_data); +typedef void (*Onnx__GraphProto_Closure) + (const Onnx__GraphProto *message, + void *closure_data); +typedef void (*Onnx__TensorProto__Segment_Closure) + (const Onnx__TensorProto__Segment *message, + void *closure_data); +typedef void (*Onnx__TensorProto_Closure) + (const Onnx__TensorProto *message, + void *closure_data); +typedef void (*Onnx__TensorShapeProto__Dimension_Closure) + (const Onnx__TensorShapeProto__Dimension *message, + void *closure_data); +typedef void (*Onnx__TensorShapeProto_Closure) + (const Onnx__TensorShapeProto *message, + void *closure_data); +typedef void (*Onnx__TypeProto__Tensor_Closure) + (const Onnx__TypeProto__Tensor *message, + void *closure_data); +typedef void (*Onnx__TypeProto_Closure) + (const Onnx__TypeProto *message, + void *closure_data); +typedef void (*Onnx__OperatorSetIdProto_Closure) + (const Onnx__OperatorSetIdProto *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCEnumDescriptor onnx__version__descriptor; +extern const ProtobufCMessageDescriptor onnx__attribute_proto__descriptor; +extern const ProtobufCEnumDescriptor onnx__attribute_proto__attribute_type__descriptor; +extern const ProtobufCMessageDescriptor onnx__value_info_proto__descriptor; +extern const ProtobufCMessageDescriptor onnx__node_proto__descriptor; +extern const ProtobufCMessageDescriptor onnx__model_proto__descriptor; +extern const ProtobufCMessageDescriptor onnx__string_string_entry_proto__descriptor; +extern const ProtobufCMessageDescriptor onnx__graph_proto__descriptor; +extern const ProtobufCMessageDescriptor onnx__tensor_proto__descriptor; +extern const ProtobufCMessageDescriptor onnx__tensor_proto__segment__descriptor; +extern const ProtobufCEnumDescriptor onnx__tensor_proto__data_type__descriptor; +extern const ProtobufCMessageDescriptor onnx__tensor_shape_proto__descriptor; +extern const ProtobufCMessageDescriptor onnx__tensor_shape_proto__dimension__descriptor; +extern const ProtobufCMessageDescriptor onnx__type_proto__descriptor; +extern const ProtobufCMessageDescriptor onnx__type_proto__tensor__descriptor; +extern const ProtobufCMessageDescriptor onnx__operator_set_id_proto__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_src_2fonnx_2eproto__INCLUDED */ diff --git a/components/ai/onnx/protobuf/protobuf-c.c b/components/ai/onnx/protobuf/protobuf-c.c new file mode 100644 index 00000000..2a37322e --- /dev/null +++ b/components/ai/onnx/protobuf/protobuf-c.c @@ -0,0 +1,3666 @@ +/* + * Copyright (c) 2008-2015, Dave Benson and the protobuf-c authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/*! \file + * Support library for `protoc-c` generated code. + * + * This file implements the public API used by the code generated + * by `protoc-c`. + * + * \authors Dave Benson and the protobuf-c authors + * + * \copyright 2008-2014. Licensed under the terms of the [BSD-2-Clause] license. + */ + +/** + * \todo 64-BIT OPTIMIZATION: certain implementations use 32-bit math + * even on 64-bit platforms (uint64_size, uint64_pack, parse_uint64). + * + * \todo Use size_t consistently. + */ + +#include /* for malloc, free */ +#include /* for strcmp, strlen, memcpy, memmove, memset */ + +#include "protobuf-c.h" + +#define TRUE 1 +#define FALSE 0 + +//#define PROTOBUF_C__ASSERT_NOT_REACHED() assert(0) + +/* Workaround for Microsoft compilers. */ +#ifdef _MSC_VER +# define inline __inline +#endif + +/** + * \defgroup internal Internal functions and macros + * + * These are not exported by the library but are useful to developers working + * on `libprotobuf-c` itself. + */ + +/** + * \defgroup macros Utility macros for manipulating structures + * + * Macros and constants used to manipulate the base "classes" generated by + * `protobuf-c`. They also define limits and check correctness. + * + * \ingroup internal + * @{ + */ + +/** The maximum length of a 64-bit integer in varint encoding. */ +#define MAX_UINT64_ENCODED_SIZE 10 + +#ifndef PROTOBUF_C_UNPACK_ERROR +# define PROTOBUF_C_UNPACK_ERROR(...) +#endif + +const char protobuf_c_empty_string[] = ""; + +/** + * Internal `ProtobufCMessage` manipulation macro. + * + * Base macro for manipulating a `ProtobufCMessage`. Used by STRUCT_MEMBER() and + * STRUCT_MEMBER_PTR(). + */ +#define STRUCT_MEMBER_P(struct_p, struct_offset) \ + ((void *) ((uint8_t *) (struct_p) + (struct_offset))) + +/** + * Return field in a `ProtobufCMessage` based on offset. + * + * Take a pointer to a `ProtobufCMessage` and find the field at the offset. + * Cast it to the passed type. + */ +#define STRUCT_MEMBER(member_type, struct_p, struct_offset) \ + (*(member_type *) STRUCT_MEMBER_P((struct_p), (struct_offset))) + +/** + * Return field in a `ProtobufCMessage` based on offset. + * + * Take a pointer to a `ProtobufCMessage` and find the field at the offset. Cast + * it to a pointer to the passed type. + */ +#define STRUCT_MEMBER_PTR(member_type, struct_p, struct_offset) \ + ((member_type *) STRUCT_MEMBER_P((struct_p), (struct_offset))) + +/* Assertions for magic numbers. */ +/* +#define ASSERT_IS_ENUM_DESCRIPTOR(desc) \ + //assert((desc)->magic == PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC) + +#define ASSERT_IS_MESSAGE_DESCRIPTOR(desc) \ + //assert((desc)->magic == PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) + +#define ASSERT_IS_MESSAGE(message) \ + ASSERT_IS_MESSAGE_DESCRIPTOR((message)->descriptor) + +#define ASSERT_IS_SERVICE_DESCRIPTOR(desc) \ + assert((desc)->magic == PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC) +*/ +/**@}*/ + +/* --- version --- */ + +const char * +protobuf_c_version(void) +{ + return PROTOBUF_C_VERSION; +} + +uint32_t +protobuf_c_version_number(void) +{ + return PROTOBUF_C_VERSION_NUMBER; +} + +/* --- allocator --- */ + +static void * +system_alloc(void *allocator_data, size_t size) +{ + return malloc(size); +} + +static void +system_free(void *allocator_data, void *data) +{ + free(data); +} + +static inline void * +do_alloc(ProtobufCAllocator *allocator, size_t size) +{ + return allocator->alloc(allocator->allocator_data, size); +} + +static inline void +do_free(ProtobufCAllocator *allocator, void *data) +{ + if (data != NULL) + allocator->free(allocator->allocator_data, data); +} + +/* + * This allocator uses the system's malloc() and free(). It is the default + * allocator used if NULL is passed as the ProtobufCAllocator to an exported + * function. + */ +static ProtobufCAllocator protobuf_c__allocator = { + .alloc = &system_alloc, + .free = &system_free, + .allocator_data = NULL, +}; + +/* === buffer-simple === */ + +void +protobuf_c_buffer_simple_append(ProtobufCBuffer *buffer, + size_t len, const uint8_t *data) +{ + ProtobufCBufferSimple *simp = (ProtobufCBufferSimple *) buffer; + size_t new_len = simp->len + len; + + if (new_len > simp->alloced) { + ProtobufCAllocator *allocator = simp->allocator; + size_t new_alloced = simp->alloced * 2; + uint8_t *new_data; + + if (allocator == NULL) + allocator = &protobuf_c__allocator; + while (new_alloced < new_len) + new_alloced += new_alloced; + new_data = do_alloc(allocator, new_alloced); + if (!new_data) + return; + memcpy(new_data, simp->data, simp->len); + if (simp->must_free_data) + do_free(allocator, simp->data); + else + simp->must_free_data = TRUE; + simp->data = new_data; + simp->alloced = new_alloced; + } + memcpy(simp->data + simp->len, data, len); + simp->len = new_len; +} + +/** + * \defgroup packedsz protobuf_c_message_get_packed_size() implementation + * + * Routines mainly used by protobuf_c_message_get_packed_size(). + * + * \ingroup internal + * @{ + */ + +/** + * Return the number of bytes required to store the tag for the field. Includes + * 3 bits for the wire-type, and a single bit that denotes the end-of-tag. + * + * \param number + * Field tag to encode. + * \return + * Number of bytes required. + */ +static inline size_t +get_tag_size(uint32_t number) +{ + if (number < (1UL << 4)) { + return 1; + } else if (number < (1UL << 11)) { + return 2; + } else if (number < (1UL << 18)) { + return 3; + } else if (number < (1UL << 25)) { + return 4; + } else { + return 5; + } +} + +/** + * Return the number of bytes required to store a variable-length unsigned + * 32-bit integer in base-128 varint encoding. + * + * \param v + * Value to encode. + * \return + * Number of bytes required. + */ +static inline size_t +uint32_size(uint32_t v) +{ + if (v < (1UL << 7)) { + return 1; + } else if (v < (1UL << 14)) { + return 2; + } else if (v < (1UL << 21)) { + return 3; + } else if (v < (1UL << 28)) { + return 4; + } else { + return 5; + } +} + +/** + * Return the number of bytes required to store a variable-length signed 32-bit + * integer in base-128 varint encoding. + * + * \param v + * Value to encode. + * \return + * Number of bytes required. + */ +static inline size_t +int32_size(int32_t v) +{ + if (v < 0) { + return 10; + } else if (v < (1L << 7)) { + return 1; + } else if (v < (1L << 14)) { + return 2; + } else if (v < (1L << 21)) { + return 3; + } else if (v < (1L << 28)) { + return 4; + } else { + return 5; + } +} + +/** + * Return the ZigZag-encoded 32-bit unsigned integer form of a 32-bit signed + * integer. + * + * \param v + * Value to encode. + * \return + * ZigZag encoded integer. + */ +static inline uint32_t +zigzag32(int32_t v) +{ + if (v < 0) + return (-(uint32_t)v) * 2 - 1; + else + return (uint32_t)(v) * 2; +} + +/** + * Return the number of bytes required to store a signed 32-bit integer, + * converted to an unsigned 32-bit integer with ZigZag encoding, using base-128 + * varint encoding. + * + * \param v + * Value to encode. + * \return + * Number of bytes required. + */ +static inline size_t +sint32_size(int32_t v) +{ + return uint32_size(zigzag32(v)); +} + +/** + * Return the number of bytes required to store a 64-bit unsigned integer in + * base-128 varint encoding. + * + * \param v + * Value to encode. + * \return + * Number of bytes required. + */ +static inline size_t +uint64_size(uint64_t v) +{ + uint32_t upper_v = (uint32_t) (v >> 32); + + if (upper_v == 0) { + return uint32_size((uint32_t) v); + } else if (upper_v < (1UL << 3)) { + return 5; + } else if (upper_v < (1UL << 10)) { + return 6; + } else if (upper_v < (1UL << 17)) { + return 7; + } else if (upper_v < (1UL << 24)) { + return 8; + } else if (upper_v < (1UL << 31)) { + return 9; + } else { + return 10; + } +} + +/** + * Return the ZigZag-encoded 64-bit unsigned integer form of a 64-bit signed + * integer. + * + * \param v + * Value to encode. + * \return + * ZigZag encoded integer. + */ +static inline uint64_t +zigzag64(int64_t v) +{ + if (v < 0) + return (-(uint64_t)v) * 2 - 1; + else + return (uint64_t)(v) * 2; +} + +/** + * Return the number of bytes required to store a signed 64-bit integer, + * converted to an unsigned 64-bit integer with ZigZag encoding, using base-128 + * varint encoding. + * + * \param v + * Value to encode. + * \return + * Number of bytes required. + */ +static inline size_t +sint64_size(int64_t v) +{ + return uint64_size(zigzag64(v)); +} + +/** + * Calculate the serialized size of a single required message field, including + * the space needed by the preceding tag. + * + * \param field + * Field descriptor for member. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t +required_field_get_packed_size(const ProtobufCFieldDescriptor *field, + const void *member) +{ + size_t rv = get_tag_size(field->id); + + switch (field->type) { + case PROTOBUF_C_TYPE_SINT32: + return rv + sint32_size(*(const int32_t *) member); + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + return rv + int32_size(*(const int32_t *) member); + case PROTOBUF_C_TYPE_UINT32: + return rv + uint32_size(*(const uint32_t *) member); + case PROTOBUF_C_TYPE_SINT64: + return rv + sint64_size(*(const int64_t *) member); + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + return rv + uint64_size(*(const uint64_t *) member); + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + return rv + 4; + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + return rv + 8; + case PROTOBUF_C_TYPE_BOOL: + return rv + 1; + case PROTOBUF_C_TYPE_FLOAT: + return rv + 4; + case PROTOBUF_C_TYPE_DOUBLE: + return rv + 8; + case PROTOBUF_C_TYPE_STRING: { + const char *str = *(char * const *) member; + size_t len = str ? strlen(str) : 0; + return rv + uint32_size(len) + len; + } + case PROTOBUF_C_TYPE_BYTES: { + size_t len = ((const ProtobufCBinaryData *) member)->len; + return rv + uint32_size(len) + len; + } + case PROTOBUF_C_TYPE_MESSAGE: { + const ProtobufCMessage *msg = *(ProtobufCMessage * const *) member; + size_t subrv = msg ? protobuf_c_message_get_packed_size(msg) : 0; + return rv + uint32_size(subrv) + subrv; + } + } + //PROTOBUF_C__ASSERT_NOT_REACHED(); + return 0; +} + +/** + * Calculate the serialized size of a single oneof message field, including + * the space needed by the preceding tag. Returns 0 if the oneof field isn't + * selected or is not set. + * + * \param field + * Field descriptor for member. + * \param oneof_case + * Enum value that selects the field in the oneof. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t +oneof_field_get_packed_size(const ProtobufCFieldDescriptor *field, + uint32_t oneof_case, + const void *member) +{ + if (oneof_case != field->id) { + return 0; + } + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void * const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } + return required_field_get_packed_size(field, member); +} + +/** + * Calculate the serialized size of a single optional message field, including + * the space needed by the preceding tag. Returns 0 if the optional field isn't + * set. + * + * \param field + * Field descriptor for member. + * \param has + * True if the field exists, false if not. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t +optional_field_get_packed_size(const ProtobufCFieldDescriptor *field, + const protobuf_c_boolean has, + const void *member) +{ + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void * const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } else { + if (!has) + return 0; + } + return required_field_get_packed_size(field, member); +} + +static protobuf_c_boolean +field_is_zeroish(const ProtobufCFieldDescriptor *field, + const void *member) +{ + protobuf_c_boolean ret = FALSE; + + switch (field->type) { + case PROTOBUF_C_TYPE_BOOL: + ret = (0 == *(const protobuf_c_boolean *) member); + break; + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_SINT32: + case PROTOBUF_C_TYPE_INT32: + case PROTOBUF_C_TYPE_UINT32: + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + ret = (0 == *(const uint32_t *) member); + break; + case PROTOBUF_C_TYPE_SINT64: + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + ret = (0 == *(const uint64_t *) member); + break; + case PROTOBUF_C_TYPE_FLOAT: + ret = (0 == *(const int *) member); + break; + case PROTOBUF_C_TYPE_DOUBLE: + ret = (0 == *(const double *) member); + break; + case PROTOBUF_C_TYPE_STRING: + ret = (NULL == *(const char * const *) member) || + ('\0' == **(const char * const *) member); + break; + case PROTOBUF_C_TYPE_BYTES: + case PROTOBUF_C_TYPE_MESSAGE: + ret = (NULL == *(const void * const *) member); + break; + default: + ret = TRUE; + break; + } + + return ret; +} + +/** + * Calculate the serialized size of a single unlabeled message field, including + * the space needed by the preceding tag. Returns 0 if the field isn't set or + * if it is set to a "zeroish" value (null pointer or 0 for numerical values). + * Unlabeled fields are supported only in proto3. + * + * \param field + * Field descriptor for member. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t +unlabeled_field_get_packed_size(const ProtobufCFieldDescriptor *field, + const void *member) +{ + if (field_is_zeroish(field, member)) + return 0; + return required_field_get_packed_size(field, member); +} + +/** + * Calculate the serialized size of repeated message fields, which may consist + * of any number of values (including 0). Includes the space needed by the + * preceding tags (as needed). + * + * \param field + * Field descriptor for member. + * \param count + * Number of repeated field members. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t +repeated_field_get_packed_size(const ProtobufCFieldDescriptor *field, + size_t count, const void *member) +{ + size_t header_size; + size_t rv = 0; + unsigned i; + void *array = *(void * const *) member; + + if (count == 0) + return 0; + header_size = get_tag_size(field->id); + if (0 == (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED)) + header_size *= count; + + switch (field->type) { + case PROTOBUF_C_TYPE_SINT32: + for (i = 0; i < count; i++) + rv += sint32_size(((int32_t *) array)[i]); + break; + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + for (i = 0; i < count; i++) + rv += int32_size(((int32_t *) array)[i]); + break; + case PROTOBUF_C_TYPE_UINT32: + for (i = 0; i < count; i++) + rv += uint32_size(((uint32_t *) array)[i]); + break; + case PROTOBUF_C_TYPE_SINT64: + for (i = 0; i < count; i++) + rv += sint64_size(((int64_t *) array)[i]); + break; + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + for (i = 0; i < count; i++) + rv += uint64_size(((uint64_t *) array)[i]); + break; + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + rv += 4 * count; + break; + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + rv += 8 * count; + break; + case PROTOBUF_C_TYPE_BOOL: + rv += count; + break; + case PROTOBUF_C_TYPE_STRING: + for (i = 0; i < count; i++) { + size_t len = strlen(((char **) array)[i]); + rv += uint32_size(len) + len; + } + break; + case PROTOBUF_C_TYPE_BYTES: + for (i = 0; i < count; i++) { + size_t len = ((ProtobufCBinaryData *) array)[i].len; + rv += uint32_size(len) + len; + } + break; + case PROTOBUF_C_TYPE_MESSAGE: + for (i = 0; i < count; i++) { + size_t len = protobuf_c_message_get_packed_size( + ((ProtobufCMessage **) array)[i]); + rv += uint32_size(len) + len; + } + break; + } + + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED)) + header_size += uint32_size(rv); + return header_size + rv; +} + +/** + * Calculate the serialized size of an unknown field, i.e. one that is passed + * through mostly uninterpreted. This is required for forward compatibility if + * new fields are added to the message descriptor. + * + * \param field + * Unknown field type. + * \return + * Number of bytes required. + */ +static inline size_t +unknown_field_get_packed_size(const ProtobufCMessageUnknownField *field) +{ + return get_tag_size(field->tag) + field->len; +} + +/**@}*/ + +/* + * Calculate the serialized size of the message. + */ +size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message) +{ + unsigned i; + size_t rv = 0; + + //ASSERT_IS_MESSAGE(message); + for (i = 0; i < message->descriptor->n_fields; i++) { + const ProtobufCFieldDescriptor *field = + message->descriptor->fields + i; + const void *member = + ((const char *) message) + field->offset; + const void *qmember = + ((const char *) message) + field->quantifier_offset; + + if (field->label == PROTOBUF_C_LABEL_REQUIRED) { + rv += required_field_get_packed_size(field, member); + } else if ((field->label == PROTOBUF_C_LABEL_OPTIONAL || + field->label == PROTOBUF_C_LABEL_NONE) && + (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF))) { + rv += oneof_field_get_packed_size( + field, + *(const uint32_t *) qmember, + member + ); + } else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) { + rv += optional_field_get_packed_size( + field, + *(protobuf_c_boolean *) qmember, + member + ); + } else if (field->label == PROTOBUF_C_LABEL_NONE) { + rv += unlabeled_field_get_packed_size( + field, + member + ); + } else { + rv += repeated_field_get_packed_size( + field, + *(const size_t *) qmember, + member + ); + } + } + for (i = 0; i < message->n_unknown_fields; i++) + rv += unknown_field_get_packed_size(&message->unknown_fields[i]); + return rv; +} + +/** + * \defgroup pack protobuf_c_message_pack() implementation + * + * Routines mainly used by protobuf_c_message_pack(). + * + * \ingroup internal + * @{ + */ + +/** + * Pack an unsigned 32-bit integer in base-128 varint encoding and return the + * number of bytes written, which must be 5 or less. + * + * \param value + * Value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static inline size_t +uint32_pack(uint32_t value, uint8_t *out) +{ + unsigned rv = 0; + + if (value >= 0x80) { + out[rv++] = value | 0x80; + value >>= 7; + if (value >= 0x80) { + out[rv++] = value | 0x80; + value >>= 7; + if (value >= 0x80) { + out[rv++] = value | 0x80; + value >>= 7; + if (value >= 0x80) { + out[rv++] = value | 0x80; + value >>= 7; + } + } + } + } + /* assert: value<128 */ + out[rv++] = value; + return rv; +} + +/** + * Pack a signed 32-bit integer and return the number of bytes written. + * Negative numbers are encoded as two's complement 64-bit integers. + * + * \param value + * Value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static inline size_t +int32_pack(int32_t value, uint8_t *out) +{ + if (value < 0) { + out[0] = value | 0x80; + out[1] = (value >> 7) | 0x80; + out[2] = (value >> 14) | 0x80; + out[3] = (value >> 21) | 0x80; + out[4] = (value >> 28) | 0x80; + out[5] = out[6] = out[7] = out[8] = 0xff; + out[9] = 0x01; + return 10; + } else { + return uint32_pack(value, out); + } +} + +/** + * Pack a signed 32-bit integer using ZigZag encoding and return the number of + * bytes written. + * + * \param value + * Value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static inline size_t +sint32_pack(int32_t value, uint8_t *out) +{ + return uint32_pack(zigzag32(value), out); +} + +/** + * Pack a 64-bit unsigned integer using base-128 varint encoding and return the + * number of bytes written. + * + * \param value + * Value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static size_t +uint64_pack(uint64_t value, uint8_t *out) +{ + uint32_t hi = (uint32_t) (value >> 32); + uint32_t lo = (uint32_t) value; + unsigned rv; + + if (hi == 0) + return uint32_pack((uint32_t) lo, out); + out[0] = (lo) | 0x80; + out[1] = (lo >> 7) | 0x80; + out[2] = (lo >> 14) | 0x80; + out[3] = (lo >> 21) | 0x80; + if (hi < 8) { + out[4] = (hi << 4) | (lo >> 28); + return 5; + } else { + out[4] = ((hi & 7) << 4) | (lo >> 28) | 0x80; + hi >>= 3; + } + rv = 5; + while (hi >= 128) { + out[rv++] = hi | 0x80; + hi >>= 7; + } + out[rv++] = hi; + return rv; +} + +/** + * Pack a 64-bit signed integer in ZigZag encoding and return the number of + * bytes written. + * + * \param value + * Value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static inline size_t +sint64_pack(int64_t value, uint8_t *out) +{ + return uint64_pack(zigzag64(value), out); +} + +/** + * Pack a 32-bit quantity in little-endian byte order. Used for protobuf wire + * types fixed32, sfixed32, int. Similar to "htole32". + * + * \param value + * Value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static inline size_t +fixed32_pack(uint32_t value, void *out) +{ +#if !defined(WORDS_BIGENDIAN) + memcpy(out, &value, 4); +#else + uint8_t *buf = out; + + buf[0] = value; + buf[1] = value >> 8; + buf[2] = value >> 16; + buf[3] = value >> 24; +#endif + return 4; +} + +/** + * Pack a 64-bit quantity in little-endian byte order. Used for protobuf wire + * types fixed64, sfixed64, double. Similar to "htole64". + * + * \todo The big-endian impl is really only good for 32-bit machines, a 64-bit + * version would be appreciated, plus a way to decide to use 64-bit math where + * convenient. + * + * \param value + * Value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static inline size_t +fixed64_pack(uint64_t value, void *out) +{ +#if !defined(WORDS_BIGENDIAN) + memcpy(out, &value, 8); +#else + fixed32_pack(value, out); + fixed32_pack(value >> 32, ((char *) out) + 4); +#endif + return 8; +} + +/** + * Pack a boolean value as an integer and return the number of bytes written. + * + * \todo Perhaps on some platforms *out = !!value would be a better impl, b/c + * that is idiomatic C++ in some STL implementations. + * + * \param value + * Value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static inline size_t +boolean_pack(protobuf_c_boolean value, uint8_t *out) +{ + *out = value ? TRUE : FALSE; + return 1; +} + +/** + * Pack a NUL-terminated C string and return the number of bytes written. The + * output includes a length delimiter. + * + * The NULL pointer is treated as an empty string. This isn't really necessary, + * but it allows people to leave required strings blank. (See Issue #13 in the + * bug tracker for a little more explanation). + * + * \param str + * String to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static inline size_t +string_pack(const char *str, uint8_t *out) +{ + if (str == NULL) { + out[0] = 0; + return 1; + } else { + size_t len = strlen(str); + size_t rv = uint32_pack(len, out); + memcpy(out + rv, str, len); + return rv + len; + } +} + +/** + * Pack a ProtobufCBinaryData and return the number of bytes written. The output + * includes a length delimiter. + * + * \param bd + * ProtobufCBinaryData to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static inline size_t +binary_data_pack(const ProtobufCBinaryData *bd, uint8_t *out) +{ + size_t len = bd->len; + size_t rv = uint32_pack(len, out); + memcpy(out + rv, bd->data, len); + return rv + len; +} + +/** + * Pack a ProtobufCMessage and return the number of bytes written. The output + * includes a length delimiter. + * + * \param message + * ProtobufCMessage object to pack. + * \param[out] out + * Packed message. + * \return + * Number of bytes written to `out`. + */ +static inline size_t +prefixed_message_pack(const ProtobufCMessage *message, uint8_t *out) +{ + if (message == NULL) { + out[0] = 0; + return 1; + } else { + size_t rv = protobuf_c_message_pack(message, out + 1); + uint32_t rv_packed_size = uint32_size(rv); + if (rv_packed_size != 1) + memmove(out + rv_packed_size, out + 1, rv); + return uint32_pack(rv, out) + rv; + } +} + +/** + * Pack a field tag. + * + * Wire-type will be added in required_field_pack(). + * + * \todo Just call uint64_pack on 64-bit platforms. + * + * \param id + * Tag value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static size_t +tag_pack(uint32_t id, uint8_t *out) +{ + if (id < (1UL << (32 - 3))) + return uint32_pack(id << 3, out); + else + return uint64_pack(((uint64_t) id) << 3, out); +} + +/** + * Pack a required field and return the number of bytes written. + * + * \param field + * Field descriptor. + * \param member + * The field member. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static size_t +required_field_pack(const ProtobufCFieldDescriptor *field, + const void *member, uint8_t *out) +{ + size_t rv = tag_pack(field->id, out); + + switch (field->type) { + case PROTOBUF_C_TYPE_SINT32: + out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + return rv + sint32_pack(*(const int32_t *) member, out + rv); + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + return rv + int32_pack(*(const int32_t *) member, out + rv); + case PROTOBUF_C_TYPE_UINT32: + out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + return rv + uint32_pack(*(const uint32_t *) member, out + rv); + case PROTOBUF_C_TYPE_SINT64: + out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + return rv + sint64_pack(*(const int64_t *) member, out + rv); + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + return rv + uint64_pack(*(const uint64_t *) member, out + rv); + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + out[0] |= PROTOBUF_C_WIRE_TYPE_32BIT; + return rv + fixed32_pack(*(const uint32_t *) member, out + rv); + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + out[0] |= PROTOBUF_C_WIRE_TYPE_64BIT; + return rv + fixed64_pack(*(const uint64_t *) member, out + rv); + case PROTOBUF_C_TYPE_BOOL: + out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + return rv + boolean_pack(*(const protobuf_c_boolean *) member, out + rv); + case PROTOBUF_C_TYPE_STRING: + out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; + return rv + string_pack(*(char *const *) member, out + rv); + case PROTOBUF_C_TYPE_BYTES: + out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; + return rv + binary_data_pack((const ProtobufCBinaryData *) member, out + rv); + case PROTOBUF_C_TYPE_MESSAGE: + out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; + return rv + prefixed_message_pack(*(ProtobufCMessage * const *) member, out + rv); + } + //PROTOBUF_C__ASSERT_NOT_REACHED(); + return 0; +} + +/** + * Pack a oneof field and return the number of bytes written. Only packs the + * field that is selected by the case enum. + * + * \param field + * Field descriptor. + * \param oneof_case + * Enum value that selects the field in the oneof. + * \param member + * The field member. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static size_t +oneof_field_pack(const ProtobufCFieldDescriptor *field, + uint32_t oneof_case, + const void *member, uint8_t *out) +{ + if (oneof_case != field->id) { + return 0; + } + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void * const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } + return required_field_pack(field, member, out); +} + +/** + * Pack an optional field and return the number of bytes written. + * + * \param field + * Field descriptor. + * \param has + * Whether the field is set. + * \param member + * The field member. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static size_t +optional_field_pack(const ProtobufCFieldDescriptor *field, + const protobuf_c_boolean has, + const void *member, uint8_t *out) +{ + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void * const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } else { + if (!has) + return 0; + } + return required_field_pack(field, member, out); +} + +/** + * Pack an unlabeled field and return the number of bytes written. + * + * \param field + * Field descriptor. + * \param member + * The field member. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static size_t +unlabeled_field_pack(const ProtobufCFieldDescriptor *field, + const void *member, uint8_t *out) +{ + if (field_is_zeroish(field, member)) + return 0; + return required_field_pack(field, member, out); +} + +/** + * Given a field type, return the in-memory size. + * + * \todo Implement as a table lookup. + * + * \param type + * Field type. + * \return + * Size of the field. + */ +static inline size_t +sizeof_elt_in_repeated_array(ProtobufCType type) +{ + switch (type) { + case PROTOBUF_C_TYPE_SINT32: + case PROTOBUF_C_TYPE_INT32: + case PROTOBUF_C_TYPE_UINT32: + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + case PROTOBUF_C_TYPE_ENUM: + return 4; + case PROTOBUF_C_TYPE_SINT64: + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + return 8; + case PROTOBUF_C_TYPE_BOOL: + return sizeof(protobuf_c_boolean); + case PROTOBUF_C_TYPE_STRING: + case PROTOBUF_C_TYPE_MESSAGE: + return sizeof(void *); + case PROTOBUF_C_TYPE_BYTES: + return sizeof(ProtobufCBinaryData); + } + //PROTOBUF_C__ASSERT_NOT_REACHED(); + return 0; +} + +/** + * Pack an array of 32-bit quantities. + * + * \param[out] out + * Destination. + * \param[in] in + * Source. + * \param[in] n + * Number of elements in the source array. + */ +static void +copy_to_little_endian_32(void *out, const void *in, const unsigned n) +{ +#if !defined(WORDS_BIGENDIAN) + memcpy(out, in, n * 4); +#else + unsigned i; + const uint32_t *ini = in; + for (i = 0; i < n; i++) + fixed32_pack(ini[i], (uint32_t *) out + i); +#endif +} + +/** + * Pack an array of 64-bit quantities. + * + * \param[out] out + * Destination. + * \param[in] in + * Source. + * \param[in] n + * Number of elements in the source array. + */ +static void +copy_to_little_endian_64(void *out, const void *in, const unsigned n) +{ +#if !defined(WORDS_BIGENDIAN) + memcpy(out, in, n * 8); +#else + unsigned i; + const uint64_t *ini = in; + for (i = 0; i < n; i++) + fixed64_pack(ini[i], (uint64_t *) out + i); +#endif +} + +/** + * Get the minimum number of bytes required to pack a field value of a + * particular type. + * + * \param type + * Field type. + * \return + * Number of bytes. + */ +static unsigned +get_type_min_size(ProtobufCType type) +{ + if (type == PROTOBUF_C_TYPE_SFIXED32 || + type == PROTOBUF_C_TYPE_FIXED32 || + type == PROTOBUF_C_TYPE_FLOAT) + { + return 4; + } + if (type == PROTOBUF_C_TYPE_SFIXED64 || + type == PROTOBUF_C_TYPE_FIXED64 || + type == PROTOBUF_C_TYPE_DOUBLE) + { + return 8; + } + return 1; +} + +/** + * Packs the elements of a repeated field and returns the serialised field and + * its length. + * + * \param field + * Field descriptor. + * \param count + * Number of elements in the repeated field array. + * \param member + * Pointer to the elements for this repeated field. + * \param[out] out + * Serialised representation of the repeated field. + * \return + * Number of bytes serialised to `out`. + */ +static size_t +repeated_field_pack(const ProtobufCFieldDescriptor *field, + size_t count, const void *member, uint8_t *out) +{ + void *array = *(void * const *) member; + unsigned i; + + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED)) { + unsigned header_len; + unsigned len_start; + unsigned min_length; + unsigned payload_len; + unsigned length_size_min; + unsigned actual_length_size; + uint8_t *payload_at; + + if (count == 0) + return 0; + header_len = tag_pack(field->id, out); + out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; + len_start = header_len; + min_length = get_type_min_size(field->type) * count; + length_size_min = uint32_size(min_length); + header_len += length_size_min; + payload_at = out + header_len; + + switch (field->type) { + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + copy_to_little_endian_32(payload_at, array, count); + payload_at += count * 4; + break; + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + copy_to_little_endian_64(payload_at, array, count); + payload_at += count * 8; + break; + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: { + const int32_t *arr = (const int32_t *) array; + for (i = 0; i < count; i++) + payload_at += int32_pack(arr[i], payload_at); + break; + } + case PROTOBUF_C_TYPE_SINT32: { + const int32_t *arr = (const int32_t *) array; + for (i = 0; i < count; i++) + payload_at += sint32_pack(arr[i], payload_at); + break; + } + case PROTOBUF_C_TYPE_SINT64: { + const int64_t *arr = (const int64_t *) array; + for (i = 0; i < count; i++) + payload_at += sint64_pack(arr[i], payload_at); + break; + } + case PROTOBUF_C_TYPE_UINT32: { + const uint32_t *arr = (const uint32_t *) array; + for (i = 0; i < count; i++) + payload_at += uint32_pack(arr[i], payload_at); + break; + } + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: { + const uint64_t *arr = (const uint64_t *) array; + for (i = 0; i < count; i++) + payload_at += uint64_pack(arr[i], payload_at); + break; + } + case PROTOBUF_C_TYPE_BOOL: { + const protobuf_c_boolean *arr = (const protobuf_c_boolean *) array; + for (i = 0; i < count; i++) + payload_at += boolean_pack(arr[i], payload_at); + break; + } + //default: + //PROTOBUF_C__ASSERT_NOT_REACHED(); + } + + payload_len = payload_at - (out + header_len); + actual_length_size = uint32_size(payload_len); + if (length_size_min != actual_length_size) { + //assert(actual_length_size == length_size_min + 1); + memmove(out + header_len + 1, out + header_len, + payload_len); + header_len++; + } + uint32_pack(payload_len, out + len_start); + return header_len + payload_len; + } else { + /* not "packed" cased */ + /* CONSIDER: optimize this case a bit (by putting the loop inside the switch) */ + size_t rv = 0; + unsigned siz = sizeof_elt_in_repeated_array(field->type); + + for (i = 0; i < count; i++) { + rv += required_field_pack(field, array, out + rv); + array = (char *)array + siz; + } + return rv; + } +} + +static size_t +unknown_field_pack(const ProtobufCMessageUnknownField *field, uint8_t *out) +{ + size_t rv = tag_pack(field->tag, out); + out[0] |= field->wire_type; + memcpy(out + rv, field->data, field->len); + return rv + field->len; +} + +/**@}*/ + +size_t +protobuf_c_message_pack(const ProtobufCMessage *message, uint8_t *out) +{ + unsigned i; + size_t rv = 0; + + //ASSERT_IS_MESSAGE(message); + for (i = 0; i < message->descriptor->n_fields; i++) { + const ProtobufCFieldDescriptor *field = + message->descriptor->fields + i; + const void *member = ((const char *) message) + field->offset; + + /* + * It doesn't hurt to compute qmember (a pointer to the + * quantifier field of the structure), but the pointer is only + * valid if the field is: + * - a repeated field, or + * - a field that is part of a oneof + * - an optional field that isn't a pointer type + * (Meaning: not a message or a string). + */ + const void *qmember = + ((const char *) message) + field->quantifier_offset; + + if (field->label == PROTOBUF_C_LABEL_REQUIRED) { + rv += required_field_pack(field, member, out + rv); + } else if ((field->label == PROTOBUF_C_LABEL_OPTIONAL || + field->label == PROTOBUF_C_LABEL_NONE) && + (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF))) { + rv += oneof_field_pack( + field, + *(const uint32_t *) qmember, + member, + out + rv + ); + } else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) { + rv += optional_field_pack( + field, + *(const protobuf_c_boolean *) qmember, + member, + out + rv + ); + } else if (field->label == PROTOBUF_C_LABEL_NONE) { + rv += unlabeled_field_pack(field, member, out + rv); + } else { + rv += repeated_field_pack(field, *(const size_t *) qmember, + member, out + rv); + } + } + for (i = 0; i < message->n_unknown_fields; i++) + rv += unknown_field_pack(&message->unknown_fields[i], out + rv); + return rv; +} + +/** + * \defgroup packbuf protobuf_c_message_pack_to_buffer() implementation + * + * Routines mainly used by protobuf_c_message_pack_to_buffer(). + * + * \ingroup internal + * @{ + */ + +/** + * Pack a required field to a virtual buffer. + * + * \param field + * Field descriptor. + * \param member + * The element to be packed. + * \param[out] buffer + * Virtual buffer to append data to. + * \return + * Number of bytes packed. + */ +static size_t +required_field_pack_to_buffer(const ProtobufCFieldDescriptor *field, + const void *member, ProtobufCBuffer *buffer) +{ + size_t rv; + uint8_t scratch[MAX_UINT64_ENCODED_SIZE * 2]; + + rv = tag_pack(field->id, scratch); + switch (field->type) { + case PROTOBUF_C_TYPE_SINT32: + scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + rv += sint32_pack(*(const int32_t *) member, scratch + rv); + buffer->append(buffer, rv, scratch); + break; + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + rv += int32_pack(*(const int32_t *) member, scratch + rv); + buffer->append(buffer, rv, scratch); + break; + case PROTOBUF_C_TYPE_UINT32: + scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + rv += uint32_pack(*(const uint32_t *) member, scratch + rv); + buffer->append(buffer, rv, scratch); + break; + case PROTOBUF_C_TYPE_SINT64: + scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + rv += sint64_pack(*(const int64_t *) member, scratch + rv); + buffer->append(buffer, rv, scratch); + break; + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + rv += uint64_pack(*(const uint64_t *) member, scratch + rv); + buffer->append(buffer, rv, scratch); + break; + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + scratch[0] |= PROTOBUF_C_WIRE_TYPE_32BIT; + rv += fixed32_pack(*(const uint32_t *) member, scratch + rv); + buffer->append(buffer, rv, scratch); + break; + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + scratch[0] |= PROTOBUF_C_WIRE_TYPE_64BIT; + rv += fixed64_pack(*(const uint64_t *) member, scratch + rv); + buffer->append(buffer, rv, scratch); + break; + case PROTOBUF_C_TYPE_BOOL: + scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; + rv += boolean_pack(*(const protobuf_c_boolean *) member, scratch + rv); + buffer->append(buffer, rv, scratch); + break; + case PROTOBUF_C_TYPE_STRING: { + const char *str = *(char *const *) member; + size_t sublen = str ? strlen(str) : 0; + + scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; + rv += uint32_pack(sublen, scratch + rv); + buffer->append(buffer, rv, scratch); + buffer->append(buffer, sublen, (const uint8_t *) str); + rv += sublen; + break; + } + case PROTOBUF_C_TYPE_BYTES: { + const ProtobufCBinaryData *bd = ((const ProtobufCBinaryData *) member); + size_t sublen = bd->len; + + scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; + rv += uint32_pack(sublen, scratch + rv); + buffer->append(buffer, rv, scratch); + buffer->append(buffer, sublen, bd->data); + rv += sublen; + break; + } + case PROTOBUF_C_TYPE_MESSAGE: { + uint8_t simple_buffer_scratch[256]; + size_t sublen; + const ProtobufCMessage *msg = *(ProtobufCMessage * const *) member; + ProtobufCBufferSimple simple_buffer = + PROTOBUF_C_BUFFER_SIMPLE_INIT(simple_buffer_scratch); + + scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; + if (msg == NULL) + sublen = 0; + else + sublen = protobuf_c_message_pack_to_buffer(msg, &simple_buffer.base); + rv += uint32_pack(sublen, scratch + rv); + buffer->append(buffer, rv, scratch); + buffer->append(buffer, sublen, simple_buffer.data); + rv += sublen; + PROTOBUF_C_BUFFER_SIMPLE_CLEAR(&simple_buffer); + break; + } + //default: + //PROTOBUF_C__ASSERT_NOT_REACHED(); + } + return rv; +} + +/** + * Pack a oneof field to a buffer. Only packs the field that is selected by the case enum. + * + * \param field + * Field descriptor. + * \param oneof_case + * Enum value that selects the field in the oneof. + * \param member + * The element to be packed. + * \param[out] buffer + * Virtual buffer to append data to. + * \return + * Number of bytes serialised to `buffer`. + */ +static size_t +oneof_field_pack_to_buffer(const ProtobufCFieldDescriptor *field, + uint32_t oneof_case, + const void *member, ProtobufCBuffer *buffer) +{ + if (oneof_case != field->id) { + return 0; + } + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void *const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } + return required_field_pack_to_buffer(field, member, buffer); +} + +/** + * Pack an optional field to a buffer. + * + * \param field + * Field descriptor. + * \param has + * Whether the field is set. + * \param member + * The element to be packed. + * \param[out] buffer + * Virtual buffer to append data to. + * \return + * Number of bytes serialised to `buffer`. + */ +static size_t +optional_field_pack_to_buffer(const ProtobufCFieldDescriptor *field, + const protobuf_c_boolean has, + const void *member, ProtobufCBuffer *buffer) +{ + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void *const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } else { + if (!has) + return 0; + } + return required_field_pack_to_buffer(field, member, buffer); +} + +/** + * Pack an unlabeled field to a buffer. + * + * \param field + * Field descriptor. + * \param member + * The element to be packed. + * \param[out] buffer + * Virtual buffer to append data to. + * \return + * Number of bytes serialised to `buffer`. + */ +static size_t +unlabeled_field_pack_to_buffer(const ProtobufCFieldDescriptor *field, + const void *member, ProtobufCBuffer *buffer) +{ + if (field_is_zeroish(field, member)) + return 0; + return required_field_pack_to_buffer(field, member, buffer); +} + +/** + * Get the packed size of an array of same field type. + * + * \param field + * Field descriptor. + * \param count + * Number of elements of this type. + * \param array + * The elements to get the size of. + * \return + * Number of bytes required. + */ +static size_t +get_packed_payload_length(const ProtobufCFieldDescriptor *field, + unsigned count, const void *array) +{ + unsigned rv = 0; + unsigned i; + + switch (field->type) { + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + return count * 4; + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + return count * 8; + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: { + const int32_t *arr = (const int32_t *) array; + for (i = 0; i < count; i++) + rv += int32_size(arr[i]); + break; + } + case PROTOBUF_C_TYPE_SINT32: { + const int32_t *arr = (const int32_t *) array; + for (i = 0; i < count; i++) + rv += sint32_size(arr[i]); + break; + } + case PROTOBUF_C_TYPE_UINT32: { + const uint32_t *arr = (const uint32_t *) array; + for (i = 0; i < count; i++) + rv += uint32_size(arr[i]); + break; + } + case PROTOBUF_C_TYPE_SINT64: { + const int64_t *arr = (const int64_t *) array; + for (i = 0; i < count; i++) + rv += sint64_size(arr[i]); + break; + } + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: { + const uint64_t *arr = (const uint64_t *) array; + for (i = 0; i < count; i++) + rv += uint64_size(arr[i]); + break; + } + case PROTOBUF_C_TYPE_BOOL: + return count; + //default: + //PROTOBUF_C__ASSERT_NOT_REACHED(); + } + return rv; +} + +/** + * Pack an array of same field type to a virtual buffer. + * + * \param field + * Field descriptor. + * \param count + * Number of elements of this type. + * \param array + * The elements to get the size of. + * \param[out] buffer + * Virtual buffer to append data to. + * \return + * Number of bytes packed. + */ +static size_t +pack_buffer_packed_payload(const ProtobufCFieldDescriptor *field, + unsigned count, const void *array, + ProtobufCBuffer *buffer) +{ + uint8_t scratch[16]; + size_t rv = 0; + unsigned i; + + switch (field->type) { + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: +#if !defined(WORDS_BIGENDIAN) + rv = count * 4; + goto no_packing_needed; +#else + for (i = 0; i < count; i++) { + unsigned len = fixed32_pack(((uint32_t *) array)[i], scratch); + buffer->append(buffer, len, scratch); + rv += len; + } + break; +#endif + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: +#if !defined(WORDS_BIGENDIAN) + rv = count * 8; + goto no_packing_needed; +#else + for (i = 0; i < count; i++) { + unsigned len = fixed64_pack(((uint64_t *) array)[i], scratch); + buffer->append(buffer, len, scratch); + rv += len; + } + break; +#endif + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + for (i = 0; i < count; i++) { + unsigned len = int32_pack(((int32_t *) array)[i], scratch); + buffer->append(buffer, len, scratch); + rv += len; + } + break; + case PROTOBUF_C_TYPE_SINT32: + for (i = 0; i < count; i++) { + unsigned len = sint32_pack(((int32_t *) array)[i], scratch); + buffer->append(buffer, len, scratch); + rv += len; + } + break; + case PROTOBUF_C_TYPE_UINT32: + for (i = 0; i < count; i++) { + unsigned len = uint32_pack(((uint32_t *) array)[i], scratch); + buffer->append(buffer, len, scratch); + rv += len; + } + break; + case PROTOBUF_C_TYPE_SINT64: + for (i = 0; i < count; i++) { + unsigned len = sint64_pack(((int64_t *) array)[i], scratch); + buffer->append(buffer, len, scratch); + rv += len; + } + break; + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + for (i = 0; i < count; i++) { + unsigned len = uint64_pack(((uint64_t *) array)[i], scratch); + buffer->append(buffer, len, scratch); + rv += len; + } + break; + case PROTOBUF_C_TYPE_BOOL: + for (i = 0; i < count; i++) { + unsigned len = boolean_pack(((protobuf_c_boolean *) array)[i], scratch); + buffer->append(buffer, len, scratch); + rv += len; + } + return count; + //default: + //PROTOBUF_C__ASSERT_NOT_REACHED(); + } + return rv; + +#if !defined(WORDS_BIGENDIAN) +no_packing_needed: + buffer->append(buffer, rv, array); + return rv; +#endif +} + +static size_t +repeated_field_pack_to_buffer(const ProtobufCFieldDescriptor *field, + unsigned count, const void *member, + ProtobufCBuffer *buffer) +{ + char *array = *(char * const *) member; + + if (count == 0) + return 0; + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED)) { + uint8_t scratch[MAX_UINT64_ENCODED_SIZE * 2]; + size_t rv = tag_pack(field->id, scratch); + size_t payload_len = get_packed_payload_length(field, count, array); + size_t tmp; + + scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; + rv += uint32_pack(payload_len, scratch + rv); + buffer->append(buffer, rv, scratch); + tmp = pack_buffer_packed_payload(field, count, array, buffer); + //assert(tmp == payload_len); + return rv + payload_len; + } else { + size_t siz; + unsigned i; + /* CONSIDER: optimize this case a bit (by putting the loop inside the switch) */ + unsigned rv = 0; + + siz = sizeof_elt_in_repeated_array(field->type); + for (i = 0; i < count; i++) { + rv += required_field_pack_to_buffer(field, array, buffer); + array += siz; + } + return rv; + } +} + +static size_t +unknown_field_pack_to_buffer(const ProtobufCMessageUnknownField *field, + ProtobufCBuffer *buffer) +{ + uint8_t header[MAX_UINT64_ENCODED_SIZE]; + size_t rv = tag_pack(field->tag, header); + + header[0] |= field->wire_type; + buffer->append(buffer, rv, header); + buffer->append(buffer, field->len, field->data); + return rv + field->len; +} + +/**@}*/ + +size_t +protobuf_c_message_pack_to_buffer(const ProtobufCMessage *message, + ProtobufCBuffer *buffer) +{ + unsigned i; + size_t rv = 0; + + //ASSERT_IS_MESSAGE(message); + for (i = 0; i < message->descriptor->n_fields; i++) { + const ProtobufCFieldDescriptor *field = + message->descriptor->fields + i; + const void *member = + ((const char *) message) + field->offset; + const void *qmember = + ((const char *) message) + field->quantifier_offset; + + if (field->label == PROTOBUF_C_LABEL_REQUIRED) { + rv += required_field_pack_to_buffer(field, member, buffer); + } else if ((field->label == PROTOBUF_C_LABEL_OPTIONAL || + field->label == PROTOBUF_C_LABEL_NONE) && + (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF))) { + rv += oneof_field_pack_to_buffer( + field, + *(const uint32_t *) qmember, + member, + buffer + ); + } else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) { + rv += optional_field_pack_to_buffer( + field, + *(const protobuf_c_boolean *) qmember, + member, + buffer + ); + } else if (field->label == PROTOBUF_C_LABEL_NONE) { + rv += unlabeled_field_pack_to_buffer( + field, + member, + buffer + ); + } else { + rv += repeated_field_pack_to_buffer( + field, + *(const size_t *) qmember, + member, + buffer + ); + } + } + for (i = 0; i < message->n_unknown_fields; i++) + rv += unknown_field_pack_to_buffer(&message->unknown_fields[i], buffer); + + return rv; +} + +/** + * \defgroup unpack unpacking implementation + * + * Routines mainly used by the unpacking functions. + * + * \ingroup internal + * @{ + */ + +static inline int +int_range_lookup(unsigned n_ranges, const ProtobufCIntRange *ranges, int value) +{ + unsigned n; + unsigned start; + + if (n_ranges == 0) + return -1; + start = 0; + n = n_ranges; + while (n > 1) { + unsigned mid = start + n / 2; + + if (value < ranges[mid].start_value) { + n = mid - start; + } else if (value >= ranges[mid].start_value + + (int) (ranges[mid + 1].orig_index - + ranges[mid].orig_index)) + { + unsigned new_start = mid + 1; + n = start + n - new_start; + start = new_start; + } else + return (value - ranges[mid].start_value) + + ranges[mid].orig_index; + } + if (n > 0) { + unsigned start_orig_index = ranges[start].orig_index; + unsigned range_size = + ranges[start + 1].orig_index - start_orig_index; + + if (ranges[start].start_value <= value && + value < (int) (ranges[start].start_value + range_size)) + { + return (value - ranges[start].start_value) + + start_orig_index; + } + } + return -1; +} + +static size_t +parse_tag_and_wiretype(size_t len, + const uint8_t *data, + uint32_t *tag_out, + ProtobufCWireType *wiretype_out) +{ + unsigned max_rv = len > 5 ? 5 : len; + uint32_t tag = (data[0] & 0x7f) >> 3; + unsigned shift = 4; + unsigned rv; + + /* 0 is not a valid tag value */ + if ((data[0] & 0xf8) == 0) { + return 0; + } + + *wiretype_out = data[0] & 7; + if ((data[0] & 0x80) == 0) { + *tag_out = tag; + return 1; + } + for (rv = 1; rv < max_rv; rv++) { + if (data[rv] & 0x80) { + tag |= (data[rv] & 0x7f) << shift; + shift += 7; + } else { + tag |= data[rv] << shift; + *tag_out = tag; + return rv + 1; + } + } + return 0; /* error: bad header */ +} + +/* sizeof(ScannedMember) must be <= (1UL< INT_MAX) { + // Protobuf messages should always be less than 2 GiB in size. + // We also want to return early here so that hdr_len + val does + // not overflow on 32-bit systems. + PROTOBUF_C_UNPACK_ERROR("length prefix of %lu is too large", val); + return 0; + } + if (hdr_len + val > len) { + PROTOBUF_C_UNPACK_ERROR("data too short after length-prefix of %lu", val); + return 0; + } + return hdr_len + val; +} + +static size_t +max_b128_numbers(size_t len, const uint8_t *data) +{ + size_t rv = 0; + while (len--) + if ((*data++ & 0x80) == 0) + ++rv; + return rv; +} + +/**@}*/ + +/** + * Merge earlier message into a latter message. + * + * For numeric types and strings, if the same value appears multiple + * times, the parser accepts the last value it sees. For embedded + * message fields, the parser merges multiple instances of the same + * field. That is, all singular scalar fields in the latter instance + * replace those in the former, singular embedded messages are merged, + * and repeated fields are concatenated. + * + * The earlier message should be freed after calling this function, as + * some of its fields may have been reused and changed to their default + * values during the merge. + */ +static protobuf_c_boolean +merge_messages(ProtobufCMessage *earlier_msg, + ProtobufCMessage *latter_msg, + ProtobufCAllocator *allocator) +{ + unsigned i; + const ProtobufCFieldDescriptor *fields = + latter_msg->descriptor->fields; + for (i = 0; i < latter_msg->descriptor->n_fields; i++) { + if (fields[i].label == PROTOBUF_C_LABEL_REPEATED) { + size_t *n_earlier = + STRUCT_MEMBER_PTR(size_t, earlier_msg, + fields[i].quantifier_offset); + uint8_t **p_earlier = + STRUCT_MEMBER_PTR(uint8_t *, earlier_msg, + fields[i].offset); + size_t *n_latter = + STRUCT_MEMBER_PTR(size_t, latter_msg, + fields[i].quantifier_offset); + uint8_t **p_latter = + STRUCT_MEMBER_PTR(uint8_t *, latter_msg, + fields[i].offset); + + if (*n_earlier > 0) { + if (*n_latter > 0) { + /* Concatenate the repeated field */ + size_t el_size = + sizeof_elt_in_repeated_array(fields[i].type); + uint8_t *new_field; + + new_field = do_alloc(allocator, + (*n_earlier + *n_latter) * el_size); + if (!new_field) + return FALSE; + + memcpy(new_field, *p_earlier, + *n_earlier * el_size); + memcpy(new_field + + *n_earlier * el_size, + *p_latter, + *n_latter * el_size); + + do_free(allocator, *p_latter); + do_free(allocator, *p_earlier); + *p_latter = new_field; + *n_latter = *n_earlier + *n_latter; + } else { + /* Zero copy the repeated field from the earlier message */ + *n_latter = *n_earlier; + *p_latter = *p_earlier; + } + /* Make sure the field does not get double freed */ + *n_earlier = 0; + *p_earlier = 0; + } + } else if (fields[i].label == PROTOBUF_C_LABEL_OPTIONAL || + fields[i].label == PROTOBUF_C_LABEL_NONE) { + const ProtobufCFieldDescriptor *field; + uint32_t *earlier_case_p = STRUCT_MEMBER_PTR(uint32_t, + earlier_msg, + fields[i]. + quantifier_offset); + uint32_t *latter_case_p = STRUCT_MEMBER_PTR(uint32_t, + latter_msg, + fields[i]. + quantifier_offset); + protobuf_c_boolean need_to_merge = FALSE; + void *earlier_elem; + void *latter_elem; + const void *def_val; + + if (fields[i].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) { + if (*latter_case_p == 0) { + /* lookup correct oneof field */ + int field_index = + int_range_lookup( + latter_msg->descriptor + ->n_field_ranges, + latter_msg->descriptor + ->field_ranges, + *earlier_case_p); + if (field_index < 0) + return FALSE; + field = latter_msg->descriptor->fields + + field_index; + } else { + /* Oneof is present in the latter message, move on */ + continue; + } + } else { + field = &fields[i]; + } + + earlier_elem = STRUCT_MEMBER_P(earlier_msg, field->offset); + latter_elem = STRUCT_MEMBER_P(latter_msg, field->offset); + def_val = field->default_value; + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: { + ProtobufCMessage *em = *(ProtobufCMessage **) earlier_elem; + ProtobufCMessage *lm = *(ProtobufCMessage **) latter_elem; + if (em != NULL) { + if (lm != NULL) { + if (!merge_messages(em, lm, allocator)) + return FALSE; + /* Already merged */ + need_to_merge = FALSE; + } else { + /* Zero copy the message */ + need_to_merge = TRUE; + } + } + break; + } + case PROTOBUF_C_TYPE_BYTES: { + uint8_t *e_data = + ((ProtobufCBinaryData *) earlier_elem)->data; + uint8_t *l_data = + ((ProtobufCBinaryData *) latter_elem)->data; + const ProtobufCBinaryData *d_bd = + (ProtobufCBinaryData *) def_val; + + need_to_merge = + (e_data != NULL && + (d_bd == NULL || + e_data != d_bd->data)) && + (l_data == NULL || + (d_bd != NULL && + l_data == d_bd->data)); + break; + } + case PROTOBUF_C_TYPE_STRING: { + char *e_str = *(char **) earlier_elem; + char *l_str = *(char **) latter_elem; + const char *d_str = def_val; + + need_to_merge = e_str != d_str && l_str == d_str; + break; + } + default: { + /* Could be has field or case enum, the logic is + * equivalent, since 0 (FALSE) means not set for + * oneof */ + need_to_merge = (*earlier_case_p != 0) && + (*latter_case_p == 0); + break; + } + } + + if (need_to_merge) { + size_t el_size = + sizeof_elt_in_repeated_array(field->type); + memcpy(latter_elem, earlier_elem, el_size); + /* + * Reset the element from the old message to 0 + * to make sure earlier message deallocation + * doesn't corrupt zero-copied data in the new + * message, earlier message will be freed after + * this function is called anyway + */ + memset(earlier_elem, 0, el_size); + + if (field->quantifier_offset != 0) { + /* Set the has field or the case enum, + * if applicable */ + *latter_case_p = *earlier_case_p; + *earlier_case_p = 0; + } + } + } + } + return TRUE; +} + +/** + * Count packed elements. + * + * Given a raw slab of packed-repeated values, determine the number of + * elements. This function detects certain kinds of errors but not + * others; the remaining error checking is done by + * parse_packed_repeated_member(). + */ +static protobuf_c_boolean +count_packed_elements(ProtobufCType type, + size_t len, const uint8_t *data, size_t *count_out) +{ + switch (type) { + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + if (len % 4 != 0) { + PROTOBUF_C_UNPACK_ERROR("length must be a multiple of 4 for fixed-length 32-bit types"); + return FALSE; + } + *count_out = len / 4; + return TRUE; + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + if (len % 8 != 0) { + PROTOBUF_C_UNPACK_ERROR("length must be a multiple of 8 for fixed-length 64-bit types"); + return FALSE; + } + *count_out = len / 8; + return TRUE; + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + case PROTOBUF_C_TYPE_SINT32: + case PROTOBUF_C_TYPE_UINT32: + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_SINT64: + case PROTOBUF_C_TYPE_UINT64: + *count_out = max_b128_numbers(len, data); + return TRUE; + case PROTOBUF_C_TYPE_BOOL: + *count_out = len; + return TRUE; + case PROTOBUF_C_TYPE_STRING: + case PROTOBUF_C_TYPE_BYTES: + case PROTOBUF_C_TYPE_MESSAGE: + default: + PROTOBUF_C_UNPACK_ERROR("bad protobuf-c type %u for packed-repeated", type); + return FALSE; + } +} + +static inline uint32_t +parse_uint32(unsigned len, const uint8_t *data) +{ + uint32_t rv = data[0] & 0x7f; + if (len > 1) { + rv |= ((uint32_t) (data[1] & 0x7f) << 7); + if (len > 2) { + rv |= ((uint32_t) (data[2] & 0x7f) << 14); + if (len > 3) { + rv |= ((uint32_t) (data[3] & 0x7f) << 21); + if (len > 4) + rv |= ((uint32_t) (data[4]) << 28); + } + } + } + return rv; +} + +static inline uint32_t +parse_int32(unsigned len, const uint8_t *data) +{ + return parse_uint32(len, data); +} + +static inline int32_t +unzigzag32(uint32_t v) +{ + if (v & 1) + return -(v >> 1) - 1; + else + return v >> 1; +} + +static inline uint32_t +parse_fixed_uint32(const uint8_t *data) +{ +#if !defined(WORDS_BIGENDIAN) + uint32_t t; + memcpy(&t, data, 4); + return t; +#else + return data[0] | + ((uint32_t) (data[1]) << 8) | + ((uint32_t) (data[2]) << 16) | + ((uint32_t) (data[3]) << 24); +#endif +} + +static uint64_t +parse_uint64(unsigned len, const uint8_t *data) +{ + unsigned shift, i; + uint64_t rv; + + if (len < 5) + return parse_uint32(len, data); + rv = ((uint64_t) (data[0] & 0x7f)) | + ((uint64_t) (data[1] & 0x7f) << 7) | + ((uint64_t) (data[2] & 0x7f) << 14) | + ((uint64_t) (data[3] & 0x7f) << 21); + shift = 28; + for (i = 4; i < len; i++) { + rv |= (((uint64_t) (data[i] & 0x7f)) << shift); + shift += 7; + } + return rv; +} + +static inline int64_t +unzigzag64(uint64_t v) +{ + if (v & 1) + return -(v >> 1) - 1; + else + return v >> 1; +} + +static inline uint64_t +parse_fixed_uint64(const uint8_t *data) +{ +#if !defined(WORDS_BIGENDIAN) + uint64_t t; + memcpy(&t, data, 8); + return t; +#else + return (uint64_t) parse_fixed_uint32(data) | + (((uint64_t) parse_fixed_uint32(data + 4)) << 32); +#endif +} + +static protobuf_c_boolean +parse_boolean(unsigned len, const uint8_t *data) +{ + unsigned i; + for (i = 0; i < len; i++) + if (data[i] & 0x7f) + return TRUE; + return FALSE; +} + +static protobuf_c_boolean +parse_required_member(ScannedMember *scanned_member, + void *member, + ProtobufCAllocator *allocator, + protobuf_c_boolean maybe_clear) +{ + unsigned len = scanned_member->len; + const uint8_t *data = scanned_member->data; + ProtobufCWireType wire_type = scanned_member->wire_type; + + switch (scanned_member->field->type) { + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) + return FALSE; + *(int32_t *) member = parse_int32(len, data); + return TRUE; + case PROTOBUF_C_TYPE_UINT32: + if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) + return FALSE; + *(uint32_t *) member = parse_uint32(len, data); + return TRUE; + case PROTOBUF_C_TYPE_SINT32: + if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) + return FALSE; + *(int32_t *) member = unzigzag32(parse_uint32(len, data)); + return TRUE; + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + if (wire_type != PROTOBUF_C_WIRE_TYPE_32BIT) + return FALSE; + *(uint32_t *) member = parse_fixed_uint32(data); + return TRUE; + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) + return FALSE; + *(uint64_t *) member = parse_uint64(len, data); + return TRUE; + case PROTOBUF_C_TYPE_SINT64: + if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) + return FALSE; + *(int64_t *) member = unzigzag64(parse_uint64(len, data)); + return TRUE; + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + if (wire_type != PROTOBUF_C_WIRE_TYPE_64BIT) + return FALSE; + *(uint64_t *) member = parse_fixed_uint64(data); + return TRUE; + case PROTOBUF_C_TYPE_BOOL: + *(protobuf_c_boolean *) member = parse_boolean(len, data); + return TRUE; + case PROTOBUF_C_TYPE_STRING: { + char **pstr = member; + unsigned pref_len = scanned_member->length_prefix_len; + + if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED) + return FALSE; + + if (maybe_clear && *pstr != NULL) { + const char *def = scanned_member->field->default_value; + if (*pstr != NULL && *pstr != def) + do_free(allocator, *pstr); + } + *pstr = do_alloc(allocator, len - pref_len + 1); + if (*pstr == NULL) + return FALSE; + memcpy(*pstr, data + pref_len, len - pref_len); + (*pstr)[len - pref_len] = 0; + return TRUE; + } + case PROTOBUF_C_TYPE_BYTES: { + ProtobufCBinaryData *bd = member; + const ProtobufCBinaryData *def_bd; + unsigned pref_len = scanned_member->length_prefix_len; + + if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED) + return FALSE; + + def_bd = scanned_member->field->default_value; + if (maybe_clear && + bd->data != NULL && + (def_bd == NULL || bd->data != def_bd->data)) + { + do_free(allocator, bd->data); + } + if (len - pref_len > 0) { + bd->data = do_alloc(allocator, len - pref_len); + if (bd->data == NULL) + return FALSE; + memcpy(bd->data, data + pref_len, len - pref_len); + } else { + bd->data = NULL; + } + bd->len = len - pref_len; + return TRUE; + } + case PROTOBUF_C_TYPE_MESSAGE: { + ProtobufCMessage **pmessage = member; + ProtobufCMessage *subm; + const ProtobufCMessage *def_mess; + protobuf_c_boolean merge_successful = TRUE; + unsigned pref_len = scanned_member->length_prefix_len; + + if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED) + return FALSE; + + def_mess = scanned_member->field->default_value; + subm = protobuf_c_message_unpack(scanned_member->field->descriptor, + allocator, + len - pref_len, + data + pref_len); + + if (maybe_clear && + *pmessage != NULL && + *pmessage != def_mess) + { + if (subm != NULL) + merge_successful = merge_messages(*pmessage, subm, allocator); + /* Delete the previous message */ + protobuf_c_message_free_unpacked(*pmessage, allocator); + } + *pmessage = subm; + if (subm == NULL || !merge_successful) + return FALSE; + return TRUE; + } + } + return FALSE; +} + +static protobuf_c_boolean +parse_oneof_member (ScannedMember *scanned_member, + void *member, + ProtobufCMessage *message, + ProtobufCAllocator *allocator) +{ + uint32_t *oneof_case = STRUCT_MEMBER_PTR(uint32_t, message, + scanned_member->field->quantifier_offset); + + /* If we have already parsed a member of this oneof, free it. */ + if (*oneof_case != 0) { + const ProtobufCFieldDescriptor *old_field; + size_t el_size; + /* lookup field */ + int field_index = + int_range_lookup(message->descriptor->n_field_ranges, + message->descriptor->field_ranges, + *oneof_case); + if (field_index < 0) + return FALSE; + old_field = message->descriptor->fields + field_index; + el_size = sizeof_elt_in_repeated_array(old_field->type); + + switch (old_field->type) { + case PROTOBUF_C_TYPE_STRING: { + char **pstr = member; + const char *def = old_field->default_value; + if (*pstr != NULL && *pstr != def) + do_free(allocator, *pstr); + break; + } + case PROTOBUF_C_TYPE_BYTES: { + ProtobufCBinaryData *bd = member; + const ProtobufCBinaryData *def_bd = old_field->default_value; + if (bd->data != NULL && + (def_bd == NULL || bd->data != def_bd->data)) + { + do_free(allocator, bd->data); + } + break; + } + case PROTOBUF_C_TYPE_MESSAGE: { + ProtobufCMessage **pmessage = member; + const ProtobufCMessage *def_mess = old_field->default_value; + if (*pmessage != NULL && *pmessage != def_mess) + protobuf_c_message_free_unpacked(*pmessage, allocator); + break; + } + default: + break; + } + + memset (member, 0, el_size); + } + if (!parse_required_member (scanned_member, member, allocator, TRUE)) + return FALSE; + + *oneof_case = scanned_member->tag; + return TRUE; +} + + +static protobuf_c_boolean +parse_optional_member(ScannedMember *scanned_member, + void *member, + ProtobufCMessage *message, + ProtobufCAllocator *allocator) +{ + if (!parse_required_member(scanned_member, member, allocator, TRUE)) + return FALSE; + if (scanned_member->field->quantifier_offset != 0) + STRUCT_MEMBER(protobuf_c_boolean, + message, + scanned_member->field->quantifier_offset) = TRUE; + return TRUE; +} + +static protobuf_c_boolean +parse_repeated_member(ScannedMember *scanned_member, + void *member, + ProtobufCMessage *message, + ProtobufCAllocator *allocator) +{ + const ProtobufCFieldDescriptor *field = scanned_member->field; + size_t *p_n = STRUCT_MEMBER_PTR(size_t, message, field->quantifier_offset); + size_t siz = sizeof_elt_in_repeated_array(field->type); + char *array = *(char **) member; + + if (!parse_required_member(scanned_member, array + siz * (*p_n), + allocator, FALSE)) + { + return FALSE; + } + *p_n += 1; + return TRUE; +} + +static unsigned +scan_varint(unsigned len, const uint8_t *data) +{ + unsigned i; + if (len > 10) + len = 10; + for (i = 0; i < len; i++) + if ((data[i] & 0x80) == 0) + break; + if (i == len) + return 0; + return i + 1; +} + +static protobuf_c_boolean +parse_packed_repeated_member(ScannedMember *scanned_member, + void *member, + ProtobufCMessage *message) +{ + const ProtobufCFieldDescriptor *field = scanned_member->field; + size_t *p_n = STRUCT_MEMBER_PTR(size_t, message, field->quantifier_offset); + size_t siz = sizeof_elt_in_repeated_array(field->type); + void *array = *(char **) member + siz * (*p_n); + const uint8_t *at = scanned_member->data + scanned_member->length_prefix_len; + size_t rem = scanned_member->len - scanned_member->length_prefix_len; + size_t count = 0; + unsigned i; + + switch (field->type) { + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + count = (scanned_member->len - scanned_member->length_prefix_len) / 4; +#if !defined(WORDS_BIGENDIAN) + goto no_unpacking_needed; +#else + for (i = 0; i < count; i++) { + ((uint32_t *) array)[i] = parse_fixed_uint32(at); + at += 4; + } + break; +#endif + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + count = (scanned_member->len - scanned_member->length_prefix_len) / 8; +#if !defined(WORDS_BIGENDIAN) + goto no_unpacking_needed; +#else + for (i = 0; i < count; i++) { + ((uint64_t *) array)[i] = parse_fixed_uint64(at); + at += 8; + } + break; +#endif + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + while (rem > 0) { + unsigned s = scan_varint(rem, at); + if (s == 0) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated int32 value"); + return FALSE; + } + ((int32_t *) array)[count++] = parse_int32(s, at); + at += s; + rem -= s; + } + break; + case PROTOBUF_C_TYPE_SINT32: + while (rem > 0) { + unsigned s = scan_varint(rem, at); + if (s == 0) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated sint32 value"); + return FALSE; + } + ((int32_t *) array)[count++] = unzigzag32(parse_uint32(s, at)); + at += s; + rem -= s; + } + break; + case PROTOBUF_C_TYPE_UINT32: + while (rem > 0) { + unsigned s = scan_varint(rem, at); + if (s == 0) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated enum or uint32 value"); + return FALSE; + } + ((uint32_t *) array)[count++] = parse_uint32(s, at); + at += s; + rem -= s; + } + break; + + case PROTOBUF_C_TYPE_SINT64: + while (rem > 0) { + unsigned s = scan_varint(rem, at); + if (s == 0) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated sint64 value"); + return FALSE; + } + ((int64_t *) array)[count++] = unzigzag64(parse_uint64(s, at)); + at += s; + rem -= s; + } + break; + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + while (rem > 0) { + unsigned s = scan_varint(rem, at); + if (s == 0) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated int64/uint64 value"); + return FALSE; + } + ((int64_t *) array)[count++] = parse_uint64(s, at); + at += s; + rem -= s; + } + break; + case PROTOBUF_C_TYPE_BOOL: + count = rem; + for (i = 0; i < count; i++) { + if (at[i] > 1) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated boolean value"); + return FALSE; + } + ((protobuf_c_boolean *) array)[i] = at[i]; + } + break; + //default: + //PROTOBUF_C__ASSERT_NOT_REACHED(); + } + *p_n += count; + return TRUE; + +#if !defined(WORDS_BIGENDIAN) +no_unpacking_needed: + memcpy(array, at, count * siz); + *p_n += count; + return TRUE; +#endif +} + +static protobuf_c_boolean +is_packable_type(ProtobufCType type) +{ + return + type != PROTOBUF_C_TYPE_STRING && + type != PROTOBUF_C_TYPE_BYTES && + type != PROTOBUF_C_TYPE_MESSAGE; +} + +static protobuf_c_boolean +parse_member(ScannedMember *scanned_member, + ProtobufCMessage *message, + ProtobufCAllocator *allocator) +{ + const ProtobufCFieldDescriptor *field = scanned_member->field; + void *member; + + if (field == NULL) { + ProtobufCMessageUnknownField *ufield = + message->unknown_fields + + (message->n_unknown_fields++); + ufield->tag = scanned_member->tag; + ufield->wire_type = scanned_member->wire_type; + ufield->len = scanned_member->len; + ufield->data = do_alloc(allocator, scanned_member->len); + if (ufield->data == NULL) + return FALSE; + memcpy(ufield->data, scanned_member->data, ufield->len); + return TRUE; + } + member = (char *) message + field->offset; + switch (field->label) { + case PROTOBUF_C_LABEL_REQUIRED: + return parse_required_member(scanned_member, member, + allocator, TRUE); + case PROTOBUF_C_LABEL_OPTIONAL: + case PROTOBUF_C_LABEL_NONE: + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) { + return parse_oneof_member(scanned_member, member, + message, allocator); + } else { + return parse_optional_member(scanned_member, member, + message, allocator); + } + case PROTOBUF_C_LABEL_REPEATED: + if (scanned_member->wire_type == + PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED && + (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED) || + is_packable_type(field->type))) + { + return parse_packed_repeated_member(scanned_member, + member, message); + } else { + return parse_repeated_member(scanned_member, + member, message, + allocator); + } + } + //PROTOBUF_C__ASSERT_NOT_REACHED(); + return 0; +} + +/** + * Initialise messages generated by old code. + * + * This function is used if desc->message_init == NULL (which occurs + * for old code, and which would be useful to support allocating + * descriptors dynamically). + */ +static void +message_init_generic(const ProtobufCMessageDescriptor *desc, + ProtobufCMessage *message) +{ + unsigned i; + + memset(message, 0, desc->sizeof_message); + message->descriptor = desc; + for (i = 0; i < desc->n_fields; i++) { + if (desc->fields[i].default_value != NULL && + desc->fields[i].label != PROTOBUF_C_LABEL_REPEATED) + { + void *field = + STRUCT_MEMBER_P(message, desc->fields[i].offset); + const void *dv = desc->fields[i].default_value; + + switch (desc->fields[i].type) { + case PROTOBUF_C_TYPE_INT32: + case PROTOBUF_C_TYPE_SINT32: + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_UINT32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + case PROTOBUF_C_TYPE_ENUM: + memcpy(field, dv, 4); + break; + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_SINT64: + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_UINT64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + memcpy(field, dv, 8); + break; + case PROTOBUF_C_TYPE_BOOL: + memcpy(field, dv, sizeof(protobuf_c_boolean)); + break; + case PROTOBUF_C_TYPE_BYTES: + memcpy(field, dv, sizeof(ProtobufCBinaryData)); + break; + + case PROTOBUF_C_TYPE_STRING: + case PROTOBUF_C_TYPE_MESSAGE: + /* + * The next line essentially implements a cast + * from const, which is totally unavoidable. + */ + *(const void **) field = dv; + break; + } + } + } +} + +/**@}*/ + +/* + * ScannedMember slabs (an unpacking implementation detail). Before doing real + * unpacking, we first scan through the elements to see how many there are (for + * repeated fields), and which field to use (for non-repeated fields given + * twice). + * + * In order to avoid allocations for small messages, we keep a stack-allocated + * slab of ScannedMembers of size FIRST_SCANNED_MEMBER_SLAB_SIZE (16). After we + * fill that up, we allocate each slab twice as large as the previous one. + */ +#define FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2 4 + +/* + * The number of slabs, including the stack-allocated ones; choose the number so + * that we would overflow if we needed a slab larger than provided. + */ +#define MAX_SCANNED_MEMBER_SLAB \ + (sizeof(unsigned int)*8 - 1 \ + - BOUND_SIZEOF_SCANNED_MEMBER_LOG2 \ + - FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2) + +#define REQUIRED_FIELD_BITMAP_SET(index) \ + (required_fields_bitmap[(index)/8] |= (1UL<<((index)%8))) + +#define REQUIRED_FIELD_BITMAP_IS_SET(index) \ + (required_fields_bitmap[(index)/8] & (1UL<<((index)%8))) + +ProtobufCMessage * +protobuf_c_message_unpack(const ProtobufCMessageDescriptor *desc, + ProtobufCAllocator *allocator, + size_t len, const uint8_t *data) +{ + ProtobufCMessage *rv; + size_t rem = len; + const uint8_t *at = data; + const ProtobufCFieldDescriptor *last_field = desc->fields + 0; + ScannedMember first_member_slab[1UL << + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2]; + + /* + * scanned_member_slabs[i] is an array of arrays of ScannedMember. + * The first slab (scanned_member_slabs[0] is just a pointer to + * first_member_slab), above. All subsequent slabs will be allocated + * using the allocator. + */ + ScannedMember *scanned_member_slabs[MAX_SCANNED_MEMBER_SLAB + 1]; + unsigned which_slab = 0; /* the slab we are currently populating */ + unsigned in_slab_index = 0; /* number of members in the slab */ + size_t n_unknown = 0; + unsigned f; + unsigned j; + unsigned i_slab; + unsigned last_field_index = 0; + unsigned required_fields_bitmap_len; + unsigned char required_fields_bitmap_stack[16]; + unsigned char *required_fields_bitmap = required_fields_bitmap_stack; + protobuf_c_boolean required_fields_bitmap_alloced = FALSE; + + //_DESCRIPTOR(desc); + + if (allocator == NULL) + allocator = &protobuf_c__allocator; + + rv = do_alloc(allocator, desc->sizeof_message); + if (!rv) + return (NULL); + scanned_member_slabs[0] = first_member_slab; + + required_fields_bitmap_len = (desc->n_fields + 7) / 8; + if (required_fields_bitmap_len > sizeof(required_fields_bitmap_stack)) { + required_fields_bitmap = do_alloc(allocator, required_fields_bitmap_len); + if (!required_fields_bitmap) { + do_free(allocator, rv); + return (NULL); + } + required_fields_bitmap_alloced = TRUE; + } + memset(required_fields_bitmap, 0, required_fields_bitmap_len); + + /* + * Generated code always defines "message_init". However, we provide a + * fallback for (1) users of old protobuf-c generated-code that do not + * provide the function, and (2) descriptors constructed from some other + * source (most likely, direct construction from the .proto file). + */ + if (desc->message_init != NULL) + protobuf_c_message_init(desc, rv); + else + message_init_generic(desc, rv); + + while (rem > 0) { + uint32_t tag; + ProtobufCWireType wire_type; + size_t used = parse_tag_and_wiretype(rem, at, &tag, &wire_type); + const ProtobufCFieldDescriptor *field; + ScannedMember tmp; + + if (used == 0) { + PROTOBUF_C_UNPACK_ERROR("error parsing tag/wiretype at offset %u", + (unsigned) (at - data)); + goto error_cleanup_during_scan; + } + /* + * \todo Consider optimizing for field[1].id == tag, if field[1] + * exists! + */ + if (last_field == NULL || last_field->id != tag) { + /* lookup field */ + int field_index = + int_range_lookup(desc->n_field_ranges, + desc->field_ranges, + tag); + if (field_index < 0) { + field = NULL; + n_unknown++; + } else { + field = desc->fields + field_index; + last_field = field; + last_field_index = field_index; + } + } else { + field = last_field; + } + + if (field != NULL && field->label == PROTOBUF_C_LABEL_REQUIRED) + REQUIRED_FIELD_BITMAP_SET(last_field_index); + + at += used; + rem -= used; + tmp.tag = tag; + tmp.wire_type = wire_type; + tmp.field = field; + tmp.data = at; + tmp.length_prefix_len = 0; + + switch (wire_type) { + case PROTOBUF_C_WIRE_TYPE_VARINT: { + unsigned max_len = rem < 10 ? rem : 10; + unsigned i; + + for (i = 0; i < max_len; i++) + if ((at[i] & 0x80) == 0) + break; + if (i == max_len) { + PROTOBUF_C_UNPACK_ERROR("unterminated varint at offset %u", + (unsigned) (at - data)); + goto error_cleanup_during_scan; + } + tmp.len = i + 1; + break; + } + case PROTOBUF_C_WIRE_TYPE_64BIT: + if (rem < 8) { + PROTOBUF_C_UNPACK_ERROR("too short after 64bit wiretype at offset %u", + (unsigned) (at - data)); + goto error_cleanup_during_scan; + } + tmp.len = 8; + break; + case PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED: { + size_t pref_len; + + tmp.len = scan_length_prefixed_data(rem, at, &pref_len); + if (tmp.len == 0) { + /* NOTE: scan_length_prefixed_data calls UNPACK_ERROR */ + goto error_cleanup_during_scan; + } + tmp.length_prefix_len = pref_len; + break; + } + case PROTOBUF_C_WIRE_TYPE_32BIT: + if (rem < 4) { + PROTOBUF_C_UNPACK_ERROR("too short after 32bit wiretype at offset %u", + (unsigned) (at - data)); + goto error_cleanup_during_scan; + } + tmp.len = 4; + break; + default: + PROTOBUF_C_UNPACK_ERROR("unsupported tag %u at offset %u", + wire_type, (unsigned) (at - data)); + goto error_cleanup_during_scan; + } + + if (in_slab_index == (1UL << + (which_slab + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2))) + { + size_t size; + + in_slab_index = 0; + if (which_slab == MAX_SCANNED_MEMBER_SLAB) { + PROTOBUF_C_UNPACK_ERROR("too many fields"); + goto error_cleanup_during_scan; + } + which_slab++; + size = sizeof(ScannedMember) + << (which_slab + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2); + scanned_member_slabs[which_slab] = do_alloc(allocator, size); + if (scanned_member_slabs[which_slab] == NULL) + goto error_cleanup_during_scan; + } + scanned_member_slabs[which_slab][in_slab_index++] = tmp; + + if (field != NULL && field->label == PROTOBUF_C_LABEL_REPEATED) { + size_t *n = STRUCT_MEMBER_PTR(size_t, rv, + field->quantifier_offset); + if (wire_type == PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED && + (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED) || + is_packable_type(field->type))) + { + size_t count; + if (!count_packed_elements(field->type, + tmp.len - + tmp.length_prefix_len, + tmp.data + + tmp.length_prefix_len, + &count)) + { + PROTOBUF_C_UNPACK_ERROR("counting packed elements"); + goto error_cleanup_during_scan; + } + *n += count; + } else { + *n += 1; + } + } + + at += tmp.len; + rem -= tmp.len; + } + + /* allocate space for repeated fields, also check that all required fields have been set */ + for (f = 0; f < desc->n_fields; f++) { + const ProtobufCFieldDescriptor *field = desc->fields + f; + if (field->label == PROTOBUF_C_LABEL_REPEATED) { + size_t siz = + sizeof_elt_in_repeated_array(field->type); + size_t *n_ptr = + STRUCT_MEMBER_PTR(size_t, rv, + field->quantifier_offset); + if (*n_ptr != 0) { + unsigned n = *n_ptr; + void *a; + *n_ptr = 0; + //assert(rv->descriptor != NULL); +#define CLEAR_REMAINING_N_PTRS() \ + for(f++;f < desc->n_fields; f++) \ + { \ + field = desc->fields + f; \ + if (field->label == PROTOBUF_C_LABEL_REPEATED) \ + STRUCT_MEMBER (size_t, rv, field->quantifier_offset) = 0; \ + } + a = do_alloc(allocator, siz * n); + if (!a) { + CLEAR_REMAINING_N_PTRS(); + goto error_cleanup; + } + STRUCT_MEMBER(void *, rv, field->offset) = a; + } + } else if (field->label == PROTOBUF_C_LABEL_REQUIRED) { + if (field->default_value == NULL && + !REQUIRED_FIELD_BITMAP_IS_SET(f)) + { + CLEAR_REMAINING_N_PTRS(); + PROTOBUF_C_UNPACK_ERROR("message '%s': missing required field '%s'", + desc->name, field->name); + goto error_cleanup; + } + } + } +#undef CLEAR_REMAINING_N_PTRS + + /* allocate space for unknown fields */ + if (n_unknown) { + rv->unknown_fields = do_alloc(allocator, + n_unknown * sizeof(ProtobufCMessageUnknownField)); + if (rv->unknown_fields == NULL) + goto error_cleanup; + } + + /* do real parsing */ + for (i_slab = 0; i_slab <= which_slab; i_slab++) { + unsigned max = (i_slab == which_slab) ? + in_slab_index : (1UL << (i_slab + 4)); + ScannedMember *slab = scanned_member_slabs[i_slab]; + + for (j = 0; j < max; j++) { + if (!parse_member(slab + j, rv, allocator)) { + PROTOBUF_C_UNPACK_ERROR("error parsing member %s of %s", + slab->field ? slab->field->name : "*unknown-field*", + desc->name); + goto error_cleanup; + } + } + } + + /* cleanup */ + for (j = 1; j <= which_slab; j++) + do_free(allocator, scanned_member_slabs[j]); + if (required_fields_bitmap_alloced) + do_free(allocator, required_fields_bitmap); + return rv; + +error_cleanup: + protobuf_c_message_free_unpacked(rv, allocator); + for (j = 1; j <= which_slab; j++) + do_free(allocator, scanned_member_slabs[j]); + if (required_fields_bitmap_alloced) + do_free(allocator, required_fields_bitmap); + return NULL; + +error_cleanup_during_scan: + do_free(allocator, rv); + for (j = 1; j <= which_slab; j++) + do_free(allocator, scanned_member_slabs[j]); + if (required_fields_bitmap_alloced) + do_free(allocator, required_fields_bitmap); + return NULL; +} + +void +protobuf_c_message_free_unpacked(ProtobufCMessage *message, + ProtobufCAllocator *allocator) +{ + const ProtobufCMessageDescriptor *desc; + unsigned f; + + if (message == NULL) + return; + + desc = message->descriptor; + + //ASSERT_IS_MESSAGE(message); + + if (allocator == NULL) + allocator = &protobuf_c__allocator; + message->descriptor = NULL; + for (f = 0; f < desc->n_fields; f++) { + if (0 != (desc->fields[f].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) && + desc->fields[f].id != + STRUCT_MEMBER(uint32_t, message, desc->fields[f].quantifier_offset)) + { + /* This is not the selected oneof, skip it */ + continue; + } + + if (desc->fields[f].label == PROTOBUF_C_LABEL_REPEATED) { + size_t n = STRUCT_MEMBER(size_t, + message, + desc->fields[f].quantifier_offset); + void *arr = STRUCT_MEMBER(void *, + message, + desc->fields[f].offset); + + if (arr != NULL) { + if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { + unsigned i; + for (i = 0; i < n; i++) + do_free(allocator, ((char **) arr)[i]); + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) { + unsigned i; + for (i = 0; i < n; i++) + do_free(allocator, ((ProtobufCBinaryData *) arr)[i].data); + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) { + unsigned i; + for (i = 0; i < n; i++) + protobuf_c_message_free_unpacked( + ((ProtobufCMessage **) arr)[i], + allocator + ); + } + do_free(allocator, arr); + } + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { + char *str = STRUCT_MEMBER(char *, message, + desc->fields[f].offset); + + if (str && str != desc->fields[f].default_value) + do_free(allocator, str); + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) { + void *data = STRUCT_MEMBER(ProtobufCBinaryData, message, + desc->fields[f].offset).data; + const ProtobufCBinaryData *default_bd; + + default_bd = desc->fields[f].default_value; + if (data != NULL && + (default_bd == NULL || + default_bd->data != data)) + { + do_free(allocator, data); + } + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) { + ProtobufCMessage *sm; + + sm = STRUCT_MEMBER(ProtobufCMessage *, message, + desc->fields[f].offset); + if (sm && sm != desc->fields[f].default_value) + protobuf_c_message_free_unpacked(sm, allocator); + } + } + + for (f = 0; f < message->n_unknown_fields; f++) + do_free(allocator, message->unknown_fields[f].data); + if (message->unknown_fields != NULL) + do_free(allocator, message->unknown_fields); + + do_free(allocator, message); +} + +void +protobuf_c_message_init(const ProtobufCMessageDescriptor * descriptor, + void *message) +{ + descriptor->message_init((ProtobufCMessage *) (message)); +} + +protobuf_c_boolean +protobuf_c_message_check(const ProtobufCMessage *message) +{ + unsigned i; + + if (!message || + !message->descriptor || + message->descriptor->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) + { + return FALSE; + } + + for (i = 0; i < message->descriptor->n_fields; i++) { + const ProtobufCFieldDescriptor *f = message->descriptor->fields + i; + ProtobufCType type = f->type; + ProtobufCLabel label = f->label; + void *field = STRUCT_MEMBER_P (message, f->offset); + + if (f->flags & PROTOBUF_C_FIELD_FLAG_ONEOF) { + const uint32_t *oneof_case = STRUCT_MEMBER_P (message, f->quantifier_offset); + if (f->id != *oneof_case) { + continue; //Do not check if it is an unpopulated oneof member. + } + } + + if (label == PROTOBUF_C_LABEL_REPEATED) { + size_t *quantity = STRUCT_MEMBER_P (message, f->quantifier_offset); + + if (*quantity > 0 && *(void **) field == NULL) { + return FALSE; + } + + if (type == PROTOBUF_C_TYPE_MESSAGE) { + ProtobufCMessage **submessage = *(ProtobufCMessage ***) field; + unsigned j; + for (j = 0; j < *quantity; j++) { + if (!protobuf_c_message_check(submessage[j])) + return FALSE; + } + } else if (type == PROTOBUF_C_TYPE_STRING) { + char **string = *(char ***) field; + unsigned j; + for (j = 0; j < *quantity; j++) { + if (!string[j]) + return FALSE; + } + } else if (type == PROTOBUF_C_TYPE_BYTES) { + ProtobufCBinaryData *bd = *(ProtobufCBinaryData **) field; + unsigned j; + for (j = 0; j < *quantity; j++) { + if (bd[j].len > 0 && bd[j].data == NULL) + return FALSE; + } + } + + } else { /* PROTOBUF_C_LABEL_REQUIRED or PROTOBUF_C_LABEL_OPTIONAL */ + + if (type == PROTOBUF_C_TYPE_MESSAGE) { + ProtobufCMessage *submessage = *(ProtobufCMessage **) field; + if (label == PROTOBUF_C_LABEL_REQUIRED || submessage != NULL) { + if (!protobuf_c_message_check(submessage)) + return FALSE; + } + } else if (type == PROTOBUF_C_TYPE_STRING) { + char *string = *(char **) field; + if (label == PROTOBUF_C_LABEL_REQUIRED && string == NULL) + return FALSE; + } else if (type == PROTOBUF_C_TYPE_BYTES) { + protobuf_c_boolean *has = STRUCT_MEMBER_P (message, f->quantifier_offset); + ProtobufCBinaryData *bd = field; + if (label == PROTOBUF_C_LABEL_REQUIRED || *has == TRUE) { + if (bd->len > 0 && bd->data == NULL) + return FALSE; + } + } + } + } + + return TRUE; +} + +/* === services === */ + +typedef void (*GenericHandler) (void *service, + const ProtobufCMessage *input, + ProtobufCClosure closure, + void *closure_data); +void +protobuf_c_service_invoke_internal(ProtobufCService *service, + unsigned method_index, + const ProtobufCMessage *input, + ProtobufCClosure closure, + void *closure_data) +{ + GenericHandler *handlers; + GenericHandler handler; + + /* + * Verify that method_index is within range. If this fails, you are + * likely invoking a newly added method on an old service. (Although + * other memory corruption bugs can cause this assertion too.) + */ + //assert(method_index < service->descriptor->n_methods); + + /* + * Get the array of virtual methods (which are enumerated by the + * generated code). + */ + handlers = (GenericHandler *) (service + 1); + + /* + * Get our method and invoke it. + * \todo Seems like handler == NULL is a situation that needs handling. + */ + handler = handlers[method_index]; + (*handler)(service, input, closure, closure_data); +} + +void +protobuf_c_service_generated_init(ProtobufCService *service, + const ProtobufCServiceDescriptor *descriptor, + ProtobufCServiceDestroy destroy) +{ + //ASSERT_IS_SERVICE_DESCRIPTOR(descriptor); + service->descriptor = descriptor; + service->destroy = destroy; + service->invoke = protobuf_c_service_invoke_internal; + memset(service + 1, 0, descriptor->n_methods * sizeof(GenericHandler)); +} + +void protobuf_c_service_destroy(ProtobufCService *service) +{ + service->destroy(service); +} + +/* --- querying the descriptors --- */ + +const ProtobufCEnumValue * +protobuf_c_enum_descriptor_get_value_by_name(const ProtobufCEnumDescriptor *desc, + const char *name) +{ + unsigned start = 0; + unsigned count; + + if (desc == NULL || desc->values_by_name == NULL) + return NULL; + + count = desc->n_value_names; + + while (count > 1) { + unsigned mid = start + count / 2; + int rv = strcmp(desc->values_by_name[mid].name, name); + if (rv == 0) + return desc->values + desc->values_by_name[mid].index; + else if (rv < 0) { + count = start + count - (mid + 1); + start = mid + 1; + } else + count = mid - start; + } + if (count == 0) + return NULL; + if (strcmp(desc->values_by_name[start].name, name) == 0) + return desc->values + desc->values_by_name[start].index; + return NULL; +} + +const ProtobufCEnumValue * +protobuf_c_enum_descriptor_get_value(const ProtobufCEnumDescriptor *desc, + int value) +{ + int rv = int_range_lookup(desc->n_value_ranges, desc->value_ranges, value); + if (rv < 0) + return NULL; + return desc->values + rv; +} + +const ProtobufCFieldDescriptor * +protobuf_c_message_descriptor_get_field_by_name(const ProtobufCMessageDescriptor *desc, + const char *name) +{ + unsigned start = 0; + unsigned count; + const ProtobufCFieldDescriptor *field; + + if (desc == NULL || desc->fields_sorted_by_name == NULL) + return NULL; + + count = desc->n_fields; + + while (count > 1) { + unsigned mid = start + count / 2; + int rv; + field = desc->fields + desc->fields_sorted_by_name[mid]; + rv = strcmp(field->name, name); + if (rv == 0) + return field; + else if (rv < 0) { + count = start + count - (mid + 1); + start = mid + 1; + } else + count = mid - start; + } + if (count == 0) + return NULL; + field = desc->fields + desc->fields_sorted_by_name[start]; + if (strcmp(field->name, name) == 0) + return field; + return NULL; +} + +const ProtobufCFieldDescriptor * +protobuf_c_message_descriptor_get_field(const ProtobufCMessageDescriptor *desc, + unsigned value) +{ + int rv = int_range_lookup(desc->n_field_ranges,desc->field_ranges, value); + if (rv < 0) + return NULL; + return desc->fields + rv; +} + +const ProtobufCMethodDescriptor * +protobuf_c_service_descriptor_get_method_by_name(const ProtobufCServiceDescriptor *desc, + const char *name) +{ + unsigned start = 0; + unsigned count; + + if (desc == NULL || desc->method_indices_by_name == NULL) + return NULL; + + count = desc->n_methods; + + while (count > 1) { + unsigned mid = start + count / 2; + unsigned mid_index = desc->method_indices_by_name[mid]; + const char *mid_name = desc->methods[mid_index].name; + int rv = strcmp(mid_name, name); + + if (rv == 0) + return desc->methods + desc->method_indices_by_name[mid]; + if (rv < 0) { + count = start + count - (mid + 1); + start = mid + 1; + } else { + count = mid - start; + } + } + if (count == 0) + return NULL; + if (strcmp(desc->methods[desc->method_indices_by_name[start]].name, name) == 0) + return desc->methods + desc->method_indices_by_name[start]; + return NULL; +} diff --git a/components/ai/onnx/protobuf/protobuf-c.h b/components/ai/onnx/protobuf/protobuf-c.h new file mode 100644 index 00000000..a49bf5ab --- /dev/null +++ b/components/ai/onnx/protobuf/protobuf-c.h @@ -0,0 +1,1106 @@ +/* + * Copyright (c) 2008-2018, Dave Benson and the protobuf-c authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/*! \file + * \mainpage Introduction + * + * This is [protobuf-c], a C implementation of [Protocol Buffers]. + * + * This file defines the public API for the `libprotobuf-c` support library. + * This API includes interfaces that can be used directly by client code as well + * as the interfaces used by the code generated by the `protoc-c` compiler. + * + * The `libprotobuf-c` support library performs the actual serialization and + * deserialization of Protocol Buffers messages. It interacts with structures, + * definitions, and metadata generated by the `protoc-c` compiler from .proto + * files. + * + * \authors Dave Benson and the `protobuf-c` authors. + * + * \copyright 2008-2014. Licensed under the terms of the [BSD-2-Clause] license. + * + * [protobuf-c]: https://github.com/protobuf-c/protobuf-c + * [Protocol Buffers]: https://developers.google.com/protocol-buffers/ + * [BSD-2-Clause]: http://opensource.org/licenses/BSD-2-Clause + * + * \page gencode Generated Code + * + * For each enum, we generate a C enum. For each message, we generate a C + * structure which can be cast to a `ProtobufCMessage`. + * + * For each enum and message, we generate a descriptor object that allows us to + * implement a kind of reflection on the structures. + * + * First, some naming conventions: + * + * - The name of the type for enums and messages and services is camel case + * (meaning WordsAreCrammedTogether) except that double underscores are used + * to delimit scopes. For example, the following `.proto` file: + * +~~~{.proto} + package foo.bar; + message BazBah { + optional int32 val = 1; + } +~~~ + * + * would generate a C type `Foo__Bar__BazBah`. + * + * - Identifiers for functions and globals are all lowercase, with camel case + * words separated by single underscores. For example, one of the function + * prototypes generated by `protoc-c` for the above example: + * +~~~{.c} +Foo__Bar__BazBah * + foo__bar__baz_bah__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +~~~ + * + * - Identifiers for enum values contain an uppercase prefix which embeds the + * package name and the enum type name. + * + * - A double underscore is used to separate further components of identifier + * names. + * + * For example, in the name of the unpack function above, the package name + * `foo.bar` has become `foo__bar`, the message name BazBah has become + * `baz_bah`, and the method name is `unpack`. These are all joined with double + * underscores to form the C identifier `foo__bar__baz_bah__unpack`. + * + * We also generate descriptor objects for messages and enums. These are + * declared in the `.pb-c.h` files: + * +~~~{.c} +extern const ProtobufCMessageDescriptor foo__bar__baz_bah__descriptor; +~~~ + * + * The message structures all begin with `ProtobufCMessageDescriptor *` which is + * sufficient to allow them to be cast to `ProtobufCMessage`. + * + * For each message defined in a `.proto` file, we generate a number of + * functions and macros. Each function name contains a prefix based on the + * package name and message name in order to make it a unique C identifier. + * + * - `INIT`. Statically initializes a message object, initializing its + * descriptor and setting its fields to default values. Uninitialized + * messages cannot be processed by the protobuf-c library. + * +~~~{.c} +#define FOO__BAR__BAZ_BAH__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&foo__bar__baz_bah__descriptor), 0 } +~~~ + * - `init()`. Initializes a message object, initializing its descriptor and + * setting its fields to default values. Uninitialized messages cannot be + * processed by the protobuf-c library. + * +~~~{.c} +void foo__bar__baz_bah__init + (Foo__Bar__BazBah *message); +~~~ + * - `unpack()`. Unpacks data for a particular message format. Note that the + * `allocator` parameter is usually `NULL` to indicate that the system's + * `malloc()` and `free()` functions should be used for dynamically allocating + * memory. + * +~~~{.c} +Foo__Bar__BazBah * + foo__bar__baz_bah__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +~~~ + * + * - `free_unpacked()`. Frees a message object obtained with the `unpack()` + * method. Freeing `NULL` is allowed (the same as with `free()`). + * +~~~{.c} +void foo__bar__baz_bah__free_unpacked + (Foo__Bar__BazBah *message, + ProtobufCAllocator *allocator); +~~~ + * + * - `get_packed_size()`. Calculates the length in bytes of the serialized + * representation of the message object. + * +~~~{.c} +size_t foo__bar__baz_bah__get_packed_size + (const Foo__Bar__BazBah *message); +~~~ + * + * - `pack()`. Pack a message object into a preallocated buffer. Assumes that + * the buffer is large enough. (Use `get_packed_size()` first.) + * +~~~{.c} +size_t foo__bar__baz_bah__pack + (const Foo__Bar__BazBah *message, + uint8_t *out); +~~~ + * + * - `pack_to_buffer()`. Packs a message into a "virtual buffer". This is an + * object which defines an "append bytes" callback to consume data as it is + * serialized. + * +~~~{.c} +size_t foo__bar__baz_bah__pack_to_buffer + (const Foo__Bar__BazBah *message, + ProtobufCBuffer *buffer); +~~~ + * + * \page pack Packing and unpacking messages + * + * To pack a message, first compute the packed size of the message with + * protobuf_c_message_get_packed_size(), then allocate a buffer of at least + * that size, then call protobuf_c_message_pack(). + * + * Alternatively, a message can be serialized without calculating the final size + * first. Use the protobuf_c_message_pack_to_buffer() function and provide a + * ProtobufCBuffer object which implements an "append" method that consumes + * data. + * + * To unpack a message, call the protobuf_c_message_unpack() function. The + * result can be cast to an object of the type that matches the descriptor for + * the message. + * + * The result of unpacking a message should be freed with + * protobuf_c_message_free_unpacked(). + */ + +#ifndef PROTOBUF_C_H +#define PROTOBUF_C_H + +#include +#include +#include +#include + +#ifdef __cplusplus +# define PROTOBUF_C__BEGIN_DECLS extern "C" { +# define PROTOBUF_C__END_DECLS } +#else +# define PROTOBUF_C__BEGIN_DECLS +# define PROTOBUF_C__END_DECLS +#endif + +PROTOBUF_C__BEGIN_DECLS + +#if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB) +# ifdef PROTOBUF_C_EXPORT +# define PROTOBUF_C__API __declspec(dllexport) +# else +# define PROTOBUF_C__API __declspec(dllimport) +# endif +#else +# define PROTOBUF_C__API +#endif + +#if !defined(PROTOBUF_C__NO_DEPRECATED) && \ + ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +# define PROTOBUF_C__DEPRECATED __attribute__((__deprecated__)) +#else +# define PROTOBUF_C__DEPRECATED +#endif + +#ifndef PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE + #define PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(enum_name) \ + , _##enum_name##_IS_INT_SIZE = INT_MAX +#endif + +#define PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC 0x14159bc3 +#define PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC 0x28aaeef9 +#define PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC 0x114315af + +/* Empty string used for initializers */ +extern const char protobuf_c_empty_string[]; + +/** + * \defgroup api Public API + * + * This is the public API for `libprotobuf-c`. These interfaces are stable and + * subject to Semantic Versioning guarantees. + * + * @{ + */ + +/** + * Values for the `flags` word in `ProtobufCFieldDescriptor`. + */ +typedef enum { + /** Set if the field is repeated and marked with the `packed` option. */ + PROTOBUF_C_FIELD_FLAG_PACKED = (1 << 0), + + /** Set if the field is marked with the `deprecated` option. */ + PROTOBUF_C_FIELD_FLAG_DEPRECATED = (1 << 1), + + /** Set if the field is a member of a oneof (union). */ + PROTOBUF_C_FIELD_FLAG_ONEOF = (1 << 2), +} ProtobufCFieldFlag; + +/** + * Message field rules. + * + * \see [Defining A Message Type] in the Protocol Buffers documentation. + * + * [Defining A Message Type]: + * https://developers.google.com/protocol-buffers/docs/proto#simple + */ +typedef enum { + /** A well-formed message must have exactly one of this field. */ + PROTOBUF_C_LABEL_REQUIRED, + + /** + * A well-formed message can have zero or one of this field (but not + * more than one). + */ + PROTOBUF_C_LABEL_OPTIONAL, + + /** + * This field can be repeated any number of times (including zero) in a + * well-formed message. The order of the repeated values will be + * preserved. + */ + PROTOBUF_C_LABEL_REPEATED, + + /** + * This field has no label. This is valid only in proto3 and is + * equivalent to OPTIONAL but no "has" quantifier will be consulted. + */ + PROTOBUF_C_LABEL_NONE, +} ProtobufCLabel; + +/** + * Field value types. + * + * \see [Scalar Value Types] in the Protocol Buffers documentation. + * + * [Scalar Value Types]: + * https://developers.google.com/protocol-buffers/docs/proto#scalar + */ +typedef enum { + PROTOBUF_C_TYPE_INT32, /**< int32 */ + PROTOBUF_C_TYPE_SINT32, /**< signed int32 */ + PROTOBUF_C_TYPE_SFIXED32, /**< signed int32 (4 bytes) */ + PROTOBUF_C_TYPE_INT64, /**< int64 */ + PROTOBUF_C_TYPE_SINT64, /**< signed int64 */ + PROTOBUF_C_TYPE_SFIXED64, /**< signed int64 (8 bytes) */ + PROTOBUF_C_TYPE_UINT32, /**< unsigned int32 */ + PROTOBUF_C_TYPE_FIXED32, /**< unsigned int32 (4 bytes) */ + PROTOBUF_C_TYPE_UINT64, /**< unsigned int64 */ + PROTOBUF_C_TYPE_FIXED64, /**< unsigned int64 (8 bytes) */ + PROTOBUF_C_TYPE_FLOAT, /**< int */ + PROTOBUF_C_TYPE_DOUBLE, /**< double */ + PROTOBUF_C_TYPE_BOOL, /**< boolean */ + PROTOBUF_C_TYPE_ENUM, /**< enumerated type */ + PROTOBUF_C_TYPE_STRING, /**< UTF-8 or ASCII string */ + PROTOBUF_C_TYPE_BYTES, /**< arbitrary byte sequence */ + PROTOBUF_C_TYPE_MESSAGE, /**< nested message */ +} ProtobufCType; + +/** + * Field wire types. + * + * \see [Message Structure] in the Protocol Buffers documentation. + * + * [Message Structure]: + * https://developers.google.com/protocol-buffers/docs/encoding#structure + */ +typedef enum { + PROTOBUF_C_WIRE_TYPE_VARINT = 0, + PROTOBUF_C_WIRE_TYPE_64BIT = 1, + PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED = 2, + /* "Start group" and "end group" wire types are unsupported. */ + PROTOBUF_C_WIRE_TYPE_32BIT = 5, +} ProtobufCWireType; + +struct ProtobufCAllocator; +struct ProtobufCBinaryData; +struct ProtobufCBuffer; +struct ProtobufCBufferSimple; +struct ProtobufCEnumDescriptor; +struct ProtobufCEnumValue; +struct ProtobufCEnumValueIndex; +struct ProtobufCFieldDescriptor; +struct ProtobufCIntRange; +struct ProtobufCMessage; +struct ProtobufCMessageDescriptor; +struct ProtobufCMessageUnknownField; +struct ProtobufCMethodDescriptor; +struct ProtobufCService; +struct ProtobufCServiceDescriptor; + +typedef struct ProtobufCAllocator ProtobufCAllocator; +typedef struct ProtobufCBinaryData ProtobufCBinaryData; +typedef struct ProtobufCBuffer ProtobufCBuffer; +typedef struct ProtobufCBufferSimple ProtobufCBufferSimple; +typedef struct ProtobufCEnumDescriptor ProtobufCEnumDescriptor; +typedef struct ProtobufCEnumValue ProtobufCEnumValue; +typedef struct ProtobufCEnumValueIndex ProtobufCEnumValueIndex; +typedef struct ProtobufCFieldDescriptor ProtobufCFieldDescriptor; +typedef struct ProtobufCIntRange ProtobufCIntRange; +typedef struct ProtobufCMessage ProtobufCMessage; +typedef struct ProtobufCMessageDescriptor ProtobufCMessageDescriptor; +typedef struct ProtobufCMessageUnknownField ProtobufCMessageUnknownField; +typedef struct ProtobufCMethodDescriptor ProtobufCMethodDescriptor; +typedef struct ProtobufCService ProtobufCService; +typedef struct ProtobufCServiceDescriptor ProtobufCServiceDescriptor; + +/** Boolean type. */ +typedef int protobuf_c_boolean; + +typedef void (*ProtobufCClosure)(const ProtobufCMessage *, void *closure_data); +typedef void (*ProtobufCMessageInit)(ProtobufCMessage *); +typedef void (*ProtobufCServiceDestroy)(ProtobufCService *); + +/** + * Structure for defining a custom memory allocator. + */ +struct ProtobufCAllocator { + /** Function to allocate memory. */ + void *(*alloc)(void *allocator_data, size_t size); + + /** Function to free memory. */ + void (*free)(void *allocator_data, void *pointer); + + /** Opaque pointer passed to `alloc` and `free` functions. */ + void *allocator_data; +}; + +/** + * Structure for the protobuf `bytes` scalar type. + * + * The data contained in a `ProtobufCBinaryData` is an arbitrary sequence of + * bytes. It may contain embedded `NUL` characters and is not required to be + * `NUL`-terminated. + */ +struct ProtobufCBinaryData { + size_t len; /**< Number of bytes in the `data` field. */ + uint8_t *data; /**< Data bytes. */ +}; + +/** + * Structure for defining a virtual append-only buffer. Used by + * protobuf_c_message_pack_to_buffer() to abstract the consumption of serialized + * bytes. + * + * `ProtobufCBuffer` "subclasses" may be defined on the stack. For example, to + * write to a `FILE` object: + * +~~~{.c} +typedef struct { + ProtobufCBuffer base; + FILE *fp; +} BufferAppendToFile; + +static void +my_buffer_file_append(ProtobufCBuffer *buffer, + size_t len, + const uint8_t *data) +{ + BufferAppendToFile *file_buf = (BufferAppendToFile *) buffer; + fwrite(data, len, 1, file_buf->fp); // XXX: No error handling! +} +~~~ + * + * To use this new type of ProtobufCBuffer, it could be called as follows: + * +~~~{.c} +... +BufferAppendToFile tmp = {0}; +tmp.base.append = my_buffer_file_append; +tmp.fp = fp; +protobuf_c_message_pack_to_buffer(&message, &tmp); +... +~~~ + */ +struct ProtobufCBuffer { + /** Append function. Consumes the `len` bytes stored at `data`. */ + void (*append)(ProtobufCBuffer *buffer, + size_t len, + const uint8_t *data); +}; + +/** + * Simple buffer "subclass" of `ProtobufCBuffer`. + * + * A `ProtobufCBufferSimple` object is declared on the stack and uses a + * scratch buffer provided by the user for the initial allocation. It performs + * exponential resizing, using dynamically allocated memory. A + * `ProtobufCBufferSimple` object can be created and used as follows: + * +~~~{.c} +uint8_t pad[128]; +ProtobufCBufferSimple simple = PROTOBUF_C_BUFFER_SIMPLE_INIT(pad); +ProtobufCBuffer *buffer = (ProtobufCBuffer *) &simple; +~~~ + * + * `buffer` can now be used with `protobuf_c_message_pack_to_buffer()`. Once a + * message has been serialized to a `ProtobufCBufferSimple` object, the + * serialized data bytes can be accessed from the `.data` field. + * + * To free the memory allocated by a `ProtobufCBufferSimple` object, if any, + * call PROTOBUF_C_BUFFER_SIMPLE_CLEAR() on the object, for example: + * +~~~{.c} +PROTOBUF_C_BUFFER_SIMPLE_CLEAR(&simple); +~~~ + * + * \see PROTOBUF_C_BUFFER_SIMPLE_INIT + * \see PROTOBUF_C_BUFFER_SIMPLE_CLEAR + */ +struct ProtobufCBufferSimple { + /** "Base class". */ + ProtobufCBuffer base; + /** Number of bytes allocated in `data`. */ + size_t alloced; + /** Number of bytes currently stored in `data`. */ + size_t len; + /** Data bytes. */ + uint8_t *data; + /** Whether `data` must be freed. */ + protobuf_c_boolean must_free_data; + /** Allocator to use. May be NULL to indicate the system allocator. */ + ProtobufCAllocator *allocator; +}; + +/** + * Describes an enumeration as a whole, with all of its values. + */ +struct ProtobufCEnumDescriptor { + /** Magic value checked to ensure that the API is used correctly. */ + uint32_t magic; + + /** The qualified name (e.g., "namespace.Type"). */ + const char *name; + /** The unqualified name as given in the .proto file (e.g., "Type"). */ + const char *short_name; + /** Identifier used in generated C code. */ + const char *c_name; + /** The dot-separated namespace. */ + const char *package_name; + + /** Number elements in `values`. */ + unsigned n_values; + /** Array of distinct values, sorted by numeric value. */ + const ProtobufCEnumValue *values; + + /** Number of elements in `values_by_name`. */ + unsigned n_value_names; + /** Array of named values, including aliases, sorted by name. */ + const ProtobufCEnumValueIndex *values_by_name; + + /** Number of elements in `value_ranges`. */ + unsigned n_value_ranges; + /** Value ranges, for faster lookups by numeric value. */ + const ProtobufCIntRange *value_ranges; + + /** Reserved for future use. */ + void *reserved1; + /** Reserved for future use. */ + void *reserved2; + /** Reserved for future use. */ + void *reserved3; + /** Reserved for future use. */ + void *reserved4; +}; + +/** + * Represents a single value of an enumeration. + */ +struct ProtobufCEnumValue { + /** The string identifying this value in the .proto file. */ + const char *name; + + /** The string identifying this value in generated C code. */ + const char *c_name; + + /** The numeric value assigned in the .proto file. */ + int value; +}; + +/** + * Used by `ProtobufCEnumDescriptor` to look up enum values. + */ +struct ProtobufCEnumValueIndex { + /** Name of the enum value. */ + const char *name; + /** Index into values[] array. */ + unsigned index; +}; + +/** + * Describes a single field in a message. + */ +struct ProtobufCFieldDescriptor { + /** Name of the field as given in the .proto file. */ + const char *name; + + /** Tag value of the field as given in the .proto file. */ + uint32_t id; + + /** Whether the field is `REQUIRED`, `OPTIONAL`, or `REPEATED`. */ + ProtobufCLabel label; + + /** The type of the field. */ + ProtobufCType type; + + /** + * The offset in bytes of the message's C structure's quantifier field + * (the `has_MEMBER` field for optional members or the `n_MEMBER` field + * for repeated members or the case enum for oneofs). + */ + unsigned quantifier_offset; + + /** + * The offset in bytes into the message's C structure for the member + * itself. + */ + unsigned offset; + + /** + * A type-specific descriptor. + * + * If `type` is `PROTOBUF_C_TYPE_ENUM`, then `descriptor` points to the + * corresponding `ProtobufCEnumDescriptor`. + * + * If `type` is `PROTOBUF_C_TYPE_MESSAGE`, then `descriptor` points to + * the corresponding `ProtobufCMessageDescriptor`. + * + * Otherwise this field is NULL. + */ + const void *descriptor; /* for MESSAGE and ENUM types */ + + /** The default value for this field, if defined. May be NULL. */ + const void *default_value; + + /** + * A flag word. Zero or more of the bits defined in the + * `ProtobufCFieldFlag` enum may be set. + */ + uint32_t flags; + + /** Reserved for future use. */ + unsigned reserved_flags; + /** Reserved for future use. */ + void *reserved2; + /** Reserved for future use. */ + void *reserved3; +}; + +/** + * Helper structure for optimizing int => index lookups in the case + * where the keys are mostly consecutive values, as they presumably are for + * enums and fields. + * + * The data structures requires that the values in the original array are + * sorted. + */ +struct ProtobufCIntRange { + int start_value; + unsigned orig_index; + /* + * NOTE: the number of values in the range can be inferred by looking + * at the next element's orig_index. A dummy element is added to make + * this simple. + */ +}; + +/** + * An instance of a message. + * + * `ProtobufCMessage` is a light-weight "base class" for all messages. + * + * In particular, `ProtobufCMessage` doesn't have any allocation policy + * associated with it. That's because it's common to create `ProtobufCMessage` + * objects on the stack. In fact, that's what we recommend for sending messages. + * If the object is allocated from the stack, you can't really have a memory + * leak. + * + * This means that calls to functions like protobuf_c_message_unpack() which + * return a `ProtobufCMessage` must be paired with a call to a free function, + * like protobuf_c_message_free_unpacked(). + */ +struct ProtobufCMessage { + /** The descriptor for this message type. */ + const ProtobufCMessageDescriptor *descriptor; + /** The number of elements in `unknown_fields`. */ + unsigned n_unknown_fields; + /** The fields that weren't recognized by the parser. */ + ProtobufCMessageUnknownField *unknown_fields; +}; + +/** + * Describes a message. + */ +struct ProtobufCMessageDescriptor { + /** Magic value checked to ensure that the API is used correctly. */ + uint32_t magic; + + /** The qualified name (e.g., "namespace.Type"). */ + const char *name; + /** The unqualified name as given in the .proto file (e.g., "Type"). */ + const char *short_name; + /** Identifier used in generated C code. */ + const char *c_name; + /** The dot-separated namespace. */ + const char *package_name; + + /** + * Size in bytes of the C structure representing an instance of this + * type of message. + */ + size_t sizeof_message; + + /** Number of elements in `fields`. */ + unsigned n_fields; + /** Field descriptors, sorted by tag number. */ + const ProtobufCFieldDescriptor *fields; + /** Used for looking up fields by name. */ + const unsigned *fields_sorted_by_name; + + /** Number of elements in `field_ranges`. */ + unsigned n_field_ranges; + /** Used for looking up fields by id. */ + const ProtobufCIntRange *field_ranges; + + /** Message initialisation function. */ + ProtobufCMessageInit message_init; + + /** Reserved for future use. */ + void *reserved1; + /** Reserved for future use. */ + void *reserved2; + /** Reserved for future use. */ + void *reserved3; +}; + +/** + * An unknown message field. + */ +struct ProtobufCMessageUnknownField { + /** The tag number. */ + uint32_t tag; + /** The wire type of the field. */ + ProtobufCWireType wire_type; + /** Number of bytes in `data`. */ + size_t len; + /** Field data. */ + uint8_t *data; +}; + +/** + * Method descriptor. + */ +struct ProtobufCMethodDescriptor { + /** Method name. */ + const char *name; + /** Input message descriptor. */ + const ProtobufCMessageDescriptor *input; + /** Output message descriptor. */ + const ProtobufCMessageDescriptor *output; +}; + +/** + * Service. + */ +struct ProtobufCService { + /** Service descriptor. */ + const ProtobufCServiceDescriptor *descriptor; + /** Function to invoke the service. */ + void (*invoke)(ProtobufCService *service, + unsigned method_index, + const ProtobufCMessage *input, + ProtobufCClosure closure, + void *closure_data); + /** Function to destroy the service. */ + void (*destroy)(ProtobufCService *service); +}; + +/** + * Service descriptor. + */ +struct ProtobufCServiceDescriptor { + /** Magic value checked to ensure that the API is used correctly. */ + uint32_t magic; + + /** Service name. */ + const char *name; + /** Short version of service name. */ + const char *short_name; + /** C identifier for the service name. */ + const char *c_name; + /** Package name. */ + const char *package; + /** Number of elements in `methods`. */ + unsigned n_methods; + /** Method descriptors, in the order defined in the .proto file. */ + const ProtobufCMethodDescriptor *methods; + /** Sort index of methods. */ + const unsigned *method_indices_by_name; +}; + +/** + * Get the version of the protobuf-c library. Note that this is the version of + * the library linked against, not the version of the headers compiled against. + * + * \return A string containing the version number of protobuf-c. + */ +PROTOBUF_C__API +const char * +protobuf_c_version(void); + +/** + * Get the version of the protobuf-c library. Note that this is the version of + * the library linked against, not the version of the headers compiled against. + * + * \return A 32 bit unsigned integer containing the version number of + * protobuf-c, represented in base-10 as (MAJOR*1E6) + (MINOR*1E3) + PATCH. + */ +PROTOBUF_C__API +uint32_t +protobuf_c_version_number(void); + +/** + * The version of the protobuf-c headers, represented as a string using the same + * format as protobuf_c_version(). + */ +#define PROTOBUF_C_VERSION "1.3.2" + +/** + * The version of the protobuf-c headers, represented as an integer using the + * same format as protobuf_c_version_number(). + */ +#define PROTOBUF_C_VERSION_NUMBER 1003002 + +/** + * The minimum protoc-c version which works with the current version of the + * protobuf-c headers. + */ +#define PROTOBUF_C_MIN_COMPILER_VERSION 1000000 + +/** + * Look up a `ProtobufCEnumValue` from a `ProtobufCEnumDescriptor` by name. + * + * \param desc + * The `ProtobufCEnumDescriptor` object. + * \param name + * The `name` field from the corresponding `ProtobufCEnumValue` object to + * match. + * \return + * A `ProtobufCEnumValue` object. + * \retval NULL + * If not found or if the optimize_for = CODE_SIZE option was set. + */ +PROTOBUF_C__API +const ProtobufCEnumValue * +protobuf_c_enum_descriptor_get_value_by_name( + const ProtobufCEnumDescriptor *desc, + const char *name); + +/** + * Look up a `ProtobufCEnumValue` from a `ProtobufCEnumDescriptor` by numeric + * value. + * + * \param desc + * The `ProtobufCEnumDescriptor` object. + * \param value + * The `value` field from the corresponding `ProtobufCEnumValue` object to + * match. + * + * \return + * A `ProtobufCEnumValue` object. + * \retval NULL + * If not found. + */ +PROTOBUF_C__API +const ProtobufCEnumValue * +protobuf_c_enum_descriptor_get_value( + const ProtobufCEnumDescriptor *desc, + int value); + +/** + * Look up a `ProtobufCFieldDescriptor` from a `ProtobufCMessageDescriptor` by + * the name of the field. + * + * \param desc + * The `ProtobufCMessageDescriptor` object. + * \param name + * The name of the field. + * \return + * A `ProtobufCFieldDescriptor` object. + * \retval NULL + * If not found or if the optimize_for = CODE_SIZE option was set. + */ +PROTOBUF_C__API +const ProtobufCFieldDescriptor * +protobuf_c_message_descriptor_get_field_by_name( + const ProtobufCMessageDescriptor *desc, + const char *name); + +/** + * Look up a `ProtobufCFieldDescriptor` from a `ProtobufCMessageDescriptor` by + * the tag value of the field. + * + * \param desc + * The `ProtobufCMessageDescriptor` object. + * \param value + * The tag value of the field. + * \return + * A `ProtobufCFieldDescriptor` object. + * \retval NULL + * If not found. + */ +PROTOBUF_C__API +const ProtobufCFieldDescriptor * +protobuf_c_message_descriptor_get_field( + const ProtobufCMessageDescriptor *desc, + unsigned value); + +/** + * Determine the number of bytes required to store the serialised message. + * + * \param message + * The message object to serialise. + * \return + * Number of bytes. + */ +PROTOBUF_C__API +size_t +protobuf_c_message_get_packed_size(const ProtobufCMessage *message); + +/** + * Serialise a message from its in-memory representation. + * + * This function stores the serialised bytes of the message in a pre-allocated + * buffer. + * + * \param message + * The message object to serialise. + * \param[out] out + * Buffer to store the bytes of the serialised message. This buffer must + * have enough space to store the packed message. Use + * protobuf_c_message_get_packed_size() to determine the number of bytes + * required. + * \return + * Number of bytes stored in `out`. + */ +PROTOBUF_C__API +size_t +protobuf_c_message_pack(const ProtobufCMessage *message, uint8_t *out); + +/** + * Serialise a message from its in-memory representation to a virtual buffer. + * + * This function calls the `append` method of a `ProtobufCBuffer` object to + * consume the bytes generated by the serialiser. + * + * \param message + * The message object to serialise. + * \param buffer + * The virtual buffer object. + * \return + * Number of bytes passed to the virtual buffer. + */ +PROTOBUF_C__API +size_t +protobuf_c_message_pack_to_buffer( + const ProtobufCMessage *message, + ProtobufCBuffer *buffer); + +/** + * Unpack a serialised message into an in-memory representation. + * + * \param descriptor + * The message descriptor. + * \param allocator + * `ProtobufCAllocator` to use for memory allocation. May be NULL to + * specify the default allocator. + * \param len + * Length in bytes of the serialised message. + * \param data + * Pointer to the serialised message. + * \return + * An unpacked message object. + * \retval NULL + * If an error occurred during unpacking. + */ +PROTOBUF_C__API +ProtobufCMessage * +protobuf_c_message_unpack( + const ProtobufCMessageDescriptor *descriptor, + ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); + +/** + * Free an unpacked message object. + * + * This function should be used to deallocate the memory used by a call to + * protobuf_c_message_unpack(). + * + * \param message + * The message object to free. May be NULL. + * \param allocator + * `ProtobufCAllocator` to use for memory deallocation. May be NULL to + * specify the default allocator. + */ +PROTOBUF_C__API +void +protobuf_c_message_free_unpacked( + ProtobufCMessage *message, + ProtobufCAllocator *allocator); + +/** + * Check the validity of a message object. + * + * Makes sure all required fields (`PROTOBUF_C_LABEL_REQUIRED`) are present. + * Recursively checks nested messages. + * + * \retval TRUE + * Message is valid. + * \retval FALSE + * Message is invalid. + */ +PROTOBUF_C__API +protobuf_c_boolean +protobuf_c_message_check(const ProtobufCMessage *); + +/** Message initialiser. */ +#define PROTOBUF_C_MESSAGE_INIT(descriptor) { descriptor, 0, NULL } + +/** + * Initialise a message object from a message descriptor. + * + * \param descriptor + * Message descriptor. + * \param message + * Allocated block of memory of size `descriptor->sizeof_message`. + */ +PROTOBUF_C__API +void +protobuf_c_message_init( + const ProtobufCMessageDescriptor *descriptor, + void *message); + +/** + * Free a service. + * + * \param service + * The service object to free. + */ +PROTOBUF_C__API +void +protobuf_c_service_destroy(ProtobufCService *service); + +/** + * Look up a `ProtobufCMethodDescriptor` by name. + * + * \param desc + * Service descriptor. + * \param name + * Name of the method. + * + * \return + * A `ProtobufCMethodDescriptor` object. + * \retval NULL + * If not found or if the optimize_for = CODE_SIZE option was set. + */ +PROTOBUF_C__API +const ProtobufCMethodDescriptor * +protobuf_c_service_descriptor_get_method_by_name( + const ProtobufCServiceDescriptor *desc, + const char *name); + +/** + * Initialise a `ProtobufCBufferSimple` object. + */ +#define PROTOBUF_C_BUFFER_SIMPLE_INIT(array_of_bytes) \ +{ \ + { protobuf_c_buffer_simple_append }, \ + sizeof(array_of_bytes), \ + 0, \ + (array_of_bytes), \ + 0, \ + NULL \ +} + +/** + * Clear a `ProtobufCBufferSimple` object, freeing any allocated memory. + */ +#define PROTOBUF_C_BUFFER_SIMPLE_CLEAR(simp_buf) \ +do { \ + if ((simp_buf)->must_free_data) { \ + if ((simp_buf)->allocator != NULL) \ + (simp_buf)->allocator->free( \ + (simp_buf)->allocator, \ + (simp_buf)->data); \ + else \ + free((simp_buf)->data); \ + } \ +} while (0) + +/** + * The `append` method for `ProtobufCBufferSimple`. + * + * \param buffer + * The buffer object to append to. Must actually be a + * `ProtobufCBufferSimple` object. + * \param len + * Number of bytes in `data`. + * \param data + * Data to append. + */ +PROTOBUF_C__API +void +protobuf_c_buffer_simple_append( + ProtobufCBuffer *buffer, + size_t len, + const unsigned char *data); + +PROTOBUF_C__API +void +protobuf_c_service_generated_init( + ProtobufCService *service, + const ProtobufCServiceDescriptor *descriptor, + ProtobufCServiceDestroy destroy); + +PROTOBUF_C__API +void +protobuf_c_service_invoke_internal( + ProtobufCService *service, + unsigned method_index, + const ProtobufCMessage *input, + ProtobufCClosure closure, + void *closure_data); + +/**@}*/ + +PROTOBUF_C__END_DECLS + +#endif /* PROTOBUF_C_H */ From c55e48b61b8e620c272eb77ae68fe8e3fb3ef7fd Mon Sep 17 00:00:00 2001 From: dkk0918 <13262679180@163.com> Date: Tue, 7 Sep 2021 11:02:26 +0800 Subject: [PATCH 2/2] add onnx pack --- components/ai/onnx/README.md | 2 +- .../onnx/examples/mnist_float/mnist_float.h | 41 ------ components/ai/onnx/examples/mnist_int/mnist.c | 39 +----- .../ai/onnx/operator_float/mnist_float.c | 125 ------------------ .../ai/onnx/operator_float/mnist_float.h | 48 ------- components/ai/onnx/pic/mnist_test.png | Bin 0 -> 39940 bytes 6 files changed, 3 insertions(+), 252 deletions(-) delete mode 100644 components/ai/onnx/examples/mnist_float/mnist_float.h delete mode 100644 components/ai/onnx/operator_float/mnist_float.c delete mode 100644 components/ai/onnx/operator_float/mnist_float.h create mode 100644 components/ai/onnx/pic/mnist_test.png diff --git a/components/ai/onnx/README.md b/components/ai/onnx/README.md index 7c574824..39103ea7 100644 --- a/components/ai/onnx/README.md +++ b/components/ai/onnx/README.md @@ -65,7 +65,7 @@ _________________________________________________________________ ``` 推理测试 -![mnist_test](../../../pic/mnist_test.png) +![mnist_test](pic/mnist_test.png) diff --git a/components/ai/onnx/examples/mnist_float/mnist_float.h b/components/ai/onnx/examples/mnist_float/mnist_float.h deleted file mode 100644 index 3c6d20b0..00000000 --- a/components/ai/onnx/examples/mnist_float/mnist_float.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __MNIST_H__ -#define __MNIST_H__ - -#include -#include - -#define IMG0 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3803922, 0.37647063, 0.3019608, 0.46274513, 0.2392157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3529412, 0.5411765, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9843138, 0.9843138, 0.9725491, 0.9960785, 0.9607844, 0.9215687, 0.74509805, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.54901963, 0.9843138, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.7411765, 0.09019608, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8862746, 0.9960785, 0.81568635, 0.7803922, 0.7803922, 0.7803922, 0.7803922, 0.54509807, 0.2392157, 0.2392157, 0.2392157, 0.2392157, 0.2392157, 0.5019608, 0.8705883, 0.9960785, 0.9960785, 0.7411765, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14901961, 0.32156864, 0.050980397, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.13333334, 0.8352942, 0.9960785, 0.9960785, 0.45098042, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4156863, 0.6156863, 0.9960785, 0.9960785, 0.95294124, 0.20000002, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.098039225, 0.45882356, 0.8941177, 0.8941177, 0.8941177, 0.9921569, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.94117653, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.26666668, 0.4666667, 0.86274517, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.5568628, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14509805, 0.73333335, 0.9921569, 0.9960785, 0.9960785, 0.9960785, 0.8745099, 0.8078432, 0.8078432, 0.29411766, 0.26666668, 0.8431373, 0.9960785, 0.9960785, 0.45882356, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4431373, 0.8588236, 0.9960785, 0.9490197, 0.89019614, 0.45098042, 0.34901962, 0.121568635, 0.0, 0.0, 0.0, 0.0, 0.7843138, 0.9960785, 0.9450981, 0.16078432, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6627451, 0.9960785, 0.6901961, 0.24313727, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.18823531, 0.9058824, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07058824, 0.48627454, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.6509804, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.54509807, 0.9960785, 0.9333334, 0.22352943, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8235295, 0.9803922, 0.9960785, 0.65882355, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9490197, 0.9960785, 0.93725497, 0.22352943, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.34901962, 0.9843138, 0.9450981, 0.3372549, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.019607844, 0.8078432, 0.96470594, 0.6156863, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.015686275, 0.45882356, 0.27058825, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0} -#define IMG0_LABEL 7 - -#define IMG1 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.121568635, 0.5176471, 0.9960785, 0.9921569, 0.9960785, 0.8352942, 0.32156864, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.5568628, 0.91372555, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.98823535, 0.8745099, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.48235297, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.87843144, 0.7960785, 0.7960785, 0.8745099, 1.0, 0.8352942, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7960785, 0.9921569, 0.98823535, 0.9921569, 0.8313726, 0.078431375, 0.0, 0.0, 0.2392157, 0.9921569, 0.98823535, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 0.95294124, 0.87843144, 0.7960785, 0.7176471, 0.16078432, 0.59607846, 0.11764707, 0.0, 0.0, 1.0, 0.9921569, 0.40000004, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15686275, 0.078431375, 0.0, 0.0, 0.40000004, 0.9921569, 0.19607845, 0.0, 0.32156864, 0.9921569, 0.98823535, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32156864, 0.83921576, 0.121568635, 0.4431373, 0.91372555, 0.9960785, 0.91372555, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.40000004, 0.32156864, 0.16078432, 0.9921569, 0.909804, 0.9921569, 0.98823535, 0.91372555, 0.19607845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.59607846, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.91372555, 0.48235297, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.59607846, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.98823535, 0.75294125, 0.19607845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.7176471, 0.7960785, 0.95294124, 0.9960785, 0.9921569, 0.24313727, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15686275, 0.6745098, 0.98823535, 0.7960785, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7176471, 0.9960785, 0.43921572, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.7960785, 0.6392157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2392157, 0.9921569, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.83921576, 0.75294125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.043137256, 0.8352942, 0.9960785, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.40000004, 0.9921569, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 0.8352942, 0.98823535, 0.9921569, 0.43529415, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 1.0, 0.8352942, 0.36078432, 0.20000002, 0.0, 0.0, 0.121568635, 0.36078432, 0.6784314, 0.9921569, 0.9960785, 0.9921569, 0.5568628, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6745098, 0.98823535, 0.9921569, 0.98823535, 0.7960785, 0.7960785, 0.91372555, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.50980395, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.7960785, 1.0, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.9568628, 0.7960785, 0.32156864, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.078431375, 0.5921569, 0.5921569, 0.9921569, 0.67058825, 0.5921569, 0.5921569, 0.15686275, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0} -#define IMG1_LABEL 3 - -#define TOTAL_IMAGE 2 - - -static const signed char label[] = {IMG0_LABEL, IMG1_LABEL}; - -static const float W3[] = {-0.3233681, -0.4261553, -0.6519891, 0.79061985, -0.2210753, 0.037107922, 0.3984157, 0.22128074, 0.7975414, 0.2549885, 0.3076058, 0.62500215, -0.58958095, 0.20375429, -0.06477713, -1.566038, -0.37670124, -0.6443057}; -static const float B3[] = {-0.829373, -0.14096421}; - -static const float W2[] = {0.0070440695, 0.23192555, 0.036849476, -0.14687373, -0.15593372, 0.0044246824, 0.27322513, -0.027562773, 0.23404223, -0.6354651, -0.55645454, -0.77057034, 0.15603222, 0.71015775, 0.23954256, 1.8201442, -0.018377468, 1.5745461, 1.7230825, -0.59662616, 1.3997843, 0.33511618, 0.56846994, 0.3797911, 0.035079807, -0.18287429, -0.032232445, 0.006910181, -0.0026898328, -0.0057844054, 0.29354542, 0.13796881, 0.3558416, 0.0022847173, 0.0025906325, -0.022641085}; -static const float B2[] = {-0.11655525, -0.0036503011}; - -static const float W1[] = {0.15791991, -0.22649878, 0.021204736, 0.025593571, 0.008755621, -0.775102, -0.41594088, -0.12580238, -0.3963741, 0.33545518, -0.631953, -0.028754484, -0.50668705, -0.3574023, -3.7807872, -0.8261617, 0.102246165, 0.571127, -0.6256297, 0.06698781, 0.55969477, 0.25374785, -3.075965, -0.6959133, 0.2531965, 0.31739804, -0.8664238, 0.12750633, 0.83136076, 0.2666574, -2.5865922, -0.572031, 0.29743987, 0.16238026, -0.99154145, 0.077973805, 0.8913329, 0.16854058, -2.5247803, -0.5639109, 0.41671264, -0.10801031, -1.0229865, 0.2062031, 0.39889312, -0.16026731, -1.9185526, -0.48375717, 0.057339806, -1.2573057, -0.23117211, 1.051854, -0.7981992, -1.6263007, -0.26003376, -0.07649365, -0.4646075, 0.755821, 0.13187818, 0.24743222, -1.5276812, 0.1636555, -0.075465426, -0.058517877, -0.33852127, 1.3052516, 0.14443535, 0.44080895, -0.31031442, 0.15416017, 0.0053661224, -0.03175326, -0.15991405, 0.66121936, 0.0832211, 0.2651985, -0.038445678, 0.18054117, -0.0073251156, 0.054193687, -0.014296916, 0.30657783, 0.006181963, 0.22319937, 0.030315898, 0.12695274, -0.028179673, 0.11189027, 0.035358384, 0.046855893, -0.026528472, 0.26450494, 0.069981076, 0.107152134, -0.030371506, 0.09524366, 0.24802336, -0.36496836, -0.102762334, 0.49609017, 0.04002767, 0.020934932, -0.054773595, 0.05412083, -0.071876526, -1.5381132, -0.2356421, 1.5890793, -0.023087852, -0.24933836, 0.018771818, 0.08040064, 0.051946845, 0.6141782, 0.15780787, 0.12887044, -0.8691056, 1.3761537, 0.43058, 0.13476849, -0.14973496, 0.4542634, 0.13077497, 0.23117822, 0.003657386, 0.42742714, 0.23396699, 0.09209521, -0.060258932, 0.4642852, 0.10395402, 0.25047097, -0.05326261, 0.21466804, 0.11694269, 0.22402634, 0.12639907, 0.23495848, 0.12770525, 0.3324459, 0.0140223345, 0.106348366, 0.10877733, 0.30522102, 0.31412345, -0.07164018, 0.13483422, 0.45414954, 0.054698735, 0.07451815, 0.097312905, 0.27480683, 0.4866108, -0.43636885, -0.13586079, 0.5724732, 0.13595985, -0.0074526076, 0.11859829, 0.24481037, -0.37537888, -0.46877658, -0.5648533, 0.86578417, 0.3407381, -0.17214134, 0.040683553, 0.3630519, 0.089548275, -0.4989473, 0.47688767, 0.021731026, 0.2856471, 0.6174715, 0.7059148, -0.30635756, -0.5705427, -0.20692639, 0.041900065, 0.23040071, -0.1790487, -0.023751246, 0.14114629, 0.02345284, -0.64177734, -0.069909826, -0.08587972, 0.16460821, -0.53466517, -0.10163383, -0.13119817, 0.14908728, -0.63503706, -0.098961875, -0.23248474, 0.15406314, -0.48586813, -0.1904713, -0.20466608, 0.10629631, -0.5291871, -0.17358926, -0.36273107, 0.12225631, -0.38659447, -0.24787207, -0.25225234, 0.102635615, -0.14507034, -0.10110793, 0.043757595, -0.17158166, -0.031343404, -0.30139172, -0.09401665, 0.06986169, -0.54915506, 0.66843456, 0.14574362, -0.737502, 0.7700305, -0.4125441, 0.10115133, 0.05281194, 0.25467375, 0.22757779, -0.030224197, -0.0832025, -0.66385627, 0.51225215, -0.121023245, -0.3340579, -0.07505331, -0.09820366, -0.016041134, -0.03187605, -0.43589246, 0.094394326, -0.04983066, -0.0777906, -0.12822862, -0.089667186, -0.07014707, -0.010794195, -0.29095307, -0.01319235, -0.039757702, -0.023403417, -0.15530063, -0.052093383, -0.1477549, -0.07557954, -0.2686017, -0.035220042, -0.095615104, -0.015471024, -0.03906604, 0.024237331, -0.19604297, -0.19998372, -0.20302829, -0.04267139, -0.18774728, -0.045169186, -0.010131819, 0.14829905, -0.117015064, -0.4180649, -0.20680964, -0.024034742, -0.15787442, -0.055698488, -0.09037726, 0.40253848, -0.35745984, -0.786149, -0.0799551, 0.16205557, -0.14461482, -0.2749642, 0.2683253, 0.6881363, -0.064145364, 0.11361358, 0.59981894, 1.2947721, -1.2500908, 0.6082035, 0.12344158, 0.15808935, -0.17505693, 0.03425684, 0.39107767, 0.23190938, -0.7568858, 0.20042256, 0.079169095, 0.014275463, -0.12135842, 0.008516737, 0.26897284, 0.05706199, -0.52615446, 0.12489152, 0.08065737, -0.038548164, -0.08894516, 7.250979E-4, 0.28635752, -0.010820533, -0.39301336, 0.11144395, 0.06563818, -0.033744805, -0.07450528, -0.027328406, 0.3002447, 0.0029921278, -0.47954947, -0.04527057, -0.010289918, 0.039380465, -0.09236952, -0.1924659, 0.15401903, 0.21237805, -0.38984418, -0.37384143, -0.20648403, 0.29201767, -0.1299253, -0.36048025, -0.5544466, 0.45723814, -0.35266167, -0.94797707, -1.2481197, 0.88701195, 0.33620682, 0.0035414647, -0.22769359, 1.4563162, 0.54950374, 0.38396382, -0.41196275, 0.3758704, 0.17687413, 0.038129736, 0.16358295, 0.70515764, 0.055063568, 0.6445265, -0.2072113, 0.14618243, 0.10311305, 0.1971523, 0.174206, 0.36578146, -0.09782787, 0.5229244, -0.18459272, -0.0013945608, 0.08863555, 0.24184574, 0.15541393, 0.1722381, -0.10531331, 0.38215113, -0.30659106, -0.16298945, 0.11549875, 0.30750987, 0.1586183, -0.017728966, -0.050216004, 0.26232007, -1.2994286, -0.22700997, 0.108534105, 0.7447398, -0.39803517, 0.016863048, 0.10067235, -0.16355589, -0.64953077, -0.5674107, 0.017935256, 0.98968256, -1.395801, 0.44127485, 0.16644385, -0.19195901}; -static const float B1[] = {1.2019119, -1.1770505, 2.1698284, -1.9615222}; - -static const float W[] = {0.55808353, 0.78707385, -0.040990848, -0.122510895, -0.41261443, -0.036044, 0.1691557, -0.14711425, -0.016407091, -0.28058195, 0.018765535, 0.062936015, 0.49562064, 0.33931744, -0.47547337, -0.1405672, -0.88271654, 0.18359914, 0.020887045, -0.13782434, -0.052250575, 0.67922074, -0.28022966, -0.31278887, 0.44416663, -0.26106882, -0.32219923, 1.0321393, -0.1444394, 0.5221766, 0.057590708, -0.96547794, -0.3051688, 0.16859075, -0.5320585, 0.42684716, -0.5434046, 0.014693736, 0.26795483, 0.15921915}; -static const float B[] = {0.041442648, 1.461427, 0.07154641, -1.2774754, 0.80927604, -1.6933714, -0.29740578, -0.11774022, 0.3292682, 0.6596958}; - - - - - -// ASCII lib from (https://www.jianshu.com/p/1f58a0ebf5d9) - - - - -int mnist(void); - -#endif //__MNIST_H__ diff --git a/components/ai/onnx/examples/mnist_int/mnist.c b/components/ai/onnx/examples/mnist_int/mnist.c index 3a8a9c51..05f521bf 100644 --- a/components/ai/onnx/examples/mnist_int/mnist.c +++ b/components/ai/onnx/examples/mnist_int/mnist.c @@ -1,29 +1,20 @@ -//#include "tos_k.h" #include #include -//#include -//#include -//#include - -//#include "mnist.h" #include "mnist_int.h" #include "onnx.h" static const char codeLib[] = "@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. "; int data[5]={1.5 , 2.5 , 3.5 , 4.5 , 5.5}; -//static const int img[2][784] = {IMG0, IMG1}; static const int img[2][784] = {IMG0, IMG1}; -//static const int imgint[2][784] = {IMG0_INT, IMG1_INT}; static const int img1[784] = {1,2,3,4,5}; int hello() { - printf("hello\r\n"); + printf("hello pnnx\r\n"); return 0; } -//void print_img(void) void print_img(void * buf) { int index = 0; @@ -39,27 +30,18 @@ void print_img(void * buf) { index = 0; - //if(img[0][y*28+x] > 600) if(((int*)buf)[y*28+x] > 600) - //if(data[0] > 0.6) { - index =69; - //ch = ' '; + index =69; } if(index < 0) { index = 0; - //ch = ' '; } printf("%c",codeLib[index]); printf("%c",codeLib[index]); - - - //printf("%c",ch); - //printf("%c",ch); - } printf("\r\n"); } @@ -69,14 +51,6 @@ int mnist() { printf("test1\r\n"); int img_index = 1; - /* - if(argc == 2) - { - img_index = atoi(argv[1]); - } - */ - - //print_img(); print_img(img[img_index]); printf("img ok\r\n"); @@ -185,14 +159,6 @@ int mnist() softmax(dense2, 10, output); printf("Softmax ok\r\n"); - - // 10. Result - /* - printf("\n\rdense2: \n\r"); - for(int i = 0; i < 10; i++) - printf("%d ", dense2[i]); - */ - int max = 0; int min = output[0]; @@ -223,4 +189,3 @@ int mnist() return 0; } -//MSH_CMD_EXPORT(mnist, mnist simple example) diff --git a/components/ai/onnx/operator_float/mnist_float.c b/components/ai/onnx/operator_float/mnist_float.c deleted file mode 100644 index 5ba6a2ff..00000000 --- a/components/ai/onnx/operator_float/mnist_float.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "mnist.h" -#include "onnx.h" - -int mnist(int argc, char const *argv[]) -{ - int img_index = 0; - if(argc == 2) - { - img_index = atoi(argv[1]); - } - print_img(img[img_index]); - - // 1. Conv2D - int64_t shapeW3[] = {2, 1, 3, 3}; - int64_t dimW3 = 4; - int64_t permW3_t[] = { 0, 2, 3, 1}; - float* W3_t = transpose(W3, shapeW3, dimW3, permW3_t); - - float* conv1 = (float*) malloc(sizeof(float)*28*28*2); - memset(conv1, 0, sizeof(sizeof(float)*28*28*2)); - conv2D(img[img_index], 28, 28, 1, W3, 2, 3, 3, 1, 1, 1, 1, B3, conv1, 28, 28); - - free(W3_t); - - // 2. Relu - float* relu1 = (float*) malloc(sizeof(float)*28*28*2); - relu(conv1, 28*28*2, relu1); - - free(conv1); - - // 3. Maxpool - float* maxpool1 = (float*) malloc(sizeof(float)*14*14*2); - memset(maxpool1, 0, sizeof(sizeof(float)*14*14*2)); - maxpool(relu1, 28, 28, 2, 2, 2, 0, 0, 2, 2, 14, 14, maxpool1); - - free(relu1); - - // 4. Conv2D - int64_t shapeW2[] = {2, 2, 3, 3}; - int64_t dimW2 = 4; - int64_t perm_t[] = { 0, 2, 3, 1}; - float* W2_t = transpose(W2, shapeW2, dimW2, perm_t); - - float* conv2 = (float*) malloc(sizeof(float)*14*14*2); - memset(conv2, 0, sizeof(sizeof(float)*14*14*2)); - conv2D(maxpool1, 14, 14, 2, W2_t, 2, 3, 3, 1, 1, 1, 1, B2, conv2, 14, 14); - - free(W2_t); - free(maxpool1); - - // 5. Relu - float* relu2 = (float*) malloc(sizeof(float)*14*14*2); - relu(conv2, 14*14*2, relu2); - - free(conv2); - - // 6. Maxpool - float* maxpool2 = (float*) malloc(sizeof(float)*7*7*2); - memset(maxpool2, 0, sizeof(sizeof(float)*7*7*2)); - maxpool(relu2, 14, 14, 2, 2, 2, 0, 0, 2, 2, 7, 7, maxpool2); - - free(relu2); - - // Flatten NOT REQUIRED - - // 7. Dense - int64_t shapeW1[] = {98, 4}; - int64_t dimW1 = 2; - int64_t permW1_t[] = { 1, 0}; - float* W1_t = transpose(W1, shapeW1, dimW1, permW1_t); - - float* dense1 = (float*) malloc(sizeof(float)*4); - memset(dense1, 0, sizeof(sizeof(float)*4)); - dense(maxpool2, W1_t, 98, 4, B1, dense1); - - free(W1_t); - free(maxpool2); - - // 8. Dense - int64_t shapeW[] = {4, 10}; - int64_t dimW = 2; - int64_t permW_t[] = { 1, 0}; - float* W_t = transpose(W, shapeW, dimW, permW_t); - - float* dense2 = (float*) malloc(sizeof(float)*10); - memset(dense2, 0, sizeof(sizeof(float)*10)); - dense(dense1, W_t, 4, 10, B, dense2); - - free(W_t); - free(dense1); - - // 9. Softmax - float* output = (float*) malloc(sizeof(float)*10); - memset(output, 0, sizeof(sizeof(float)*10)); - softmax(dense2, 10, output); - - // 10. Result - float max = 0; - int max_index = 0; - printf("\nPredictions: \n"); - for(int i = 0; i < 10; i++) - { - printf("%f ", output[i]); - if(output[i] > max) - { - max = output[i]; - max_index = i; - } - } - printf("\n"); - printf("\nThe number is %d\n", max_index); - - free(dense2); - free(output); - - return 0; -} -MSH_CMD_EXPORT(mnist, mnist simple example) diff --git a/components/ai/onnx/operator_float/mnist_float.h b/components/ai/onnx/operator_float/mnist_float.h deleted file mode 100644 index f5f57d90..00000000 --- a/components/ai/onnx/operator_float/mnist_float.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef __MNIST_H__ -#define __MNIST_H__ - -#include -#include - -#define IMG0 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3803922, 0.37647063, 0.3019608, 0.46274513, 0.2392157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3529412, 0.5411765, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9215687, 0.9843138, 0.9843138, 0.9725491, 0.9960785, 0.9607844, 0.9215687, 0.74509805, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.54901963, 0.9843138, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.7411765, 0.09019608, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8862746, 0.9960785, 0.81568635, 0.7803922, 0.7803922, 0.7803922, 0.7803922, 0.54509807, 0.2392157, 0.2392157, 0.2392157, 0.2392157, 0.2392157, 0.5019608, 0.8705883, 0.9960785, 0.9960785, 0.7411765, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14901961, 0.32156864, 0.050980397, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.13333334, 0.8352942, 0.9960785, 0.9960785, 0.45098042, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4156863, 0.6156863, 0.9960785, 0.9960785, 0.95294124, 0.20000002, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.098039225, 0.45882356, 0.8941177, 0.8941177, 0.8941177, 0.9921569, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.94117653, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.26666668, 0.4666667, 0.86274517, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.9960785, 0.5568628, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14509805, 0.73333335, 0.9921569, 0.9960785, 0.9960785, 0.9960785, 0.8745099, 0.8078432, 0.8078432, 0.29411766, 0.26666668, 0.8431373, 0.9960785, 0.9960785, 0.45882356, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4431373, 0.8588236, 0.9960785, 0.9490197, 0.89019614, 0.45098042, 0.34901962, 0.121568635, 0.0, 0.0, 0.0, 0.0, 0.7843138, 0.9960785, 0.9450981, 0.16078432, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6627451, 0.9960785, 0.6901961, 0.24313727, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.18823531, 0.9058824, 0.9960785, 0.9176471, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07058824, 0.48627454, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32941177, 0.9960785, 0.9960785, 0.6509804, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.54509807, 0.9960785, 0.9333334, 0.22352943, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8235295, 0.9803922, 0.9960785, 0.65882355, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9490197, 0.9960785, 0.93725497, 0.22352943, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.34901962, 0.9843138, 0.9450981, 0.3372549, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.019607844, 0.8078432, 0.96470594, 0.6156863, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.015686275, 0.45882356, 0.27058825, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0} -#define IMG0_LABEL 7 - -#define IMG1 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.121568635, 0.5176471, 0.9960785, 0.9921569, 0.9960785, 0.8352942, 0.32156864, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.5568628, 0.91372555, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.98823535, 0.8745099, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.48235297, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.87843144, 0.7960785, 0.7960785, 0.8745099, 1.0, 0.8352942, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7960785, 0.9921569, 0.98823535, 0.9921569, 0.8313726, 0.078431375, 0.0, 0.0, 0.2392157, 0.9921569, 0.98823535, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 0.95294124, 0.87843144, 0.7960785, 0.7176471, 0.16078432, 0.59607846, 0.11764707, 0.0, 0.0, 1.0, 0.9921569, 0.40000004, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15686275, 0.078431375, 0.0, 0.0, 0.40000004, 0.9921569, 0.19607845, 0.0, 0.32156864, 0.9921569, 0.98823535, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.32156864, 0.83921576, 0.121568635, 0.4431373, 0.91372555, 0.9960785, 0.91372555, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.40000004, 0.32156864, 0.16078432, 0.9921569, 0.909804, 0.9921569, 0.98823535, 0.91372555, 0.19607845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.59607846, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.91372555, 0.48235297, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.59607846, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.98823535, 0.75294125, 0.19607845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.7176471, 0.7960785, 0.95294124, 0.9960785, 0.9921569, 0.24313727, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15686275, 0.6745098, 0.98823535, 0.7960785, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7176471, 0.9960785, 0.43921572, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24313727, 0.7960785, 0.6392157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2392157, 0.9921569, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.83921576, 0.75294125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.043137256, 0.8352942, 0.9960785, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.40000004, 0.9921569, 0.5921569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 0.8352942, 0.98823535, 0.9921569, 0.43529415, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16078432, 1.0, 0.8352942, 0.36078432, 0.20000002, 0.0, 0.0, 0.121568635, 0.36078432, 0.6784314, 0.9921569, 0.9960785, 0.9921569, 0.5568628, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6745098, 0.98823535, 0.9921569, 0.98823535, 0.7960785, 0.7960785, 0.91372555, 0.98823535, 0.9921569, 0.98823535, 0.9921569, 0.50980395, 0.078431375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08235294, 0.7960785, 1.0, 0.9921569, 0.9960785, 0.9921569, 0.9960785, 0.9921569, 0.9568628, 0.7960785, 0.32156864, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.078431375, 0.5921569, 0.5921569, 0.9921569, 0.67058825, 0.5921569, 0.5921569, 0.15686275, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0} -#define IMG1_LABEL 3 - -#define TOTAL_IMAGE 2 - -static const float img[][784] = {IMG0, IMG1}; -static const signed char label[] = {IMG0_LABEL, IMG1_LABEL}; - -static const float W3[] = {-0.3233681, -0.4261553, -0.6519891, 0.79061985, -0.2210753, 0.037107922, 0.3984157, 0.22128074, 0.7975414, 0.2549885, 0.3076058, 0.62500215, -0.58958095, 0.20375429, -0.06477713, -1.566038, -0.37670124, -0.6443057}; -static const float B3[] = {-0.829373, -0.14096421}; - -static const float W2[] = {0.0070440695, 0.23192555, 0.036849476, -0.14687373, -0.15593372, 0.0044246824, 0.27322513, -0.027562773, 0.23404223, -0.6354651, -0.55645454, -0.77057034, 0.15603222, 0.71015775, 0.23954256, 1.8201442, -0.018377468, 1.5745461, 1.7230825, -0.59662616, 1.3997843, 0.33511618, 0.56846994, 0.3797911, 0.035079807, -0.18287429, -0.032232445, 0.006910181, -0.0026898328, -0.0057844054, 0.29354542, 0.13796881, 0.3558416, 0.0022847173, 0.0025906325, -0.022641085}; -static const float B2[] = {-0.11655525, -0.0036503011}; - -static const float W1[] = {0.15791991, -0.22649878, 0.021204736, 0.025593571, 0.008755621, -0.775102, -0.41594088, -0.12580238, -0.3963741, 0.33545518, -0.631953, -0.028754484, -0.50668705, -0.3574023, -3.7807872, -0.8261617, 0.102246165, 0.571127, -0.6256297, 0.06698781, 0.55969477, 0.25374785, -3.075965, -0.6959133, 0.2531965, 0.31739804, -0.8664238, 0.12750633, 0.83136076, 0.2666574, -2.5865922, -0.572031, 0.29743987, 0.16238026, -0.99154145, 0.077973805, 0.8913329, 0.16854058, -2.5247803, -0.5639109, 0.41671264, -0.10801031, -1.0229865, 0.2062031, 0.39889312, -0.16026731, -1.9185526, -0.48375717, 0.057339806, -1.2573057, -0.23117211, 1.051854, -0.7981992, -1.6263007, -0.26003376, -0.07649365, -0.4646075, 0.755821, 0.13187818, 0.24743222, -1.5276812, 0.1636555, -0.075465426, -0.058517877, -0.33852127, 1.3052516, 0.14443535, 0.44080895, -0.31031442, 0.15416017, 0.0053661224, -0.03175326, -0.15991405, 0.66121936, 0.0832211, 0.2651985, -0.038445678, 0.18054117, -0.0073251156, 0.054193687, -0.014296916, 0.30657783, 0.006181963, 0.22319937, 0.030315898, 0.12695274, -0.028179673, 0.11189027, 0.035358384, 0.046855893, -0.026528472, 0.26450494, 0.069981076, 0.107152134, -0.030371506, 0.09524366, 0.24802336, -0.36496836, -0.102762334, 0.49609017, 0.04002767, 0.020934932, -0.054773595, 0.05412083, -0.071876526, -1.5381132, -0.2356421, 1.5890793, -0.023087852, -0.24933836, 0.018771818, 0.08040064, 0.051946845, 0.6141782, 0.15780787, 0.12887044, -0.8691056, 1.3761537, 0.43058, 0.13476849, -0.14973496, 0.4542634, 0.13077497, 0.23117822, 0.003657386, 0.42742714, 0.23396699, 0.09209521, -0.060258932, 0.4642852, 0.10395402, 0.25047097, -0.05326261, 0.21466804, 0.11694269, 0.22402634, 0.12639907, 0.23495848, 0.12770525, 0.3324459, 0.0140223345, 0.106348366, 0.10877733, 0.30522102, 0.31412345, -0.07164018, 0.13483422, 0.45414954, 0.054698735, 0.07451815, 0.097312905, 0.27480683, 0.4866108, -0.43636885, -0.13586079, 0.5724732, 0.13595985, -0.0074526076, 0.11859829, 0.24481037, -0.37537888, -0.46877658, -0.5648533, 0.86578417, 0.3407381, -0.17214134, 0.040683553, 0.3630519, 0.089548275, -0.4989473, 0.47688767, 0.021731026, 0.2856471, 0.6174715, 0.7059148, -0.30635756, -0.5705427, -0.20692639, 0.041900065, 0.23040071, -0.1790487, -0.023751246, 0.14114629, 0.02345284, -0.64177734, -0.069909826, -0.08587972, 0.16460821, -0.53466517, -0.10163383, -0.13119817, 0.14908728, -0.63503706, -0.098961875, -0.23248474, 0.15406314, -0.48586813, -0.1904713, -0.20466608, 0.10629631, -0.5291871, -0.17358926, -0.36273107, 0.12225631, -0.38659447, -0.24787207, -0.25225234, 0.102635615, -0.14507034, -0.10110793, 0.043757595, -0.17158166, -0.031343404, -0.30139172, -0.09401665, 0.06986169, -0.54915506, 0.66843456, 0.14574362, -0.737502, 0.7700305, -0.4125441, 0.10115133, 0.05281194, 0.25467375, 0.22757779, -0.030224197, -0.0832025, -0.66385627, 0.51225215, -0.121023245, -0.3340579, -0.07505331, -0.09820366, -0.016041134, -0.03187605, -0.43589246, 0.094394326, -0.04983066, -0.0777906, -0.12822862, -0.089667186, -0.07014707, -0.010794195, -0.29095307, -0.01319235, -0.039757702, -0.023403417, -0.15530063, -0.052093383, -0.1477549, -0.07557954, -0.2686017, -0.035220042, -0.095615104, -0.015471024, -0.03906604, 0.024237331, -0.19604297, -0.19998372, -0.20302829, -0.04267139, -0.18774728, -0.045169186, -0.010131819, 0.14829905, -0.117015064, -0.4180649, -0.20680964, -0.024034742, -0.15787442, -0.055698488, -0.09037726, 0.40253848, -0.35745984, -0.786149, -0.0799551, 0.16205557, -0.14461482, -0.2749642, 0.2683253, 0.6881363, -0.064145364, 0.11361358, 0.59981894, 1.2947721, -1.2500908, 0.6082035, 0.12344158, 0.15808935, -0.17505693, 0.03425684, 0.39107767, 0.23190938, -0.7568858, 0.20042256, 0.079169095, 0.014275463, -0.12135842, 0.008516737, 0.26897284, 0.05706199, -0.52615446, 0.12489152, 0.08065737, -0.038548164, -0.08894516, 7.250979E-4, 0.28635752, -0.010820533, -0.39301336, 0.11144395, 0.06563818, -0.033744805, -0.07450528, -0.027328406, 0.3002447, 0.0029921278, -0.47954947, -0.04527057, -0.010289918, 0.039380465, -0.09236952, -0.1924659, 0.15401903, 0.21237805, -0.38984418, -0.37384143, -0.20648403, 0.29201767, -0.1299253, -0.36048025, -0.5544466, 0.45723814, -0.35266167, -0.94797707, -1.2481197, 0.88701195, 0.33620682, 0.0035414647, -0.22769359, 1.4563162, 0.54950374, 0.38396382, -0.41196275, 0.3758704, 0.17687413, 0.038129736, 0.16358295, 0.70515764, 0.055063568, 0.6445265, -0.2072113, 0.14618243, 0.10311305, 0.1971523, 0.174206, 0.36578146, -0.09782787, 0.5229244, -0.18459272, -0.0013945608, 0.08863555, 0.24184574, 0.15541393, 0.1722381, -0.10531331, 0.38215113, -0.30659106, -0.16298945, 0.11549875, 0.30750987, 0.1586183, -0.017728966, -0.050216004, 0.26232007, -1.2994286, -0.22700997, 0.108534105, 0.7447398, -0.39803517, 0.016863048, 0.10067235, -0.16355589, -0.64953077, -0.5674107, 0.017935256, 0.98968256, -1.395801, 0.44127485, 0.16644385, -0.19195901}; -static const float B1[] = {1.2019119, -1.1770505, 2.1698284, -1.9615222}; - -static const float W[] = {0.55808353, 0.78707385, -0.040990848, -0.122510895, -0.41261443, -0.036044, 0.1691557, -0.14711425, -0.016407091, -0.28058195, 0.018765535, 0.062936015, 0.49562064, 0.33931744, -0.47547337, -0.1405672, -0.88271654, 0.18359914, 0.020887045, -0.13782434, -0.052250575, 0.67922074, -0.28022966, -0.31278887, 0.44416663, -0.26106882, -0.32219923, 1.0321393, -0.1444394, 0.5221766, 0.057590708, -0.96547794, -0.3051688, 0.16859075, -0.5320585, 0.42684716, -0.5434046, 0.014693736, 0.26795483, 0.15921915}; -static const float B[] = {0.041442648, 1.461427, 0.07154641, -1.2774754, 0.80927604, -1.6933714, -0.29740578, -0.11774022, 0.3292682, 0.6596958}; - -// ASCII lib from (https://www.jianshu.com/p/1f58a0ebf5d9) -static const char codeLib[] = "@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. "; -static void print_img(const float * buf) -{ - for(int y = 0; y < 28; y++) - { - for (int x = 0; x < 28; x++) - { - int index = 0; - if(buf[y*28+x] > 0.6f) index =69; - if(index < 0) index = 0; - printf("%c",codeLib[index]); - printf("%c",codeLib[index]); - } - printf("\n"); - } -} - -#endif //__MNIST_H__ diff --git a/components/ai/onnx/pic/mnist_test.png b/components/ai/onnx/pic/mnist_test.png new file mode 100644 index 0000000000000000000000000000000000000000..8fe248bf46680a0c5f7ca23498c2360a88f83831 GIT binary patch literal 39940 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 z z6NdxLOvtD!$;YEi3@(uFeF5ks<|hid9M0emr~}w6#Cyl5Gpy-V2{+WUtzXhUGvC$B zWu|-Q!Zp^esNcrark}zuc>Kn>sR5ko%-p4pknZ1Uy>L&>>)A<>noX9ssBdDIiqU56 z1po*{kCL*^ZR%sC>T`$S(z*T(!aY79%<%-q?D-@4>x}f`k(ET+-|1>n1=hd4==4 zx$wLabn~O$I*<#YZ$eM-fp)-cop!I6$W#Rwr~d%>+gjx_J8^}@`a;h07y+)yX4Wis z_fLRkzefZ5XP>#f){*yC?h`X*97VjW=1TdAjDHJY6D+Vr&YEZ8rJE8N0eaOm)6qZo zcx{&zHtv@cIkT+`R9L_WJjscgRzDOUCoNbOr-t>G?!UF!NYT=M`;;s5$M=`fr#>Yt zsR3Cu{G2}_XLa5dKd=w$3U#XaKES4br*WpC)n4ci95|5PH#*^K+u5wGKhOD*NFb+U zSKNH=$+)?@f4!FI(;z@j5H>LpPqnhb-O?21dA$U;Qr**y$yC~m2AYzRoDrgSa~93r zybEn$lI)2w4JLb@PK1#@6(Q8GjOR!DQ?m_U#e*tPJJT%2QAnzIfj`M40y;jrO3G`` zzX^ykJ*@H?;vwxRu~*E{I}@s+Pc+T_w@E4O>I0uZE6dj}$Jk%|07xY<%efZW9Bwt> z0lpSC5wCUa`Ogj98!Z#h?2lU@zxYlo+_ zYn@T4s>;rBq<+l4|9ymlgNWna6%^ipIzBLhyMLh*_~N?KqgOgcYE=b)0WJD3pU+D+ zQNwJT?b`f4z~)rD~hxS{k)Fa5@%E;tO@l2bzlv ze))Ew^B}PQ!WFFXXXB#FZziV3yzV;PE(UUJGWl!Mio&MrdK zkFRB-tCpdm)Wxv+zJijkSFI~VeZOP?XgxI|85#8y(go*+o(%08|EY3w1=VFw^aCz6 z0qn?P1r{D>%>=c0)N`iz%%^evm72{!8~h)0yL8;sw68WKdq#|y_T~S3L;wGWH(SsJ zFzG2T#5@KfrW5({kFi;V_5}wWkKN@7u$J_=uzI}!(Q82e?tAwDPYuL^A}oDjECu^3 zl(IZn|CL5M5KKC<%M&WI!2WzFlRf5G2y#gW3bv`t?Htx1nJ#-?XPEh+MD8u`?n~cU zHp}jxA2=0?J|p&>05%b`Q)t92Nt0S6$~Yfsrwp+CAe}2Y^C!LdTamXEo2$!z)Me$+ z%;3K|@Jc@h@v;Qwr6b*3NmC3;qwcwre>*<7)rqC<9g2*52*KHK&PNSN*tLBrWBJ%o zd}gmGk8-;H@nuMg3t`>RgTkixA``OlJpFQ!V`;6~ zCQKJ{+CQqrY!ncsGhOkf)Jnjbi&}HJGwuh<#lB8#v3Xq6g}9;Tu%=Px*WWF2>d(r^ zjTAmlz_+|wwT&b;1(JBs$?@-Gbkk}pH}`gU?$_6QnMUjzo4?R&%x2ME8YNEu6?Wz@ z%G}@h;gPwipL{YH8c&xt&4x+n%VM@!NzSZCFw7;|W_24ZQjnf}>#*~32B6vS-0f(k z)Ic;rPq4!)^SBSw(t8DJLuq})gSEQC^4oAC?IQm}dFC9%65Yc^>C!`ab4dl@%sQ*W zimW@CKk1gnTON32^0MGXHd8Rp#_G@k`ol$*|6i@EXXyR0U;YdYYx-K#bZ1pJ5s!lU z6-CMPvAaEMPRV%_s?M)|xuthfuz6ls%$QH-qbmi8^*eS%V)#MdY{Rz773_l!o0L zM+7{24RRb4^%}eVHaxh8y-XgY&GqZNMwssgeU#|Oz@c93PFt>n!Hvm_3M{g~RiVgv z{J4kY^0lc2!S(qXrsxX}gH{5z?}#m$N@HioG~ott<1<}h0C_>vzA3&sW~Ey}w$P!f zc!zR9x)c?Tx#D;0YUXj)SQQP@7p$!Je80qp;yNF7jw&4_Mt(&qtMTS=Nfa2lJ3J}i z{u?un5Hh%#YvA4@u1KGO#%(;FP21JXGJ2&KKEi4dvDja%74~ZAr2{i`|1)LkavPG? zwVz7{2Zzbk)!Bbv0Y9YL%F6^$|n zVD&D`qYrA&J#^|bi)C6&5FwC&8z{TbExBW`EA9IU1_rvquhE$-Wa9drL4sPP*1Oj% zsP|{W90GVUEGe$1Ul~|KZ!(xG%zh+!fLSj;a>|aqc*hl__%7%I135&Iv#M`_Q5)P< zft!?g4#wz`pviH^G;qh+HZ}tP8$c&D$nn$3j5rKc(PClG+)d0oi%EOTm3s|`cmpD) z;>dkqoOJwUD8aR0{alh%^hgOK^sgOuqALQxIOXRQy3PB5-L^lo^$_;&Xjzdtp3F+n zcA7*0O!XV;Fr&cOz=MXyR>`Y(E%{CGp@BDfyXpbo8GOX3F~sCD3r4J_Dmlu0mCR1o zVwfqo@E@(Xu;(o4@o>{#8Eo!_?9X}oMK@?GT#dpgy&n;%NGx^a%2s~@$tP6Iv=1)4Y{FiE`^<)|(H#@gzooE&cK4$0y0|-|Wd%j8{F$CQ)iTyL(Bs zW9e)6H~TS;iF6R=b`0q*R>OBS%0hxumCvJDcziDk{XrYc-(>fvNU5_eohtOA1;_3- zCO-~m`(okQ`%J;rr}c_!sY4yJ>%C@5L*wJgqq7}V3=iEUx<>eSj3)!X9LH>LkE%?z ze(}$;JHvp}w?;nA5|77Ia1})B2=*#X377+`{!1K;s9pQ3#Gg(=X5gNoA9${-qvsVX z$_+lwRK!egc#`*-43GiZ+gh=2oJ}-(iph1`BerwI5F<0k7L6pb<7nYh0%Kz!V_6=1 z(?N29*`7D+G?M@0XK`m)4I7t#@rIQp-Jnw_61qjrda;1ECW34{k{(+hwJqNKlw2lo2at2b}fo~?o>rvC8J zv8PXS9ak*|h%O&Qdg8xDw2X~x8lgfxc$jDX2uNZ6fSQae?mM=SWXCm=ZjIQ*#OmJ> zuhhhD!5Z~V*@{PCe@RGU9pZP7qR*WSH+#3T@wN((5oh%Y*QG6&7q59+#Nv_Qb$w#d z`2o98dNWQKf#ZWOoo-z5(9n= zxncJiui-8>qKfOfF@-V`RftL3jT)NQ#c*Gfg*hH4O_f_I`KS}jD%BI>Wz$4a6~Wnyw<^sMOW%Ne)H7GTWV@&tW*(UrHZ_(E!@+xb$33k-wjXs9;lJ|rb0pC~ zxZptlBHIt-97pl&&XMrBwUJ~o8H<3w!_oH4%YVMrwF#}abEFJQvzTXQGNfCqU3@qG z6;Bu*yM31k&a-8-wmmbr4$VJEAF4)5mP4fhKSmvA8TE%}mFZBCh!3@OksS!%ariFa z3?29-H_T>j)@NWNlJS)7yhGrz@{r5>vCzuSaB+>NC!ULXtY3^1W?xnxi0WRfGdX^& zk9D*CJ&xjg9ua$*EPr)mHxfOU{Uv8}w(wYD2~>d0DIDE7HMUg4V&XqIieV?E)0e2L zJ;guCwQ6zV&PP`eh`DQ4*C=lce3nKwsRvQLHUPWdTpvhZ;|2!@o1nek0WWyo+Voik z$^?vNGYl;sKeqI)Si^OlYS%tFM68UVcB`ltT62-{*eUKC;gbqC(xUf6dc+poD$2v| z$wfaF<~zB}zXTQue!s=1cRt&5yOJK{c!H20S&=g$v>PuMr9BGVP2CHx>eS9(!XEdXH;)80V)mB(BhZc+oJ*Pb5hvT#0zJMk1vB5@FeM`PKvz2 zfCc%fa>H+>;Z7zl(5q5oppaXLhV4!b{V#?JCGYQPpKp5z5MQ&0PPBHcF_NzGGE1kw zd>P7#+&}({^16(v4T7`#!D@SJEO;_9maOjmeD`cB@bR)-RhMPwKqY1~)-qvayg5}M zi`a+SiUgIt&+4z5?Q#?&kK9TCiSmS$436=Ig9RUGe&u-VTNZ5_N7mI5`nZ;}a)+J_ zuS6#7bB0c2?rm(`zf@@xreYiW1f0ho$h^;rCxu+2e|8!4f2k2R)jt!p_k`Jl)3H)Q zMx#A~vOrx;*>m3XP+Au>&+^qS&@6ivTR?=!H#IsVc=RS8<3#nfaVT~`Nc&h_Pxk{a zalj*WK^U`8&kUsd~;+m|h#7M+?lR~B=IZ_7(9r2}JSHQ-mS-BJljiwy@dSve$ zc}opF$oh2`-FELq!#XSXJS6?&$NcI2PIdrws88Fc<&?~Wmbm?TNqMyO^;9o6vYw)e zyb~(H@H-AM=QW#;)PIH*)@MNCtY>t~MyH*=vW^cLEZ-!DcTTrEcMl>dpBqMBdAV2a z%V5qZMxMb97uIGaAmRtVKsj*gn?mSLl5f6TiX9K>rRgvlOJfgLnyB6BR*&k#2`DdkV)62^i51LHKKLjV8( literal 0 HcmV?d00001