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