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 : #include "phy_topo.h"
12 : #include "exception_util.h"
13 : #include "internal_exception.h"
14 : namespace Hccl {
15 :
16 355 : std::unique_ptr<PhyTopo>& PhyTopo::GetInstance()
17 : {
18 355 : static std::unique_ptr<PhyTopo> topo = std::make_unique<PhyTopo>();
19 355 : return topo;
20 : }
21 :
22 15 : void PhyTopo::InitFinish() { initFlag = true; }
23 :
24 26 : bool PhyTopo::IsInitFinished() const { return initFlag; }
25 :
26 64 : void PhyTopo::Clear()
27 : {
28 64 : topos.clear();
29 64 : initFlag = false;
30 64 : }
31 :
32 26 : void PhyTopo::AddTopoGraph(const u32 netLayer, std::shared_ptr<Graph<PhyTopo::Node, PhyTopo::Link>> topo)
33 : {
34 26 : if (!initFlag) {
35 26 : topos[netLayer] = topo;
36 38 : HCCL_DEBUG("[PhyTopo]add topo success, netLayer [%u], topo size is [%zu]", netLayer, topos.size());
37 : } else {
38 0 : THROW<InternalException>("PhyTopo AddTopoGraph fail. PhyTopo has been initialized "
39 : "and cannot be changed, please check.");
40 : }
41 26 : }
42 :
43 124 : std::shared_ptr<Graph<PhyTopo::Node, PhyTopo::Link>> PhyTopo::GetTopoGraph(const u32 netLayer) const
44 : {
45 124 : if (topos.find(netLayer) == topos.end()) {
46 5 : return nullptr;
47 : }
48 119 : return topos.at(netLayer);
49 : }
50 :
51 99 : bool PhyTopo::IsNetLayerExisted(const u32 netLayer) const
52 : {
53 99 : if (topos.find(netLayer) == topos.end()) {
54 1 : return false;
55 : }
56 98 : return true;
57 : }
58 :
59 14 : void PhyTopo::Dump() const
60 : {
61 22 : HCCL_DEBUG("PhyTopo Dump:");
62 31 : for (auto& pair : topos) {
63 29 : HCCL_DEBUG("netLayer[%u]:", pair.first);
64 29 : HCCL_DEBUG("nodes:");
65 17 : std::set<NodeId> nodeIds{};
66 17 : pair.second->TraverseNode([&](NodeId nodeId, std::shared_ptr<PhyTopo::Node> node) {
67 58 : nodeIds.insert(nodeId);
68 112 : HCCL_DEBUG("%s", node->Describe().c_str());
69 58 : });
70 29 : HCCL_DEBUG("links:");
71 75 : for (NodeId nodeId : nodeIds) {
72 58 : pair.second->TraverseEdge(nodeId, [&](std::shared_ptr<Link> link) {
73 352 : HCCL_DEBUG("%s", link->Describe().c_str());
74 148 : });
75 : }
76 17 : }
77 14 : }
78 :
79 343 : PhyTopo::ConnInterface::ConnInterface(
80 : const std::set<std::string> inputPorts, const AddrPosition inputPos, const LinkType inputLinkType,
81 343 : const std::set<LinkProtocol> inputLinkProtocols)
82 343 : : ports(inputPorts),
83 343 : pos(inputPos),
84 343 : linkType(inputLinkType),
85 343 : linkProtocols(inputLinkProtocols)
86 343 : {}
87 :
88 323 : std::set<std::string> PhyTopo::ConnInterface::GetPorts() const { return ports; }
89 :
90 316 : AddrPosition PhyTopo::ConnInterface::GetPos() const { return pos; }
91 :
92 1 : LinkType PhyTopo::ConnInterface::GetLinkType() const { return linkType; }
93 :
94 777 : std::set<LinkProtocol> PhyTopo::ConnInterface::GetLinkProtocols() const { return linkProtocols; }
95 :
96 487 : std::string PhyTopo::ConnInterface::Describe() const
97 : {
98 487 : std::string portsStr;
99 717 : for (auto it = ports.begin(); it != ports.end(); ++it) {
100 230 : if (it != ports.begin()) {
101 32 : portsStr += ",";
102 : }
103 230 : portsStr += *it;
104 : }
105 487 : std::string protocolStr;
106 974 : for (auto it = linkProtocols.begin(); it != linkProtocols.end(); ++it) {
107 487 : if (!protocolStr.empty()) {
108 0 : protocolStr += ", ";
109 : }
110 487 : protocolStr += it->Describe();
111 : }
112 :
113 : return StringFormat(
114 974 : "ConnInterface[ports={%s}, pos=%s, protocols={%s}, linkType=%s]", portsStr.c_str(), pos.Describe().c_str(),
115 1948 : protocolStr.c_str(), linkType.Describe().c_str());
116 487 : }
117 :
118 444 : bool PhyTopo::ConnInterface::operator==(const ConnInterface& rhs) const
119 : {
120 444 : return ports == rhs.ports && pos == rhs.pos && linkType == rhs.linkType && linkProtocols == rhs.linkProtocols;
121 : }
122 :
123 1 : bool PhyTopo::ConnInterface::operator!=(const ConnInterface& rhs) const { return !(rhs == *this); }
124 :
125 99 : PhyTopo::Node::Node(const PhyTopo::Node::NodeType inputType) : type(inputType) {}
126 :
127 26 : PhyTopo::Node::NodeType PhyTopo::Node::GetType() const { return type; }
128 :
129 336 : void PhyTopo::Node::AddConnInterface(const std::shared_ptr<PhyTopo::ConnInterface>& interface)
130 : {
131 601 : for (const auto& iface : interfaces) {
132 442 : if (*iface == *interface) {
133 415 : HCCL_WARNING("[PhyTopo][Node][AddConnInterface] %s has existed.", interface->Describe().c_str());
134 177 : return;
135 : }
136 : }
137 159 : interfaces.emplace_back(interface);
138 : }
139 :
140 0 : PhyTopo::Node::IfaceIterator PhyTopo::Node::IterIfaces() const { return PhyTopo::Node::IfaceIterator(interfaces); }
141 :
142 0 : std::string PhyTopo::Node::Describe() const { return "PhyTopo::Node[]"; }
143 :
144 57 : PhyTopo::Peer::Peer(const LocalId localId) : Node(PhyTopo::Node::NodeType::PEER), localId(localId) {}
145 :
146 2 : LocalId PhyTopo::Peer::GetLocalId() const { return localId; }
147 :
148 542 : NodeId PhyTopo::Peer::GetId(const LocalId localId) { return static_cast<NodeId>(localId); }
149 :
150 242 : std::string PhyTopo::Peer::Describe() const { return StringFormat("PhyTopo::Peer[localId=%u]", localId); }
151 :
152 17 : PhyTopo::Fabric::Fabric() : Node(PhyTopo::Node::NodeType::FABRIC) {}
153 :
154 : constexpr s32 FABRIC_ID_OFFSET = 32;
155 241 : NodeId PhyTopo::Fabric::GetId()
156 : {
157 241 : NodeId res = static_cast<NodeId>(0);
158 241 : res |= (1ULL << FABRIC_ID_OFFSET);
159 241 : return res;
160 : }
161 :
162 126 : std::string PhyTopo::Fabric::Describe() const { return StringFormat("PhyTopo::Fabric[NodeId=%llu]", GetId()); }
163 :
164 179 : PhyTopo::Link::Link(
165 : std::shared_ptr<PhyTopo::Node> inputSource, std::shared_ptr<PhyTopo::Node> inputTarget,
166 179 : const LinkAttributes& properties, const TopoType inputTopoType, const u32 inputTopoInstId)
167 179 : : sourceIface(nullptr),
168 179 : targetIface(nullptr),
169 179 : source(inputSource),
170 179 : target(inputTarget),
171 179 : linkProtocols(properties.protocols),
172 179 : linkType(properties.linktype),
173 179 : direction(LinkDirection::BOTH),
174 179 : topoType(inputTopoType),
175 179 : topoInstId(inputTopoInstId),
176 179 : hop{1}
177 179 : {}
178 :
179 168 : void PhyTopo::Link::SetSourceIface(std::shared_ptr<PhyTopo::ConnInterface> inputSourceIface)
180 : {
181 168 : sourceIface = inputSourceIface;
182 168 : }
183 :
184 170 : void PhyTopo::Link::SetTargetIface(std::shared_ptr<PhyTopo::ConnInterface> inputTargetIface)
185 : {
186 170 : targetIface = inputTargetIface;
187 170 : }
188 :
189 1 : LinkType PhyTopo::Link::GetType() const { return linkType; }
190 :
191 375 : std::set<LinkProtocol> PhyTopo::Link::GetLinkProtocols() const { return linkProtocols; }
192 :
193 1 : LinkDirection PhyTopo::Link::GetLinkDirection() const { return direction; }
194 :
195 371 : TopoType PhyTopo::Link::GetTopoType() const { return topoType; }
196 :
197 387 : u32 PhyTopo::Link::GetTopoInstId() const { return topoInstId; }
198 :
199 1 : u32 PhyTopo::Link::GetHop() const { return hop; }
200 :
201 347 : std::shared_ptr<PhyTopo::ConnInterface> PhyTopo::Link::GetSourceIFace() { return sourceIface; }
202 :
203 96 : std::shared_ptr<PhyTopo::ConnInterface> PhyTopo::Link::GetTargetIFace() { return targetIface; }
204 :
205 9 : std::shared_ptr<PhyTopo::Node> PhyTopo::Link::GetSourceNode() { return source; }
206 :
207 9 : std::shared_ptr<PhyTopo::Node> PhyTopo::Link::GetTargetNode() { return target; }
208 :
209 155 : std::string PhyTopo::Link::Describe() const
210 : {
211 155 : std::stringstream iFace;
212 155 : if (sourceIface != nullptr) {
213 155 : iFace << ", sourceIface=" << sourceIface->Describe();
214 : }
215 155 : if (targetIface != nullptr) {
216 155 : iFace << ", targetIface=" << targetIface->Describe();
217 : }
218 :
219 : // 将 linkProtocol 转换为字符串
220 155 : std::string protocolStr;
221 310 : for (auto it = linkProtocols.begin(); it != linkProtocols.end(); ++it) {
222 155 : if (!protocolStr.empty()) {
223 0 : protocolStr += ", ";
224 : }
225 155 : protocolStr += it->Describe();
226 : }
227 :
228 : return StringFormat(
229 : "PhyTopo::Link[type=%s, protocol=%s, source=%s, target=%s%s, topoInstId=%u, topoType=%d]",
230 620 : linkType.Describe().c_str(), protocolStr.c_str(), source->Describe().c_str(), target->Describe().c_str(),
231 930 : iFace.str().c_str(), topoInstId, topoType);
232 155 : }
233 : } // namespace Hccl
|