其他
【他山之石】ONNX模型文件->可执行文件 C Runtime通路 具体实现方法
“他山之石,可以攻玉”,站在巨人的肩膀才能看得更高,走得更远。在科研的道路上,更需借助东风才能更快前行。为此,我们特别搜集整理了一些实用的代码链接,数据集,软件,编程技巧等,开辟“他山之石”专栏,助你乘风破浪,一路奋勇向前,敬请关注。
01
02
03
04
ONNX 模型文件的生成:
$ python gen_add_onnx.py
将ONNX 模型文件(add.onnx)转化为动态链接库文件(add.so):
在执行命令的目录下,得到库文件 add.so。
$ ./onnx-mlir --EmitLib ${PWD}/add.onnx
Shared library ${PWD}/add.so has been compiled.
在官网上直接给出了对应刚刚生成的 add.so 库文件的C程序:
在此直接给出C程序(该C程序与官网给出的C程序一样,作为备份),保存为 main.c。
#include <OnnxMlirRuntime.h>#include <stdio.h>
OMTensorList *run_main_graph(OMTensorList *);
int main() {
// Shared shape & rank.
int64_t shape[] = {2, 2};
int64_t rank = 2;
// Construct x1 omt filled with 1.
float x1Data[] = {1., 1., 1., 1., 1., 1.};
int64_t *x1Shape = {2, 2};
OMTensor *x1 = omTensorCreate(x1Data, shape, rank, ONNX_TYPE_FLOAT);
// Construct x2 omt filled with 2.
float x2Data[] = {2., 2., 2., 2., 2., 2.};
int64_t *x2Shape = {2, 2};
OMTensor *x2 = omTensorCreate(x2Data, shape, rank, ONNX_TYPE_FLOAT);
// Construct a list of omts as input.
OMTensor *list[2] = {x1, x2};
OMTensorList *input = omTensorListCreate(list, 2);
// Call the compiled onnx model function.
OMTensorList *outputList = run_main_graph(input);
// Get the first omt as output.
OMTensor *y = omTensorListGetOmtByIndex(outputList, 0);
float *outputPtr = (float *)omTensorGetDataPtr(y);
// Print its content, should be all 3.
for (int i = 0; i < 6; i++)
printf("%f ", outputPtr[i]);
return 0;
}
将文件 main.c 与 add.so 使用 gcc 链接编译得到生成可执行文件 add。
gcc main.c add.so -o add
最后,执行可执行文件 ./.add。
$ ./add
3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
05
main.c: In function ‘main’:
main.c:12:23: warning: initialization of ‘int64_t *’ {aka ‘long int *’} from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
12 | int64_t *x1Shape = {2, 2};
| ^
main.c:12:23: note: (near initialization for ‘x1Shape’)
main.c:12:26: warning: excess elements in scalar initializer
12 | int64_t *x1Shape = {2, 2};
| ^
main.c:12:26: note: (near initialization for ‘x1Shape’)
main.c:17:23: warning: initialization of ‘int64_t *’ {aka ‘long int *’} from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
17 | int64_t *x2Shape = {2, 2};
| ^
main.c:17:23: note: (near initialization for ‘x2Shape’)
main.c:17:26: warning: excess elements in scalar initializer
17 | int64_t *x2Shape = {2, 2};
|
^main.c:17:26: note: (near initialization for ‘x2Shape’)
本文目的在于学术交流,并不代表本公众号赞同其观点或对其内容真实性负责,版权归原作者所有,如有侵权请告知删除。
“源头活水”历史文章
Pytorch mixed precision 概述(混合精度)
TIP 2021论文速递:多曝光图像融合及超分辨的联合实现
层次风格解耦:人脸多属性篡改终于可控了(CVPR 2021 Oral)
Transformer实现Video Instance Segmentation
CVPR 2021 Oral | “无招胜有招”?北航、耶鲁、商汤提出用于无数据量化的多样化样本生成
神经网络图结构如何影响其预测性能?Graph Structure of Neural Networks
Graph上的预训练模型
Transformer is All You Need 论文翻译
小样本学习中的比对学习
探究小样本学习中等变性与不变性表示的互补优势
AAAI2021 通过主动学习提升模型鲁棒性
深入理解:迁移强化学习之Successor Representation
PSS:更简单有效的End-to-End检测
Transfer in DRL Using SFs & GPI
图上如何学习组合优化算法
更多源头活水专栏文章,
请点击文章底部“阅读原文”查看
分享、在看,给个三连击呗!