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 "primitive.h"
12 : #include "null_ptr_exception.h"
13 : #include "prim_queue.h"
14 :
15 : #include <set>
16 :
17 : namespace Hccl {
18 6 : PrimPostTo::PrimPostTo(const weak_ptr<PrimQueue> queue, NotifyType notifyType, u32 topicId)
19 6 : : Primitive(PrimType::POST_TO), queue(queue), notifyType(notifyType), topicId(topicId)
20 : {
21 6 : if (queue.lock().get() == nullptr) {
22 1 : THROW<NullPtrException>("queue");
23 : }
24 8 : }
25 :
26 4 : void PrimPostTo::SetParent(const weak_ptr<PrimQueue> &que)
27 : {
28 4 : if (que.lock().get() == nullptr) {
29 1 : THROW<NullPtrException>("parent");
30 : }
31 3 : if (GetQid() == que.lock()->GetId()) {
32 1 : THROW<InvalidParamsException>("parent Qid is equal to queue Qid");
33 : }
34 2 : parent = que;
35 2 : }
36 :
37 1 : std::string PrimPostTo::Describe() const
38 : {
39 1 : if (parent.lock().get() == nullptr) {
40 0 : return StringFormat("%s Qid[%u] NotifyType[%s]", type.Describe().c_str(), queue.lock()->GetId(),
41 0 : notifyType.Describe().c_str());
42 : } else {
43 2 : return StringFormat("%s parent[%u] postTo Qid[%u] NotifyType[%s]", type.Describe().c_str(),
44 3 : parent.lock()->GetId(), queue.lock()->GetId(), notifyType.Describe().c_str());
45 : }
46 : }
47 :
48 4 : QId PrimPostTo::GetQid() const
49 : {
50 4 : return queue.lock()->GetId();
51 : }
52 :
53 2 : QId PrimPostTo::GetParentQid() const
54 : {
55 2 : if (parent.lock().get() == nullptr) {
56 1 : return INVALID_PRIM_QID;
57 : } else {
58 1 : return parent.lock()->GetId();
59 : }
60 : }
61 :
62 6 : PrimWaitFrom::PrimWaitFrom(const weak_ptr<PrimQueue> queue, u32 topicId)
63 6 : : Primitive(PrimType::WAIT_FROM), queue(queue), topicId(topicId)
64 : {
65 6 : if (queue.lock().get() == nullptr) {
66 1 : THROW<NullPtrException>("queue");
67 : }
68 8 : }
69 :
70 1 : std::string PrimWaitFrom::Describe() const
71 : {
72 1 : if (parent.lock().get() == nullptr) {
73 0 : return StringFormat("%s Qid[%u]", type.Describe().c_str(), queue.lock()->GetId());
74 : } else {
75 3 : return StringFormat("%s parent[%u] waitFrom Qid[%u]", type.Describe().c_str(), parent.lock()->GetId(),
76 4 : queue.lock()->GetId());
77 : }
78 : }
79 :
80 4 : void PrimWaitFrom::SetParent(const weak_ptr<PrimQueue> &que)
81 : {
82 4 : if (que.lock().get() == nullptr) {
83 1 : THROW<NullPtrException>("parent");
84 : }
85 3 : if (GetQid() == que.lock()->GetId()) {
86 1 : THROW<InvalidParamsException>("parent Qid is equal to queue Qid");
87 : }
88 2 : parent = que;
89 2 : }
90 :
91 4 : QId PrimWaitFrom::GetQid() const
92 : {
93 4 : return queue.lock()->GetId();
94 : }
95 :
96 2 : QId PrimWaitFrom::GetParentQid() const
97 : {
98 2 : if (parent.lock().get() == nullptr) {
99 1 : return INVALID_PRIM_QID;
100 : } else {
101 1 : return parent.lock()->GetId();
102 : }
103 : }
104 :
105 4 : PrimWaitGroup::PrimWaitGroup(u32 topicId) : Primitive(PrimType::WAIT_GROUP), topicId(topicId)
106 : {
107 4 : }
108 :
109 2 : void PrimWaitGroup::Append(const weak_ptr<PrimQueue> queue)
110 : {
111 2 : if (queue.lock().get() == nullptr) {
112 0 : THROW<NullPtrException>("queue");
113 : }
114 2 : qids.push_back(queue.lock()->GetId());
115 2 : }
116 :
117 2 : std::string PrimWaitGroup::Describe() const
118 : {
119 2 : std::string qidsStr;
120 2 : for (u32 idx = 0; idx < qids.size(); idx++) {
121 0 : qidsStr += StringFormat("qid[%u], ", qids[idx]);
122 : }
123 2 : if (!qidsStr.empty()) {
124 0 : u32 redundantLen = 2;
125 0 : qidsStr = qidsStr.substr(0, qidsStr.size() - redundantLen);
126 : }
127 :
128 2 : if (parent.lock().get() == nullptr) {
129 2 : return StringFormat("%s: qidNum[%u] qids[%s]", type.Describe().c_str(), qids.size(), qidsStr.c_str());
130 : } else {
131 3 : return StringFormat("%s: parent[%u] qidNum[%u] qids[%s]", type.Describe().c_str(), parent.lock()->GetId(),
132 3 : qids.size(), qidsStr.c_str());
133 : }
134 2 : }
135 :
136 4 : void PrimWaitGroup::SetParent(const weak_ptr<PrimQueue> &que)
137 : {
138 4 : if (que.lock().get() == nullptr) {
139 0 : THROW<NullPtrException>("parent");
140 : }
141 :
142 4 : QId parentQid = que.lock()->GetId();
143 6 : for (auto qid = qids.begin(); qid != qids.end(); ++qid) {
144 3 : if (*qid == parentQid) {
145 1 : THROW<InvalidParamsException>("parent Qid is equal to one of queue Qids");
146 : }
147 : }
148 :
149 3 : parent = que;
150 3 : }
151 :
152 3 : QId PrimWaitGroup::GetParentQid() const
153 : {
154 3 : if (parent.lock().get() == nullptr) {
155 1 : return INVALID_PRIM_QID;
156 : } else {
157 2 : return parent.lock()->GetId();
158 : }
159 : }
160 :
161 7 : PrimLocalCopy::PrimLocalCopy(const DataSlice &srcSlice, const DataSlice &dstSlice)
162 7 : : Primitive(PrimType::LOCAL_COPY), srcSlice(srcSlice), dstSlice(dstSlice)
163 : {
164 7 : if (srcSlice.GetSize() != dstSlice.GetSize()) {
165 1 : THROW<InvalidParamsException>("The size of dstSlice is not equal to srcSlice");
166 : }
167 6 : if (srcSlice.GetType() == dstSlice.GetType()) {
168 2 : u64 srcStart = srcSlice.GetOffset();
169 2 : u64 srcEnd = srcStart + srcSlice.GetSize();
170 2 : u64 dstStart = dstSlice.GetOffset();
171 2 : u64 dstEnd = dstStart + dstSlice.GetSize();
172 2 : if (srcStart >= dstStart && srcStart < dstEnd) {
173 0 : THROW<InvalidParamsException>("The addresses of dstSlice and srcSlice overlap");
174 : }
175 2 : if (dstStart >= srcStart && dstStart < srcEnd) {
176 1 : THROW<InvalidParamsException>("The addresses of dstSlice and srcSlice overlap");
177 : }
178 : }
179 7 : }
180 :
181 4 : std::string PrimLocalCopy::Describe() const
182 : {
183 12 : return StringFormat("%s: src[%s], dst[%s]", type.Describe().c_str(), srcSlice.Describe().c_str(),
184 16 : dstSlice.Describe().c_str());
185 : }
186 :
187 0 : PrimLocalReduce::PrimLocalReduce(const DataSlice &srcSlice, const DataSlice &dstSlice, DataType dataType,
188 0 : ReduceOp reduceOp)
189 0 : : Primitive(PrimType::LOCAL_REDUCE), srcSlice(srcSlice), dstSlice(dstSlice), dataType(dataType), reduceOp(reduceOp)
190 : {
191 0 : if (srcSlice.GetSize() != dstSlice.GetSize()) {
192 0 : THROW<InvalidParamsException>("The size of dstSlice is not equal to srcSlice");
193 : }
194 0 : if (srcSlice.GetType() == dstSlice.GetType()) {
195 0 : u64 srcStart = srcSlice.GetOffset();
196 0 : u64 srcEnd = srcStart + srcSlice.GetSize();
197 0 : u64 dstStart = dstSlice.GetOffset();
198 0 : u64 dstEnd = dstStart + dstSlice.GetSize();
199 0 : if (srcStart >= dstStart && srcStart < dstEnd) {
200 0 : THROW<InvalidParamsException>("The addresses of dstSlice and srcSlice overlap");
201 : }
202 0 : if (dstStart >= srcStart && dstStart < srcEnd) {
203 0 : THROW<InvalidParamsException>("The addresses of dstSlice and srcSlice overlap");
204 : }
205 : }
206 0 : }
207 :
208 0 : std::string PrimLocalReduce::Describe() const
209 : {
210 0 : return StringFormat("%s: %s, %s, src[%s], dst[%s]", type.Describe().c_str(), reduceOp.Describe().c_str(),
211 0 : dataType.Describe().c_str(), srcSlice.Describe().c_str(), dstSlice.Describe().c_str());
212 : }
213 :
214 28 : PrimSend::PrimSend(RankId remoteRank, const LinkData &link, const DataSlice &localSlice, const DataSlice &remoteSlice,
215 28 : DmaMode dmaMode)
216 28 : : Primitive(PrimType::SEND), remoteRank(remoteRank), link(link), dmaMode(dmaMode)
217 : {
218 28 : if (localSlice.GetSize() != remoteSlice.GetSize()) {
219 0 : THROW<InvalidParamsException>("The size of remoteSlice is not equal to localSlice");
220 : }
221 28 : localSlices.push_back(localSlice);
222 28 : remoteSlices.push_back(remoteSlice);
223 28 : }
224 :
225 10 : std::string PrimSend::Describe() const
226 : {
227 20 : string desc = StringFormat("%s: remoteRank[%u], %s, %s, sliceNUm[%u]", type.Describe().c_str(), remoteRank,
228 30 : link.Describe().c_str(), dmaMode.Describe().c_str(), localSlices.size());
229 23 : for (u32 idx = 0; idx < localSlices.size(); idx++) {
230 26 : desc += StringFormat(" sliceIdx[%d]: local%s, remote%s;", idx, localSlices[idx].Describe().c_str(),
231 39 : remoteSlices[idx].Describe().c_str());
232 : }
233 10 : return desc;
234 0 : }
235 :
236 3 : void PrimSend::Append(const DataSlice &localSlice, const DataSlice &remoteSlice)
237 : {
238 3 : if (localSlice.GetSize() != remoteSlice.GetSize()) {
239 0 : THROW<InvalidParamsException>("The size of remoteSlice is not equal to localSlice");
240 : }
241 3 : localSlices.push_back(localSlice);
242 3 : remoteSlices.push_back(remoteSlice);
243 3 : }
244 :
245 30 : PrimRecv::PrimRecv(RankId remoteRank, const LinkData &link, const DataSlice &localSlice, const DataSlice &remoteSlice,
246 30 : DmaMode dmaMode)
247 30 : : Primitive(PrimType::RECV), remoteRank(remoteRank), link(link), dmaMode(dmaMode)
248 : {
249 30 : if (localSlice.GetSize() != remoteSlice.GetSize()) {
250 1 : THROW<InvalidParamsException>("The size of remoteSlice is not equal to localSlice");
251 : }
252 29 : localSlices.push_back(localSlice);
253 29 : remoteSlices.push_back(remoteSlice);
254 32 : }
255 :
256 9 : std::string PrimRecv::Describe() const
257 : {
258 18 : string desc = StringFormat("%s: remoteRank[%u], %s, %s, sliceNUm[%u]", type.Describe().c_str(), remoteRank,
259 27 : link.Describe().c_str(), dmaMode.Describe().c_str(), localSlices.size());
260 21 : for (u32 idx = 0; idx < localSlices.size(); idx++) {
261 24 : desc += StringFormat(" sliceIdx[%d]: local%s, remote%s;", idx, localSlices[idx].Describe().c_str(),
262 36 : remoteSlices[idx].Describe().c_str());
263 : }
264 9 : return desc;
265 0 : }
266 :
267 4 : void PrimRecv::Append(const DataSlice &localSlice, const DataSlice &remoteSlice)
268 : {
269 4 : if (localSlice.GetSize() != remoteSlice.GetSize()) {
270 1 : THROW<InvalidParamsException>("The size of remoteSlice is not equal to localSlice");
271 : }
272 3 : localSlices.push_back(localSlice);
273 3 : remoteSlices.push_back(remoteSlice);
274 3 : }
275 :
276 11 : PrimSendReduce::PrimSendReduce(RankId remoteRank, const LinkData &link, const DataSlice &localSlice,
277 : const DataSlice &remoteSrcSlice, const DataSlice &remoteDstSlice,
278 11 : const DataType &dataType, const ReduceOp &reduceOp, DmaMode dmaMode)
279 22 : : Primitive(PrimType::SEND_REDUCE), remoteRank(remoteRank), link(link), dataType(dataType), reduceOp(reduceOp),
280 11 : dmaMode(dmaMode)
281 : {
282 11 : if (localSlice.GetSize() != remoteSrcSlice.GetSize() || remoteSrcSlice.GetSize() != remoteDstSlice.GetSize()) {
283 0 : THROW<InvalidParamsException>("The size of localSlice, remoteSrcSlice, and remoteDstSlice are not equal");
284 : }
285 11 : localSlices.push_back(localSlice);
286 11 : remoteSrcSlices.push_back(remoteSrcSlice);
287 11 : remoteDstSlices.push_back(remoteDstSlice);
288 11 : }
289 :
290 8 : std::string PrimSendReduce::Describe() const
291 : {
292 16 : string desc = StringFormat("%s: remoteRank[%u], %s, %s, sliceNum[%u]", type.Describe().c_str(), remoteRank,
293 24 : link.Describe().c_str(), dmaMode.Describe().c_str(), localSlices.size());
294 18 : for (u32 idx = 0; idx < localSlices.size(); idx++) {
295 40 : desc += StringFormat(" sliceIdx[%d]: local%s, remoteSrc%s, remoteDst%s;", idx,
296 30 : localSlices[idx].Describe().c_str(), remoteSrcSlices[idx].Describe().c_str(),
297 30 : remoteDstSlices[idx].Describe().c_str());
298 : }
299 8 : return desc;
300 0 : }
301 :
302 2 : void PrimSendReduce::Append(const DataSlice &localSlice, const DataSlice &remoteSrcSlice,
303 : const DataSlice &remoteDstSlice)
304 : {
305 2 : if (localSlice.GetSize() != remoteSrcSlice.GetSize() || remoteSrcSlice.GetSize() != remoteDstSlice.GetSize()) {
306 0 : THROW<InvalidParamsException>("The size of localSlice, remoteSrcSlice, and remoteDstSlice are not equal");
307 : }
308 2 : localSlices.push_back(localSlice);
309 2 : remoteSrcSlices.push_back(remoteSrcSlice);
310 2 : remoteDstSlices.push_back(remoteDstSlice);
311 2 : }
312 :
313 11 : PrimRecvReduce::PrimRecvReduce(RankId remoteRank, const LinkData &link, const DataSlice &remoteSlice,
314 : const DataSlice &localSrcSlice, const DataSlice &localDstSlice, const DataType &dataType,
315 11 : const ReduceOp &reduceOp, DmaMode dmaMode)
316 22 : : Primitive(PrimType::RECV_REDUCE), remoteRank(remoteRank), link(link), dataType(dataType), reduceOp(reduceOp),
317 11 : dmaMode(dmaMode)
318 : {
319 11 : if (remoteSlice.GetSize() != localSrcSlice.GetSize() || localSrcSlice.GetSize() != localDstSlice.GetSize()) {
320 0 : THROW<InvalidParamsException>("The size of remoteSlice, localSrcSlice, and localDstSlice are not equal");
321 : }
322 11 : remoteSlices.push_back(remoteSlice);
323 11 : localSrcSlices.push_back(localSrcSlice);
324 11 : localDstSlices.push_back(localDstSlice);
325 11 : }
326 :
327 8 : std::string PrimRecvReduce::Describe() const
328 : {
329 16 : string desc = StringFormat("%s: remoteRank[%u], %s, %s, sliceNum[%u]", type.Describe().c_str(), remoteRank,
330 24 : link.Describe().c_str(), dmaMode.Describe().c_str(), remoteSlices.size());
331 20 : for (u32 idx = 0; idx < remoteSlices.size(); idx++) {
332 48 : desc += StringFormat(" sliceIdx[%d]: local%s, localSrc%s, localDst%s;", idx,
333 36 : remoteSlices[idx].Describe().c_str(), localSrcSlices[idx].Describe().c_str(),
334 36 : localDstSlices[idx].Describe().c_str());
335 : }
336 8 : return desc;
337 0 : }
338 :
339 4 : void PrimRecvReduce::Append(const DataSlice &remoteSlice, const DataSlice &localSrcSlice,
340 : const DataSlice &localDstSlice)
341 : {
342 4 : if (remoteSlice.GetSize() != localSrcSlice.GetSize() || localSrcSlice.GetSize() != localDstSlice.GetSize()) {
343 0 : THROW<InvalidParamsException>("The size of remoteSlice, localSrcSlice, and localDstSlice are not equal");
344 : }
345 4 : remoteSlices.push_back(remoteSlice);
346 4 : localSrcSlices.push_back(localSrcSlice);
347 4 : localDstSlices.push_back(localDstSlice);
348 4 : }
349 :
350 0 : std::string PrimGroup::Describe() const
351 : {
352 0 : string desc = StringFormat("%s: primSize[%u]", type.Describe().c_str(), prims.size());
353 0 : auto primIter = prims.begin();
354 0 : for (; primIter != prims.end(); primIter++) {
355 0 : desc += (*primIter)->Describe() + "\n";
356 : }
357 0 : return desc;
358 0 : }
359 :
360 11 : void PrimGroup::CheckValid() const
361 : {
362 11 : std::set<LinkData> sendLink;
363 11 : std::set<LinkData> recvLink;
364 29 : for (auto iter = Iter(); iter.HasNext(); ++iter) {
365 23 : if (iter->GetType() == PrimType::SEND) {
366 7 : PrimSend *primSend = dynamic_cast<PrimSend *>(const_cast<Primitive *>(&(*iter)));
367 7 : if (sendLink.count(primSend->GetLink()) > 0) {
368 1 : THROW<InvalidParamsException>("One link has two Send Prims");
369 : }
370 6 : sendLink.insert(primSend->GetLink());
371 16 : } else if (iter->GetType() == PrimType::SEND_REDUCE) {
372 4 : PrimSendReduce *primSendReduce = dynamic_cast<PrimSendReduce *>(const_cast<Primitive *>(&(*iter)));
373 4 : if (sendLink.count(primSendReduce->GetLink()) > 0) {
374 1 : THROW<InvalidParamsException>("One link has two Send Prims");
375 : }
376 3 : sendLink.insert(primSendReduce->GetLink());
377 12 : } else if (iter->GetType() == PrimType::RECV) {
378 8 : PrimRecv *primRecv = dynamic_cast<PrimRecv *>(const_cast<Primitive *>(&(*iter)));
379 8 : if (recvLink.count(primRecv->GetLink()) > 0) {
380 2 : THROW<InvalidParamsException>("One link has two Recv Prims");
381 : }
382 6 : recvLink.insert(primRecv->GetLink());
383 : } else { // when come here , the PrimType is PrimType::RECV_REDUCE
384 4 : PrimRecvReduce *primRecvReduce = dynamic_cast<PrimRecvReduce *>(const_cast<Primitive *>(&(*iter)));
385 4 : if (recvLink.count(primRecvReduce->GetLink()) > 0) {
386 1 : THROW<InvalidParamsException>("One link has two Recv Prims");
387 : }
388 3 : recvLink.insert(primRecvReduce->GetLink());
389 : }
390 11 : }
391 12 : return;
392 16 : }
393 :
394 26 : void PrimGroup::Append(unique_ptr<Primitive> prim)
395 : {
396 45 : if (prim->GetType() != PrimType::SEND && prim->GetType() != PrimType::RECV
397 45 : && prim->GetType() != PrimType::SEND_REDUCE && prim->GetType() != PrimType::RECV_REDUCE) {
398 1 : THROW<InvalidParamsException>("PrimGroup only support PrimSend or PrimRecv or "
399 : "PrimSendReduce or PrimRecvReduce");
400 : }
401 25 : prims.push_back(std::move(prim));
402 25 : return;
403 : }
404 : } // namespace Hccl
|