• NCCL源码解析②:Bootstrap网络连接的建立


    5e07b34a878c2ea195fe113b7ebf94bc.png

    作者|KIDGINBROOK

    更新|潘丽晨

    上次介绍到rank0的机器生成了ncclUniqueId,并完成了机器的bootstrap网络和通信网络的初始化,这节接着看下所有节点间bootstrap的连接是如何建立的。

    rank0节点执行ncclGetUniqueId生成ncclUniqueId,通过mpi将Id广播到所有节点,然后所有节点都会执行ncclCommInitRank,这里其他节点也会进行初始化bootstrap网络和通信网络的操作,然后会执行到ncclCommInitRankSync。

     
     
    1. ncclResult_t ncclCommInitRankSync(ncclComm_t* newcomm, int nranks, ncclUniqueId commId, int myrank, int cudaDev) {
    2. ncclResult_t res;
    3. CUDACHECK(cudaSetDevice(cudaDev));
    4. NCCLCHECKGOTO(commAlloc(newcomm, nranks, myrank), res, cleanup);
    5. NCCLCHECKGOTO(initTransportsRank(*newcomm, &commId), res, cleanup);
    6. NCCLCHECKGOTO(devCommSetup(*newcomm), res, cleanup);
    7. INFO(NCCL_INIT,"comm %p rank %d nranks %d cudaDev %d busId %x - Init COMPLETE", *newcomm, myrank, nranks, (*newcomm)->cudaDev, (*newcomm)->busId);
    8. return ncclSuccess;
    9. cleanup:
    10. if ((*newcomm) && (*newcomm)->bootstrap) bootstrapAbort((*newcomm)->bootstrap);
    11. *newcomm = NULL;
    12. return res;
    13. }

    ncclComm_t是指向ncclComm的指针,ncclComm是一个大杂烩,包含了通信用到的所有上下文信息,里面的字段等用到的时候再介绍,然后通过commAlloc分配newcom,并且完成初始化,比如当前是哪个卡,对应的pcie busid是什么,然后执行initTransportsRank。

     
     
    1. static ncclResult_t initTransportsRank(struct ncclComm* comm, ncclUniqueId* commId) {
    2. // We use 3 AllGathers
    3. // 1. { peerInfo, comm }
    4. // 2. ConnectTransport[nranks], ConnectValue[nranks]
    5. // 3. { nThreads, nrings, compCap, prev[MAXCHANNELS], next[MAXCHANNELS] }
    6. int rank = comm->rank;
    7. int nranks = comm->nRanks;
    8. uint64_t commHash = getHash(commId->internal, NCCL_UNIQUE_ID_BYTES);
    9. TRACE(NCCL_INIT, "comm %p, commHash %lx, rank %d nranks %d - BEGIN", comm, commHash, rank, nranks);
    10. NCCLCHECK(bootstrapInit(commId, rank, nranks, &comm->bootstrap));
    11. // AllGather1 - begin
    12. struct {
    13. struct ncclPeerInfo peerInfo;
    14. struct ncclComm* comm;
    15. } *allGather1Data;
    16. NCCLCHECK(ncclCalloc(&allGather1Data, nranks));
    17. allGather1Data[rank].comm = comm;
    18. struct ncclPeerInfo* myInfo = &allGather1Data[rank].peerInfo;
    19. NCCLCHECK(fillInfo(comm, myInfo, commHash));
    20. NCCLCHECK(bootstrapAllGather(comm->bootstrap, allGather1Data, sizeof(*allGather1Data)));
    21. NCCLCHECK(ncclCalloc(&comm->peerInfo, nranks+1)); // Extra rank to represent CollNet root
    22. for (int i = 0; i < nranks; i++) {
    23. memcpy(comm->peerInfo+i, &allGather1Data[i].peerInfo, sizeof(struct ncclPeerInfo));
    24. if ((i != rank) && (comm->peerInfo[i].hostHash == myInfo->hostHash) && (comm->peerInfo[i].busId == myInfo->busId)) {
    25. WARN("Duplicate GPU d
  • 相关阅读:
    TensorFlow学习(4) 学习率调度 & 正则化
    leaflet教程041: Point 和 LatLng 坐标互相转换
    【Flink】
    JNI查漏补缺(3)JNI调用java层
    全连接神经网络结构图,神经网络示意图怎么画
    【MATLAB图像处理实用案例详解(16)】——利用概念神经网络实现手写体数字识别
    《实现领域驱动设计》—实体
    mac安装应用提示已损坏的解决方法
    SpringBoot基础(一)-- 使用idea(2022版)创建一个Springboot项目(联网开发)
    【Freeradius】使用Freeradius、LDAP和Google Authenticator实现双因素身份验证
  • 原文地址:https://blog.csdn.net/OneFlow_Official/article/details/130023628