【2023 · CANN训练营第一季】TIK C++算子开发入门 笔记
【2023 · CANN训练营第一季】TIK C++算子开发入门 笔记
TIK C++介绍
TIK C++是一种使用C/C++作为前端语言的算子开发工具,通过四层接口抽象、并行编程范式、孪生调试等技术,极大提高算子开发效率,助力AI开发者低成本完成算子开发和模型调优部署
使用TIK C++开发自定义算子的优势:
•C/C++原语编程
•编程模型屏蔽硬件差异,编程范式提高开发效率
•多层级API封装,从简单到灵活,兼顾易用与高效
•孪生调试,CPU侧模拟NPU侧的行为,可先在CPU侧调试
核函数
核函数(Kernel Function)是TIK C++算子设备侧的入口。TIK C++允许用户使用核函数这种C/C++函数的语法扩展来管理设备侧的运行代码,用户在核函数中实现算子逻辑的编写,例如自定义算子类及其成员函数以实现该算子的所有功能。核函数是主机侧和设备侧连接的桥梁。
核函数是直接在设备侧执行的代码。在核函数中,需要为在一个核上执行的代码规定要进行的数据访问和计算操作,当核函数被调用时,多个核将并行执行同一个计算任务
算子执行的不同模式
TIK C++算子可用CPU模式或NPU模式执行
CPU模式:算子功能调试用,可以模拟在NPU上的计算行为,不需要依赖昇腾设备
NPU模式:算子功能/性能调试,可以使用NPU的强大算力进行运算加速
使用内置宏__CCE_KT_TEST__标识被宏包括的代码在特定的模式下编译
#ifdef __CCE_KT_TEST__ 表示在CPU模式下会编译该段代码
#ifndef __CCE_KT_TEST__ 表示在NPU模式下会编译该段代码
编程范式
快速开发编程的固定步骤
统一代码框架的开发捷径
使用者总结出的开发经验
面向特定场景的编程思想
定制化的方法论开发体验
TIK C++编程范式把算子内部的处理程序,分成多个流水任务(Stage),以张量(Tensor)为数据载体,以队列(Queue)进行任务之间的通信与同步,以内存管理模块(Pipe)管理任务间的通信内存。
流水任务
流水任务(Stage)指的是单核处理程序中主程序调度的并行任务。在核函数内部,可以通过流水任务实现数据的并行处理来提升性能。
举例来说,单核处理程序的功能可以被拆分成3个流水任务:Stage1、Stage2、Stage3,每个任务专注于完成单一功能;需要处理的数据被切分成n片,使用Progress1~n表示,每个任务需要依次完成n个数据切片的处理。Stage间的箭头表达数据间的依赖关系,比如Stage1处理完Progress1之后,Stage2才能对Progress1进行处理。
流水任务设计——矢量编程
矢量算子编程范式把算子的实现流程分为3个基本任务:CopyIn,Compute,CopyOutCopyIn负责数据搬入操作,Compute负责矢量计算操作,CopyOut负责数据搬出操作
任务间通信和同步
数据通信与同步的管理者
不同的流水任务之间存在数据依赖,需要进行数据传递
TIK C++中使用Queue队列完成任务之间的数据通信和同步,Queue提供了EnQue、DeQue等基础APIQueue队列管理NPU上不同层级的物理内存时,用一种抽象的逻辑位置(QuePosition)来表达各个级别的存储(Storage Scope),代替了片上物理存储的概念,开发者无需感知硬件架构矢量编程中Queue类型(逻辑位置)包括:VECIN、VECOUT
任务间通信和同步——矢量编程
矢量编程中的逻辑位置(QuePosition):搬入数据的存放位置:VECIN、搬出数据的存放位置:VECOUT
矢量编程主要分为CopyIn、Compute、CopyOut三个任务:•CopyIn任务中将输入数据从GlobalTensor搬运至LocalTensor后,需要使用EnQue将LocalTensor放入VECIN的Queue中
•Compute任务等待VECIN的Queue中LocalTensor出队之后才可以进行矢量计算,计算完成后使用EnQue将计算结果LocalTensor放入到VECOUT的Queue中•CopyOut任务等待VECOUT的Queue中LocalTensor出队,再将其拷贝到GlobalTensor
- 点赞
- 收藏
- 关注作者
评论(0)