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_v1.h"
12 :
13 : #include "exception_util.h"
14 : #include "ccu_api_exception.h"
15 : #include "ccu_rep_assign_v1.h"
16 : #include "const_val.h"
17 :
18 : #include "hcomm_c_adpt.h" // 需优化
19 : #include "../../../endpoint_pairs/channels/ccu/ccu_urma_channel.h" // 需优化
20 : #include "ccu_dev_mgr_imp.h"
21 :
22 : namespace hcomm {
23 : namespace CcuRep {
24 :
25 204 : CcuRepContext::CcuRepContext()
26 : {
27 204 : mainBlock = std::make_shared<CcuRep::CcuRepBlock>(insGenerator);
28 204 : activeBlock = mainBlock;
29 204 : }
30 :
31 204 : CcuRepContext::~CcuRepContext() {}
32 :
33 2434 : std::shared_ptr<CcuRep::CcuRepBlock> CcuRepContext::CurrentBlock()
34 : {
35 2434 : if (activeBlock == nullptr) {
36 1 : Hccl::THROW<Hccl::CcuApiException>("Invalid ActiveBlock");
37 : }
38 2433 : return activeBlock;
39 : }
40 :
41 115 : void CcuRepContext::SetCurrentBlock(std::shared_ptr<CcuRep::CcuRepBlock> repBlock) { activeBlock = repBlock; }
42 :
43 : /**
44 : * @details:保存rep信息,后续有arg后配合补全profiling信息
45 : */
46 1257 : void CcuRepContext::CollectProfilingReps(std::shared_ptr<CcuRep::CcuRepBase> rep)
47 : {
48 1257 : if (rep->Type() == CcuRepType::ASSIGN) {
49 508 : auto assignRep = dynamic_cast<CcuRepAssign*>(rep.get());
50 508 : if (assignRep->GetSubType() == AssignSubType::VAR_TO_VAR) {
51 159 : lgProfilingInfo.assignProfilingReps.push_back(rep);
52 : }
53 749 : } else if (
54 1498 : CurrentBlock()->Type() != CcuRep::CcuRepType::LOOP_BLOCK
55 2135 : && (rep->Type() == CcuRepType::LOC_WAIT_EVENT || rep->Type() == CcuRepType::REM_WAIT_SEM
56 637 : || rep->Type() == CcuRepType::REM_WAIT_GROUP)) {
57 38 : waitCkeProfilingReps.push_back(rep);
58 711 : } else if (rep->Type() == CcuRepType::LOOPGROUP) {
59 28 : allLgProfilingReps.push_back(rep);
60 : }
61 1257 : }
62 :
63 1257 : void CcuRepContext::Append(std::shared_ptr<CcuRep::CcuRepBase> rep)
64 : {
65 1257 : CollectProfilingReps(rep);
66 1257 : CurrentBlock()->Append(rep);
67 1257 : }
68 :
69 300 : const std::vector<std::shared_ptr<CcuRep::CcuRepBase>>& CcuRepContext::GetRepSequence()
70 : {
71 300 : return mainBlock->GetReps();
72 : }
73 :
74 0 : std::shared_ptr<CcuRep::CcuRepBase> CcuRepContext::GetRepByInstrId(uint16_t instrId)
75 : {
76 0 : for (const auto& rep : GetRepSequence()) {
77 0 : CHK_PRT_RET(rep == nullptr, HCCL_ERROR("[%s]fail, rep is nullptr", __func__), nullptr);
78 0 : const uint16_t repInstrCount = rep->InstrCount();
79 0 : if (repInstrCount == 0) {
80 0 : continue;
81 : }
82 0 : const uint16_t startId = rep->StartInstrId();
83 0 : const uint16_t endId = startId + repInstrCount - 1;
84 0 : HCCL_INFO("[%s]startId[%u], endId[%u], instrId[%u]", __func__, startId, endId, instrId);
85 0 : if (instrId >= startId && instrId <= endId) {
86 0 : return rep;
87 : }
88 : }
89 0 : return nullptr;
90 : }
91 :
92 0 : void CcuRepContext::DumpReprestation()
93 : {
94 0 : HCCL_INFO("Rep Count: %lu", GetRepSequence().size());
95 0 : for (uint32_t index = 0; index < GetRepSequence().size(); index++) {
96 0 : HCCL_INFO("index[%u]: %s", index, GetRepSequence()[index]->Describe().c_str());
97 : }
98 0 : }
99 :
100 129 : void CcuRepContext::SetDieId(uint32_t dieId)
101 : {
102 129 : HCCL_INFO("set dieId[%u]", dieId);
103 129 : this->dieId = dieId;
104 129 : }
105 :
106 1453 : uint32_t CcuRepContext::GetDieId() const { return dieId; }
107 :
108 47 : void CcuRepContext::SetMissionId(uint32_t missionId)
109 : {
110 47 : if (this->missionId == Hccl::INVALID_U32) {
111 47 : this->missionId = missionId;
112 : }
113 47 : }
114 :
115 55 : uint32_t CcuRepContext::GetMissionId() const { return missionId; }
116 :
117 47 : void CcuRepContext::SetMissionKey(uint32_t missionKey) { this->missionKey = missionKey; }
118 :
119 9 : uint32_t CcuRepContext::GetMissionKey() const { return missionKey; }
120 :
121 0 : std::vector<CcuProfilingInfo>& CcuRepContext::GetProfilingInfo() { return profilingInfo; }
122 :
123 0 : const std::vector<std::shared_ptr<CcuRepBase>>& CcuRepContext::GetWaiteCkeProfilingReps() const
124 : {
125 0 : return waitCkeProfilingReps;
126 : }
127 :
128 23 : LoopGroupProfilingInfo& CcuRepContext::GetLGProfilingInfo() { return lgProfilingInfo; }
129 :
130 72 : void CcuRepContext::AddSqeProfiling(const std::string& kernelName)
131 : {
132 72 : constexpr uint32_t defaultDieId = 0; // 首次填写profiling时dieId未确定
133 : // 生成SQE粒度profiling信息
134 72 : ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_TASK_PROFILING;
135 72 : ccuProfilingInfoCache.name = kernelName.c_str();
136 72 : ccuProfilingInfoCache.dieId = defaultDieId;
137 72 : HCCL_DEBUG(
138 : "[%s]type[%d], name[%s], deafultDieId[0]", __func__, ccuProfilingInfoCache.type,
139 : ccuProfilingInfoCache.name.c_str(), ccuProfilingInfoCache.dieId);
140 72 : profilingInfo.push_back(ccuProfilingInfoCache);
141 72 : }
142 :
143 28 : int32_t CcuRepContext::AddProfiling(const std::string& name, uint32_t mask)
144 : {
145 28 : ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_WAITCKE_PROFILING;
146 28 : ccuProfilingInfoCache.name = name;
147 28 : ccuProfilingInfoCache.ckeId = INVALID_CKE_ID;
148 28 : ccuProfilingInfoCache.mask = mask;
149 28 : CHK_SAFETY_FUNC_RET(memset_s(
150 : ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID,
151 : sizeof(ccuProfilingInfoCache.channelId)));
152 :
153 28 : HCCL_INFO("[%s]name[%s], mask[%u], type[%d]", __func__, name.c_str(), mask, ccuProfilingInfoCache.type);
154 28 : profilingInfo.push_back(ccuProfilingInfoCache);
155 28 : return HCCL_SUCCESS;
156 : }
157 :
158 11 : int32_t CcuRepContext::AddProfiling(
159 : const ChannelHandle channel, const std::string& name, uint32_t signalIndex, uint32_t mask)
160 : {
161 11 : void* channelPtr{nullptr};
162 11 : CHK_RET(static_cast<HcclResult>(HcommChannelGet(channel, &channelPtr)));
163 10 : auto* channelImpl = dynamic_cast<CcuUrmaChannel*>(static_cast<Channel*>(channelPtr));
164 10 : CHK_PTR_NULL(channelImpl);
165 :
166 10 : ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_WAITCKE_PROFILING;
167 10 : ccuProfilingInfoCache.name = name;
168 10 : CHK_RET(channelImpl->GetLocCkeByIndex(signalIndex, ccuProfilingInfoCache.ckeId));
169 10 : ccuProfilingInfoCache.mask = mask;
170 10 : CHK_SAFETY_FUNC_RET(memset_s(
171 : ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID,
172 : sizeof(ccuProfilingInfoCache.channelId)));
173 10 : ccuProfilingInfoCache.channelId[0] = channelImpl->GetChannelId();
174 10 : ccuProfilingInfoCache.channelHandle[0] = channel;
175 :
176 10 : HCCL_INFO(
177 : "[%s]channelHandle[0x%llx], name[%s], signalIndex[%u], mask[%u], type[%d], ckeId[%u], channelId[%u]",
178 : __func__, channel, name.c_str(), signalIndex, mask, ccuProfilingInfoCache.type, ccuProfilingInfoCache.ckeId,
179 : ccuProfilingInfoCache.channelId[0]);
180 10 : profilingInfo.push_back(ccuProfilingInfoCache);
181 10 : return HCCL_SUCCESS;
182 : }
183 :
184 0 : int32_t CcuRepContext::AddProfiling(const ChannelHandle* channels, uint32_t channelNum)
185 : {
186 0 : CHK_PTR_NULL(channels);
187 0 : ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_LOOPGROUP_PROFILING;
188 0 : ccuProfilingInfoCache.name = "GroupBroadcast";
189 0 : ccuProfilingInfoCache.reduceOpType = 0xFF; // 0xFF 无效值
190 0 : ccuProfilingInfoCache.inputDataType = 0xFF; // 0xFF 无效值
191 0 : ccuProfilingInfoCache.outputDataType = 0xFF; // 0xFF 无效值
192 0 : ccuProfilingInfoCache.missionId = GetMissionId();
193 :
194 0 : CHK_SAFETY_FUNC_RET(memset_s(
195 : ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID,
196 : sizeof(ccuProfilingInfoCache.channelId)));
197 0 : for (u32 i = 0; i < channelNum; i++) {
198 0 : void* channelPtr{nullptr};
199 0 : CHK_RET(static_cast<HcclResult>(HcommChannelGet(channels[i], &channelPtr)));
200 0 : auto* channelImpl = dynamic_cast<CcuUrmaChannel*>(static_cast<Channel*>(channelPtr));
201 0 : CHK_PTR_NULL(channelImpl);
202 0 : ccuProfilingInfoCache.channelId[i] = channelImpl->GetChannelId();
203 0 : ccuProfilingInfoCache.channelHandle[i] = channels[i];
204 0 : HCCL_INFO(
205 : "[%s]type[%d], name[%s], missionId[%u], channelHandle[0x%llx], channelId[%u]", __func__,
206 : ccuProfilingInfoCache.type, ccuProfilingInfoCache.name.c_str(), ccuProfilingInfoCache.missionId,
207 : ccuProfilingInfoCache.channelHandle[i], ccuProfilingInfoCache.channelId[i]);
208 : }
209 :
210 0 : lgProfilingInfo.ccuProfilingInfos.push_back(ccuProfilingInfoCache);
211 0 : if (!allLgProfilingReps.empty()) {
212 0 : lgProfilingInfo.lgProfilingReps.push_back(allLgProfilingReps.back());
213 : }
214 0 : return HCCL_SUCCESS;
215 : }
216 :
217 0 : int32_t CcuRepContext::AddProfiling(
218 : const ChannelHandle* channels, uint32_t channelNum, HcommDataType hcommDataType,
219 : HcommDataType hcommOutputDataType, HcommReduceOp hcommOpType)
220 : {
221 0 : HcclDataType dataType = static_cast<HcclDataType>(hcommDataType);
222 0 : HcclDataType outputDataType = static_cast<HcclDataType>(hcommOutputDataType);
223 0 : HcclReduceOp opType = static_cast<HcclReduceOp>(hcommOpType);
224 :
225 0 : CHK_PTR_NULL(channels);
226 0 : ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_LOOPGROUP_PROFILING;
227 0 : ccuProfilingInfoCache.name = "GroupReduce";
228 0 : ccuProfilingInfoCache.reduceOpType = opType;
229 0 : ccuProfilingInfoCache.inputDataType = dataType;
230 0 : ccuProfilingInfoCache.outputDataType = outputDataType;
231 0 : ccuProfilingInfoCache.missionId = GetMissionId();
232 :
233 0 : CHK_SAFETY_FUNC_RET(memset_s(
234 : ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID,
235 : sizeof(ccuProfilingInfoCache.channelId)));
236 0 : for (u32 i = 0; i < channelNum; ++i) {
237 0 : void* channelPtr{nullptr};
238 0 : CHK_RET(static_cast<HcclResult>(HcommChannelGet(channels[i], &channelPtr)));
239 0 : auto* channelImpl = dynamic_cast<CcuUrmaChannel*>(static_cast<Channel*>(channelPtr));
240 0 : CHK_PTR_NULL(channelImpl);
241 0 : ccuProfilingInfoCache.channelId[i] = channelImpl->GetChannelId();
242 0 : ccuProfilingInfoCache.channelHandle[i] = channels[i];
243 0 : HCCL_INFO(
244 : "[%s]type[%d], name[%s], opType[%d], dataType[%d], outputDataType[%d], missionId[%u], "
245 : "channelHandle[0x%llx], channelId[%u]",
246 : __func__, ccuProfilingInfoCache.type, ccuProfilingInfoCache.name.c_str(), opType, dataType,
247 : outputDataType, ccuProfilingInfoCache.missionId, ccuProfilingInfoCache.channelHandle[i],
248 : ccuProfilingInfoCache.channelId[i]);
249 : }
250 :
251 0 : lgProfilingInfo.ccuProfilingInfos.push_back(ccuProfilingInfoCache);
252 0 : lgProfilingInfo.lgProfilingReps.push_back(allLgProfilingReps.back());
253 0 : return HCCL_SUCCESS;
254 : }
255 :
256 67 : void CcuRepContext::SetDependencyInfo(uint32_t id, uint32_t mask, const std::shared_ptr<CcuRepBase>& rep)
257 : {
258 : // 按 mask 各置位 bit 分别登记:异常侧按 1<<i 单 bit 查询,多 bit mask 需拆解到每个单 bit key
259 67 : constexpr uint32_t CCU_CKE_BIT_NUM = 16; // CKE 的 bit 数最多为 16
260 67 : auto& inner = depInfo[id];
261 1139 : for (uint32_t i = 0; i < CCU_CKE_BIT_NUM; i++) {
262 1072 : uint32_t bit = 1u << i;
263 1072 : if ((mask & bit) != 0u) {
264 76 : inner[bit].push_back(rep);
265 : }
266 : }
267 67 : }
268 :
269 53 : std::unordered_map<uint32_t, std::vector<std::shared_ptr<CcuRepBase>>> CcuRepContext::GetDependencyInfo(uint32_t id)
270 : {
271 : // 查找给定 id 是否存在于 depInfo 中
272 53 : auto it = depInfo.find(id);
273 : // 如果找到 id,返回与之关联的内层 unordered_map
274 53 : if (it != depInfo.end()) {
275 49 : return it->second;
276 : }
277 : // 如果未找到 id,返回一个空的 unordered_map
278 4 : return std::unordered_map<uint32_t, std::vector<std::shared_ptr<CcuRepBase>>>();
279 : }
280 :
281 45 : void CcuRepContext::EraseDependencyInfo(uint32_t id) { depInfo.erase(id); }
282 :
283 1 : void CcuRepContext::ClearDependencyInfo() { depInfo.clear(); }
284 :
285 : }; // namespace CcuRep
286 : }; // namespace hcomm
|