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 <memory>
16 : #include <unordered_map>
17 :
18 : #include "ccu_jetty.h"
19 : #include "hash_utils.h"
20 : #include "ip_address.h"
21 : #include "virtual_topo.h"
22 :
23 : namespace Hccl {
24 :
25 : class CcuJettyMgr final {
26 : public:
27 : explicit CcuJettyMgr(int32_t devLogicId);
28 : ~CcuJettyMgr();
29 :
30 : HcclResult PrepareCreate(const std::vector<LinkData>& links);
31 : std::pair<CcuChannelInfo, std::vector<CcuJetty*>> GetChannelJettys(const LinkData& link) const;
32 :
33 : void Confirm();
34 : void Fallback();
35 : void Clean();
36 : void Resume();
37 :
38 : uint32_t GetUsedChannelCount(const uint8_t dieId);
39 : RankId GetRemoteRankIdByChannelId(const uint8_t dieId, const uint32_t channelId);
40 : std::pair<IpAddress, IpAddress> GetAddrPairByChannelId(const uint8_t dieId, const uint32_t channelId);
41 :
42 : private:
43 : int32_t devLogicId_{0};
44 : bool isReleased{true};
45 :
46 : struct ResIdHash {
47 2852 : std::size_t operator()(const std::pair<uint8_t, uint32_t>& p) const { return HashCombine({p.first, p.second}); }
48 : };
49 :
50 : using CcuJettyPtr = CcuJetty*;
51 : using BatchKey = IpAddress; // srcIpAddress;
52 : using ResIdkey = std::pair<uint8_t, uint32_t>;
53 : using ChannelIdKey = ResIdkey;
54 : using JettyIdKey = ResIdkey;
55 :
56 : // 平台层每次调用CcuAllocChannels可能提供多个ccu channel,且不同srcIp的jetty不能复用
57 : // 故以srcIp为粒度,多次调用接口,每次接口结果定义为一个批次资源
58 : struct ResourceBatch { // 记录该批次申请到的所有channel资源信息
59 : BatchKey key;
60 : std::vector<ChannelIdKey> channelIdKeys;
61 : std::vector<ChannelIdKey> availableChannelIdKeys;
62 : std::unordered_map<JettyIdKey, std::unique_ptr<CcuJetty>, ResIdHash> jettys;
63 :
64 46 : ResourceBatch(const BatchKey& batchKey, const std::vector<CcuChannelInfo>& channelInfos) : key(batchKey)
65 : {
66 46 : const uint32_t channelNum = channelInfos.size();
67 46 : channelIdKeys.reserve(channelNum);
68 46 : availableChannelIdKeys.reserve(channelNum);
69 414 : for (const auto& channelInfo : channelInfos) {
70 368 : const auto dieId = channelInfo.dieId;
71 368 : const auto channelId = channelInfo.channelId;
72 368 : channelIdKeys.emplace_back(dieId, channelId);
73 368 : availableChannelIdKeys.emplace_back(dieId, channelId);
74 :
75 1104 : for (const auto& jettyInfo : channelInfo.jettyInfos) {
76 736 : const auto taJettyId = jettyInfo.taJettyId;
77 736 : const auto jettyIdKey = std::make_pair(dieId, taJettyId);
78 736 : if (jettys.find(jettyIdKey) != jettys.end()) {
79 644 : continue;
80 : }
81 :
82 92 : std::unique_ptr<CcuJetty> ccuJetty;
83 92 : CHK_RET_THROW(
84 : InternalException,
85 : StringFormat(
86 : "[CcuJettyMgr][%s] failed to create ccu jetty, locAddr[%s] "
87 : "dieId[%u] taJettyId[%u].",
88 : __func__, key.Describe().c_str(), dieId, taJettyId),
89 : CcuCreateJetty(key, jettyInfo, ccuJetty));
90 :
91 92 : jettys[jettyIdKey] = std::move(ccuJetty);
92 92 : }
93 : }
94 46 : }
95 : };
96 :
97 : struct Allocation {
98 : LinkData link;
99 : ChannelIdKey channelIdKey;
100 : ResourceBatch* batchPtr;
101 : };
102 :
103 : struct UnconfirmedRecord {
104 : std::vector<Allocation> allocations; // 记录从已申请的资源中的分配操作
105 : std::unordered_set<ResourceBatch*> newBatchSet; // 记录新申请资源的操作
106 :
107 15 : void Clear()
108 : {
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(
132 : const BatchKey& batchKey, 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
|