From 72a79459e495d5ab6dcf275003e9a06f49c11821 Mon Sep 17 00:00:00 2001 From: taoxiangdong Date: Fri, 27 Nov 2020 10:59:17 +0800 Subject: [PATCH] check aicpu op type --- ge/common/profiling/profiling_manager.h | 4 + ge/graph/build/model_builder.cc | 29 ++++ .../load/new_model_manager/davinci_model.cc | 2 + .../load/new_model_manager/model_manager.cc | 162 ++++++++++++++++++ .../load/new_model_manager/model_manager.h | 4 + 5 files changed, 201 insertions(+) diff --git a/ge/common/profiling/profiling_manager.h b/ge/common/profiling/profiling_manager.h index 66cefc32..4af99412 100755 --- a/ge/common/profiling/profiling_manager.h +++ b/ge/common/profiling/profiling_manager.h @@ -135,6 +135,10 @@ class FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY ProfilingManager { map subs_dev_module_; // key: device_id, value: profiling on module uint32_t subscribe_count_; std::mutex mutex_; + struct MsprofCallback { + MsprofCtrlCallback msprofCtrlCallback; + MsprofReporterCallback msprofReporterCallback; + }; }; } // namespace ge #endif // GE_COMMON_PROFILING_PROFILING_MANAGER_H_ diff --git a/ge/graph/build/model_builder.cc b/ge/graph/build/model_builder.cc index e8657a49..73982f49 100755 --- a/ge/graph/build/model_builder.cc +++ b/ge/graph/build/model_builder.cc @@ -586,9 +586,13 @@ Status ModelBuilder::SaveDataToModel(ge::Model &model, ge::GeModel &ge_model) { // Add TBE Kernels and custom aicpu op bin std::set tbe_name_set; std::set aicpu_name_set; + std::vector aicpu_optype_list; + std::vector aicpu_tf_optype_list; for (const ge::NodePtr &n : compute_graph_->GetNodes(compute_graph_->GetGraphUnknownFlag())) { auto node_op_desc = n->GetOpDesc(); GE_IF_BOOL_EXEC(node_op_desc == nullptr, continue); + // check aicpu op type + (void)CheckAicpuOp(node_op_desc, aicpu_optype_list, aicpu_tf_optype_list); TBEKernelPtr tbe_kernel = node_op_desc->TryGetExtAttr(ge::OP_EXTATTR_NAME_TBE_KERNEL, TBEKernelPtr()); if (tbe_kernel == nullptr) { std::string kernel_name; @@ -611,6 +615,14 @@ Status ModelBuilder::SaveDataToModel(ge::Model &model, ge::GeModel &ge_model) { GELOGI("Add tbe kernel bin %s", tbe_kernel->GetName().c_str()); } + if (!aicpu_optype_list.empty()) { + GE_CHK_BOOL_EXEC(ge::AttrUtils.SetListStr(&ge_model, "needCheckCpu", aicpu_optype_list), return FAILED, "Set attr needCheckCpu fail."); + } + + if (!aicpu_tf_optype_list.empty()) { + GE_CHK_BOOL_EXEC(ge::AttrUtils.SetListStr(&ge_model, "needCheckTf", aicpu_tf_optype_list), return FAILED, "Set attr needCheckTf fail."); + } + for (const ge::NodePtr &n : compute_graph_->GetNodes(compute_graph_->GetGraphUnknownFlag())) { auto node_op_desc = n->GetOpDesc(); GE_IF_BOOL_EXEC(node_op_desc == nullptr, continue); @@ -803,4 +815,21 @@ Status ModelBuilder::CompileSingleOp() { GE_TIMESTAMP_CALLNUM_END(BatchCompileOp, "GraphBuild::CompileOp"); return ge::SUCCESS; } + +Status ModelBuilder::CheckAicpuOp(const OpDescPtr &op_desc, std::set &cpue_check_set, std::set &tf_engine_set) { + GE_CHECK_NOTNULL(op_desc); + std::string aicpu_optype; + bool has_attr_check_cpu = AttrUtils.GetStr(op_desc, "needCheckCpu", aicpu_optype); + std::vector tf_optypes; + bool has_attr_check_tf = AttrUtils.GetListStr(op_desc, "needCheckTf", tf_optypes); + if (has_attr_check_cpu && !aicpu_optype.empty()) { + cpue_check_set.insert(aicpu_optype); + } + + if (has_attr_check_tf && !tf_optypes.empty()) { + tf_engine_set.insert(tf_optypes.begin(), tf_optypes.end()); + } + + return SUCCESS; +} } // namespace ge diff --git a/ge/graph/load/new_model_manager/davinci_model.cc b/ge/graph/load/new_model_manager/davinci_model.cc index b6db50a7..e67b1795 100755 --- a/ge/graph/load/new_model_manager/davinci_model.cc +++ b/ge/graph/load/new_model_manager/davinci_model.cc @@ -469,6 +469,8 @@ Status DavinciModel::DoTaskSink() { GE_CHK_STATUS_RET(ModelManager::GetInstance()->LaunchCustAicpuSo(), "Launch cust aicpu so failed."); + GE_CHK_STATUS_RET(ModelManager::GetInstance()->CheckAicpuOptype(ge_model_), "Check aicpu op type failed."); + GE_CHK_STATUS_RET(InitEntryTask(), "InitEntryTask failed."); GE_CHK_STATUS_RET(DistributeTask(), "Distribute failed."); diff --git a/ge/graph/load/new_model_manager/model_manager.cc b/ge/graph/load/new_model_manager/model_manager.cc index e4e0681d..31c82345 100755 --- a/ge/graph/load/new_model_manager/model_manager.cc +++ b/ge/graph/load/new_model_manager/model_manager.cc @@ -18,6 +18,7 @@ #include +#include "aicpu/aicpu_schedule/aicpu_op_type_list.h" #include "common/dump/dump_manager.h" #include "common/l2_cache_optimize.h" #include "common/profiling/profiling_manager.h" @@ -1499,4 +1500,165 @@ Status ModelManager::EnableExceptionDump(const std::map &options return SUCCESS; } +Status ModelManager::LaunchKernelCheckAicpuOpType(GeModelPtr ge_model) { + GE_CHECK_NOTNULL(ge_model); + std::string kernel_name = "checkOpType"; + GELOGI("LaunchCustAucpuSo in, kernel name %s", kernel_name.c_str()); + std::lock_guard lock(cust_aicpu_mutex_); + std::vector aicpu_optype_list; + std::vector aicpu_tf_optype_list; + + bool aicpu_need_check = ge::AttrUtils.GetListStr(&ge_model, "needCheckCpu", aicpu_optype_list); + bool tf_need_check = ge::AttrUtils.GetListStr(&ge_model, "needCheckTf", aicpu_tf_optype_list); + + if (!aicpu_need_check && !tf_need_check) + { + GELOGI("No need to check aicpu optype."); + return SUCCESS; + } + + vector allocated_mem; + rtError_t status; + rtStream_t stream = nullptr; + void *args = nullptr; + + void *d_req_op_list = nullptr; + void *d_res_op_list = nullptr; + void *d_ret_code_list = nullptr; + + size_t aicpu_op_nums = aicpu_optype_list.size(); + size_t tf_op_nums = aicpu_tf_optype_list.size(); + size_t op_nums = aicpu_op_nums + tf_op_nums; + // malloc sysOpInfoList in SysOpCheckInfo + status = rtMalloc(&d_req_op_list, op_nums * sizeof(SysOpInfo), RT_MEMORY_HBM); + if (status != RT_ERROR_NONE) { + GELOGE(RT_FAILED, "Call rt failed, status: 0x%x", status); + return RT_ERROR_TO_GE_STATUS(status); + } + allocated_mem.push_back(d_req_op_list); + + // malloc sysOpInfoList in SysOpCheckResp + status = rtMalloc(&d_res_op_list, op_nums * sizeof(SysOpInfo), RT_MEMORY_HBM); + if (status != RT_ERROR_NONE) { + GELOGE(RT_FAILED, "Call rt failed, status: 0x%x", status); + return RT_ERROR_TO_GE_STATUS(status); + } + allocated_mem.push_back(d_res_op_list); + + // malloc returnCodeList in SysOpCheckResp + status = rtMalloc(&d_ret_code_list, op_nums * sizeof(ReturnCode), RT_MEMORY_HBM); + if (status != RT_ERROR_NONE) { + GELOGE(RT_FAILED, "Call rt failed, status: 0x%x", status); + return RT_ERROR_TO_GE_STATUS(status); + } + allocated_mem.push_back(d_ret_code_list); + + for (const auto &op_type : aicpu_optype_list) { + uint32_t i = 0; + SysOpInfo op_info; + // malloc op_type name in SysOpInfo + void *d_op_type_name = nullptr; + status = rtMalloc(&d_op_type_name, op_type.length(), RT_MEMORY_HBM); + if (status != RT_ERROR_NONE) { + GELOGE(RT_FAILED, "Call rt failed, status: 0x%x", status); + return RT_ERROR_TO_GE_STATUS(status); + } + allocated_mem.push_back(d_op_type_name); + GE_CHK_RT(rtMemcpy(d_op_type_name, op_type.length(), op_type.c_str(), op_type.length(), RT_MEMCPY_HOST_TO_DEVICE)); + op_info.opType = reinterpret_cast(reinterpret_cast(d_op_type_name)); + op_info.opLen = op_type.length(); + op_info.kernelsType = CPU_KERNEL; + GE_CHK_RT(rtMemcpy(d_req_op_list + i * sizeof(SysOpInfo), sizeof(SysOpInfo), &op_info, sizeof(SysOpInfo), RT_MEMCPY_HOST_TO_DEVICE)); + i++; + } + + for (const auto &op_type : aicpu_tf_optype_list) { + uint32_t i = aicpu_op_nums; + SysOpInfo op_info; + // malloc op_type name in SysOpInfo + void *d_op_type_name = nullptr; + status = rtMalloc(&d_op_type_name, op_type.size(), RT_MEMORY_HBM); + if (status != RT_ERROR_NONE) { + GELOGE(RT_FAILED, "Call rt failed, status: 0x%x", status); + return RT_ERROR_TO_GE_STATUS(status); + } + allocated_mem.push_back(d_op_type_name); + GE_CHK_RT(rtMemcpy(d_op_type_name, op_type.size(), op_type.c_str(), op_type.size(), RT_MEMCPY_HOST_TO_DEVICE)); + op_info.opType = reinterpret_cast(reinterpret_cast(d_op_type_name)); + op_info.opLen = op_type.size(); + op_info.kernelsType = TF_KERNEL; + GE_CHK_RT(rtMemcpy(d_req_op_list + i * sizeof(SysOpInfo), sizeof(SysOpInfo), &op_info, sizeof(SysOpInfo), RT_MEMCPY_HOST_TO_DEVICE)); + i++; + } + + SysOpCheckInfo op_check_info_req; + SysOpCheckResp op_check_info_res; + op_check_info_req.opListNum = op_nums; + op_check_info_req.offSetLen = sizeof(SysOpCheckInfo); + SysOpCheckInfo.sysOpInfoList = d_req_op_list; + + op_check_info_res.opListNum = op_nums; + op_check_info_res.returnCodeList = d_ret_code_list; + op_check_info_res.sysOpInfoList = d_res_op_list; + + uint32_t args_size = sizeof(SysOpCheckInfo) + sizeof(SysOpCheckResp); + status = rtMalloc(&args, args_size, RT_MEMORY_HBM); + if (status != RT_ERROR_NONE) { + GELOGE(RT_FAILED, "Call rt failed, status: 0x%x", status); + return RT_ERROR_TO_GE_STATUS(status); + } + allocated_mem.push_back(args); + GE_CHK_RT(rtMemcpy(args, sizeof(SysOpCheckInfo), &op_check_info_req, sizeof(SysOpCheckInfo), RT_MEMCPY_HOST_TO_DEVICE)); + GE_CHK_RT(rtMemcpy(args + op_check_info_req.offSetLen, sizeof(SysOpCheckResp), &op_check_info_res, sizeof(SysOpCheckResp), RT_MEMCPY_HOST_TO_DEVICE)); + + GE_CHK_RT(rtStreamCreate(&stream, 0)); + GE_CHK_RT(rtCpuKernelLaunch(nullptr, kernel_name.c_str(), 1, args, args_size, nullptr, stream)); + + status = rtStreamSynchronize(stream); + if (status != RT_ERROR_NONE) { + GELOGE(RT_FAILED, "Call rt stream sync failed, status: 0x%x", status); + return RT_ERROR_TO_GE_STATUS(status); + } + + // Check the response + void *d_op_check_info_res = args + op_check_info_req.offSetLen; + std::vector res_sysopinfo_list; + std::vector ret_code_list; + op_check_info_res = {}; + GE_CHK_RT(rtMemcpy(&op_check_info_res, sizeof(SysOpCheckResp), d_op_check_info_res, sizeof(SysOpCheckResp), RT_MEMCPY_DEVICE_TO_HOST)); + std::function callback = [&]() { + for (auto mem : allocated_mem) { + GE_CHK_RT(rtFree(mem)); + } + GE_CHK_RT(rtStreamDestroy(stream)); + }; + + if (op_check_info_res.opListNum != 0) { + String fail_reason = "Check aicpu op_type failed. details: \n"; + for (uint32_t i = 0; i < op_check_info_res.opListNum; i++) { + ReturnCode ret_code; + GE_CHK_RT(rtMemcpy(&ret_code, sizeof(ReturnCode), op_check_info_res.returnCodeList + i * sizeof(ReturnCode), sizeof(ReturnCode), RT_MEMCPY_DEVICE_TO_HOST)); + SysOpInfo aicpu_info; + GE_CHK_RT(rtMemcpy(&aicpu_info, sizeof(SysOpInfo), op_check_info_res.sysOpInfoList + i * sizeof(SysOpInfo), sizeof(SysOpInfo), RT_MEMCPY_DEVICE_TO_HOST)); + std::vector op_name; + GE_CHK_RT(rtMemcpy(op_name.data(), aicpu_info.opLen, aicpu_info.opType, aicpu_info.opLen, RT_MEMCPY_DEVICE_TO_HOST)); + String kernel_type = static_cast(aicpu_info.kernelsType) == TF_KERNEL ? "TF_KERNEL" : "CPU_KERNEL"; + string op_name_str(op_name.data()); + fail_reason += "op_type: " + op_name_str + " kernel_type: " + kernel_type + " " + ret_code + "<0: op_type, 1: format, 2: datatype> not support\n"; + } + GELOGE(FAILED, fail_reason); + GE_MAKE_GUARD(release, callback); + return FAILED; + } + + GE_MAKE_GUARD(release, callback); + GELOGI("Cpu kernel launch check optype task success."); + return SUCCESS; +} + +Status ModelManager::CheckAicpuOptype(GeModelPtr ge_model) { + GE_CHK_STATUS_RET(LaunchKernelCheckAicpuType(ge_model), "launch cust op so failed."); + return SUCCESS; +} + } // namespace ge diff --git a/ge/graph/load/new_model_manager/model_manager.h b/ge/graph/load/new_model_manager/model_manager.h index ff2e3030..3237f3f6 100755 --- a/ge/graph/load/new_model_manager/model_manager.h +++ b/ge/graph/load/new_model_manager/model_manager.h @@ -294,6 +294,10 @@ class FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY ModelManager { ge::Status LaunchKernelCustAicpuSo(const string &kernel_name); + ge::Status CheckAicpuOptype(GeModelPtr ge_model); + + ge::Status LaunchKernelCheckAicpuOpType(GeModelPtr ge_model); + ge::Status GetOrigInputInfo(uint32_t model_id, uint32_t index, OriginInputInfo &orig_input_info); ge::Status GenSessionId(uint64_t &session_id);