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 "ccu_rep_context.h"
12 :
13 : #include "exception_util.h"
14 : #include "ccu_api_exception.h"
15 : #include "ccu_rep_assign.h"
16 : #include "const_val.h"
17 : namespace Hccl {
18 : namespace CcuRep {
19 :
20 65 : CcuRepContext::CcuRepContext()
21 : {
22 65 : mainBlock = std::make_shared<CcuRep::CcuRepBlock>();
23 65 : activeBlock = mainBlock;
24 65 : }
25 :
26 73 : CcuRepContext::~CcuRepContext()
27 : {
28 73 : }
29 :
30 5357 : std::shared_ptr<CcuRep::CcuRepBlock> CcuRepContext::CurrentBlock()
31 : {
32 5357 : if (activeBlock == nullptr) {
33 0 : THROW<CcuApiException>("Invalid ActiveBlock");
34 : }
35 5357 : return activeBlock;
36 : }
37 :
38 87 : void CcuRepContext::SetCurrentBlock(std::shared_ptr<CcuRep::CcuRepBlock> repBlock)
39 : {
40 87 : activeBlock = repBlock;
41 87 : }
42 :
43 2859 : void CcuRepContext::CollectProfilingReps(std::shared_ptr<CcuRep::CcuRepBase> rep)
44 : {
45 2859 : if (rep->Type() == CcuRepType::ASSIGN) {
46 638 : auto assignRep = dynamic_cast<CcuRepAssign *>(rep.get());
47 638 : if (assignRep->subType == AssignSubType::VAR_TO_VAR) {
48 257 : lgProfilingInfo.assignProfilingReps.push_back(rep);
49 : }
50 4442 : } else if (CurrentBlock()->Type() != CcuRep::CcuRepType::LOOP_BLOCK
51 6184 : && (rep->Type() == CcuRepType::LOC_WAIT_SEM || rep->Type() == CcuRepType::REM_WAIT_SEM
52 1742 : || rep->Type() == CcuRepType::REM_WAIT_GROUP)) {
53 134 : waitCkeProfilingReps.push_back(rep);
54 2087 : } else if (rep->Type() == CcuRepType::LOOPGROUP) {
55 38 : allLgProfilingReps.push_back(rep);
56 : }
57 2859 : }
58 :
59 2859 : void CcuRepContext::Append(std::shared_ptr<CcuRep::CcuRepBase> rep)
60 : {
61 2859 : CollectProfilingReps(rep);
62 2859 : CurrentBlock()->Append(rep);
63 2859 : }
64 :
65 741 : const std::vector<std::shared_ptr<CcuRep::CcuRepBase>> &CcuRepContext::GetRepSequence()
66 : {
67 741 : return mainBlock->GetReps();
68 : }
69 :
70 1 : std::shared_ptr<CcuRep::CcuRepBase> CcuRepContext::GetRepByInstrId(uint16_t instrId)
71 : {
72 1 : for (const auto& rep : GetRepSequence()) {
73 1 : const uint16_t instrCount = rep->InstrCount();
74 1 : if (instrCount == 0) {
75 0 : continue;
76 : }
77 1 : const uint16_t startId = rep->StartInstrId();
78 1 : const uint16_t endId = startId + instrCount - 1;
79 1 : if (instrId >= startId && instrId <= endId) {
80 1 : return rep;
81 : }
82 : }
83 0 : return nullptr;
84 : }
85 :
86 13 : void CcuRepContext::DumpReprestation()
87 : {
88 39 : HCCL_INFO("Rep Count: %lu", GetRepSequence().size());
89 350 : for (uint32_t index = 0; index < GetRepSequence().size(); index++) {
90 1011 : HCCL_INFO("index[%u]: %s", index, GetRepSequence()[index]->Describe().c_str());
91 : }
92 13 : }
93 :
94 51 : void CcuRepContext::SetDieId(uint32_t dieId)
95 : {
96 51 : this->dieId = dieId;
97 51 : }
98 :
99 2461 : uint32_t CcuRepContext::GetDieId() const
100 : {
101 2461 : return dieId;
102 : }
103 :
104 26 : void CcuRepContext::SetMissionId(uint32_t missionId)
105 : {
106 26 : if (this->missionId == INVALID_U32) {
107 26 : this->missionId = missionId;
108 : }
109 26 : }
110 :
111 176 : uint32_t CcuRepContext::GetMissionId() const
112 : {
113 176 : return missionId;
114 : }
115 :
116 7 : void CcuRepContext::SetMissionKey(uint32_t missionKey)
117 : {
118 7 : this->missionKey = missionKey;
119 7 : }
120 :
121 18 : uint32_t CcuRepContext::GetMissionKey() const
122 : {
123 18 : return missionKey;
124 : }
125 :
126 22 : std::vector<CcuProfilingInfo> &CcuRepContext::GetProfilingInfo()
127 : {
128 22 : return profilingInfo;
129 : }
130 :
131 192 : const std::vector<std::shared_ptr<CcuRepBase>> &CcuRepContext::GetWaiteCkeProfilingReps() const
132 : {
133 192 : return waitCkeProfilingReps;
134 : }
135 :
136 232 : LoopGroupProfilingInfo &CcuRepContext::GetLGProfilingInfo()
137 : {
138 232 : return lgProfilingInfo;
139 : }
140 :
141 43 : void CcuRepContext::AddSqeProfiling(const CcuCtxArg &arg)
142 : {
143 43 : profilingInfo.clear();
144 : // 生成SQE粒度profiling信息
145 43 : ccuProfilingInfoCache.type = CcuProfilinType::CCU_TASK_PROFILING;
146 43 : ccuProfilingInfoCache.name = arg.GetCtxSignature().Describe();
147 43 : ccuProfilingInfoCache.dieId = GetDieId();
148 :
149 43 : profilingInfo.push_back(ccuProfilingInfoCache);
150 43 : }
151 :
152 45 : void CcuRepContext::AddProfiling(const std::string &name, uint32_t mask)
153 : {
154 45 : ccuProfilingInfoCache.type = CcuProfilinType::CCU_WAITCKE_PROFILING;
155 45 : ccuProfilingInfoCache.name = name;
156 45 : ccuProfilingInfoCache.ckeId = INVALID_CKE_ID;
157 45 : ccuProfilingInfoCache.mask = mask;
158 45 : (void)memset_s(ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID, sizeof(ccuProfilingInfoCache.channelId));
159 :
160 45 : profilingInfo.push_back(ccuProfilingInfoCache);
161 45 : }
162 :
163 33 : void CcuRepContext::AddProfiling(const CcuTransport &transport, const std::string &name, uint32_t signalIndex, uint32_t mask)
164 : {
165 33 : ccuProfilingInfoCache.type = CcuProfilinType::CCU_WAITCKE_PROFILING;
166 33 : ccuProfilingInfoCache.name = name;
167 33 : ccuProfilingInfoCache.ckeId = transport.GetLocCntCkeByIndex(signalIndex);
168 33 : ccuProfilingInfoCache.mask = mask;
169 33 : (void)memset_s(ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID, sizeof(ccuProfilingInfoCache.channelId));
170 33 : ccuProfilingInfoCache.channelId[0] = transport.GetChannelId();
171 :
172 33 : profilingInfo.push_back(ccuProfilingInfoCache);
173 33 : }
174 :
175 56 : void CcuRepContext::AddProfiling(const CcuTransportGroup &transportGroup, const std::string &name, uint32_t signalIndex, uint32_t mask)
176 : {
177 56 : ccuProfilingInfoCache.type = CcuProfilinType::CCU_WAITCKE_PROFILING;
178 56 : ccuProfilingInfoCache.name = name;
179 56 : u32 cntCkeId = 0;
180 56 : HcclResult ret = transportGroup.GetCntCkeId(signalIndex, cntCkeId);
181 56 : if (ret != HcclResult::HCCL_SUCCESS) {
182 : string msg = StringFormat("[AddProfiling]rt get cntCkeId failed. "
183 0 : "signalIndex[%u], cntCkeId[%u], return[%d].", signalIndex, cntCkeId, ret);
184 0 : MACRO_THROW(CcuApiException, msg);
185 0 : }
186 56 : ccuProfilingInfoCache.ckeId = cntCkeId;
187 56 : ccuProfilingInfoCache.mask = mask;
188 :
189 56 : (void)memset_s(ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID, sizeof(ccuProfilingInfoCache.channelId));
190 56 : auto &transports = transportGroup.GetTransports();
191 400 : for (u32 i = 0; i < transports.size(); i++) {
192 344 : ccuProfilingInfoCache.channelId[i] = transports[i]->GetChannelId();
193 : }
194 :
195 56 : profilingInfo.push_back(ccuProfilingInfoCache);
196 56 : }
197 :
198 30 : void CcuRepContext::AddProfiling(const std::vector<CcuTransport*> &transports)
199 : {
200 30 : ccuProfilingInfoCache.type = CcuProfilinType::CCU_LOOPGROUP_PROFILING;
201 30 : ccuProfilingInfoCache.name = "GroupBroadcast";
202 30 : ccuProfilingInfoCache.reduceOpType = 0xFF; // 0xFF 无效值
203 30 : ccuProfilingInfoCache.inputDataType = 0xFF; // 0xFF 无效值
204 30 : ccuProfilingInfoCache.outputDataType = 0xFF; // 0xFF 无效值
205 30 : ccuProfilingInfoCache.missionId = GetMissionId();
206 :
207 30 : (void)memset_s(ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID, sizeof(ccuProfilingInfoCache.channelId));
208 240 : for (u32 i = 0; i < transports.size(); i++) {
209 210 : ccuProfilingInfoCache.channelId[i] = transports[i]->GetChannelId();
210 : }
211 :
212 30 : lgProfilingInfo.ccuProfilingInfos.push_back(ccuProfilingInfoCache);
213 30 : lgProfilingInfo.lgProfilingReps.push_back(allLgProfilingReps.back());
214 30 : }
215 :
216 4 : void CcuRepContext::AddProfiling(const std::vector<CcuTransport *> &transports, DataType dataType,
217 : DataType outputDataType, ReduceOp opType)
218 : {
219 4 : ccuProfilingInfoCache.type = CcuProfilinType::CCU_LOOPGROUP_PROFILING;
220 4 : ccuProfilingInfoCache.name = "GroupReduce";
221 4 : ccuProfilingInfoCache.reduceOpType = opType;
222 4 : ccuProfilingInfoCache.inputDataType = dataType;
223 4 : ccuProfilingInfoCache.outputDataType = outputDataType;
224 4 : ccuProfilingInfoCache.missionId = GetMissionId();
225 :
226 4 : (void)memset_s(ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID, sizeof(ccuProfilingInfoCache.channelId));
227 32 : for (u32 i = 0; i < transports.size(); i++) {
228 28 : ccuProfilingInfoCache.channelId[i] = transports[i]->GetChannelId();
229 : }
230 :
231 4 : lgProfilingInfo.ccuProfilingInfos.push_back(ccuProfilingInfoCache);
232 4 : lgProfilingInfo.lgProfilingReps.push_back(allLgProfilingReps.back());
233 4 : }
234 :
235 345 : void CcuRepContext::SetDependencyInfo(uint32_t id, uint32_t mask, std::shared_ptr<CcuRepBase> rep)
236 : {
237 345 : if (mask == 0 || (mask & (mask - 1)) != 0) {
238 0 : THROW<CcuApiException>("Invalid Mask[%u]", mask);
239 : }
240 : // 查找 id 是否已存在于外层 map 中
241 345 : auto idIt = depInfo.find(id);
242 345 : if (idIt == depInfo.end()) {
243 : // 如果不存在,插入一个新的内层 unordered_map
244 51 : idIt = depInfo.emplace(id, std::unordered_map<uint32_t, std::vector<std::shared_ptr<CcuRepBase>>>()).first;
245 : }
246 :
247 : // 现在查找 mask 是否存在于内层 map 中
248 345 : auto maskIt = idIt->second.find(mask);
249 345 : if (maskIt == idIt->second.end()) {
250 : // 如果不存在,插入一个新的 vector
251 297 : maskIt = idIt->second.emplace(mask, std::vector<std::shared_ptr<CcuRepBase>>()).first;
252 : }
253 :
254 : // 将 rep 添加到 vector 中
255 345 : maskIt->second.push_back(rep);
256 345 : }
257 :
258 45 : std::unordered_map<uint32_t, std::vector<std::shared_ptr<CcuRepBase>>> CcuRepContext::GetDependencyInfo(uint32_t id) {
259 : // 查找给定 id 是否存在于 depInfo 中
260 45 : auto it = depInfo.find(id);
261 : // 如果找到 id,返回与之关联的内层 unordered_map
262 45 : if (it != depInfo.end()) {
263 4 : return it->second;
264 : }
265 : // 如果未找到 id,返回一个空的 unordered_map
266 41 : return std::unordered_map<uint32_t, std::vector<std::shared_ptr<CcuRepBase>>>();
267 : }
268 :
269 45 : void CcuRepContext::ClearDependencyInfo() {
270 45 : depInfo.clear();
271 45 : }
272 :
273 : }; // namespace CcuRep
274 : }; // namespace Hccl
|