From a9e30a96dbe225fd1a2f5c66423d6c1b841ca55e Mon Sep 17 00:00:00 2001 From: leopz Date: Thu, 28 May 2020 16:08:39 +0800 Subject: [PATCH] separate py from debug and utils --- mindspore/ccsrc/debug/CMakeLists.txt | 1 + mindspore/ccsrc/debug/info.cc | 4 +- mindspore/ccsrc/debug/trace.cc | 85 ----- mindspore/ccsrc/debug/trace.h | 8 +- mindspore/ccsrc/debug/trace_base.cc | 120 +++++++ mindspore/ccsrc/debug/trace_base.h | 39 +++ mindspore/ccsrc/ir/dtype/type.cc | 12 +- mindspore/ccsrc/ir/dtype/type.h | 3 +- mindspore/ccsrc/ir/func_graph.cc | 2 +- mindspore/ccsrc/ir/func_graph_cloner.cc | 3 +- mindspore/ccsrc/ir/manager.cc | 4 +- mindspore/ccsrc/ir/primitive.cc | 4 +- mindspore/ccsrc/ir/value.cc | 6 +- mindspore/ccsrc/pipeline/pipeline.cc | 3 +- mindspore/ccsrc/pipeline/pipeline.h | 2 + .../pre_activate/common/pattern_engine.cc | 3 +- mindspore/ccsrc/session/ascend_session.cc | 1 + mindspore/ccsrc/session/gpu_session.cc | 3 +- mindspore/ccsrc/session/session_basic.cc | 2 +- mindspore/ccsrc/session/session_basic.h | 3 +- mindspore/ccsrc/utils/any.cc | 7 +- mindspore/ccsrc/utils/any.h | 6 +- mindspore/ccsrc/utils/base_ref.cc | 11 +- mindspore/ccsrc/utils/base_ref.h | 28 +- mindspore/ccsrc/utils/base_ref_extends.cc | 28 ++ mindspore/ccsrc/utils/base_ref_extends.h | 45 +++ mindspore/ccsrc/utils/base_ref_py.h | 31 ++ mindspore/ccsrc/utils/convert_utils.cc | 155 ++++++++- mindspore/ccsrc/utils/convert_utils.h | 113 ++----- mindspore/ccsrc/utils/convert_utils_base.h | 111 +++++++ mindspore/ccsrc/utils/graph_utils.cc | 299 +----------------- mindspore/ccsrc/utils/graph_utils.h | 26 +- mindspore/ccsrc/utils/graph_utils_extends.cc | 174 ++++++++++ mindspore/ccsrc/vm/backend.cc | 3 +- mindspore/ccsrc/vm/vm.cc | 3 +- mindspore/ccsrc/vm/vm.h | 4 +- mindspore/ccsrc/vm/vmimpl.h | 2 +- 37 files changed, 787 insertions(+), 567 deletions(-) create mode 100644 mindspore/ccsrc/debug/trace_base.cc create mode 100644 mindspore/ccsrc/debug/trace_base.h create mode 100644 mindspore/ccsrc/utils/base_ref_extends.cc create mode 100644 mindspore/ccsrc/utils/base_ref_extends.h create mode 100644 mindspore/ccsrc/utils/base_ref_py.h create mode 100644 mindspore/ccsrc/utils/convert_utils_base.h create mode 100644 mindspore/ccsrc/utils/graph_utils_extends.cc diff --git a/mindspore/ccsrc/debug/CMakeLists.txt b/mindspore/ccsrc/debug/CMakeLists.txt index 881eb7f1f8..30b10a17fd 100644 --- a/mindspore/ccsrc/debug/CMakeLists.txt +++ b/mindspore/ccsrc/debug/CMakeLists.txt @@ -6,6 +6,7 @@ set(_DEBUG_SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/info.cc" "${CMAKE_CURRENT_SOURCE_DIR}/label.cc" "${CMAKE_CURRENT_SOURCE_DIR}/trace_info.cc" + "${CMAKE_CURRENT_SOURCE_DIR}/trace_base.cc" "${CMAKE_CURRENT_SOURCE_DIR}/trace.cc" ) diff --git a/mindspore/ccsrc/debug/info.cc b/mindspore/ccsrc/debug/info.cc index 770192a81d..406bd11fab 100644 --- a/mindspore/ccsrc/debug/info.cc +++ b/mindspore/ccsrc/debug/info.cc @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ #include #include #include "ir/anf.h" -#include "utils/convert_utils.h" +#include "utils/convert_utils_base.h" namespace mindspore { std::string HighLightLine(const std::string &line, int col_begin, int col_end, SourceLineTip tip) { diff --git a/mindspore/ccsrc/debug/trace.cc b/mindspore/ccsrc/debug/trace.cc index 249d6cd6ec..e5507a8c2b 100644 --- a/mindspore/ccsrc/debug/trace.cc +++ b/mindspore/ccsrc/debug/trace.cc @@ -54,91 +54,6 @@ std::string GetAbstractStr(const abstract::AbstractBasePtr &abs) { return oss.str(); } -std::vector GetSourceCodeDebugInfoVec(DebugInfoPtr debug_info) { - std::vector debug_with_loc_vec; - while (debug_info != nullptr) { - if (debug_info->location() != nullptr) { - debug_with_loc_vec.push_back(debug_info); - } - if (debug_info->trace_info() != nullptr) { - debug_info = debug_info->trace_info()->debug_info(); - } else { - break; - } - } - return debug_with_loc_vec; -} - -DebugInfoPtr GetSourceCodeDebugInfo(const DebugInfoPtr &info) { - auto debug_with_loc_vec = GetSourceCodeDebugInfoVec(info); - if (debug_with_loc_vec.size() > 0) { - return debug_with_loc_vec[0]; - } else { - return info; - } -} - -std::string GetDebugInfo(const DebugInfoPtr &info, SourceLineTip tip) { - if (info == nullptr) { - return ""; - } - auto src_info = GetSourceCodeDebugInfo(info); - if (src_info->location() != nullptr) { - return src_info->location()->ToString(tip); - } - return ""; -} - -// a trace info identifies a node transform, so we can trace the node transform through -// a link of trace info and debug info -std::string GetInfoWithAction(const std::vector &info_vec, SourceLineTip tip) { - if (info_vec.size() < 1) { - return ""; - } - if (info_vec.size() == 1) { - return info_vec[0]->location()->ToString(tip); - } - std::string traced_info = info_vec[0]->location()->ToString(tip); - for (size_t i = 1; i < info_vec.size(); i++) { - auto action_name = info_vec[i - 1]->trace_info()->GetActionBetweenNode(info_vec[i]); - if (action_name == "") { - break; - } - traced_info = traced_info + action_name + info_vec[i]->location()->ToString(tip); - } - return traced_info; -} - -std::string GetTracedDebugInfo(const DebugInfoPtr &info, SourceLineTip tip) { - if (info == nullptr) { - return ""; - } - auto info_vec = GetSourceCodeDebugInfoVec(info); - if (info_vec.size() == 0) { - return ""; - } else if (info_vec.size() == 1) { - return info_vec[0]->location()->ToString(tip); - } else if (info_vec.size() > 1) { - return GetInfoWithAction(info_vec, tip); - } - return ""; -} - -std::string GetDebugInfo(const DebugInfoPtr &info, const std::string &prefix, SourceLineTip tip) { - std::ostringstream oss; - if (info == nullptr) { - return ""; - } - - auto debug_info = GetTracedDebugInfo(info, tip); - if (tip == kSourceLineTipDiscard) { - std::replace(debug_info.begin(), debug_info.end(), '\r', '/'); - std::replace(debug_info.begin(), debug_info.end(), '\n', '/'); - } - oss << prefix << debug_info; - return oss.str(); -} - std::string GetGraphParamString(const FuncGraphPtr &graph, abstract::AbstractBasePtrList args_spec_list) { std::ostringstream oss; oss << "graph:" << graph->ToString() << " with args["; diff --git a/mindspore/ccsrc/debug/trace.h b/mindspore/ccsrc/debug/trace.h index 2f4c98a112..9583997e93 100644 --- a/mindspore/ccsrc/debug/trace.h +++ b/mindspore/ccsrc/debug/trace.h @@ -23,17 +23,15 @@ #include #include +#include "debug/trace_base.h" +#include "debug/info.h" #include "ir/anf.h" -#include "utils/any.h" #include "ir/func_graph.h" -#include "debug/info.h" #include "pipeline/static_analysis/static_analysis.h" +#include "utils/any.h" namespace mindspore { namespace trace { -std::string GetDebugInfo(const DebugInfoPtr &info, SourceLineTip tip = kSourceLineTipNextLine); -std::string GetDebugInfo(const DebugInfoPtr &info, const std::string &prefix, - SourceLineTip tip = kSourceLineTipNextLine); DebugInfoPtr GetSourceCodeDebugInfo(const DebugInfoPtr &info); void TraceGraphEval(); void GetEvalStackInfo(std::ostringstream &oss); diff --git a/mindspore/ccsrc/debug/trace_base.cc b/mindspore/ccsrc/debug/trace_base.cc new file mode 100644 index 0000000000..6cd41d7f2d --- /dev/null +++ b/mindspore/ccsrc/debug/trace_base.cc @@ -0,0 +1,120 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "debug/trace_base.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils/graph_utils.h" + +namespace mindspore { +// namespace to support debug trace infomation +namespace trace { +std::vector GetSourceCodeDebugInfoVec(DebugInfoPtr debug_info) { + std::vector debug_with_loc_vec; + while (debug_info != nullptr) { + if (debug_info->location() != nullptr) { + debug_with_loc_vec.push_back(debug_info); + } + if (debug_info->trace_info() != nullptr) { + debug_info = debug_info->trace_info()->debug_info(); + } else { + break; + } + } + return debug_with_loc_vec; +} + +DebugInfoPtr GetSourceCodeDebugInfo(const DebugInfoPtr &info) { + auto debug_with_loc_vec = GetSourceCodeDebugInfoVec(info); + if (debug_with_loc_vec.size() > 0) { + return debug_with_loc_vec[0]; + } else { + return info; + } +} + +std::string GetDebugInfo(const DebugInfoPtr &info, SourceLineTip tip) { + if (info == nullptr) { + return ""; + } + auto src_info = GetSourceCodeDebugInfo(info); + if (src_info->location() != nullptr) { + return src_info->location()->ToString(tip); + } + return ""; +} + +// a trace info identifies a node transform, so we can trace the node transform through +// a link of trace info and debug info +std::string GetInfoWithAction(const std::vector &info_vec, SourceLineTip tip) { + if (info_vec.size() < 1) { + return ""; + } + if (info_vec.size() == 1) { + return info_vec[0]->location()->ToString(tip); + } + std::string traced_info = info_vec[0]->location()->ToString(tip); + for (size_t i = 1; i < info_vec.size(); i++) { + auto action_name = info_vec[i - 1]->trace_info()->GetActionBetweenNode(info_vec[i]); + if (action_name == "") { + break; + } + traced_info = traced_info + action_name + info_vec[i]->location()->ToString(tip); + } + return traced_info; +} + +std::string GetTracedDebugInfo(const DebugInfoPtr &info, SourceLineTip tip) { + if (info == nullptr) { + return ""; + } + auto info_vec = GetSourceCodeDebugInfoVec(info); + if (info_vec.size() == 0) { + return ""; + } else if (info_vec.size() == 1) { + return info_vec[0]->location()->ToString(tip); + } else if (info_vec.size() > 1) { + return GetInfoWithAction(info_vec, tip); + } + return ""; +} + +std::string GetDebugInfo(const DebugInfoPtr &info, const std::string &prefix, SourceLineTip tip) { + std::ostringstream oss; + if (info == nullptr) { + return ""; + } + + auto debug_info = GetTracedDebugInfo(info, tip); + if (tip == kSourceLineTipDiscard) { + std::replace(debug_info.begin(), debug_info.end(), '\r', '/'); + std::replace(debug_info.begin(), debug_info.end(), '\n', '/'); + } + oss << prefix << debug_info; + return oss.str(); +} +} // namespace trace +} // namespace mindspore diff --git a/mindspore/ccsrc/debug/trace_base.h b/mindspore/ccsrc/debug/trace_base.h new file mode 100644 index 0000000000..774931cc09 --- /dev/null +++ b/mindspore/ccsrc/debug/trace_base.h @@ -0,0 +1,39 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MINDSPORE_CCSRC_DEBUG_TRACE_BASE_H_ +#define MINDSPORE_CCSRC_DEBUG_TRACE_BASE_H_ + +#include +#include +#include +#include +#include +#include + +#include "debug/info.h" +#include "ir/anf.h" +#include "ir/func_graph.h" +#include "utils/any.h" + +namespace mindspore { +namespace trace { +std::string GetDebugInfo(const DebugInfoPtr &info, SourceLineTip tip = kSourceLineTipNextLine); +std::string GetDebugInfo(const DebugInfoPtr &info, const std::string &prefix, + SourceLineTip tip = kSourceLineTipNextLine); +} // namespace trace +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_DEBUG_TRACE_BASE_H_ diff --git a/mindspore/ccsrc/ir/dtype/type.cc b/mindspore/ccsrc/ir/dtype/type.cc index 402010759d..5395b59617 100644 --- a/mindspore/ccsrc/ir/dtype/type.cc +++ b/mindspore/ccsrc/ir/dtype/type.cc @@ -1,7 +1,7 @@ /** * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). * - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,14 @@ */ #include "ir/dtype/type.h" -#include -#include + #include -#include "utils/log_adapter.h" +#include +#include + #include "ir/dtype/number.h" -#include "utils/convert_utils.h" +#include "utils/log_adapter.h" +#include "utils/convert_utils_base.h" namespace mindspore { TypeId IntBitsToTypeId(const int nbits) { diff --git a/mindspore/ccsrc/ir/dtype/type.h b/mindspore/ccsrc/ir/dtype/type.h index 1c67b6a855..a4035abf50 100644 --- a/mindspore/ccsrc/ir/dtype/type.h +++ b/mindspore/ccsrc/ir/dtype/type.h @@ -1,7 +1,7 @@ /** * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). * - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ #include #include #include + #include "ir/base.h" #include "ir/named.h" diff --git a/mindspore/ccsrc/ir/func_graph.cc b/mindspore/ccsrc/ir/func_graph.cc index 5cefcadee7..d5d80eb2f0 100644 --- a/mindspore/ccsrc/ir/func_graph.cc +++ b/mindspore/ccsrc/ir/func_graph.cc @@ -27,7 +27,7 @@ #include "operator/ops.h" #include "pybind_api/export_flags.h" #include "utils/ordered_set.h" -#include "utils/convert_utils.h" +#include "utils/convert_utils_base.h" namespace mindspore { /* diff --git a/mindspore/ccsrc/ir/func_graph_cloner.cc b/mindspore/ccsrc/ir/func_graph_cloner.cc index db52e08348..4622bf9ea2 100644 --- a/mindspore/ccsrc/ir/func_graph_cloner.cc +++ b/mindspore/ccsrc/ir/func_graph_cloner.cc @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ #include "ir/manager.h" #include "ir/param_value_py.h" #include "operator/ops.h" +#include "utils/convert_utils_base.h" #include "utils/log_adapter.h" #include "utils/profile.h" #include "utils/context/ms_context.h" diff --git a/mindspore/ccsrc/ir/manager.cc b/mindspore/ccsrc/ir/manager.cc index ca6b6219db..4b9f0c22e9 100644 --- a/mindspore/ccsrc/ir/manager.cc +++ b/mindspore/ccsrc/ir/manager.cc @@ -22,11 +22,11 @@ #include #include +#include "debug/trace_base.h" #include "ir/func_graph.h" #include "utils/profile.h" -#include "utils/convert_utils.h" +#include "utils/convert_utils_base.h" #include "operator/ops.h" -#include "debug/trace.h" namespace mindspore { diff --git a/mindspore/ccsrc/ir/primitive.cc b/mindspore/ccsrc/ir/primitive.cc index 7f6080828d..4be4489d5b 100644 --- a/mindspore/ccsrc/ir/primitive.cc +++ b/mindspore/ccsrc/ir/primitive.cc @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ #include "pipeline/parse/python_adapter.h" #include "pipeline/parse/data_converter.h" #include "pybind11/pytypes.h" -#include "utils/convert_utils.h" +#include "utils/convert_utils_base.h" #include "utils/primitive_utils.h" #include "pybind_api/api_register.h" diff --git a/mindspore/ccsrc/ir/value.cc b/mindspore/ccsrc/ir/value.cc index 4dc0550c3d..92535bc2e9 100644 --- a/mindspore/ccsrc/ir/value.cc +++ b/mindspore/ccsrc/ir/value.cc @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,13 @@ */ #include "ir/value.h" + #include #include #include #include -#include "utils/convert_utils.h" + +#include "utils/convert_utils_base.h" namespace mindspore { const ValuePtr ValueSequeue::operator[](const std::size_t &dim) const { diff --git a/mindspore/ccsrc/pipeline/pipeline.cc b/mindspore/ccsrc/pipeline/pipeline.cc index 3606fb8cd6..e672481fdb 100644 --- a/mindspore/ccsrc/pipeline/pipeline.cc +++ b/mindspore/ccsrc/pipeline/pipeline.cc @@ -1,7 +1,7 @@ /** * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). * - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,6 @@ #include "utils/config_manager.h" #include "utils/convert_utils.h" #include "utils/utils.h" -#include "utils/base_ref.h" #include "vm/segment_runner.h" #include "parallel/context.h" #include "parallel/graph_util/get_parallel_info.h" diff --git a/mindspore/ccsrc/pipeline/pipeline.h b/mindspore/ccsrc/pipeline/pipeline.h index cfe84c448e..22d6a3ee60 100644 --- a/mindspore/ccsrc/pipeline/pipeline.h +++ b/mindspore/ccsrc/pipeline/pipeline.h @@ -24,6 +24,8 @@ #include #include #include + +#include "utils/base_ref_extends.h" #include "debug/draw.h" #include "ir/anf.h" #include "ir/tensor.h" diff --git a/mindspore/ccsrc/pre_activate/common/pattern_engine.cc b/mindspore/ccsrc/pre_activate/common/pattern_engine.cc index 350332b9d1..42f966aa3d 100644 --- a/mindspore/ccsrc/pre_activate/common/pattern_engine.cc +++ b/mindspore/ccsrc/pre_activate/common/pattern_engine.cc @@ -1,7 +1,7 @@ /** * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). * - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ #include "optimizer/opt.h" #include "ir/anf.h" +#include "utils/convert_utils_base.h" #include "utils/overload.h" namespace mindspore { diff --git a/mindspore/ccsrc/session/ascend_session.cc b/mindspore/ccsrc/session/ascend_session.cc index 0da6fc067e..624527b2df 100644 --- a/mindspore/ccsrc/session/ascend_session.cc +++ b/mindspore/ccsrc/session/ascend_session.cc @@ -42,6 +42,7 @@ #include "device/kernel_runtime_manager.h" #include "kernel/tbe/tbe_python_funcs.h" #include "utils/config_manager.h" +#include "utils/base_ref_extends.h" namespace mindspore { namespace session { diff --git a/mindspore/ccsrc/session/gpu_session.cc b/mindspore/ccsrc/session/gpu_session.cc index 725e2181d0..452e032ed1 100644 --- a/mindspore/ccsrc/session/gpu_session.cc +++ b/mindspore/ccsrc/session/gpu_session.cc @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ #include "common/utils.h" #include "common/trans.h" #include "utils/context/ms_context.h" +#include "utils/base_ref_extends.h" namespace mindspore { namespace session { diff --git a/mindspore/ccsrc/session/session_basic.cc b/mindspore/ccsrc/session/session_basic.cc index 928ac88501..b2d4644e15 100644 --- a/mindspore/ccsrc/session/session_basic.cc +++ b/mindspore/ccsrc/session/session_basic.cc @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/mindspore/ccsrc/session/session_basic.h b/mindspore/ccsrc/session/session_basic.h index e33efd4be5..b2e8c8894f 100755 --- a/mindspore/ccsrc/session/session_basic.h +++ b/mindspore/ccsrc/session/session_basic.h @@ -22,12 +22,13 @@ #include #include #include + +#include "utils/base_ref_extends.h" #include "session/session_context.h" #include "session/kernel_graph.h" #include "ir/anf.h" #include "ir/tensor.h" #include "utils/any.h" -#include "utils/base_ref.h" #include "utils/contract.h" #include "pynative/pynative_execute.h" #include "device/kernel_info.h" diff --git a/mindspore/ccsrc/utils/any.cc b/mindspore/ccsrc/utils/any.cc index 80b8d86658..8f4039922c 100644 --- a/mindspore/ccsrc/utils/any.cc +++ b/mindspore/ccsrc/utils/any.cc @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,11 +30,6 @@ bool AnyIsLiteral(const Any &any) { return typeid_int == typeid_any || typeid_float == typeid_any || typeid_bool == typeid_any; } -std::ostream &operator<<(std::ostream &os, const pybind11::object &obj) { - os << "[py::object]"; - return os; -} - Any &Any::operator=(const Any &other) { if (m_ptr == other.m_ptr || &other == this) { return *this; diff --git a/mindspore/ccsrc/utils/any.h b/mindspore/ccsrc/utils/any.h index b4edf602ac..d5da5b2938 100644 --- a/mindspore/ccsrc/utils/any.h +++ b/mindspore/ccsrc/utils/any.h @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,8 +26,6 @@ #include #include -#include "pybind11/pybind11.h" - #include "utils/overload.h" #include "utils/log_adapter.h" #include "utils/misc.h" @@ -39,8 +37,6 @@ std::string type(const T &t) { return demangle(typeid(t).name()); } -std::ostream &operator<<(std::ostream &os, const pybind11::object &obj); - class Any { public: // constructors diff --git a/mindspore/ccsrc/utils/base_ref.cc b/mindspore/ccsrc/utils/base_ref.cc index aa38c8a6a0..b0d3564c1c 100644 --- a/mindspore/ccsrc/utils/base_ref.cc +++ b/mindspore/ccsrc/utils/base_ref.cc @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -185,13 +185,4 @@ bool RunFunctionRef::operator==(const BaseRef &other) const { } bool RunFunctionRef::operator==(const RunFunctionRef &other) const { return func_ == other.func_; } - -bool PyObjectRef::operator==(const BaseRef &other) const { - if (!utils::isa(other)) { - return false; - } - return *this == utils::cast(other); -} - -bool PyObjectRef::operator==(const PyObjectRef &other) const { return object_ == other.object_; } } // namespace mindspore diff --git a/mindspore/ccsrc/utils/base_ref.h b/mindspore/ccsrc/utils/base_ref.h index e55cd39357..7c0b4b2f1c 100644 --- a/mindspore/ccsrc/utils/base_ref.h +++ b/mindspore/ccsrc/utils/base_ref.h @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,16 @@ #include #include #include -#include "pybind11/pybind11.h" -#include "ir/value.h" -namespace py = pybind11; +#include "ir/value.h" namespace mindspore { class BaseRef; class VectorRef; class SetRef; -class PyObjectRef; class RunFunctionRef; using iterator = std::vector::iterator; - using const_iterator = std::vector::const_iterator; using const_reverse_iterator = std::vector::const_reverse_iterator; @@ -88,8 +84,6 @@ inline std::shared_ptr MakeNode(const AnfNodePtrList &a) { } inline std::shared_ptr MakeNode(const SetRef &a) { return std::make_shared(std::move(a)); } inline std::shared_ptr MakeNode(const RunFuncPtr &a) { return std::make_shared(a); } -inline std::shared_ptr MakeNode(const py::object &a) { return std::make_shared(a); } -inline std::shared_ptr MakeNode(const py::tuple &a) { return std::make_shared(a); } class BaseRef : public Base { public: @@ -367,24 +361,6 @@ class SetRef : public BaseRef { using SetRefPtr = std::shared_ptr; -class PyObjectRef : public BaseRef { - public: - explicit PyObjectRef(const py::object &py_object) : object_(py_object) {} - explicit PyObjectRef(const py::tuple &tuple_obj) : object_(tuple_obj) {} - - ~PyObjectRef() override = default; - - std::shared_ptr copy() const override { return std::make_shared(object_); } - MS_DECLARE_PARENT(PyObjectRef, BaseRef) - - uint32_t type() const override { return tid(); } - std::string ToString() const override { return py::str(object_); } - bool operator==(const BaseRef &other) const override; - bool operator==(const PyObjectRef &other) const; - - py::object object_; -}; - class RunFunctionRef : public BaseRef { public: RunFunctionRef() {} diff --git a/mindspore/ccsrc/utils/base_ref_extends.cc b/mindspore/ccsrc/utils/base_ref_extends.cc new file mode 100644 index 0000000000..e720b150b8 --- /dev/null +++ b/mindspore/ccsrc/utils/base_ref_extends.cc @@ -0,0 +1,28 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils/base_ref_extends.h" + +namespace mindspore { +bool PyObjectRef::operator==(const BaseRef &other) const { + if (!utils::isa(other)) { + return false; + } + return *this == utils::cast(other); +} + +bool PyObjectRef::operator==(const PyObjectRef &other) const { return object_ == other.object_; } +} // namespace mindspore diff --git a/mindspore/ccsrc/utils/base_ref_extends.h b/mindspore/ccsrc/utils/base_ref_extends.h new file mode 100644 index 0000000000..5aa603bfe9 --- /dev/null +++ b/mindspore/ccsrc/utils/base_ref_extends.h @@ -0,0 +1,45 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MINDSPORE_CCSRC_UTILS_BASE_REF_EXTENDS_H_ +#define MINDSPORE_CCSRC_UTILS_BASE_REF_EXTENDS_H_ + +#include +#include + +#include "utils/base_ref_py.h" +#include "utils/base_ref.h" + +namespace mindspore { +class PyObjectRef : public BaseRef { + public: + explicit PyObjectRef(const py::object &py_object) : object_(py_object) {} + explicit PyObjectRef(const py::tuple &tuple_obj) : object_(tuple_obj) {} + + ~PyObjectRef() override = default; + + std::shared_ptr copy() const override { return std::make_shared(object_); } + MS_DECLARE_PARENT(PyObjectRef, BaseRef) + + uint32_t type() const override { return tid(); } + std::string ToString() const override { return py::str(object_); } + bool operator==(const BaseRef &other) const override; + bool operator==(const PyObjectRef &other) const; + + py::object object_; +}; +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_UTILS_BASE_REF_EXTENDS_H_ diff --git a/mindspore/ccsrc/utils/base_ref_py.h b/mindspore/ccsrc/utils/base_ref_py.h new file mode 100644 index 0000000000..36b5f5d2aa --- /dev/null +++ b/mindspore/ccsrc/utils/base_ref_py.h @@ -0,0 +1,31 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MINDSPORE_CCSRC_UTILS_BASE_REF_PY_H_ +#define MINDSPORE_CCSRC_UTILS_BASE_REF_PY_H_ + +#include + +#include "pybind11/pybind11.h" + +namespace py = pybind11; + +namespace mindspore { +class PyObjectRef; +inline std::shared_ptr MakeNode(const py::object &a) { return std::make_shared(a); } +inline std::shared_ptr MakeNode(const py::tuple &a) { return std::make_shared(a); } +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_UTILS_BASE_REF_PY_H_ diff --git a/mindspore/ccsrc/utils/convert_utils.cc b/mindspore/ccsrc/utils/convert_utils.cc index 97c2be142d..9cad14da33 100644 --- a/mindspore/ccsrc/utils/convert_utils.cc +++ b/mindspore/ccsrc/utils/convert_utils.cc @@ -25,11 +25,12 @@ #include #include "pybind11/pybind11.h" - -#include "ir/tensor.h" +#include "pipeline/static_analysis/abstract_value.h" #include "pipeline/parse/parse.h" #include "pipeline/parse/parse_base.h" #include "ir/value.h" +#include "ir/tensor.h" +#include "utils/base_ref_extends.h" namespace mindspore { py::object BuiltinsToPyData(const Any &value); @@ -429,4 +430,154 @@ bool IsGraphOutputValueNodeOrParameter(const AnfNodePtr &output, const py::tuple } return false; } + +// Isomorphism +static bool SameNodeShallow(const AnfNodePtr &node1, const AnfNodePtr &node2, FuncGraphPairMapEquiv *equiv_func_graph, + NodeMapEquiv *const equiv_node) { + if (equiv_node == nullptr) { + MS_LOG(ERROR) << "Invalid equiv_node"; + return false; + } + if (equiv_node->count(node1) > 0 && (*equiv_node)[node1] == node2) { + return true; + } + if (IsValueNode(node1) && IsValueNode(node2)) { + return Isomorphic(GetValueNode(node1), GetValueNode(node2), equiv_func_graph, + equiv_node); + } + if (node1->isa() && node2->isa()) { + auto a1 = GetValueNode(node1); + auto a2 = GetValueNode(node2); + if (a1->isa() && a2->isa()) { + return a1->cast()->name() == a2->cast()->name(); + } else if (a1->isa() && a2->isa()) { + return a1->cast()->ValueEqual(*(a2->cast())); + } else { + return *a1 == *a2; + } + } + if (node1->isa() && node2->isa()) { + auto para1 = node1->cast(); + auto para2 = node2->cast(); + if (para1->name() == para2->name()) { + return true; + } + MS_LOG(DEBUG) << "two parameters are not equal."; + return false; + } + MS_LOG(ERROR) << "type error"; + return false; +} + +static bool SameNode(const AnfNodePtr &node1, const AnfNodePtr &node2, FuncGraphPairMapEquiv *equiv_func_graph, + NodeMapEquiv *const equiv_node) { + MS_EXCEPTION_IF_NULL(node1); + MS_EXCEPTION_IF_NULL(node2); + if (node1->isa() && node2->isa()) { + auto &inputs1 = node1->cast()->inputs(); + auto &inputs2 = node2->cast()->inputs(); + for (std::size_t i = 0; i < inputs1.size(); ++i) { + if (!SameNodeShallow(inputs1[i], inputs2[i], equiv_func_graph, equiv_node)) { + return false; + } + } + return true; + } + return SameNodeShallow(node1, node2, equiv_func_graph, equiv_node); +} + +static bool SameSubgraph(AnfNodePtr root1, AnfNodePtr root2, FuncGraphPairMapEquiv *equiv_func_graph, + NodeMapEquiv *const equiv_node) { + std::unordered_set done; + std::stack> todo; + + todo.push(std::make_pair(root1, root2)); + while (todo.size() > 0) { + AnfNodePtr node1 = todo.top().first; + if (done.count(node1) > 0) { + todo.pop(); + continue; + } + AnfNodePtr node2 = todo.top().second; + + bool condition = false; + std::vector s1 = SuccIncoming(node1); + std::vector s2 = SuccIncoming(node2); + + if (s1.size() != s2.size()) { + return false; + } + for (std::size_t i = 0; i < s1.size(); ++i) { + if (done.count(s1[i]) == 0) { + todo.push(std::make_pair(s1[i], s2[i])); + condition = true; + } + } + if (condition) { + continue; + } + (void)done.insert(node1); + + auto res = SameNode(node1, node2, equiv_func_graph, equiv_node); + if (res) { + (*equiv_node)[node1] = node2; + } else { + return false; + } + todo.pop(); + } + return true; +} + +bool Isomorphic(FuncGraphPtr fg1, FuncGraphPtr fg2, FuncGraphPairMapEquiv *equiv_func_graph, + NodeMapEquiv *const equiv_node) { + auto fg1_fg2 = std::make_pair(fg1, fg2); + if (equiv_func_graph == nullptr) { + MS_LOG(ERROR) << "equiv_func_graph not init"; + return false; + } + if (equiv_func_graph->find(fg1_fg2) != equiv_func_graph->end()) { + return (*equiv_func_graph)[fg1_fg2] != kNotEquiv; + } + if (fg1 == nullptr || fg2 == nullptr) { + MS_LOG(ERROR) << "Invalid function graph"; + return false; + } + if (fg1->parameters().size() != fg2->parameters().size()) { + MS_LOG(DEBUG) << "parameters size not match"; + return false; + } + if (equiv_node != nullptr) { + for (std::size_t i = 0; i < fg1->parameters().size(); ++i) { + (*equiv_node)[fg1->parameters()[i]] = fg2->parameters()[i]; + } + (*equiv_func_graph)[fg1_fg2] = kPending; + auto result = SameSubgraph(fg1->get_return(), fg2->get_return(), equiv_func_graph, equiv_node); + (*equiv_func_graph)[fg1_fg2] = EquivState(result); + return result; + } + + MS_LOG(ERROR) << "equiv_node not init"; + return false; +} + +tensor::TensorPtr ScalarToTensor(const ScalarPtr &scalar) { + if (scalar == nullptr) { + MS_EXCEPTION(ArgumentError) << "Nullptr Error!"; + } + tensor::TensorPtr tensor = nullptr; + if (scalar->isa()) { + tensor = std::make_shared(py::float_(GetValue(scalar)), kFloat32); + } else if (scalar->isa()) { + tensor = std::make_shared(py::int_(GetValue(scalar)), kInt32); + } else if (scalar->isa()) { + tensor = std::make_shared(py::array(py::bool_(GetValue(scalar))), kBool); + } else { + auto type = scalar->type(); + auto type_str = (type == nullptr) ? "nullptr" : type->ToString(); + MS_LOG(EXCEPTION) << "Invalid scalar type: " << type_str; + } + MS_EXCEPTION_IF_NULL(tensor); + return tensor; +} } // namespace mindspore diff --git a/mindspore/ccsrc/utils/convert_utils.h b/mindspore/ccsrc/utils/convert_utils.h index 55f478d5fe..40c3e88c5c 100644 --- a/mindspore/ccsrc/utils/convert_utils.h +++ b/mindspore/ccsrc/utils/convert_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,16 +19,25 @@ #include #include -#include "pybind11/pybind11.h" +#include +#include +#include +#include +#include "pybind11/pybind11.h" +#include "utils/convert_utils_base.h" #include "utils/any.h" +#include "utils/base_ref.h" #include "ir/base.h" #include "ir/anf.h" -#include "utils/base_ref.h" namespace py = pybind11; namespace mindspore { +namespace tensor { +class Tensor; +using TensorPtr = std::shared_ptr; +} // namespace tensor py::object AnyToPyData(const Any &value); py::object BaseRefToPyData(const BaseRef &value); @@ -36,95 +45,29 @@ bool BaseRefToBool(const BaseRef &in, bool *out); bool ValueToBool(const ValuePtr &in, bool *out); py::object ValuePtrToPyData(const ValuePtr &value); -inline int SizeToInt(size_t u) { - if (u > static_cast((std::numeric_limits::max)())) { - MS_LOG(EXCEPTION) << "The size_t value(" << u << ") exceeds the maximum value of int."; - } - return static_cast(u); -} - -inline uint32_t SizeToUint(size_t u) { - if (u > static_cast((std::numeric_limits::max)())) { - MS_LOG(EXCEPTION) << "The size_t value(" << u << ") exceeds the maximum value of uint32_t."; - } - return static_cast(u); -} - -inline int64_t SizeToLong(size_t u) { - if (u > static_cast((std::numeric_limits::max)())) { - MS_LOG(EXCEPTION) << "The size_t value(" << u << ") exceeds the maximum value of int64_t."; - } - return static_cast(u); -} - -inline size_t IntToSize(int u) { - if (u < 0) { - MS_LOG(EXCEPTION) << "The int value(" << u << ") is less than 0."; - } - return static_cast(u); -} - -inline size_t LongToSize(int64_t u) { - if (u < 0) { - MS_LOG(EXCEPTION) << "The int64_t value(" << u << ") is less than 0."; - } - return static_cast(u); -} - -inline size_t FloatToSize(float u) { - if (u < 0) { - MS_LOG(EXCEPTION) << "The float value(" << u << ") is less than 0."; - } - - if (u > static_cast((std::numeric_limits::max)())) { - MS_LOG(EXCEPTION) << "The float value(" << u << ") exceeds the maximum value of size_t."; - } - return static_cast(u); -} -inline float IntToFloat(int32_t v) { return static_cast(v); } - -inline uint32_t IntToUint(int32_t u) { - if (u < 0) { - MS_LOG(EXCEPTION) << "The int32_t value(" << u << ") is less than 0."; - } - return static_cast(u); -} - -inline int32_t UintToInt(uint32_t u) { - if (u > static_cast((std::numeric_limits::max)())) { - MS_LOG(EXCEPTION) << "The uint32_t value(" << u << ") exceeds the maximum value of int32_t."; - } - return static_cast(u); -} +AbstractBasePtr PyListDtype2AbstractTensor(const py::object &shape_obj, const py::object &type_obj); -inline unsigned int UlongToUint(size_t u) { - if (u > static_cast((std::numeric_limits::max)())) { - MS_LOG(EXCEPTION) << "The size_t value(" << u << ") exceeds the maximum value of unsigned int."; - } - return static_cast(u); -} +bool IsGraphOutputValueNodeOrParameter(const AnfNodePtr &output, const py::tuple &args, + const std::shared_ptr &ret_val); -inline void IntMulWithOverflowCheck(int a, int b, int *c) { - int out = a * b; - if (a != 0) { - bool ok = ((out / a) != b); - if (ok) { - MS_LOG(EXCEPTION) << "Mul: a(" << a << ") * b(" << b << ") result is overflow"; - } +// Isomorphism +struct PairHasher { + template + std::size_t operator()(const std::pair &p) const { + auto h1 = std::hash{}(p.first); + auto h2 = std::hash{}(p.second); + return h1 ^ h2; } - *c = out; -} +}; -inline uint8_t *AddressOffset(void *address, size_t offset) { - MS_EXCEPTION_IF_NULL(address); - return static_cast(address) + offset; -} +enum EquivState { kNotEquiv = 0, kEquiv = 1, kPending = 2 }; -AbstractBasePtr PyListDtype2AbstractTensor(const py::object &shape_obj, const py::object &type_obj); +using FuncGraphPairMapEquiv = std::unordered_map, EquivState, PairHasher>; +using NodeMapEquiv = std::unordered_map; -bool IsGraphOutputValueNodeOrParameter(const AnfNodePtr &output, const py::tuple &args, - const std::shared_ptr &ret_val); +bool Isomorphic(FuncGraphPtr g1, FuncGraphPtr g2, FuncGraphPairMapEquiv *equiv_func_graph, NodeMapEquiv *equiv_node); +tensor::TensorPtr ScalarToTensor(const ScalarPtr &scalar); } // namespace mindspore #endif // MINDSPORE_CCSRC_UTILS_CONVERT_UTILS_H_ diff --git a/mindspore/ccsrc/utils/convert_utils_base.h b/mindspore/ccsrc/utils/convert_utils_base.h new file mode 100644 index 0000000000..76d8930324 --- /dev/null +++ b/mindspore/ccsrc/utils/convert_utils_base.h @@ -0,0 +1,111 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_UTILS_CONVERT_UTILS_BASE_H_ +#define MINDSPORE_CCSRC_UTILS_CONVERT_UTILS_BASE_H_ + +#include +#include + +#include "utils/log_adapter.h" + +namespace mindspore { +inline int SizeToInt(size_t u) { + if (u > static_cast((std::numeric_limits::max)())) { + MS_LOG(EXCEPTION) << "The size_t value(" << u << ") exceeds the maximum value of int."; + } + return static_cast(u); +} + +inline uint32_t SizeToUint(size_t u) { + if (u > static_cast((std::numeric_limits::max)())) { + MS_LOG(EXCEPTION) << "The size_t value(" << u << ") exceeds the maximum value of uint32_t."; + } + return static_cast(u); +} + +inline int64_t SizeToLong(size_t u) { + if (u > static_cast((std::numeric_limits::max)())) { + MS_LOG(EXCEPTION) << "The size_t value(" << u << ") exceeds the maximum value of int64_t."; + } + return static_cast(u); +} + +inline size_t IntToSize(int u) { + if (u < 0) { + MS_LOG(EXCEPTION) << "The int value(" << u << ") is less than 0."; + } + return static_cast(u); +} + +inline size_t LongToSize(int64_t u) { + if (u < 0) { + MS_LOG(EXCEPTION) << "The int64_t value(" << u << ") is less than 0."; + } + return static_cast(u); +} + +inline size_t FloatToSize(float u) { + if (u < 0) { + MS_LOG(EXCEPTION) << "The float value(" << u << ") is less than 0."; + } + + if (u > static_cast((std::numeric_limits::max)())) { + MS_LOG(EXCEPTION) << "The float value(" << u << ") exceeds the maximum value of size_t."; + } + return static_cast(u); +} +inline float IntToFloat(int32_t v) { return static_cast(v); } + +inline uint32_t IntToUint(int32_t u) { + if (u < 0) { + MS_LOG(EXCEPTION) << "The int32_t value(" << u << ") is less than 0."; + } + return static_cast(u); +} + +inline int32_t UintToInt(uint32_t u) { + if (u > static_cast((std::numeric_limits::max)())) { + MS_LOG(EXCEPTION) << "The uint32_t value(" << u << ") exceeds the maximum value of int32_t."; + } + return static_cast(u); +} + +inline unsigned int UlongToUint(size_t u) { + if (u > static_cast((std::numeric_limits::max)())) { + MS_LOG(EXCEPTION) << "The size_t value(" << u << ") exceeds the maximum value of unsigned int."; + } + return static_cast(u); +} + +inline void IntMulWithOverflowCheck(int a, int b, int *c) { + int out = a * b; + if (a != 0) { + bool ok = ((out / a) != b); + if (ok) { + MS_LOG(EXCEPTION) << "Mul: a(" << a << ") * b(" << b << ") result is overflow"; + } + } + *c = out; +} + +inline uint8_t *AddressOffset(void *address, size_t offset) { + MS_EXCEPTION_IF_NULL(address); + return static_cast(address) + offset; +} +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_UTILS_CONVERT_UTILS_BASE_H_ diff --git a/mindspore/ccsrc/utils/graph_utils.cc b/mindspore/ccsrc/utils/graph_utils.cc index 60733642e7..e956498a3f 100644 --- a/mindspore/ccsrc/utils/graph_utils.cc +++ b/mindspore/ccsrc/utils/graph_utils.cc @@ -1,7 +1,7 @@ /** * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). * - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,153 +29,12 @@ #include #include -#include "ir/visitor.h" -#include "utils/log_adapter.h" #include "common/utils.h" -#include "pipeline/parse/function_block.h" -#include "pipeline/parse/python_adapter.h" +#include "debug/label.h" +#include "ir/func_graph.h" +#include "utils/log_adapter.h" namespace mindspore { -using SymbolicKeyTypePtr = std::shared_ptr; - -namespace { -class DeepFirstSearcher : public AnfVisitor { - public: - explicit DeepFirstSearcher(const IncludeFunc &include) : include_(include) {} - ~DeepFirstSearcher() override = default; - - std::vector Search(const AnfNodePtr &root) { - if (root == nullptr) { - return res_; - } - seen_ = NewSeenGeneration(); - Visit(root); - return res_; - } - - void Visit(const AnfNodePtr &node) override { - MS_EXCEPTION_IF_NULL(node); - if (node->seen_ == seen_) { - return; - } - - node->seen_ = seen_; - - auto incl = include_(node); - if (incl == EXCLUDE) { - return; - } - - res_.push_back(node); - if (incl == FOLLOW) { - AnfVisitor::Visit(node); - } - } - - private: - size_t seen_{0}; - IncludeFunc include_; - std::vector res_{}; -}; - -class DeepScopedGraphSearcher : public DeepFirstSearcher { - public: - explicit DeepScopedGraphSearcher(const IncludeFunc &include) : DeepFirstSearcher(include) {} - ~DeepScopedGraphSearcher() override = default; - - void Visit(const CNodePtr &cnode) override { - if (cnode->func_graph() == nullptr) { - return; - } - - AnfNodePtr ret = cnode->func_graph()->get_return(); - if (ret != nullptr) { - DeepFirstSearcher::Visit(ret); - } - - auto &inputs = cnode->inputs(); - for (auto iter = inputs.rbegin(); iter != inputs.rend(); ++iter) { - DeepFirstSearcher::Visit(*iter); - } - } - - void Visit(const ValueNodePtr &vnode) override { - if (!IsValueNode(vnode)) { - return; - } - - auto graph = GetValueNode(vnode); - AnfNodePtr ret = graph->get_return(); - if (ret != nullptr) { - DeepFirstSearcher::Visit(ret); - } - } - - void Visit(const ParameterPtr ¶m) override { - if (param->func_graph() == nullptr) { - return; - } - - AnfNodePtr ret = param->func_graph()->get_return(); - if (ret != nullptr) { - DeepFirstSearcher::Visit(ret); - } - } -}; - -class DeepUsedGraphSearcher : public DeepFirstSearcher { - public: - explicit DeepUsedGraphSearcher(const IncludeFunc &include) : DeepFirstSearcher(include) {} - ~DeepUsedGraphSearcher() override = default; - - void Visit(const CNodePtr &cnode) override { - auto &inputs = cnode->inputs(); - for (auto iter = inputs.rbegin(); iter != inputs.rend(); ++iter) { - DeepFirstSearcher::Visit(*iter); - } - } - - void Visit(const ValueNodePtr &vnode) override { - if (!IsValueNode(vnode)) { - return; - } - - auto graph = GetValueNode(vnode); - AnfNodePtr ret = graph->get_return(); - if (ret != nullptr) { - DeepFirstSearcher::Visit(ret); - } - } -}; - -class DeepLinkedGraphSearcher : public DeepFirstSearcher { - public: - explicit DeepLinkedGraphSearcher(const IncludeFunc &include) : DeepFirstSearcher(include) {} - ~DeepLinkedGraphSearcher() override = default; - - void Visit(const CNodePtr &cnode) override { - auto &inputs = cnode->inputs(); - for (auto iter = inputs.rbegin(); iter != inputs.rend(); ++iter) { - DeepFirstSearcher::Visit(*iter); - } - } - - void Visit(const ValueNodePtr &) override {} -}; -} // namespace - -std::vector DeepScopedGraphSearch(const AnfNodePtr &root, const IncludeFunc &include) { - return DeepScopedGraphSearcher(include).Search(root); -} - -std::vector DeepUsedGraphSearch(const AnfNodePtr &root, const IncludeFunc &include) { - return DeepUsedGraphSearcher(include).Search(root); -} - -std::vector DeepLinkedGraphSearch(const AnfNodePtr &root, const IncludeFunc &include) { - return DeepLinkedGraphSearcher(include).Search(root); -} - std::vector TopoSort(const AnfNodePtr &root, const SuccFunc &succ, const IncludeFunc &include) { size_t seen = NewSeenGeneration(); std::list todo(1, root); @@ -408,154 +267,4 @@ void FuncGraphIndex::Acquire(const AnfNodePtr &key) { (void)index_node_[name].insert(key); } } - -// Isomorphism -static bool SameNodeShallow(const AnfNodePtr &node1, const AnfNodePtr &node2, FuncGraphPairMapEquiv *equiv_func_graph, - NodeMapEquiv *const equiv_node) { - if (equiv_node == nullptr) { - MS_LOG(ERROR) << "Invalid equiv_node"; - return false; - } - if (equiv_node->count(node1) > 0 && (*equiv_node)[node1] == node2) { - return true; - } - if (IsValueNode(node1) && IsValueNode(node2)) { - return Isomorphic(GetValueNode(node1), GetValueNode(node2), equiv_func_graph, - equiv_node); - } - if (node1->isa() && node2->isa()) { - auto a1 = GetValueNode(node1); - auto a2 = GetValueNode(node2); - if (a1->isa() && a2->isa()) { - return a1->cast()->name() == a2->cast()->name(); - } else if (a1->isa() && a2->isa()) { - return a1->cast()->ValueEqual(*(a2->cast())); - } else { - return *a1 == *a2; - } - } - if (node1->isa() && node2->isa()) { - auto para1 = node1->cast(); - auto para2 = node2->cast(); - if (para1->name() == para2->name()) { - return true; - } - MS_LOG(DEBUG) << "two parameters are not equal."; - return false; - } - MS_LOG(ERROR) << "type error"; - return false; -} - -static bool SameNode(const AnfNodePtr &node1, const AnfNodePtr &node2, FuncGraphPairMapEquiv *equiv_func_graph, - NodeMapEquiv *const equiv_node) { - MS_EXCEPTION_IF_NULL(node1); - MS_EXCEPTION_IF_NULL(node2); - if (node1->isa() && node2->isa()) { - auto &inputs1 = node1->cast()->inputs(); - auto &inputs2 = node2->cast()->inputs(); - for (std::size_t i = 0; i < inputs1.size(); ++i) { - if (!SameNodeShallow(inputs1[i], inputs2[i], equiv_func_graph, equiv_node)) { - return false; - } - } - return true; - } - return SameNodeShallow(node1, node2, equiv_func_graph, equiv_node); -} - -static bool SameSubgraph(AnfNodePtr root1, AnfNodePtr root2, FuncGraphPairMapEquiv *equiv_func_graph, - NodeMapEquiv *const equiv_node) { - std::unordered_set done; - std::stack> todo; - - todo.push(std::make_pair(root1, root2)); - while (todo.size() > 0) { - AnfNodePtr node1 = todo.top().first; - if (done.count(node1) > 0) { - todo.pop(); - continue; - } - AnfNodePtr node2 = todo.top().second; - - bool condition = false; - std::vector s1 = SuccIncoming(node1); - std::vector s2 = SuccIncoming(node2); - - if (s1.size() != s2.size()) { - return false; - } - for (std::size_t i = 0; i < s1.size(); ++i) { - if (done.count(s1[i]) == 0) { - todo.push(std::make_pair(s1[i], s2[i])); - condition = true; - } - } - if (condition) { - continue; - } - (void)done.insert(node1); - - auto res = SameNode(node1, node2, equiv_func_graph, equiv_node); - if (res) { - (*equiv_node)[node1] = node2; - } else { - return false; - } - todo.pop(); - } - return true; -} - -bool Isomorphic(FuncGraphPtr fg1, FuncGraphPtr fg2, FuncGraphPairMapEquiv *equiv_func_graph, - NodeMapEquiv *const equiv_node) { - auto fg1_fg2 = std::make_pair(fg1, fg2); - if (equiv_func_graph == nullptr) { - MS_LOG(ERROR) << "equiv_func_graph not init"; - return false; - } - if (equiv_func_graph->find(fg1_fg2) != equiv_func_graph->end()) { - return (*equiv_func_graph)[fg1_fg2] != kNotEquiv; - } - if (fg1 == nullptr || fg2 == nullptr) { - MS_LOG(ERROR) << "Invalid function graph"; - return false; - } - if (fg1->parameters().size() != fg2->parameters().size()) { - MS_LOG(DEBUG) << "parameters size not match"; - return false; - } - if (equiv_node != nullptr) { - for (std::size_t i = 0; i < fg1->parameters().size(); ++i) { - (*equiv_node)[fg1->parameters()[i]] = fg2->parameters()[i]; - } - (*equiv_func_graph)[fg1_fg2] = kPending; - auto result = SameSubgraph(fg1->get_return(), fg2->get_return(), equiv_func_graph, equiv_node); - (*equiv_func_graph)[fg1_fg2] = EquivState(result); - return result; - } - - MS_LOG(ERROR) << "equiv_node not init"; - return false; -} - -tensor::TensorPtr ScalarToTensor(const ScalarPtr &scalar) { - if (scalar == nullptr) { - MS_EXCEPTION(ArgumentError) << "Nullptr Error!"; - } - tensor::TensorPtr tensor = nullptr; - if (scalar->isa()) { - tensor = std::make_shared(py::float_(GetValue(scalar)), kFloat32); - } else if (scalar->isa()) { - tensor = std::make_shared(py::int_(GetValue(scalar)), kInt32); - } else if (scalar->isa()) { - tensor = std::make_shared(py::array(py::bool_(GetValue(scalar))), kBool); - } else { - auto type = scalar->type(); - auto type_str = (type == nullptr) ? "nullptr" : type->ToString(); - MS_LOG(EXCEPTION) << "Invalid scalar type: " << type_str; - } - MS_EXCEPTION_IF_NULL(tensor); - return tensor; -} } // namespace mindspore diff --git a/mindspore/ccsrc/utils/graph_utils.h b/mindspore/ccsrc/utils/graph_utils.h index cbe766af81..0b49615523 100644 --- a/mindspore/ccsrc/utils/graph_utils.h +++ b/mindspore/ccsrc/utils/graph_utils.h @@ -29,7 +29,7 @@ #include #include "ir/anf.h" -#include "ir/primitive.h" +#include "ir/primitive_base.h" #include "ir/scalar.h" #include "ir/tensor.h" #include "debug/label.h" @@ -42,6 +42,10 @@ using IncludeFunc = std::function; using SuccFunc = std::function(AnfNodePtr)>; using SearchFunc = std::function(const AnfNodePtr &, const IncludeFunc &)>; +std::vector DeepScopedGraphSearch(const AnfNodePtr &root, const IncludeFunc &include); +std::vector DeepUsedGraphSearch(const AnfNodePtr &root, const IncludeFunc &include); +std::vector DeepLinkedGraphSearch(const AnfNodePtr &root, const IncludeFunc &include); + std::vector SuccDeeper(const AnfNodePtr &node); std::vector SuccDeeperSimple(const AnfNodePtr &node); std::vector SuccIncoming(const AnfNodePtr &node); @@ -79,26 +83,6 @@ class FuncGraphIndex { std::map> index_func_graph_; std::map> index_node_; }; - -// Isomorphism - -struct PairHasher { - template - std::size_t operator()(const std::pair &p) const { - auto h1 = std::hash{}(p.first); - auto h2 = std::hash{}(p.second); - return h1 ^ h2; - } -}; - -enum EquivState { kNotEquiv = 0, kEquiv = 1, kPending = 2 }; - -using FuncGraphPairMapEquiv = std::unordered_map, EquivState, PairHasher>; -using NodeMapEquiv = std::unordered_map; - -bool Isomorphic(FuncGraphPtr g1, FuncGraphPtr g2, FuncGraphPairMapEquiv *equiv_func_graph, NodeMapEquiv *equiv_node); - -tensor::TensorPtr ScalarToTensor(const ScalarPtr &scalar); } // namespace mindspore #endif // MINDSPORE_CCSRC_UTILS_GRAPH_UTILS_H_ diff --git a/mindspore/ccsrc/utils/graph_utils_extends.cc b/mindspore/ccsrc/utils/graph_utils_extends.cc new file mode 100644 index 0000000000..7c3991b638 --- /dev/null +++ b/mindspore/ccsrc/utils/graph_utils_extends.cc @@ -0,0 +1,174 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils/graph_utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ir/visitor.h" +#include "ir/func_graph.h" +#include "debug/label.h" +#include "utils/log_adapter.h" +#include "common/utils.h" +#include "pipeline/parse/function_block.h" +#include "pipeline/parse/python_adapter.h" + +namespace mindspore { +namespace { +class DeepFirstSearcher : public AnfVisitor { + public: + explicit DeepFirstSearcher(const IncludeFunc &include) : include_(include) {} + ~DeepFirstSearcher() override = default; + + std::vector Search(const AnfNodePtr &root) { + if (root == nullptr) { + return res_; + } + seen_ = NewSeenGeneration(); + Visit(root); + return res_; + } + + void Visit(const AnfNodePtr &node) override { + MS_EXCEPTION_IF_NULL(node); + if (node->seen_ == seen_) { + return; + } + + node->seen_ = seen_; + + auto incl = include_(node); + if (incl == EXCLUDE) { + return; + } + + res_.push_back(node); + if (incl == FOLLOW) { + AnfVisitor::Visit(node); + } + } + + private: + size_t seen_{0}; + IncludeFunc include_; + std::vector res_{}; +}; + +class DeepScopedGraphSearcher : public DeepFirstSearcher { + public: + explicit DeepScopedGraphSearcher(const IncludeFunc &include) : DeepFirstSearcher(include) {} + ~DeepScopedGraphSearcher() override = default; + + void Visit(const CNodePtr &cnode) override { + if (cnode->func_graph() == nullptr) { + return; + } + + AnfNodePtr ret = cnode->func_graph()->get_return(); + if (ret != nullptr) { + DeepFirstSearcher::Visit(ret); + } + + auto &inputs = cnode->inputs(); + for (auto iter = inputs.rbegin(); iter != inputs.rend(); ++iter) { + DeepFirstSearcher::Visit(*iter); + } + } + + void Visit(const ValueNodePtr &vnode) override { + if (!IsValueNode(vnode)) { + return; + } + + auto graph = GetValueNode(vnode); + AnfNodePtr ret = graph->get_return(); + if (ret != nullptr) { + DeepFirstSearcher::Visit(ret); + } + } + + void Visit(const ParameterPtr ¶m) override { + if (param->func_graph() == nullptr) { + return; + } + + AnfNodePtr ret = param->func_graph()->get_return(); + if (ret != nullptr) { + DeepFirstSearcher::Visit(ret); + } + } +}; + +class DeepUsedGraphSearcher : public DeepFirstSearcher { + public: + explicit DeepUsedGraphSearcher(const IncludeFunc &include) : DeepFirstSearcher(include) {} + ~DeepUsedGraphSearcher() override = default; + + void Visit(const CNodePtr &cnode) override { + auto &inputs = cnode->inputs(); + for (auto iter = inputs.rbegin(); iter != inputs.rend(); ++iter) { + DeepFirstSearcher::Visit(*iter); + } + } + + void Visit(const ValueNodePtr &vnode) override { + if (!IsValueNode(vnode)) { + return; + } + + auto graph = GetValueNode(vnode); + AnfNodePtr ret = graph->get_return(); + if (ret != nullptr) { + DeepFirstSearcher::Visit(ret); + } + } +}; + +class DeepLinkedGraphSearcher : public DeepFirstSearcher { + public: + explicit DeepLinkedGraphSearcher(const IncludeFunc &include) : DeepFirstSearcher(include) {} + ~DeepLinkedGraphSearcher() override = default; + + void Visit(const CNodePtr &cnode) override { + auto &inputs = cnode->inputs(); + for (auto iter = inputs.rbegin(); iter != inputs.rend(); ++iter) { + DeepFirstSearcher::Visit(*iter); + } + } + + void Visit(const ValueNodePtr &) override {} +}; +} // namespace + +std::vector DeepScopedGraphSearch(const AnfNodePtr &root, const IncludeFunc &include) { + return DeepScopedGraphSearcher(include).Search(root); +} + +std::vector DeepUsedGraphSearch(const AnfNodePtr &root, const IncludeFunc &include) { + return DeepUsedGraphSearcher(include).Search(root); +} + +std::vector DeepLinkedGraphSearch(const AnfNodePtr &root, const IncludeFunc &include) { + return DeepLinkedGraphSearcher(include).Search(root); +} +} // namespace mindspore diff --git a/mindspore/ccsrc/vm/backend.cc b/mindspore/ccsrc/vm/backend.cc index b447bb8225..0fac84d901 100644 --- a/mindspore/ccsrc/vm/backend.cc +++ b/mindspore/ccsrc/vm/backend.cc @@ -1,5 +1,5 @@ /** - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ #include "ir/anf.h" #include "utils/callbacks.h" #include "utils/graph_utils.h" +#include "utils/base_ref_extends.h" #include "session/session_factory.h" #include "common/utils.h" #ifdef ENABLE_GE diff --git a/mindspore/ccsrc/vm/vm.cc b/mindspore/ccsrc/vm/vm.cc index 2df475c39d..6aa3b6018a 100644 --- a/mindspore/ccsrc/vm/vm.cc +++ b/mindspore/ccsrc/vm/vm.cc @@ -1,7 +1,7 @@ /** * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). * - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ #include "vm/backend.h" #include "vm/transform.h" #include "pipeline/parse/data_converter.h" +#include "utils/base_ref_extends.h" namespace mindspore { namespace compile { diff --git a/mindspore/ccsrc/vm/vm.h b/mindspore/ccsrc/vm/vm.h index c72737a1db..4579b1bc97 100644 --- a/mindspore/ccsrc/vm/vm.h +++ b/mindspore/ccsrc/vm/vm.h @@ -1,7 +1,7 @@ /** * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). * - * Copyright 2019 Huawei Technologies Co., Ltd + * Copyright 2019-2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ #include #include "ir/anf.h" -#include "utils/base_ref.h" +#include "utils/base_ref_extends.h" namespace mindspore { namespace compile { diff --git a/mindspore/ccsrc/vm/vmimpl.h b/mindspore/ccsrc/vm/vmimpl.h index 12d2b2551b..2cc94bc062 100644 --- a/mindspore/ccsrc/vm/vmimpl.h +++ b/mindspore/ccsrc/vm/vmimpl.h @@ -24,10 +24,10 @@ #include #include +#include "utils/base_ref_extends.h" #include "ir/anf.h" #include "ir/manager.h" #include "ir/tensor.h" -#include "utils/base_ref.h" namespace mindspore { namespace compile {