bootstrap_utils.h 4.65 KB
Newer Older
lishen's avatar
lishen committed
1
2
3
#pragma once

#include <string.h>
4
5
#include <cstddef>
#include <vector>
lishen's avatar
lishen committed
6
#include "base.h"
7
8
9
#include "topo_utils.h"
#include "comm.h"
#include "rocm_smi_wrap.h"
lishen's avatar
lishen committed
10
11
12
13
14
15

namespace sccl {
namespace hardware {
namespace topology {
namespace bootstrap {

16
17
typedef union net::net_socket::scclSocketAddress scclSocketAddress_t;
typedef struct net::net_socket::scclSocket scclSocket_t;
18
typedef net::scclNet_t scclNet_t;
lishen's avatar
lishen committed
19

20
21
22
// 用于初始化时广播0号rank的地址信息
struct BootstrapHandle {
    uint64_t magic = 0;       // 随机码,用于socket通信
lishen's avatar
lishen committed
23
24
25
    scclSocketAddress_t addr; // 地址,用于网络通信
};

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#define SCCL_UNIQUE_ID_BYTES (40) // sizeof(BootstrapHandle)
typedef struct {
    char internal[SCCL_UNIQUE_ID_BYTES];
} scclUniqueId;

// 仅用于初始化的函数bootstrapCreateRoot,用于传递detach线程的参数
struct bootstrapRootArgs {
    uint64_t magic;
    scclSocket_t* listenSock = nullptr; // 根节点的监听
};

// 用于初始建立连接阶段,0号rank之外的进程向其传递的信息
struct BootstrapNodeBasic {
    int rank;
    int nRanks;               // 进程的总数量
    uint64_t hostHash;        // 用于区分host的CPU编号
    scclSocketAddress_t addr; // 各个进程的监听套接字地址,用于网络通信
};
44
45
46

// 定义每个rank所持有的所有拓扑节点
struct topoLocalNode {
47
48
49
50
51
52
    struct {
        scclSocket_t listen_sock; // 监听套接字
    } cpu;                        // CPU节点
    struct {
        int64_t busId; // PCI总线ID以int64_t格式表示
    } pci;             // pci节点
53
54
55
56
57
58
59
    struct {
        int dev;      // NVML设备编号
        char name[8]; // 设备名称
        char gcn[7];  // GCN架构名称
        int compCap;  // CUDA计算能力
    } gpu;            // GPU节点
    struct {
60
        int count; // 网卡数量
61
62
63
64
        net::scclNetProperties_t props;
    } net; // 网络节点
};

65
66
// 定义结构体 scclNodeInfo,用于存储每个rank的通信节点的信息
struct scclNodeInfo {
67
    struct topoLocalNode localNode;
68
69
    int rank      = -1; // 当前节点的全局排名
    int localRank = -1; // 当前节点在本地计算节点中的排名
70

71
72
    uint64_t hostHash = 0; // 主机哈希值
    uint64_t pidHash  = 0; // 进程 ID 哈希值
73
74
};

75
76
77
78
79
80
81
// 每个节点的信息
struct scclNodeInfoSet {
    int nUniqueInfos; // 通信节点的数量
    std::vector<struct scclNodeInfo> node_info_vec;

    // 构造函数声明
    scclNodeInfoSet(int nRanks);
lishen's avatar
lishen committed
82
83
};

84
85
86
87
// BootstrapComm 结构体定义,用于存储引导通信信息
struct BootstrapComm {
    void init(int rank, int nRanks, int localRank, int nLocalRanks);
    void destroy();
88

89
90
91
public:
    scclNet_t* scclNet;
    struct scclNodeInfoSet* node_info_set;
92
93

    cpu_set_t cpuAffinity; // CPU亲和性
94
95
96
97
98
99
100
101
    int rank        = -1;  // 当前节点的全局排名
    int nRanks      = 0;   // 总的节点数量
    int localRank   = -1;  // 当前节点在本地计算节点中的排名
    int nLocalRanks = 0;   // 本地计算节点中的节点总数
    int hipDev      = -1;  // CUDA 设备 ID
    int deviceCnt   = 0;   // 设备数量

    // proxy通信
lishen's avatar
lishen committed
102
    uint64_t magic;               // 魔术数,用于验证结构体
103
    volatile uint32_t* abortFlag; // 中止标志,非阻塞套接字设置
lishen's avatar
lishen committed
104

105
106
107
108
    // int splitShare;      // 是否使用共享内存进行分割
    // int* topParentRanks; // 顶级父节点的rank
    // /* 与代理相关的共享资源 */
    // struct scclProxyState* proxyState;
lishen's avatar
lishen committed
109
110
};

111
112
113
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 获取主机唯一标识的哈希值,该哈希值在裸机和容器实例中都是唯一的
uint64_t getHostHash(void);
lishen's avatar
lishen committed
114

115
116
117
118
119
120
121
122
123
124
125
126
127
// 获取当前进程的唯一哈希标识符
uint64_t getPidHash(void);

// 从/dev/urandom设备获取随机数据填充缓冲区
scclResult_t getRandomData(void* buffer, size_t bytes);

// 获取指定CUDA设备的PCI总线ID并转换为64位整数
scclResult_t getBusId(int hipDev, int64_t* busId);

// 获取当前HIP设备的计算能力版本号
int scclCudaCompCap(void);

// 打印唯一的拓扑信息
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
scclResult_t printNodeInfo(struct scclNodeInfo* info);

// 实现类似于std::span的功能,将字节数组转换为类型数组
template <typename T>
class ByteSpan {
public:
    ByteSpan(const char* data, std::size_t size) : data_(reinterpret_cast<const T*>(data)), size_(size / sizeof(T)) {}

    const T* data() const { return data_; }
    std::size_t size() const { return size_; }

    const T& operator[](std::size_t index) const { return data_[index]; }

private:
    const T* data_;
    std::size_t size_;
};
lishen's avatar
lishen committed
145
146
147
148
149

} // namespace bootstrap
} // namespace topology
} // namespace hardware
} // namespace sccl