【2024CANN训练营第二季】Ascend C编程范式

举报
JeffDing 发表于 2024/10/18 10:10:12 2024/10/18
【摘要】 编程范式快速开发编程的固定步骤统一代码框架的开发捷径使用者总结出的开发经验面向特定场景的编程思想定制化的方法论开发体验Ascend C编程范式把算子内部的处理程序,分成多个流水任务(Stage),以张量(Tensor)为数据载体,以队列(Queue)进行任务之间的通信与同步,以内存管理模块(Pipe)管理任务间的通信内存。 Ascend C编程范式:针对各代Davinci芯片的复杂数据流,...

编程范式

  • 快速开发编程的固定步骤
  • 统一代码框架的开发捷径
  • 使用者总结出的开发经验
  • 面向特定场景的编程思想
  • 定制化的方法论开发体验

Ascend C编程范式把算子内部的处理程序,分成多个流水任务(Stage),以张量(Tensor)为数据载体,以队列(Queue)进行任务之间的通信与同步,以内存管理模块(Pipe)管理任务间的通信内存。

Ascend C编程范式:

  1. 针对各代Davinci芯片的复杂数据流,根据实际计算需求,抽象出并行编程范式,简化流水并行
  2. Ascend C的并行编程范式核心要素
    1.一组并行计算任务
    2.通过队列实现任务之间的通信和同步
    3.程序员自主表达对并行计算任务和资源的调度
  3. 典型的计算范式
    1.基本的矢量编程范式:计算任务分为CopyIn,Compute,CopyOut
    2.基本的矩阵编程范式:计算任务分为:CopyIn,Split,Compute,Aggregate,CopyOut
    3.复杂的矢量/矩阵编程范式:通过将矢量/矩阵的Out/In组合在一起的方式来实现复杂计算数据流

抽象编程模型

image.png

流水任务

流水任务(Stage)指的是单核处理程序中主程序调度的并行任务。
在核函数内部,可以通过流水任务实现数据的并行处理来提升性能

举例来说,单核处理程序的功能可以被拆分成3个流水任务:Stage1、Stage2、Stage3,每个任务专注于完成单一功能,需要处理的数据被切分成n片,使用Progress1~n表示,每个任务需要依次完成n个数据切片的处理。Stage间的箭头表达数据间的依赖关系,比如Stage1处理完Progress1之后,Stage2才能对Progress1进行处理。
image.png
若Progress的n=3,待处理的数据被切分成3片,对于同一片数据,Stage1、Stage2、Stage3之间的处理具有依赖关系、需要串行处理。不同的数据切片,同一时间点,可以有多个流水任务Stage在并行处理,由此达到任务并行,提升性能目的
image.png

矢量编程流水任务设计

矢量算子编程范式把算子的实现流程分为3个基本任务:CopyIn,Compute,CopyOut
CopyIn:负责数据搬入操作
Compute:负责矢量计算操作
CopyOut:负责数据搬出操作
image.png

任务间通信和同步

数据通信与同步的管理者
不同的流水任务之间存在数据依赖,需要进行数据传递
Ascend C中使用Queue队列完成任务之间的数据通信和同步
Queue提供了EnQue,DeQue等基础API
Queue队列管理NPU上不同层级的物理内存时,用一种抽象的逻辑位置(QuePosition)来表达各个级别的存储(Storage Scope)代替了片上物理存储的概念,开发者无需感知硬件架构
TPosition类型包括:VECIN、VECCALC、VECOUT、A1、A2、B1、B2、CO1、CO2。其中VECIN、VECCALC、VECOUT主要用于面向向量编程;A1、A2、B1、B2、CO1、CO2用于矩阵编程
数据的载体
Ascend C使用Global Tensor和Local Tensor作为数据的基本操作单元,它是各种指令API直接调用的对象,也是数据的载体

TPosiition 具体含义
GM Global Memory,对应AI Core的外部存储
VECIN 用于向量计算,搬入数据的存放位置,在数据搬入Vectory计算单元时使用此为止
VECOUT 用于向量计算,搬出数据的存放位置,在将Vector计算单元结果搬出时使用此位置
VECALC 用于向量计算/矩阵计算,在计算需要临时变量时使用此位置
A1 用于矩阵计算,存放整块A矩阵,可类比CPU多级存储中的二级缓存
B1 用于矩阵计算,存放整块B矩阵,可类比CPU多级存储中的二级缓存
A2 用于矩阵计算,存放切分后的小块A矩阵,可类比CPU多级存储中的一级缓存
B2 用于矩阵计算,存放切分后的小块B矩阵,可类比CPU多级存储中的一级缓存
CO1 用于矩阵计算,存放小块结果C矩阵,可理解为Cube Out
CO2 用于矩阵计算,存放整块结果C矩阵,可理解为Cube Out

矢量编程任务间通信和同步

矢量编程中的逻辑位置(QuePosition):搬入数据的存放位置:VECIN、搬出数据的存放位置:VECOUT
矢量编程主要分为CopyIn、Compute、CopyOut三个任务:

  • CopyIn任务中将输入数据从GlobalTensor搬运至LocalTensor后,需要使用EnQueLocalTensor放入VECIN的Queue
  • Compute任务等待VECINQueueLocalTensor出队之后才可以进行矢量计算,计算完成后使用Enque将计算结果LocalTensor放入到VECOUTQueue
  • CopyOut任务等待VECOUTQueueLocalTensor出队,再将其拷贝到GlobalTensor

image.png
Stage1:CopyIn任务
使用DataCopy接口将GlobalTensor拷贝到LocalTensor
使用EnqueLocalTensor放入VECINQueue
Stage2:Compute任务
使用DeQueVECIN中取出LocalTensor
使用Ascend C指令API完成矢量计算:Add
使用EnQue将结果LocalTensor放入VECOUTQueue
Stage3:CopyOut任务
使用DeQue接口从VECOUTQueue中取出LocalTensor
使用DataCopy接口将LocalTensor拷贝到GlobalTensor

内存管理

任务间数据传递使用到的内存统一由内存管理模块Pipe进行管理
Pipe作为片上内存管理者,通过InitBuffer接口对外提供Queue内存初始化功能,开发者可以通过该接口为指定的Queue分配内存
Queue队列内存初始化完成后,需要使用内存时,通过调用AllocTensor来为LocalTensor分配内存给Tensor,当创建的LocalTensor完成相关计算无需再使用时,再调用FreeTensor来回收LocalTenor的内存

InitBuffer、AllocTensor和FreeTensor的示例

// 使用AllocTensor分配Tensor
TPipe pipe;
TQue<TPosition::VECOUT, 2> que;
int num = 4;
int len = 1024;
// InitBuffer分配内存块数为4,每块大小为1024Bytes
Pipe.InitBuffer(que, num, len);
// AllocTensor分配Tensor长度为1024Bytes
LocalTensor<half> tensor1 = que.AllocTensor();
// 使用FreeTensor释放通过AllocTensor分配的Tensor,注意配对使用
que.FreeTensor<half>(tensor1);

image.png

临时变量内存管理

编程过程中使用到的临时内存同样通过Pipe进行管理。临时变量可以使用TBuf数据结构来申请指定的QuePosition上的存储空间,并使用Get()来将分配到的存储空间分配给新的LocalTensor
TBuf上获取全部长度,或者获取指定长度的LocalTensor

LocalTensor<T> Get<T>(uint32_t len);

Tbuf及其Get接口的示例

// 为TBuff初始化分配内存,分配内存长度为1024字节
TPipe pipe;
TBuf<TPosition::VECIN> calcuBuf; //模板参数为QuePosition中的VECIN类型
uint32_t byteLen = 1024;
pipe.InitBuffer(calcBuf, byteLen);
// 从calcBuf获取Tensor,Tensor为pipe分配的所有内存大小,为1024字节
LocalTensor<int32_t> tempTensor1 = calcBuf.Get<int32_t>();
//// 从calcBuf获取Tensor,Tensor为128个int32_t类型元素的内存大小,为512字节
LocalTensor<int32_t> tempTensor1 = calcBuf.Get<inte32_t>(128);

使用TBuf申请的内存空间只能参与计算,无法执行Queue队列的入队出队操作

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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