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 1935 : OpExeCounter& OpExeCounter::GetInstance(s32 deviceLogicID)
17 : {
18 1935 : static OpExeCounter opCounter[MAX_MODULE_DEVICE_NUM];
19 1935 : 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 1660 : return opCounter[deviceLogicID];
24 : }
25 :
26 526 : HcclResult OpExeCounter::InitCounter()
27 : {
28 526 : DevType devType = DevType::DEV_TYPE_910;
29 526 : CHK_RET(hrtGetDeviceType(devType));
30 1050 : if (!GetExternalInputStuckDetect() || devType == DevType::DEV_TYPE_310P3 || devType == DevType::DEV_TYPE_910
31 1050 : || devType == DevType::DEV_TYPE_310P1) {
32 388 : isNeedOpCounter_ = false;
33 388 : HCCL_RUN_INFO("do not need add counter");
34 388 : 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(
44 : headCountMem_, memSize_, &defCount, 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(
49 : tailCountMem_, memSize_, &defCount, 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(
55 : addOneMem_, memSize_, &addOneVal, 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 808 : HcclResult OpExeCounter::DeInitCounter()
67 : {
68 808 : if (!isNeedOpCounter_) {
69 670 : HCCL_DEBUG("do not need add counter");
70 670 : ReleaseMemHandles();
71 670 : return HCCL_SUCCESS;
72 : }
73 138 : refCount_--;
74 138 : if (refCount_ <= 0) {
75 138 : std::pair<int32_t, int32_t> counter;
76 138 : CHK_RET(GetCounter(counter));
77 138 : HCCL_RUN_INFO(
78 : "[OpExeCounter][DeInitCounter] head counter[%d], tail counter[%d]", counter.first, counter.second);
79 138 : ReleaseMemHandles();
80 138 : isNeedOpCounter_ = false;
81 138 : HCCL_RUN_INFO("free counter mem resource");
82 : }
83 138 : return HCCL_SUCCESS;
84 : }
85 :
86 45 : HcclResult OpExeCounter::AddCounter(
87 : const HcclDispatcher& dispatcher, Stream& stream, int flag) // flag 0为下发前计数,1为下发后计数
88 : {
89 45 : if (!isNeedOpCounter_) {
90 45 : HCCL_DEBUG("do not need add counter");
91 45 : return HCCL_SUCCESS;
92 : }
93 0 : if ((stream.ptr() == nullptr)) {
94 0 : HCCL_WARNING("stream is nullptr");
95 0 : return HCCL_SUCCESS;
96 : }
97 0 : CHK_RET(HcclReduceAsync(
98 : dispatcher, static_cast<void*>(addOneMem_), 1, HCCL_DATA_TYPE_INT32, HCCL_REDUCE_SUM, stream,
99 : (flag == HEAD) ? static_cast<void*>(headCountMem_) : static_cast<void*>(tailCountMem_), INVALID_VALUE_RANKID,
100 : 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 141 : HcclResult OpExeCounter::GetCounter(std::pair<int32_t, int32_t>& counter)
108 : {
109 141 : if (!isNeedOpCounter_) {
110 3 : HCCL_DEBUG("do not need add counter");
111 3 : return HCCL_SUCCESS;
112 : }
113 138 : CHK_RET(hrtMemSyncCopy(
114 : &counter.first, memSize_, headCountMem_, memSize_, HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_DEVICE_TO_HOST));
115 :
116 138 : CHK_RET(hrtMemSyncCopy(
117 : &counter.second, memSize_, tailCountMem_, memSize_, 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 547 : HcclResult OpExeCounter::GetOpCountInfo(OpCounterInfo& opCounterInfo)
125 : {
126 547 : opCounterInfo.isEnableCounter = GetExternalInputStuckDetect();
127 547 : if (!isNeedOpCounter_) {
128 409 : HCCL_DEBUG("do not need add counter");
129 409 : 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 3 : HcclResult OpExeCounter::ClearOpCounterMem()
144 : {
145 3 : if (!isNeedOpCounter_) {
146 2 : HCCL_DEBUG("do not need add counter");
147 2 : return HCCL_SUCCESS;
148 : }
149 1 : if (headCountMem_ == nullptr || tailCountMem_ == nullptr) {
150 1 : HCCL_ERROR("[OpExeCounter][ClearOpCounterMem] headCountMem or tailCountMem is nullptr");
151 1 : 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 946 : void OpExeCounter::ReleaseMemHandles()
160 : {
161 946 : if (headCountMem_ != nullptr) {
162 138 : CHK_PRT(hrtFree(headCountMem_));
163 138 : headCountMem_ = nullptr;
164 : }
165 946 : if (tailCountMem_ != nullptr) {
166 138 : CHK_PRT(hrtFree(tailCountMem_));
167 138 : tailCountMem_ = nullptr;
168 : }
169 946 : if (addOneMem_ != nullptr) {
170 138 : CHK_PRT(hrtFree(addOneMem_));
171 138 : addOneMem_ = nullptr;
172 : }
173 946 : }
174 :
175 56 : HcclResult FftsHeadCounter(const HcclDispatcher& dispatcher, Stream& stream)
176 : {
177 56 : if (!GetExternalInputHcclEnableFfts()
178 56 : || GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
179 56 : HCCL_DEBUG("do not need add ffts mode counter");
180 56 : return HCCL_SUCCESS;
181 : }
182 0 : s32 devLogicID = 0;
183 0 : CHK_RET(hrtGetDevice(&devLogicID));
184 0 : return OpExeCounter::GetInstance(devLogicID).AddCounter(dispatcher, stream, HEAD);
185 : }
186 :
187 103 : HcclResult FftsTailCounter(const HcclDispatcher& dispatcher, Stream& stream)
188 : {
189 103 : if (!GetExternalInputHcclEnableFfts()
190 103 : || GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
191 95 : HCCL_DEBUG("do not need add ffts mode counter");
192 95 : return HCCL_SUCCESS;
193 : }
194 8 : s32 devLogicID = 0;
195 8 : CHK_RET(hrtGetDevice(&devLogicID));
196 8 : return OpExeCounter::GetInstance(devLogicID).AddCounter(dispatcher, stream, TAIL);
197 : }
198 :
199 : HcclResult
200 45 : StarsCounter(const HcclDispatcher& dispatcher, Stream& stream, int flag, bool isAicpuMode, bool isRetry, bool isAivMode)
201 : {
202 : // 不需要STARS头尾计数的场景: AICPU展开不开重执行 或者 AIV 或者 HOST展开FFTS+模式
203 45 : if ((isAicpuMode && !isRetry) || isAivMode
204 106 : || (!isAicpuMode && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE
205 16 : && GetExternalInputHcclEnableFfts())) {
206 10 : HCCL_DEBUG("do not need add stars mode counter");
207 10 : return HCCL_SUCCESS;
208 : }
209 : // 需要添加STARS头尾计数的场景: AICPU开启重执行 或者 非AICPU展开 单算子STARS、图模式
210 35 : s32 devLogicID = 0;
211 35 : CHK_RET(hrtGetDevice(&devLogicID));
212 35 : return OpExeCounter::GetInstance(devLogicID).AddCounter(dispatcher, stream, flag);
213 : }
214 :
215 547 : HcclResult GetOpCountInfo(OpCounterInfo& opCounterInfo)
216 : {
217 547 : s32 devLogicID = 0;
218 547 : CHK_RET(hrtGetDevice(&devLogicID));
219 547 : return OpExeCounter::GetInstance(devLogicID).GetOpCountInfo(opCounterInfo);
220 : }
221 :
222 2 : HcclResult ClearOpCounterMem()
223 : {
224 2 : s32 devLogicID = 0;
225 2 : CHK_RET(hrtGetDevice(&devLogicID));
226 2 : return OpExeCounter::GetInstance(devLogicID).ClearOpCounterMem();
227 : }
228 :
229 47 : __attribute__((constructor)) void CallBackInit()
230 : {
231 47 : RegisterInitTaskCallBack(FftsHeadCounter);
232 47 : RegisterLaunchTaskCallBack(FftsTailCounter);
233 47 : }
234 :
235 : } // namespace hccl
|