* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include "sink_node_bin.h"
#include <list>
#include "graph/ge_error_codes.h"
#include "register/kernel_registry.h"
#include "graph/utils/math_util.h"
#include "runtime/kernel.h"
#include "kernel/kernel_log.h"
#include "runtime/rt_ffts_plus.h"
#include "common/checker.h"
#include "engine/aicore/kernel/aicore_update_kernel.h"
#include "exe_graph/runtime/extended_kernel_context.h"
namespace gert {
namespace kernel {
namespace {
std::mutex g_bin_hash_to_handles_lock;
std::unordered_map<std::string, void*> g_bin_hash_to_handles;
std::string GetComputeNodeName(const KernelContext *context) {
if ((context == nullptr) ||
(reinterpret_cast<const ExtendedKernelContext *>(context)->GetComputeNodeInfo() == nullptr) ||
(reinterpret_cast<const ExtendedKernelContext *>(context)->GetComputeNodeInfo()->GetNodeName() == nullptr)) {
return "unknown";
}
return reinterpret_cast<const ExtendedKernelContext *>(context)->GetComputeNodeInfo()->GetNodeName();
}
}
UINT32 SinkNodeBinWithoutHandle(KernelContext *context) {
auto bin_data_holder = context->GetInputValue<kernel::BinData *>(0);
auto stub_name = context->GetInputValue<char *>(1);
auto metadata = context->GetInputValue<char *>(2);
auto kernel_name = context->GetInputValue<char *>(3);
auto stub_func = context->GetOutputPointer<void *>(0);
const rtError_t ret_ret = rtQueryFunctionRegistered(stub_name);
if (ret_ret != RT_ERROR_NONE) {
if (bin_data_holder == nullptr || stub_name == nullptr || metadata == nullptr || kernel_name == nullptr) {
GELOGE(ge::FAILED, "SinkNodeBinWithoutHandle para check failed");
return ge::GRAPH_FAILED;
}
void *bin_handle;
rtDevBinary_t *bin_data = reinterpret_cast<rtDevBinary_t *>(bin_data_holder);
bin_data->data = &bin_data_holder->placeholder;
GELOGI("Register static kernel size %lu, node %s, stub %s", bin_data->length, GetComputeNodeName(context).c_str(),
stub_name);
GE_ASSERT_RT_OK(rtDevBinaryRegister(bin_data, &bin_handle));
if (strlen(metadata) > 1) {
GE_ASSERT_RT_OK(rtMetadataRegister(bin_handle, metadata));
}
static std::list<uint8_t> kernel_unique_ids;
static std::mutex mtx;
void *kernel_unique_ids_addr;
{
std::unique_lock<std::mutex> lk(mtx);
kernel_unique_ids.push_back(0U);
kernel_unique_ids_addr = &kernel_unique_ids.back();
}
GE_ASSERT_RT_OK(rtFunctionRegister(bin_handle, kernel_unique_ids_addr, stub_name, kernel_name, 0U));
}
GE_ASSERT_NOTNULL(stub_func);
GE_ASSERT_RT_OK(rtGetFunctionByName(stub_name, stub_func));
return ge::GRAPH_SUCCESS;
}
REGISTER_KERNEL(SinkNodeBinWithoutHandle).RunFunc(SinkNodeBinWithoutHandle);
UINT32 SinkNodeBinWithHandle(KernelContext *context) {
auto bin_data_holder = context->GetInputValue<kernel::BinData *>(0);
if (bin_data_holder == nullptr) {
GELOGE(ge::FAILED, "SinkNodeBinWithHandle para check failed");
return ge::GRAPH_FAILED;
}
auto bin_key = context->GetInputValue<char *>(1);
GE_ASSERT_NOTNULL(bin_key);
rtDevBinary_t *bin_data = reinterpret_cast<rtDevBinary_t *>(bin_data_holder);
bin_data->data = &bin_data_holder->placeholder;
auto bin_handle = context->GetOutputPointer<void *>(0);
GE_ASSERT_NOTNULL(bin_handle);
std::string bin_hash(bin_key);
if (bin_hash.empty()) {
GELOGI("Register dynamic kernel empty hash size %lu, node %s", bin_data->length,
GetComputeNodeName(context).c_str());
GE_ASSERT_RT_OK(rtRegisterAllKernel(bin_data, bin_handle));
return ge::GRAPH_SUCCESS;
}
std::unique_lock<std::mutex> lk(g_bin_hash_to_handles_lock);
const std::unordered_map<std::string, void*>::const_iterator iter = g_bin_hash_to_handles.find(bin_hash);
if (iter != g_bin_hash_to_handles.cend()) {
*bin_handle = iter->second;
return ge::GRAPH_SUCCESS;
}
GELOGI("Register dynamic kernel size %lu, node %s, hash %s",
bin_data->length, GetComputeNodeName(context).c_str(), bin_hash.c_str());
GE_ASSERT_RT_OK(rtRegisterAllKernel(bin_data, bin_handle));
g_bin_hash_to_handles[bin_hash] = *bin_handle;
return ge::GRAPH_SUCCESS;
}
REGISTER_KERNEL(SinkNodeBinWithHandle).RunFunc(SinkNodeBinWithHandle);
UINT32 SinkFFTSAICoreNodeBin(KernelContext *context) {
auto bin_data_holder = context->GetInputValue<kernel::BinData *>(0U);
GE_ASSERT_NOTNULL(bin_data_holder);
auto bin_handle = context->GetOutputPointer<void *>(0U);
GE_ASSERT_NOTNULL(bin_handle);
rtDevBinary_t *bin_data = reinterpret_cast<rtDevBinary_t *>(bin_data_holder);
bin_data->data = &bin_data_holder->placeholder;
rtError_t ret = rtRegisterAllKernel(bin_data, bin_handle);
if (ret != RT_ERROR_NONE) {
GELOGE(ge::FAILED, "[kernel][SinkFFTSAICoreNodeBin] Register kernel failed.");
return ge::GRAPH_FAILED;
}
return ge::GRAPH_SUCCESS;
}
REGISTER_KERNEL(SinkFFTSAICoreNodeBin).RunFunc(SinkFFTSAICoreNodeBin);
UINT32 GetFFTSAICorePcAndPref(KernelContext *context) {
auto bin_handle = context->GetInputValue<void *>(static_cast<int32_t>(0U));
auto none_tail_key = context->GetInputValue<size_t>(1U);
auto tail_key = context->GetInputValue<size_t>(2U);
void *none_tail_addr = nullptr;
uint32_t none_tail_pref = 0U;
void *tail_addr = nullptr;
uint32_t tail_pref = 0U;
auto sink_ret = context->GetOutputPointer<AICoreSinkRet>(0U);
if (sink_ret == nullptr) {
GELOGE(ge::FAILED, "[kernel][SinkFFTSAICoreNodeBin] Flush data is null.");
return ge::GRAPH_FAILED;
}
if (rtKernelGetAddrAndPrefCnt(bin_handle, none_tail_key, nullptr, RT_DYNAMIC_SHAPE_KERNEL, &none_tail_addr,
&none_tail_pref) != RT_ERROR_NONE) {
GELOGE(ge::FAILED, "[kernel][SinkFFTSAICoreNodeBin] get none tail start pc failed.");
return ge::GRAPH_FAILED;
}
if (none_tail_key != tail_key) {
if (rtKernelGetAddrAndPrefCnt(bin_handle, tail_key, nullptr, RT_DYNAMIC_SHAPE_KERNEL, &tail_addr,
&tail_pref) != RT_ERROR_NONE) {
GELOGE(ge::FAILED, "[kernel][SinkFFTSAICoreNodeBin] get tail start pc failed.");
return ge::GRAPH_FAILED;
}
} else {
tail_addr = none_tail_addr;
tail_pref = none_tail_pref;
}
sink_ret->aic_non_tail_task_start_pc = reinterpret_cast<uintptr_t>(none_tail_addr);
sink_ret->aic_tail_task_start_pc = reinterpret_cast<uintptr_t>(tail_addr);
sink_ret->aic_icache_prefetch_cnt = std::min(none_tail_pref, tail_pref);
GELOGD("Sink bin get pc[%lx][%lx].", sink_ret->aic_non_tail_task_start_pc, sink_ret->aic_tail_task_start_pc);
return ge::GRAPH_SUCCESS;
}
ge::graphStatus CreateSinkRet(const ge::FastNode *node, KernelContext *context) {
(void)node;
auto chain = context->GetOutput(0);
GE_ASSERT_NOTNULL(chain);
chain->SetWithDefaultDeleter(new AICoreSinkRet());
return ge::GRAPH_SUCCESS;
}
REGISTER_KERNEL(GetFFTSAICorePcAndPref).RunFunc(GetFFTSAICorePcAndPref).OutputsCreator(CreateSinkRet);
UINT32 SinkFFTSStaManualNodeBin(KernelContext *context) {
auto sink_ret = context->GetOutputPointer<AICoreSinkRet>(0U);
GE_ASSERT_NOTNULL(sink_ret);
auto kernel_name = context->GetInputValue<char *>(0U);
GE_ASSERT_NOTNULL(kernel_name);
auto stub_name = context->GetInputValue<char *>(1U);
GE_ASSERT_NOTNULL(stub_name);
auto metadata = context->GetInputValue<char *>(2U);
GE_ASSERT_NOTNULL(metadata);
auto bin_data_holder = context->GetInputValue<kernel::BinData *>(3U);
GE_ASSERT_NOTNULL(bin_data_holder);
void *bin_handle = nullptr;
rtDevBinary_t *bin_data = reinterpret_cast<rtDevBinary_t *>(bin_data_holder);
bin_data->data = &bin_data_holder->placeholder;
GE_ASSERT_RT_OK(rtDevBinaryRegister(bin_data, &bin_handle));
if (strlen(metadata) > 1U) {
GE_ASSERT_RT_OK(rtMetadataRegister(bin_handle, metadata));
}
static std::list<uint8_t> kernel_unique_ids;
static std::mutex mtx;
void *kernel_unique_ids_addr;
{
std::unique_lock<std::mutex> lk(mtx);
kernel_unique_ids.push_back(0U);
kernel_unique_ids_addr = &kernel_unique_ids.back();
}
GE_ASSERT_RT_OK(rtFunctionRegister(bin_handle, kernel_unique_ids_addr, stub_name, kernel_name, 0U));
uint32_t prefetch_cnt = 0U;
void *addr = nullptr;
GE_CHK_RT_RET(rtKernelGetAddrAndPrefCnt(bin_handle, 0U, kernel_unique_ids_addr, RT_STATIC_SHAPE_KERNEL, &addr,
&prefetch_cnt));
GELOGD("Get static pc addr:%lx pre_cnt:%u.", addr, prefetch_cnt);
sink_ret->aic_icache_prefetch_cnt = prefetch_cnt;
sink_ret->aic_non_tail_task_start_pc = reinterpret_cast<uintptr_t>(addr);
sink_ret->aic_tail_task_start_pc = reinterpret_cast<uintptr_t>(addr);
return ge::GRAPH_SUCCESS;
}
REGISTER_KERNEL(SinkFFTSStaManualNodeBin).RunFunc(SinkFFTSStaManualNodeBin).OutputsCreator(CreateSinkRet);
UINT32 SinkFFTSStaAutoNodeBin(KernelContext *context) {
auto sink_ret = context->GetOutputPointer<AICoreSinkRet>(0U);
GE_ASSERT_NOTNULL(sink_ret);
auto kernel_num = context->GetInputValue<size_t>(0U);
KLOGD("Sink static auto kernel with num[%zu].", kernel_num);
size_t start_in = 1U;
for (size_t i = 0; i < kernel_num; ++i) {
auto kernel_name = context->GetInputValue<char *>(start_in++);
GE_ASSERT_NOTNULL(kernel_name);
auto stub_name = context->GetInputValue<char *>(start_in++);
GE_ASSERT_NOTNULL(stub_name);
auto metadata = context->GetInputValue<char *>(start_in++);
GE_ASSERT_NOTNULL(metadata);
auto bin_data_holder = context->GetInputValue<kernel::BinData *>(start_in++);
GE_ASSERT_NOTNULL(bin_data_holder);
void *bin_handle = nullptr;
rtDevBinary_t *bin_data = reinterpret_cast<rtDevBinary_t *>(bin_data_holder);
bin_data->data = &bin_data_holder->placeholder;
GE_ASSERT_RT_OK(rtDevBinaryRegister(bin_data, &bin_handle));
if (strlen(metadata) > 1U) {
GE_ASSERT_RT_OK(rtMetadataRegister(bin_handle, metadata));
}
static std::list<uint8_t> kernel_unique_ids;
static std::mutex mtx;
void *kernel_unique_ids_addr;
{
std::unique_lock<std::mutex> lk(mtx);
kernel_unique_ids.push_back(0U);
kernel_unique_ids_addr = &kernel_unique_ids.back();
}
GE_ASSERT_RT_OK(rtFunctionRegister(bin_handle, kernel_unique_ids_addr, stub_name, kernel_name, 0U));
uint32_t prefetch_cnt = 0U;
void *addr = nullptr;
GE_CHK_RT_RET(rtKernelGetAddrAndPrefCnt(bin_handle, 0U, kernel_unique_ids_addr, RT_STATIC_SHAPE_KERNEL, &addr,
&prefetch_cnt));
GELOGD("Get [%zu] kernel[%s] pc addr:%lx pre_cnt:%u.", i, kernel_name, addr, prefetch_cnt);
if (i == 0U) {
sink_ret->aic_icache_prefetch_cnt = prefetch_cnt;
sink_ret->aic_non_tail_task_start_pc = reinterpret_cast<uintptr_t>(addr);
} else {
sink_ret->aic_tail_task_start_pc = reinterpret_cast<uintptr_t>(addr);
sink_ret->aic_icache_prefetch_cnt = std::min(sink_ret->aic_icache_prefetch_cnt, prefetch_cnt);
}
}
if (kernel_num == 1U) {
sink_ret->aic_tail_task_start_pc = sink_ret->aic_non_tail_task_start_pc;
}
return ge::GRAPH_SUCCESS;
}
REGISTER_KERNEL(SinkFFTSStaAutoNodeBin).RunFunc(SinkFFTSStaAutoNodeBin).OutputsCreator(CreateSinkRet);
const std::string kTaskCubeTBEKernelPrefixAic = "_mix_aic";
const std::string kTaskVectorTBEKernelPrefixAiv = "_mix_aiv";
UINT32 SinkMixDyNodeBin(KernelContext *context) {
auto bin_data_holder = context->GetInputValue<kernel::BinData *>(0U);
if (bin_data_holder == nullptr) {
GELOGE(ge::FAILED, "[kernel][SinkFFTSAICoreNodeBin] Bin data is nullptr.");
return ge::GRAPH_FAILED;
}
auto ret_handle = context->GetOutputPointer<void*>(0U);
GE_ASSERT_NOTNULL(ret_handle);
rtDevBinary_t *bin_data = reinterpret_cast<rtDevBinary_t *>(bin_data_holder);
bin_data->data = &bin_data_holder->placeholder;
auto bin_key = context->GetInputValue<char *>(1);
GE_ASSERT_NOTNULL(bin_key);
std::string bin_hash(bin_key);
if (!bin_hash.empty()) {
std::unique_lock<std::mutex> lk(g_bin_hash_to_handles_lock);
const std::unordered_map<std::string, void*>::const_iterator iter = g_bin_hash_to_handles.find(bin_hash);
if (iter != g_bin_hash_to_handles.cend()) {
*ret_handle = iter->second;
return ge::GRAPH_SUCCESS;
}
GELOGI("Register dynamic kernel size %lu, node %s, hash %s",
bin_data->length, GetComputeNodeName(context).c_str(), bin_hash.c_str());
GE_ASSERT_RT_OK(rtRegisterAllKernel(bin_data, ret_handle));
g_bin_hash_to_handles[bin_hash] = *ret_handle;
return ge::GRAPH_SUCCESS;
}
GE_CHK_RT_RET(rtRegisterAllKernel(bin_data, ret_handle));
return ge::GRAPH_SUCCESS;
}
REGISTER_KERNEL(SinkMixDyNodeBin).RunFunc(SinkMixDyNodeBin);
bool CheckKernelInfoValid(const rtKernelDetailInfo_t &kernel_info) {
return kernel_info.functionInfoNum < static_cast<uint8_t>(MIX_KERNEL_FUNC_NUM::MIX_INVALID_KERNEL);
}
UINT32 ParseKernelInfo(const rtKernelDetailInfo_t &kernel_info, const rtKernelDetailInfo_t &tail_kernel_info,
AICoreSinkRet *sink_ret) {
GELOGD("start parse kernelinfo: functionInfoNum: %u", kernel_info.functionInfoNum);
if (kernel_info.functionInfoNum == static_cast<uint8_t>(MIX_KERNEL_FUNC_NUM::MIX_WITH_ONE_KERNEL)) {
const auto &info = kernel_info.functionInfo[0];
const auto &tail_info = tail_kernel_info.functionInfo[0];
GELOGD("mixType is %u, prefetchCnt is %u pcAddr is Ox%x", info.mixType, info.prefetchCnt, info.pcAddr);
if (info.mixType == static_cast<uint8_t>(MIX_KERNEL_TYPE::MIX_AIC_ONLY)) {
sink_ret->aic_non_tail_task_start_pc = reinterpret_cast<uintptr_t>(info.pcAddr);
sink_ret->aic_icache_prefetch_cnt = std::min(info.prefetchCnt, tail_info.prefetchCnt);
sink_ret->aic_tail_task_start_pc = reinterpret_cast<uintptr_t>(tail_info.pcAddr);
} else if (info.mixType == static_cast<uint8_t>(MIX_KERNEL_TYPE::MIX_AIV_ONLY)) {
sink_ret->aiv_non_tail_task_start_pc = reinterpret_cast<uintptr_t>(info.pcAddr);
sink_ret->aiv_icache_prefetch_cnt = std::min(info.prefetchCnt, tail_info.prefetchCnt);
sink_ret->aiv_tail_task_start_pc = reinterpret_cast<uintptr_t>(tail_info.pcAddr);
} else {
GELOGD("find invalid mixType %u with kernel num is 1", info.mixType);
}
return ge::SUCCESS;
}
if (kernel_info.functionInfoNum == static_cast<uint8_t>(MIX_KERNEL_FUNC_NUM::MIX_WITH_TWO_KERNEL)) {
GELOGD("aic mixType is %u, prefetchCnt is %u pcAddr is Ox%lx", kernel_info.functionInfo[0].mixType,
kernel_info.functionInfo[0].prefetchCnt, kernel_info.functionInfo[0].pcAddr);
GELOGD("aiv mixType is %u, prefetchCnt is %u pcAddr is Ox%lx", kernel_info.functionInfo[1].mixType,
kernel_info.functionInfo[1].prefetchCnt, kernel_info.functionInfo[1].pcAddr);
sink_ret->aic_non_tail_task_start_pc = reinterpret_cast<uintptr_t>(kernel_info.functionInfo[0].pcAddr);
sink_ret->aic_icache_prefetch_cnt = std::min(kernel_info.functionInfo[0].prefetchCnt,
tail_kernel_info.functionInfo[0].prefetchCnt);;
sink_ret->aic_tail_task_start_pc = reinterpret_cast<uintptr_t>(tail_kernel_info.functionInfo[0].pcAddr);
sink_ret->aiv_non_tail_task_start_pc = reinterpret_cast<uintptr_t>(kernel_info.functionInfo[1].pcAddr);
sink_ret->aiv_icache_prefetch_cnt = std::min(kernel_info.functionInfo[1].prefetchCnt,
tail_kernel_info.functionInfo[1].prefetchCnt);;
sink_ret->aiv_tail_task_start_pc = reinterpret_cast<uintptr_t>(tail_kernel_info.functionInfo[1].pcAddr);
return ge::SUCCESS;
}
return ge::FAILED;
}
ge::graphStatus GetMixDynamicPC(const KernelFunctionCtx &ctx, const std::string &prefix, AICoreSinkRet *sink_ret) {
uint32_t prefetch_cnt = 0U;
void *addr = nullptr;
GE_CHK_RT_RET(rtKernelGetAddrAndPrefCnt(ctx.bin_handler, ctx.tiling_key, ctx.kernel_unique_ids_addr, ctx.flag,
&addr, &prefetch_cnt));
uint32_t tail_prefetch_cnt = 0U;
void *tail_addr = nullptr;
if (ctx.tail_tiling_key == ctx.tiling_key) {
tail_prefetch_cnt = prefetch_cnt;
tail_addr = addr;
} else {
GE_CHK_RT_RET(rtKernelGetAddrAndPrefCnt(ctx.bin_handler, ctx.tail_tiling_key, ctx.kernel_unique_ids_addr, ctx.flag,
&tail_addr, &tail_prefetch_cnt));
}
GELOGD("Get mix node with flag: %u prefix:%s pc addr:%p pre_cnt:%u.", ctx.flag, prefix.c_str(), addr,
prefetch_cnt);
if (prefix == kTaskCubeTBEKernelPrefixAic) {
sink_ret->aic_non_tail_task_start_pc = reinterpret_cast<uintptr_t>(addr);
sink_ret->aic_tail_task_start_pc = reinterpret_cast<uintptr_t>(tail_addr);
sink_ret->aic_icache_prefetch_cnt = std::min(prefetch_cnt, tail_prefetch_cnt);
} else {
sink_ret->aiv_non_tail_task_start_pc = reinterpret_cast<uintptr_t>(addr);
sink_ret->aiv_tail_task_start_pc = reinterpret_cast<uintptr_t>(tail_addr);
sink_ret->aiv_icache_prefetch_cnt = std::min(prefetch_cnt, tail_prefetch_cnt);
}
return ge::SUCCESS;
}
UINT32 GetKernelFuncInfoByKernelType(const KernelFunctionCtx &ctx, const std::string &prefix, AICoreSinkRet *sink_ret) {
MIX_KERNEL_REQ_TYPE type = MIX_KERNEL_REQ_TYPE(ctx.kernel_type);
switch (type) {
case MIX_KERNEL_REQ_TYPE::MIX_SINGLE_KERNEL:
case MIX_KERNEL_REQ_TYPE::MIX_MULTI_KERNEL: {
return GetMixDynamicPC(ctx, prefix, sink_ret);
}
case MIX_KERNEL_REQ_TYPE::ENHANCED_MIX_SINGLE_KERNEL:
case MIX_KERNEL_REQ_TYPE::ENHANCED_MIX_DYNAMIC: {
rtKernelDetailInfo_t kernel_info;
GE_CHK_RT_RET(rtKernelGetAddrAndPrefCntV2(ctx.bin_handler, ctx.tiling_key, ctx.kernel_unique_ids_addr, ctx.flag,
&kernel_info));
GELOGD("Get mix node with flag: %u prefix:%s.", ctx.flag, prefix.c_str());
if (!CheckKernelInfoValid(kernel_info)) {
return ge::FAILED;
}
rtKernelDetailInfo_t tail_kernel_info;
if (ctx.tail_tiling_key == ctx.tiling_key) {
tail_kernel_info = kernel_info;
} else {
GE_CHK_RT_RET(rtKernelGetAddrAndPrefCntV2(ctx.bin_handler, ctx.tail_tiling_key, ctx.kernel_unique_ids_addr,
ctx.flag, &tail_kernel_info));
if (!CheckKernelInfoValid(tail_kernel_info)) {
return ge::FAILED;
}
}
return ParseKernelInfo(kernel_info, tail_kernel_info, sink_ret);
}
default:
break;
}
return ge::SUCCESS;
}
UINT32 GetMixAddrAndPrefCnt(KernelContext *context) {
auto sink_ret = context->GetOutputPointer<AICoreSinkRet>(0U);
if (sink_ret == nullptr) {
GELOGE(ge::FAILED, "[kernel][SinkFFTSAICoreNodeBin] Sink ret is null.");
return ge::GRAPH_FAILED;
}
auto kernel_num = context->GetInputValue<size_t>(static_cast<size_t>(MIXDyInKey::KERNEL_NUM));
auto kernel_type = context->GetInputValue<size_t>(static_cast<size_t>(MIXDyInKey::KERNEL_TYPE));
auto tiling_key = context->GetInputValue<size_t>(static_cast<size_t>(MIXDyInKey::TILING_KEY));
auto tail_tiling_key = context->GetInputValue<size_t>(static_cast<size_t>(MIXDyInKey::TAIL_TILING_KEY));
GELOGD("Get Mix pc with num %u, task_type %u, key:%u/%u", kernel_num, kernel_type, tiling_key, tail_tiling_key);
size_t input_num = static_cast<size_t>(MIXDyInKey::PREFIX_START);
for (size_t i = 0U; i < kernel_num; ++i) {
auto prefix = context->GetInputValue<char *>(input_num++);
auto bin_handle = context->GetInputValue<void *>(input_num++);
if (bin_handle == nullptr) {
GELOGE(ge::FAILED, "[kernel][GetMixL2AddrAndPrefCnt] No bin handle.");
return ge::GRAPH_FAILED;
}
KernelFunctionCtx ctx(kernel_type, RT_DYNAMIC_SHAPE_KERNEL, tiling_key, tail_tiling_key, bin_handle, nullptr);
if (GetKernelFuncInfoByKernelType(ctx, prefix, sink_ret) != ge::SUCCESS) {
return ge::FAILED;
}
}
return ge::GRAPH_SUCCESS;
}
ge::graphStatus CreateMixSinkRet(const ge::FastNode *node, KernelContext *context) {
(void)node;
auto chain = context->GetOutput(0);
GE_ASSERT_NOTNULL(chain);
chain->SetWithDefaultDeleter(new AICoreSinkRet());
return ge::GRAPH_SUCCESS;
}
REGISTER_KERNEL(GetMixAddrAndPrefCnt).RunFunc(GetMixAddrAndPrefCnt).OutputsCreator(CreateMixSinkRet);
UINT32 SinkMixStaticNodeBin(KernelContext *context) {
auto sink_ret = context->GetOutputPointer<AICoreSinkRet>(0U);
GE_ASSERT_NOTNULL(sink_ret);
auto kernel_num = context->GetInputValue<size_t>(0);
auto kernel_type = context->GetInputValue<size_t>(1U);
size_t input_num = 2U;
for (size_t i = 0U; i < kernel_num; ++i) {
auto kernel_name = context->GetInputValue<char *>(input_num++);
GE_ASSERT_NOTNULL(kernel_name);
auto prefix = context->GetInputValue<char *>(input_num++);
GE_ASSERT_NOTNULL(prefix);
auto stub_name = context->GetInputValue<char *>(input_num++);
GE_ASSERT_NOTNULL(stub_name);
auto metadata = context->GetInputValue<char *>(input_num++);
GE_ASSERT_NOTNULL(metadata);
auto bin_data_holder = context->GetInputValue<kernel::BinData *>(input_num++);
GE_ASSERT_NOTNULL(bin_data_holder);
void *bin_handle;
rtDevBinary_t *bin_data = reinterpret_cast<rtDevBinary_t *>(bin_data_holder);
bin_data->data = &bin_data_holder->placeholder;
GE_ASSERT_RT_OK(rtDevBinaryRegister(bin_data, &bin_handle));
if (strlen(metadata) > 1U) {
GE_ASSERT_RT_OK(rtMetadataRegister(bin_handle, metadata));
}
static std::list<uint8_t> kernel_unique_ids;
static std::mutex mtx;
void *kernel_unique_ids_addr;
{
std::unique_lock<std::mutex> lk(mtx);
kernel_unique_ids.push_back(0U);
kernel_unique_ids_addr = &kernel_unique_ids.back();
}
GELOGD("register for kernel:%s prefix %s stub_name %s", kernel_name, prefix, stub_name);
GE_ASSERT_RT_OK(rtFunctionRegister(bin_handle, kernel_unique_ids_addr, stub_name, kernel_name, 0U));
KernelFunctionCtx ctx(kernel_type, RT_STATIC_SHAPE_KERNEL, 0U, 0U, bin_handle, kernel_unique_ids_addr);
if (GetKernelFuncInfoByKernelType(ctx, prefix, sink_ret) != ge::SUCCESS) {
return ge::FAILED;
}
}
return ge::GRAPH_SUCCESS;
}
REGISTER_KERNEL(SinkMixStaticNodeBin).RunFunc(SinkMixStaticNodeBin).OutputsCreator(CreateMixSinkRet);
}
}