Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #ifndef HCCL_CCU_JETTY_MGR_H
12 : #define HCCL_CCU_JETTY_MGR_H
13 :
14 : #include <vector>
15 : #include <unordered_map>
16 :
17 : #include "ccu_jetty.h"
18 : #include "hash_utils.h"
19 : #include "ip_address.h"
20 : #include "virtual_topo.h"
21 :
22 : namespace Hccl {
23 :
24 : class CcuJettyMgr final {
25 : public:
26 : explicit CcuJettyMgr(int32_t devLogicId);
27 : ~CcuJettyMgr();
28 :
29 : HcclResult PrepareCreate(const std::vector<LinkData> &links);
30 : std::pair<CcuChannelInfo, std::vector<CcuJetty *>> GetChannelJettys(const LinkData &link) const;
31 :
32 : void Confirm();
33 : void Fallback();
34 : void Clean();
35 : void Resume();
36 :
37 : uint32_t GetUsedChannelCount(const uint8_t dieId);
38 : RankId GetRemoteRankIdByChannelId(const uint8_t dieId, const uint32_t channelId);
39 : std::pair<IpAddress, IpAddress> GetAddrPairByChannelId(const uint8_t dieId, const uint32_t channelId);
40 :
41 : private:
42 : int32_t devLogicId_{0};
43 : bool isReleased{true};
44 :
45 : struct ResIdHash {
46 2852 : std::size_t operator()(const std::pair<uint8_t, uint32_t>& p) const
47 : {
48 2852 : return HashCombine({p.first, p.second});
49 : }
50 : };
51 :
52 : using CcuJettyPtr = CcuJetty*;
53 : using BatchKey = IpAddress; // srcIpAddress;
54 : using ResIdkey = std::pair<uint8_t, uint32_t>;
55 : using ChannelIdKey = ResIdkey;
56 : using JettyIdKey = ResIdkey;
57 :
58 : // 平台层每次调用CcuAllocChannels可能提供多个ccu channel,且不同srcIp的jetty不能复用
59 : // 故以srcIp为粒度,多次调用接口,每次接口结果定义为一个批次资源
60 : struct ResourceBatch { // 记录该批次申请到的所有channel资源信息
61 : BatchKey key;
62 : std::vector<ChannelIdKey> channelIdKeys;
63 : std::vector<ChannelIdKey> availableChannelIdKeys;
64 : std::unordered_map<JettyIdKey, std::unique_ptr<CcuJetty>, ResIdHash> jettys;
65 :
66 46 : ResourceBatch(const BatchKey &batchKey, const std::vector<CcuChannelInfo> &channelInfos)
67 46 : : key(batchKey)
68 : {
69 46 : const uint32_t channelNum = channelInfos.size();
70 46 : channelIdKeys.reserve(channelNum);
71 46 : availableChannelIdKeys.reserve(channelNum);
72 414 : for (const auto &channelInfo : channelInfos) {
73 368 : const auto dieId = channelInfo.dieId;
74 368 : const auto channelId = channelInfo.channelId;
75 368 : channelIdKeys.emplace_back(dieId, channelId);
76 368 : availableChannelIdKeys.emplace_back(dieId, channelId);
77 :
78 1104 : for (const auto &jettyInfo : channelInfo.jettyInfos) {
79 736 : const auto taJettyId = jettyInfo.taJettyId;
80 736 : const auto jettyIdKey = std::make_pair(dieId, taJettyId);
81 736 : if (jettys.find(jettyIdKey) != jettys.end()) {
82 644 : continue;
83 : }
84 :
85 92 : std::unique_ptr<CcuJetty> ccuJetty;
86 92 : CHK_RET_THROW(InternalException,
87 : StringFormat("[CcuJettyMgr][%s] failed to create ccu jetty, locAddr[%s] "
88 : "dieId[%u] taJettyId[%u].", __func__, key.Describe().c_str(),
89 : dieId, taJettyId),
90 : CcuCreateJetty(key, jettyInfo, ccuJetty));
91 :
92 92 : jettys[jettyIdKey] = std::move(ccuJetty);
93 92 : }
94 : }
95 46 : }
96 : };
97 :
98 : struct Allocation {
99 : LinkData link;
100 : ChannelIdKey channelIdKey;
101 : ResourceBatch *batchPtr;
102 : };
103 :
104 : struct UnconfirmedRecord {
105 : std::vector<Allocation> allocations; // 记录从已申请的资源中的分配操作
106 : std::unordered_set<ResourceBatch *> newBatchSet; // 记录新申请资源的操作
107 :
108 15 : void Clear() {
109 15 : allocations.clear();
110 15 : newBatchSet.clear();
111 15 : }
112 : };
113 :
114 : // 本轮下发算子新增分配记录
115 : UnconfirmedRecord unconfirmedRecord_;
116 : // 各资源申请记录,当前按SrcIpAddr粒度申请和管理
117 : std::unordered_map<BatchKey, std::vector<std::unique_ptr<ResourceBatch>>> batchMap_;
118 : // 各link已分配的channel资源Id信息
119 : std::unordered_map<LinkData, ChannelIdKey> allocatedChannelIdMap_;
120 : // 全部已申请的channel资源信息,资源申请成功后将要记录到该map中
121 : using CcuChannelJettyInfo = std::pair<CcuChannelInfo, std::vector<CcuJetty *>>;
122 : std::unordered_map<ChannelIdKey, CcuChannelJettyInfo, ResIdHash> channelJettyInfoMap_;
123 : // 以die粒度记录已分配channel资源, index: dieId
124 : std::unordered_map<uint8_t, uint32_t> usedChannelCntMap_;
125 : // 记录channel与对端rank的映射关系, index: (die, channelId)
126 : std::unordered_map<ChannelIdKey, RankId, ResIdHash> channelRemoteRankIdMap_;
127 : std::unordered_map<ChannelIdKey, std::pair<IpAddress, IpAddress>, ResIdHash> channelIpAddressMap_;
128 :
129 : HcclResult GetAvailableBatch(const BatchKey &batchKey, ResourceBatch *&batchPtr, uint32_t sqSize);
130 : bool FindAvailableBatch(const BatchKey &batchKey, ResourceBatch *&batchPtr) const;
131 : HcclResult CreateAndSaveNewBatch(const BatchKey &batchKey,
132 : const std::vector<CcuChannelInfo> channelInfos, ResourceBatch *&batchPtr);
133 : void FallbackAndRemoveBatches();
134 : void FallbackAllocatedChannelJettyInfo();
135 : void ReleaseConfirmedChannelRes();
136 : };
137 :
138 : } // namespace Hccl
139 :
140 : #endif // HCCL_CCU_JETTY_MGR_H
|