查询拓扑信息
背景
为了应对复杂的网络拓扑结构,通信算子需要根据通信域的拓扑结构选择最匹配的算法,为此,HCCL控制面提供了拓扑信息查询功能,供开发者使用。
拓扑信息
HCCL控制面接口支持查询的拓扑信息如下表所示。
|
拓扑信息 |
查询接口 |
|---|---|
|
获取Device在指定通信域中对应的rank序号。 |
|
|
查询指定通信域的rank数。 |
|
|
查询包含当前rank的拓扑层级编号列表以及拓扑层级数量。 |
|
|
给定通信域和拓扑层级编号,返回该层级下本rank所在拓扑实例的所有rank编号列表以及rank数量。 |
|
|
给定通信域和拓扑层级编号,返回该层级下本rank所在拓扑实例的rank数量。 |
|
|
给定通信域和拓扑层级编号,返回本rank所在拓扑层级中的拓扑类型。 |
|
|
给定通信域和拓扑层级编号,查询该层级下的拓扑实例数量,以及每个实例包含的rank数量。 |
|
|
给定通信域和拓扑层级编号,查询源rank和目的rank之间的通信连接信息。 |
- 查询通信域内当前rank的id。
1 2 3 4 5
u32 userRank = INVALID_VALUE_RANKID; HcclResult ret = HcclGetRankId(comm, &userRank); if (userRank == root && sendBuf == nullptr) { // root节点的send_buff不允许为空 return HCCL_E_PTR; }
- 查询通信域的rank数量。
1 2 3 4 5
u32 rankSize = INVALID_VALUE_RANKSIZE; HcclResult ret = HcclGetRankSize(comm, &rankSize); if (userRank >= rankSize) { // rank_id 超出范围 return HCCL_E_PARA; }
- 查询本卡与Server内0号卡之间的链路信息。
1 2 3 4 5 6 7 8 9 10 11
u32 dstRank = 0; u32 srcRank = rank; CommLink *linkList = nullptr; u32 listSize = 0; HcclResult ret = HcclRankGraphGetLinks(comm, 0, srcRank, dstRank, &linkList, &listSize); for (u32 i = 0; i < listSize; ++i) { CommLink& currentLink = linkList[i]; // 枚举所有链路对象 if (currentLink.linkAttr.linkProtocol == CommProtocol::COMM_PROTOCOL_HCCS) { // 对HCCS链路的判断处理 } }
- 查询本卡所在通信域包含的超节点数量。
1 2 3 4 5 6 7 8 9 10
u32 *netlayers = nullptr; u32 netLayersNum = 0; HcclResult ret = HcclRankGraphGetLayers(comm, &netlayers, &netLayersNum); // 获取通信域中包含的通信网络层次 u32 superPodNum; u32 level1RankListNum = 0; u32 *level1SizeList = nullptr; if (netLayersNum == 3) { // 超节点场景 ret = HcclRankGraphGetInstSizeListByLayer(comm, 1, &level1SizeList, &level1RankListNum); superPodNum = level1RankListNum; }
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
// 以一个单机4卡的Mesh连接为例 struct TopoInfo { uint32_t rankId; // 用以唯一标识一个rank uint32_t rankSize; // 参与此次集合通信的rank的数量 std::vector<u32> rankList; // 参与此次集合通信的rank的rankId集合 CommTopo topoType; // 链路连接类型:COMM_TOPO_1DMESH/COMM_TOPO_CLOS等 std::vector<HcclCHannelDesc> channels; // 本rank和其他卡之间的链路信息 }; HcclResult FillSimpleTopoInfo(HcclComm comm, TopoInfo &topoInfo){ HcclResult ret = HcclGetRankId(comm, &topoInfo.rankId); // 校验ret结果 ret = HcclGetRankSize(comm, &topoInfo.rankSize); // 校验ret结果 uint32_t *ranks = nullptr; uint32_t rankNum = 0; // 由于是单机4卡,因此netLayer=0,获取netLayer 0 下的ranks即为此次集合通信的rankId的集合 ret = HcclRankGraphGetRanksByLayer(comm, 0, &ranks, &rankNum); // 校验ret结果 for (size_t index = 0; index < rankNum; index++) { topoInfo.rankList.push_back(ranks[index]); } uint32_t topoInstNum = 0; uint32_t *topoInsts; ret = HcclRankGraphGetTopoInstsByLayer(comm, 0, &topoInsts, &topoInstNum); // 校验结果 // 因为是单机4卡,所以只会有1个topoInst,因此topoInsts = [0], topoInstNum = 1 // 通过topoInst即可获取设备的物理链接类型 ret = HcclRankGraphGetTopoTypeByLayer(comm, 0, topoInsts[0], &topoInfo.topoType); // 校验结果 // 计算需要的channels for (auto remoteRankId : topoInfo.rankList) { if (remoteRankId == topoInfo.rankId) {continue;} CommLink *linkList = nullptr; u32 listSize = 0; ret = HcclRankGraphGetLinks(comm, netLayer, myRank, remoteRankId, &linkList, &listSize); for (uint32_t idx = 0; idx < listSize; idx++) { HcclChannelDesc channelDesc; HcclChannelDescInit(&channelDesc, 1); channelDesc.remoteRank = remoteRankId; CommLink link = linkList[idx]; channelDesc.localEndpoint.protocol = link.srcEndpointDesc.protocol; channelDesc.localEndpoint.commAddr = link.srcEndpointDesc.commAddr; channelDesc.localEndpoint.loc = link.srcEndpointDesc.loc; channelDesc.remoteEndpoint.protocol = link.dstEndpointDesc.protocol; channelDesc.remoteEndpoint.commAddr = link.dstEndpointDesc.commAddr; channelDesc.remoteEndpoint.loc = link.dstEndpointDesc.loc; channelDesc.channelProtocol = link.linkAttr.linkProtocol; channelDesc.notifyNum = 3; topoInfo.channels.push_back(channelDesc); } } return ret; } |
父主题: AI CPU算子开发