NCCL基础模块 - ncclSocket模块

ncclSocket系NCCL网络通信的基础模块,bootstrap阶段以及多机网络数据通信时会使用该模块,因此需要分析ncclSocket模块代码,理解它的设计。

ncclSocket结构体

ncclSocketAddress结构体可以是sockaddr,sockaddr_in或sockaddr_in6,对应Unix Domain Socket地址,IPV4 Socket地址和IPV6 Socket地址。意味着ncclSocket希望设计成支持UDS,IPV4和IPV6的Socket为不同类型的Socket提供统一接口。
ncclSocketType可以是ncclSocketTypeBootstrap,ncclSocketTypeProxy,ncclSocketTypeNetSocket以及ncclSocketTypeNetIb,涵盖和Bootstrap控制面通信和以太网和IB的数据面通信。意味着ncclSocket硬件层可以支持普通网卡和IB网卡。

/* Common socket address storage structure for IPv4/IPv6 */
union ncclSocketAddress {
  struct sockaddr sa;
  struct sockaddr_in sin;
  struct sockaddr_in6 sin6;
};

enum ncclSocketType {
  ncclSocketTypeUnknown = 0,
  ncclSocketTypeBootstrap = 1,
  ncclSocketTypeProxy = 2,
  ncclSocketTypeNetSocket = 3,
  ncclSocketTypeNetIb = 4
};

struct ncclSocket {
  int fd;
  int acceptFd;
  int timedOutRetries;
  int refusedRetries;
  union ncclSocketAddress addr;
  volatile uint32_t* abortFlag;
  int asyncFlag;
  enum ncclSocketState state;
  int salen;
  uint64_t magic;
  enum ncclSocketType type;
};

ncclSocket接口

ncclSocket接口可分为3类,第一类是IP字符串解析,网络设备搜索等网络相关等工具类接口;第二类是负责Socket构建,监听,连接,销毁等负责Socket状态转换的接口;第三类是发送数据和接受数据接口;不同种类接口已用空行隔开,并用注释加以注解,参见以下代码片段。

// ncclSocketAddress to string
const char *ncclSocketToString(union ncclSocketAddress *addr, char *buf, const int numericHostForm = 1);
// string to ncclSocketAddress
ncclResult_t ncclSocketGetAddrFromString(union ncclSocketAddress* ua, const char* ip_port_pair);
// find network device located in same subnet of remoteAddr and initilize localAddrs
int ncclFindInterfaceMatchSubnet(char* ifNames, union ncclSocketAddress* localAddrs, union ncclSocketAddress* remoteAddr, int ifNameMaxSize, int maxIfs);
// find network device in a fix rule, e.g. IB first then local network etc.
int ncclFindInterfaces(char* ifNames, union ncclSocketAddress *ifAddrs, int ifNameMaxSize, int maxIfs);


// Initialize a socket
ncclResult_t ncclSocketInit(struct ncclSocket* sock, union ncclSocketAddress* addr = NULL, uint64_t magic = NCCL_SOCKET_MAGIC, enum ncclSocketType type = ncclSocketTypeUnknown, volatile uint32_t* abortFlag = NULL, int asyncFlag = 0);
// Create a listening socket. sock->addr can be pre-filled with IP & port info. sock->fd is set after a successful call
ncclResult_t ncclSocketListen(struct ncclSocket* sock);
// Extract ncclSocketAddress from sock
ncclResult_t ncclSocketGetAddr(struct ncclSocket* sock, union ncclSocketAddress* addr);
// Connect to sock->addr. sock->fd is set after a successful call.
ncclResult_t ncclSocketConnect(struct ncclSocket* sock);
// Return socket connection state.
ncclResult_t ncclSocketReady(struct ncclSocket* sock, int *running);
// Accept an incoming connection from listenSock->fd and keep the file descriptor in sock->fd, with the remote side IP/port in sock->addr.
ncclResult_t ncclSocketAccept(struct ncclSocket* sock, struct ncclSocket* ulistenSock);
ncclResult_t ncclSocketGetFd(struct ncclSocket* sock, int* fd);
ncclResult_t ncclSocketSetFd(int fd, struct ncclSocket* sock);
ncclResult_t ncclSocketClose(struct ncclSocket* sock);


#define NCCL_SOCKET_SEND 0
#define NCCL_SOCKET_RECV 1
ncclResult_t ncclSocketProgress(int op, struct ncclSocket* sock, void* ptr, int size, int* offset);
ncclResult_t ncclSocketWait(int op, struct ncclSocket* sock, void* ptr, int size, int* offset);
ncclResult_t ncclSocketSend(struct ncclSocket* sock, void* ptr, int size);
ncclResult_t ncclSocketRecv(struct ncclSocket* sock, void* ptr, int size);
ncclResult_t ncclSocketSendRecv(struct ncclSocket* sendSock, void* sendPtr, int sendSize, struct ncclSocket* recvSock, void* recvPtr, int recvSize);
ncclResult_t ncclSocketTryRecv(struct ncclSocket* sock, void* ptr, int size, int* closed, bool blocking);

ncclSocket状态转换

ncclSocket定义了10种状态,如ncclSocketState定义所示。

enum ncclSocketState {
  ncclSocketStateNone = 0,
  ncclSocketStateInitialized = 1,
  ncclSocketStateAccepting = 2,
  ncclSocketStateAccepted = 3,
  ncclSocketStateConnecting = 4,
  ncclSocketStateConnectPolling = 5,
  ncclSocketStateConnected = 6,
  ncclSocketStateReady = 7,
  ncclSocketStateClosed = 8,
  ncclSocketStateError = 9,
  ncclSocketStateNum = 10
};

以下是ncclSocket状态转换图,当ncclSocket处于ncclSocketStateReady状态时候即可执行新的任务。
ncclSocket State

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我可以告诉你关于nccl和PyTorch的一些信息。NCCL是NVIDIA通信收集库的缩写,它是用于在多个GPU之间进行高能通信的库。PyTorch是一个开源的机器学习框架,用于构建深度神经网络模型。PyTorch通过使用CUDA和NCCL来加速深度学习训练过程。 在安装PyTorch时,你可以使用官方提供的命令来安装所需的版本。具体的安装命令可以在PyTorch官方网站上找到。 如果你想检查你的系统是否支持CUDA和NCCL,你可以在Python中使用PyTorch提供的函数进行检查。通过导入torch模块并调用torch.cuda.is_available()函数,你可以判断CUDA是否可用。 在选择CUDA版本时,你需要考虑你的显卡驱动支持的版本。根据你提供的引用内容,当前最新版的PyTorch和PaddlePaddle与CUDA版本重叠分别为CUDA 10.2和11.6。然而,如果你的显卡驱动不支持CUDA 11.6,那么安装CUDA 11.6可能会导致问题。此外,对于3090ti显卡,PyTorch需要使用CUDA 11.x版本来提供支持,因此安装CUDA 10.2也不推荐。你可以根据你的显卡驱动支持的CUDA版本来选择合适的版本进行安装。 总结一下,NCCL是用于在多个GPU之间进行高性能通信的库,而PyTorch是一个使用CUDA和NCCL来加速深度学习训练的机器学习框架。安装PyTorch时,你可以使用官方提供的命令,并使用torch.cuda.is_available()函数来检查CUDA是否可用。选择合适的CUDA版本时,你需要考虑你的显卡驱动支持的版本。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [一文掌握Ubuntu20.04深度学习环境搭建(显卡驱动、CUDA、CUDNN、NCCL、Pytorch、PaddlePaddle)](https://blog.csdn.net/qianbin3200896/article/details/126063445)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值