tvm学习笔记(六):数据类型及形状

2023-12-23 10:48

本文主要是介绍tvm学习笔记(六):数据类型及形状,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

据说tvm会支持训练,然后沐神他们为了推广tvm,专门对tvm重写了文档d2l-tvm,具体详见资料[1],下面就是对着沐神他们写的文档做的学习记录:

1.tvm的数据类型

我们在声明placeholder的时候,可以显式的指定数据的类型,如:'float16', 'float64', 'int8','int16', 'int64'等

import tvm
A = tvm.placeholder((n,), dtype='float32')
print(A.dtype)
B = tvm.placeholder((n,), dtype='int8')
print(B.dtype)

结果如下:

下面来看一下,如何使用tvm来定义两个向量相加的运算:

首先声明两个占位符A和B,并指定他们的shape:

A = tvm.placeholder((n,), dtype=dtype)
A = tvm.placeholder((n,), dtype=dtype)

然后使用使用tvm.compute定义C的计算,并使用lambda函数来指定输出C中每个元素的计算方式:

C = tvm.compute(A.shape, lambda i: A[i] + B[i])

其次,我们需要指定如何来执行程序,如,数据访问顺序及如何进行多线程并行计算,这样一个执行设计称之为一个schedule,C为输出,下面使用tvm.create_schedule就对C的操作创建一个默认的schedule:

s = tvm.create_schedule(C.op)

后面可以看到如何通过改变执行设计来更好的利用硬件资源,进而提升执行效率。这里,我们可以使用tvm.lower操作,打印一下当前默认执行设计:

tvm.lower(s, [A, B, C], simple_mode=True)

可以得到:

最后,使用tvm.build操作将定义好的计算和设计编译成可执行模块:

module = tvm.build(s, [A, B, C])

将上面的代码连在一起,就是使用tvm来创建两个向量相加的函数:

import tvm
import numpy as npn = 100# Defined in file: ./chapter_expression/vector_add.md
def eval_mod(mod, *inputs, out):"""Evaluate a TVM module, and save results in out."""# Convert all numpy arrays to tvm arraystvm_args = [tvm.nd.array(x) if isinstance(x, np.ndarray) else x for x in inputs + (out,)]mod(*tvm_args)# If out is a tvm array, then its value has already been inplaced. # Otherwise, explicitly copy the results. if isinstance(out, np.ndarray):np.copyto(out, tvm_args[-1].asnumpy())def tvm_vector_add(dtype):A = tvm.placeholder((n,), dtype=dtype)B = tvm.placeholder((n,), dtype=dtype)C = tvm.compute(A.shape, lambda i: A[i] + B[i])s = tvm.create_schedule(C.op)return tvm.build(s, [A, B, C])mod = tvm_vector_add('int32')def test_mod(mod, dtype):# you can use astype to convert data typea, b = (np.random.normal(size=100).astype(dtype) for _ in range(2))c = np.empty(100, dtype=dtype)eval_mod(mod, a, b, out=c)print("data type of c: {}".format(c.dtype))np.testing.assert_equal(c, a + b)test_mod(mod, 'int32')for dtype in ['float16', 'float64', 'int8', 'int16', 'int64']:mod = tvm_vector_add(dtype)test_mod(mod, dtype)

运行效果如下:

2.变化形状

在定义计算时,可能对于输入的形状是未知的,可以通过tvm.var定义一个变量来指定形状,然后在具体调用时,传入具体值即可,如对于定义A、B、C三个占位符时,如果不知道输入的维度,可以使用变量n来创建任意长度数组:

n = tvm.var(name='n')
print(type(n), n.dtype)A = tvm.placeholder((n,), name='a')
B = tvm.placeholder((n,), name='b')
C = tvm.compute(A.shape, lambda i: A[i] + B[i])
s = tvm.create_schedule(C.op)
mod = tvm.build(s, [A, B, C])

在调用时,传入数组长度:

def test_mod(mod, size):a, b = (np.random.normal(size=size).astype('float32') for _ in range(2))c = np.empty(size, dtype='float32')print("c shape: {}".format(c.shape))eval_mod(mod, a, b, out=c)np.testing.assert_equal(c, a + b)

完整代码如下:

import numpy as np
import tvm# Defined in file: ./chapter_expression/vector_add.md
def eval_mod(mod, *inputs, out):"""Evaluate a TVM module, and save results in out."""# Convert all numpy arrays to tvm arraystvm_args = [tvm.nd.array(x) if isinstance(x, np.ndarray) else x for x in inputs + (out,)]mod(*tvm_args)# If out is a tvm array, then its value has already been inplaced. # Otherwise, explicitly copy the results. if isinstance(out, np.ndarray):np.copyto(out, tvm_args[-1].asnumpy())n = tvm.var(name='n')
print(type(n), n.dtype)A = tvm.placeholder((n,), name='a')
B = tvm.placeholder((n,), name='b')
C = tvm.compute(A.shape, lambda i: A[i] + B[i])
s = tvm.create_schedule(C.op)
tvm.lower(s, [A, B, C], simple_mode=True)def test_mod(mod, size):a, b = (np.random.normal(size=size).astype('float32') for _ in range(2))c = np.empty(size, dtype='float32')print("c shape: {}".format(c.shape))eval_mod(mod, a, b, out=c)np.testing.assert_equal(c, a + b)mod = tvm.build(s, [A, B, C])
test_mod(mod, 5)
test_mod(mod, 1000)def tvm_vector_add(ndim):A = tvm.placeholder([tvm.var() for _ in range(ndim)])B = tvm.placeholder(A.shape)C = tvm.compute(A.shape, lambda *i: A[i] + B[i])s = tvm.create_schedule(C.op)return tvm.build(s, [A, B, C])mod = tvm_vector_add(2)
test_mod(mod, (2, 2))mod = tvm_vector_add(4)
test_mod(mod, (2, 3, 4, 5))

运行结果如下:

3.矩阵转置

 

参考资料:

[1] https://github.com/d2l-ai/d2l-tvm

[2] http://tvm.d2l.ai.s3-website-us-west-2.amazonaws.com/

这篇关于tvm学习笔记(六):数据类型及形状的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/527756

相关文章

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

MySQL数据类型与表操作全指南( 从基础到高级实践)

《MySQL数据类型与表操作全指南(从基础到高级实践)》本文详解MySQL数据类型分类(数值、日期/时间、字符串)及表操作(创建、修改、维护),涵盖优化技巧如数据类型选择、备份、分区,强调规范设计与... 目录mysql数据类型详解数值类型日期时间类型字符串类型表操作全解析创建表修改表结构添加列修改列删除列

Python标准库datetime模块日期和时间数据类型解读

《Python标准库datetime模块日期和时间数据类型解读》文章介绍Python中datetime模块的date、time、datetime类,用于处理日期、时间及日期时间结合体,通过属性获取时间... 目录Datetime常用类日期date类型使用时间 time 类型使用日期和时间的结合体–日期时间(

详解MySQL中JSON数据类型用法及与传统JSON字符串对比

《详解MySQL中JSON数据类型用法及与传统JSON字符串对比》MySQL从5.7版本开始引入了JSON数据类型,专门用于存储JSON格式的数据,本文将为大家简单介绍一下MySQL中JSON数据类型... 目录前言基本用法jsON数据类型 vs 传统JSON字符串1. 存储方式2. 查询方式对比3. 索引

Python变量与数据类型全解析(最新整理)

《Python变量与数据类型全解析(最新整理)》文章介绍Python变量作为数据载体,命名需遵循字母数字下划线规则,不可数字开头,大小写敏感,避免关键字,本文给大家介绍Python变量与数据类型全解析... 目录1、变量变量命名规范python数据类型1、基本数据类型数值类型(Number):布尔类型(bo

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

通过C#获取Excel单元格的数据类型的方法详解

《通过C#获取Excel单元格的数据类型的方法详解》在处理Excel文件时,了解单元格的数据类型有助于我们正确地解析和处理数据,本文将详细介绍如何使用FreeSpire.XLS来获取Excel单元格的... 目录引言环境配置6种常见数据类型C# 读取单元格数据类型引言在处理 Excel 文件时,了解单元格