昇腾社区首页
中文
注册

通信域创建

通信域创建根据用户场景的不同主要有以下三种方式:
  • 多机集合通信场景,如果有完整的描述集群信息的ranktable文件,可通过HcclCommInitClusterInfo接口创建通信域。
  • 多机集合通信场景,如果无完整的ranktable,可通过HcclGetRootInfo接口与HcclCommInitRootInfo/HcclCommInitRootInfoConfig接口配合使用创建通信域。
  • 单机集合通信场景,可通过HcclCommInitAll接口创建通信域。

基于ranktable创建通信域

多机集合通信、基于集群信息配置ranktable文件创建通信域的场景,需要每张卡使用一个单独的进程参考如下流程创建通信域:
  1. 构造ranktable文件(ranktable文件的配置可参见ranktable文件配置资源信息),如果已存在ranktable文件,也可以通过环境变量RANK_TABLE_FILE获取。
  2. 每张卡使用HcclCommInitClusterInfo接口创建通信域。
一个简单的代码示例片段如下:
    // 获取ranktable路径
    char* rankTableFile = getenv("RANK_TABLE_FILE");
    // 定义通信域句柄
    HcclComm hcclComm;
    // 初始化HCCL通信域
    HcclCommInitClusterInfo(rankTableFile, devId, &hcclComm);
   
    /*  集合通信操作   */

    // 销毁HCCL通信域
    HcclCommDestroy(hcclComm);

完整的代码示例可参见HcclCommInitClusterInfo初始化方式

基于root节点广播方式创建通信域

多机集合通信场景,若无完整的集群信息配置ranktable文件,HCCL提供了基于root节点广播的方式创建通信域,详细流程如下:
  1. 配置环境变量HCCL_IF_IP,指定root通信网卡的IP地址。
    指定的网卡需为Host网卡,仅支持配置一个IP地址,要求是IPv4或IPv6格式,配置示例如下:
    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等信息,进行HCCL初始化。

需要注意:每个卡使用一个单独的进程进行如下操作。

使用HcclCommInitRootInfo接口创建通信域的简单代码示例片段如下:

    // 在root节点获取其rank信息
    HcclRootInfo rootInfo;
    int32_t rootRank = 0;
    if(devId == rootRank) {
        HcclGetRootInfo(&rootInfo);
    }
    // 将root_info广播到通信域内的其他rank
    MPI_Bcast(&rootInfo, HCCL_ROOT_INFO_BYTES, MPI_CHAR, rootRank, MPI_COMM_WORLD);
    MPI_Barrier(MPI_COMM_WORLD);
    // 定义通信域句柄
    HcclComm hcclComm;
    // 初始化HCCL通信域
    HcclCommInitRootInfo(devCount, &rootInfo, devId, &hcclComm);
    
    /*  集合通信操作   */

    // 销毁HCCL通信域
    HcclCommDestroy(hcclComm);

通过HcclCommInitRootInfo接口进行通信域创建的完整代码示例可参见HcclCommInitRootInfo初始化方式

单机内批量创建通信域

单机通信场景中,开发者通过一个进程统一创建多张卡的通信域,其中一张卡对应一个线程,创建流程如下:
  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的时间,避免建链超时。

完整的代码示例可参见HcclCommInitAll初始化