* 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 "common/dump_util.h"
#include <sstream>
#include "common/fe_log.h"
#include "common/aicore_util_types.h"
#include "common/aicore_util_attr_define.h"
#include "common/string_utils.h"
#include "graph/debug/ge_attr_define.h"
namespace fe {
using ToOpStructPtr = std::shared_ptr<ToOpStruct_t>;
void DumpOpInfoTensor(const std::vector<te::TbeOpParam> &op_params, std::string &debug_str) {
std::ostringstream debug_oss;
for (size_t i = 0; i < op_params.size(); i++) {
debug_oss << std::endl << "tensor[" << std::to_string(i) << "]";
debug_oss << std::endl << "tensor type : " << std::to_string(op_params.at(i).GetType());
const std::vector<te::TbeOpTensor> &tensors = op_params.at(i).GetTensors();
for (const te::TbeOpTensor &tensor : tensors) {
debug_oss << std::endl << "name : " << tensor.GetName();
debug_oss << std::endl << "shape : [" << StringUtils::IntegerVecToString(tensor.GetShape()) << "]";
debug_oss << std::endl << "origin shape : [" << StringUtils::IntegerVecToString(tensor.GetOriginShape()) << "]";
debug_oss << std::endl << "shape type : " << std::to_string(tensor.GetShapeType());
debug_oss << std::endl << "format : " << tensor.GetFormat();
debug_oss << std::endl << "sub_format : " << tensor.GetSubFormat();
debug_oss << std::endl << "origin format : " << tensor.GetOriginFormat();
debug_oss << std::endl << "dtype : " << tensor.GetType();
debug_oss << std::endl << "addr type : " << std::to_string(tensor.GetAddrType());
debug_oss << std::endl << "L1WorkspaceFlag : " << std::to_string(tensor.GetL1WorkspaceFlag());
debug_oss << std::endl << "slice offset : " << StringUtils::IntegerVecToString(tensor.GetSliceOffset());
debug_oss << std::endl << "valid shape : " << StringUtils::IntegerVecToString(tensor.GetValidShape());
debug_oss << std::endl << "sgt slice shape : " << StringUtils::IntegerVecToString(tensor.GetSgtSliceShape());
}
}
debug_oss << std::endl;
debug_str = debug_oss.str();
}
void DumpOpInfo(const te::TbeOpInfo &op_info) {
std::ostringstream debug_oss;
debug_oss << std::endl << "name : " << op_info.GetName();
debug_oss << std::endl << "OpFileName : " << op_info.GetOpFileName();
debug_oss << std::endl << "OpFuncName : " << op_info.GetOpFuncName();
debug_oss << std::endl << "CheckSupportedFunc : " << op_info.GetCheckSupportedFunc();
debug_oss << std::endl << "Pattern : " << op_info.GetPattern();
debug_oss << std::endl << "KernelName : " << op_info.GetKernelName();
debug_oss << std::endl << "L1Space : " << std::to_string(op_info.GetL1Space());
debug_oss << std::endl;
FE_LOGD("Dump Op info. %s.", debug_oss.str().c_str());
string debug_str;
DumpOpInfoTensor(op_info.GetInputs(), debug_str);
FE_LOGD("Dump Op info inputs, %s.", debug_str.c_str());
debug_str.clear();
DumpOpInfoTensor(op_info.GetOutputs(), debug_str);
FE_LOGD("Dump Op info outputs, %s.", debug_str.c_str());
}
void DumpL1Attr(const ge::Node *node) {
auto op_desc = node->GetOpDesc();
vector<int32_t> in_memery_type_vec;
vector<int32_t> out_memery_type_vec;
ToOpStructPtr l1_info = std::shared_ptr<ToOpStruct_t>();
(void)ge::AttrUtils::GetListInt(op_desc, ge::ATTR_NAME_INPUT_MEM_TYPE_LIST, in_memery_type_vec);
(void)ge::AttrUtils::GetListInt(op_desc, ge::ATTR_NAME_OUTPUT_MEM_TYPE_LIST, out_memery_type_vec);
l1_info = op_desc->TryGetExtAttr(ge::ATTR_NAME_L1_FUSION_EXTEND_PTR, l1_info);
string in_mem_type_str;
string out_mem_type_str;
string op_l1_fusion_type_str;
string slice_input_offset_str;
string slice_output_offset_str;
string slice_input_shape_str;
string slice_output_shape_str;
FE_CHECK(l1_info == nullptr, FE_LOGD("l1Info is null."), return);
for (unsigned int i = 0; i < in_memery_type_vec.size(); i++) {
in_mem_type_str += std::to_string(in_memery_type_vec[i]) + " ";
}
for (unsigned int i = 0; i < out_memery_type_vec.size(); i++) {
out_mem_type_str += std::to_string(out_memery_type_vec[i]) + " ";
}
for (unsigned int i = 0; i < l1_info->op_l1_fusion_type.size(); i++) {
op_l1_fusion_type_str += " L1 fusion type" + std::to_string(i) + ": ";
for (auto &type : l1_info->op_l1_fusion_type) {
op_l1_fusion_type_str += std::to_string(type) + " ";
}
}
for (unsigned int i = 0; i < l1_info->slice_input_shape.size(); i++) {
slice_input_shape_str += " valid shape input" + std::to_string(i) + ": ";
for (auto &valid_input_shape : l1_info->slice_input_shape.at(i)) {
slice_input_shape_str += std::to_string(valid_input_shape) + " ";
}
}
for (unsigned int i = 0; i < l1_info->slice_output_shape.size(); i++) {
slice_output_shape_str += " valid shape output" + std::to_string(i) + ": ";
for (auto &valid_output_shape : l1_info->slice_output_shape.at(i)) {
slice_output_shape_str += std::to_string(valid_output_shape) + " ";
}
}
for (unsigned int i = 0; i < l1_info->slice_input_offset.size(); i++) {
slice_input_offset_str += " slice offset input" + std::to_string(i) + ": ";
for (auto &slice_offset : l1_info->slice_input_offset.at(i)) {
slice_input_offset_str += std::to_string(slice_offset) + " ";
}
}
for (unsigned int i = 0; i < l1_info->slice_output_offset.size(); i++) {
slice_output_offset_str += " slice offset output" + std::to_string(i) + ": ";
for (auto &slice_offset : l1_info->slice_output_offset.at(i)) {
slice_output_offset_str += std::to_string(slice_offset) + " ";
}
}
FE_LOGD("Dump L1 Op info[%s, %s], input size [%zu], type [%s], output size [%zu], type [%s].",
op_desc->GetName().c_str(), op_desc->GetType().c_str(), in_memery_type_vec.size(), in_mem_type_str.c_str(),
out_memery_type_vec.size(), out_mem_type_str.c_str());
FE_LOGD("Dump L1 Op info. op_l1_fusion_type size [%zu], type [%s],"
" slice_input_shape size [%zu], type [%s]. slice_output_shape size [%zu], type [%s],"
" slice_input_offset size [%zu], type [%s]. slice_output_offset size [%zu], type [%s], l1space [%ld].",
l1_info->op_l1_fusion_type.size(), op_l1_fusion_type_str.c_str(), l1_info->slice_input_shape.size(),
slice_input_shape_str.c_str(), l1_info->slice_output_shape.size(), slice_output_shape_str.c_str(),
l1_info->slice_input_offset.size(), slice_input_offset_str.c_str(), l1_info->slice_output_offset.size(),
slice_output_offset_str.c_str(), l1_info->op_l1_space);
}
void DumpL2Attr(const ge::Node *node) {
auto op_desc = node->GetOpDesc();
vector<int32_t> in_memery_type_vec;
vector<int32_t> out_memery_type_vec;
ToOpStructPtr l2_info = std::shared_ptr<ToOpStruct_t>();
(void)ge::AttrUtils::GetListInt(op_desc, ge::ATTR_NAME_INPUT_MEM_TYPE_LIST, in_memery_type_vec);
(void)ge::AttrUtils::GetListInt(op_desc, ge::ATTR_NAME_OUTPUT_MEM_TYPE_LIST, out_memery_type_vec);
l2_info = op_desc->TryGetExtAttr(ATTR_NAME_L2_FUSION_EXTEND_PTR, l2_info);
string in_mem_type_str;
string out_mem_type_str;
string slice_input_offset_str;
string slice_output_offset_str;
string slice_input_shape_str;
string slice_output_shape_str;
FE_CHECK(l2_info == nullptr, FE_LOGD("l2Info is null."), return);
for (unsigned int i = 0; i < in_memery_type_vec.size(); i++) {
in_mem_type_str += std::to_string(in_memery_type_vec[i]) + " ";
}
for (unsigned int i = 0; i < out_memery_type_vec.size(); i++) {
out_mem_type_str += std::to_string(out_memery_type_vec[i]) + " ";
}
for (unsigned int i = 0; i < l2_info->slice_input_shape.size(); i++) {
slice_input_shape_str += " valid shape input" + std::to_string(i) + ": ";
for (auto &valid_input_shape : l2_info->slice_input_shape.at(i)) {
slice_input_shape_str += std::to_string(valid_input_shape) + " ";
}
}
for (unsigned int i = 0; i < l2_info->slice_output_shape.size(); i++) {
slice_output_shape_str += " valid shape output" + std::to_string(i) + ": ";
for (auto &valid_output_shape : l2_info->slice_output_shape.at(i)) {
slice_output_shape_str += std::to_string(valid_output_shape) + " ";
}
}
for (unsigned int i = 0; i < l2_info->slice_input_offset.size(); i++) {
slice_input_offset_str += " slice offset input" + std::to_string(i) + ": ";
for (auto &slice_offset : l2_info->slice_input_offset.at(i)) {
slice_input_offset_str += std::to_string(slice_offset) + " ";
}
}
for (unsigned int i = 0; i < l2_info->slice_output_offset.size(); i++) {
slice_output_offset_str += " slice offset output" + std::to_string(i) + ": ";
for (auto &slice_offset : l2_info->slice_output_offset.at(i)) {
slice_output_offset_str += std::to_string(slice_offset) + " ";
}
}
FE_LOGD("Dump L2 Op info[%s, %s], input size [%zu], type [%s], output size [%zu], type [%s].",
op_desc->GetName().c_str(), op_desc->GetType().c_str(), in_memery_type_vec.size(), in_mem_type_str.c_str(),
out_memery_type_vec.size(), out_mem_type_str.c_str());
FE_LOGD("Dump L2 Op info."
" slice_input_shape size [%zu], type [%s]. slice_output_shape size [%zu], type [%s],"
" slice_input_offset size [%zu], type [%s]. slice_output_offset size [%zu], type [%s].",
l2_info->slice_input_shape.size(), slice_input_shape_str.c_str(), l2_info->slice_output_shape.size(),
slice_output_shape_str.c_str(), l2_info->slice_input_offset.size(), slice_input_offset_str.c_str(),
l2_info->slice_output_offset.size(), slice_output_offset_str.c_str());
}
}