TVM:TensorIR
TensorIR是一种用于深度学习的特定领域语言,主要有两个目的。
- 在各种硬件后端进行程序变换和优化的实现
- 用于自动张量化程序优化的抽象
import tvm
from tvm.script.parser import ir_module
from tvm.ir.module import IRModule
from tvm.script import tir as T
import numpy as np
IRModule
IRModule是TVM的中心数据结构,它包含深度学习程序。它是 IR 变换和模型构建的基本关注对象。

这是 IRModule 的生命周期(life cycle),它可以从 TVMScript 创建。TensorIR 调度原语(primitive)和传递(pass)是变换 IRModule 的两种主要方式。另外,对 IRModule 进行一系列的变换也是可以接受的。请注意,可以在 任何 阶段向 TVMScript 打印 IRModule。 在所有变换和优化完成后,可以将 IRModule 构建为可运行的模块,以部署在目标设备上。
基于 TensorIR 和 IRModule 的设计,能够创建新的编程方式:
1.用 TVMScript 写基于 Python-AST 语法的程序。
2. 用 python api 变换和优化程序。
3. 通过命令式的变换 API,交互式地检查和尝试性能。
Create an IRModule
IRModule 可以通过编写 TVMScript 来创建,TVMScript 是 TVM IR 的可圆润化(round-trippable)的语法。
与通过 张量表达式 创建计算表达式不同,TensorIR 允许用户通过 TVMScript(嵌入式 python AST 的语言)来编程。这种新方法使得编写复杂的程序并进一步调度和优化它成为可能。
@tvm.script.ir_module
class MyModule:
@T.prim_func
def main(a: T.handle, b: T.handle):
# We exchange data between function by handles, which are similar to pointer.
T.func_attr({"global_symbol": "main", "tir.noalias": True})
# Create buffer from handles.
A = T.match_buffer(a, (8,), dtype="float32")
B = T.match_buffer(b, (8,), dtype="float32")
for i in range(8):
# A block is an abstraction for computation.
with T.block("B"):
# Define a spatial block iterator and bind it to value i.
vi = T.axis.spatial(8, i)
B[vi] = A[vi] + 1.0
ir_module = MyModule
print(type(ir_module))
print(ir_module.script())

此外,还可以使用张量表达式 DSL 来编写简单的算子,并将其转换为 IRModule。
from tvm import te
A = te.placeholder((8,), dtype="float32", name="A")
B = te.compute((8,), lambda *i: A(*i) + 1.0, name="B")
func = te.create_prim_func([A, B])
ir_module_from_te = IRModule({"main": func})
print(ir_module_from_te.script())

Build and Run an IRModule
可以将 IRModule 构建为具有特定目标后端的可运行模块。
mod = tvm.build(ir_module, target="llvm") # The module for CPU backends.
print(type(mod))
输出结果:
<class 'tvm.driver.build_module.OperatorModule'>
准备好输入 array 和输出 array,然后运行该模块。
a = tvm.nd.array(np.arange(8).astype("float32"))
b = tvm.nd.array(np.zeros((8,)).astype("float32"))
mod(a, b)
print(a)
print(b)
输出结果:
[0. 1. 2. 3. 4. 5. 6. 7.]
[1. 2. 3. 4. 5. 6. 7. 8.]
Transform an IRModule
IRModule 是程序优化的中心数据结构,它可以通过 Schedule 进行转换。调度包含多个原语方法,以交互式地转换程序。每个原语都以某些方式改造程序,以带来额外的性能优化。

上面的图片是优化张量程序的典型工作流程。首先,需要在由 TVMScript 或 Tensor Expression 创建的初始 IRModule 上创建调度。然后,一连串的调度原语将有助于提高性能。最后,我们可以将其降低并构建为可运行的模块。
这里只演示了非常简单的变换。首先,在输入的 ir_module 上创建调度。
sch = tvm.tir.Schedule(ir_module)
print(type(sch))
输出结果:
<class 'tvm.tir.schedule.schedule.Schedule'>
将该循环分为 3 个循环,并打印结果。
# Get block by its name
block_b = sch.get_block("B")
# Get loops surrounding the block
(i,) = sch.get_loops(block_b)
# Tile the loop nesting.
i_0, i_1, i_2 = sch.split(i, factors=[2, 2, 2])
print(sch.mod.script())

也可以重新调度循环的顺序。现在将循环 i_2 移到 i_1 的外面。

i_1)
print(sch.mod.script())

Transform to a GPU program
如果想在 GPU 上部署模型,线程绑定是必要的。幸运的是,也可以使用原语并做增量变换。
sch.bind(i_0, "blockIdx.x")
sch.bind(i_2, "threadIdx.x")
print(sch.mod.script())
# from tvm.script import tir as T
@tvm.script.ir_module
class Module:
@T.prim_func
def main(A: T.Buffer[8, "float32"], B: T.Buffer[8, "float32"]) -> None:
# function attr dict
T.func_attr({"global_symbol": "main", "tir.noalias": True})
# body
# with T.block("root")
for i_0 in T.thread_binding(2, thread="blockIdx.x"):
for i_2 in T.thread_binding(2, thread="threadIdx.x"):
for i_1 in T.serial(2):
with T.block("B"):
vi = T.axis.spatial(8, i_0 * 4 + i_1 * 2 + i_2)
T.reads(A[vi])
T.writes(B[vi])
B[vi] = A[vi] + T.float32(1)
绑定线程后,现在用 cuda 后端构建 IRModule。
ctx = tvm.cuda(0)
cuda_mod = tvm.build(sch.mod, target="cuda")
cuda_a = tvm.nd.array(np.arange(8).astype("float32"), ctx)
cuda_b = tvm.nd.array(np.zeros((8,)).astype("float32"), ctx)
cuda_mod(cuda_a, cuda_b)
print(cuda_a)
print(cuda_b)
输出结果:
[0. 1. 2. 3. 4. 5. 6. 7.]
[1. 2. 3. 4. 5. 6. 7. 8.]
TVM:TensorIR的更多相关文章
- tvm install
一.系统需求:1.可以访问互联网2.关闭防火墙和selinux 二.安装步骤(进入软件包所在目录):1.rpm -ivh daemontools-0.76-1.el6.x86_64.rpm2.yum ...
- 关于 TVM
偶然间对 arm 中 mali 显示核心感兴趣,找到的 TVM.将了解到的信息做个备忘. TVM 是 Tensor Virtual Machine 的所写? 官网上,TVM 定义自己为一种 Inter ...
- TVM:
Hello TVM 发表于 2019-06-29 TVM 是什么?A compiler stack,graph level / operator level optimization,目的是(不同框 ...
- TVM图优化(以Op Fusion为例)
首先给出一个TVM 相关的介绍,这个是Tianqi Chen演讲在OSDI18上用的PPThttps://files.cnblogs.com/files/jourluohua/Tianqi-Chen- ...
- TVM设备添加以及代码生成
因为要添加的设备是一种类似于GPU的加速卡,TVM中提供了对GPU编译器的各种支持,有openCl,OpenGL和CUDA等,这里我们选取比较熟悉的CUDA进行模仿生成.从总体上来看,TVM是一个多层 ...
- TVM调试指南
1. TVM安装 这部分之前就写过,为了方便,这里再复制一遍. 首先下载代码 git clone --recursive https://github.com/dmlc/tvm 这个地方最好使用--r ...
- TVM安装
因为现在NNVM的代码都转移到了TVM中,NNVM代码也不再进行更新,因此选择安装的是TVM. git clone --recursive https://github.com/dmlc/tvm su ...
- TVM:一个端到端的用于开发深度学习负载以适应多种硬件平台的IR栈
TVM:一个端到端的用于开发深度学习负载以适应多种硬件平台的IR栈 本文对TVM的论文进行了翻译整理 深度学习如今无处不在且必不可少.这次创新部分得益于可扩展的深度学习系统,比如 TensorFlo ...
- TVM性能评估分析(七)
TVM性能评估分析(七) Figure 1. Performance Improvement Figure 2. Depthwise convolution Figure 3. Data Fus ...
- TVM性能评估分析(六)
TVM性能评估分析(六) Figure 1. The workflow of development PC, compile, deploy to the device, test, then mo ...
随机推荐
- StarBlog博客开发笔记(33):全新的访问统计功能,异步队列,分库存储
前言 虽然现在工作重心以AI为主了,不过相比起各种大模型的宏大叙事,我还是更喜欢自己构思功能.写代码,享受解决问题和发布上线的过程. 之前 StarBlog 系列更新的时候我也有提到,随着功能更新,会 ...
- 【Manim】空间与变换笔记
[Manim]空间与变换笔记 所有常量都可以在constants.py中找到 屏幕空间 屏幕中心为原点(0,0,0),遵循右手坐标系,向右为x轴正方向,向上为y轴正方向,向前为z轴负方向,旋转时正方向 ...
- 服务器vps测试脚本大全,新云linux综合工具箱-linux加速脚本 一键硬盘挂载
服务器vps测试脚本大全 一键更换yum脚本 一键优化shh卡顿 一键更换软件源 各种linux加速 BBR原版 bbrplus 魔改plus 锐速 脚本linux加速脚本 一键硬盘挂载 一键cc防御 ...
- mac brew 安装
Homebrew国内源 知乎文章地址:https://zhuanlan.zhihu.com/p/111014448 苹果电脑安装脚本: /bin/zsh -c "$(curl -fsSL h ...
- linux 源码安装完php后在目录下找不到php.ini的问题
首先,我们需要确定php版本的php.ini文件需要放在个目录下 我们先执行以下命令查看php的php.ini目录应该放在那个地方 php -i |grep php.ini 效果如下,现在我们确定好了 ...
- 【Azure Fabric Service】演示使用PowerShell命令部署SF应用程序(.NET)
问题描述 在中国区微软云Azure上使用Service Fabrics服务,本地通过Visual Studio 2022的发布.NET应用,发现无法发布! 在搜寻官方文档之后,可以通过PowerShe ...
- JVM堆内存(heap)详解
JAVA堆内存管理是影响性能主要因素之一.堆内存溢出是JAVA项目非常常见的故障,在解决该问题之前,必须先了解下JAVA堆内存是怎么工作的.先看下JAVA堆内存是如何划分的,如图:Java堆内存又溢出 ...
- Linux下如何重启Oracle
操作步骤 切换到oracle用户 su – oracle 通过sqlplus以管理员身份登录 sqlplus / as sysdba 然后执行 shutdown immediate 退出sqlplus ...
- [每日算法 - 华为机试] leetcode680. 验证回文串 II
入口 力扣https://leetcode.cn/problems/valid-palindrome-ii/submissions/ 题目描述 给你一个字符串 s,最多 可以从中删除一个字符. 请你判 ...
- C# 13 中的新增功能实操
前言 今天大姚带领大家一起来看看 C# 13 中的新增几大功能,并了解其功能特性和实际应用场景. 前提准备 要体验 C# 13 新增的功能可以使用最新的 Visual Studio 2022 版本或 ...