diff --git a/ge/executor/ge_executor.cc b/ge/executor/ge_executor.cc index 4081bdf2..6d3114f4 100755 --- a/ge/executor/ge_executor.cc +++ b/ge/executor/ge_executor.cc @@ -731,6 +731,23 @@ Status GeExecutor::GetAippType(uint32_t model_id, uint32_t index, InputAippType return SUCCESS; } +Status GeExecutor::GetOpAttr(uint32_t model_id, const std::string &op_name, const std::string &attr_name, + std::string &attr_value) { + GELOGI("Begin to get op attr."); + if (!isInit_) { + GELOGE(ACL_ERROR_GE_EXEC_NOT_INIT, "[Init][GeExecutor]Ge executor not inited yet!"); + REPORT_INNER_ERROR("E19999", "Ge executor not inited yet!"); + return ACL_ERROR_GE_EXEC_NOT_INIT; + } + Status ret = GraphExecutor::GetOpAttr(model_id, op_name, attr_name, attr_value); + if (ret != SUCCESS) { + GELOGE(ret, "[Get][OpAttr]Get op:%s attr:%s failed.", op_name.c_str(), attr_name.c_str()); + REPORT_CALL_ERROR("E19999", "Get op:%s attr:%s failed.", op_name.c_str(), attr_name.c_str()); + return ret; + } + return SUCCESS; +} + Status GeExecutor::GetModelAttr(uint32_t model_id, std::vector &dynamic_output_shape_info) { if (!isInit_) { GELOGE(ACL_ERROR_GE_EXEC_NOT_INIT, "not inited yet!"); diff --git a/ge/graph/execute/graph_execute.cc b/ge/graph/execute/graph_execute.cc index 1d22016e..db45deef 100755 --- a/ge/graph/execute/graph_execute.cc +++ b/ge/graph/execute/graph_execute.cc @@ -637,6 +637,19 @@ Status GraphExecutor::GetCurShape(const uint32_t model_id, std::vector return SUCCESS; } +Status GraphExecutor::GetOpAttr(uint32_t model_id, const std::string &op_name, const std::string &attr_name, + std::string &attr_value) { + auto model_manager = ge::ModelManager::GetInstance(); + GE_CHECK_NOTNULL(model_manager); + Status ret = model_manager->GetOpAttr(model_id, op_name, attr_name, attr_value); + if (ret != SUCCESS) { + GELOGE(ret, "[Get][OpAttr]Get op:%s attr:%s failed.", op_name.c_str(), attr_name.c_str()); + REPORT_CALL_ERROR("E19999", "Get op:%s attr:%s failed.", op_name.c_str(), attr_name.c_str()); + return ret; + } + return SUCCESS; +} + Status GraphExecutor::GetModelAttr(uint32_t model_id, std::vector &dynamic_output_shape_info) { auto model_manager = ge::ModelManager::GetInstance(); GE_CHECK_NOTNULL(model_manager); diff --git a/ge/graph/execute/graph_execute.h b/ge/graph/execute/graph_execute.h index 2add453f..b18a0d54 100755 --- a/ge/graph/execute/graph_execute.h +++ b/ge/graph/execute/graph_execute.h @@ -108,6 +108,9 @@ class GraphExecutor { static Status GetCurShape(const uint32_t model_id, std::vector &batch_info, int32_t &dynamic_type); + static Status GetOpAttr(uint32_t model_id, const std::string &op_name, const std::string &attr_name, + std::string &attr_value); + static Status GetModelAttr(uint32_t model_id, std::vector &dynamic_output_shape_info); static Status GetOrigInputInfo(uint32_t model_id, uint32_t index, OriginInputInfo &orig_input_info); diff --git a/ge/graph/load/model_manager/davinci_model.cc b/ge/graph/load/model_manager/davinci_model.cc index 49fd518d..d0624dd8 100755 --- a/ge/graph/load/model_manager/davinci_model.cc +++ b/ge/graph/load/model_manager/davinci_model.cc @@ -743,6 +743,19 @@ Status DavinciModel::Init(void *dev_ptr, size_t mem_size, void *weight_ptr, size return SUCCESS; } +// save specify attr values of op, such as ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES +// it will save more attr values in the future +void DavinciModel::SaveSpecifyAttrValues(const OpDescPtr &op_desc) { + std::vector value; + if (AttrUtils::GetListStr(op_desc, ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, value)) { + std::map> attr_name_to_value; + attr_name_to_value[ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES]= value; + op_name_to_attrs_[op_desc->GetName()] = attr_name_to_value; + GELOGD("Get op:%s attr:%s success.", op_desc->GetName().c_str(), ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES.c_str()); + } + return; +} + Status DavinciModel::ReportProfilingData() { ProfilingManager::Instance().ReportProfilingData(model_id_, GetTaskDescInfo()); GE_CHK_STATUS(SinkModelProfile(), "Sink model profiler failed."); @@ -846,7 +859,7 @@ Status DavinciModel::InitNodes(const ComputeGraphPtr &compute_graph) { const auto &node = nodes.at(i); const auto &op_desc = node->GetOpDesc(); GE_CHECK_NOTNULL(op_desc); - + SaveSpecifyAttrValues(op_desc); op_list_[op_desc->GetId()] = op_desc; GE_TIMESTAMP_RESTART(LoadTBEKernelBinToOpDesc); @@ -2056,6 +2069,25 @@ void DavinciModel::GetCurShape(std::vector &batch_info, int32_t &dynami dynamic_type = dynamic_type_; } +Status DavinciModel::GetOpAttr(const std::string &op_name, const std::string &attr_name, + std::string &attr_value) const { + auto itr = op_name_to_attrs_.find(op_name); + if (itr == op_name_to_attrs_.end()) { + GELOGW("Did not save op:%s attr", op_name.c_str()); + return SUCCESS; + } + auto attr_itr = itr->second.find(attr_name); + if (attr_itr == itr->second.end()) { + GELOGW("Did not save attr:%s of op:%s", attr_name.c_str(), op_name.c_str()); + return SUCCESS; + } + for (const auto &name : attr_itr->second) { + attr_value += "[" + std::to_string(name.size()) + "]" + name; + } + GELOGD("Get attr:%s of op:%s success, attr value:%s", attr_name.c_str(), op_name.c_str(), attr_value.c_str()); + return SUCCESS; +} + void DavinciModel::GetModelAttr(vector &out_shape_info) const { out_shape_info.insert(out_shape_info.end(), dynamic_output_shape_info_.begin(), dynamic_output_shape_info_.end()); } diff --git a/ge/graph/load/model_manager/davinci_model.h b/ge/graph/load/model_manager/davinci_model.h index 736272f7..0b06736c 100755 --- a/ge/graph/load/model_manager/davinci_model.h +++ b/ge/graph/load/model_manager/davinci_model.h @@ -361,6 +361,8 @@ class DavinciModel { void GetCurShape(vector &batch_info, int32_t &dynamic_type) const; + Status GetOpAttr(const std::string &op_name, const std::string &attr_name, std::string &attr_value) const; + void GetModelAttr(vector &dynamic_output_shape_info) const; /// @@ -474,6 +476,8 @@ class DavinciModel { int64_t GetLoadEndTime() { return load_end_time_; } + void SaveSpecifyAttrValues(const OpDescPtr &op_desc); + Status ReportProfilingData(); void SaveDumpOpInfo(const RuntimeParam &model_param, const OpDescPtr &op, uint32_t task_id, uint32_t stream_id) { @@ -1096,6 +1100,9 @@ class DavinciModel { // known shape node for dump void *known_shape_global_step_; + + // op name to attrs mapping + std::map>> op_name_to_attrs_; }; } // namespace ge #endif // GE_GRAPH_LOAD_NEW_MODEL_MANAGER_DAVINCI_MODEL_H_ diff --git a/ge/graph/load/model_manager/model_manager.cc b/ge/graph/load/model_manager/model_manager.cc index a288e14e..3428dad1 100755 --- a/ge/graph/load/model_manager/model_manager.cc +++ b/ge/graph/load/model_manager/model_manager.cc @@ -1045,6 +1045,21 @@ Status ModelManager::GetCurShape(const uint32_t model_id, std::vector & return SUCCESS; } +Status ModelManager::GetOpAttr(uint32_t model_id, const std::string &op_name, const std::string &attr_name, + std::string &attr_value) { + auto davinci_model = GetModel(model_id); + if (davinci_model != nullptr) { + return davinci_model->GetOpAttr(op_name, attr_name, attr_value); + } + std::shared_ptr hybrid_davinci_model = GetHybridModel(model_id); + if (hybrid_davinci_model != nullptr) { + return hybrid_davinci_model->GetOpAttr(op_name, attr_name, attr_value); + } + GELOGE(ACL_ERROR_GE_EXEC_MODEL_ID_INVALID, "[Get][Model]Get model failed, invalid model id:%u.", model_id); + REPORT_INNER_ERROR("E19999", "Get model failed, invalid model id:%u.", model_id); + return ACL_ERROR_GE_EXEC_MODEL_ID_INVALID; +} + Status ModelManager::GetModelAttr(uint32_t model_id, std::vector &dynamic_output_shape_info) { std::shared_ptr hybrid_davinci_model = GetHybridModel(model_id); if (hybrid_davinci_model != nullptr) { diff --git a/ge/graph/load/model_manager/model_manager.h b/ge/graph/load/model_manager/model_manager.h index bf804d32..d177052d 100755 --- a/ge/graph/load/model_manager/model_manager.h +++ b/ge/graph/load/model_manager/model_manager.h @@ -246,6 +246,9 @@ class FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY ModelManager { ge::Status GetCurShape(const uint32_t model_id, std::vector &batch_info, int32_t &dynamic_type); + ge::Status GetOpAttr(uint32_t model_id, const std::string &op_name, const std::string &attr_name, + std::string &attr_value); + ge::Status GetModelAttr(uint32_t model_id, std::vector &dynamic_output_shape_info); ge::Status SetDynamicSize(uint32_t model_id, const std::vector &batch_num, int32_t dynamic_type); diff --git a/ge/hybrid/hybrid_davinci_model.cc b/ge/hybrid/hybrid_davinci_model.cc index 45868078..7368784c 100755 --- a/ge/hybrid/hybrid_davinci_model.cc +++ b/ge/hybrid/hybrid_davinci_model.cc @@ -126,6 +126,11 @@ class HybridDavinciModel::Impl { return SUCCESS; } + Status GetOpAttr(const std::string &op_name, const std::string &attr_name, + std::string &attr_value) { + return model_.GetOpAttr(op_name, attr_name, attr_value); + } + private: std::shared_ptr listener_; HybridModel model_; @@ -273,5 +278,11 @@ bool HybridDavinciModel::GetOpDescInfo(uint32_t stream_id, uint32_t task_id, OpD } return ret; } + +Status HybridDavinciModel::GetOpAttr(const std::string &op_name, const std::string &attr_name, + std::string &attr_value) const { + GE_CHECK_NOTNULL(impl_); + return impl_->GetOpAttr(op_name, attr_name, attr_value); +} } // namespace hybrid } // namespace ge diff --git a/ge/hybrid/hybrid_davinci_model.h b/ge/hybrid/hybrid_davinci_model.h index 472fff17..34503b01 100644 --- a/ge/hybrid/hybrid_davinci_model.h +++ b/ge/hybrid/hybrid_davinci_model.h @@ -84,6 +84,8 @@ class HybridDavinciModel { bool GetOpDescInfo(uint32_t stream_id, uint32_t task_id, OpDescInfo &op_desc_info) const; + Status GetOpAttr(const std::string &op_name, const std::string &attr_name, std::string &attr_value) const; + private: HybridDavinciModel() = default; class Impl; diff --git a/ge/hybrid/hybrid_davinci_model_stub.cc b/ge/hybrid/hybrid_davinci_model_stub.cc index 2d4fbe03..67cd29b8 100644 --- a/ge/hybrid/hybrid_davinci_model_stub.cc +++ b/ge/hybrid/hybrid_davinci_model_stub.cc @@ -107,5 +107,9 @@ Status HybridDavinciModel::SetRunAsyncListenerCallback(const RunAsyncCallback &c bool HybridDavinciModel::GetOpDescInfo(uint32_t stream_id, uint32_t task_id, OpDescInfo &op_desc_info) const { return true; } +Status HybridDavinciModel::GetOpAttr(const std::string &op_name, const std::string &attr_name, + std::string &attr_value) const { + return UNSUPPORTED; +} } // namespace hybrid } // namespace ge \ No newline at end of file diff --git a/ge/hybrid/model/hybrid_model.cc b/ge/hybrid/model/hybrid_model.cc index a669c06f..49726734 100644 --- a/ge/hybrid/model/hybrid_model.cc +++ b/ge/hybrid/model/hybrid_model.cc @@ -48,6 +48,7 @@ Status HybridModel::Init(bool is_single_op) { } else { GE_CHK_STATUS_RET(HybridModelBuilder(*this).Build(), "[Build][HybridModel] failed."); } + SaveSpecifyAttrValues(); GELOGD("HybridModel initialized successfully."); return SUCCESS; } @@ -409,5 +410,45 @@ TensorBuffer *HybridModel::GetModelWeight(const string &subgraph_name) const { } return it->second.get(); } + +// save specify attr values of op, such as ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES +// it will save more attr values in the future +void HybridModel::SaveSpecifyAttrValues() { + for (const auto &node : root_graph_->GetAllNodes()) { + if (node == nullptr) { + continue; + } + auto op_desc = node->GetOpDesc(); + if (op_desc == nullptr) { + continue; + } + std::vector value; + if (AttrUtils::GetListStr(op_desc, ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, value)) { + std::map> attr_name_to_value; + attr_name_to_value[ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES] = value; + op_name_to_attrs_[op_desc->GetName()] = attr_name_to_value; + GELOGD("Get op:%s attr:%s success.", op_desc->GetName().c_str(), ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES.c_str()); + } + } + return; +} +Status HybridModel::GetOpAttr(const std::string &op_name, const std::string &attr_name, + std::string &attr_value) const { + auto itr = op_name_to_attrs_.find(op_name); + if (itr == op_name_to_attrs_.end()) { + GELOGW("Did not save op:%s attr", op_name.c_str()); + return SUCCESS; + } + auto attr_itr = itr->second.find(attr_name); + if (attr_itr == itr->second.end()) { + GELOGW("Did not save attr:%s of op:%s", attr_name.c_str(), op_name.c_str()); + return SUCCESS; + } + for (const auto &name : attr_itr->second) { + attr_value += "[" + std::to_string(name.size()) + "]" + name; + } + GELOGD("Get attr:%s of op:%s success, attr value:%s", attr_name.c_str(), op_name.c_str(), attr_value.c_str()); + return SUCCESS; +} } // namespace hybrid } // namespace ge diff --git a/ge/hybrid/model/hybrid_model.h b/ge/hybrid/model/hybrid_model.h index 18daed4f..2c2533a2 100644 --- a/ge/hybrid/model/hybrid_model.h +++ b/ge/hybrid/model/hybrid_model.h @@ -131,6 +131,9 @@ class HybridModel { void SetInputDimsAndShapeRangesInfo(const vector &model_input_dims, std::vector> &shape_ranges, InputOutputDescInfo &input); + void SaveSpecifyAttrValues(); + + Status GetOpAttr(const std::string &op_name, const std::string &attr_name, std::string &attr_value) const; private: friend class HybridModelBuilder; @@ -165,6 +168,8 @@ class HybridModel { RuntimeParam root_runtime_param_; string om_name_; std::unique_ptr global_step_; + // op name to attrs mapping + std::map>> op_name_to_attrs_; }; } // namespace hybrid } // namespace ge diff --git a/inc/framework/executor/ge_executor.h b/inc/framework/executor/ge_executor.h index 9da630c9..fcca561c 100644 --- a/inc/framework/executor/ge_executor.h +++ b/inc/framework/executor/ge_executor.h @@ -153,6 +153,10 @@ class GE_FUNC_VISIBILITY GeExecutor { const kAippDynamicPara &aippParms); ge::Status GetAIPPInfo(uint32_t model_id, uint32_t index, AippConfigInfo &aipp_info); + + ge::Status GetOpAttr(uint32_t model_id, const std::string &op_name, const std::string &attr_name, + std::string &attr_value); + ge::Status GetModelAttr(uint32_t model_id, std::vector &dynamic_output_shape_info); ge::Status GetAippType(uint32_t model_id, uint32_t index, InputAippType &type, size_t &aipp_index); diff --git a/tests/ut/ge/graph/ge_executor_unittest.cc b/tests/ut/ge/graph/ge_executor_unittest.cc index 13293eea..e1f4e0f0 100644 --- a/tests/ut/ge/graph/ge_executor_unittest.cc +++ b/tests/ut/ge/graph/ge_executor_unittest.cc @@ -34,6 +34,7 @@ #include "common/types.h" #include "graph/load/graph_loader.h" #include "graph/load/model_manager/davinci_model.h" +#include "hybrid/hybrid_davinci_model.h" #include "graph/load/model_manager/model_manager.h" #include "graph/load/model_manager/task_info/kernel_task_info.h" #include "graph/load/model_manager/task_info/kernel_ex_task_info.h" @@ -190,4 +191,37 @@ TEST_F(UtestGeExecutor, kernel_ex_InitDumpTask) { kernel_ex_task_info.davinci_model_ = &model; kernel_ex_task_info.InitDumpTask(nullptr, op_desc); } + +TEST_F(UtestGeExecutor, get_op_attr) { + shared_ptr model = MakeShared(1, g_label_call_back); + model->SetId(1); + model->om_name_ = "testom"; + model->name_ = "test"; + + shared_ptr hybrid_model = MakeShared(); + model->SetId(2); + model->om_name_ = "testom_hybrid"; + model->name_ = "test_hybrid"; + + std::shared_ptr model_manager = ModelManager::GetInstance(); + model_manager->InsertModel(1, model); + model_manager->InsertModel(2, hybrid_model); + + OpDescPtr op_desc = CreateOpDesc("test", "test"); + std::vector value{"test"}; + ge::AttrUtils::SetListStr(op_desc, ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, value); + + model->SaveSpecifyAttrValues(op_desc); + + GeExecutor ge_executor; + GeExecutor::isInit_ = true; + std::string attr_value; + auto ret = ge_executor.GetOpAttr(1, "test", ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, attr_value); + EXPECT_EQ(ret, SUCCESS); + EXPECT_EQ(attr_value, "[4]test"); + ret = ge_executor.GetOpAttr(2, "test", ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, attr_value); + EXPECT_EQ(ret, UNSUPPORTED); + ret = ge_executor.GetOpAttr(3, "test", ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, attr_value); + EXPECT_EQ(ret, ACL_ERROR_GE_EXEC_MODEL_ID_INVALID); +} } \ No newline at end of file