Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
lishen01
Sccl
Commits
379c4128
Commit
379c4128
authored
Jul 20, 2025
by
lishen
Browse files
完成各个rank中的节点全部信息的allgather
parent
ecf8df33
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
240 additions
and
131 deletions
+240
-131
src/hardware/net/net_socket/socket.h
src/hardware/net/net_socket/socket.h
+1
-0
src/hardware/net/net_utils.cpp
src/hardware/net/net_utils.cpp
+2
-2
src/hardware/net/net_utils.h
src/hardware/net/net_utils.h
+10
-10
src/hardware/topology/bootstrap/bootstrap.cpp
src/hardware/topology/bootstrap/bootstrap.cpp
+168
-80
src/hardware/topology/bootstrap/bootstrap.h
src/hardware/topology/bootstrap/bootstrap.h
+11
-13
src/hardware/topology/bootstrap/bootstrap_utils.cpp
src/hardware/topology/bootstrap/bootstrap_utils.cpp
+19
-15
src/hardware/topology/bootstrap/bootstrap_utils.h
src/hardware/topology/bootstrap/bootstrap_utils.h
+21
-11
src/utils/thread_pool.cpp
src/utils/thread_pool.cpp
+6
-0
src/utils/thread_pool.h
src/utils/thread_pool.h
+2
-0
No files found.
src/hardware/net/net_socket/socket.h
View file @
379c4128
...
@@ -230,6 +230,7 @@ public:
...
@@ -230,6 +230,7 @@ public:
/**
/**
* @brief 管理接受连接的套接字的类,继承自scclSocketManager。
* @brief 管理接受连接的套接字的类,继承自scclSocketManager。
*
*
* 服务器端接受客户端的连接请求,创建一个新的套接字用于通信
* 该类在构造时初始化套接字,并接受来自监听套接字的连接。
* 该类在构造时初始化套接字,并接受来自监听套接字的连接。
*/
*/
class
scclSocketAcceptManager
:
public
scclSocketManager
{
class
scclSocketAcceptManager
:
public
scclSocketManager
{
...
...
src/hardware/net/net_utils.cpp
View file @
379c4128
...
@@ -98,13 +98,13 @@ bool matchIfList(const char* string, int port, struct netIf* ifList, int listSiz
...
@@ -98,13 +98,13 @@ bool matchIfList(const char* string, int port, struct netIf* ifList, int listSiz
}
}
scclResult_t
printNetProps
(
const
scclNetProperties_t
*
props
,
int
rank
,
int
localRank
)
{
scclResult_t
printNetProps
(
const
scclNetProperties_t
*
props
,
int
rank
,
int
localRank
)
{
printf
(
"rank=%d, localRank=%d, device name=%s, pciPath=%s, guid=%lu, ptrSupport=%
d
, speed=%d, port=%d, latency=%f, maxComms=%d, maxRecvs=%d
\n
"
,
printf
(
"rank=%d, localRank=%d, device name=%s, pciPath=%s, guid=%lu, ptrSupport=%
u
, speed=%d, port=%d, latency=%f, maxComms=%d, maxRecvs=%d
\n
"
,
rank
,
rank
,
localRank
,
localRank
,
props
->
name
,
props
->
name
,
props
->
pciPath
,
props
->
pciPath
,
props
->
guid
,
props
->
guid
,
props
->
ptrSupport
,
static_cast
<
unsigned
int
>
(
props
->
ptrSupport
)
,
props
->
speed
,
props
->
speed
,
props
->
port
,
props
->
port
,
props
->
latency
,
props
->
latency
,
...
...
src/hardware/net/net_utils.h
View file @
379c4128
...
@@ -7,7 +7,7 @@ namespace sccl {
...
@@ -7,7 +7,7 @@ namespace sccl {
namespace
hardware
{
namespace
hardware
{
namespace
net
{
namespace
net
{
typedef
enum
{
typedef
enum
:
uint8_t
{
SCCL_PTR_HOST
=
0x1
,
SCCL_PTR_HOST
=
0x1
,
SCCL_PTR_CUDA
=
0x2
,
SCCL_PTR_CUDA
=
0x2
,
SCCL_PTR_DMABUF
=
0x4
SCCL_PTR_DMABUF
=
0x4
...
@@ -19,15 +19,15 @@ constexpr int SCCL_NET_HANDLE_MAXSIZE = 128;
...
@@ -19,15 +19,15 @@ constexpr int SCCL_NET_HANDLE_MAXSIZE = 128;
////////////////////////////////// 用于定义网络设备 //////////////////////////////////
////////////////////////////////// 用于定义网络设备 //////////////////////////////////
typedef
struct
{
typedef
struct
{
char
*
name
;
// 主要用于日志记录。
char
*
name
;
// 主要用于日志记录。
char
*
pciPath
;
// PCI设备在/sys中的路径。
char
*
pciPath
;
// PCI设备在/sys中的路径。
uint64_t
guid
;
// NIC芯片的唯一标识符。对于具有多个PCI功能(物理或虚拟)的卡非常重要。
uint64_t
guid
;
// NIC芯片的唯一标识符。对于具有多个PCI功能(物理或虚拟)的卡非常重要。
int
ptrSupport
;
// [SCCL_PTR_HOST|SCCL_PTR_CUDA|SCCL_PTR_DMABUF]
u
int
8_t
ptrSupport
;
// [SCCL_PTR_HOST|SCCL_PTR_CUDA|SCCL_PTR_DMABUF]
int
speed
;
// 端口速度,单位为Mbps。
int
speed
;
// 端口速度,单位为Mbps。
int
port
;
// 端口号。
int
port
;
// 端口号。
float
latency
;
// 网络延迟
float
latency
;
// 网络延迟
int
maxComms
;
// 我们可以创建的最大通信数量
int
maxComms
;
// 我们可以创建的最大通信数量
int
maxRecvs
;
// 最大分组接收数量。
int
maxRecvs
;
// 最大分组接收数量。
}
scclNetProperties_t
;
}
scclNetProperties_t
;
/**
/**
...
...
src/hardware/topology/bootstrap/bootstrap.cpp
View file @
379c4128
...
@@ -15,6 +15,20 @@
...
@@ -15,6 +15,20 @@
namespace
sccl
{
namespace
sccl
{
namespace
hardware
{
namespace
hardware
{
namespace
topology
{
namespace
topology
{
/**
* @brief 执行根节点的数据收集和广播操作
*
* 该函数负责以下操作:
* 1. 设置本地监听服务
* 2. 向根节点发送本节点的基本数据
* 3. 从根节点接收本地rank数量信息
* 4. 当本地rank为0时,从根节点接收所有rank的IP数据
* 5. 将收集到的所有rank数据广播给节点内其他rank
*
* @param send_data_basic 发送给根节点的节点基础数据
* @param recv_data_basic 接收广播数据的缓冲区向量
* @return scclResult_t 返回操作结果,成功返回scclSuccess
*/
namespace
bootstrap
{
namespace
bootstrap
{
////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////
...
@@ -36,7 +50,7 @@ static scclResult_t basicInit() {
...
@@ -36,7 +50,7 @@ static scclResult_t basicInit() {
SCCLCHECK
(
bootstrapNet
::
bootstrapNetInit
());
SCCLCHECK
(
bootstrapNet
::
bootstrapNetInit
());
// initGdrCopy(); // 初始化GDR复制
// initGdrCopy(); // 初始化GDR复制
// SCCLCHECK(scclNetPluginInit());
// SCCLCHECK(scclNetPluginInit());
#if 0
char strValue[1024];
char strValue[1024];
// 检查NUMA自动平衡是否启用
// 检查NUMA自动平衡是否启用
SCCLCHECK(scclTopoGetStrFromSys("/proc/sys/kernel", "numa_balancing", strValue));
SCCLCHECK(scclTopoGetStrFromSys("/proc/sys/kernel", "numa_balancing", strValue));
...
@@ -77,6 +91,7 @@ static scclResult_t basicInit() {
...
@@ -77,6 +91,7 @@ static scclResult_t basicInit() {
if(err != hipSuccess)
if(err != hipSuccess)
hsaFineGrainFlag = false;
hsaFineGrainFlag = false;
}
}
#endif
// 设置初始化标志
// 设置初始化标志
asm_ops
::
st_release_sys_global
(
&
initialized
,
true
);
asm_ops
::
st_release_sys_global
(
&
initialized
,
true
);
...
@@ -143,16 +158,16 @@ static void* bootstrapRoot(void* rargs) {
...
@@ -143,16 +158,16 @@ static void* bootstrapRoot(void* rargs) {
scclResult_t
res
=
scclSuccess
;
// 函数结果
scclResult_t
res
=
scclSuccess
;
// 函数结果
class
ThreadPool
*
pthread_pool
=
nullptr
;
// 用于根节点分发消息的线程池
class
ThreadPool
*
pthread_pool
=
nullptr
;
// 用于根节点分发消息的线程池
int
nRanks
=
0
;
// nRanks: 进程总数;
int
nRanks
=
0
;
// nRanks: 进程总数;
int
nLocalRanks
=
1
;
int
nLocalRanks
=
1
;
int
c
=
0
;
// c: 已连接的进程计数
int
c
=
0
;
// c: 已连接的进程计数
uint64_t
rootHostHash
=
0
;
uint64_t
rootHostHash
=
0
;
struct
BootstrapNodeBasic
node_basic
;
// 用于存储扩展信息的结构体
struct
BootstrapNodeBasic
node_basic
=
{};
// 用于存储扩展信息的结构体
struct
BootstrapNodeBasic
*
all_rank_node_basic
=
nullptr
;
// 所有进程的地址
struct
BootstrapNodeBasic
*
all_rank_node_basic
=
nullptr
;
// 所有进程的地址
// 定义一个函数或者一个函数对象,用于执行实际的发送数据操作
// 定义一个函数或者一个函数对象,用于执行实际的发送数据操作
。在后面执行
auto
send_task
=
[](
BootstrapNodeBasic
&
node_basic
,
uint64_t
magic
,
int
rank
,
void
*
data
,
size_t
size
)
{
auto
send_task
=
[](
BootstrapNodeBasic
&
node_basic
,
uint64_t
magic
,
int
rank
,
void
*
data
,
size_t
size
)
{
net
::
net_socket
::
scclSocketClientManager
client_manager
(
&
node_basic
.
addr
,
magic
,
net
::
net_socket
::
scclSocketTypeBootstrap
);
net
::
net_socket
::
scclSocketClientManager
client_manager
(
&
node_basic
.
sock
.
addr
,
magic
,
net
::
net_socket
::
scclSocketTypeBootstrap
);
bootstrapNet
::
bootstrapNetSend
(
client_manager
.
getSocket
(),
data
,
size
);
bootstrapNet
::
bootstrapNetSend
(
client_manager
.
getSocket
(),
data
,
size
);
};
};
...
@@ -175,9 +190,9 @@ static void* bootstrapRoot(void* rargs) {
...
@@ -175,9 +190,9 @@ static void* bootstrapRoot(void* rargs) {
WARN
(
"Bootstrap Root : mismatch in rank count from procs %d : %d"
,
nRanks
,
node_basic
.
nRanks
);
// 警告
WARN
(
"Bootstrap Root : mismatch in rank count from procs %d : %d"
,
nRanks
,
node_basic
.
nRanks
);
// 警告
goto
out
;
// 跳转到out标签
goto
out
;
// 跳转到out标签
}
}
if
(
memcmp
(
zero
,
&
all_rank_node_basic
[
node_basic
.
rank
].
addr
,
sizeof
(
scclSocketAddress_t
))
!=
0
)
{
// 如果rank已经签到
if
(
memcmp
(
zero
,
&
all_rank_node_basic
[
node_basic
.
rank
].
sock
.
addr
,
sizeof
(
scclSocketAddress_t
))
!=
0
)
{
// 如果rank已经签到
WARN
(
"Bootstrap Root : rank %d of %d ranks has already checked in"
,
node_basic
.
rank
,
nRanks
);
// 警告
WARN
(
"Bootstrap Root : rank %d of %d ranks has already checked in"
,
node_basic
.
rank
,
nRanks
);
// 警告
goto
out
;
// 跳转到out标签
goto
out
;
// 跳转到out标签
}
}
// 保存该rank的连接句柄
// 保存该rank的连接句柄
...
@@ -188,16 +203,6 @@ static void* bootstrapRoot(void* rargs) {
...
@@ -188,16 +203,6 @@ static void* bootstrapRoot(void* rargs) {
INFO
(
SCCL_LOG_BOOTSTRAP
,
"COLLECTED ALL %d HANDLES"
,
nRanks
);
// 日志:收集到所有句柄
INFO
(
SCCL_LOG_BOOTSTRAP
,
"COLLECTED ALL %d HANDLES"
,
nRanks
);
// 日志:收集到所有句柄
// --------------------- 2.计算nLocalRanks,并广播给其他所有rank --------------------- //
// --------------------- 2.计算nLocalRanks,并广播给其他所有rank --------------------- //
#if 1
for
(
int
r
=
0
;
r
<
nRanks
;
++
r
)
{
auto
temp_node_basic
=
all_rank_node_basic
[
r
];
char
line
[
100
];
sprintf
(
line
,
"bootstrapRoot r=%d, rank=%d/%d, hostHash=%lu,
\n
"
,
r
,
temp_node_basic
.
rank
,
temp_node_basic
.
nRanks
,
temp_node_basic
.
hostHash
);
scclSocketAddress_t
temp_addr
=
temp_node_basic
.
addr
;
hardware
::
net
::
printSocketAddr
(
&
temp_addr
,
line
);
}
#endif
// 首先计算nLocalRanks大小,即具有相同hostHash的节点数量
// 首先计算nLocalRanks大小,即具有相同hostHash的节点数量
rootHostHash
=
all_rank_node_basic
[
0
].
hostHash
;
rootHostHash
=
all_rank_node_basic
[
0
].
hostHash
;
for
(
int
i
=
1
;
i
<
nRanks
;
++
i
)
{
for
(
int
i
=
1
;
i
<
nRanks
;
++
i
)
{
...
@@ -207,7 +212,7 @@ static void* bootstrapRoot(void* rargs) {
...
@@ -207,7 +212,7 @@ static void* bootstrapRoot(void* rargs) {
break
;
// 一旦发现不同的hostHash,停止计数
break
;
// 一旦发现不同的hostHash,停止计数
}
}
}
}
// 给每个节点
的
localRank
=0的进程发送信息,并由其进行广播,从而加快速度
// 给每个节点
发送
localRank
的值
for
(
int
r
=
0
;
r
<
nRanks
;
++
r
)
{
for
(
int
r
=
0
;
r
<
nRanks
;
++
r
)
{
auto
dst_node_basic
=
all_rank_node_basic
[
r
];
auto
dst_node_basic
=
all_rank_node_basic
[
r
];
// 使用std::bind将参数绑定到send_task函数
// 使用std::bind将参数绑定到send_task函数
...
@@ -225,7 +230,7 @@ static void* bootstrapRoot(void* rargs) {
...
@@ -225,7 +230,7 @@ static void* bootstrapRoot(void* rargs) {
for
(
int
r
=
0
;
r
<
nRanks
/
nLocalRanks
;
++
r
)
{
for
(
int
r
=
0
;
r
<
nRanks
/
nLocalRanks
;
++
r
)
{
int
dst_rank
=
r
*
nLocalRanks
;
// 计算目标rank
int
dst_rank
=
r
*
nLocalRanks
;
// 计算目标rank
auto
dst_node_basic
=
all_rank_node_basic
[
dst_rank
];
auto
dst_node_basic
=
all_rank_node_basic
[
dst_rank
];
net
::
net_socket
::
scclSocketClientManager
client_manager
(
&
dst_node_basic
.
addr
,
magic
,
net
::
net_socket
::
scclSocketTypeBootstrap
);
net
::
net_socket
::
scclSocketClientManager
client_manager
(
&
dst_node_basic
.
sock
.
addr
,
magic
,
net
::
net_socket
::
scclSocketTypeBootstrap
);
bootstrapNet
::
bootstrapNetSend
(
client_manager
.
getSocket
(),
all_rank_node_basic
,
sizeof
(
struct
BootstrapNodeBasic
)
*
nRanks
);
bootstrapNet
::
bootstrapNetSend
(
client_manager
.
getSocket
(),
all_rank_node_basic
,
sizeof
(
struct
BootstrapNodeBasic
)
*
nRanks
);
printf
(
"root send nLocalRanks value to rank=%d
\n
"
,
r
);
printf
(
"root send nLocalRanks value to rank=%d
\n
"
,
r
);
}
}
...
@@ -251,7 +256,7 @@ out:
...
@@ -251,7 +256,7 @@ out:
free
(
rargs
);
// 释放rargs内存
free
(
rargs
);
// 释放rargs内存
INFO
(
SCCL_LOG_BOOTSTRAP
,
"DONE"
);
// 日志:完成
INFO
(
SCCL_LOG_BOOTSTRAP
,
"DONE"
);
// 日志:完成
return
NULL
;
// 返回NULL
return
NULL
;
}
}
/**
/**
...
@@ -291,16 +296,11 @@ scclResult_t bootstrapCreateRoot(struct BootstrapHandle* handle) {
...
@@ -291,16 +296,11 @@ scclResult_t bootstrapCreateRoot(struct BootstrapHandle* handle) {
// 构造函数
// 构造函数
Bootstrap
::
Bootstrap
(
const
struct
BootstrapHandle
*
handle
,
int
rank
,
int
nRanks
)
Bootstrap
::
Bootstrap
(
const
struct
BootstrapHandle
*
handle
,
int
rank
,
int
nRanks
)
:
root_handle
(
handle
),
rank
(
rank
),
nRanks
(
nRanks
),
localRank
(
-
1
),
nLocalRanks
(
0
),
socketInitDone
(
false
)
{
:
root_handle
(
handle
),
rank
(
rank
),
nRanks
(
nRanks
),
localRank
(
-
1
),
nLocalRanks
(
0
),
socketInitDone
(
false
)
{
printf
(
"construct init Bootstrap
\n
"
);
printf
(
"Bootstrap 构造函数
\n
"
);
// 初始化线程池
pthread_pool
=
new
ThreadPool
(
nRanks
);
}
}
Bootstrap
::~
Bootstrap
()
{
Bootstrap
::~
Bootstrap
()
{
if
(
pthread_pool
)
{
printf
(
"Bootstrap 析构函数
\n
"
);
delete
pthread_pool
;
}
if
(
ipcsocket
)
{
if
(
ipcsocket
)
{
delete
ipcsocket
;
delete
ipcsocket
;
}
}
...
@@ -316,16 +316,14 @@ scclResult_t Bootstrap::init(struct BootstrapComm* bootstrap_comm) {
...
@@ -316,16 +316,14 @@ scclResult_t Bootstrap::init(struct BootstrapComm* bootstrap_comm) {
// -------------------------- 1.获取自身基础信息 ----------------------------------- //
// -------------------------- 1.获取自身基础信息 ----------------------------------- //
SCCLCHECK
(
basicInit
());
SCCLCHECK
(
basicInit
());
uint64_t
hostHash
=
getHostHash
();
scclSocketAddress_t
localSocketAddr
=
bootstrapNet
::
getLocalSocketAddr
();
// 设置基础信息
// 设置基础信息
struct
BootstrapNodeBasic
node_basic
{
rank
,
nRanks
,
hostHash
,
localSocketAddr
};
struct
BootstrapNodeBasic
node_basic
=
{
};
// -------------------------- 2.设置0号rank搜集的CPU信息和localRank信息 ----------------------------------- //
// -------------------------- 2.设置0号rank搜集的CPU信息和localRank信息 ----------------------------------- //
// 创建根节点的数据收集
// 创建根节点的数据收集
std
::
vector
<
struct
BootstrapNodeBasic
>
all_node_basic
;
std
::
vector
<
struct
BootstrapNodeBasic
>
all_node_basic
;
all_node_basic
.
reserve
(
nRanks
);
all_node_basic
.
reserve
(
nRanks
);
SCCLCHECK
(
bootstrapRootGatherAndBroadcast
(
&
node_basic
,
all_node_basic
.
data
()
));
SCCLCHECK
(
bootstrapRootGatherAndBroadcast
(
&
node_basic
,
all_node_basic
));
// -------------------------- 3.设置本地localRank的BootstrapComm信息 ----------------------------------- //
// -------------------------- 3.设置本地localRank的BootstrapComm信息 ----------------------------------- //
// 初始化BootstrapComm类
// 初始化BootstrapComm类
...
@@ -344,8 +342,9 @@ scclResult_t Bootstrap::init(struct BootstrapComm* bootstrap_comm) {
...
@@ -344,8 +342,9 @@ scclResult_t Bootstrap::init(struct BootstrapComm* bootstrap_comm) {
LTCHECK
(
devices_num
,
0
);
// 检查设备数量是否 devices_num>0
LTCHECK
(
devices_num
,
0
);
// 检查设备数量是否 devices_num>0
LTCHECK
(
devices_num
,
nLocalRanks
);
// 检查设备数量是否 devices_num>nLocalRanks
LTCHECK
(
devices_num
,
nLocalRanks
);
// 检查设备数量是否 devices_num>nLocalRanks
bootstrap_comm
->
deviceCnt
=
static_cast
<
int
>
(
devices_num
);
// 将设备数量转换为int并赋值给的deviceCnt
bootstrap_comm
->
deviceCnt
=
static_cast
<
int
>
(
devices_num
);
// 将设备数量转换为int并赋值给的deviceCnt
#if 0
printf("devices_num=%d\n", bootstrap_comm->deviceCnt);
printf("devices_num=%d\n", bootstrap_comm->deviceCnt);
#endif
LECHECK
(
devices_num
,
bootstrap_comm
->
hipDev
);
// 检查hipDev是否小于deviceCnt
LECHECK
(
devices_num
,
bootstrap_comm
->
hipDev
);
// 检查hipDev是否小于deviceCnt
HIPCHECK
(
hipSetDevice
(
bootstrap_comm
->
hipDev
));
// 设置当前设备为hipDev
HIPCHECK
(
hipSetDevice
(
bootstrap_comm
->
hipDev
));
// 设置当前设备为hipDev
...
@@ -353,7 +352,9 @@ scclResult_t Bootstrap::init(struct BootstrapComm* bootstrap_comm) {
...
@@ -353,7 +352,9 @@ scclResult_t Bootstrap::init(struct BootstrapComm* bootstrap_comm) {
// 获取环境变量SCCL_NET_NAME的值,如果不存在则默认使用"IB"
// 获取环境变量SCCL_NET_NAME的值,如果不存在则默认使用"IB"
const
char
*
envNetName
=
getenv
(
"SCCL_NET_NAME"
);
const
char
*
envNetName
=
getenv
(
"SCCL_NET_NAME"
);
char
*
netName
=
(
envNetName
!=
NULL
)
?
strdup
(
envNetName
)
:
strdup
(
"IB"
);
char
*
netName
=
(
envNetName
!=
NULL
)
?
strdup
(
envNetName
)
:
strdup
(
"IB"
);
#if 0
printf("netName=%s\n", netName);
printf("netName=%s\n", netName);
#endif
// 初始化网络和引导网络
// 初始化网络和引导网络
SCCLCHECK
(
net
::
scclNetInit
(
netName
,
bootstrap_comm
->
scclNet
));
SCCLCHECK
(
net
::
scclNetInit
(
netName
,
bootstrap_comm
->
scclNet
));
// 释放分配的网络名称字符串
// 释放分配的网络名称字符串
...
@@ -361,14 +362,33 @@ scclResult_t Bootstrap::init(struct BootstrapComm* bootstrap_comm) {
...
@@ -361,14 +362,33 @@ scclResult_t Bootstrap::init(struct BootstrapComm* bootstrap_comm) {
//////// 初始化唯一信息结构体 ////////
//////// 初始化唯一信息结构体 ////////
struct
scclNodeInfo
local_node_info
;
struct
scclNodeInfo
local_node_info
;
local_node_info
.
hostHash
=
hostHash
;
// 补充定义
local_node_info
.
hostHash
=
node_basic
.
hostHash
;
SCCLCHECK
(
bootstrapCommInitNodeInfo
(
bootstrap_comm
->
scclNet
,
&
local_node_info
));
SCCLCHECK
(
bootstrapCommInitNodeInfo
(
bootstrap_comm
->
scclNet
,
&
local_node_info
));
// 设置CPU信息
printNodeInfo
(
&
local_node_info
);
memcpy
(
&
(
local_node_info
.
localNode
.
cpu
.
listen_sock
),
&
(
node_basic
.
sock
),
sizeof
(
scclSocket_t
));
#if 0
{
char line[20];
sprintf(line, "11111 print rank=%d", rank);
std::string prefix(line); // 创建prefix字符串
printNodeInfo(prefix, &local_node_info); // 正确的调用方式
}
#endif
// -------------------------- 4.BootstrapComm信息的allgather ----------------------------------- //
// -------------------------- 4.BootstrapComm信息的allgather ----------------------------------- //
bootstrapCommAllGather
(
all_node_basic
,
&
local_node_info
,
bootstrap_comm
->
node_info_set
);
// bootstrapAllGather(bootstrap_comm->node_info);
if
(
1
)
{
char
line
[
20
];
sprintf
(
line
,
"print rank=%d"
,
rank
);
std
::
string
prefix
(
line
);
// 创建prefix字符串
for
(
int
r
=
0
;
r
<
nRanks
;
r
++
)
{
struct
scclNodeInfo
node_basic
=
bootstrap_comm
->
node_info_set
->
node_info_vec
[
r
];
printNodeInfo
(
prefix
,
&
node_basic
);
// 正确的调用方式
}
}
// 设置初始化标志
// 设置初始化标志
asm_ops
::
st_release_sys_global
(
&
socketInitDone
,
true
);
asm_ops
::
st_release_sys_global
(
&
socketInitDone
,
true
);
...
@@ -393,39 +413,52 @@ scclResult_t Bootstrap::init(struct BootstrapComm* bootstrap_comm) {
...
@@ -393,39 +413,52 @@ scclResult_t Bootstrap::init(struct BootstrapComm* bootstrap_comm) {
* @param recv_data 接收广播数据的缓冲区指针
* @param recv_data 接收广播数据的缓冲区指针
* @return scclResult_t 返回操作结果,成功返回scclSuccess
* @return scclResult_t 返回操作结果,成功返回scclSuccess
*/
*/
scclResult_t
Bootstrap
::
bootstrapRootGatherAndBroadcast
(
void
*
send_data
,
void
*
recv_data
)
{
scclResult_t
Bootstrap
::
bootstrapRootGatherAndBroadcast
(
struct
BootstrapNodeBasic
*
send_data_basic
,
std
::
vector
<
struct
BootstrapNodeBasic
>&
recv_data_basic
)
{
// 数据类型转换
// 总的需要广播的数据
auto
send_data_basic
=
reinterpret_cast
<
struct
BootstrapNodeBasic
*>
(
send_data
);
int
recv_data_basic_size
=
nRanks
*
sizeof
(
struct
BootstrapNodeBasic
);
auto
recv_data_basic
=
reinterpret_cast
<
struct
BootstrapNodeBasic
*>
(
recv_data
);
scclSocketAddress_t
root_addr
=
root_handle
->
addr
;
int
recv_data_basic_size
=
nRanks
*
sizeof
(
struct
BootstrapNodeBasic
);
scclSocketAddress_t
localSocketAddr
=
bootstrapNet
::
getLocalSocketAddr
();
scclSocketAddress_t
root_addr
=
root_handle
->
addr
;
// ------------- 1.各个rank在发送给根节点数据之前,首先设置监听listen ------------- //
// ------------- 1.各个rank在发送给根节点数据之前,首先设置监听listen ------------- //
net
::
net_socket
::
scclSocketServerManager
local_server_manager
(
&
send_data_basic
->
addr
,
root_handle
->
magic
,
net
::
net_socket
::
scclSocketTypeBootstrap
);
net
::
net_socket
::
scclSocketServerManager
local_server_manager
(
&
localSocketAddr
,
root_handle
->
magic
,
net
::
net_socket
::
scclSocketTypeBootstrap
);
// 保存监听的sock信息到本类,用于后续proxy使用
my_listen_sock
=
local_server_manager
.
releaseSocket
();
// ------------- 2.各个节点向根节点发送数据 ------------- //
// 设置基础数据
net
::
net_socket
::
scclSocketClientManager
client_manager
(
&
root_addr
,
root_handle
->
magic
,
net
::
net_socket
::
scclSocketTypeBootstrap
);
send_data_basic
->
rank
=
rank
;
SCCLCHECK
(
bootstrapNet
::
bootstrapNetSend
(
client_manager
.
getSocket
(),
send_data_basic
,
sizeof
(
struct
BootstrapNodeBasic
)));
send_data_basic
->
nRanks
=
nRanks
;
send_data_basic
->
hostHash
=
getHostHash
();
scclSocket_t
*
local_server_sock
=
local_server_manager
.
releaseSocket
();
send_data_basic
->
sock
=
*
local_server_sock
;
// ------------- 2.各个节点向根节点发送数据 ------------- //
{
net
::
net_socket
::
scclSocketClientManager
client_manager
(
&
root_addr
,
root_handle
->
magic
,
net
::
net_socket
::
scclSocketTypeBootstrap
);
SCCLCHECK
(
bootstrapNet
::
bootstrapNetSend
(
client_manager
.
getSocket
(),
send_data_basic
,
sizeof
(
struct
BootstrapNodeBasic
)));
}
// ------------- 3.从根节点接收nLocalRanks值 ------------- //
// ------------- 3.从根节点接收nLocalRanks值 ------------- //
// 接收nLocalRanks信息
// 接收nLocalRanks信息
{
{
net
::
net_socket
::
scclSocketAcceptManager
accept_manager
(
my_listen
_sock
);
net
::
net_socket
::
scclSocketAcceptManager
accept_manager
(
local_server
_sock
);
SCCLCHECK
(
bootstrapNet
::
bootstrapNetRecv
(
accept_manager
.
getSocket
(),
&
nLocalRanks
,
sizeof
(
int
)));
SCCLCHECK
(
bootstrapNet
::
bootstrapNetRecv
(
accept_manager
.
getSocket
(),
&
nLocalRanks
,
sizeof
(
int
)));
}
}
// 要求必须 nRanks%nLocalRanks == 0
NEQCHECK
(
nRanks
%
nLocalRanks
,
0
);
// ------------- 4.nLocalRanks==0时,从根节点接收所有rank的ip数据 ------------- //
// ------------- 4.nLocalRanks==0时,从根节点接收所有rank的ip数据 ------------- //
this
->
localRank
=
rank
%
nLocalRanks
;
this
->
localRank
=
rank
%
nLocalRanks
;
this
->
interRank
=
rank
/
nLocalRanks
;
this
->
nInterRanks
=
nRanks
/
nLocalRanks
;
// 从根节点接收数据,对应到函数 bootstrapRoot
if
(
localRank
==
0
)
{
if
(
localRank
==
0
)
{
net
::
net_socket
::
scclSocketAcceptManager
accept_manager
(
my_listen
_sock
);
net
::
net_socket
::
scclSocketAcceptManager
accept_manager
(
local_server
_sock
);
SCCLCHECK
(
bootstrapNet
::
bootstrapNetRecv
(
accept_manager
.
getSocket
(),
recv_data_basic
,
recv_data_basic_size
));
SCCLCHECK
(
bootstrapNet
::
bootstrapNetRecv
(
accept_manager
.
getSocket
(),
recv_data_basic
.
data
()
,
recv_data_basic_size
));
}
}
// ------------- 5.nLocalRanks==0时,将所有rank的ip数据广播给节点内其他rank ------------- //
// ------------- 5.nLocalRanks==0时,将所有rank的ip数据广播给节点内其他rank ------------- //
ipcsocket
=
new
scclIpcSocket_t
(
localRank
,
nLocalRanks
,
/*hash*/
root_handle
->
magic
);
ipcsocket
=
new
scclIpcSocket_t
(
localRank
,
nLocalRanks
,
/*hash*/
root_handle
->
magic
);
ipcsocket
->
scclIpcSocketBroadcast
(
recv_data_basic
,
recv_data_basic_size
,
/*localRank root*/
0
);
ipcsocket
->
scclIpcSocketBroadcast
(
recv_data_basic
.
data
()
,
recv_data_basic_size
,
/*localRank root*/
0
);
return
scclSuccess
;
return
scclSuccess
;
}
}
...
@@ -456,9 +489,6 @@ scclResult_t Bootstrap::bootstrapCommInitNodeInfo(scclNet_t* scclNet, struct scc
...
@@ -456,9 +489,6 @@ scclResult_t Bootstrap::bootstrapCommInitNodeInfo(scclNet_t* scclNet, struct scc
////////////////// 设置硬件信息 //////////////////
////////////////// 设置硬件信息 //////////////////
struct
topoLocalNode
*
p_localNode
=
&
node_info
->
localNode
;
struct
topoLocalNode
*
p_localNode
=
&
node_info
->
localNode
;
// 设置CPU信息
p_localNode
->
cpu
.
listen_sock
=
*
my_listen_sock
;
// 设置PCI信息
// 设置PCI信息
SCCLCHECK
(
getBusId
(
hipDev
,
&
p_localNode
->
pci
.
busId
));
SCCLCHECK
(
getBusId
(
hipDev
,
&
p_localNode
->
pci
.
busId
));
...
@@ -471,37 +501,95 @@ scclResult_t Bootstrap::bootstrapCommInitNodeInfo(scclNet_t* scclNet, struct scc
...
@@ -471,37 +501,95 @@ scclResult_t Bootstrap::bootstrapCommInitNodeInfo(scclNet_t* scclNet, struct scc
p_localNode
->
gpu
.
compCap
=
deviceProp
.
major
*
10
+
deviceProp
.
minor
;
p_localNode
->
gpu
.
compCap
=
deviceProp
.
major
*
10
+
deviceProp
.
minor
;
// 设置RDMA信息
// 设置RDMA信息
SCCLCHECK
(
scclNet
->
getProperties
(
hipDev
,
&
p_localNode
->
net
.
props
));
net
::
scclNetProperties_t
props
;
SCCLCHECK
(
scclNet
->
devices
(
&
p_localNode
->
net
.
count
));
SCCLCHECK
(
scclNet
->
getProperties
(
hipDev
,
&
props
));
SCCLCHECK
(
scclNet
->
devices
(
&
p_localNode
->
net
.
count
));
// 节点内网卡数量
snprintf
(
p_localNode
->
net
.
name
,
sizeof
(
p_localNode
->
net
.
name
),
"%s"
,
props
.
name
);
// 主要用于日志记录。
snprintf
(
p_localNode
->
net
.
pciPath
,
sizeof
(
p_localNode
->
net
.
pciPath
),
"%s"
,
props
.
pciPath
);
// PCI设备在/sys中的路径。
#if 0
printf("p_localNode->net.pciPath len=%zu\n", strlen(p_localNode->net.pciPath));
#endif
p_localNode
->
net
.
guid
=
props
.
guid
;
// NIC芯片的唯一标识符。对于具有多个PCI功能(物理或虚拟)的卡非常重要。
p_localNode
->
net
.
ptrSupport
=
props
.
ptrSupport
;
// [SCCL_PTR_HOST|SCCL_PTR_CUDA|SCCL_PTR_DMABUF]
p_localNode
->
net
.
speed
=
props
.
speed
;
// 端口速度,单位为Mbps。
p_localNode
->
net
.
port
=
props
.
port
;
// 端口号。
p_localNode
->
net
.
latency
=
props
.
latency
;
// 网络延迟
p_localNode
->
net
.
maxComms
=
props
.
maxComms
;
// 可以创建的最大通信数量
p_localNode
->
net
.
maxRecvs
=
props
.
maxRecvs
;
// 最大分组接收数量。
return
scclSuccess
;
return
scclSuccess
;
}
}
scclResult_t
Bootstrap
::
bootstrapAllGather
(
struct
scclNodeInfo
*
)
{
scclResult_t
Bootstrap
::
bootstrapCommAllGather
(
std
::
vector
<
struct
BootstrapNodeBasic
>&
all_node_basic
,
struct
scclNodeInfo
*
node_info
,
struct
scclNodeInfoSet
*
node_info_set
)
{
// 数据准备
size_t
inter_data_len
=
nLocalRanks
*
sizeof
(
struct
scclNodeInfo
);
// 节点间传输时每个子块的大小
auto
all_recv_data
=
reinterpret_cast
<
char
*>
(
node_info_set
->
node_info_vec
.
data
());
// 1.节点内通信 allgather
// 1.节点内通信 allgather
auto
local_recv_data
=
all_recv_data
+
this
->
interRank
*
inter_data_len
;
ipcsocket
->
scclIpcSocketAllgatherSync
(
node_info
,
(
void
*
)
local_recv_data
,
sizeof
(
struct
scclNodeInfo
));
// 2.节点间通信,ring allgather
// 2.节点间通信,ring allgather
// TODO: 后续nRanks特别大的时候,可以进一步优化算法,减少通信次数
if
(
localRank
==
0
)
{
int
prev_interRank
=
(
this
->
interRank
-
1
+
this
->
nInterRanks
)
%
this
->
nInterRanks
*
this
->
nLocalRanks
;
int
next_interRank
=
(
this
->
interRank
+
1
+
this
->
nInterRanks
)
%
this
->
nInterRanks
*
this
->
nLocalRanks
;
// scclSocket_t prev_rank_sock = all_node_basic[prev_interRank].sock;
scclSocket_t
next_rank_sock
=
all_node_basic
[
next_interRank
].
sock
;
scclSocket_t
self_rank_sock
=
all_node_basic
[
rank
].
sock
;
printf
(
"bootstrap allgather 11: rank %d, prev_interRank=%d, next_interRank=%d
\n
"
,
rank
,
prev_interRank
,
next_interRank
);
// 对于prev,当前rank是客户端;对于next,当前rank是服务器端
// 客户端:用于发送数据
net
::
net_socket
::
scclSocketClientManager
client_manager
(
&
next_rank_sock
.
addr
,
root_handle
->
magic
,
net
::
net_socket
::
scclSocketTypeBootstrap
);
// 服务器端:用于接收数据
net
::
net_socket
::
scclSocketAcceptManager
accept_manager
(
&
self_rank_sock
);
/////////////////// 实现数据传输 ///////////////////
for
(
int
r
=
0
;
r
<
nInterRanks
-
1
;
r
++
)
{
int
prev_rank
=
(
this
->
interRank
-
r
-
1
+
nInterRanks
)
%
nInterRanks
;
int
next_rank
=
(
this
->
interRank
-
r
+
nInterRanks
)
%
nInterRanks
;
// 准备发送/接收的数据
auto
send_data
=
all_recv_data
+
next_rank
*
inter_data_len
;
auto
recv_data
=
all_recv_data
+
prev_rank
*
inter_data_len
;
#if 0
printf("bootstrapCommAllGather rank=%d, interRank=%d, r=%d, prev_rank=%d, next_rank=%d, inter_data_len=%zu\n",
this->rank,
this->interRank,
r,
prev_rank,
next_rank,
inter_data_len);
#endif
// 3.节点内通信 allgather
// 发送/接收数据
SCCLCHECK
(
bootstrapNet
::
bootstrapNetSend
(
client_manager
.
getSocket
(),
send_data
,
inter_data_len
));
SCCLCHECK
(
bootstrapNet
::
bootstrapNetRecv
(
accept_manager
.
getSocket
(),
recv_data
,
inter_data_len
));
}
}
#if 0
printf("222222\n");
if(rank == 0) {
char line[20];
sprintf(line, "print rank=%d", rank);
std::string prefix(line); // 创建prefix字符串
for(int r = 0; r < nRanks; r++) {
struct scclNodeInfo node_basic = node_info_set->node_info_vec[r];
printNodeInfo(prefix, &node_basic); // 正确的调用方式
}
}
#endif
// 3.节点内通信 broadcast
ipcsocket
->
scclIpcSocketBroadcast
(
all_recv_data
,
nRanks
*
sizeof
(
struct
scclNodeInfo
),
0
);
return
scclSuccess
;
return
scclSuccess
;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
// // 将本地socket地址写入到/tmp/文件夹的文件中,通过nfs共享存储,其他rank可见
// scclResult_t bootstrapGetAllNodes(const struct scclNodeInfo* , struct BootstrapComm* comm) {
// // // 分配并初始化IPC套接字
// // struct scclIpcSocket ipcSock = {0};
// // // Create a UDS socket to receive the converted fd
// // SCCLCHECK(scclIpcSocketInit(&ipcSock, ->rank, /*hash*/ handle->magic, /*abortFlag*/ NULL));
// // printf("fd=%d, socketName=%s\n", ipcSock.fd, ipcSock.socketName);
// return scclInProgress;
// }
// auto node_info = bootstrap_comm->node_info;
// // 设置节点内socket通信工具
// ipcsocket = new scclIpcSocket_t(node_info->localRank, node_info->nRanks, node_info->hostHash, bootstrap_comm->abortFlag);
}
// namespace bootstrap
}
// namespace bootstrap
}
// namespace topology
}
// namespace topology
}
// namespace hardware
}
// namespace hardware
...
...
src/hardware/topology/bootstrap/bootstrap.h
View file @
379c4128
...
@@ -28,21 +28,23 @@ public:
...
@@ -28,21 +28,23 @@ public:
// 初始化bootstrap通信环境
// 初始化bootstrap通信环境
scclResult_t
init
(
struct
BootstrapComm
*
bootstrap_comm
);
scclResult_t
init
(
struct
BootstrapComm
*
bootstrap_comm
);
// 广播节点信息
scclResult_t
bootstrapAllGather
(
struct
scclNodeInfo
*
);
private:
private:
// 创建根节点的数据广播
// 创建根节点的数据广播
scclResult_t
bootstrapRootGatherAndBroadcast
(
void
*
send_data
,
void
*
recv_data
);
scclResult_t
bootstrapRootGatherAndBroadcast
(
struct
BootstrapNodeBasic
*
send_data_basic
,
std
::
vector
<
struct
BootstrapNodeBasic
>&
recv_data
_basic
);
// 初始化唯一ID信息结构体
// 初始化唯一ID信息结构体
scclResult_t
bootstrapCommInitNodeInfo
(
scclNet_t
*
scclNet
,
struct
scclNodeInfo
*
node_info
);
scclResult_t
bootstrapCommInitNodeInfo
(
scclNet_t
*
scclNet
,
struct
scclNodeInfo
*
node_info
);
// scclResult_t bootstrapGetAllNodes(const struct scclNodeInfo* , struct BootstrapComm* comm);
// 广播节点信息
scclResult_t
bootstrapCommAllGather
(
std
::
vector
<
struct
BootstrapNodeBasic
>&
all_node_basic
,
struct
scclNodeInfo
*
node_info
,
struct
scclNodeInfoSet
*
node_info_set
);
private:
private:
int
rank
,
nRanks
;
// 初始化阶段获取MPI的值
int
rank
,
nRanks
;
// 初始化阶段获取MPI的值
int
localRank
,
nLocalRanks
;
// 通过bootstrapRootGatherAndBroadcast函数确定值
int
localRank
,
nLocalRanks
;
// 通过bootstrapRootGatherAndBroadcast函数确定值
int
interRank
,
nInterRanks
;
// 整个节点在全部节点中的位置
// TODO: 用于控制套接字终端的变量,目前不知道在哪里使用
volatile
uint32_t
*
abortFlag
;
// 中止标志,非阻塞套接字设置
volatile
uint32_t
*
abortFlag
;
// 中止标志,非阻塞套接字设置
// 外部传入的0号节点的基础信息
// 外部传入的0号节点的基础信息
...
@@ -54,12 +56,8 @@ private:
...
@@ -54,12 +56,8 @@ private:
pthread_mutex_t
bootstrapMutex
=
PTHREAD_MUTEX_INITIALIZER
;
pthread_mutex_t
bootstrapMutex
=
PTHREAD_MUTEX_INITIALIZER
;
pthread_cond_t
bootstrapCond
=
PTHREAD_COND_INITIALIZER
;
pthread_cond_t
bootstrapCond
=
PTHREAD_COND_INITIALIZER
;
// 标志是否已经初始化
// 节点内通信的类
// 线程池变量
scclIpcSocket_t
*
ipcsocket
=
nullptr
;
// 指向scclIpcSocket类实例的指针,初始值为nullptr
int
max_pthreads
=
0
;
// 用于存储最大并行线程数的整型变量
class
ThreadPool
*
pthread_pool
=
nullptr
;
// 指向ThreadPool类实例的指针,初始值为nullptr
scclIpcSocket_t
*
ipcsocket
=
nullptr
;
// 指向scclIpcSocket类实例的指针,初始值为nullptr
scclSocket_t
*
my_listen_sock
=
nullptr
;
// 指向scclSocket类实例的指针,初始值为nullptr
};
};
}
// namespace bootstrap
}
// namespace bootstrap
...
...
src/hardware/topology/bootstrap/bootstrap_utils.cpp
View file @
379c4128
...
@@ -9,7 +9,7 @@ namespace bootstrap {
...
@@ -9,7 +9,7 @@ namespace bootstrap {
////////////////////////////// 结构体定义 //////////////////////////////
////////////////////////////// 结构体定义 //////////////////////////////
// 构造函数定义
// 构造函数定义
scclNodeInfoSet
::
scclNodeInfoSet
(
int
nRanks
)
:
nUniqueInfos
(
nRanks
)
{
scclNodeInfoSet
::
scclNodeInfoSet
(
int
nRanks
)
{
printf
(
"scclNodeInfoSet 构造函数
\n
"
);
printf
(
"scclNodeInfoSet 构造函数
\n
"
);
node_info_vec
.
reserve
(
nRanks
);
// 预留空间
node_info_vec
.
reserve
(
nRanks
);
// 预留空间
printf
(
"scclNodeInfoSet 预留空间
\n
"
);
printf
(
"scclNodeInfoSet 预留空间
\n
"
);
...
@@ -21,6 +21,8 @@ void BootstrapComm::init(int rank, int nRanks, int localRank, int nLocalRanks) {
...
@@ -21,6 +21,8 @@ void BootstrapComm::init(int rank, int nRanks, int localRank, int nLocalRanks) {
this
->
nRanks
=
nRanks
;
this
->
nRanks
=
nRanks
;
this
->
localRank
=
localRank
;
this
->
localRank
=
localRank
;
this
->
nLocalRanks
=
nLocalRanks
;
this
->
nLocalRanks
=
nLocalRanks
;
this
->
interRank
=
rank
/
nLocalRanks
;
this
->
nInterRanks
=
nRanks
/
nLocalRanks
;
node_info_set
=
new
scclNodeInfoSet
(
nRanks
);
// 假设需要动态分配
node_info_set
=
new
scclNodeInfoSet
(
nRanks
);
// 假设需要动态分配
};
};
...
@@ -192,16 +194,18 @@ scclResult_t getBusId(int hipDev, int64_t* busId) {
...
@@ -192,16 +194,18 @@ scclResult_t getBusId(int hipDev, int64_t* busId) {
}
}
// 函数:打印 scclNodeInfo 结构体的信息
// 函数:打印 scclNodeInfo 结构体的信息
scclResult_t
printNodeInfo
(
struct
scclNodeInfo
*
info
)
{
scclResult_t
printNodeInfo
(
const
std
::
string
&
prefix
,
struct
scclNodeInfo
*
info
)
{
char
addrline
[
net
::
SOCKET_NAME_MAXLEN
+
1
];
char
addrline
[
net
::
SOCKET_NAME_MAXLEN
+
1
];
if
(
info
->
localRank
==
0
)
{
// if(info->localRank == 0) {
if
(
1
)
{
printf
(
"==========================================
\n
"
printf
(
"==========================================
\n
"
"Total Rank: %d, Local Rank: %d, Host Hash: %lu, PID Hash: %lu
\n
"
"
%s,
Total Rank: %d, Local Rank: %d, Host Hash: %lu, PID Hash: %lu
\n
"
"gpu: dev=%d, gpu.name=%s, gcn=%s, compCap=%d
\n
"
"gpu: dev=%d, gpu.name=%s, gcn=%s, compCap=%d
\n
"
"net: count=%d, device name=%s, pciPath=%s, guid=%lu, ptrSupport=%
d
, speed=%d, port=%d, latency=%f, maxComms=%d, maxRecvs=%d
\n
"
"net: count=%d, device name=%s, pciPath=%s, guid=%lu, ptrSupport=%
u
, speed=%d, port=%d, latency=%f, maxComms=%d, maxRecvs=%d
\n
"
"cpu: socketAddr=%s
\n
pci: busId=%ld
\n
"
"cpu: socketAddr=%s
\n
pci: busId=%ld"
"
\n
==========================================
\n
"
,
"
\n
==========================================
\n
"
,
prefix
.
c_str
(),
info
->
rank
,
info
->
rank
,
info
->
localRank
,
info
->
localRank
,
info
->
hostHash
,
info
->
hostHash
,
...
@@ -211,15 +215,15 @@ scclResult_t printNodeInfo(struct scclNodeInfo* info) {
...
@@ -211,15 +215,15 @@ scclResult_t printNodeInfo(struct scclNodeInfo* info) {
info
->
localNode
.
gpu
.
gcn
,
info
->
localNode
.
gpu
.
gcn
,
info
->
localNode
.
gpu
.
compCap
,
info
->
localNode
.
gpu
.
compCap
,
info
->
localNode
.
net
.
count
,
info
->
localNode
.
net
.
count
,
info
->
localNode
.
net
.
props
.
name
,
info
->
localNode
.
net
.
name
,
info
->
localNode
.
net
.
props
.
pciPath
,
info
->
localNode
.
net
.
pciPath
,
info
->
localNode
.
net
.
props
.
guid
,
info
->
localNode
.
net
.
guid
,
info
->
localNode
.
net
.
props
.
ptrSupport
,
static_cast
<
unsigned
int
>
(
info
->
localNode
.
net
.
ptrSupport
)
,
info
->
localNode
.
net
.
props
.
speed
,
info
->
localNode
.
net
.
speed
,
info
->
localNode
.
net
.
props
.
port
,
info
->
localNode
.
net
.
port
,
info
->
localNode
.
net
.
props
.
latency
,
info
->
localNode
.
net
.
latency
,
info
->
localNode
.
net
.
props
.
maxComms
,
info
->
localNode
.
net
.
maxComms
,
info
->
localNode
.
net
.
props
.
maxRecvs
,
info
->
localNode
.
net
.
maxRecvs
,
net
::
net_socket
::
scclSocketToString
(
&
info
->
localNode
.
cpu
.
listen_sock
.
addr
,
addrline
),
net
::
net_socket
::
scclSocketToString
(
&
info
->
localNode
.
cpu
.
listen_sock
.
addr
,
addrline
),
info
->
localNode
.
pci
.
busId
);
info
->
localNode
.
pci
.
busId
);
}
}
...
...
src/hardware/topology/bootstrap/bootstrap_utils.h
View file @
379c4128
...
@@ -37,9 +37,9 @@ struct bootstrapRootArgs {
...
@@ -37,9 +37,9 @@ struct bootstrapRootArgs {
// 用于初始建立连接阶段,0号rank之外的进程向其传递的信息
// 用于初始建立连接阶段,0号rank之外的进程向其传递的信息
struct
BootstrapNodeBasic
{
struct
BootstrapNodeBasic
{
int
rank
;
int
rank
;
int
nRanks
;
// 进程的总数量
int
nRanks
;
// 进程的总数量
uint64_t
hostHash
;
// 用于区分host的CPU编号
uint64_t
hostHash
;
// 用于区分host的CPU编号
scclSocket
Address_t
addr
;
// 各个进程的监听套接字地址,用于网络通信
scclSocket
_t
sock
;
// 各个进程的监听套接字地址,用于网络通信
};
};
// 定义每个rank所持有的所有拓扑节点
// 定义每个rank所持有的所有拓扑节点
...
@@ -53,13 +53,21 @@ struct topoLocalNode {
...
@@ -53,13 +53,21 @@ struct topoLocalNode {
struct
{
struct
{
int
dev
;
// NVML设备编号
int
dev
;
// NVML设备编号
char
name
[
8
];
// 设备名称
char
name
[
8
];
// 设备名称
char
gcn
[
7
];
// GCN架构名称
char
gcn
[
8
];
// GCN架构名称
int
compCap
;
// CUDA计算能力
int
compCap
;
// CUDA计算能力
}
gpu
;
// GPU节点
}
gpu
;
// GPU节点
struct
{
struct
{
int
count
;
// 网卡数量
int
count
;
// 网卡数量
net
::
scclNetProperties_t
props
;
char
name
[
8
];
// 主要用于日志记录。
}
net
;
// 网络节点
char
pciPath
[
128
];
// PCI设备在/sys中的路径。
uint64_t
guid
;
// NIC芯片的唯一标识符。对于具有多个PCI功能(物理或虚拟)的卡非常重要。
uint8_t
ptrSupport
;
// [SCCL_PTR_HOST|SCCL_PTR_CUDA|SCCL_PTR_DMABUF]
int
speed
;
// 端口速度,单位为Mbps。
int
port
;
// 端口号。
float
latency
;
// 网络延迟
int
maxComms
;
// 可以创建的最大通信数量
int
maxRecvs
;
// 最大分组接收数量。
}
net
;
// 网络节点
};
};
// 定义结构体 scclNodeInfo,用于存储每个rank的通信节点的信息
// 定义结构体 scclNodeInfo,用于存储每个rank的通信节点的信息
...
@@ -74,7 +82,6 @@ struct scclNodeInfo {
...
@@ -74,7 +82,6 @@ struct scclNodeInfo {
// 每个节点的信息
// 每个节点的信息
struct
scclNodeInfoSet
{
struct
scclNodeInfoSet
{
int
nUniqueInfos
;
// 通信节点的数量
std
::
vector
<
struct
scclNodeInfo
>
node_info_vec
;
std
::
vector
<
struct
scclNodeInfo
>
node_info_vec
;
// 构造函数声明
// 构造函数声明
...
@@ -95,8 +102,11 @@ public:
...
@@ -95,8 +102,11 @@ public:
int
nRanks
=
0
;
// 总的节点数量
int
nRanks
=
0
;
// 总的节点数量
int
localRank
=
-
1
;
// 当前节点在本地计算节点中的排名
int
localRank
=
-
1
;
// 当前节点在本地计算节点中的排名
int
nLocalRanks
=
0
;
// 本地计算节点中的节点总数
int
nLocalRanks
=
0
;
// 本地计算节点中的节点总数
int
hipDev
=
-
1
;
// CUDA 设备 ID
int
interRank
=
-
1
;
// 整个节点在全部节点中的位置
int
deviceCnt
=
0
;
// 设备数量
int
nInterRanks
=
0
;
// 全局拥有节点的个数
int
hipDev
=
-
1
;
// CUDA 设备 ID
int
deviceCnt
=
0
;
// 设备数量
// proxy通信
// proxy通信
uint64_t
magic
;
// 魔术数,用于验证结构体
uint64_t
magic
;
// 魔术数,用于验证结构体
...
@@ -125,7 +135,7 @@ scclResult_t getBusId(int hipDev, int64_t* busId);
...
@@ -125,7 +135,7 @@ scclResult_t getBusId(int hipDev, int64_t* busId);
int
scclCudaCompCap
(
void
);
int
scclCudaCompCap
(
void
);
// 打印唯一的拓扑信息
// 打印唯一的拓扑信息
scclResult_t
printNodeInfo
(
struct
scclNodeInfo
*
info
);
scclResult_t
printNodeInfo
(
const
std
::
string
&
prefix
,
struct
scclNodeInfo
*
info
);
// 实现类似于std::span的功能,将字节数组转换为类型数组
// 实现类似于std::span的功能,将字节数组转换为类型数组
template
<
typename
T
>
template
<
typename
T
>
...
...
src/utils/thread_pool.cpp
View file @
379c4128
...
@@ -108,6 +108,12 @@ bool ThreadPool::allTasksCompleted() {
...
@@ -108,6 +108,12 @@ bool ThreadPool::allTasksCompleted() {
return
completed
;
return
completed
;
}
}
/**
* @brief 获取线程池的容量大小
* @return 返回线程池当前的最大工作线程数
*/
int
ThreadPool
::
getThreadPoolSize
()
{
return
workers
.
capacity
();
}
/**
/**
* 设置指定线程的CPU亲和性,将其绑定到指定的核心上
* 设置指定线程的CPU亲和性,将其绑定到指定的核心上
* @param thread 需要设置亲和性的线程
* @param thread 需要设置亲和性的线程
...
...
src/utils/thread_pool.h
View file @
379c4128
...
@@ -35,6 +35,8 @@ public:
...
@@ -35,6 +35,8 @@ public:
// 检查是否所有任务都已完成
// 检查是否所有任务都已完成
bool
allTasksCompleted
();
bool
allTasksCompleted
();
// 获取线程池中工作线程的数量
int
getThreadPoolSize
();
private:
private:
std
::
vector
<
pthread_t
>
workers
;
// 工作线程列表
std
::
vector
<
pthread_t
>
workers
;
// 工作线程列表
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment