通信域是集合通信算子执行的上下文,管理对应的通信对象(例如一个NPU就是一个通信对象)和通信所需的资源。通信域中的每个通信对象称为一个rank,每个rank都会分配一个介于0~n-1(n为NPU的数量)的唯一标识。
1 2 3 4 5 6 7 8 9 10 11 12 |
int devId = 0; // 配置ranktable文件路径 char* rankTableFile = "/home/ranktable.json"; // 定义通信域句柄 HcclComm hcclComm; // 初始化HCCL通信域 HcclCommInitClusterInfo(rankTableFile, devId, &hcclComm); /* 集合通信操作 */ // 销毁HCCL通信域 HcclCommDestroy(hcclComm); |
完整的代码示例可参见HcclCommInitClusterInfo初始化方式或HcclCommInitClusterInfoConfig初始化方式。
调用HcclCommInitRootInfo接口进行通信域初始化的完整代码示例可参见Device与业务进程一对一场景。
调用HcclCommInitRootInfoConfig接口进行通信域初始化的完整代码示例可参见Device与业务进程一对一场景。
调用HcclCommInitRootInfo接口进行通信域初始化的完整代码示例可参见AI Server与业务进程一对一场景。
调用HcclCommInitRootInfoConfig接口进行通信域初始化的完整代码示例可参见AI Server与业务进程一对一场景。
export HCCL_HOST_SOCKET_PORT_RANGE="auto" export HCCL_NPU_SOCKET_PORT_RANGE="auto"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
uint32_t ndev = 8; // 构造Device的逻辑ID列表 int32_t devices[8] = {0, 1, 2, 3, 4, 5, 6, 7}; // 定义通信域句柄 HcclComm comms[ndev]; // 初始化HCCL通信域 HcclCommInitAll(ndev, devices, comms); // 启动线程执行集合通信操作 std::vector<std::unique_ptr<std::thread> > threads(ndev); struct ThreadContext args[ndev]; for (uint32_t i = 0; i < ndev; i++) { args[i].device = i; args[i].comm = comms[i]; /* 集合通信操作 */ } // 销毁HCCL通信域 for (uint32_t i = 0; i < ndev; i++) { HcclCommDestroy(comms[i]); } |
需要注意,多线程调用集合通信操作API时(例如HcclAllReduce),需要确保不同线程中调用集合通信操作API的前后时间差不超过集合通信的建链超时等待时间(可通过环境变量HCCL_CONNECT_TIMEOUT设置,默认120s),避免建链超时。
完整的代码示例可参见HcclCommInitAll初始化方式。
HCCL提供了HcclCreateSubCommConfig接口,实现基于已有通信域切分具有特性配置子通信域的功能。该子通信域创建方式无需进行socket建链与rank信息交换,可应用于业务故障下的快速通信域创建。
使用HcclCreateSubCommConfig接口切分子通信域的代码示例可参见HcclCreateSubCommConfig方式创建子通信域。
该接口仅支持从全局通信域切分子通信域,不支持通信域的嵌套切分。
集合通信操作完成后,需要调用运行时管理接口释放通信所用的内存、Stream、Device资源,并调用HcclCommDestroy接口销毁指定的通信域。