【TBE算子开发】TIk算子开发总结

举报
kourei 发表于 2020/03/31 11:41:55 2020/03/31
【摘要】 TIk算子开发总结tik算子开发时可以采用当前我们DSL的开发框架进行,当变量过多时可以以class形式来开发 tik算子开发只需要在算子接口处进行shape、dtype等的验证,但tik不需要定义tvm.placeholder,直接定义TIK的DSL容器,语句如下 12import tik tik_instacnce = tik.Tik(tik.Dprofile("v100", "clou...

TIk算子开发总结


tik算子开发时可以采用当前我们DSL的开发框架进行,当变量过多时可以以class形式来开发 

tik算子开发只需要在算子接口处进行shape、dtype等的验证,但tik不需要定义tvm.placeholder,直接定义TIK的DSL容器,语句如下 

1
2
import tik 
tik_instacnce = tik.Tik(tik.Dprofile("v100""cloud"))

目前只支持v100下cloud和mini,其中tik.Tik用于创建TIK的DSL的容器,tik.Dprofile用于指定编程时针对的编程环境

一旦创建了TIK容器,所有的语句都是基于tik_instacnce进行语句开发,不能出现普通的python语句

当前tik语句支持的数据类型有:int8,uint8, int16, uint16, int32, uint32, float16, float32,uint1(bool),比如在cloud形式下,除了输入输出的gm类型局限在fp32、fp16、int8、int32、uint8,tik中的数据类型都可以采用上述的数据类型;

定义Scalar方法:

1
= tik_instance.Scalar("int64")

相当于定义了一个uint64的Scalar变量x;

定义tensor方法:

1
= tik_instance.Tensor(name = "X", dtype="float32", shape=[1,], scope=tik.scope_gm)

其中scope表示tensor定义的区域;

Scalar和tensor的生命周期:在定义语句时创建,到定义语句所在代码块(ifelsefor)的结束并释放,只有在存在期间可以被访问,,所以要根据需要去确定定义的范围

分支结构:采用if_scope进行分支判断(else部分为可选),实现如下:

1
2
3
4
with tik_instance.if_scope(x>1):
    #some method
with tik_instance.else_scope:
   #some method

For语句:

1
tik_instance.for_range(begint,endt,name="i", thread_num=1,block_num=1,dtype="int32") as i

等同于 for i in range(begint, endt),里面的begint, endt可以使用常量,不一定要tik定义的scalar

thread_num可以选择1或者2,默认为1,当选择2时,为开启pingpong,在该for循环语句下,每个buf会double

block_num:分核数,默认值为1,只能在一个for循环中设置该值,建议在最外循环外设置该值;

tik.Tik.BuildCCE(kernel_name, inputs,outpus):用于将DSL容器中语句编译成CCEC代码

inputs:List型变量,List中存放程序的输入Tensor(需要是global memory的存储类型)

outputs,List型变量,List中存放程序的输出Tensor(需要是global memory的存储类型)

以上为tik开发最基本的语句

下面给出一个简单的例子:使用tik语句实现a+b:

a:fp32 [1024, 1024,1024]

b : fp32 [1024, 1024,1024]

add属于vector操作,需要把a和b的数据从gm搬到ub中,在然后进行add操作,最后再从搬出来

考虑到a+b的结果可以复写到a中,因此考虑在ub中定义两个tensor,分别用于存放a和b;另外由于a和b的shape比较大,在考虑分核的同时,还需要考虑DB使能,因此a和b可以分到的UB为UB总大小的1/4(记为a_ub和b_ub).

UB大小为256K,a_ub=b_ub=64k,相当于64*1024/4=16*1024个fp32数据,因此每次可以从gm往ub中搬运16*1024个数据

vector一拍可以处理64个fp32数据,因此repeat=1024*16/64=256(repeat 上限是255,考虑分两次执行,每次128)

具体实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 定义tik容器,这里定义为cloud环境下
tik_instance = tik.Tik(tik.Dprofile("v100""cloud"))
# 定义输入输出的gm
input_x_gm = tik_instance.Tensor("float32", [102410241024], name="input_x", scope=tik.scope_gm)
input_y_gm = tik_instance.Tensor("float32", [102410241024], name="input_y", scope=tik.scope_gm)
output_gm = tik_instance.Tensor("float32", [102410241024], name="ioutput", scope=tik.scope_gm)
# 最外面循环进行分核,cloud下最大为32核
with tik_instance.for_range(0,32, block_num=32) as out:
    # db循环,循环次数为1024^3/32/16/1024=2048,该循环内定义的ub都会自动double
    with tik_instance.for_range(02048, thread_num=2) as db_out:
        # 定义ub_a和ub_b
            a_ub = tik_instance.Tensor("float32", (16,1024), name="a_ub", scope=tik.scope_ubuf)
        b_ub = tik_instance.Tensor("float32", (16,1024), name="b_ub", scope=tik.scope_ubuf)
        # 搬运数据
        tik_instance.data_move(a_ub, input_x_gm[out*32 + db_out*16%1024, db_out*16%10240], 0116*1024*4//3200)
        tik_instance.data_move(y_ub, input_y_gm[out*32 + db_out*16%1024, db_out*16%10240], 0116*1024*4//3200)
        # 数据运算
        tik_instance.vadd(64, a_ub, a_ub, b_ub, 128111888)
        tik_instance.vadd(64, a_ub[80], a_ub[80], b_ub[80], 128111888)
        # 搬运数据
        tik_instance.data_move(input_x_gm[out*32 + db_out*16%1024, db_out*16%10240], a_ub, 0116*1024*4//3200)
tik_instance.BuildCCE(kernel_name="add", inputs=[input_x_gm, input_y_gm], outputs=[output_gm,])



【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。