本文给读者介绍了HCCL算法开发所涉及的概念和流程,并通过一个样例将前文介绍的内容串联起来。本文定位为HCCL算法开发的入门介绍,读者读完后,可结合HCCL开放代码仓中的算法样例,做深入研究。
1 什么是集合通信
集合通信定义了一系列标准信息交换接口,解决并行计算时不同进程之间的通信问题。集合通信的概念和作用可参考文章《HCCL——昇腾高性能集合通信库》。
举例来说,AllGather将group内所有节点的输入按照Rank Id重新排序,然后拼接起来,再将结果发送到所有节点的输出。
HCCL为集合通信算子提供了对应的API供开发者调用,例如AllGather算子的API如下:
HcclResult HcclAllGather(void *sendBuf, void *recvBuf, uint64_t sendCount, HcclDataType dataType, HcclComm comm, aclrtStream stream);
- sendBuf表示输入内存缓冲区指针
- recvBuf表示输出内存缓冲区指针
- sendCount表示输入的数据个数
- dataType表示处理的数据类型
- comm表示算子执行所在的通信域
- stream表示算子执行所在的主流
开发者可以在PyTorch等AI框架中调用HcclAllGather接口,使能昇腾AI处理器(下文简称NPU)执行AllGather通信。
2 集合通信算法
针对同一个通信算子,随着网络拓扑、通信数据量、硬件资源等变化,往往会采用不同的通信算法,从而最大化集群通信性能。以AllGather算子举例,HCCL实现了Mesh、Ring、Recursive Halving-Doubling(RHD)、NHR(Nonuniform Hierarchical Ring)、NB(Nonuniform Bruck)等多种算法用于Server内和Server间的集合通信,通信操作执行时,HCCL会根据输入条件从算法仓中自动选择性能最佳的算法。
3 概念介绍
通信域
集合通信发生在一组通信对象上(比如一个NPU就是一个通信对象)。通信域是集合通信算子执行的上下文,管理对应的通信对象和通信所需的资源。
Rank
通信域中的每个通信对象称为一个Rank。
Memory
集合通信执行所需要的各种Buffer资源。
- Input Buffer:集合通信算子输入数据缓冲区。
- Output Buffer:集合通信算子输出数据缓冲区,存放算法计算结果。
- CCL Buffer:一组地址固定的Buffer,可被远端访问。单算子模式下,通信对象通过CCL Buffer来实现跨Rank的数据交换。
- CCL buffer和通信域绑定,通信域初始化的时候创建两块CCL buffer,分别称为CCL_In和CCL_Out。CCL_In和CCL_Out默认大小是200M Byte,可以通过环境变量HCCL_BUFFSIZE进行修改。同一个通信域内执行的集合通信算子都复用相同的CCL Buffer。
- Scratch Buffer:除了CCL Buffer,有些算法计算过程中需要额外的存储空间,这部分额外的存储空间,称为Scratch Buffer。
流
流(Stream)是NPU上的一种硬件资源,承载了待执行的Task序列。Task可以是一个DMA操作、一个同步操作或者一个NPU算子等。同一个流上的Task序列按顺序执行,不同流上的Task序列可并发执行。
- 主流:由Pytorch等训练框架调用集合通信API传入的stream对象称为主流。
- 从流&#x