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