【2023 · CANN训练营第一季】TIK C++算子开发入门-笔记总结

举报
hw1028010755 发表于 2023/05/13 19:36:58 2023/05/13
【摘要】 TIK C++算子开发入门-笔记总结TIK2简介TIK2是一种使用C/C++作为前端语言的编程框架,开发者可以使用TIK2提供的API编写自定义算子,并通过CCEC编译器将自定义算子编译成为可运行在昇腾AI处理器上的应用程序。TIK2继承了TIK数据操作灵活的优点,除此之外,更多优势如下:C/C++原语编程编程模型屏蔽硬件差异,编程范式提高开发效率多层级API封装,从简单到灵活,兼顾易用与高...

TIK C++算子开发入门-笔记总结

TIK2简介

TIK2是一种使用C/C++作为前端语言的编程框架,开发者可以使用TIK2提供的API编写自定义算子,并通过CCEC编译器将自定义算子编译成为可运行在昇腾AI处理器上的应用程序。

TIK2继承了TIK数据操作灵活的优点,除此之外,更多优势如下:

C/C++原语编程

编程模型屏蔽硬件差异,编程范式提高开发效率

多层级API封装,从简单到灵活,兼顾易用与高效

调试方法简单


核函数(Kernel Function)介绍

核函数(Kernel Function)是TIK2算子的入口。TIK2允许用户使用核函数这种C/C++函数的语法扩展来管理设备端的运行代码,用户在核函数中进行算子类的声明和其成员函数的调用,由此实现该算子的所有功能。

核函数是直接在设备端执行的代码。在核函数中,需要为在一个核上执行的代码规定要进行的数据访问和计算操作,当核函数被调用时,多个核将并行执行同一个计算任务。核函数需要按照如下规则进行编写。

核函数调用

内核调用符仅可在NPU侧编译时调用,CPU侧编译无法识别该符号。

执行配置由3个参数决定:

blockDim,规定了核函数将会在几个核上执行,blockDim的大小不能超过当前设备上核的配置个数。每个执行该核函数的核会被分配一个逻辑ID,表现为内置变量block_idx,可以在核函数的实现中直接使用;

l2ctrl,保留参数,暂时设置为固定值nullptr,开发者无需关注;

stream,类型为aclrtStream,stream是一个任务队列,应用程序通过stream来管理任务的并行。

编程范式

编程范式描述了算子实现的固定流程,基于编程范式进行编程,可以快速搭建算子实现的代码框架。

TIK2编程范式把算子核内的处理程序,分成多个流水任务,任务之间通过队列(Queue)进行通信和同步,并通过统一的内存管理模块(Pipe)管理任务间通信内存。


流水任务

TIK2分别针对Vector、Cube编程设计了不同的流水任务。开发者只需要完成基本任务的代码实现即可,底层的指令同步和并行调度由TIK2框架实现,开发者无需关注。

Vector编程范式把算子的实现流程分为3个基本任务:CopyIn,Compute,CopyOut。CopyIn负责搬入操作,Compute负责矢量指令计算操作,CopyOut负责搬出操作。

矢量编程

矢量编程主要分为CopyIn、Compute、CopyOut三个任务。CopyIn任务中将输入数据从Global内存搬运至Local内存后,需要使用EnQue 将LocalTensor放入VECIN的Queue中;Compute任务等待VECIN的Queue中LocalTensor出队之后才可以完成矢量计算,计算完成后使用EnQue 将计算结果LocalTensor放入到VECOUT的Queue中;CopyOut任务等待VECOUT的Queue中LocalTensor出队,再将其拷贝到Global内存。这样 ,Queue队列就完成了三个任务间的数据通信和同步。

内存管理

任务间数据传递使用到的内存统一由内存管理模块Pipe进行管理。Pipe作为片上内存管理者,通过InitBuffer 接口对外提供Queue内存初始化功能,开发者可以通过该接口为指定的Queue分配内存。

Queue队列内存初始化完成后,需要使用内存时,通过调用AllocTensor 来为LocalTensor分配内存,当创建的LocalTensor完成相关计算无需再使用时,再调用FreeTensor 来回收LocalTensor的内存。


TIK2方式实现矩阵算子

算子分析:分析算子的数学表达式、输入、输出以及计算逻辑的实现,明确需要调用的TIK2接口。

核函数定义:定义TIK2算子入口函数。

根据矩阵编程范式实现算子类:完成核函数的内部实现。


算子调试

TIK2提供孪生调试方法,即在cpu侧创建一个npu的模型并模拟它的计算行为,用来进行业务功能调试。相同的算子代码可以在cpu域调试精度,npu域调试性能。

cpu域

运行使能ASSERT,初步拦截算子指令或框架使用错误,如参数超限,指令数据地址重叠,该芯片不支持的指令等;

可使用gdb单步调试算子计算精度,也可以在代码中直接编写printf(...)来观察数值的输出;

可使用model仿真粗调算子性能,获取性能仿真数据;

通过指令录制回放,可获得算子运行调用指令序列,分析指令执行顺序以及同步死锁分析。

npu域

可在真实芯片上获取profiling数据,进行性能精细调优;

npu域调试手段较少,可在cpu域精度调试通过,且性能粗调通过后,在芯片上验收测试。


















【版权声明】本文为华为云社区用户翻译文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容, 举报邮箱:cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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