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 <cstdint>
12 : #include <iostream>
13 : #include <fstream>
14 : #include <string>
15 : #include "launch_aicpu.h"
16 : #include "log.h"
17 : #include "mmpa_api.h"
18 : #include "mem_host_pub.h"
19 : #include "adapter_rts_common.h"
20 :
21 : using namespace std;
22 :
23 : namespace hccl {
24 : static thread_local HostMem g_aicpuKernelBinV2;
25 :
26 0 : HcclResult InitKernelArgsPrepare(
27 : aclrtBinHandle binHandle, const std::string& kernelName, void* initTaskAddr, u32 initTaskSize,
28 : aclrtFuncHandle& funcHandle, aclrtArgsHandle& argsHandle)
29 : {
30 0 : aclError ret = aclrtBinaryGetFunction(binHandle, kernelName.c_str(), &funcHandle);
31 0 : CHK_PRT_RET(
32 : ret != ACL_SUCCESS,
33 : HCCL_ERROR(
34 : "[aclrtBinaryGetFunction]errNo[0x%016llx] get func handle failed, kernelName[%s]", ret, kernelName.c_str()),
35 : HCCL_E_RUNTIME);
36 :
37 0 : ret = aclrtKernelArgsInit(funcHandle, &argsHandle);
38 0 : CHK_PRT_RET(
39 : ret != ACL_SUCCESS,
40 : HCCL_ERROR("[aclrtKernelArgsInit]errNo[0x%016llx] args init failed, kernelName[%s]", ret, kernelName.c_str()),
41 : HCCL_E_RUNTIME);
42 :
43 : aclrtParamHandle paraHandle;
44 0 : ret = aclrtKernelArgsAppend(argsHandle, initTaskAddr, initTaskSize, ¶Handle);
45 0 : CHK_PRT_RET(
46 : ret != ACL_SUCCESS,
47 : HCCL_ERROR(
48 : "[aclrtKernelArgsAppend]errNo[0x%016llx] args append failed, append size %u, kernelName[%s]", ret,
49 : initTaskSize, kernelName.c_str()),
50 : HCCL_E_RUNTIME);
51 :
52 0 : ret = aclrtKernelArgsFinalize(argsHandle);
53 0 : CHK_PRT_RET(
54 : ret != ACL_SUCCESS,
55 : HCCL_ERROR(
56 : "[aclrtKernelArgsFinalize]errNo[0x%016llx] args finalize failed, kernelName[%s]", ret, kernelName.c_str()),
57 : HCCL_E_RUNTIME);
58 0 : return HCCL_SUCCESS;
59 : }
60 :
61 0 : HcclResult TaskCommKernelArgsPrepare(
62 : aclrtBinHandle binHandle, const std::string& kernelName, void* contextAddr, u32 contextSize, void* tilingDataPtr,
63 : u32 tilingDataSize, aclrtFuncHandle& funcHandle, aclrtArgsHandle& argsHandle)
64 : {
65 0 : CHK_PRT_RET(
66 : (tilingDataPtr == nullptr || tilingDataSize == 0),
67 : HCCL_ERROR(
68 : "[TaskCommKernelArgsPrepare]param is invalid,tilingDataPtr[%p], tilingDataSize[%u], kernelName[%s]",
69 : tilingDataPtr, tilingDataSize, kernelName.c_str()),
70 : HCCL_E_PARA);
71 :
72 0 : aclError aclRet = aclrtBinaryGetFunction(binHandle, kernelName.c_str(), &funcHandle);
73 0 : CHK_PRT_RET(
74 : aclRet != ACL_SUCCESS,
75 : HCCL_ERROR(
76 : "[aclrtBinaryGetFunction]errNo[0x%016llx] get func handle failed, kernelName[%s]", aclRet,
77 : kernelName.c_str()),
78 : HCCL_E_RUNTIME);
79 :
80 0 : aclRet = aclrtKernelArgsInit(funcHandle, &argsHandle);
81 0 : CHK_PRT_RET(
82 : aclRet != ACL_SUCCESS,
83 : HCCL_ERROR(
84 : "[aclrtKernelArgsInit]errNo[0x%016llx] args init failed, kernelName[%s]", aclRet, kernelName.c_str()),
85 : HCCL_E_RUNTIME);
86 : // 拼凑aicpu侧KFCTaskComm结构体
87 : // 1、先存放HcclOpResParam的context指针
88 : aclrtParamHandle paraHandle;
89 0 : aclRet = aclrtKernelArgsAppend(argsHandle, contextAddr, contextSize, ¶Handle);
90 0 : CHK_PRT_RET(
91 : aclRet != ACL_SUCCESS,
92 : HCCL_ERROR(
93 : "[aclrtKernelArgsAppend]errNo[0x%016llx] args append failed, append size[%u], kernelName[%s]", aclRet,
94 : contextSize, kernelName.c_str()),
95 : HCCL_E_RUNTIME);
96 : // 2、再将OpTilingData的tilingData指针拼凑,并将tilingData的hostMem给rts进行H2D
97 : void* dataAddr;
98 0 : aclRet = aclrtKernelArgsAppendPlaceHolder(argsHandle, ¶Handle);
99 0 : CHK_PRT_RET(
100 : aclRet != ACL_SUCCESS,
101 : HCCL_ERROR("[aclrtKernelArgsAppendPlaceHolder]errNo[0x%016llx] args append place holder failed", aclRet),
102 : HCCL_E_RUNTIME);
103 :
104 0 : aclRet = aclrtKernelArgsGetPlaceHolderBuffer(argsHandle, paraHandle, tilingDataSize, &dataAddr);
105 0 : CHK_PRT_RET(
106 : aclRet != ACL_SUCCESS,
107 : HCCL_ERROR(
108 : "[aclrtKernelArgsGetPlaceHolderBuffer]errNo[0x%016llx] args get place holder buffer failed,"
109 : "tilingDataSize[%u]",
110 : aclRet, tilingDataSize),
111 : HCCL_E_RUNTIME);
112 0 : CHK_SAFETY_FUNC_RET(memcpy_s(dataAddr, tilingDataSize, tilingDataPtr, tilingDataSize));
113 :
114 0 : aclRet = aclrtKernelArgsFinalize(argsHandle);
115 0 : CHK_PRT_RET(
116 : aclRet != ACL_SUCCESS,
117 : HCCL_ERROR(
118 : "[aclrtKernelArgsFinalize]errNo[0x%016llx] args finalize failed, kernelName[%s]", aclRet,
119 : kernelName.c_str()),
120 : HCCL_E_RUNTIME);
121 0 : return HCCL_SUCCESS;
122 : }
123 :
124 0 : HcclResult AicpuAclKernelLaunch(
125 : const rtStream_t stm, void* addr, u32 size, aclrtBinHandle binHandle, const std::string& kernelName,
126 : bool isInitTask, u16 timeOut, void* tilingDataPtr, u32 tilingDataSize)
127 : {
128 0 : if (binHandle == nullptr) {
129 0 : HCCL_ERROR("binHandle is nullptr, no need to launch aicpu kernel, binHandle[%p]", binHandle);
130 0 : return HCCL_E_PTR;
131 : }
132 0 : CHK_PRT_RET(
133 : (addr == nullptr || size == 0),
134 : HCCL_ERROR(
135 : "[AicpuAclKernelLaunch]param is invalid, contextAddr[%p], size[%u], kernelName[%s]", addr, size,
136 : kernelName.c_str()),
137 : HCCL_E_PARA);
138 :
139 : aclrtFuncHandle funcHandle;
140 : aclrtArgsHandle argsHandle;
141 : HcclResult ret;
142 0 : if (isInitTask) {
143 0 : ret = InitKernelArgsPrepare(binHandle, kernelName, addr, size, funcHandle, argsHandle);
144 0 : CHK_PRT_RET(
145 : ret != HCCL_SUCCESS,
146 : HCCL_ERROR(
147 : "[InitKernelArgsPrepare]errNo[0x%016llx]init args prepare failed, kernelName[%s], "
148 : "contextAddr[%p], size[%u]",
149 : ret, kernelName.c_str(), addr, size),
150 : HCCL_E_RUNTIME);
151 : } else {
152 0 : ret = TaskCommKernelArgsPrepare(
153 : binHandle, kernelName, addr, size, tilingDataPtr, tilingDataSize, funcHandle, argsHandle);
154 0 : CHK_PRT_RET(
155 : ret != HCCL_SUCCESS,
156 : HCCL_ERROR(
157 : "[TaskCommKernelArgsPrepare]errNo[0x%016llx]taskCOmm args prepare failed, kernelName[%s], "
158 : "contextAddr[%p], size[%u]",
159 : ret, kernelName.c_str(), addr, size),
160 : HCCL_E_RUNTIME);
161 : }
162 :
163 : aclrtLaunchKernelCfg cfg;
164 : aclrtLaunchKernelAttr attr;
165 0 : attr.id = ACL_RT_LAUNCH_KERNEL_ATTR_TIMEOUT;
166 0 : attr.value.timeout = timeOut;
167 0 : cfg.numAttrs = 1;
168 0 : cfg.attrs = &attr;
169 0 : constexpr u32 numBlocks = 1;
170 0 : aclError aclRet = aclrtLaunchKernelWithConfig(funcHandle, numBlocks, stm, &cfg, argsHandle, nullptr);
171 0 : CHK_PRT_RET(
172 : aclRet != ACL_SUCCESS, HCCL_ERROR("[aclrtLaunchKernelWithConfig]errNo[0x%016llx] launch kernel failed", ret),
173 : HCCL_E_RUNTIME);
174 0 : return HCCL_SUCCESS;
175 : }
176 :
177 19 : HcclResult CacheTaskOpInfo(aclrtStream stream, const std::string& identify)
178 : {
179 19 : aclmdlRI rtModel = nullptr;
180 19 : aclmdlRICaptureStatus captureStatus = aclmdlRICaptureStatus::ACL_MODEL_RI_CAPTURE_STATUS_NONE;
181 19 : aclError aclRet = aclmdlRICaptureGetInfo(stream, &captureStatus, &rtModel);
182 19 : if (aclRet == ACL_ERROR_RT_FEATURE_NOT_SUPPORT) {
183 2 : HCCL_WARNING("[%s]Stream capture does not support!", __func__);
184 2 : return HCCL_SUCCESS;
185 : }
186 17 : CHK_PRT_RET(
187 : aclRet != ACL_SUCCESS, HCCL_ERROR("[%s]rtGet stream get capture status fail. return[%d]", __func__, aclRet),
188 : HCCL_E_RUNTIME);
189 :
190 : aclrtStreamAttrValue value;
191 15 : aclRet = aclrtGetStreamAttribute(stream, ACL_STREAM_ATTR_CACHE_OP_INFO, &value);
192 15 : CHK_PRT_RET(
193 : aclRet != ACL_SUCCESS, HCCL_ERROR("[%s]stream get attribute fail. return[%d]", __func__, aclRet),
194 : HCCL_E_RUNTIME);
195 :
196 13 : HCCL_INFO(
197 : "[CacheTaskOpInfo] cacheOpInfoSwitch[%u] captureStatus[%d] identify[%s]", value.cacheOpInfoSwitch,
198 : captureStatus, identify.c_str());
199 13 : if (value.cacheOpInfoSwitch == 1 && captureStatus == ACL_MODEL_RI_CAPTURE_STATUS_ACTIVE) {
200 8 : HcclResult cacheRet = hrtCacheLastTaskExtendInfo(identify.c_str(), strlen(identify.c_str()));
201 8 : if (cacheRet == HCCL_E_NOT_SUPPORT) {
202 2 : HCCL_INFO("[%s] aclrtCacheLastTaskExtendInfo not supported", __func__);
203 : } else {
204 6 : CHK_PRT_RET(
205 : cacheRet != HCCL_SUCCESS,
206 : HCCL_ERROR("[%s] stream cache task op info fail. return[%d]", __func__, cacheRet), HCCL_E_RUNTIME);
207 : }
208 : }
209 11 : return HCCL_SUCCESS;
210 : }
211 :
212 18 : HcclResult AicpuAclKernelLaunchV2(
213 : const rtStream_t stm, void* addr, u32 size, aclrtBinHandle binHandle, const std::string& kernelName,
214 : bool isInitTask, u16 timeOut, void* tilingDataPtr, u32 tilingDataSize, const std::string& identify)
215 : {
216 18 : if (binHandle == nullptr) {
217 2 : HCCL_ERROR("binHandle is nullptr, no need to launch aicpu kernel, binHandle[%p]", binHandle);
218 2 : return HCCL_E_PTR;
219 : }
220 16 : CHK_PRT_RET(
221 : (addr == nullptr || size == 0),
222 : HCCL_ERROR(
223 : "[AicpuAclKernelLaunch]param is invalid, contextAddr[%p], "
224 : "size[%u], kernelName[%s]",
225 : addr, size, kernelName.c_str()),
226 : HCCL_E_PARA);
227 : aclrtFuncHandle funcHandle;
228 12 : aclError aclRet = aclrtBinaryGetFunction(binHandle, kernelName.c_str(), &funcHandle);
229 12 : CHK_PRT_RET(
230 : aclRet != ACL_SUCCESS,
231 : HCCL_ERROR(
232 : "[aclrtBinaryGetFunction]errNo[0x%016llx] get func handle failed, "
233 : "kernelName[%s]",
234 : aclRet, kernelName.c_str()),
235 : HCCL_E_RUNTIME);
236 : // !isInitTask LaunchTask {u64 context, TillingData data}
237 10 : u64 hostBufferSize = isInitTask ? size : sizeof(u64) + tilingDataSize;
238 10 : if (g_aicpuKernelBinV2.size() < hostBufferSize) {
239 2 : g_aicpuKernelBinV2.free();
240 2 : g_aicpuKernelBinV2 = HostMem::alloc(hostBufferSize, false);
241 2 : if (g_aicpuKernelBinV2.ptr() == nullptr) {
242 0 : HCCL_ERROR("[AicpuAclKernelLaunchV2] alloc memory failed");
243 0 : return HCCL_E_MEMORY;
244 : }
245 : }
246 10 : if (isInitTask) {
247 10 : auto memRet = memcpy_s(reinterpret_cast<void*>(g_aicpuKernelBinV2.ptr()), hostBufferSize, addr, hostBufferSize);
248 10 : CHK_PRT_RET(
249 : memRet != EOK, HCCL_ERROR("[AicpuAclKernelLaunchV2]memcpy_s failed,return[%d]", memRet), HCCL_E_INTERNAL);
250 : } else {
251 0 : auto memRet = memcpy_s(reinterpret_cast<void*>(g_aicpuKernelBinV2.ptr()), sizeof(u64), addr, sizeof(u64));
252 0 : CHK_PRT_RET(
253 : memRet != EOK, HCCL_ERROR("[AicpuAclKernelLaunchV2]memcpy_s failed,return[%d]", memRet), HCCL_E_INTERNAL);
254 0 : memRet = memcpy_s(
255 0 : reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(g_aicpuKernelBinV2.ptr()) + sizeof(u64)),
256 0 : hostBufferSize - sizeof(u64), tilingDataPtr, tilingDataSize);
257 0 : CHK_PRT_RET(
258 : memRet != EOK, HCCL_ERROR("[AicpuAclKernelLaunchV2]memcpy_s failed,return[%d]", memRet), HCCL_E_INTERNAL);
259 : }
260 : aclrtLaunchKernelCfg cfg;
261 : aclrtLaunchKernelAttr attr;
262 10 : attr.id = ACL_RT_LAUNCH_KERNEL_ATTR_TIMEOUT;
263 10 : attr.value.timeout = timeOut;
264 10 : cfg.numAttrs = 1;
265 10 : cfg.attrs = &attr;
266 10 : constexpr u32 numBlocks = 1;
267 10 : aclRet = aclrtLaunchKernelWithHostArgs(
268 10 : funcHandle, numBlocks, stm, &cfg, g_aicpuKernelBinV2.ptr(), hostBufferSize, nullptr, 0);
269 10 : CHK_PRT_RET(
270 : aclRet != ACL_SUCCESS,
271 : HCCL_ERROR("[aclrtLaunchKernelWithHostArgs]errNo[0x%016llx] launch kernel failed", aclRet), HCCL_E_RUNTIME);
272 :
273 8 : CHK_RET(CacheTaskOpInfo(stm, identify));
274 :
275 4 : return HCCL_SUCCESS;
276 : }
277 :
278 685 : HcclResult GetKernelFilePath(std::string& binaryPath)
279 : {
280 : // 获取二进制文件路径
281 685 : std::string libPath;
282 685 : char* getPath = getenv("ASCEND_HOME_PATH");
283 685 : MM_SYS_GET_ENV(MM_ENV_ASCEND_HOME_PATH, getPath);
284 685 : if (getPath != nullptr) {
285 685 : libPath = getPath;
286 : } else {
287 0 : libPath = "/usr/local/Ascend/cann/";
288 0 : HCCL_WARNING("[GetKernelFilePath]ENV:ASCEND_HOME_PATH is not set");
289 : }
290 :
291 685 : libPath += "/opp/built-in/op_impl/aicpu/config/";
292 685 : binaryPath = libPath;
293 685 : HCCL_DEBUG("[GetKernelFilePath]kernel folder path[%s]", binaryPath.c_str());
294 :
295 685 : return HCCL_SUCCESS;
296 685 : }
297 :
298 0 : HcclResult GetCustomKernelFilePath(std::string& binaryPath)
299 : {
300 : // 获取二进制文件路径
301 0 : std::string libPath;
302 0 : char* getPath = getenv("ASCEND_HOME_PATH");
303 0 : MM_SYS_GET_ENV(MM_ENV_ASCEND_HOME_PATH, getPath);
304 0 : if (getPath != nullptr) {
305 0 : libPath = getPath;
306 : } else {
307 0 : libPath = "/usr/local/Ascend/cann/";
308 0 : HCCL_WARNING("[GetCustomKernelFilePath]ENV:ASCEND_HOME_PATH is not set");
309 : }
310 :
311 0 : libPath += "/opp/built-in/op_impl/aicpu/kernel/";
312 0 : binaryPath = libPath;
313 0 : HCCL_DEBUG("[GetCustomKernelFilePath]kernel folder path[%s]", binaryPath.c_str());
314 :
315 0 : return HCCL_SUCCESS;
316 0 : }
317 :
318 : } // namespace hccl
|