nccl-1_initialization bootstrap

news/2025/12/6 23:41:31/文章来源:https://www.cnblogs.com/mumujun12345/p/19316867

nccl学习-1: 初始化communicator与bootstrap 网络

在nccl的例子中,当我们获取了设备的数量,为每一个设备分配了一个ncclComm_t后,需要根据已经固定的通信拓扑,对每一个算子进行配置。目前,针对communicator的初始化,我们具有四个函数:

  • ncclCommInitAll
  • ncclCommInitRank
  • ncclCommInitRankConfig
  • ncclCommInitRankScalable

接下来我们大致了解一下各个算子。

ncclCommInitAll

利用一个进程,通过阻塞的方式创建一个通信群,将会为传入的comm指针进行初始化,通过一个进程来实现多个设备的communicator的初始化。

我们进入ncclCommInitAll中。首先我们将初始化Nvtx(用于profiling)相关参数的payload,并且初始化cudaLibrary(加载动态库,设置相关的设备,获取驱动等工作)。在这里,初始化采用了 std::call_once 操作。这个操作保证了在一台设备上,多个线程/进程只会调用该函数一次。如果发生异常则将调用权转移给其他线程/进程,这样他们就可以继续调用直到成功或者失败退出。

C++: std::call_once在libc++中的实现
std::call_once 通过一个 once_flag 结构,提供三种状态: 0: 未初始化。 1: 进行中。 2: 调用成功返回。在其中一个线程正在执行时,原子操作flag并且获取锁来保证线程唯一执行。

通过exception_guard,利用RAII特性,在抛出异常析构时调用guard的析构函数,释放锁同时将flag进行更改,将其修改成为“未初始化”模式,保证其他线程/进程能重新获得锁进行执行。

通过信号量来减少CPU占用。一个模拟的实现: call_once

在获取设备,进行指针检查和节点设备数量后,如果传入了对应的devList(用于确定节点内设备的rank号),则判断是否合法。否则接下来开始bootstrap网络,获取通信域,也即将开始进入核心部分:bootstrap 网络。

BootStrap network

ncclGetUniqueId

这部分将会为我们创建一个 ncclUniqueId, 用于标识我们的一个通信域。

首先我们执行ncclInitEnv。这一部分主要用于载入对应的插件/网络结构的动态库。例如ext-net中我们可以插入 collNet 用于在网集合通信运算,提升跨节点的一些集合通信速度。ext-profiler用于性能检测,ext-tuner用于性能调优。同样是call_once.

接着我们执行ncclInit。这一部分将执行三个部份,同样是call_once。

  • 设置CPU栈的大小。对于nccl,他需要至少8M的安全栈空间。
  • 初始化GdrCopy。加载gdr的相关内核模块和驱动。
  • 初始化BootStrap网络。

我们来观察初始化bootStrap网络的过程。


  • bootstrapNetInit

  • 首先,读取环境变量中的设定NCCL_COMM_ID=<ipv4>:<port>,我们可以手动通过这个方式来设置通信子的相关信息。这样直接获取了信息后,将socket的相关地址转换成string并且在子网中进行匹配。这种使用的情况不多,因此我们不再赘述。

  • 当没有设定上述环境变量的时候,我们就需要自行寻找interfaces了,执行ncclFindInterfaces来寻找对应的接口信息。


  • ncclFindInterfaces

根据我们设定的socket来寻找,或者直接寻找所有的网卡。这里我们分别进行介绍。

  • 在设置了 NCCL_SOCKET_IFNAME后,首先将会根据设定的网卡名进行前缀匹配。=为完全匹配,^则代表排除该网口。在寻找到网口后,存储他们的ipv4/ipv6信息。
  • 否则,在没有设置的情况下,将会优先寻找ib网口->排除docker, lo, virbr寻找->寻找docker,lo,virbr网口。
  • findInterfaces函数将会把网卡信息逐个进行填写。
    执行完成后我们获得了多个网口的信息(网口名+ip地址),返回 bootstrapNetInit

  • bootstrapNetInit

在上述函数将网卡写好后,我们将网卡名转换成字符记录在log中,返回。于是初始化bootstrap网络完成。

接下来我们将真正从我们的bootstrap网络中获取UniqueID。进入bootStrapGetUniqueId.
首先我们已经在bootstrapNetIfAddr中初始化了一系列的网口信息。因此,我们将会用第一个网口作为生成我们的ID的网口。我们可以看到:

  • 首先我们利用随机数生成器,通过硬件从环境中获取噪声后生成。通过读取/dev/urandom获取一个uinteger,填写到state->magic中。
  • 随后将bootstrapNetIfAddr中的第一个网卡地址读取到handle -> addr中。
  • 开始执行 bootstrapCreateRoot

  • bootstrapCreateRoot

将第一个网卡作为监听网卡,并且创建BootStrapRoot进程,该进程该进程将会在background进行。我们可以看到执行了pthread_detach操作。于是主进程将直接返回继续其他工作。笔者的blog不能并发,因此我们会先进入到这其中。

进入bootstrapRoot中,我们准备好如下的相关数据:

  • bootstrap相关:参数(刚刚生成的magic,以及确定的监听socket信息)
  • bootstrap拓扑相关:nranks(总进程rank数量),iroot(其他进程的root),nroots(多少个root,多少个node进程),localID(iroot下进程的rank),n2send(将要传输给的进程的rank)和nrecv(将要接受数据的进程的rank),c(完成信息注册的其他进程的轮数)。
  • info(root获取的特定进程的通信信息,包括了他监听root的socket地址和他进行p2p通信的地址)。
  • ringConnectInfo(p2p之间进行通信的相关信息)。
  • ncclSocketAddress (各个进程用于与root进程通信的地址)。
  • 一个全零数据用于判断是否已经进行初始化。

接下来我们开始进行初始化过程。接下来是比较复杂的流程,需要更加耐心地理解。在初始化中,需要完成以下的目标:

  • 每个root节点需要了解整体的rank信息和自己的子节点的相关信息。
  • 告诉每个子节点ring逻辑拓扑关系,帮助他们建立p2p连接。

首先,我们初始化sock,建立与Root主进程中的listenSocket连接后(其实就是复制fd),开始等待其他进程发来的信息。这里我们发现,在创建sock的时候,async_flag设置成了阻塞模式,因此会在建立连接(过渡过程中等待完成)。这一部分在ncclSocketAccept中执行。

ncclSocketAccept中,(1)首先将复制listenSocket的相关内容,随后开始尝试进行accept,进入socketProgressState中。在阻塞模式下,我们将等待直到完成。(2)在ncclSocketStateAccepting状态下,socketTryAccept将首先执行,用于在OS层面建立TCP连接。在获得对应的套接字fd后,我们将返回,说明完成了TCP连接。状态转换成ncclSocketStateAccepted。
(3)接着,继续执行socketFinalizeAccept。在这一步我们将会判断当前的socket是否真正地和主进程建立了一个连接。通过读取fd的方式来判断TCP连接是否合法,我们需要检查:1. fd中的magic是否正确,也就是主进程和线程的magic是否相同(判断TCP连接是否正常)。2. 判断socket类型是否相同。判断当前的socket是否为我们需要的ncclSocketTypeBootstrap,而非其他的服务socket。(4)在判断完成后,我们将进入ncclSocketRecv,循环等待其他进程的连接。

这时,我们收到了来自其他进程的连接后,首次获得了获得了其他进程的info信息。这里的info信息包含了:1.进程的rank。2.进程对应的root(iroot)。3. 进程中存储的系统nranks信息(有多少进程)和nroots(有多少root节点),4. 用于监听root信息的socket信息,5.用于p2p交换信息的socket信息。

img

当第一个rank进入的时候,也就是 c==0,我们需要获取系统的整体信息。也就是nranks,nroots,并且和第一个iroot交换信息(当具有多个root的时候)。所有的root都需要了解自己的子节点信息和系统整体的信息,并且分配rankAddressesRoot用于存储自己管理的子节点信息,分配rankInfo来用于存储自己管理的子节点用于p2p的信息。

计算出对应的节点在其root节点下的rank号后,我们需要判断他是否已经完成过注册。这时前面全零数据就起到了作用。

接下来完善ring通信逻辑,需要判断当前新加入节点在ring逻辑拓扑中的前序节点和后序节点是否有没有加入过。

在前序节点已经加入的情况下:bootStrapRoot线程将直接通过rankAddressesRoot发送当前新加入节点的info给前序节点,供前序节点建立p2p通信。
在后序节点已经加入的情况下:bootStrapRoot线程将会直接通过info中记录的新加入节点监听root的socket,发送自己已经记录的后序节点的rankInfo给新加入的节点,从而帮助当前这两个节点构建p2p连接。
这样最后一个节点始终是最后的,没有收到任何信息的节点。因此将rank 0的信息发送给这个节点。

为了方便理解,我们构建了一个简单的图示。

img

img

在进行bootstrap的过程中,通过ncclCommInitRancFunc函数中的bootstrapInit来构建p2p ring网络和与bootStrapRoot线程通信。此处之后的信息后面我们将会介绍。

TBD...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/990661.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年国内TOP5会计培训机构推荐,引领专业提升之路

在当前的会计培训市场中,各类机构提供了丰富的选择,以满足不同学员的需求。比如,成都环宇知了科技有限公司专注于基础课程,适合初学者。而超有爱教育培训则为在职人员开设了实用性强的课程,结合真实案例帮助学员提…

2025年国内TOP5会计培训机构推荐,引领专业提升之路

在当前的会计培训市场中,各类机构提供了丰富的选择,以满足不同学员的需求。比如,成都环宇知了科技有限公司专注于基础课程,适合初学者。而超有爱教育培训则为在职人员开设了实用性强的课程,结合真实案例帮助学员提…

2025年评价高的草本床垫供应厂家TOP5推荐

在2025年,市场上的草本床垫供应厂家层出不穷,每一家公司都在努力提升产品质量与用户体验。从材料选择到设计理念,众多厂家在不断创新。其中,四川宅逸居家居有限公司凭借其独特的草本助眠技术广受好评;而芬驰家居则…

2025 最新智能运维服务商/ 厂家 TOP5 评测!科技赋能 + 全周期服务权威榜单发布,引领智慧工厂运维新生态

随着智能制造的深入发展,智能运维作为保障工厂高效、稳定、绿色运行的核心环节,其重要性日益凸显。本榜单基于技术创新力、行业适配性、服务覆盖度、实战效果四大维度,结合行业权威数据与客户反馈,对2025年智能运维…

人生第一篇博客:千里之行,始于足下

现在是2025年12月6日晚,大二的我像一个刚闯入森林的探险者,好奇的注册了这个博客网站,四处打量着各个大佬写的高级的东西(看不懂)据说写博客是很多学计算机的人的好习惯,用来记录和监督自己一天的学习或者思考,…

全网热议!2025年比较好的全屋定制公司推荐

全屋定制市场在2025年展现出强劲的发展势头,吸引了越来越多的消费者关注。众多厂家如东莞市洋臣家具有限公司、志想家具和家思家具等,通过独特的设计理念和优质的服务,不断赢得市场口碑。这些品牌不仅注重产品的质量…

扩散炉供应厂家TOP推荐:2025年值得关注的优质厂家

在本文中,我们将深入探讨扩散炉供应厂家的TOP推荐榜单,以帮助您更好地了解当前市场上值得关注的优质厂家。首先,我们将列出排名前列的制造商,如青岛晨立电子有限公司、福润德和金瑞源,这些企业在质量、技术和服务…

2025年专业HIFI耳机口碑排行榜推荐,不容错过!

在2025年,专业HIFI耳机的市场持续发展,各品牌争相推出高品质耳机,吸引音响爱好者的关注。我们的推荐榜单中包括了市面上评价好的耳机,这些耳机不仅在音质表现上出众,还兼具外观设计美感和佩戴舒适性。东莞斯唯嘉电…

全网热议!2025年靠谱的全屋定制品牌推荐,让生活更智能

在2025年,全屋定制市场竞争愈加激烈,消费者对于家居环境的需求也日益提高。本文将介绍靠谱的全屋定制品牌TOP10,涵盖高端的全屋定制十大品牌以及广东全屋定制TOP前十,为寻找理想家居方案的客户提供实用参考。这些品…

Ancel AD410 OBD2 Scanner - Multi-Language OBD2 Code Reader Error Eraser for European American Cars

Why the Ancel AD410 OBD2 Scanner is Your Next Essential Diagnostic Tool Ever stared at your check engine light, only to be met with cryptic error codes that leave you guessing what’s wrong? Or spent …

2025年如何选择值得信赖的家居照明公司?

选择值得信赖的家居照明公司至关重要,尤其在现代智慧家居的背景下。消费者可以从多个方面进行评估,例如品牌的市场表现和用户反馈。关注照明公司的产品质量与创新技术,了解其是否将简约设计与智能科技相结合,为客户…

2025年护眼吸顶灯销售厂家有哪些?

护眼吸顶灯在现代家居和办公环境中扮演着重要角色。随着市场对健康照明需求的增加,越来越多的消费者开始关注自然光护眼吸顶灯,这些产品的设计理念是减少光线对眼睛的伤害。同时,选择合适的厂家也显得尤为重要。不同…

豆包碰壁微信,你只看热闹吗?个人数据归属的经济范式、法理解析 与我们的未来

我们的数据被割据在许多孤岛中 每个孤岛都可以成为利维坦 几天前,字节跳动携手中兴通讯,推出了基于人工智能操作系统(AIOS)的智能手机工程样机。这款手机允许后台调用APP,通过组合填制表单、模拟触屏等动作,实现…

20251206 之所思 - 人生如梦

20251206 之所思今天两件事做的特别糟糕:1) 早上起来太太要我帮她在手机上弄医保绑定的事情,因为我自己安排了事情,所以很不情愿,加上我本人最不喜欢的就是在手机上操作一些和政府部门单位相关的业务(界面恶心,…

一些心事

一些心事无有的时候觉得自己很想回家,但是回了家又想逃离。因为不论我在家待多久,总有一个时刻,或许是第一天,或许是最后一眼,我会猛的一下意识到,自己其实不属于这里。 这大部分原因是因为我妈。 从这个学期开始…

洛谷 P11345 [KTSC 2023 R2] 基地简化 题解

校内模拟赛题,倒在了正解前最后一步 qwq。 解题思路 首先,发现题目要求的东西很不好做。于是转化一下,考虑计算每条边对答案贡献了几次。 这样问题就转化成了求有多少个区间的点分布在一条边两端的两个子树中。 发现…

Visual Studio Installer 2022正在进行准备

问题描述 在安装Visual Studio 2022时,一直停在Visual Studio Installer正在进行准备…… 尝试了修改网络DNS、系统hosts文件无效。 解决方案 打开禾斗学上网,就可以了。 可以查看到下载主机的域名: 作者:我也是个…

在keil 中使用__attribute__关键字实现静态加载

实现各个线程或者各个模块自动初始化加载,避免在main中手动调用各种init()函数,各个模块间可实现高度解藕点击查看代码 /* 宏定义如下 */#define SECTION_DEF(_level) __attribute__((used,__section__(…

在keil 中使用__attribute__关键字实现静态加载

实现各个线程或者各个模块自动初始化加载,避免在main中手动调用各种init()函数,各个模块间可实现高度解藕点击查看代码 /* 宏定义如下 */#define SECTION_DEF(_level) __attribute__((used,__section__(…

ANCEL AS100 OBD2 Scanner: Full EOBD/OBDII/CAN BMW Check Engine Light Diagnostic Tool

Struggling with Unexplained Check Engine Lights? You Need the Right Tool For European and American car owners—especially those with BMWs—a mysterious check engine light can derail plans, drain walle…