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 189 : CcuRepContext::CcuRepContext()
26 : {
27 189 : mainBlock = std::make_shared<CcuRep::CcuRepBlock>(insGenerator);
28 189 : activeBlock = mainBlock;
29 189 : }
30 :
31 189 : CcuRepContext::~CcuRepContext() {}
32 :
33 2419 : std::shared_ptr<CcuRep::CcuRepBlock> CcuRepContext::CurrentBlock()
34 : {
35 2419 : if (activeBlock == nullptr) {
36 1 : Hccl::THROW<Hccl::CcuApiException>("Invalid ActiveBlock");
37 : }
38 2418 : 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 1254 : void CcuRepContext::CollectProfilingReps(std::shared_ptr<CcuRep::CcuRepBase> rep)
47 : {
48 1254 : if (rep->Type() == CcuRepType::ASSIGN) {
49 511 : auto assignRep = dynamic_cast<CcuRepAssign*>(rep.get());
50 511 : if (assignRep->GetSubType() == AssignSubType::VAR_TO_VAR) {
51 159 : lgProfilingInfo.assignProfilingReps.push_back(rep);
52 : }
53 743 : } else if (
54 1486 : CurrentBlock()->Type() != CcuRep::CcuRepType::LOOP_BLOCK
55 2120 : && (rep->Type() == CcuRepType::LOC_WAIT_EVENT || rep->Type() == CcuRepType::REM_WAIT_SEM
56 634 : || rep->Type() == CcuRepType::REM_WAIT_GROUP)) {
57 35 : waitCkeProfilingReps.push_back(rep);
58 708 : } else if (rep->Type() == CcuRepType::LOOPGROUP) {
59 28 : allLgProfilingReps.push_back(rep);
60 : }
61 1254 : }
62 :
63 1254 : void CcuRepContext::Append(std::shared_ptr<CcuRep::CcuRepBase> rep)
64 : {
65 1254 : CollectProfilingReps(rep);
66 1254 : CurrentBlock()->Append(rep);
67 1254 : }
68 :
69 193 : const std::vector<std::shared_ptr<CcuRep::CcuRepBase>>& CcuRepContext::GetRepSequence()
70 : {
71 193 : 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 125 : void CcuRepContext::SetDieId(uint32_t dieId)
101 : {
102 125 : HCCL_INFO("set dieId[%u]", dieId);
103 125 : this->dieId = dieId;
104 125 : }
105 :
106 1436 : uint32_t CcuRepContext::GetDieId() const { return dieId; }
107 :
108 45 : void CcuRepContext::SetMissionId(uint32_t missionId)
109 : {
110 45 : if (this->missionId == Hccl::INVALID_U32) {
111 45 : this->missionId = missionId;
112 : }
113 45 : }
114 :
115 53 : uint32_t CcuRepContext::GetMissionId() const { return missionId; }
116 :
117 45 : 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 0 : LoopGroupProfilingInfo& CcuRepContext::GetLGProfilingInfo() { return lgProfilingInfo; }
129 :
130 70 : void CcuRepContext::AddSqeProfiling(const std::string& kernelName)
131 : {
132 70 : constexpr uint32_t defaultDieId = 0; // 首次填写profiling时dieId未确定
133 : // 生成SQE粒度profiling信息
134 70 : ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_TASK_PROFILING;
135 70 : ccuProfilingInfoCache.name = kernelName.c_str();
136 70 : ccuProfilingInfoCache.dieId = defaultDieId;
137 70 : HCCL_DEBUG(
138 : "[%s]type[%d], name[%s], deafultDieId[0]", __func__, ccuProfilingInfoCache.type,
139 : ccuProfilingInfoCache.name.c_str(), ccuProfilingInfoCache.dieId);
140 70 : profilingInfo.push_back(ccuProfilingInfoCache);
141 70 : }
142 :
143 25 : int32_t CcuRepContext::AddProfiling(const std::string& name, uint32_t mask)
144 : {
145 25 : ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_WAITCKE_PROFILING;
146 25 : ccuProfilingInfoCache.name = name;
147 25 : ccuProfilingInfoCache.ckeId = INVALID_CKE_ID;
148 25 : ccuProfilingInfoCache.mask = mask;
149 25 : CHK_SAFETY_FUNC_RET(memset_s(
150 : ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID,
151 : sizeof(ccuProfilingInfoCache.channelId)));
152 :
153 25 : HCCL_INFO("[%s]name[%s], mask[%u], type[%d]", __func__, name.c_str(), mask, ccuProfilingInfoCache.type);
154 25 : profilingInfo.push_back(ccuProfilingInfoCache);
155 25 : 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 :
165 10 : ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_WAITCKE_PROFILING;
166 10 : ccuProfilingInfoCache.name = name;
167 10 : CHK_RET(channelImpl->GetLocCkeByIndex(signalIndex, ccuProfilingInfoCache.ckeId));
168 10 : ccuProfilingInfoCache.mask = mask;
169 10 : CHK_SAFETY_FUNC_RET(memset_s(
170 : ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID,
171 : sizeof(ccuProfilingInfoCache.channelId)));
172 10 : ccuProfilingInfoCache.channelId[0] = channelImpl->GetChannelId();
173 10 : ccuProfilingInfoCache.channelHandle[0] = channel;
174 :
175 10 : HCCL_INFO(
176 : "[%s]channelHandle[0x%llx], name[%s], signalIndex[%u], mask[%u], type[%d], ckeId[%u], channelId[%u]",
177 : __func__, channel, name.c_str(), signalIndex, mask, ccuProfilingInfoCache.type, ccuProfilingInfoCache.ckeId,
178 : ccuProfilingInfoCache.channelId[0]);
179 10 : profilingInfo.push_back(ccuProfilingInfoCache);
180 10 : return HCCL_SUCCESS;
181 : }
182 :
183 0 : int32_t CcuRepContext::AddProfiling(const ChannelHandle* channels, uint32_t channelNum)
184 : {
185 0 : CHK_PTR_NULL(channels);
186 0 : ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_LOOPGROUP_PROFILING;
187 0 : ccuProfilingInfoCache.name = "GroupBroadcast";
188 0 : ccuProfilingInfoCache.reduceOpType = 0xFF; // 0xFF 无效值
189 0 : ccuProfilingInfoCache.inputDataType = 0xFF; // 0xFF 无效值
190 0 : ccuProfilingInfoCache.outputDataType = 0xFF; // 0xFF 无效值
191 0 : ccuProfilingInfoCache.missionId = GetMissionId();
192 :
193 0 : CHK_SAFETY_FUNC_RET(memset_s(
194 : ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID,
195 : sizeof(ccuProfilingInfoCache.channelId)));
196 0 : for (u32 i = 0; i < channelNum; i++) {
197 0 : void* channelPtr{nullptr};
198 0 : CHK_RET(static_cast<HcclResult>(HcommChannelGet(channels[i], &channelPtr)));
199 0 : auto* channelImpl = dynamic_cast<CcuUrmaChannel*>(static_cast<Channel*>(channelPtr));
200 0 : CHK_PTR_NULL(channelImpl);
201 0 : ccuProfilingInfoCache.channelId[i] = channelImpl->GetChannelId();
202 0 : ccuProfilingInfoCache.channelHandle[i] = channels[i];
203 0 : HCCL_INFO(
204 : "[%s]type[%d], name[%s], missionId[%u], channelHandle[0x%llx], channelId[%u]", __func__,
205 : ccuProfilingInfoCache.type, ccuProfilingInfoCache.name.c_str(), ccuProfilingInfoCache.missionId,
206 : ccuProfilingInfoCache.channelHandle[i], ccuProfilingInfoCache.channelId[i]);
207 : }
208 :
209 0 : lgProfilingInfo.ccuProfilingInfos.push_back(ccuProfilingInfoCache);
210 0 : if (!allLgProfilingReps.empty()) {
211 0 : lgProfilingInfo.lgProfilingReps.push_back(allLgProfilingReps.back());
212 : }
213 0 : return HCCL_SUCCESS;
214 : }
215 :
216 0 : int32_t CcuRepContext::AddProfiling(
217 : const ChannelHandle* channels, uint32_t channelNum, HcommDataType hcommDataType,
218 : HcommDataType hcommOutputDataType, HcommReduceOp hcommOpType)
219 : {
220 0 : HcclDataType dataType = static_cast<HcclDataType>(hcommDataType);
221 0 : HcclDataType outputDataType = static_cast<HcclDataType>(hcommOutputDataType);
222 0 : HcclReduceOp opType = static_cast<HcclReduceOp>(hcommOpType);
223 :
224 0 : CHK_PTR_NULL(channels);
225 0 : ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_LOOPGROUP_PROFILING;
226 0 : ccuProfilingInfoCache.name = "GroupReduce";
227 0 : ccuProfilingInfoCache.reduceOpType = opType;
228 0 : ccuProfilingInfoCache.inputDataType = dataType;
229 0 : ccuProfilingInfoCache.outputDataType = outputDataType;
230 0 : ccuProfilingInfoCache.missionId = GetMissionId();
231 :
232 0 : CHK_SAFETY_FUNC_RET(memset_s(
233 : ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID,
234 : sizeof(ccuProfilingInfoCache.channelId)));
235 0 : for (u32 i = 0; i < channelNum; ++i) {
236 0 : void* channelPtr{nullptr};
237 0 : CHK_RET(static_cast<HcclResult>(HcommChannelGet(channels[i], &channelPtr)));
238 0 : auto* channelImpl = dynamic_cast<CcuUrmaChannel*>(static_cast<Channel*>(channelPtr));
239 0 : CHK_PTR_NULL(channelImpl);
240 0 : ccuProfilingInfoCache.channelId[i] = channelImpl->GetChannelId();
241 0 : ccuProfilingInfoCache.channelHandle[i] = channels[i];
242 0 : HCCL_INFO(
243 : "[%s]type[%d], name[%s], opType[%d], dataType[%d], outputDataType[%d], missionId[%u], "
244 : "channelHandle[0x%llx], channelId[%u]",
245 : __func__, ccuProfilingInfoCache.type, ccuProfilingInfoCache.name.c_str(), opType, dataType,
246 : outputDataType, ccuProfilingInfoCache.missionId, ccuProfilingInfoCache.channelHandle[i],
247 : ccuProfilingInfoCache.channelId[i]);
248 : }
249 :
250 0 : lgProfilingInfo.ccuProfilingInfos.push_back(ccuProfilingInfoCache);
251 0 : lgProfilingInfo.lgProfilingReps.push_back(allLgProfilingReps.back());
252 0 : return HCCL_SUCCESS;
253 : }
254 :
255 64 : void CcuRepContext::SetDependencyInfo(uint32_t id, uint32_t mask, const std::shared_ptr<CcuRepBase>& rep)
256 : {
257 : // 按 mask 各置位 bit 分别登记:异常侧按 1<<i 单 bit 查询,多 bit mask 需拆解到每个单 bit key
258 64 : constexpr uint32_t CCU_CKE_BIT_NUM = 16; // CKE 的 bit 数最多为 16
259 64 : auto& inner = depInfo[id];
260 1088 : for (uint32_t i = 0; i < CCU_CKE_BIT_NUM; i++) {
261 1024 : uint32_t bit = 1u << i;
262 1024 : if ((mask & bit) != 0u) {
263 73 : inner[bit].push_back(rep);
264 : }
265 : }
266 64 : }
267 :
268 50 : std::unordered_map<uint32_t, std::vector<std::shared_ptr<CcuRepBase>>> CcuRepContext::GetDependencyInfo(uint32_t id)
269 : {
270 : // 查找给定 id 是否存在于 depInfo 中
271 50 : auto it = depInfo.find(id);
272 : // 如果找到 id,返回与之关联的内层 unordered_map
273 50 : if (it != depInfo.end()) {
274 46 : return it->second;
275 : }
276 : // 如果未找到 id,返回一个空的 unordered_map
277 4 : return std::unordered_map<uint32_t, std::vector<std::shared_ptr<CcuRepBase>>>();
278 : }
279 :
280 42 : void CcuRepContext::EraseDependencyInfo(uint32_t id) { depInfo.erase(id); }
281 :
282 1 : void CcuRepContext::ClearDependencyInfo() { depInfo.clear(); }
283 :
284 : }; // namespace CcuRep
285 : }; // namespace hcomm
|