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