昇腾社区首页
中文
注册

通信域管理

通信域是集合通信算子执行的上下文,管理对应的通信对象(例如一个NPU就是一个通信对象)和通信所需的资源。通信域中的每个通信对象称为一个rank,每个rank都会分配一个介于0~n-1(n为NPU的数量)的唯一标识。

通信域创建根据用户场景的不同主要有以下几种方式:
  • 多机集合通信场景
    • 如果有完整的描述集群信息的ranktable文件,可通过HcclCommInitClusterInfo接口创建通信域,或者通过HcclCommInitClusterInfoConfig接口创建具有特定配置的通信域。
    • 如果无完整的ranktable,可通过HcclGetRootInfo接口与HcclCommInitRootInfo/HcclCommInitRootInfoConfig接口配合使用,基于root节点信息创建通信域。
  • 单机集合通信场景,可通过HcclCommInitAll接口在单机内批量创建通信域。
  • 基于已有的通信域,可通过HcclCreateSubCommConfig接口切分具有特定配置的子通信域。
  • 针对同一个rank,通信算子需要one by one保序调用,不支持并发下发。
  • 针对整个通信域,通信算子的调用在不同rank间要保证同一下发顺序。
  • 同一个通信域内不支持图模式通信和单算子通信混合执行。
  • 针对 Atlas A3 训练系列产品/Atlas A3 推理系列产品 ,通信域初始化时,如果组网中存在多个超节点,请将属于同一超节点内的AI Server信息配置在一起。假设有两个超节点,标识分别为“0”和“1”,请先配置“0”中的AI Server信息,再配置“1”中的AI Server信息,不支持“0”中的AI Server信息与“1”中的AI Server信息交叉配置。

基于ranktable创建通信域

多机集合通信、基于集群信息配置文件(ranktable文件)创建通信域的场景,每张卡需要使用一个单独的进程参考如下流程创建通信域:
  1. 构造ranktable文件(ranktable文件的配置可参见ranktable文件配置资源信息)。
  2. 每张卡分别调用HcclCommInitClusterInfo接口创建通信域,或者调用HcclCommInitClusterInfoConfig接口创建具有特定配置的通信域。
一个简单的代码示例片段如下:
 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初始化方式

基于root节点信息创建通信域

多机集合通信场景,若无完整的集群信息配置文件(ranktable文件),HCCL提供了基于root节点信息创建通信域的方式,主要有如下两种典型使用场景
  • 每个Device对应一个业务进程的场景,实现流程如下所示:
    1. 配置环境变量HCCL_IF_IP,指定root节点通信网卡的IP地址(可选)。
      需要配置为root节点Host网卡的IP地址,可以是IPv4或IPv6格式,仅支持配置一个IP地址,配置示例如下:
      1
      export HCCL_IF_IP=10.10.10.1
      
    2. 在root节点调用HcclGetRootInfo接口,生成root节点rank标识信息“rootInfo”,包括device ip、device id等信息。
    3. 将root节点的rank信息广播至通信域中的所有rank。
    4. 在通信域中所有节点调用HcclCommInitRootInfo或者HcclCommInitRootInfoConfig接口(创建具有特定配置的通信域),基于接收到的“rootInfo”,以及本rank的rank id等信息,进行通信域初始化。

    调用HcclCommInitRootInfo接口进行通信域初始化的完整代码示例可参见Device与业务进程一对一场景

    调用HcclCommInitRootInfoConfig接口进行通信域初始化的完整代码示例可参见Device与业务进程一对一场景

  • 每个AI Server对应一个业务进程,每个线程对应一个Device,通过多线程的方式创建多个卡平面通信域的场景,实现流程如下所示:
    1. 在主进程中循环执行“指定不同的Device + 调用HcclGetRootInfo接口”,获取多个“rootInfo”信息。
    2. 每个Device匹配一个线程,分别根据不同的“rootInfo”信息,并发调用HcclCommInitRootInfo或者HcclCommInitRootInfoConfig接口,进行通信域初始化。

    调用HcclCommInitRootInfo接口进行通信域初始化的完整代码示例可参见AI Server与业务进程一对一场景

    调用HcclCommInitRootInfoConfig接口进行通信域初始化的完整代码示例可参见AI Server与业务进程一对一场景

针对 Atlas A3 训练系列产品/Atlas A3 推理系列产品 Atlas A2 训练系列产品 ,若业务为单卡多进程场景,建议通过环境变量“HCCL_HOST_SOCKET_PORT_RANGE”与“HCCL_NPU_SOCKET_PORT_RANGE”分别配置HCCL在Host侧与NPU侧使用的通信端口,否则可能会端口冲突,配置示例如下所示。但需要注意,多进程会对资源开销、通信性能产生一定的影响,
export HCCL_HOST_SOCKET_PORT_RANGE="auto"
export HCCL_NPU_SOCKET_PORT_RANGE="auto"

单机内批量创建通信域

单机通信场景中,开发者可通过一个进程统一创建多张卡的通信域,其中一张卡对应一个线程,创建流程如下:
  1. 构造通信域中的Device列表,例如:{0, 1, 2, 3, 4, 5, 6, 7},其中列表中的Device ID是逻辑ID。
  2. 在进程中调用HcclCommInitAll接口创建通信域。
 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接口销毁指定的通信域。