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 "opexecounter.h"
12 : #include "adapter_rts_common.h"
13 : #include "env_config.h"
14 : #include "dispatcher.h"
15 : namespace hccl {
16 1922 : OpExeCounter& OpExeCounter::GetInstance(s32 deviceLogicID)
17 : {
18 1922 : static OpExeCounter opCounter[MAX_MODULE_DEVICE_NUM];
19 1921 : if (static_cast<u32>(deviceLogicID) >= MAX_MODULE_DEVICE_NUM - 1) {
20 275 : HCCL_WARNING("[OpExeCounter][GetInstance] deviceLogicID[%d] is invalid", deviceLogicID);
21 275 : return opCounter[MAX_MODULE_DEVICE_NUM - 1];
22 : }
23 1646 : return opCounter[deviceLogicID];
24 : }
25 :
26 523 : HcclResult OpExeCounter::InitCounter()
27 : {
28 523 : DevType devType = DevType::DEV_TYPE_910;
29 523 : CHK_RET(hrtGetDeviceType(devType));
30 661 : if (!GetExternalInputStuckDetect() || devType == DevType::DEV_TYPE_310P3 || devType == DevType::DEV_TYPE_910 ||
31 138 : devType == DevType::DEV_TYPE_310P1) {
32 385 : isNeedOpCounter_ = false;
33 385 : HCCL_RUN_INFO("do not need add counter");
34 385 : return HCCL_SUCCESS;
35 : }
36 138 : if (refCount_ <= 0) {
37 138 : refCount_ = 0;
38 138 : int32_t defCount = 0;
39 138 : ReleaseMemHandles();
40 138 : memSize_ = sizeof(int32_t);
41 138 : CHK_RET(hrtMalloc(&headCountMem_, memSize_));
42 138 : CHK_PTR_NULL(headCountMem_);
43 138 : CHK_RET(hrtMemSyncCopy(headCountMem_, memSize_, &defCount,
44 : memSize_, HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
45 :
46 138 : CHK_RET(hrtMalloc(&tailCountMem_, memSize_));
47 138 : CHK_PTR_NULL(tailCountMem_);
48 138 : CHK_RET(hrtMemSyncCopy(tailCountMem_, memSize_, &defCount,
49 : memSize_, HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
50 :
51 138 : int32_t addOneVal = 1;
52 138 : CHK_RET(hrtMalloc(&addOneMem_, memSize_));
53 138 : CHK_PTR_NULL(addOneMem_);
54 138 : CHK_RET(hrtMemSyncCopy(addOneMem_, memSize_, &addOneVal,
55 : memSize_, HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
56 :
57 138 : HCCL_RUN_INFO("alloc counter mem resource.");
58 : }
59 138 : refCount_++;
60 138 : isNeedOpCounter_ = true;
61 138 : return HCCL_SUCCESS;
62 : }
63 :
64 845 : OpExeCounter::~OpExeCounter()
65 : {
66 845 : }
67 :
68 804 : HcclResult OpExeCounter::DeInitCounter()
69 : {
70 804 : if (!isNeedOpCounter_) {
71 667 : HCCL_DEBUG("do not need add counter");
72 667 : ReleaseMemHandles();
73 667 : return HCCL_SUCCESS;
74 : }
75 137 : refCount_--;
76 137 : if (refCount_ <= 0) {
77 138 : std::pair<int32_t, int32_t> counter;
78 138 : CHK_RET(GetCounter(counter));
79 138 : HCCL_RUN_INFO("[OpExeCounter][DeInitCounter] head counter[%d], tail counter[%d]",
80 : counter.first, counter.second);
81 138 : ReleaseMemHandles();
82 138 : isNeedOpCounter_= false;
83 138 : HCCL_RUN_INFO("free counter mem resource");
84 : }
85 137 : return HCCL_SUCCESS;
86 : }
87 :
88 45 : HcclResult OpExeCounter::AddCounter(const HcclDispatcher &dispatcher, Stream &stream, int flag) // flag 0为下发前计数,1为下发后计数
89 : {
90 45 : if (!isNeedOpCounter_) {
91 45 : HCCL_DEBUG("do not need add counter");
92 45 : return HCCL_SUCCESS;
93 : }
94 0 : if ((stream.ptr() == nullptr)) {
95 0 : HCCL_WARNING("stream is nullptr");
96 0 : return HCCL_SUCCESS;
97 : }
98 0 : CHK_RET(HcclReduceAsync(dispatcher, static_cast<void *>(addOneMem_), 1, HCCL_DATA_TYPE_INT32, HCCL_REDUCE_SUM,
99 : stream, (flag == HEAD) ? static_cast<void *>(headCountMem_) : static_cast<void *>(tailCountMem_),
100 : INVALID_VALUE_RANKID, LinkType::LINK_ONCHIP, INLINE_REDUCE_BIT));
101 :
102 0 : HCCL_DEBUG("add %s count.", (flag == HEAD) ? "head" : "tail");
103 :
104 0 : return HCCL_SUCCESS;
105 : }
106 :
107 140 : HcclResult OpExeCounter::GetCounter(std::pair<int32_t, int32_t> &counter)
108 : {
109 140 : if (!isNeedOpCounter_) {
110 3 : HCCL_DEBUG("do not need add counter");
111 3 : return HCCL_SUCCESS;
112 : }
113 137 : CHK_RET(hrtMemSyncCopy(&counter.first, memSize_, headCountMem_, memSize_,
114 : HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_DEVICE_TO_HOST));
115 :
116 138 : CHK_RET(hrtMemSyncCopy(&counter.second, memSize_, tailCountMem_, memSize_,
117 : HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_DEVICE_TO_HOST));
118 :
119 138 : HCCL_DEBUG("head:%d, tail:%d", counter.first, counter.second);
120 :
121 138 : return HCCL_SUCCESS;
122 : }
123 :
124 544 : HcclResult OpExeCounter::GetOpCountInfo(OpCounterInfo &opCounterInfo)
125 : {
126 544 : opCounterInfo.isEnableCounter = GetExternalInputStuckDetect();
127 544 : if (!isNeedOpCounter_) {
128 406 : HCCL_DEBUG("do not need add counter");
129 406 : return HCCL_SUCCESS;
130 : }
131 :
132 138 : if (headCountMem_ == nullptr || tailCountMem_ == nullptr || addOneMem_ == nullptr ) {
133 0 : HCCL_ERROR("[OpExeCounter][GetOpCountInfo] aicpu headCountMem or tailCountMem or addOneMem is nullptr");
134 0 : return HCCL_E_PTR;
135 : }
136 138 : opCounterInfo.headCountMem = reinterpret_cast<u64>(headCountMem_);
137 138 : opCounterInfo.tailCountMem = reinterpret_cast<u64>(tailCountMem_);
138 138 : opCounterInfo.addOneMem = reinterpret_cast<u64>(addOneMem_);
139 138 : opCounterInfo.memSize = memSize_;
140 138 : return HCCL_SUCCESS;
141 : }
142 :
143 2 : HcclResult OpExeCounter::ClearOpCounterMem()
144 : {
145 2 : if (!isNeedOpCounter_) {
146 2 : HCCL_DEBUG("do not need add counter");
147 2 : return HCCL_SUCCESS;
148 : }
149 0 : if (headCountMem_ == nullptr || tailCountMem_ == nullptr) {
150 0 : HCCL_ERROR("[OpExeCounter][ClearOpCounterMem] headCountMem or tailCountMem is nullptr");
151 0 : return HCCL_E_PTR;
152 : }
153 0 : CHK_RET(hrtMemSet(headCountMem_, memSize_, memSize_));
154 0 : CHK_RET(hrtMemSet(tailCountMem_, memSize_, memSize_));
155 0 : HCCL_DEBUG("[OpExeCounter][ClearOpCounterMem] headCountMem or tailCountMem is to success set 0");
156 0 : return HCCL_SUCCESS;
157 : }
158 :
159 943 : void OpExeCounter::ReleaseMemHandles()
160 : {
161 943 : if (headCountMem_ != nullptr) {
162 138 : CHK_PRT(hrtFree(headCountMem_));
163 138 : headCountMem_ = nullptr;
164 : }
165 943 : if (tailCountMem_ != nullptr) {
166 138 : CHK_PRT(hrtFree(tailCountMem_));
167 138 : tailCountMem_ = nullptr;
168 : }
169 943 : if (addOneMem_ != nullptr) {
170 138 : CHK_PRT(hrtFree(addOneMem_));
171 138 : addOneMem_ = nullptr;
172 : }
173 943 : }
174 :
175 56 : HcclResult FftsHeadCounter(const HcclDispatcher &dispatcher, Stream &stream)
176 : {
177 56 : if (!GetExternalInputHcclEnableFfts() || GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
178 56 : HCCL_DEBUG("do not need add ffts mode counter");
179 56 : return HCCL_SUCCESS;
180 : }
181 0 : s32 devLogicID = 0;
182 0 : CHK_RET(hrtGetDevice(&devLogicID));
183 0 : return OpExeCounter::GetInstance(devLogicID).AddCounter(dispatcher, stream, HEAD);
184 : }
185 :
186 103 : HcclResult FftsTailCounter(const HcclDispatcher &dispatcher, Stream &stream)
187 : {
188 103 : if (!GetExternalInputHcclEnableFfts() || GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
189 95 : HCCL_DEBUG("do not need add ffts mode counter");
190 95 : return HCCL_SUCCESS;
191 : }
192 8 : s32 devLogicID = 0;
193 8 : CHK_RET(hrtGetDevice(&devLogicID));
194 8 : return OpExeCounter::GetInstance(devLogicID).AddCounter(dispatcher, stream, TAIL);
195 : }
196 :
197 45 : HcclResult StarsCounter(const HcclDispatcher &dispatcher, Stream &stream, int flag, bool isAicpuMode, bool isRetry, bool isAivMode)
198 : {
199 : // 不需要STARS头尾计数的场景: AICPU展开不开重执行 或者 AIV 或者 HOST展开FFTS+模式
200 80 : if ((isAicpuMode && !isRetry) || isAivMode ||
201 35 : (!isAicpuMode && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && GetExternalInputHcclEnableFfts())) {
202 10 : HCCL_DEBUG("do not need add stars mode counter");
203 10 : return HCCL_SUCCESS;
204 : }
205 : // 需要添加STARS头尾计数的场景: AICPU开启重执行 或者 非AICPU展开 单算子STARS、图模式
206 35 : s32 devLogicID = 0;
207 35 : CHK_RET(hrtGetDevice(&devLogicID));
208 35 : return OpExeCounter::GetInstance(devLogicID).AddCounter(dispatcher, stream, flag);
209 : }
210 :
211 544 : HcclResult GetOpCountInfo(OpCounterInfo &opCounterInfo)
212 : {
213 544 : s32 devLogicID = 0;
214 544 : CHK_RET(hrtGetDevice(&devLogicID));
215 544 : return OpExeCounter::GetInstance(devLogicID).GetOpCountInfo(opCounterInfo);
216 : }
217 :
218 2 : HcclResult ClearOpCounterMem()
219 : {
220 2 : s32 devLogicID = 0;
221 2 : CHK_RET(hrtGetDevice(&devLogicID));
222 2 : return OpExeCounter::GetInstance(devLogicID).ClearOpCounterMem();
223 : }
224 :
225 43 : __attribute__((constructor)) void CallBackInit()
226 : {
227 43 : RegisterInitTaskCallBack(FftsHeadCounter);
228 43 : RegisterLaunchTaskCallBack(FftsTailCounter);
229 43 : }
230 :
231 : } // namespace hccl
|