已合并
【feat】: sk support tiling and custom value argsformat #3921
tang-haojie创建于 7月8日
【feat】: sk support tiling and custom value argsformat #3921
已合并
tang-haojie创建于 7月8日
8 个文件变更+567-64
@@ -604,17 +604,28 @@ static const std::map<std::string, PatternHandler, PatternCmp> kSkPatternToHandl
604};604};
605 605 
606static graphStatus ConvertArgDescNormal2Sk(const ArgDesc &normal_arg_desc, int32_t op_id, ArgDesc &sk_arg_desc) {606static graphStatus ConvertArgDescNormal2Sk(const ArgDesc &normal_arg_desc, int32_t op_id, ArgDesc &sk_arg_desc) {
607- GE_ASSERT_TRUE(normal_arg_desc.addr_type != AddrType::CUSTOM_VALUE);607+ SkArgDesc sk_arg_desc_tmp{};
608- SkArgDescV2 sk_arg_desc_tmp{};
609 sk_arg_desc_tmp.addr_type = AddrType::SUPER_KERNEL_SUB_NODE;608 sk_arg_desc_tmp.addr_type = AddrType::SUPER_KERNEL_SUB_NODE;
610 sk_arg_desc_tmp.ir_idx = op_id;609 sk_arg_desc_tmp.ir_idx = op_id;
611- if (normal_arg_desc.addr_type != AddrType::HIDDEN_INPUT) {610+ sk_arg_desc_tmp.sub_addr_type = static_cast<int16_t>(normal_arg_desc.addr_type);
612- sk_arg_desc_tmp.reserved = normal_arg_desc.folded;611+ if (normal_arg_desc.addr_type == AddrType::CUSTOM_VALUE) {
612+ sk_arg_desc_tmp.sub_idx = (normal_arg_desc.ir_idx == static_cast<int32_t>(ArgsFormatWidth::BIT64))
613+ ? static_cast<int16_t>(1)
614+ : static_cast<int16_t>(-1);
615+ (void)memcpy_s(sk_arg_desc_tmp.reserved, sizeof(sk_arg_desc_tmp.reserved), normal_arg_desc.reserved,
616+ sizeof(uint64_t));
617+ } else if (normal_arg_desc.addr_type == AddrType::HIDDEN_INPUT) {
618+ sk_arg_desc_tmp.sub_idx = static_cast<int16_t>(normal_arg_desc.ir_idx);
619+ uint32_t hidden_type = *reinterpret_cast<const uint32_t *>(normal_arg_desc.reserved);
620+ (void)memcpy_s(sk_arg_desc_tmp.reserved, sizeof(sk_arg_desc_tmp.reserved), &hidden_type, sizeof(uint32_t));
621+ } else if (normal_arg_desc.addr_type == AddrType::EVENT_ADDR) {
622+ sk_arg_desc_tmp.sub_idx = 0;
623+ const int32_t ir_idx = normal_arg_desc.ir_idx;
624+ (void)memcpy_s(sk_arg_desc_tmp.reserved, sizeof(sk_arg_desc_tmp.reserved), &ir_idx, sizeof(int32_t));
613 } else {625 } else {
614- sk_arg_desc_tmp.reserved = *reinterpret_cast<const uint32_t *>(normal_arg_desc.reserved);626+ sk_arg_desc_tmp.sub_idx = static_cast<int16_t>(normal_arg_desc.ir_idx);
atomgit-bot
atomgit-botatomgit-bot7月8日

🟡 Medium Priority

ConvertArgDescNormal2Sk 中,normal_arg_desc.ir_idx(int32_t)通过 static_cast<int16_t> 赋值给 SkArgDesc::sub_idx(int16_t):

旧代码中 SkArgDesc::sub_idxint32_t,不存在截断。新代码将其改为 int16_t 后,若 ir_idx 的值超出 [-32768, 32767],则发生静默截断,导致后续 ConvertArgDescSk2Normal 恢复出的 ir_idx 错误(例如 EVENT_ADDR 的 mem_event_id 被截断后取到错误的 event 地址,或 ir 索引被截断后匹配错误的输入/输出)。

实际场景中 EVENT_ADDR 的 ir_idx 作为 mem_event_id 使用(在 AssembleIoByArgsFormat 第 863 行被 static_cast<uint32_t> 读取),若原始值超过 32767 则会被截断。

建议:在 static_cast<int16_t> 之前添加范围检查,或恢复 sub_idxint32_t 类型。如果 sub_idx 必须保持 int16_t(为保持 24 字节 POD 布局),则需要对 normal_arg_desc.ir_idx 做范围断言,确保不会发生截断。

likedislike
627+ sk_arg_desc_tmp.reserved[0] = normal_arg_desc.folded ? 1 : 0;
615 }628 }
616- sk_arg_desc_tmp.sub_addr_type = normal_arg_desc.addr_type;
617- sk_arg_desc_tmp.sub_idx = normal_arg_desc.ir_idx;
618 sk_arg_desc = *reinterpret_cast<ArgDesc *>(&sk_arg_desc_tmp);629 sk_arg_desc = *reinterpret_cast<ArgDesc *>(&sk_arg_desc_tmp);
619 return GRAPH_SUCCESS;630 return GRAPH_SUCCESS;
620}631}
@@ -628,16 +639,30 @@ static graphStatus ConvertArgDescSk2Normal(const ArgDesc &sk_arg_desc, ArgDesc &
628 ArgDesc tmp_arg_desc{};639 ArgDesc tmp_arg_desc{};
629 const SkArgDesc *sk_arg_desc_tmp = reinterpret_cast<const SkArgDesc *>(&sk_arg_desc);640 const SkArgDesc *sk_arg_desc_tmp = reinterpret_cast<const SkArgDesc *>(&sk_arg_desc);
630 sub_op_id = sk_arg_desc_tmp->ir_idx;641 sub_op_id = sk_arg_desc_tmp->ir_idx;
631- if (sk_arg_desc_tmp->sub_addr_type != AddrType::HIDDEN_INPUT) {642+ const auto sub_addr_type = static_cast<AddrType>(sk_arg_desc_tmp->sub_addr_type);
632- tmp_arg_desc.addr_type = sk_arg_desc_tmp->sub_addr_type;643+ if (sub_addr_type == AddrType::CUSTOM_VALUE) {
633- tmp_arg_desc.ir_idx = sk_arg_desc_tmp->sub_idx;644+ tmp_arg_desc.addr_type = AddrType::CUSTOM_VALUE;
634- tmp_arg_desc.folded = sk_arg_desc_tmp->folded;645+ tmp_arg_desc.ir_idx = (sk_arg_desc_tmp->sub_idx > 0) ? static_cast<int32_t>(ArgsFormatWidth::BIT64)
635- } else {646+ : static_cast<int32_t>(ArgsFormatWidth::BIT32);
636- const SkArgDescV2 *sk_arg_desc_v2_tmp = reinterpret_cast<const SkArgDescV2 *>(&sk_arg_desc);
637- tmp_arg_desc.addr_type = sk_arg_desc_v2_tmp->sub_addr_type;
638- tmp_arg_desc.ir_idx = sk_arg_desc_v2_tmp->sub_idx;
639 tmp_arg_desc.folded = false;647 tmp_arg_desc.folded = false;
640- *reinterpret_cast<uint32_t *>(tmp_arg_desc.reserved) = sk_arg_desc_v2_tmp->reserved;648+ (void)memcpy_s(tmp_arg_desc.reserved, sizeof(tmp_arg_desc.reserved), sk_arg_desc_tmp->reserved, sizeof(uint64_t));
649+ } else if (sub_addr_type == AddrType::HIDDEN_INPUT) {
650+ tmp_arg_desc.addr_type = AddrType::HIDDEN_INPUT;
651+ tmp_arg_desc.ir_idx = sk_arg_desc_tmp->sub_idx;
652+ tmp_arg_desc.folded = false;
653+ uint32_t hidden_type = 0;
654+ (void)memcpy_s(&hidden_type, sizeof(hidden_type), sk_arg_desc_tmp->reserved, sizeof(uint32_t));
655+ *reinterpret_cast<uint32_t *>(tmp_arg_desc.reserved) = hidden_type;
656+ } else if (sub_addr_type == AddrType::EVENT_ADDR) {
657+ tmp_arg_desc.addr_type = AddrType::EVENT_ADDR;
658+ int32_t ir_idx = 0;
659+ (void)memcpy_s(&ir_idx, sizeof(ir_idx), sk_arg_desc_tmp->reserved, sizeof(int32_t));
660+ tmp_arg_desc.ir_idx = ir_idx;
661+ tmp_arg_desc.folded = false;
662+ } else {
663+ tmp_arg_desc.addr_type = sub_addr_type;
664+ tmp_arg_desc.ir_idx = sk_arg_desc_tmp->sub_idx;
665+ tmp_arg_desc.folded = sk_arg_desc_tmp->reserved[0] != 0;
641 }666 }
642 arg_desc = tmp_arg_desc;667 arg_desc = tmp_arg_desc;
643 return GRAPH_SUCCESS;668 return GRAPH_SUCCESS;
@@ -32,20 +32,12 @@ enum class ArgsFormatWidth : int32_t {
32struct SkArgDesc {32struct SkArgDesc {
33 AddrType addr_type;33 AddrType addr_type;
34 int32_t ir_idx;34 int32_t ir_idx;
35- bool folded;35+ int16_t sub_addr_type;
36- AddrType sub_addr_type;36+ int16_t sub_idx;
37- int32_t sub_idx;37+ uint8_t reserved[8];
38};38};
39static_assert(std::is_standard_layout<SkArgDesc>::value, "The class SkArgDesc must be a POD");39static_assert(std::is_standard_layout<SkArgDesc>::value, "The class SkArgDesc must be a POD");
40- 40+static_assert(sizeof(SkArgDesc) == sizeof(ArgDesc), "SkArgDesc must be same size as ArgDesc");
41-struct SkArgDescV2 {
42- AddrType addr_type;
43- int32_t ir_idx;
44- uint32_t reserved;
45- AddrType sub_addr_type;
46- int32_t sub_idx;
47-};
48-static_assert(std::is_standard_layout<SkArgDescV2>::value, "The class SkArgDescV2 must be a POD");
49 41 
50class ArgsFormatDesc {42class ArgsFormatDesc {
51 public:43 public:
@@ -1692,13 +1692,11 @@ Status KernelTaskInfo::PreprocessForSkNode() {
1692 auto &arg_descs = args_format_holder_.arg_descs;1692 auto &arg_descs = args_format_holder_.arg_descs;
1693 int32_t sub_node_id = -1;1693 int32_t sub_node_id = -1;
1694 for (const auto &arg_format : arg_descs) {1694 for (const auto &arg_format : arg_descs) {
1695- ArgDesc tmp_arg_desc = arg_format;1695+ ArgDesc tmp_arg_desc{};
1696+ int32_t tmp_sub_node_id = 0;
1697+ GE_ASSERT_SUCCESS(ArgsFormatDesc::ConvertArgDescSkToNormal(arg_format, tmp_arg_desc, tmp_sub_node_id));
1696 if (arg_format.addr_type == AddrType::SUPER_KERNEL_SUB_NODE) {1698 if (arg_format.addr_type == AddrType::SUPER_KERNEL_SUB_NODE) {
1697- const SkArgDesc *sk_args_desc = reinterpret_cast<const SkArgDesc *>(&arg_format);1699+ sub_node_id = tmp_sub_node_id;
1698- tmp_arg_desc.addr_type = sk_args_desc->sub_addr_type;
1699- tmp_arg_desc.ir_idx = sk_args_desc->sub_idx;
1700- tmp_arg_desc.folded = sk_args_desc->folded;
1701- sub_node_id = sk_args_desc->ir_idx;
1702 }1700 }
1703 sub_arg_descs.emplace_back(tmp_arg_desc);1701 sub_arg_descs.emplace_back(tmp_arg_desc);
1704 }1702 }
@@ -728,6 +728,31 @@ Status SuperKernelV2TaskInfo::AssembleTilingContextArgs(int32_t node_idx, const
728 return SUCCESS;728 return SUCCESS;
729}729}
730 730 
731+Status SuperKernelV2TaskInfo::CopySubNodeTilingDataIfNeeded() {
732+ sub_node_tiling_data_addrs_.resize(sub_node_op_desc_list_.size(), nullptr);
733+ for (size_t node_idx = 0U; node_idx < sub_node_op_desc_list_.size(); ++node_idx) {
734+ const auto &sub_op_desc = sub_node_op_desc_list_[node_idx];
735+ std::shared_ptr<optiling::utils::OpRunInfo> default_tiling = nullptr;
736+ auto run_info = sub_op_desc->TryGetExtAttr(ge::ATTR_NAME_OP_RUN_INFO, default_tiling);
737+ if (run_info == nullptr) {
738+ continue;
739+ }
740+ if (run_info->GetAllTilingData().str().empty()) {
741+ GELOGD("Tiling data of sub node[%zu] %s is empty.", node_idx, sub_op_desc->GetNamePtr());
742+ continue;
743+ }
744+ const std::string &tiling_data = run_info->GetAllTilingData().str();
745+ const size_t tiling_data_size = tiling_data.size();
746+ sub_node_tiling_data_addrs_[node_idx] = davinci_model_->MallocDynamicMemory(tiling_data_size);
747+ GE_CHECK_NOTNULL(sub_node_tiling_data_addrs_[node_idx]);
748+ GE_CHK_RT_RET(aclrtMemcpy(sub_node_tiling_data_addrs_[node_idx], tiling_data_size, tiling_data.data(),
749+ tiling_data_size, ACL_MEMCPY_HOST_TO_DEVICE));
750+ GELOGI("Success to copy tiling data for sub node[%zu] %s, addr: %p, size: %zu.", node_idx,
751+ sub_op_desc->GetNamePtr(), sub_node_tiling_data_addrs_[node_idx], tiling_data_size);
752+ }
753+ return SUCCESS;
754+}
755+ 
731Status SuperKernelV2TaskInfo::AssembleIoByArgsFormat() {756Status SuperKernelV2TaskInfo::AssembleIoByArgsFormat() {
732 std::vector<std::vector<size_t>> sub_node_level_addr_idx;757 std::vector<std::vector<size_t>> sub_node_level_addr_idx;
733 std::vector<std::vector<ArgDesc>> sub_node_dynamic_args_desc;758 std::vector<std::vector<ArgDesc>> sub_node_dynamic_args_desc;
@@ -743,6 +768,7 @@ Status SuperKernelV2TaskInfo::AssembleIoByArgsFormat() {
743 GE_ASSERT_TRUE(node_num == sub_node_input_addrs_list_.size());768 GE_ASSERT_TRUE(node_num == sub_node_input_addrs_list_.size());
744 GE_ASSERT_TRUE(node_num == sub_node_output_addrs_list_.size());769 GE_ASSERT_TRUE(node_num == sub_node_output_addrs_list_.size());
745 GE_ASSERT_TRUE(node_num == sub_node_workspace_addrs_list_.size());770 GE_ASSERT_TRUE(node_num == sub_node_workspace_addrs_list_.size());
atomgit-bot
atomgit-botatomgit-bot7月8日

🟡 Medium Priority

AssembleIoByArgsFormat(super_kernel_task_info.cc 第 768-770 行)对 sub_node_input_addrs_list_sub_node_output_addrs_list_sub_node_workspace_addrs_list_ 均做了 GE_ASSERT_TRUE(node_num == ...size()) 断言,但未对新增的 sub_node_tiling_data_addrs_ 做同样的断言。

随后在第 910 行直接访问 sub_node_tiling_data_addrs_[node_idx],若 CopySubNodeTilingDataIfNeeded() 未被调用、调用失败或向量大小不匹配,会导致越界访问(未定义行为)。虽然当前代码路径中 CopySubNodeTilingDataIfNeededInitKernel 中紧邻调用,但该不变量未显式检查,缺少防御性编程保护。

建议:在第 770 行后添加 GE_ASSERT_TRUE(node_num == sub_node_tiling_data_addrs_.size());

改动建议
770
- GE_ASSERT_TRUE(node_num == sub_node_workspace_addrs_list_.size());
770
+ GE_ASSERT_TRUE(node_num == sub_node_workspace_addrs_list_.size());
771
+ GE_ASSERT_TRUE(node_num == sub_node_tiling_data_addrs_.size());
应用建议
likedislike
771+ GE_ASSERT_TRUE(node_num == sub_node_tiling_data_addrs_.size());
746 for (const auto &args_format_holder : sub_node_args_format_holder_list_) {772 for (const auto &args_format_holder : sub_node_args_format_holder_list_) {
747 const std::map<size_t, std::pair<size_t, size_t>> &ir_input_2_range = args_format_holder.ir_input_2_range;773 const std::map<size_t, std::pair<size_t, size_t>> &ir_input_2_range = args_format_holder.ir_input_2_range;
748 const std::map<size_t, std::pair<size_t, size_t>> &ir_output_2_range = args_format_holder.ir_output_2_range;774 const std::map<size_t, std::pair<size_t, size_t>> &ir_output_2_range = args_format_holder.ir_output_2_range;
@@ -875,10 +901,16 @@ Status SuperKernelV2TaskInfo::AssembleIoByArgsFormat() {
875 }901 }
876 break;902 break;
877 }903 }
878- case AddrType::TILING:
879 case AddrType::CUSTOM_VALUE: {904 case AddrType::CUSTOM_VALUE: {
880- GELOGE(FAILED, "super kernel no support args format add type %d", arg_format.addr_type);905+ l0_dump_list_.push_back(std::numeric_limits<uint64_t>::max());
881- return FAILED;906+ AppendIoAddr(*reinterpret_cast<const uint64_t *>(arg_format.reserved), kAbsoluteMemType);
907+ break;
908+ }
909+ case AddrType::TILING: {
910+ l0_dump_list_.push_back(std::numeric_limits<uint64_t>::max());
911+ GE_ASSERT_NOTNULL(sub_node_tiling_data_addrs_[node_idx], "Sub node[%zu] tiling data addr is null.", node_idx);
912+ AppendIoAddr(PtrToValue(sub_node_tiling_data_addrs_[node_idx]), kAbsoluteMemType);
913+ break;
882 }914 }
883 default:915 default:
884 l0_dump_list_.push_back(std::numeric_limits<uint64_t>::max()); // 占位916 l0_dump_list_.push_back(std::numeric_limits<uint64_t>::max()); // 占位
@@ -984,6 +1016,7 @@ Status SuperKernelV2TaskInfo::InitKernel(const domi::TaskDef &task_def, const Pi
984 "[Check][Param] Op:%s, dev addr is nullptr.", op_desc_->GetName().c_str());1016 "[Check][Param] Op:%s, dev addr is nullptr.", op_desc_->GetName().c_str());
985 args_ = ValueToPtr(args[static_cast<size_t>(args_placement_)].dev_addr);1017 args_ = ValueToPtr(args[static_cast<size_t>(args_placement_)].dev_addr);
986 1018 
1019+ GE_ASSERT_SUCCESS(CopySubNodeTilingDataIfNeeded(), "Copy sub node tiling data failed.");
987 GE_ASSERT_SUCCESS(AssembleIoByArgsFormat(), "[Assemble][Addresses] failed, op = %s.", op_desc_->GetNamePtr());1020 GE_ASSERT_SUCCESS(AssembleIoByArgsFormat(), "[Assemble][Addresses] failed, op = %s.", op_desc_->GetNamePtr());
988 1021 
989 Status ret = InitTask(kernel_def);1022 Status ret = InitTask(kernel_def);
@@ -120,6 +120,7 @@ class SuperKernelV2TaskInfo : public TaskInfo {
120 Status AssembleTilingSinkTensors(std::map<int32_t, std::map<size_t, gert::AddrRefreshedTensor>> &index_to_tensor);120 Status AssembleTilingSinkTensors(std::map<int32_t, std::map<size_t, gert::AddrRefreshedTensor>> &index_to_tensor);
121 void GetAddrAlignedGertTensorSize(size_t &io_aligned_offset, size_t &double_aliged_tensor_size) const;121 void GetAddrAlignedGertTensorSize(size_t &io_aligned_offset, size_t &double_aliged_tensor_size) const;
122 Status AssembleIoByArgsFormat();122 Status AssembleIoByArgsFormat();
123+ Status CopySubNodeTilingDataIfNeeded();
123 void AppendIoAddr(const uint64_t addr, const uint64_t addr_type);124 void AppendIoAddr(const uint64_t addr, const uint64_t addr_type);
124 Status AppendWorkspaceAddr(size_t node_idx, int32_t ir_idx);125 Status AppendWorkspaceAddr(size_t node_idx, int32_t ir_idx);
125 Status AppendInputOutputAddrByInstanceIndex(size_t node_idx, size_t ins_idx, bool is_input);126 Status AppendInputOutputAddrByInstanceIndex(size_t node_idx, size_t ins_idx, bool is_input);
@@ -157,6 +158,7 @@ class SuperKernelV2TaskInfo : public TaskInfo {
157 std::vector<std::vector<uint64_t>> sub_node_input_mem_types_list_;158 std::vector<std::vector<uint64_t>> sub_node_input_mem_types_list_;
158 std::vector<std::vector<uint64_t>> sub_node_output_mem_types_list_;159 std::vector<std::vector<uint64_t>> sub_node_output_mem_types_list_;
159 std::vector<std::vector<uint64_t>> sub_node_workspace_mem_types_list_;160 std::vector<std::vector<uint64_t>> sub_node_workspace_mem_types_list_;
161+ std::vector<void *> sub_node_tiling_data_addrs_;
160 162 
161 // dump相关163 // dump相关
162 uint32_t dump_flag_{RT_KERNEL_DEFAULT};164 uint32_t dump_flag_{RT_KERNEL_DEFAULT};
@@ -4297,6 +4297,9 @@ TEST_F(DavinciModelTest, super_kernel_graph_load_and_success) {
4297 op_desc_1->AppendIrOutput("z", IrOutputType::kIrOutputRequired);4297 op_desc_1->AppendIrOutput("z", IrOutputType::kIrOutputRequired);
4298 4298 
4299 op_desc_1->SetId(19);4299 op_desc_1->SetId(19);
4300+ auto run_info_1 = std::make_shared<optiling::utils::OpRunInfo>(0, false, 0);
4301+ run_info_1->AddTilingData("sk_sub_node_tiling_data");
4302+ op_desc_1->SetExtAttr(ATTR_NAME_OP_RUN_INFO, run_info_1);
4300 4303 
4301 // 初始化subnode24304 // 初始化subnode2
4302 auto skt_sub_node_2 = sub_graph->FindNode("node_2");4305 auto skt_sub_node_2 = sub_graph->FindNode("node_2");
@@ -4458,11 +4461,12 @@ TEST_F(DavinciModelTest, super_kernel_graph_load_and_success) {
4458 aicore_context.set_op_id(super_node->GetOpDescBarePtr()->GetId());4461 aicore_context.set_op_id(super_node->GetOpDescBarePtr()->GetId());
4459 aicore_context.set_op_index(super_node->GetOpDescBarePtr()->GetId());4462 aicore_context.set_op_index(super_node->GetOpDescBarePtr()->GetId());
4460 aicore_context.set_args_format(4463 aicore_context.set_args_format(
4461- "{skn19ffts_addr}{skn19i_desc0}{skn19i_desc1}{skn19o0}{skn19ws0}{skn20ffts_addr}{skn20event_addr123*}"4464+ "{skn19ffts_addr}{skn19i_desc0}{skn19i_desc1}{skn19o0}{skn19ws0}{skn19t}{skn19#42}{skn20ffts_addr}{skn20event_"
4465+ "addr123*}"
4462 "{skn20i_desc0}{skn20i1}{skn20i_instance3}{skn20o_desc0}{skn20o_instance2}{skn20ws*}{skn20hi.hcom0*}"4466 "{skn20i_desc0}{skn20i1}{skn20i_instance3}{skn20o_desc0}{skn20o_instance2}{skn20ws*}{skn20hi.hcom0*}"
4463- "{skn20tiling_context}{skn20tiling_context.tiling_data}{skn20*op_type}{skn20tiling_context.tiling_key}{"4467+ "{skn20tiling_context}{skn20tiling_context.tiling_data}{skn20*op_type}{skn20tiling_context.tiling_key}"
4464- "skn20tiling_context.block_dim}{ws0}{overflow_addr}");4468+ "{skn20tiling_context.block_dim}{ws0}{overflow_addr}");
4465- aicore_context.set_args_count(14);4469+ aicore_context.set_args_count(16);
4466 uint16_t args_offset = 0;4470 uint16_t args_offset = 0;
4467 aicore_context.set_args_offset(&args_offset, sizeof(uint16_t));4471 aicore_context.set_args_offset(&args_offset, sizeof(uint16_t));
4468 size_t args_size = 128UL;4472 size_t args_size = 128UL;
@@ -5716,6 +5716,43 @@ void StubExceptionFunc(aclrtExceptionInfo *exception_info, void *reserved) {
5716 (void)reserved;5716 (void)reserved;
5717}5717}
5718 5718 
5719+TEST_F(UtestKernelTaskInfo, AssembleIoByArgsFormat_CustomValue_Success) {
5720+ SuperKernelV2TaskInfo sk_task_info;
5721+ sk_task_info.task_type_ = ModelTaskType::MODEL_TASK_SUPER_KERNEL;
5722+ sk_task_info.kernel_type_ = ccKernelType::MIX_VECTOR_CORE;
5723+ sk_task_info.sub_node_op_index_list_.emplace_back(0);
5724+ 
5725+ auto op_desc = CreateOpDesc("relu", RELU);
5726+ sk_task_info.sub_node_op_desc_list_.emplace_back(op_desc);
5727+ 
5728+ SuperKernelV2TaskInfo::ArgsFormatInfo sub_node_args_format_holder = {};
5729+ ArgDesc custom_value_desc{};
5730+ custom_value_desc.addr_type = AddrType::CUSTOM_VALUE;
5731+ custom_value_desc.ir_idx = static_cast<int32_t>(ArgsFormatWidth::BIT64);
5732+ custom_value_desc.folded = false;
5733+ uint64_t payload = 42ULL;
5734+ (void)memcpy_s(custom_value_desc.reserved, sizeof(custom_value_desc.reserved), &payload, sizeof(uint64_t));
5735+ sub_node_args_format_holder.arg_descs.push_back(custom_value_desc);
5736+ sk_task_info.sub_node_args_format_holder_list_.push_back(sub_node_args_format_holder);
5737+ 
5738+ std::vector<uint64_t> fake_addr{1};
5739+ sk_task_info.sub_node_input_addrs_list_.emplace_back(fake_addr);
5740+ sk_task_info.sub_node_output_addrs_list_.emplace_back(fake_addr);
5741+ sk_task_info.sub_node_workspace_addrs_list_.emplace_back(fake_addr);
5742+ sk_task_info.sub_node_input_mem_types_list_.emplace_back(fake_addr);
5743+ sk_task_info.sub_node_output_mem_types_list_.emplace_back(fake_addr);
5744+ sk_task_info.sub_node_workspace_mem_types_list_.emplace_back(fake_addr);
5745+ sk_task_info.sub_node_tiling_data_addrs_.emplace_back(nullptr);
5746+ sk_task_info.op_desc_ = CreateOpDesc("sk", "SuperKernel");
5747+ sk_task_info.args_ = 0x0;
5748+ 
5749+ EXPECT_EQ(sk_task_info.AssembleIoByArgsFormat(), SUCCESS);
5750+ EXPECT_EQ(sk_task_info.io_addrs_.size(), 1);
5751+ EXPECT_EQ(sk_task_info.io_addrs_[0], 42ULL);
5752+ EXPECT_EQ(sk_task_info.l0_dump_list_.size(), 1);
5753+ EXPECT_EQ(sk_task_info.l0_dump_list_[0], std::numeric_limits<uint64_t>::max());
5754+}
5755+ 
5719TEST_F(UtestKernelTaskInfo, SetExceptionCallback_Success) {5756TEST_F(UtestKernelTaskInfo, SetExceptionCallback_Success) {
5720 gert::SpaceRegistryFaker::UpdateOpImplToDefaultSpaceRegistry();5757 gert::SpaceRegistryFaker::UpdateOpImplToDefaultSpaceRegistry();
5721 auto space_registry_array = gert::OpImplSpaceRegistryV2Array();5758 auto space_registry_array = gert::OpImplSpaceRegistryV2Array();
@@ -5819,4 +5856,74 @@ TEST_F(UtestKernelTaskInfo, SetExceptionCallback_Success) {
5819 EXPECT_EQ(model.DistributeTask(model_task_def), SUCCESS);5856 EXPECT_EQ(model.DistributeTask(model_task_def), SUCCESS);
5820 }5857 }
5821}5858}
5859+ 
5860+TEST_F(UtestKernelTaskInfo, CopySubNodeTilingDataIfNeeded_Success) {
5861+ DavinciModel model(0, nullptr);
5862+ model.SetKnownNode(true);
5863+ model.runtime_param_.mem_size = 2048U;
5864+ std::vector<uint8_t> memory_holder(model.runtime_param_.mem_size);
5865+ model.runtime_param_.mem_base = reinterpret_cast<uintptr_t>(memory_holder.data());
5866+ MemAllocation fm_mem_allocation = {0, 0, UINT64_MAX, ge::MemAllocation::Type::FEATURE_MAP, 0U};
5867+ model.logical_mem_allocations_.emplace_back(fm_mem_allocation);
5868+ 
5869+ SuperKernelV2TaskInfo sk_task_info;
5870+ sk_task_info.davinci_model_ = &model;
5871+ 
5872+ auto op_desc_1 = CreateOpDesc("relu1", RELU);
5873+ auto run_info_1 = std::make_shared<optiling::utils::OpRunInfo>(0, false, 0);
5874+ run_info_1->AddTilingData("tiling_data_for_node1");
5875+ op_desc_1->SetExtAttr(ATTR_NAME_OP_RUN_INFO, run_info_1);
5876+ sk_task_info.sub_node_op_desc_list_.emplace_back(op_desc_1);
5877+ 
5878+ auto op_desc_2 = CreateOpDesc("relu2", RELU);
5879+ sk_task_info.sub_node_op_desc_list_.emplace_back(op_desc_2);
5880+ 
5881+ auto op_desc_3 = CreateOpDesc("relu3", RELU);
5882+ auto run_info_3 = std::make_shared<optiling::utils::OpRunInfo>(0, false, 0);
5883+ run_info_3->AddTilingData("tiling_data_for_node3");
5884+ op_desc_3->SetExtAttr(ATTR_NAME_OP_RUN_INFO, run_info_3);
5885+ sk_task_info.sub_node_op_desc_list_.emplace_back(op_desc_3);
5886+ 
5887+ EXPECT_EQ(sk_task_info.CopySubNodeTilingDataIfNeeded(), SUCCESS);
5888+ EXPECT_EQ(sk_task_info.sub_node_tiling_data_addrs_.size(), 3U);
5889+ EXPECT_NE(sk_task_info.sub_node_tiling_data_addrs_[0], nullptr);
5890+ EXPECT_EQ(sk_task_info.sub_node_tiling_data_addrs_[1], nullptr);
5891+ EXPECT_NE(sk_task_info.sub_node_tiling_data_addrs_[2], nullptr);
5892+}
5893+ 
5894+TEST_F(UtestKernelTaskInfo, AssembleIoByArgsFormat_Tiling_Success) {
5895+ SuperKernelV2TaskInfo sk_task_info;
5896+ sk_task_info.task_type_ = ModelTaskType::MODEL_TASK_SUPER_KERNEL;
5897+ sk_task_info.kernel_type_ = ccKernelType::MIX_VECTOR_CORE;
5898+ sk_task_info.sub_node_op_index_list_.emplace_back(0);
5899+ 
5900+ auto op_desc = CreateOpDesc("relu", RELU);
5901+ sk_task_info.sub_node_op_desc_list_.emplace_back(op_desc);
5902+ 
5903+ SuperKernelV2TaskInfo::ArgsFormatInfo sub_node_args_format_holder = {};
5904+ ArgDesc tiling_desc{};
5905+ tiling_desc.addr_type = AddrType::TILING;
5906+ sub_node_args_format_holder.arg_descs.push_back(tiling_desc);
5907+ sk_task_info.sub_node_args_format_holder_list_.push_back(sub_node_args_format_holder);
5908+ 
5909+ std::vector<uint64_t> fake_addr{1};
5910+ sk_task_info.sub_node_input_addrs_list_.emplace_back(fake_addr);
5911+ sk_task_info.sub_node_output_addrs_list_.emplace_back(fake_addr);
5912+ sk_task_info.sub_node_workspace_addrs_list_.emplace_back(fake_addr);
5913+ sk_task_info.sub_node_input_mem_types_list_.emplace_back(fake_addr);
5914+ sk_task_info.sub_node_output_mem_types_list_.emplace_back(fake_addr);
5915+ sk_task_info.sub_node_workspace_mem_types_list_.emplace_back(fake_addr);
5916+ sk_task_info.op_desc_ = CreateOpDesc("sk", "SuperKernel");
5917+ sk_task_info.args_ = 0x0;
5918+ 
5919+ void *fake_tiling_addr = reinterpret_cast<void *>(0xDEADBEEF);
5920+ sk_task_info.sub_node_tiling_data_addrs_.push_back(fake_tiling_addr);
5921+ 
5922+ EXPECT_EQ(sk_task_info.AssembleIoByArgsFormat(), SUCCESS);
5923+ EXPECT_EQ(sk_task_info.io_addrs_.size(), 1U);
5924+ EXPECT_EQ(sk_task_info.io_addrs_[0], PtrToValue(fake_tiling_addr));
5925+ EXPECT_EQ(sk_task_info.l0_dump_list_.size(), 1U);
5926+ EXPECT_EQ(sk_task_info.l0_dump_list_[0], std::numeric_limits<uint64_t>::max());
5927+}
5928+ 
5822} // namespace ge5929} // namespace ge
@@ -9,6 +9,7 @@
9 */9 */
10 10 
11#include <gtest/gtest.h>11#include <gtest/gtest.h>
12+#include <cstring>
12#include <memory>13#include <memory>
13#include <string>14#include <string>
14 15 
@@ -569,7 +570,8 @@ TEST_F(UtestArgsFormatDesc, SknArgDescTest) {
569 EXPECT_NE(sub_graph, nullptr);570 EXPECT_NE(sub_graph, nullptr);
570 EXPECT_NE(op_desc, nullptr);571 EXPECT_NE(op_desc, nullptr);
571 op_desc->SetExtAttr("_sk_sub_graph", sub_graph);572 op_desc->SetExtAttr("_sk_sub_graph", sub_graph);
572- SkArgDesc sk_desc = {AddrType::SUPER_KERNEL_SUB_NODE, 1, false, AddrType::INPUT, 0};573+ SkArgDesc sk_desc = {
574+ AddrType::SUPER_KERNEL_SUB_NODE, 1, static_cast<int16_t>(AddrType::INPUT), static_cast<int16_t>(0), {0}};
573 ArgDesc sub_desc = *reinterpret_cast<ArgDesc *>(&sk_desc);575 ArgDesc sub_desc = *reinterpret_cast<ArgDesc *>(&sk_desc);
574 std::vector<ArgDesc> args_desc_vec;576 std::vector<ArgDesc> args_desc_vec;
575 args_desc_vec.emplace_back(sub_desc);577 args_desc_vec.emplace_back(sub_desc);
@@ -587,7 +589,6 @@ TEST_F(UtestArgsFormatDesc, SknArgDescTest) {
587 EXPECT_EQ(target_sub_desc_vec.size(), 1);589 EXPECT_EQ(target_sub_desc_vec.size(), 1);
588 EXPECT_EQ(target_sub_desc_vec[0].ir_idx, sub_desc.ir_idx);590 EXPECT_EQ(target_sub_desc_vec[0].ir_idx, sub_desc.ir_idx);
589 EXPECT_EQ(target_sub_desc_vec[0].addr_type, sub_desc.addr_type);591 EXPECT_EQ(target_sub_desc_vec[0].addr_type, sub_desc.addr_type);
590- EXPECT_EQ(target_sub_desc_vec[0].folded, sub_desc.folded);
591 592 
592 EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_idx,593 EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_idx,
593 reinterpret_cast<SkArgDesc *>(&sub_desc)->sub_idx);594 reinterpret_cast<SkArgDesc *>(&sub_desc)->sub_idx);
@@ -607,15 +608,19 @@ TEST_F(UtestArgsFormatDesc, SknArgDescTestHiddenInput) {
607 EXPECT_NE(sub_graph, nullptr);608 EXPECT_NE(sub_graph, nullptr);
608 EXPECT_NE(op_desc, nullptr);609 EXPECT_NE(op_desc, nullptr);
609 op_desc->SetExtAttr("_sk_sub_graph", sub_graph);610 op_desc->SetExtAttr("_sk_sub_graph", sub_graph);
610- SkArgDescV2 sk_desc = {AddrType::SUPER_KERNEL_SUB_NODE, 1, static_cast<uint32_t>(HiddenInputsType::HCOM),611+ SkArgDesc sk_desc = {
611- AddrType::HIDDEN_INPUT, 0};612+ AddrType::SUPER_KERNEL_SUB_NODE, 1, static_cast<int16_t>(AddrType::HIDDEN_INPUT), static_cast<int16_t>(0), {0}};
613+ uint32_t hcom_type = static_cast<uint32_t>(HiddenInputsType::HCOM);
614+ (void)memcpy_s(sk_desc.reserved, sizeof(sk_desc.reserved), &hcom_type, sizeof(uint32_t));
612 auto sub_desc = *reinterpret_cast<ArgDesc *>(&sk_desc);615 auto sub_desc = *reinterpret_cast<ArgDesc *>(&sk_desc);
613 std::vector<ArgDesc> args_desc_vec;616 std::vector<ArgDesc> args_desc_vec;
614 args_desc_vec.emplace_back(*reinterpret_cast<ArgDesc *>(&sk_desc));617 args_desc_vec.emplace_back(*reinterpret_cast<ArgDesc *>(&sk_desc));
615 618 
616- sk_desc.reserved = static_cast<uint32_t>(HiddenInputsType::TILEFWK);619+ uint32_t tilefwk_type = static_cast<uint32_t>(HiddenInputsType::TILEFWK);
620+ (void)memcpy_s(sk_desc.reserved, sizeof(sk_desc.reserved), &tilefwk_type, sizeof(uint32_t));
617 args_desc_vec.emplace_back(*reinterpret_cast<ArgDesc *>(&sk_desc));621 args_desc_vec.emplace_back(*reinterpret_cast<ArgDesc *>(&sk_desc));
618- sk_desc.reserved = static_cast<uint32_t>(HiddenInputsType::HCCLSUPERKERNEL);622+ uint32_t hcclsk_type = static_cast<uint32_t>(HiddenInputsType::HCCLSUPERKERNEL);
623+ (void)memcpy_s(sk_desc.reserved, sizeof(sk_desc.reserved), &hcclsk_type, sizeof(uint32_t));
619 args_desc_vec.emplace_back(*reinterpret_cast<ArgDesc *>(&sk_desc));624 args_desc_vec.emplace_back(*reinterpret_cast<ArgDesc *>(&sk_desc));
620 625 
621 auto str = ArgsFormatDesc::Serialize(args_desc_vec);626 auto str = ArgsFormatDesc::Serialize(args_desc_vec);
@@ -627,24 +632,30 @@ TEST_F(UtestArgsFormatDesc, SknArgDescTestHiddenInput) {
627 EXPECT_EQ(target_sub_desc_vec.size(), 3);632 EXPECT_EQ(target_sub_desc_vec.size(), 3);
628 EXPECT_EQ(target_sub_desc_vec[0].ir_idx, sub_desc.ir_idx);633 EXPECT_EQ(target_sub_desc_vec[0].ir_idx, sub_desc.ir_idx);
629 EXPECT_EQ(target_sub_desc_vec[0].addr_type, sub_desc.addr_type);634 EXPECT_EQ(target_sub_desc_vec[0].addr_type, sub_desc.addr_type);
630- EXPECT_EQ(target_sub_desc_vec[0].folded, sub_desc.folded);
631 635 
632 EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_idx,636 EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_idx,
633 reinterpret_cast<SkArgDesc *>(&sub_desc)->sub_idx);637 reinterpret_cast<SkArgDesc *>(&sub_desc)->sub_idx);
634 EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_idx, 0);638 EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_idx, 0);
635 EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_addr_type,639 EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_addr_type,
636 reinterpret_cast<SkArgDesc *>(&sub_desc)->sub_addr_type);640 reinterpret_cast<SkArgDesc *>(&sub_desc)->sub_addr_type);
637- EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_addr_type, AddrType::HIDDEN_INPUT);641+ EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_addr_type,
638- EXPECT_EQ(reinterpret_cast<SkArgDescV2 *>(&target_sub_desc_vec[0])->reserved,642+ static_cast<int16_t>(AddrType::HIDDEN_INPUT));
639- static_cast<uint32_t>(HiddenInputsType::HCOM));643+ uint32_t reserved_val = 0;
644+ (void)memcpy_s(&reserved_val, sizeof(reserved_val), reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->reserved,
645+ sizeof(uint32_t));
646+ EXPECT_EQ(reserved_val, static_cast<uint32_t>(HiddenInputsType::HCOM));
640 647 
641- EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[1])->sub_addr_type, AddrType::HIDDEN_INPUT);648+ EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[1])->sub_addr_type,
642- EXPECT_EQ(reinterpret_cast<SkArgDescV2 *>(&target_sub_desc_vec[1])->reserved,649+ static_cast<int16_t>(AddrType::HIDDEN_INPUT));
643- static_cast<uint32_t>(HiddenInputsType::TILEFWK));650+ (void)memcpy_s(&reserved_val, sizeof(reserved_val), reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[1])->reserved,
651+ sizeof(uint32_t));
652+ EXPECT_EQ(reserved_val, static_cast<uint32_t>(HiddenInputsType::TILEFWK));
644 653 
645- EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[2])->sub_addr_type, AddrType::HIDDEN_INPUT);654+ EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[2])->sub_addr_type,
646- EXPECT_EQ(reinterpret_cast<SkArgDescV2 *>(&target_sub_desc_vec[2])->reserved,655+ static_cast<int16_t>(AddrType::HIDDEN_INPUT));
647- static_cast<uint32_t>(HiddenInputsType::HCCLSUPERKERNEL));656+ (void)memcpy_s(&reserved_val, sizeof(reserved_val), reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[2])->reserved,
657+ sizeof(uint32_t));
658+ EXPECT_EQ(reserved_val, static_cast<uint32_t>(HiddenInputsType::HCCLSUPERKERNEL));
648 659 
649 ArgDesc tmp_arg_desc{};660 ArgDesc tmp_arg_desc{};
650 int32_t sub_op_id = 0;661 int32_t sub_op_id = 0;
@@ -670,7 +681,9 @@ TEST_F(UtestArgsFormatDesc, SknArgDesceEventAddr) {
670 EXPECT_NE(sub_graph, nullptr);681 EXPECT_NE(sub_graph, nullptr);
671 EXPECT_NE(op_desc, nullptr);682 EXPECT_NE(op_desc, nullptr);
672 op_desc->SetExtAttr("_sk_sub_graph", sub_graph);683 op_desc->SetExtAttr("_sk_sub_graph", sub_graph);
673- SkArgDesc sk_desc = {AddrType::SUPER_KERNEL_SUB_NODE, 1, false, AddrType::EVENT_ADDR, 10};684+ SkArgDesc sk_desc = {AddrType::SUPER_KERNEL_SUB_NODE, 1, static_cast<int16_t>(AddrType::EVENT_ADDR), 0, {0}};
685+ const int32_t mem_event_id = 10;
686+ (void)memcpy_s(sk_desc.reserved, sizeof(sk_desc.reserved), &mem_event_id, sizeof(int32_t));
674 ArgDesc sub_desc = *reinterpret_cast<ArgDesc *>(&sk_desc);687 ArgDesc sub_desc = *reinterpret_cast<ArgDesc *>(&sk_desc);
675 std::vector<ArgDesc> args_desc_vec;688 std::vector<ArgDesc> args_desc_vec;
676 args_desc_vec.emplace_back(sub_desc);689 args_desc_vec.emplace_back(sub_desc);
@@ -682,22 +695,53 @@ TEST_F(UtestArgsFormatDesc, SknArgDesceEventAddr) {
682 auto ret = ArgsFormatDesc::Parse(op_desc, str, target_sub_desc_vec, false);695 auto ret = ArgsFormatDesc::Parse(op_desc, str, target_sub_desc_vec, false);
683 EXPECT_EQ(ret, GRAPH_SUCCESS);696 EXPECT_EQ(ret, GRAPH_SUCCESS);
684 EXPECT_EQ(target_sub_desc_vec.size(), 1);697 EXPECT_EQ(target_sub_desc_vec.size(), 1);
685- EXPECT_EQ(target_sub_desc_vec[0].ir_idx, sub_desc.ir_idx);
686 EXPECT_EQ(target_sub_desc_vec[0].addr_type, sub_desc.addr_type);698 EXPECT_EQ(target_sub_desc_vec[0].addr_type, sub_desc.addr_type);
687- EXPECT_EQ(target_sub_desc_vec[0].folded, sub_desc.folded);
688 699 
689- EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_idx,
690- reinterpret_cast<SkArgDesc *>(&sub_desc)->sub_idx);
691- EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_idx, 10);
692 EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_addr_type,700 EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_addr_type,
693 reinterpret_cast<SkArgDesc *>(&sub_desc)->sub_addr_type);701 reinterpret_cast<SkArgDesc *>(&sub_desc)->sub_addr_type);
694- EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_addr_type, AddrType::EVENT_ADDR);702+ EXPECT_EQ(reinterpret_cast<SkArgDesc *>(&target_sub_desc_vec[0])->sub_addr_type,
703+ static_cast<int16_t>(AddrType::EVENT_ADDR));
704+ ArgDesc normal_desc = {};
705+ int32_t sub_op_id = 0;
706+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(target_sub_desc_vec[0], normal_desc, sub_op_id), GRAPH_SUCCESS);
707+ EXPECT_EQ(normal_desc.addr_type, AddrType::EVENT_ADDR);
708+ EXPECT_EQ(normal_desc.ir_idx, mem_event_id);
709+ EXPECT_EQ(sub_op_id, 1);
695 size_t arg_size = 0;710 size_t arg_size = 0;
696 ret = ArgsFormatDesc::GetArgSize(op_desc, sub_desc, arg_size);711 ret = ArgsFormatDesc::GetArgSize(op_desc, sub_desc, arg_size);
697 EXPECT_EQ(ret, GRAPH_SUCCESS);712 EXPECT_EQ(ret, GRAPH_SUCCESS);
698 EXPECT_EQ(arg_size, 8);713 EXPECT_EQ(arg_size, 8);
699}714}
700 715 
716+TEST_F(UtestArgsFormatDesc, SknArgDescEventAddrOverflow) {
717+ auto sub_graph = BuildNormalGraph("test");
718+ auto op_desc = std::make_shared<OpDesc>("sk", "SuperKernel");
719+ EXPECT_NE(sub_graph, nullptr);
720+ EXPECT_NE(op_desc, nullptr);
721+ op_desc->SetExtAttr("_sk_sub_graph", sub_graph);
722+ SkArgDesc sk_desc = {AddrType::SUPER_KERNEL_SUB_NODE, 1, static_cast<int16_t>(AddrType::EVENT_ADDR), 0, {0}};
723+ const int32_t mem_event_id = 200000; // exceeds int16_t range [-32768, 32767]
724+ (void)memcpy_s(sk_desc.reserved, sizeof(sk_desc.reserved), &mem_event_id, sizeof(int32_t));
725+ ArgDesc sub_desc = *reinterpret_cast<ArgDesc *>(&sk_desc);
726+ std::vector<ArgDesc> args_desc_vec;
727+ args_desc_vec.emplace_back(sub_desc);
728+ auto str = ArgsFormatDesc::Serialize(args_desc_vec);
729+ 
730+ EXPECT_EQ(str, "{skn1event_addr200000*}");
731+ 
732+ std::vector<ArgDesc> target_sub_desc_vec;
733+ auto ret = ArgsFormatDesc::Parse(op_desc, str, target_sub_desc_vec, false);
734+ EXPECT_EQ(ret, GRAPH_SUCCESS);
735+ EXPECT_EQ(target_sub_desc_vec.size(), 1);
736+ 
737+ ArgDesc normal_desc = {};
738+ int32_t sub_op_id = 0;
739+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(target_sub_desc_vec[0], normal_desc, sub_op_id), GRAPH_SUCCESS);
740+ EXPECT_EQ(normal_desc.addr_type, AddrType::EVENT_ADDR);
741+ EXPECT_EQ(normal_desc.ir_idx, mem_event_id);
742+ EXPECT_EQ(sub_op_id, 1);
743+}
744+ 
701TEST_F(UtestArgsFormatDesc, ConvertToSuperKernelArgFormat) {745TEST_F(UtestArgsFormatDesc, ConvertToSuperKernelArgFormat) {
702 auto sub_graph = BuildNormalGraph("test");746 auto sub_graph = BuildNormalGraph("test");
703 auto op_desc = std::make_shared<OpDesc>("sk", "SuperKernel");747 auto op_desc = std::make_shared<OpDesc>("sk", "SuperKernel");
@@ -718,4 +762,302 @@ TEST_F(UtestArgsFormatDesc, ConvertToSuperKernelArgFormat) {
718 ge::GRAPH_SUCCESS);762 ge::GRAPH_SUCCESS);
719 EXPECT_EQ(sk_arg_format, "{skn0i0*}");763 EXPECT_EQ(sk_arg_format, "{skn0i0*}");
720}764}
765+TEST_F(UtestArgsFormatDesc, SknArgDescCustomValueBit64) {
766+ auto sub_graph = BuildNormalGraph("test");
767+ auto op_desc = std::make_shared<OpDesc>("sk", "SuperKernel");
768+ EXPECT_NE(sub_graph, nullptr);
769+ EXPECT_NE(op_desc, nullptr);
770+ op_desc->SetExtAttr("_sk_sub_graph", sub_graph);
771+ 
772+ std::string sub_node_arg_format = "{#1234567890}";
773+ std::string sk_arg_format;
774+ auto sk_node = std::shared_ptr<Node>(new (std::nothrow) Node(op_desc, nullptr));
775+ EXPECT_NE(sk_node, nullptr);
776+ (void)sk_node->Init();
777+ 
778+ NodePtr sub_node;
779+ for (const auto &node : sub_graph->GetDirectNode()) {
780+ if (node->GetOpDesc()->GetId() == 1) {
781+ sub_node = node;
782+ break;
783+ }
784+ }
785+ ASSERT_NE(sub_node, nullptr);
786+ 
787+ EXPECT_EQ(ArgsFormatDesc::ConvertToSuperKernelArgFormat(sk_node, sub_node, sub_node_arg_format, sk_arg_format),
788+ ge::GRAPH_SUCCESS);
789+ EXPECT_EQ(sk_arg_format, "{skn1#1234567890}");
790+ 
791+ std::vector<ArgDesc> target_sub_desc_vec;
792+ auto ret = ArgsFormatDesc::Parse(op_desc, sk_arg_format, target_sub_desc_vec, false);
793+ EXPECT_EQ(ret, GRAPH_SUCCESS);
794+ EXPECT_EQ(target_sub_desc_vec.size(), 1);
795+ 
796+ ArgDesc tmp_arg_desc{};
797+ int32_t sub_op_id = 0;
798+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(target_sub_desc_vec[0], tmp_arg_desc, sub_op_id), GRAPH_SUCCESS);
799+ EXPECT_EQ(tmp_arg_desc.addr_type, AddrType::CUSTOM_VALUE);
800+ EXPECT_EQ(tmp_arg_desc.ir_idx, static_cast<int32_t>(ArgsFormatWidth::BIT64));
801+ EXPECT_EQ(*reinterpret_cast<uint64_t *>(tmp_arg_desc.reserved), 1234567890ULL);
802+ EXPECT_EQ(sub_op_id, 1);
803+ 
804+ size_t arg_size = 0;
805+ ret = ArgsFormatDesc::GetArgSize(op_desc, target_sub_desc_vec[0], arg_size);
806+ EXPECT_EQ(ret, GRAPH_SUCCESS);
807+ EXPECT_EQ(arg_size, 8);
808+}
809+ 
810+TEST_F(UtestArgsFormatDesc, SknArgDescCustomValueBit32) {
811+ auto sub_graph = BuildNormalGraph("test");
812+ auto op_desc = std::make_shared<OpDesc>("sk", "SuperKernel");
813+ EXPECT_NE(sub_graph, nullptr);
814+ EXPECT_NE(op_desc, nullptr);
815+ op_desc->SetExtAttr("_sk_sub_graph", sub_graph);
816+ 
817+ std::string sub_node_arg_format = "{#.32b42}";
818+ std::string sk_arg_format;
819+ auto sk_node = std::shared_ptr<Node>(new (std::nothrow) Node(op_desc, nullptr));
820+ EXPECT_NE(sk_node, nullptr);
821+ (void)sk_node->Init();
822+ 
823+ NodePtr sub_node;
824+ for (const auto &node : sub_graph->GetDirectNode()) {
825+ if (node->GetOpDesc()->GetId() == 1) {
826+ sub_node = node;
827+ break;
828+ }
829+ }
830+ ASSERT_NE(sub_node, nullptr);
831+ 
832+ EXPECT_EQ(ArgsFormatDesc::ConvertToSuperKernelArgFormat(sk_node, sub_node, sub_node_arg_format, sk_arg_format),
833+ ge::GRAPH_SUCCESS);
834+ EXPECT_EQ(sk_arg_format, "{skn1#.32b42}");
835+ 
836+ std::vector<ArgDesc> target_sub_desc_vec;
837+ auto ret = ArgsFormatDesc::Parse(op_desc, sk_arg_format, target_sub_desc_vec, false);
838+ EXPECT_EQ(ret, GRAPH_SUCCESS);
839+ EXPECT_EQ(target_sub_desc_vec.size(), 1);
840+ 
841+ ArgDesc tmp_arg_desc{};
842+ int32_t sub_op_id = 0;
843+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(target_sub_desc_vec[0], tmp_arg_desc, sub_op_id), GRAPH_SUCCESS);
844+ EXPECT_EQ(tmp_arg_desc.addr_type, AddrType::CUSTOM_VALUE);
845+ EXPECT_EQ(tmp_arg_desc.ir_idx, static_cast<int32_t>(ArgsFormatWidth::BIT32));
846+ EXPECT_EQ(*reinterpret_cast<uint64_t *>(tmp_arg_desc.reserved), 42ULL);
847+ EXPECT_EQ(sub_op_id, 1);
848+ 
849+ size_t arg_size = 0;
850+ ret = ArgsFormatDesc::GetArgSize(op_desc, target_sub_desc_vec[0], arg_size);
851+ EXPECT_EQ(ret, GRAPH_SUCCESS);
852+ EXPECT_EQ(arg_size, 4);
853+}
854+ 
855+TEST_F(UtestArgsFormatDesc, SknArgDescCustomValueMaxPayload) {
856+ auto sub_graph = BuildNormalGraph("test");
857+ auto op_desc = std::make_shared<OpDesc>("sk", "SuperKernel");
858+ EXPECT_NE(sub_graph, nullptr);
859+ EXPECT_NE(op_desc, nullptr);
860+ op_desc->SetExtAttr("_sk_sub_graph", sub_graph);
861+ 
862+ std::string sub_node_arg_format = "{#18446744073709551615}";
863+ std::string sk_arg_format;
864+ auto sk_node = std::shared_ptr<Node>(new (std::nothrow) Node(op_desc, nullptr));
865+ EXPECT_NE(sk_node, nullptr);
866+ (void)sk_node->Init();
867+ 
868+ NodePtr sub_node;
869+ for (const auto &node : sub_graph->GetDirectNode()) {
870+ if (node->GetOpDesc()->GetId() == 1) {
871+ sub_node = node;
872+ break;
873+ }
874+ }
875+ ASSERT_NE(sub_node, nullptr);
876+ 
877+ EXPECT_EQ(ArgsFormatDesc::ConvertToSuperKernelArgFormat(sk_node, sub_node, sub_node_arg_format, sk_arg_format),
878+ ge::GRAPH_SUCCESS);
879+ 
880+ std::vector<ArgDesc> target_sub_desc_vec;
881+ auto ret = ArgsFormatDesc::Parse(op_desc, sk_arg_format, target_sub_desc_vec, false);
882+ EXPECT_EQ(ret, GRAPH_SUCCESS);
883+ EXPECT_EQ(target_sub_desc_vec.size(), 1);
884+ 
885+ ArgDesc tmp_arg_desc{};
886+ int32_t sub_op_id = 0;
887+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(target_sub_desc_vec[0], tmp_arg_desc, sub_op_id), GRAPH_SUCCESS);
888+ EXPECT_EQ(tmp_arg_desc.addr_type, AddrType::CUSTOM_VALUE);
889+ EXPECT_EQ(tmp_arg_desc.ir_idx, static_cast<int32_t>(ArgsFormatWidth::BIT64));
890+ EXPECT_EQ(*reinterpret_cast<uint64_t *>(tmp_arg_desc.reserved), 0xFFFFFFFFFFFFFFFFULL);
891+}
892+ 
893+TEST_F(UtestArgsFormatDesc, SknArgDescFoldedRoundTrip) {
894+ auto sub_graph = BuildNormalGraph("test");
895+ auto op_desc = std::make_shared<OpDesc>("sk", "SuperKernel");
896+ EXPECT_NE(sub_graph, nullptr);
897+ EXPECT_NE(op_desc, nullptr);
898+ op_desc->SetExtAttr("_sk_sub_graph", sub_graph);
899+ 
900+ std::string sub_node_arg_format = "{i0}{i_desc1}{o_desc0}";
901+ std::string sk_arg_format;
902+ auto sk_node = std::shared_ptr<Node>(new (std::nothrow) Node(op_desc, nullptr));
903+ EXPECT_NE(sk_node, nullptr);
904+ (void)sk_node->Init();
905+ 
906+ NodePtr sub_node;
907+ for (const auto &node : sub_graph->GetDirectNode()) {
908+ if (node->GetOpDesc()->GetId() == 1) {
909+ sub_node = node;
910+ break;
911+ }
912+ }
913+ ASSERT_NE(sub_node, nullptr);
914+ sub_node->GetOpDesc()->AppendIrInput("x", kIrInputRequired);
915+ sub_node->GetOpDesc()->AppendIrOutput("y", kIrOutputRequired);
916+ GeShape shape({1});
917+ GeTensorDesc desc(shape);
918+ sub_node->GetOpDesc()->AddInputDesc(desc);
919+ sub_node->GetOpDesc()->AddOutputDesc(desc);
920+ 
921+ EXPECT_EQ(ArgsFormatDesc::ConvertToSuperKernelArgFormat(sk_node, sub_node, sub_node_arg_format, sk_arg_format),
922+ ge::GRAPH_SUCCESS);
923+ 
924+ std::vector<ArgDesc> target_sub_desc_vec;
925+ auto ret = ArgsFormatDesc::Parse(op_desc, sk_arg_format, target_sub_desc_vec, false);
926+ EXPECT_EQ(ret, GRAPH_SUCCESS);
927+ 
928+ for (const auto &sk_arg : target_sub_desc_vec) {
929+ ArgDesc normal_arg{};
930+ int32_t sub_op_id = 0;
931+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(sk_arg, normal_arg, sub_op_id), GRAPH_SUCCESS);
932+ EXPECT_EQ(sub_op_id, 1);
933+ }
934+}
935+ 
936+TEST_F(UtestArgsFormatDesc, SknArgDescFoldedTrue) {
937+ auto sub_graph = BuildNormalGraph("test");
938+ auto op_desc = std::make_shared<OpDesc>("sk", "SuperKernel");
939+ EXPECT_NE(sub_graph, nullptr);
940+ EXPECT_NE(op_desc, nullptr);
941+ op_desc->SetExtAttr("_sk_sub_graph", sub_graph);
942+ 
943+ std::string sub_node_arg_format = "{i0*}{o0*}";
944+ std::string sk_arg_format;
945+ auto sk_node = std::shared_ptr<Node>(new (std::nothrow) Node(op_desc, nullptr));
946+ EXPECT_NE(sk_node, nullptr);
947+ (void)sk_node->Init();
948+ 
949+ NodePtr sub_node;
950+ for (const auto &node : sub_graph->GetDirectNode()) {
951+ if (node->GetOpDesc()->GetId() == 1) {
952+ sub_node = node;
953+ break;
954+ }
955+ }
956+ ASSERT_NE(sub_node, nullptr);
957+ sub_node->GetOpDesc()->AppendIrInput("x", kIrInputRequired);
958+ sub_node->GetOpDesc()->AppendIrOutput("y", kIrOutputRequired);
959+ GeShape shape({1});
960+ GeTensorDesc desc(shape);
961+ sub_node->GetOpDesc()->AddInputDesc(desc);
962+ sub_node->GetOpDesc()->AddOutputDesc(desc);
963+ 
964+ EXPECT_EQ(ArgsFormatDesc::ConvertToSuperKernelArgFormat(sk_node, sub_node, sub_node_arg_format, sk_arg_format),
965+ ge::GRAPH_SUCCESS);
966+ EXPECT_EQ(sk_arg_format, "{skn1i0*}{skn1o0*}");
967+ 
968+ std::vector<ArgDesc> target_sub_desc_vec;
969+ auto ret = ArgsFormatDesc::Parse(op_desc, sk_arg_format, target_sub_desc_vec, false);
970+ EXPECT_EQ(ret, GRAPH_SUCCESS);
971+ EXPECT_EQ(target_sub_desc_vec.size(), 2);
972+ 
973+ ArgDesc normal_arg{};
974+ int32_t sub_op_id = 0;
975+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(target_sub_desc_vec[0], normal_arg, sub_op_id), GRAPH_SUCCESS);
976+ EXPECT_EQ(normal_arg.addr_type, AddrType::INPUT);
977+ EXPECT_EQ(normal_arg.ir_idx, 0);
978+ EXPECT_EQ(normal_arg.folded, false);
979+ EXPECT_EQ(sub_op_id, 1);
980+ 
981+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(target_sub_desc_vec[1], normal_arg, sub_op_id), GRAPH_SUCCESS);
982+ EXPECT_EQ(normal_arg.addr_type, AddrType::OUTPUT);
983+ EXPECT_EQ(normal_arg.ir_idx, 0);
984+ EXPECT_EQ(normal_arg.folded, false);
985+ EXPECT_EQ(sub_op_id, 1);
986+}
987+ 
988+TEST_F(UtestArgsFormatDesc, SknArgDescMixedTypes) {
989+ auto sub_graph = BuildNormalGraph("test");
990+ auto op_desc = std::make_shared<OpDesc>("sk", "SuperKernel");
991+ EXPECT_NE(sub_graph, nullptr);
992+ EXPECT_NE(op_desc, nullptr);
993+ op_desc->SetExtAttr("_sk_sub_graph", sub_graph);
994+ 
995+ std::string sub_node_arg_format = "{i0}{#42}{o0}";
996+ std::string sk_arg_format;
997+ auto sk_node = std::shared_ptr<Node>(new (std::nothrow) Node(op_desc, nullptr));
998+ EXPECT_NE(sk_node, nullptr);
999+ (void)sk_node->Init();
1000+ 
1001+ NodePtr sub_node;
1002+ for (const auto &node : sub_graph->GetDirectNode()) {
1003+ if (node->GetOpDesc()->GetId() == 1) {
1004+ sub_node = node;
1005+ break;
1006+ }
1007+ }
1008+ ASSERT_NE(sub_node, nullptr);
1009+ sub_node->GetOpDesc()->AppendIrInput("x", kIrInputRequired);
1010+ sub_node->GetOpDesc()->AppendIrOutput("y", kIrOutputRequired);
1011+ GeShape shape({1});
1012+ GeTensorDesc desc(shape);
1013+ sub_node->GetOpDesc()->AddInputDesc(desc);
1014+ sub_node->GetOpDesc()->AddOutputDesc(desc);
1015+ 
1016+ EXPECT_EQ(ArgsFormatDesc::ConvertToSuperKernelArgFormat(sk_node, sub_node, sub_node_arg_format, sk_arg_format),
1017+ ge::GRAPH_SUCCESS);
1018+ EXPECT_EQ(sk_arg_format, "{skn1i0*}{skn1#42}{skn1o0*}");
1019+ 
1020+ std::vector<ArgDesc> target_sub_desc_vec;
1021+ auto ret = ArgsFormatDesc::Parse(op_desc, sk_arg_format, target_sub_desc_vec, false);
1022+ EXPECT_EQ(ret, GRAPH_SUCCESS);
1023+ EXPECT_EQ(target_sub_desc_vec.size(), 3);
1024+ 
1025+ ArgDesc normal_arg{};
1026+ int32_t sub_op_id = 0;
1027+ 
1028+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(target_sub_desc_vec[0], normal_arg, sub_op_id), GRAPH_SUCCESS);
1029+ EXPECT_EQ(normal_arg.addr_type, AddrType::INPUT);
1030+ EXPECT_EQ(normal_arg.ir_idx, 0);
1031+ EXPECT_EQ(sub_op_id, 1);
1032+ 
1033+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(target_sub_desc_vec[1], normal_arg, sub_op_id), GRAPH_SUCCESS);
1034+ EXPECT_EQ(normal_arg.addr_type, AddrType::CUSTOM_VALUE);
1035+ EXPECT_EQ(normal_arg.ir_idx, static_cast<int32_t>(ArgsFormatWidth::BIT64));
1036+ EXPECT_EQ(*reinterpret_cast<uint64_t *>(normal_arg.reserved), 42ULL);
1037+ EXPECT_EQ(sub_op_id, 1);
1038+ 
1039+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(target_sub_desc_vec[2], normal_arg, sub_op_id), GRAPH_SUCCESS);
1040+ EXPECT_EQ(normal_arg.addr_type, AddrType::OUTPUT);
1041+ EXPECT_EQ(normal_arg.ir_idx, 0);
1042+ EXPECT_EQ(sub_op_id, 1);
1043+}
1044+ 
1045+TEST_F(UtestArgsFormatDesc, ConvertSkToNormalNonSkType) {
1046+ ArgDesc normal_desc{};
1047+ normal_desc.addr_type = AddrType::INPUT;
1048+ normal_desc.ir_idx = 3;
1049+ normal_desc.folded = true;
1050+ uint64_t payload = 0xDEADBEEFULL;
1051+ (void)memcpy_s(normal_desc.reserved, sizeof(normal_desc.reserved), &payload, sizeof(uint64_t));
1052+ 
1053+ ArgDesc result{};
1054+ int32_t sub_op_id = 0;
1055+ EXPECT_EQ(ArgsFormatDesc::ConvertArgDescSkToNormal(normal_desc, result, sub_op_id), GRAPH_SUCCESS);
1056+ EXPECT_EQ(result.addr_type, AddrType::INPUT);
1057+ EXPECT_EQ(result.ir_idx, 3);
1058+ EXPECT_EQ(result.folded, true);
1059+ EXPECT_EQ(*reinterpret_cast<uint64_t *>(result.reserved), 0xDEADBEEFULL);
1060+ EXPECT_EQ(sub_op_id, INT32_MAX);
1061+}
1062+ 
721} // namespace ge1063} // namespace ge