【TVM模型编译】2. relay算子构造.md
从TVM的官方Tutorial里面,介绍了如何新增自定义算子。(这是我翻译的)
之前的文章讲到了onnx 算子转换到Relay IR的过程
下面以Conv2d算子介绍,编译过程中 Relay IR是如何被调用的。
relay 算子调用
上面的get_relay_op实际上是查找所有 relay ir算子,其代码在python/tvm/relay/frontend/common.py中的get_relay_op。继续以conv卷积算子为例介绍。上文所述的转换算子中,有下面的语句
for candidate in (_op, _op.nn, _op.image, _op.vision, _op.contrib):
op = getattr(candidate, op_name, None)
if op is not None:
break
对于conv2d算子,在_op.nn中,找到conv2d实现。
def conv2d(
data,
weight,
strides=(1, 1),
padding=(0, 0),
dilation=(1, 1),
groups=1,
channels=None,
kernel_size=None,
data_layout="NCHW",
kernel_layout="OIHW",
out_layout="",
out_dtype="",
):
if isinstance(kernel_size, int):
kernel_size = (kernel_size, kernel_size)
if isinstance(strides, int):
strides = (strides, strides)
if isinstance(dilation, int):
dilation = (dilation, dilation)
padding = get_pad_tuple2d(padding)
return _make.conv2d( data, weight, strides, padding, dilation, groups, channels, kernel_size, data_layout, kernel_layout, out_layout, out_dtype,
)
这里的_make.conv2d是通过下面的PackFunc注册得到的
tvm._ffi._init_api("relay.op.nn._make", __name__)
在src/relay/op/nn/convolution.cc找到conv2d的注册函数
TVM_REGISTER_GLOBAL("relay.op.nn._make.conv2d")
.set_body_typed([](Expr data, Expr weight, Array<IndexExpr> strides, Array<IndexExpr> padding,
Array<IndexExpr> dilation, int groups, IndexExpr channels,
Array<IndexExpr> kernel_size, String data_layout, String kernel_layout,
String out_layout, DataType out_dtype) {
return MakeConv<Conv2DAttrs>(data, weight, strides, padding, dilation, groups, channels,
kernel_size, data_layout, kernel_layout, out_layout, out_dtype,
"nn.conv2d");
});
MakeConv 是对所有卷积的模板,根据参数实例化相应的函数
template <typename T>
inline Expr MakeConv(Expr data, Expr weight, Array<IndexExpr> strides, Array<IndexExpr> padding,
Array<IndexExpr> dilation, int groups, IndexExpr channels,
Array<IndexExpr> kernel_size, std::string data_layout,
std::string kernel_layout, std::string out_layout, DataType out_dtype,
std::string op_name) {
auto attrs = make_object<T>();
attrs->strides = std::move(strides);
attrs->padding = std::move(padding);
attrs->dilation = std::move(dilation);
attrs->groups = groups;
attrs->channels = std::move(channels);
attrs->kernel_size = std::move(kernel_size);
attrs->data_layout = std::move(data_layout);
attrs->kernel_layout = std::move(kernel_layout);
attrs->out_layout = std::move(out_layout);
attrs->out_dtype = std::move(out_dtype);
const Op& op = Op::Get(op_name);
return Call(op, {data, weight}, Attrs(attrs), {});
}
这里通过Op::Get(op_name); 获取对应relay算子,在Op::Get函数中发现是通过查表得到。
// find operator by name
const Op& Op::Get(const String& name) {
const OpRegEntry* reg = OpRegistry::Global()->Get(name);
ICHECK(reg != nullptr) << "AttributeError: Operator " << name << " is not registered";
return reg->op();
}
注册是通过C++的RELAY_REGISTER_OP("nn.conv2d")宏注册到OpRegistry::Global()中。宏展开为
static __attribute__((unused))::tvm::OpRegEntry& __make_Op230 =
::tvm::OpRegEntry::RegisterOrGet("nn.conv2d").set_name()
注册过程:
RELAY_REGISTER_OP("nn.conv2d")
.describe(R"code(2D convolution layer (e.g. spatial convolution over images).
This layer creates a convolution kernel that is convolved
with the layer input to produce a tensor of outputs.
- **data**: This depends on the `layout` parameter. Input is 4D array of shape
(batch_size, in_channels, height, width) if `layout` is `NCHW`.
- **weight**: (channels, in_channels, kernel_size[0], kernel_size[1])
- **out**: This depends on the `layout` parameter. Output is 4D array of shape
(batch_size, channels, out_height, out_width) if `layout` is `NCHW`.
)code" TVM_ADD_FILELINE)
.set_attrs_type<Conv2DAttrs>()
.set_num_inputs(2)
.add_argument("data", "Tensor", "The input tensor.")
.add_argument("weight", "Tensor", "The weight tensor.")
.set_support_level(2)
.add_type_rel("Conv2D", Conv2DRel<Conv2DAttrs>)
.set_attr<FInferCorrectLayout>("FInferCorrectLayout", ConvInferCorrectLayout<Conv2DAttrs>);
返回的是OpRegEntry,后续的set_name等,则是通过OpRegEntry的get接口(返回的是OpNode),构造对应的Relay op
【TVM模型编译】2. relay算子构造.md的更多相关文章
- TVM将深度学习模型编译为WebGL
使用TVM将深度学习模型编译为WebGL TVM带有全新的OpenGL / WebGL后端! OpenGL / WebGL后端 TVM已经瞄准了涵盖各种平台的大量后端:CPU,GPU,移动设备等.这次 ...
- 【KAWAKO】TVM-tflite模型编译与优化
目录 前言 准备模型 版本问题 精度问题 加载tflite模型 编译模型 在python上运行模型进行测试 加载输入数据 运行四连 优化(Autotune) 注: 前言 TVM的编译与优化主要有两种方 ...
- - 反编译 AndroidKiller 逆向 实践案例 MD
目录 目录 反编译 AndroidKiller 逆向 实践案例 MD AndroidKiller 简介 插件升级 基本使用 实践案例 修改清单文件 打印 debug 级别的日志 方式一:直接代理 Lo ...
- TVM优化Deep Learning GPU算子
TVM优化Deep Learning GPU算子 高效的深度学习算子是深度学习系统的核心.通常,这些算子很难优化,需要HPC专家付出巨大的努力. 端到端张量IR / DSL堆栈TVM使这一过程变得更加 ...
- MACE(2)-----模型编译
作者:十岁的小男孩 QQ:929994365 无用 本文仅用于学习研究,非商业用途,欢迎大家指出错误一起学习,文章内容翻译自 MACE 官方手册,记录本人阅读与开发过程,力求不失原意,但推荐阅读原文. ...
- Win 10环境下6sV2.1模型编译心得
最新版本6sV2.1模型是通过FORTRAN95编写的,2017年11月代码编写完成,2018年11月发布在模型官网上.通常我们在使用过程中都是调用模型的.exe可执行文件,而下载下来的是FORTRA ...
- opencv编译静态库时选择MD模式无效的原因
在Cmake-gui上看到的明明是MD运行库依赖,生成MS项目时却变成了MT运行库依赖. 原因在于编译静态库时内部做了自动替换.
- TVM部署预定义模型
TVM部署预定义模型 本文通过深度学习框架量化的模型加载到TVM中.预量化的模型导入是在TVM中提供的量化支持之一. 本文演示如何加载和运行由PyTorch,MXNet和TFLite量化的模型.加载后 ...
- 字节码 反编译 APKTool 重新打jar包 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- keras channels_last、preprocess_input、全连接层Dense、SGD优化器、模型及编译
channels_last 和 channels_first keras中 channels_last 和 channels_first 用来设定数据的维度顺序(image_data_format). ...
随机推荐
- Docker 配置阿里云或腾讯云镜像加速
1.新建 /etc/docker/daemon.json 文件,并写入以下内容: 阿里云按下面配置 sudo tee /etc/docker/daemon.json <<-'EOF' { ...
- Docker认识、Docker安装
一.免费版和企业版 Docker-CE指Docker社区版,由社区维护和提供技术支持,为免费版本,适合个人开发人员和小团队使用. Docker-EE指Docker企业版,为收费版本,由售后团队和技术团 ...
- 关于Java中方法重载和方法重写
方法重写是子类继承父类(默认继承Object类)后覆盖父类的方法 需要保证同名 同参 同返回值 且访问权限范围不能缩小(public>protected>default>privat ...
- TENGSHE-OS-渗透测试系统-win11版
下载ISO文件 创建新的虚拟机 VM17 已支持直接创建 win11 x64 稍后安装系统 选中win11 修改路径 win11需要设置8位加密密码 勾选安全引导 根据自身情况选择 默认即可 150G ...
- 【FAQ】关于JavaScript版本的华为地图服务Map的点击事件与Marker的点击事件存在冲突的解决方案
一. 问题描述 创建地图对象,并添加marker标记,对map和marker均添加了点击事件: <body> <script> function initMap() { // ...
- ERROR: libfdk_aac not found和ERROR: libmp3lame >= 3.98.3 not dound
ERROR: libfdk_aac not found和ERROR: libmp3lame >= 3.98.3 not dound 编译ffmepg时出现这两个错误或者有时候需要x264编码的时 ...
- input输入框输入组合的限制
1 输入大小写字母.数字.下划线: 2 <input type="text" οnkeyup="this.value=this.value.replace(/[^\ ...
- Java的对象包装器 & 自动装箱
有时,需要将 int 这样的基本类型转换为对象.所有的基本类型都有一个与之对应的类.例如,Integer 类对应基本类型 int.通常,这些类被称为包装器(wrapper).这些对象包装器类拥有很明显 ...
- 使用Kepserver 自带 DataLogger 功能 实现工控数据转储关系型数据库
本文以 Mysql数据库为例,介绍使用 kepserver 的datalogger 功能转储数据到 mysql 第一步:下载安装 Mysql ODBC 数据库驱动前往 官网下载ODBC驱动https: ...
- laravel框架三级联动,详细代码
这里运用到省份表中,下面是效果图 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 需要一个省份表,里面的字段要有个pid,name这些字段 下面是控制器代码,(Cit ...