CANN/hcomm CCU编程模型与概念

CANN/hcomm CCU编程模型与概念
CCU编程模型与概念【免费下载链接】hcommHCOMMHuawei Communication是HCCL的通信基础库提供通信域以及通信资源的管理能力。项目地址: https://gitcode.com/cann/hcommCCU架构系统架构CCUCollective Communication Unit集合通信处理器是昇腾NPU中的专用集合通信协处理器位于IO Die上。下图展示了CCU在Ascend 950PR/Ascend 950DT中的位置基础概念CCU内部包含多个关键组件共同完成集合通信任务片上缓存片上数据缓存以4KB分片为基础操作单元支持多片的片上规约操作。寄存器分为通用寄存器、同步寄存器和地址寄存器通用寄存器用于存放CCU执行过程中的参数或数据支持简单赋值和加法运算。同步寄存器用于实现类似信号量的同步操作支持Wait或Set操作。地址寄存器用于存放通信操作的内存地址未来会取消使用通用寄存器替代。并发执行引擎提供CCU的并发与循环执行指令的能力。指令空间存储CCU执行的指令序列。Channel表存放多个Channel表项每个表项包含用于UB通信的上下文信息。CCU典型用法与优势在大规模分布式训练和推理业务中集合通信的性能是影响整体系统性能的关键瓶颈之一。传统通信方式中集合通信依赖AI CPU、AI Core等计算单元通过软件协议栈构造通信任务描述符驱动硬件执行通信任务。这种执行方式需要占用计算核或计算算力并且软件协议栈的调度开销较大导致通信整体延迟较高。为了解决上述问题NPU引入了集合通信加速单元Collective Communication UnitCCU作为专用处理器加速集合通信任务。CCU可接收NPU调度器下发的集合通信任务执行通信算法指令完成跨NPU的同步、地址交换、数据传输以及归约Reduce运算从而实现完整的集合通信能力。CCU典型用法是通过使用片上缓存进行数据中转以此降低内存访问如图所示Reduce操作从远端读取数据到片上缓存与本地内存数据进行归约最终写回本地内存。如果不使用片上缓存在对每个对端的数据进行规约时都需要读写一次本地数据再加上每个对端对本地数据的读取共需要进行2(n-1)次读和n-1次写如果使用片上缓存那么只需要1次本地数据的读取以及1次规约后的写回再加上每个对端对本地数据的读取共需要进行n次读和1次写。Broadcast操作类似地利用片上缓存减少内存访问次数同理Broadcast可将n-1次读和n-1次写降低为1次读和n-1次写。CCU优势节省访存带宽在分布式训练和推理业务中访存带宽是性能瓶颈。CCU结合集合通信算子的数据移动特征通过内置独立的片上MS将Allreduce等通信算子的访存需求降低约一个数量级释放出更多访存带宽供计算算子使用从而提升通信与计算的并发性能。升精度归约与确定性集合通信中的归约运算存在精度损失和顺序不确定性问题。CCU利用独立片上MS和升精度归约单元确保加法顺序和浮点数截断误差可控有效提升归约运算的精度和确定性。低时延通信不占用计算核传统通信方式依赖AICPU/AI Vector核占用计算资源。CCU通过硬件加速通信任务描述符的构造与下发在降低通信时延的同时不占用计算算力为低时延业务提供独立的硬件支持。资源抽象资源类型说明对应资源ccu::Variable变量通用寄存器ccu::Address地址地址寄存器ccu::Event事件同步寄存器ccu::CcuBuffer片上缓存分片大小为4KBCCU片上缓存ccu::LocalAddr本地地址用于通信操作包含地址和token分别由Address和Variable保存ccu::RemoteAddr远端地址用于通信操作包含地址和token分别由Address和Variable保存资源创建单个资源创建默认构造函数直接创建。批量连续资源创建LoopLoopGroup操作对资源有连续性要求使用ccu::Array创建注意使用原生数组创建资源比如Variable vars[10]不保证资源的连续性。[!NOTE]说明CCU并发操作对资源的连续性有要求。使用原生数组创建资源比如Variable vars[10]不保证资源的连续性。使用示例// 单个资源 ccu::Variable var; ccu::CcuBuffer buf; // 批量资源分配 ccu::Arrayccu::Variable vars(10); ccu::Arrayccu::Event events(5);数据搬运能力如图所示CCU具备以下数据搬运能力本地内存 - Variable/Address寄存器从本地内存加载数据到寄存器。将寄存器内容保存到本地内存中。本地内存 - CcuBuf从本地内存读取数据到CcuBuf将CcuBuf数据写到本地内存CcuBuf - 远端内存从远端内存读取数据到CcuBuf。将CcuBuf数据写到远端内存。本地内存 - 远端内存读远端内存。写远端内存。写远端寄存器写远端同步寄存器。写本地Variable数据到远端Variable。计算能力通用寄存器/地址寄存器立即数赋值// 通用寄存器赋值 Variable x; x 5; // 地址寄存器赋值 uint64_t ptr; // ... Address addr; addr ptr;Variable赋值Variable x, y; // ... Variable v; v x; Address addr; addr y;加法Variable x5, y3, z; z xy; Address addr1, addr2; // ... addr1 x; addr2 addr1 x;CcuBuffer支持最多8个CcuBuffer的按序Reduce计算输入类型与输出类型一致支持的Reduce操作ADD、MAX、MIN支持的数据类型FP32、FP16、BF16、INT32、INT16、INT8和UINT8。对于FP16/BF16的ADD操作为避免精度损失CCU会升精度为FP32类型进行规约计算如下图所示并发模型LoopCCU任务中的基础并发单元。Loop内的操作串行执行不同Loop并行执行Loop可以循环执行内部操作配合CcuBuffer循环搬运数据Loop参数循环次数、每次循环操作的内存地址增量偏移使用CcuBuffer搬运数据时因大小有限单次数据搬运数据量有限利用多Loop并发可撑满链路带宽。LoopGroup将一组Loop复制多份增加并发Loop个数。Loop不能单独执行需要放在LoopGroup中对于LoopGroup中的LoopLoopGroup可以指定从哪个Loop开始复制以及复制的次数LoopGroup需要指定复制后每组Loop使用的资源id偏移。使用示例ccu::Func func([](){ Write(chann, remoteMem, localCcuBuf, 4096); }); ccu::Loop loop({10, 4096}, func); // 循环执行10次每次地址增量偏移为4096B // 对LoopGroup中的Loop从第0个Loop开始到最后一个都复制5次 ccu::LoopGroup loopGroup({5, 0, 4096*10, 10, 10}, {loop});同步机制CCU使用同步寄存器实现同步操作Wait操作等待掩码对应的寄存器比特置位才能返回。Record操作置位掩码对应的寄存器比特位。同步寄存器分为两种使用场景单个Device的本地操作抽象为Event。不同Device之间的通信操作抽象为Notify。本地事件本地事件有两种使用场景异步操作可以传入event对象通过EventWait可以等待异步操作完成。不同CCU任务使用EventRecord和EventWait通过event对象实现同步。使用示例ccu::Event evt; ccu::EventRecord(evt, 0x01); ccu::EventWait(evt, 0x01);远端通知两个通信实体建立Channel后1可以基于Channel中Notify序号写对端同步寄存器2可以基于Channel中Notify序号等待来自对端的通知信号。接口说明NotifyRecord(ch, notifyIdx, mask)向远端发送通知NotifyWait(ch, notifyIdx, mask)等待远端通知使用示例// 发送通知到远端 ccu::NotifyRecord(channelHandle, 0, 0x12); // 等待远端通知 ccu::NotifyWait(channelHandle, 0, 0x12);流程控制条件分支CCU_IF(counter ! limit) { // then-block} CCU_ELSE { // else-block }循环CCU_WHILE(counter ! limit) { accumulator accumulator step; counter counter one; }函数块类型/接口说明ccu::Func函数块定义ccu::CallFuncfunc(...)调用函数块使用示例// 定义函数块 ccu::Func myFunc([](https://gitcode.com/cann/hcomm/blob/97cb0aabda0b105e52a9e78c091530acc22ab783/docs/zh/comm_op_dev_guide/prog_models_concepts/Variable x, Variable y?utm_sourcegitcode_repo_files){ ... }); // 调用函数块 Variable arg1, arg2; ... ccu::CallFuncmyFunc(arg1, arg2);约束与限制参数加载CCU任务描述符最多只支持13个64bit的参数。参数加载指令LoadArg必须在程序最开始调用。资源创建资源创建出来后不支持动态回收比如在局部作用域中定义的资源比如Variable在局部作用域结束后Variable对象本身会销毁但是对应的寄存器资源不会回收。数据搬运数据搬运类操作长度不能等于0否则硬件行为不可预知。本地内存到远端内存搬运长度要小于256MB。涉及CcuBuffer的数据搬运操作长度要小于等于4096B。不支持读写其他设备的CcuBuffer。并发操作Loop内只能放置数据搬运指令和Wait指令其他均不支持。Loop的循环次数必须大于0。创建Loop和LoopGroup时如果使用立即数作为参数创建后的Loop和LoopGroup会消耗Variable资源用于保存配置参数。创建Loop和LoopGroup前需要提前计算好需要使用的资源并申请避免越界。LoopGroup可以将一组Group复制多份并发执行每个Loop使用的资源不能冲突因此LoopGroup除了需要指定复制次数还需要指定复制后Loop使用的寄存器ID增量偏移如下图所示以Loop S为例Loop S是开发者手写的LoopGroup对它复制N份那复制后Loop使用的CcuBuffer是在基础CcuBuffer之上做增量偏移。Loop S使用CcuBuffer xLoopGroup指定CcuBuffer偏移参数为offset那基于Loop S复制出来的第N个Loop使用的CcuBuffer xN*offset。在开发代码时只能显式感知CcuBuffer x那为了避免复制后的Loop使用的资源越界需要规划好资源使用并提前申请。指令部署CCU位于一个设备的IO Die上。一个设备可能包含多个IO Die不同IO Die包含不同的网络设备。实际组网中不同的网络设备可能与不同的其他设备互联。一个CCU不能跨Die使用另一个IO Die的网络设备进行通信。因此在开发运行于某个CCU上的程序时需要保证它使用的网络设备都在一个Die上CCU翻译器会根据它使用的网络设备推导出翻译后的指令序列应该部署到哪个CCU设备上。【免费下载链接】hcommHCOMMHuawei Communication是HCCL的通信基础库提供通信域以及通信资源的管理能力。项目地址: https://gitcode.com/cann/hcomm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考