| @@ -42,11 +42,13 @@ else() | |||
| include(${CMAKE_SOURCE_DIR}/cmake/dependency_graphengine.cmake) | |||
| endif() | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/graphengine/inc) | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/graphengine/inc/external) | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/graphengine/inc/framework) | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/graphengine/third_party/fwkacllib/inc) | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/graphengine/third_party/fwkacllib/inc/toolchain) | |||
| if (ENABLE_GE OR ENABLE_D OR ENABLE_TESTCASES) | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/graphengine/inc) | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/graphengine/inc/external) | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/graphengine/inc/framework) | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/graphengine/third_party/fwkacllib/inc) | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/graphengine/third_party/fwkacllib/inc/toolchain) | |||
| endif() | |||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") | |||
| add_subdirectory(mindspore/ccsrc) | |||
| @@ -40,7 +40,7 @@ if (ENABLE_GE) | |||
| include_directories(${CMAKE_SOURCE_DIR}/third_party/ge/include) | |||
| include_directories(${CMAKE_SOURCE_DIR}/third_party/ge/include/external) | |||
| include_directories(${CMAKE_SOURCE_DIR}/third_party/ge/include/external/graph) | |||
| else() | |||
| elseif(ENABLE_D OR ENABLE_TESTCASES) | |||
| include_directories(${CMAKE_SOURCE_DIR}/graphengine/inc) | |||
| include_directories(${CMAKE_SOURCE_DIR}/graphengine/inc/ops) | |||
| include_directories(${CMAKE_SOURCE_DIR}/graphengine/inc/external) | |||
| @@ -34,6 +34,8 @@ if(ENABLE_GPU) | |||
| "device/gpu/*.cu" | |||
| "kernel/gpu/*.cu" | |||
| "kernel/akg/gpu/*.cc" | |||
| "kernel/akg/akgkernelbuild.cc" | |||
| "kernel/akg/akg_kernel_attrs_process.cc" | |||
| ) | |||
| file(GLOB_RECURSE GPU_KERNEL_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} | |||
| "kernel/gpu/*.cc" | |||
| @@ -100,14 +102,14 @@ file(GLOB_RECURSE MINDSPORE_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} | |||
| "debug/*.cc" | |||
| "onnx/onnx_exporter.cc" | |||
| "operator/*.cc" | |||
| "transform/*.cc" | |||
| "session/kernel_graph.cc" | |||
| "utils/node_utils.cc" | |||
| "session/session_basic.cc" | |||
| "session/session_factory.cc" | |||
| "session/anf_runtime_algorithm.cc" | |||
| "vm/*.cc" | |||
| "pynative/*.cc" | |||
| "pynative/base.cc" | |||
| "pynative/pynative_execute.cc" | |||
| "pybind_api/*.cc" | |||
| "device/common/*.cc" | |||
| "kernel/kernel_query.cc" | |||
| @@ -117,7 +119,6 @@ file(GLOB_RECURSE MINDSPORE_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} | |||
| "device/kernel_runtime.cc" | |||
| "device/kernel_runtime_manager.cc" | |||
| "device/convert_tensor_utils.cc" | |||
| "pre_activate/ascend/*.cc" | |||
| "pre_activate/common/*.cc" | |||
| "pre_activate/pass/*.cc" | |||
| "pre_activate/gpu/*.cc" | |||
| @@ -168,6 +169,15 @@ if(ENABLE_DUMP_PROTO) | |||
| add_compile_definitions(ENABLE_DUMP_PROTO) | |||
| endif() | |||
| if(ENABLE_GE) | |||
| file(GLOB_RECURSE GE_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} | |||
| "transform/*.cc" | |||
| "pynative/pynative_execute_ge.cc" | |||
| "pipeline/pipeline_ge.cc" | |||
| ) | |||
| list(APPEND MINDSPORE_SRC_LIST ${GE_SRC_LIST}) | |||
| endif() | |||
| if(ENABLE_D) | |||
| include_directories("${CMAKE_BINARY_DIR}/kernel/aicpu") | |||
| file(GLOB_RECURSE PROTO_IN RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} | |||
| @@ -188,6 +198,9 @@ if(ENABLE_D) | |||
| "device/kernel_adjust.cc" | |||
| "kernel/kernel_fusion.cc" | |||
| "kernel/tbe/*.cc" | |||
| "pre_activate/ascend/*.cc" | |||
| "transform/*.cc" | |||
| "pipeline/pipeline_ge.cc" | |||
| ) | |||
| list(APPEND MINDSPORE_SRC_LIST ${D_SRC_LIST}) | |||
| list(APPEND MINDSPORE_PROTO_AICPU_LIST ${PROTOSRCS}) | |||
| @@ -246,9 +259,11 @@ if (ENABLE_GE) | |||
| target_link_libraries(mindspore graph ge_client) | |||
| endif() | |||
| target_link_libraries(mindspore tsdclient) | |||
| else() | |||
| elseif(ENABLE_D) | |||
| add_compile_definitions(NO_GE_CLIENT) | |||
| target_link_libraries(mindspore graph) | |||
| else() | |||
| add_compile_definitions(NO_GE_CLIENT) | |||
| endif() | |||
| if(ENABLE_D) | |||
| @@ -288,8 +303,6 @@ endif() | |||
| set(PYTHON_MODULE_SOURCE | |||
| pipeline/init.cc | |||
| kernel/oplib/oplib.cc | |||
| kernel/akg/akgkernelbuild.cc | |||
| kernel/akg/akg_kernel_attrs_process.cc | |||
| ${MS_STEPS_SRC_LIST} ${MS_CCE_SRC_LIST} ${MS_AICPU_SRC_LIST} ${MS_TASKINFO_LIST} ${MS_RT_SRC_LIST} | |||
| ${GPU_NCCL_LIST} ${MS_HCCL_SRC_LIST} ${MS_PREDICT_SRC_LIST} ${CPU_SRC_LIST} ${MEM_REUSE_SRC_LIST} ${GPU_KERNEL_SRC_LIST}) | |||
| @@ -350,6 +363,7 @@ if(ENABLE_GPU) | |||
| assign_source_group("Include" ${GROUP_INCLUDE}) | |||
| file(GLOB COMPILER_SRCS | |||
| "pre_activate/gpu/*.cc" | |||
| ${TVM_DIR}/src/api/*.cc | |||
| ${TVM_DIR}/src/arithmetic/*.cc | |||
| ${TVM_DIR}/src/autotvm/*.cc | |||
| @@ -49,7 +49,7 @@ bool Dump::IsKernelNeedDump(const std::string& kernel_name) { | |||
| return false; | |||
| } | |||
| bool Dump::ParseDumpConfig(const string& dump_config_file) { | |||
| bool Dump::ParseDumpConfig(const std::string& dump_config_file) { | |||
| std::ifstream jsonFile(dump_config_file); | |||
| if (!jsonFile.is_open()) { | |||
| MS_LOG(ERROR) << dump_config_file << " open failed."; | |||
| @@ -94,7 +94,7 @@ static bool KernelBuildParallelCompile(const mindspore::session::KernelGraph *ke | |||
| return ret; | |||
| } | |||
| static vector<int> CalCleanZerosSize(const CNodePtr &pre_node) { | |||
| static std::vector<int> CalCleanZerosSize(const CNodePtr &pre_node) { | |||
| MS_EXCEPTION_IF_NULL(pre_node); | |||
| std::vector<int> clean_size_list; | |||
| // clean output | |||
| @@ -27,6 +27,7 @@ | |||
| #include "utils/log_adapter.h" | |||
| #include "utils/context/ms_context.h" | |||
| #include "common/utils.h" | |||
| #include "utils/convert_utils.h" | |||
| using std::vector; | |||
| using Json = nlohmann::json; | |||
| @@ -121,8 +121,8 @@ bool TaskGenerator::LaunchKernel(const CNodePtr &anf_node_ptr, uint32_t stream_i | |||
| LaunchAddrCleanKernel(anf_node_ptr, &kernel_inputs); | |||
| } | |||
| std::vector<TaskInfoPtr> task_info_ptrs = | |||
| kernel_mod->GenTask(kernel_inputs, kernel_workspaces, kernel_outputs, stream_id); | |||
| std::vector<TaskInfoPtr> task_info_ptrs = dynamic_cast<kernel::AscendKernelMod *>(kernel_mod) | |||
| ->GenTask(kernel_inputs, kernel_workspaces, kernel_outputs, stream_id); | |||
| task_info_list->insert(task_info_list->end(), task_info_ptrs.begin(), task_info_ptrs.end()); | |||
| return true; | |||
| } | |||
| @@ -24,7 +24,7 @@ | |||
| #include <vector> | |||
| #include "device/kernel_runtime.h" | |||
| #include "ir/anf.h" | |||
| #include "kernel/kernel.h" | |||
| #include "kernel/ascend_kernel_mod.h" | |||
| #include "framework/ge_runtime/task_info.h" | |||
| namespace mindspore { | |||
| @@ -21,7 +21,6 @@ | |||
| #include "kernel/gpu/gpu_kernel_factory.h" | |||
| #include "operator/ops.h" | |||
| #include "pybind11/stl.h" | |||
| #include "transform/convert.h" | |||
| #include "session/anf_runtime_algorithm.h" | |||
| namespace mindspore { | |||
| namespace device { | |||
| @@ -91,7 +91,7 @@ std::string SupportedTypeList(const CNodePtr& kernel_node) { | |||
| return supported_type_lists; | |||
| } | |||
| bool SelectAkgKernel(const CNodePtr& kernel_node, const shared_ptr<KernelBuildInfo>& selected_kernel_info) { | |||
| bool SelectAkgKernel(const CNodePtr& kernel_node, const std::shared_ptr<KernelBuildInfo>& selected_kernel_info) { | |||
| MS_EXCEPTION_IF_NULL(kernel_node); | |||
| MS_EXCEPTION_IF_NULL(selected_kernel_info); | |||
| std::vector<std::shared_ptr<KernelBuildInfo>> kernel_info_list; | |||
| @@ -32,6 +32,7 @@ | |||
| #include "device/ascend/profiling/profiling_manager.h" | |||
| #include "device/ascend/kernel_select_ascend.h" | |||
| #include "device/kernel_info.h" | |||
| #include "runtime/base.h" | |||
| constexpr auto kLoopCountParamName = "loop_count"; | |||
| constexpr auto kIterLoopParamName = "iter_loop"; | |||
| @@ -197,6 +197,23 @@ PrimitivePtr GetCNodePrimitive(const AnfNodePtr& node) { | |||
| return nullptr; | |||
| } | |||
| std::string GetCNodeFuncName(const CNodePtr cnode) { | |||
| if (cnode->inputs().empty()) { | |||
| return ""; | |||
| } | |||
| AnfNodePtr valuenode = cnode->input(0); | |||
| if (valuenode->isa<ValueNode>()) { | |||
| auto value = GetValueNode(valuenode); | |||
| // check whether the valuenode is primitive | |||
| if (value->isa<Primitive>()) { | |||
| return value->cast<PrimitivePtr>()->name(); | |||
| } | |||
| return value->ToString(); | |||
| } | |||
| return ""; | |||
| } | |||
| bool IsPrimitive(const AnfNodePtr& node, const PrimitivePtr& value) { | |||
| if (IsValueNode<Primitive>(node)) { | |||
| PrimitivePtr fn_value = GetValueNode<PrimitivePtr>(node); | |||
| @@ -384,6 +384,8 @@ static S GetValue(const ValuePtr &value) { | |||
| return v; | |||
| } | |||
| std::string GetCNodeFuncName(CNodePtr cnode); | |||
| // used to check whether an AnfNode is a cnode with a kind of Primitive as first input | |||
| bool IsPrimitiveCNode(const AnfNodePtr &node, const PrimitivePtr &value); | |||
| @@ -25,7 +25,6 @@ | |||
| #include "device/device_address.h" | |||
| #include "pybind_api/api_register.h" | |||
| #include "pybind_api/export_flags.h" | |||
| #include "pynative/pynative_execute.h" | |||
| #include "pipeline/static_analysis/abstract_value.h" | |||
| namespace mindspore { | |||
| @@ -18,11 +18,11 @@ | |||
| #include <vector> | |||
| #include <memory> | |||
| #include <string> | |||
| #include "kernel/kernel.h" | |||
| #include "kernel/ascend_kernel_mod.h" | |||
| #include "kernel/aicpu/aicpu_util.h" | |||
| namespace mindspore { | |||
| namespace kernel { | |||
| class AicpuOpKernelMod : public KernelMod { | |||
| class AicpuOpKernelMod : public AscendKernelMod { | |||
| public: | |||
| AicpuOpKernelMod(); | |||
| ~AicpuOpKernelMod() override; | |||
| @@ -35,7 +35,6 @@ | |||
| #include "utils/convert_utils.h" | |||
| #include "utils/any.h" | |||
| #include "utils/utils.h" | |||
| #include "transform/convert.h" | |||
| #include "session/anf_runtime_algorithm.h" | |||
| #include "kernel/akg/akg_kernel_attrs_process.h" | |||
| @@ -240,8 +239,8 @@ bool AkgKernelBuild::CreateOutputDescJson(const AnfNodePtr &anf_node, nlohmann:: | |||
| return true; | |||
| } | |||
| void GetJson(const AnfNodePtr &anf_node, const vector<int> &dyn_input_sizes, const shared_ptr<OpAttr> &op_attr, | |||
| nlohmann::json *const attr_json, const ValuePtr &attr_value) { | |||
| void GetJson(const AnfNodePtr &anf_node, const std::vector<int> &dyn_input_sizes, | |||
| const std::shared_ptr<OpAttr> &op_attr, nlohmann::json *const attr_json, const ValuePtr &attr_value) { | |||
| MS_EXCEPTION_IF_NULL(anf_node); | |||
| MS_EXCEPTION_IF_NULL(op_attr); | |||
| MS_EXCEPTION_IF_NULL(attr_json); | |||
| @@ -0,0 +1,36 @@ | |||
| /** | |||
| * Copyright 2019 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_KERNEL_ASCEND_KERNEL_MOD_H_ | |||
| #define MINDSPORE_CCSRC_KERNEL_ASCEND_KERNEL_MOD_H_ | |||
| #include <vector> | |||
| #include <memory> | |||
| #include "framework/ge_runtime/task_info.h" | |||
| #include "kernel/kernel.h" | |||
| using TaskInfoPtr = std::shared_ptr<ge::model_runner::TaskInfo>; | |||
| namespace mindspore { | |||
| namespace kernel { | |||
| class AscendKernelMod : public KernelMod { | |||
| public: | |||
| virtual std::vector<TaskInfoPtr> GenTask(const std::vector<AddressPtr> &, const std::vector<AddressPtr> &, | |||
| const std::vector<AddressPtr> &, uint32_t) = 0; | |||
| }; | |||
| } // namespace kernel | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_KERNEL_ASCEND_KERNEL_MOD_H_ | |||
| @@ -19,7 +19,6 @@ | |||
| #include <map> | |||
| #include <iostream> | |||
| #include <fstream> | |||
| #include "runtime/rt.h" | |||
| #include "nlohmann/json.hpp" | |||
| #include "session/anf_runtime_algorithm.h" | |||
| #include "common/utils.h" | |||
| @@ -490,7 +489,7 @@ void SaveJsonInfo(const std::string &json_name, const std::string &info) { | |||
| if (!filewrite.is_open()) { | |||
| return; | |||
| } | |||
| filewrite << info << endl; | |||
| filewrite << info << std::endl; | |||
| filewrite.close(); | |||
| if (nullptr == realpath(path.c_str(), real_path)) { | |||
| MS_LOG(DEBUG) << "dir " << path << " does not exit."; | |||
| @@ -226,12 +226,12 @@ class LstmGpuKernel : public GpuKernel { | |||
| size_t reserved_size_; | |||
| // input desc | |||
| unique_ptr<cudnnTensorDescriptor_t[]> x_desc_; | |||
| std::unique_ptr<cudnnTensorDescriptor_t[]> x_desc_; | |||
| cudnnTensorDescriptor_t hx_desc_; | |||
| cudnnTensorDescriptor_t cx_desc_; | |||
| cudnnFilterDescriptor_t w_desc_; | |||
| cudnnDropoutDescriptor_t dropout_desc_; | |||
| unique_ptr<cudnnTensorDescriptor_t[]> y_desc_; | |||
| std::unique_ptr<cudnnTensorDescriptor_t[]> y_desc_; | |||
| cudnnTensorDescriptor_t hy_desc_; | |||
| cudnnTensorDescriptor_t cy_desc_; | |||
| cudnnRNNDescriptor_t rnn_desc_; | |||
| @@ -258,8 +258,8 @@ class LstmGradDataGpuKernel : public GpuKernel { | |||
| cudnnRNNDescriptor_t rnn_desc_; | |||
| // input desc | |||
| unique_ptr<cudnnTensorDescriptor_t[]> y_desc_; | |||
| unique_ptr<cudnnTensorDescriptor_t[]> dy_desc_; | |||
| std::unique_ptr<cudnnTensorDescriptor_t[]> y_desc_; | |||
| std::unique_ptr<cudnnTensorDescriptor_t[]> dy_desc_; | |||
| cudnnTensorDescriptor_t dhy_desc_; | |||
| cudnnTensorDescriptor_t dcy_desc_; | |||
| cudnnFilterDescriptor_t w_desc_; | |||
| @@ -269,7 +269,7 @@ class LstmGradDataGpuKernel : public GpuKernel { | |||
| cudnnDropoutDescriptor_t dropout_desc_; | |||
| // output desc | |||
| unique_ptr<cudnnTensorDescriptor_t[]> dx_desc_; | |||
| std::unique_ptr<cudnnTensorDescriptor_t[]> dx_desc_; | |||
| cudnnTensorDescriptor_t dhx_desc_; | |||
| cudnnTensorDescriptor_t dcx_desc_; | |||
| @@ -214,9 +214,9 @@ class LstmGradWeightGpuKernel : public GpuKernel { | |||
| cudnnDropoutDescriptor_t dropout_desc_; | |||
| // input desc | |||
| unique_ptr<cudnnTensorDescriptor_t[]> x_desc_; | |||
| std::unique_ptr<cudnnTensorDescriptor_t[]> x_desc_; | |||
| cudnnTensorDescriptor_t hx_desc_; | |||
| unique_ptr<cudnnTensorDescriptor_t[]> y_desc_; | |||
| std::unique_ptr<cudnnTensorDescriptor_t[]> y_desc_; | |||
| // output desc | |||
| cudnnFilterDescriptor_t dw_desc_; | |||
| @@ -23,14 +23,14 @@ | |||
| #include <vector> | |||
| #include <algorithm> | |||
| #include <utility> | |||
| #include "kernel/kernel.h" | |||
| #include "kernel/ascend_kernel_mod.h" | |||
| #include "kernel/hccl/hcom_util.h" | |||
| #include "hccl/hcom.h" | |||
| #include "common/utils.h" | |||
| namespace mindspore { | |||
| namespace kernel { | |||
| class HcclKernel : public KernelMod { | |||
| class HcclKernel : public AscendKernelMod { | |||
| public: | |||
| HcclKernel(); | |||
| ~HcclKernel() override; | |||
| @@ -25,7 +25,6 @@ | |||
| #include "ir/meta_tensor.h" | |||
| #include "pipeline/static_analysis/dshape.h" | |||
| #include "utils/log_adapter.h" | |||
| #include "framework/ge_runtime/task_info.h" | |||
| namespace mindspore { | |||
| enum KernelType : int { UNKNOWN_KERNEL_TYPE = 0, AUTO_DIFF_KERNEL, AICPU_KERNEL, RT_KERNEL, HCCL_KERNEL, TBE_KERNEL }; | |||
| @@ -111,7 +110,6 @@ struct Address { | |||
| size_t size; | |||
| }; | |||
| using AddressPtr = std::shared_ptr<Address>; | |||
| using TaskInfoPtr = std::shared_ptr<ge::model_runner::TaskInfo>; | |||
| class KernelMod { | |||
| public: | |||
| @@ -120,10 +118,6 @@ class KernelMod { | |||
| virtual const std::vector<size_t> &GetWorkspaceSizeList() const = 0; | |||
| virtual bool Launch(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace, | |||
| const std::vector<AddressPtr> &outputs, uintptr_t stream_ptr) = 0; | |||
| virtual std::vector<TaskInfoPtr> GenTask(const std::vector<AddressPtr> &, const std::vector<AddressPtr> &, | |||
| const std::vector<AddressPtr> &, uint32_t) { | |||
| return {}; | |||
| } | |||
| virtual std::vector<size_t> GenParameters() { return {}; } | |||
| virtual ~KernelMod() = default; | |||
| @@ -22,12 +22,12 @@ | |||
| #include <memory> | |||
| #include <map> | |||
| #include <string> | |||
| #include "kernel/kernel.h" | |||
| #include "kernel/ascend_kernel_mod.h" | |||
| #include "kernel/task_stream.h" | |||
| namespace mindspore { | |||
| namespace kernel { | |||
| class RtKernel : public KernelMod { | |||
| class RtKernel : public AscendKernelMod { | |||
| public: | |||
| RtKernel(); | |||
| ~RtKernel() override; | |||
| @@ -19,7 +19,7 @@ | |||
| #include <unordered_map> | |||
| #include <memory> | |||
| #include "utils/log_adapter.h" | |||
| #include "kernel/oplib/opinfo.h" | |||
| #include "utils/overload.h" | |||
| #include "utils/context/ms_context.h" | |||
| namespace mindspore { | |||
| @@ -50,7 +50,7 @@ constexpr auto kNeedCompile = "need_compile"; | |||
| constexpr auto kShape = "shape"; | |||
| std::vector<std::shared_ptr<OpInfo>> OpLib::op_info_; | |||
| string ImplTypeToStr(OpImplyType impl_type) { | |||
| std::string ImplTypeToStr(OpImplyType impl_type) { | |||
| switch (impl_type) { | |||
| case kTBE: | |||
| return kTbe; | |||
| @@ -48,7 +48,7 @@ class TbeKernelBuild { | |||
| private: | |||
| TbeKernelBuild() = default; | |||
| ~TbeKernelBuild() = default; | |||
| static bool GenFusionDataInputJson(const shared_ptr<mindspore::AnfNode> &data_input, nlohmann::json *data_str, | |||
| static bool GenFusionDataInputJson(const std::shared_ptr<mindspore::AnfNode> &data_input, nlohmann::json *data_str, | |||
| size_t *index); | |||
| static bool GenFusionComputeJson(const mindspore::AnfNodePtr &compute_node, | |||
| std::vector<std::vector<mindspore::AnfNodePtr>>::iterator *layer_iter, | |||
| @@ -56,12 +56,13 @@ class TbeKernelBuild { | |||
| static bool GenFusionComputeInputeJson(const mindspore::CNodePtr &cnode, | |||
| std::vector<std::vector<mindspore::AnfNodePtr>>::iterator *layer_iter, | |||
| std::vector<nlohmann::json> *input_desc_list, size_t *index); | |||
| static void GenDescJson(const shared_ptr<mindspore::AnfNode> &anf_node, size_t out_idx, nlohmann::json *output_desc); | |||
| static void GenReusedOutputDesc(const shared_ptr<mindspore::AnfNode> &anf_node, size_t index, size_t output_index, | |||
| nlohmann::json *output_desc); | |||
| static void GenDescJson(const std::shared_ptr<mindspore::AnfNode> &anf_node, size_t out_idx, | |||
| nlohmann::json *output_desc); | |||
| static void GenReusedOutputDesc(const std::shared_ptr<mindspore::AnfNode> &anf_node, size_t index, | |||
| size_t output_index, nlohmann::json *output_desc); | |||
| static size_t GetIOSizeImpl(const nlohmann::json &desc); | |||
| static bool GetInputLayers(const vector<mindspore::AnfNodePtr> &input_nodes, | |||
| const vector<mindspore::AnfNodePtr> &compute_nodes, | |||
| static bool GetInputLayers(const std::vector<mindspore::AnfNodePtr> &input_nodes, | |||
| const std::vector<mindspore::AnfNodePtr> &compute_nodes, | |||
| std::vector<std::vector<mindspore::AnfNodePtr>> *input_layers); | |||
| static bool IsDynamicInput(const CNodePtr &cnode); | |||
| static size_t GetOptionalInput(const CNodePtr &cnode, bool is_dynamic_input); | |||
| @@ -82,15 +83,17 @@ class TbeKernelJsonCreator { | |||
| bool GenTbeAttrJson(const std::shared_ptr<AnfNode> &anf_node, const std::shared_ptr<OpInfo> &op_info, | |||
| nlohmann::json *attrs_json); | |||
| void ParseAttrValue(const std::string &type, const ValuePtr &value, nlohmann::json *attr_obj); | |||
| bool GenInputDescJson(const shared_ptr<AnfNode> &anf_node, size_t real_input_index, bool value, | |||
| const shared_ptr<OpIOInfo> &input_ptr, const string &op_input_name, size_t input_i, | |||
| vector<nlohmann::json> *input_list); | |||
| bool GenOutputDescJson(const shared_ptr<AnfNode> &anf_node, const vector<std::shared_ptr<OpIOInfo>> &outputs_ptr, | |||
| nlohmann::json *outputs_json); | |||
| bool GenInputList(const shared_ptr<AnfNode> &anf_node, size_t input_tensor_num, const shared_ptr<OpIOInfo> &input_ptr, | |||
| size_t *real_input_index, string *op_input_name, vector<nlohmann::json> *input_list); | |||
| void GenOutputList(const shared_ptr<AnfNode> &anf_node, const size_t &output_obj_num, | |||
| const shared_ptr<OpIOInfo> &output_ptr, size_t *output_idx, vector<nlohmann::json> *output_list); | |||
| bool GenInputDescJson(const std::shared_ptr<AnfNode> &anf_node, size_t real_input_index, bool value, | |||
| const std::shared_ptr<OpIOInfo> &input_ptr, const string &op_input_name, size_t input_i, | |||
| std::vector<nlohmann::json> *input_list); | |||
| bool GenOutputDescJson(const std::shared_ptr<AnfNode> &anf_node, | |||
| const std::vector<std::shared_ptr<OpIOInfo>> &outputs_ptr, nlohmann::json *outputs_json); | |||
| bool GenInputList(const std::shared_ptr<AnfNode> &anf_node, size_t input_tensor_num, | |||
| const std::shared_ptr<OpIOInfo> &input_ptr, size_t *real_input_index, string *op_input_name, | |||
| std::vector<nlohmann::json> *input_list); | |||
| void GenOutputList(const std::shared_ptr<AnfNode> &anf_node, const size_t &output_obj_num, | |||
| const std::shared_ptr<OpIOInfo> &output_ptr, size_t *output_idx, | |||
| std::vector<nlohmann::json> *output_list); | |||
| kCreaterType creater_type_; | |||
| std::string json_name_; | |||
| std::string json_info_; | |||
| @@ -21,12 +21,12 @@ | |||
| #include <string> | |||
| #include <vector> | |||
| #include <utility> | |||
| #include "kernel/kernel.h" | |||
| #include "kernel/ascend_kernel_mod.h" | |||
| #include "kernel/tbe/tbe_utils.h" | |||
| namespace mindspore { | |||
| namespace kernel { | |||
| class TbeKernelMod : public KernelMod { | |||
| class TbeKernelMod : public AscendKernelMod { | |||
| public: | |||
| explicit TbeKernelMod(KernelPackPtr kernel_pack) : kernel_pack_(std::move(kernel_pack)) {} | |||
| ~TbeKernelMod() override = default; | |||
| @@ -55,8 +55,9 @@ class ParallelBuildManager { | |||
| bool WaitOne(int *task_id, char **task_result) const; | |||
| bool IsAllTaskFinish() const; | |||
| std::pair<int32_t, KernelModPtr> TaskFinishProcess(int32_t task_id, bool set_kernel_mod = true); | |||
| KernelModPtr GenKernelMod(const string &json_name, const string &processor, const vector<size_t> &input_size_list, | |||
| const vector<size_t> &output_size_list, const KernelPackPtr &kernel_pack) const; | |||
| KernelModPtr GenKernelMod(const string &json_name, const string &processor, | |||
| const std::vector<size_t> &input_size_list, const std::vector<size_t> &output_size_list, | |||
| const KernelPackPtr &kernel_pack) const; | |||
| private: | |||
| PyObject *tbe_parallel_compiler_; | |||
| @@ -168,7 +168,7 @@ bool ParseDynamicFormatJson(const std::string &jsonStr, std::vector<std::shared_ | |||
| return true; | |||
| } | |||
| std::string OpSelectFormat(const shared_ptr<AnfNode> &anf_node) { | |||
| std::string OpSelectFormat(const std::shared_ptr<AnfNode> &anf_node) { | |||
| nlohmann::json kernel_json; | |||
| std::string res_json_str; | |||
| TbeKernelJsonCreator creator(OP_SELECT_FORMAT); | |||
| @@ -182,7 +182,7 @@ std::string OpSelectFormat(const shared_ptr<AnfNode> &anf_node) { | |||
| return res_json_str; | |||
| } | |||
| void SetTidyInputsInfo(const shared_ptr<AnfNode> &anf_node, | |||
| void SetTidyInputsInfo(const std::shared_ptr<AnfNode> &anf_node, | |||
| const std::shared_ptr<KernelBuildInfo::KernelBuildInfoBuilder> &builder, | |||
| const std::vector<std::shared_ptr<OpIOInfo>> &inputs) { | |||
| std::vector<TypeId> inputs_type; | |||
| @@ -231,7 +231,7 @@ void SetTidyInputsInfo(const shared_ptr<AnfNode> &anf_node, | |||
| builder->SetInputsFormat(inputs_format); | |||
| } | |||
| void SetTidyOutputsInfo(const shared_ptr<AnfNode> &anf_node, | |||
| void SetTidyOutputsInfo(const std::shared_ptr<AnfNode> &anf_node, | |||
| const std::shared_ptr<KernelBuildInfo::KernelBuildInfoBuilder> &builder, | |||
| const std::vector<std::shared_ptr<OpIOInfo>> &outputs) { | |||
| std::vector<TypeId> outputs_type; | |||
| @@ -268,7 +268,8 @@ void SetTidyOutputsInfo(const shared_ptr<AnfNode> &anf_node, | |||
| builder->SetOutputsFormat(outputs_format); | |||
| } | |||
| void GenTidyKernelBuildInfo(const shared_ptr<AnfNode> &anf_node, const std::vector<std::shared_ptr<OpIOInfo>> &inputs, | |||
| void GenTidyKernelBuildInfo(const std::shared_ptr<AnfNode> &anf_node, | |||
| const std::vector<std::shared_ptr<OpIOInfo>> &inputs, | |||
| const std::vector<std::shared_ptr<OpIOInfo>> &outputs) { | |||
| auto builder_tmp = std::make_shared<KernelBuildInfo::KernelBuildInfoBuilder>(); | |||
| builder_tmp->SetKernelType(TBE_KERNEL); | |||
| @@ -26,6 +26,7 @@ | |||
| #include <iostream> | |||
| #include <fstream> | |||
| #include "runtime/kernel.h" | |||
| #include "kernel/oplib/oplib.h" | |||
| #include "utils/utils.h" | |||
| #include "session/anf_runtime_algorithm.h" | |||
| @@ -0,0 +1,64 @@ | |||
| /** | |||
| * 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_PIPELINE_BASE_H_ | |||
| #define MINDSPORE_CCSRC_PIPELINE_BASE_H_ | |||
| #include <mutex> | |||
| #include <memory> | |||
| #include <string> | |||
| #include <sstream> | |||
| #include "ir/anf.h" | |||
| #include "pipeline/resource.h" | |||
| #include "utils/context/ms_context.h" | |||
| namespace mindspore { | |||
| namespace pipeline { | |||
| struct ExecutorInfo { | |||
| FuncGraphPtr func_graph; | |||
| ResourcePtr resource; | |||
| std::size_t arg_list_size; | |||
| }; | |||
| using ExecutorInfoPtr = std::shared_ptr<ExecutorInfo>; | |||
| inline std::string GetPhasePrefix(const std::string& phase) { | |||
| auto pos = phase.find('.'); | |||
| if (pos == std::string::npos) { | |||
| MS_LOG(EXCEPTION) << "phase has no . for prefix" << phase; | |||
| } | |||
| return phase.substr(0, pos); | |||
| } | |||
| inline std::string GetFilePathName(const std::string& file_name) { | |||
| std::ostringstream oss; | |||
| auto ms_context = MsContext::GetInstance(); | |||
| if (ms_context == nullptr) { | |||
| MS_LOG(EXCEPTION) << "ms_context is nullptr"; | |||
| } | |||
| auto save_graphs_path = ms_context->save_graphs_path(); | |||
| if (save_graphs_path.empty()) { | |||
| save_graphs_path = "."; | |||
| } | |||
| oss << save_graphs_path << "/" << file_name; | |||
| return oss.str(); | |||
| } | |||
| } // namespace pipeline | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_PIPELINE_BASE_H_ | |||
| @@ -73,7 +73,7 @@ PYBIND11_MODULE(_c_expression, m) { | |||
| "Get CNode Strategy Dictionary.") | |||
| .def("get_allreduce_fusion", &ExecutorPy::GetAllreduceFusion, py::arg("phase") = py::str("train"), | |||
| "Get Allreduce Fusion Dictionary.") | |||
| .def("build_data_graph", &ExecutorPy::BuildDFGraph, py::arg("build_params"), py::arg("phase") = py::str("train"), | |||
| .def("build_data_graph", &ExecutorPy::BuildGraph, py::arg("build_params"), py::arg("phase") = py::str("train"), | |||
| py::arg("broadcast_params") = py::dict(), "Build data graph.") | |||
| .def("has_compiled", &ExecutorPy::HasCompiled, py::arg("phase") = py::str(""), "get if cell compiled.") | |||
| .def("run_init_graph", &ExecutorPy::RunInitGraph, "Run init Graph."); | |||
| @@ -86,19 +86,17 @@ PYBIND11_MODULE(_c_expression, m) { | |||
| (void)m.def("generate_key", &mindspore::pipeline::GenerateKey, "Generate the function graph key."); | |||
| (void)m.def("real_run_op", &mindspore::pynative::RunOp, "Run op pynatively."); | |||
| (void)m.def("initialize_distribute", &mindspore::pipeline::InitDistribute, "Initialize for Distribute.") | |||
| .def("init_ge", &mindspore::pipeline::InitGe, "Init GE"); | |||
| (void)m.def("reset_op_id", &mindspore::pipeline::ResetOpId, "Reset Operator Id"); | |||
| (void)m.def("init_hccl", &mindspore::pipeline::InitHccl, "Init Hccl"); | |||
| (void)m.def("finalize_ge", &mindspore::pipeline::FinalizeGe, "Finalize Ge"); | |||
| (void)m.def("finalize_hccl", &mindspore::pipeline::FinalizeHccl, "Finalize Hccl"); | |||
| (void)m.def("set_ge_option", &mindspore::pipeline::SetGeOption, "API for set ge option."); | |||
| (void)m.def("verify_inputs_signature", &mindspore::pipeline::VerifyInputSignature, "Verify input signature."); | |||
| (void)m.def("init_exec_dataset", &mindspore::pipeline::InitExecDataset, py::arg("queue_name"), py::arg("size"), | |||
| py::arg("batch_size"), py::arg("types"), py::arg("shapes"), py::arg("input_indexs"), | |||
| py::arg("phase") = py::str("dataset"), "Init and exec dataset."); | |||
| (void)m.def("_set_dataset_mode_config", &mindspore::ConfigManager::SetDatasetModeConfig, "API for set dataset mode."); | |||
| (void)m.def("export_graph", &mindspore::pipeline::ExportDFGraph, "Export Graph."); | |||
| (void)m.def("init_ge", &mindspore::pipeline::InitGe, "Init GE"); | |||
| (void)m.def("export_graph", &mindspore::pipeline::ExportGraph, "Export Graph."); | |||
| (void)py::class_<mindspore::MsContext, std::shared_ptr<mindspore::MsContext>>(m, "MSContext") | |||
| .def_static("get_instance", &mindspore::MsContext::GetInstance, "Get ms context instance.") | |||
| @@ -27,6 +27,7 @@ static std::shared_ptr<py::scoped_interpreter> scoped_ = nullptr; | |||
| // true: start process from python, false: start process from c++ | |||
| static bool python_env_ = false; | |||
| static bool use_signature_in_resolve_ = true; | |||
| void ResetPythonScope() { scoped_ = nullptr; } | |||
| void set_use_signature_in_resolve(bool use_signature) noexcept { use_signature_in_resolve_ = use_signature; } | |||
| bool UseSignatureInResolve() { return use_signature_in_resolve_; } | |||
| void set_python_env_flag(bool python_env) noexcept { python_env_ = python_env; } | |||
| @@ -55,6 +55,7 @@ void set_use_signature_in_resolve(bool use_signature) noexcept; | |||
| bool UseSignatureInResolve(); | |||
| std::shared_ptr<py::scoped_interpreter> set_python_scoped(); | |||
| void ResetPythonScope(); | |||
| bool IsPythonEnv(); | |||
| void SetPythonPath(const std::string& path); | |||
| void set_python_env_flag(bool python_env) noexcept; | |||
| @@ -27,11 +27,6 @@ | |||
| #include "pipeline/pass.h" | |||
| #include "pipeline/parse/data_converter.h" | |||
| #include "optimizer/ad/dfunctor.h" | |||
| #include "ir/meta_tensor.h" | |||
| #include "transform/convert.h" | |||
| #include "transform/df_graph_manager.h" | |||
| #include "transform/graph_builder.h" | |||
| #include "transform/graph_runner.h" | |||
| #include "debug/anf_ir_dump.h" | |||
| #include "debug/anf_ir_utils.h" | |||
| #include "utils/config_manager.h" | |||
| @@ -44,6 +39,12 @@ | |||
| #include "device/kernel_runtime_manager.h" | |||
| #include "debug/trace.h" | |||
| #if (ENABLE_GE || ENABLE_D) | |||
| #include "pipeline/pipeline_ge.h" | |||
| #include "transform/convert.h" | |||
| #include "transform/df_graph_manager.h" | |||
| #endif | |||
| namespace mindspore { | |||
| // namespace to support intermediate representation definition | |||
| namespace pipeline { | |||
| @@ -54,12 +55,6 @@ using mindspore::abstract::AbstractTensor; | |||
| using mindspore::abstract::AbstractTensorPtr; | |||
| using mindspore::abstract::AbstractTuple; | |||
| using mindspore::abstract::AbstractTuplePtr; | |||
| using mindspore::transform::DfGraphConvertor; | |||
| using mindspore::transform::DfGraphManager; | |||
| using mindspore::transform::GeTensorPtr; | |||
| using mindspore::transform::MeTensorPtr; | |||
| using mindspore::transform::Status; | |||
| using mindspore::transform::TransformUtil; | |||
| const char IR_TYPE_ANF[] = "anf_ir"; | |||
| const char IR_TYPE_ONNX[] = "onnx_ir"; | |||
| @@ -85,65 +80,8 @@ std::string GetBaseNameForIR(int stage_idx, const std::string& action_name) { | |||
| oss << save_graphs_path << "/" << stage_idx << "_" << action_name; | |||
| return oss.str(); | |||
| } | |||
| std::string GetFilePathName(const std::string& file_name) { | |||
| std::ostringstream oss; | |||
| auto ms_context = MsContext::GetInstance(); | |||
| if (ms_context == nullptr) { | |||
| MS_LOG(EXCEPTION) << "ms_context is nullptr"; | |||
| } | |||
| auto save_graphs_path = ms_context->save_graphs_path(); | |||
| if (save_graphs_path.empty()) { | |||
| save_graphs_path = "."; | |||
| } | |||
| oss << save_graphs_path << "/" << file_name; | |||
| return oss.str(); | |||
| } | |||
| } // namespace | |||
| // We will not execute graph when output is constant or just input itself. | |||
| static bool IsGraphOutputValueNodeOrParameter(const AnfNodePtr& output, const py::tuple& args, | |||
| const std::shared_ptr<py::object>& ret_val) { | |||
| if (output->isa<ValueNode>()) { | |||
| MS_LOG(INFO) << "Graph's output is a constant. No need to execute."; | |||
| ValuePtr value = GetValueNode(output); | |||
| *ret_val = ValuePtrToPyData(value); | |||
| return true; | |||
| } | |||
| // Adapter will transform values in __init__() and construct() to parameters, this could cause | |||
| // inputs (a.k.a args in current function) size less than parameters'. | |||
| if (output->isa<Parameter>()) { | |||
| MS_LOG(INFO) << "Graph's output is a parameter. If all params are inputs, no need to execute."; | |||
| if (args.empty()) { | |||
| MS_LOG(EXCEPTION) << "Inputs size is 0, let graph to be executed."; | |||
| } | |||
| // Find the right parameter as ret_val. | |||
| auto func_graph = output->func_graph(); | |||
| MS_EXCEPTION_IF_NULL(func_graph); | |||
| auto params = func_graph->parameters(); | |||
| if (params.empty()) { | |||
| MS_EXCEPTION(UnknownError) << "Graph's parameters size is 0"; | |||
| } | |||
| if (args.size() != params.size()) { | |||
| MS_LOG(EXCEPTION) << "Input size " << args.size() << " not equal to params size " << params.size() | |||
| << ", let graph to be executed."; | |||
| } | |||
| auto it = std::find(params.begin(), params.end(), output); | |||
| if (it == params.end()) { | |||
| MS_EXCEPTION(UnknownError) << "When graph output is Parameter, it should be found in graph parameters"; | |||
| } | |||
| size_t index = it - params.cbegin(); | |||
| if (index >= args.size()) { | |||
| MS_EXCEPTION(UnknownError) << "Index " << index << " equal or larger than args size " << args.size() << "."; | |||
| } | |||
| *ret_val = args[index]; | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| py::tuple GenerateKey(const std::string& name, const std::unordered_map<std::string, py::object>& defaults) { | |||
| MS_LOG(DEBUG) << "GenerateKey args size:" << defaults.size(); | |||
| abstract::AbstractBasePtrList args_spec; | |||
| @@ -207,11 +145,7 @@ py::bool_ VerifyInputSignature(const py::list input_signature, const py::tuple i | |||
| return true; | |||
| } | |||
| ExecutorPy::ExecutorPy() { | |||
| // because Ge only support one Session exist at the same time ,so we delete the old one | |||
| DfGraphManager::GetInstance().DeleteGraphRunner(); | |||
| DfGraphManager::GetInstance().DeleteGeSession(); | |||
| } | |||
| ExecutorPy::ExecutorPy() {} | |||
| ResourcePtr ExecutorPy::GetResource(const std::string& phase) { | |||
| MS_LOG(DEBUG) << "phase size:" << info_.size(); | |||
| @@ -221,14 +155,6 @@ ResourcePtr ExecutorPy::GetResource(const std::string& phase) { | |||
| return info_[phase]->resource; | |||
| } | |||
| std::string GetPhasePrefix(const std::string& phase) { | |||
| auto pos = phase.find('.'); | |||
| if (pos == std::string::npos) { | |||
| MS_LOG(EXCEPTION) << "phase has no . for prefix" << phase; | |||
| } | |||
| return phase.substr(0, pos); | |||
| } | |||
| FuncGraphPtr ExecutorPy::GetFuncGraph(const std::string& phase) { | |||
| if (info_.count(phase) == 0) { | |||
| MS_LOG(EXCEPTION) << "no phase in executor:" << GetPhasePrefix(phase); | |||
| @@ -323,11 +249,15 @@ void ExecutorPy::DelNetRes(const std::string& id) { | |||
| } | |||
| } | |||
| MS_LOG(INFO) << "Delete flag:" << flag; | |||
| #ifdef ENABLE_GE | |||
| if (flag && info_.size() == 0) { | |||
| DfGraphManager::GetInstance().DeleteGraphRunner(); | |||
| DfGraphManager::GetInstance().EraseAnfGraph(); | |||
| DfGraphManager::GetInstance().DeleteGeSession(); | |||
| // because Ge only support one Session exist at the same time ,so we delete the old one | |||
| transform::DfGraphManager::GetInstance().DeleteGraphRunner(); | |||
| transform::DfGraphManager::GetInstance().EraseAnfGraph(); | |||
| transform::DfGraphManager::GetInstance().DeleteGeSession(); | |||
| } | |||
| #endif | |||
| } | |||
| } | |||
| @@ -405,7 +335,8 @@ bool ExecutorPy::CompileInner(const py::object& obj, const py::tuple& args, cons | |||
| use_vm = ChangeExportGeirUseVmFlag(use_vm, phase_s); | |||
| if (use_vm) { | |||
| std::string backend = MsContext::GetInstance()->backend_policy(); | |||
| if (use_vm && backend != "ge") { | |||
| // Create backend and session | |||
| resource->results()[kBackend] = compile::CreateBackend(); | |||
| p_actions = VmPipeline(); | |||
| @@ -497,30 +428,6 @@ bool ExecutorPy::Compile(const py::object& obj, const py::tuple& args, const py: | |||
| return ret_value; | |||
| } | |||
| void SetGeOption(const std::map<std::string, std::string>& options) { | |||
| ConfigManager::GetInstance().set_ge_initialize_options(options); | |||
| } | |||
| bool InitDistribute(const std::map<std::string, std::string>& options) { | |||
| ConfigManager::GetInstance().set_parallel_strategy(ParallelStrategy::DISTRIBUTION); | |||
| MS_LOG(INFO) << "ME run in DISTRIBUTION strategy mode"; | |||
| SetGeOption(options); | |||
| #ifdef ENABLE_GE | |||
| auto ge_options = ConfigManager::GetInstance().ge_initialize_options(); | |||
| { | |||
| // Release GIL before calling into (potentially long-running) C++ code | |||
| py::gil_scoped_release release; | |||
| if (ge::GEInitialize(ge_options) != ge::GRAPH_SUCCESS) { | |||
| MS_LOG(ERROR) << "Initialize GE failed!"; | |||
| return false; | |||
| } | |||
| } | |||
| #endif | |||
| MS_LOG(DEBUG) << "Initialize Ge success"; | |||
| return true; | |||
| } | |||
| #ifdef ENABLE_LOAD_ANF_IR | |||
| // get MindSpore Intermediate Representation File | |||
| std::string GetMsIrFile(void) { | |||
| @@ -704,9 +611,25 @@ py::object ExecutorPy::Run(const py::tuple& args, const py::object& phase) { | |||
| } | |||
| auto phase_s = py::cast<std::string>(phase); | |||
| std::string backend = MsContext::GetInstance()->backend_policy(); | |||
| #ifdef ENABLE_GE | |||
| if (backend == "ge") { | |||
| return ExecDFGraph(info_, args, phase_s); | |||
| } | |||
| #else | |||
| MS_LOG(WARNING) << "In ut test " << size << phase_s; | |||
| if (backend == "ge") { | |||
| return ExecDFGraph(args, phase_s); | |||
| std::shared_ptr<py::object> ret_val = std::make_shared<py::object>(); | |||
| if (info_.count(phase_s) != 0 && info_[phase_s]->func_graph != nullptr) { | |||
| if (IsGraphOutputValueNodeOrParameter(info_[phase_s]->func_graph->output(), args, ret_val)) { | |||
| return *ret_val; | |||
| } | |||
| } | |||
| if (args.size() > 0) { | |||
| return args[0]; | |||
| } | |||
| return args; | |||
| } | |||
| #endif | |||
| std::size_t full_arg_size = ArgListSize(phase_s); | |||
| if (size > full_arg_size) { | |||
| MS_LOG(WARNING) << "The arg num : size = " << size << ". full_arg_size = " << full_arg_size; | |||
| @@ -719,435 +642,25 @@ py::object ExecutorPy::Run(const py::tuple& args, const py::object& phase) { | |||
| MS_LOG(EXCEPTION) << "Can't find run graph func for " << phase_s; | |||
| } | |||
| MS_LOG(DEBUG) << "eval run"; | |||
| MS_LOG(DEBUG) << "eval run" << backend; | |||
| BaseRef value = (*run)(arg_list); | |||
| MS_LOG(DEBUG) << "run end"; | |||
| return BaseRefToPyData(value); | |||
| } | |||
| py::object ExtractGeneralCnodeRet(const AbstractBasePtr& cnode_data, const py::tuple& data, size_t* count) { | |||
| MS_EXCEPTION_IF_NULL(cnode_data); | |||
| if (*count >= data.size()) { | |||
| MS_LOG(EXCEPTION) << "The number of elements in the outputs : " << data.size() | |||
| << " less than the number of elements required. "; | |||
| } | |||
| if (cnode_data->isa<AbstractTensor>()) { | |||
| BaseShapePtr shape = cnode_data->BuildShape(); | |||
| auto shape_act = shape->cast<abstract::ShapePtr>()->shape(); | |||
| Tensor tensor_exp = py::cast<Tensor>(data[*count]); | |||
| if (shape_act != tensor_exp.shape()) { | |||
| MS_LOG(EXCEPTION) << "The shape of the tensor returned from GE is not the same as " | |||
| "the shape of the tensor derived from ME."; | |||
| } | |||
| return data[(*count)++]; | |||
| } | |||
| if (!cnode_data->isa<AbstractTuple>()) { | |||
| MS_LOG(EXCEPTION) << "The output of operator in the final anf graph could " | |||
| << "only be a tensor or a tuple of tensor, but got " << cnode_data->BuildValue()->ToString() | |||
| << "."; | |||
| } | |||
| auto data_tp = cnode_data->cast<AbstractTuplePtr>(); | |||
| auto elements = data_tp->elements(); | |||
| size_t size = data_tp->size(); | |||
| py::tuple tp = py::tuple(size); | |||
| for (size_t i = 0; i < size; i++) { | |||
| tp[i] = ExtractGeneralCnodeRet(elements[i], data, count); | |||
| } | |||
| return std::move(tp); | |||
| } | |||
| py::object StructureOutput(const AnfNodePtr& output_node, const py::tuple& data, size_t* count) { | |||
| MS_EXCEPTION_IF_NULL(output_node); | |||
| if (output_node->isa<ValueNode>()) { | |||
| return ValuePtrToPyData(GetValueNode(output_node)); | |||
| } | |||
| if (*count >= data.size()) { | |||
| MS_LOG(EXCEPTION) << "The number of elements in the outputs : " << data.size() | |||
| << " less than the number of elements required. "; | |||
| } | |||
| if (output_node->isa<Parameter>()) { | |||
| return data[(*count)++]; | |||
| } | |||
| auto output_c = output_node->cast<CNodePtr>(); | |||
| if (output_c == nullptr) { | |||
| MS_LOG(EXCEPTION) << "The final anf graph could only have constant, parameter, and operator, but got " | |||
| << output_node->ToString(); | |||
| } | |||
| if (output_c->IsApply(prim::kPrimMakeTuple)) { | |||
| auto input_list = output_c->inputs(); | |||
| size_t size = input_list.size(); | |||
| py::tuple tp = py::tuple(size - 1); | |||
| for (size_t i = 1; i < size; i++) { | |||
| tp[i - 1] = StructureOutput(input_list[i], data, count); | |||
| } | |||
| return std::move(tp); | |||
| } | |||
| if (output_c->IsApply(prim::kPrimDepend)) { | |||
| return StructureOutput(output_c->input(1), data, count); | |||
| } | |||
| return ExtractGeneralCnodeRet(output_c->abstract(), data, count); | |||
| } | |||
| std::shared_ptr<py::object> DoExecGraph(const FuncGraphPtr& graph, const std::vector<MeTensorPtr>& inputs, | |||
| const std::string& phase) { | |||
| std::vector<GeTensorPtr> ge_tensors = TransformUtil::ConvertInputTensors(inputs, kOpFormat_NCHW); | |||
| if (ge_tensors.size() != inputs.size()) { | |||
| MS_LOG(ERROR) << "args convert to ge tensor error"; | |||
| return nullptr; | |||
| } | |||
| std::vector<GeTensorPtr> ge_outputs; | |||
| transform::RunOptions run_options; | |||
| run_options.name = phase; | |||
| auto graph_runner = DfGraphManager::GetInstance().GetGraphRunner(); | |||
| if (graph_runner == nullptr) { | |||
| MS_LOG(ERROR) << "Can not found GraphRunner"; | |||
| return nullptr; | |||
| } | |||
| { | |||
| // Release GIL before calling into (potentially long-running) C++ code | |||
| py::gil_scoped_release release; | |||
| MS_LOG(DEBUG) << "Run graph begin, inputs size is: " << inputs.size(); | |||
| Status ret = graph_runner->RunGraph(run_options, ge_tensors, &ge_outputs); | |||
| MS_LOG(DEBUG) << "Run graph finish, outputs size is: " << ge_outputs.size(); | |||
| if (ret != Status::SUCCESS) { | |||
| MS_LOG(ERROR) << "Exec graph failed"; | |||
| return nullptr; | |||
| } | |||
| } | |||
| std::vector<MeTensorPtr> me_outputs = TransformUtil::ConvertGeTensors(ge_outputs); | |||
| if (me_outputs.size() != ge_outputs.size()) { | |||
| MS_LOG(ERROR) << "Convert output Ge tensor to Me tensor failed"; | |||
| } | |||
| py::tuple outputs(me_outputs.size()); | |||
| for (std::size_t i = 0; i < outputs.size(); i++) { | |||
| outputs[i] = *me_outputs[i]; | |||
| } | |||
| std::shared_ptr<py::object> ret = nullptr; | |||
| #ifdef ENABLE_GE | |||
| AnfNodePtr output_node = graph->get_return()->input(1); | |||
| MS_EXCEPTION_IF_NULL(output_node); | |||
| size_t count = 0; | |||
| py::object oj = StructureOutput(output_node, outputs, &count); | |||
| ret = std::make_shared<py::object>(oj); | |||
| FuncGraphPtr ExecutorPy::BuildGraph(const py::dict& init_params, const std::string& phase, | |||
| const py::object& broadcast_params) { | |||
| #if (ENABLE_GE || ENABLE_D) | |||
| return BuildDFGraph(info_, init_params, phase, broadcast_params); | |||
| #else | |||
| if (outputs.size() == 1) { | |||
| ret = std::make_shared<py::object>(outputs[0]); | |||
| } else { | |||
| ret = std::make_shared<py::object>(outputs); | |||
| } | |||
| #endif | |||
| return ret; | |||
| } | |||
| void DoExecNonInputGraph(const std::string& phase) { | |||
| std::vector<GeTensorPtr> ge_tensors; | |||
| std::vector<GeTensorPtr> ge_outputs; | |||
| transform::RunOptions run_options; | |||
| run_options.name = phase; | |||
| auto graph_runner = DfGraphManager::GetInstance().GetGraphRunner(); | |||
| if (graph_runner == nullptr) { | |||
| MS_LOG(ERROR) << "Can not found GraphRunner"; | |||
| return; | |||
| } | |||
| { | |||
| // Release GIL before calling into (potentially long-running) C++ code | |||
| py::gil_scoped_release release; | |||
| Status ret = graph_runner->RunGraph(run_options, ge_tensors, &ge_outputs); | |||
| if (ret != Status::SUCCESS) { | |||
| MS_LOG(ERROR) << "Exec graph:" << run_options.name << " failed"; | |||
| return; | |||
| } | |||
| } | |||
| } | |||
| void ExecutorPy::ProcessGeArg(const py::tuple& args, const std::string& phase, std::vector<tensor::TensorPtr>* inputs) { | |||
| // check the arg and use the ExecutorPy args | |||
| std::size_t size = args.size(); | |||
| if (size != ArgListSize(phase)) { | |||
| MS_LOG(EXCEPTION) << "The real arg num : size = " << size << ". graph_arg_size = " << ArgListSize(phase); | |||
| } | |||
| // process the first args of tensor | |||
| // only in Dataset Feed Mode, fp_bp graph need input tensors | |||
| if (ConfigManager::GetInstance().dataset_mode() == DS_FEED_MODE) { | |||
| for (std::size_t i = 0; i < size; i++) { | |||
| ValuePtr converted = nullptr; | |||
| bool succ = parse::ConvertData(args[i], &converted); | |||
| if (!succ) { | |||
| MS_LOG(EXCEPTION) << "args convert error"; | |||
| } | |||
| if (converted->isa<tensor::Tensor>()) { | |||
| (*inputs).push_back(converted->cast<tensor::TensorPtr>()); | |||
| } else { | |||
| MS_LOG(EXCEPTION) << "args, " << converted->ToString() << " is not tensor"; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| py::object ExecutorPy::ExecDFGraph(const py::tuple& args, const std::string& phase) { | |||
| std::string phase_prefix = GetPhasePrefix(phase); | |||
| if (phase_prefix == "save") { | |||
| DoExecNonInputGraph(phase); | |||
| ConfigManager::GetInstance().ResetConfig(); | |||
| return py::none(); | |||
| } | |||
| if (info_.count(phase) == 0) { | |||
| MS_LOG(EXCEPTION) << "has no phase:" << phase; | |||
| } | |||
| #if (!defined ENABLE_GE) || (defined ENABLE_INFER) | |||
| // Now don't use the graph because the exec ge function don't take effect | |||
| MS_EXCEPTION_IF_NULL(info_[phase]->func_graph); | |||
| if (ENABLE_TRAIN != info_[phase]->func_graph->flags()["training"]) { | |||
| MS_LOG(ERROR) << "Graph training mode mismatch mode of libraries"; | |||
| ConfigManager::GetInstance().ResetConfig(); | |||
| return py::none(); | |||
| } | |||
| return nullptr; | |||
| #endif | |||
| std::shared_ptr<py::object> ret_val = std::make_shared<py::object>(); | |||
| if (IsGraphOutputValueNodeOrParameter(info_[phase]->func_graph->output(), args, ret_val)) { | |||
| ConfigManager::GetInstance().ResetConfig(); | |||
| return *ret_val; | |||
| } | |||
| std::vector<tensor::TensorPtr> inputs; | |||
| ProcessGeArg(args, phase, &inputs); | |||
| std::shared_ptr<py::object> ret = DoExecGraph(GetFuncGraph(phase), inputs, phase); | |||
| ConfigManager::GetInstance().ResetConfig(); | |||
| if (ret != nullptr) { | |||
| return *ret; | |||
| } else { | |||
| MS_LOG(EXCEPTION) << "exec graph failed"; | |||
| } | |||
| } | |||
| void ExecutorPy::RunInitGraph(const py::dict& init_params, const std::string& phase) { | |||
| MS_LOG(DEBUG) << "ExecInitGraph start."; | |||
| TensorOrderMap inputs_with_name{}; | |||
| ConvertObjectToTensors(init_params, &inputs_with_name); | |||
| std::vector<tensor::TensorPtr> inputs; | |||
| (void)std::transform(inputs_with_name.begin(), inputs_with_name.end(), std::back_inserter(inputs), | |||
| [](const std::pair<std::string, tensor::TensorPtr>& item) { return item.second; }); | |||
| std::vector<GeTensorPtr> ge_tensors = TransformUtil::ConvertInputTensors(inputs, kOpFormat_NCHW); | |||
| if (ge_tensors.size() != inputs.size()) { | |||
| MS_LOG(ERROR) << "Args convert to ge tensor error."; | |||
| return; | |||
| } | |||
| MS_LOG(DEBUG) << "Run graph begin, inputs size is: " << inputs.size() << "."; | |||
| std::vector<GeTensorPtr> ge_outputs; | |||
| transform::RunOptions run_options; | |||
| run_options.name = phase; | |||
| if (DfGraphManager::GetInstance().GetGraphByName(phase) == nullptr) { | |||
| MS_LOG(WARNING) << "Can not find " << phase << " sub graph, don't need data init subgraph in INFER mode."; | |||
| return; | |||
| } | |||
| auto graph_runner = DfGraphManager::GetInstance().GetGraphRunner(); | |||
| if (graph_runner == nullptr) { | |||
| MS_LOG(EXCEPTION) << "Can not found GraphRunner."; | |||
| } | |||
| { | |||
| // Release GIL before calling into (potentially long-running) C++ code | |||
| py::gil_scoped_release release; | |||
| Status ret = graph_runner->RunGraph(run_options, ge_tensors, &ge_outputs); | |||
| if (ret != Status::SUCCESS) { | |||
| MS_LOG(EXCEPTION) << "Exec " << phase << " graph failed."; | |||
| } | |||
| MS_LOG(INFO) << "Exec " << phase << " graph success."; | |||
| if ((ConfigManager::GetInstance().parallel_strategy() == ParallelStrategy::DISTRIBUTION) && | |||
| (DfGraphManager::GetInstance().GetGraphByName(BROADCAST_GRAPH_NAME) != nullptr)) { | |||
| run_options.name = BROADCAST_GRAPH_NAME; | |||
| ret = graph_runner->RunGraph(run_options, ge_tensors, &ge_outputs); | |||
| if (ret != Status::SUCCESS) { | |||
| MS_LOG(EXCEPTION) << "Exec BROADCAST_GRAPH_NAME failed."; | |||
| } | |||
| MS_LOG(INFO) << "Exec broadcast graph success."; | |||
| } | |||
| } | |||
| } | |||
| Status CreateSessionAndGraphRunner(bool is_training = true) { | |||
| std::shared_ptr<ge::Session> sess = DfGraphManager::GetInstance().GetGeSession(); | |||
| if (sess == nullptr) { | |||
| transform::SessionOptions options; | |||
| if (is_training) { | |||
| options["ge.trainFlag"] = "1"; | |||
| options["ge.streamNum"] = "100"; | |||
| options["ge.enabledLocalFmkop"] = "1"; | |||
| options["ge.hcomParallel"] = "1"; | |||
| } else { | |||
| options["ge.trainFlag"] = "0"; | |||
| } | |||
| options["ge.enablePrintOpPass"] = "0"; | |||
| sess = transform::GraphRunner::NewSession(options); | |||
| if (sess == nullptr) { | |||
| MS_LOG(ERROR) << "Init data graph failed, because of create Ge session failed"; | |||
| return Status::FAILED; | |||
| } else { | |||
| DfGraphManager::GetInstance().SetGeSession(sess); | |||
| } | |||
| } | |||
| transform::GraphRunnerOptions options; | |||
| options.sess_ptr = sess; | |||
| auto graph_runner = std::make_shared<transform::GraphRunner>(options); | |||
| if (graph_runner == nullptr) { | |||
| MS_LOG(ERROR) << "Create new graph runner failed"; | |||
| return Status::FAILED; | |||
| } else { | |||
| DfGraphManager::GetInstance().SetGraphRunner(graph_runner); | |||
| } | |||
| return Status::SUCCESS; | |||
| } | |||
| void ExecutorPy::ConvertObjectToTensors(const py::dict& dict, TensorOrderMap* const tensors) { | |||
| for (auto item : dict) { | |||
| if ((!py::isinstance<py::str>(item.first))) { | |||
| MS_LOG(WARNING) << "Type of key of py_dict is not string, ignore it."; | |||
| continue; | |||
| } | |||
| std::shared_ptr<Tensor> tensor; | |||
| std::string name = py::cast<std::string>(item.first); | |||
| if (py::isinstance<py::float_>(item.second.attr("default_input"))) { | |||
| // convert float to tensor with shape([1]) | |||
| tensor = std::make_shared<Tensor>(kNumberTypeFloat32, std::vector<int>({1})); | |||
| *(static_cast<float*>(tensor->data_c(true))) = py::cast<float>(item.second.attr("default_input")); | |||
| } else if (py::isinstance<py::int_>(item.second.attr("default_input"))) { | |||
| // convert int to tensor with shape([1]) | |||
| tensor = std::make_shared<Tensor>(kNumberTypeInt32, std::vector<int>({1})); | |||
| *(static_cast<float*>(tensor->data_c(true))) = py::cast<float>(item.second.attr("default_input")); | |||
| } else if (py::hasattr(item.second.attr("default_input"), PYTHON_TENSOR_FLAG)) { | |||
| // cast tensor | |||
| tensor = py::cast<std::shared_ptr<Tensor>>(item.second.attr("default_input")); | |||
| } | |||
| if (tensor == nullptr) { | |||
| MS_LOG(EXCEPTION) << "Get default value for " << name << " failed"; | |||
| } | |||
| (void)tensors->emplace(name, tensor); | |||
| } | |||
| } | |||
| bool ExecutorPy::AddDFGraph(const py::dict& init_params, const std::string& phase, const py::object& broadcast_params) { | |||
| FuncGraphPtr anf_graph = info_[phase]->func_graph; | |||
| DfGraphConvertor convertor(anf_graph); | |||
| size_t pos = phase.find('.'); | |||
| std::string net_id = ((pos == std::string::npos || pos == phase.size() - 1) ? phase : phase.substr(pos + 1)); | |||
| std::string phase_prefix = phase.substr(0, pos); | |||
| if (phase_prefix == "export") { | |||
| MS_LOG(INFO) << "Set DfGraphConvertor training : false"; | |||
| convertor.set_training(false); | |||
| } | |||
| TensorOrderMap init_tensors{}; | |||
| ConvertObjectToTensors(init_params, &init_tensors); | |||
| (void)convertor.ConvertAllNode().InitParam(init_tensors).BuildGraph(); | |||
| if (broadcast_params != py::none()) { | |||
| if (!py::isinstance<py::dict>(broadcast_params)) { | |||
| MS_LOG(ERROR) << "Invalid broadcast params, it must be py::dict type"; | |||
| return false; | |||
| } | |||
| py::dict broadcast = broadcast_params.cast<py::dict>(); | |||
| if (broadcast.empty()) { | |||
| (void)convertor.GenerateBroadcastGraph(init_tensors); | |||
| } else { | |||
| TensorOrderMap broadcast_tensors{}; | |||
| ConvertObjectToTensors(broadcast, &broadcast_tensors); | |||
| (void)convertor.GenerateBroadcastGraph(broadcast_tensors); | |||
| } | |||
| MS_LOG(INFO) << "Generate broadcast graph with params and broadcast_empty is " << broadcast.empty(); | |||
| } | |||
| (void)convertor.GenerateCheckpointGraph(); | |||
| if (convertor.ErrCode() != 0) { | |||
| DfGraphManager::GetInstance().ClearGraph(); | |||
| MS_LOG(ERROR) << "convert df graph failed, err:" << convertor.ErrCode(); | |||
| return false; | |||
| } | |||
| if (MsContext::GetInstance()->save_graphs_flag()) { | |||
| convertor.DrawComputeGraph(GetFilePathName("ge_graph.dot")); // for debug | |||
| convertor.DrawInitGraph(GetFilePathName("init_graph.dot")); // for debug | |||
| convertor.DrawSaveCheckpointGraph(GetFilePathName("save_checkpoint_graph.dot")); // for debug | |||
| } | |||
| std::string init_graph = "init_subgraph." + net_id; | |||
| std::string checkpoint_name = "save." + net_id; | |||
| if (phase.find("train") != std::string::npos) { | |||
| (void)DfGraphManager::GetInstance().AddGraph(phase, convertor.GetComputeGraph(), {{"ge.exec.variable_acc", "1"}}); | |||
| } else { | |||
| (void)DfGraphManager::GetInstance().AddGraph(phase, convertor.GetComputeGraph()); | |||
| } | |||
| (void)DfGraphManager::GetInstance().AddGraph(init_graph, convertor.GetInitGraph()); | |||
| (void)DfGraphManager::GetInstance().AddGraph(BROADCAST_GRAPH_NAME, convertor.GetBroadcastGraph()); | |||
| Status ret = DfGraphManager::GetInstance().AddGraph(checkpoint_name, convertor.GetSaveCheckpointGraph()); | |||
| if (ret == Status::SUCCESS) { | |||
| DfGraphManager::GetInstance().SetAnfGraph(checkpoint_name, anf_graph); | |||
| } | |||
| return true; | |||
| } | |||
| FuncGraphPtr ExecutorPy::BuildDFGraph(const py::dict& init_params, const std::string& phase, | |||
| const py::object& broadcast_params) { | |||
| if (info_.count(phase) == 0) { | |||
| MS_LOG(EXCEPTION) << "no phase in executor:" << GetPhasePrefix(phase); | |||
| } | |||
| FuncGraphPtr anf_graph = info_[phase]->func_graph; | |||
| if (MsContext::GetInstance()->save_graphs_flag()) { | |||
| draw::Draw(GetFilePathName("anf_graph.dot"), anf_graph); // for debug | |||
| DumpIR(GetFilePathName("anf_graph.ir"), anf_graph, true); | |||
| } | |||
| if (!AddDFGraph(init_params, phase, broadcast_params)) { | |||
| MS_LOG(ERROR) << "GenConvertor failed"; | |||
| return nullptr; | |||
| } | |||
| #if ENABLE_TRAIN | |||
| (void)setenv("GE_TRAIN", "1", 1); | |||
| #else | |||
| (void)setenv("GE_TRAIN", "0", 1); | |||
| #if ENABLE_GE | |||
| RunGEInitGraph(init_params, phase); | |||
| #endif | |||
| if (CreateSessionAndGraphRunner(static_cast<bool>(ENABLE_TRAIN)) != Status::SUCCESS) { | |||
| MS_LOG(ERROR) << "Create GE Session or GraphRunner failed."; | |||
| return nullptr; | |||
| } | |||
| return anf_graph; | |||
| } | |||
| bool InitExecDataset(const std::string& queue_name, int64_t iter_num, int64_t batch_size, | |||
| @@ -1156,47 +669,16 @@ bool InitExecDataset(const std::string& queue_name, int64_t iter_num, int64_t ba | |||
| std::string name = MsContext::GetInstance()->backend_policy(); | |||
| if (name == kMsConvert || name == kMsVm) { | |||
| return InitExecDatasetVm(queue_name, iter_num, batch_size, types, shapes, input_indexes); | |||
| } else { | |||
| return InitExecDatasetGe(queue_name, iter_num, batch_size, types, shapes, input_indexes, phase); | |||
| } | |||
| } | |||
| bool InitExecDatasetGe(const std::string& queue_name, int64_t size, int64_t batch_size, | |||
| const std::vector<TypePtr>& types, const std::vector<std::vector<int64_t>>& shapes, | |||
| const std::vector<int64_t>& input_indexes, const std::string& phase) { | |||
| // Convert types to GE types and TF types | |||
| std::vector<int64_t> ge_types; | |||
| (void)std::transform(types.begin(), types.end(), std::back_inserter(ge_types), [](const TypePtr& i) -> int64_t { | |||
| return transform::TransformUtil::ConvertDataType(i->type_id()); | |||
| }); | |||
| ConfigManager::GetInstance().set_dataset_mode(DatasetMode::DS_GRAPH_MODE); | |||
| ConfigManager::GetInstance().set_iter_num(size); | |||
| ConfigManager::GetInstance().set_dataset_phase(phase); | |||
| DatasetGraphParam param(queue_name, size, batch_size, ge_types, shapes, input_indexes); | |||
| ConfigManager::GetInstance().set_dataset_param(param); | |||
| if (transform::BuildDatasetGraph(param, phase) != transform::SUCCESS) { | |||
| MS_LOG(ERROR) << "Build dateset graph failed."; | |||
| return false; | |||
| } | |||
| #if ENABLE_TRAIN | |||
| (void)setenv("GE_TRAIN", "1", 1); | |||
| #if ENABLE_GE | |||
| return InitExecDatasetGe(queue_name, iter_num, batch_size, types, shapes, input_indexes, phase); | |||
| #else | |||
| (void)setenv("GE_TRAIN", "0", 1); | |||
| #endif | |||
| if (CreateSessionAndGraphRunner(static_cast<bool>(ENABLE_TRAIN)) != Status::SUCCESS) { | |||
| MS_LOG(ERROR) << "Create GE Session or GraphRunner failed."; | |||
| return false; | |||
| std::string backend = MsContext::GetInstance()->backend_policy(); | |||
| if (backend == "ge") { | |||
| return true; | |||
| } | |||
| MS_LOG(INFO) << "DoExecNonInputGraph:" << phase; | |||
| DoExecNonInputGraph(phase); | |||
| return true; | |||
| #endif | |||
| return false; | |||
| } | |||
| bool InitExecDatasetVm(const std::string& queue_name, int64_t size, int64_t batch_size, | |||
| @@ -1259,25 +741,6 @@ bool InitExecDatasetVm(const std::string& queue_name, int64_t size, int64_t batc | |||
| return true; | |||
| } | |||
| void InitGe() { | |||
| // set python env flag | |||
| mindspore::parse::python_adapter::set_python_env_flag(true); | |||
| // open tsd before ge initialize | |||
| auto ms_context = MsContext::GetInstance(); | |||
| MS_EXCEPTION_IF_NULL(ms_context); | |||
| if (!ms_context->OpenTsd()) { | |||
| MS_LOG(EXCEPTION) << "open tsd failed"; | |||
| } | |||
| (void)ms_context->InitGe(); | |||
| } | |||
| void FinalizeGe() { | |||
| auto context_ptr = MsContext::GetInstance(); | |||
| MS_EXCEPTION_IF_NULL(context_ptr); | |||
| (void)context_ptr->FinalizeGe(); | |||
| (void)context_ptr->CloseTsd(); | |||
| } | |||
| void ResetOpId() { mindspore::id_generator::reset_id(); } | |||
| void InitHccl() { | |||
| @@ -1309,24 +772,57 @@ void FinalizeHccl() { | |||
| device::KernelRuntimeManager::Instance().ClearRuntimeResource(); | |||
| #endif | |||
| } | |||
| void ExportDFGraph(const std::string& file_name, const std::string&, const std::string& phase) { | |||
| MS_LOG(DEBUG) << "ExportGraph Begin"; | |||
| transform::DfGraphWrapperPtr wrap_ptr = DfGraphManager::GetInstance().GetGraphByName(phase); | |||
| if (wrap_ptr == nullptr) { | |||
| MS_LOG(ERROR) << "Get graph form DfGraphManager failed!"; | |||
| return; | |||
| } | |||
| transform::DfGraphPtr ge_graph = wrap_ptr->graph_ptr_; | |||
| if (nullptr == ge_graph) { | |||
| MS_LOG(ERROR) << "The export graph is null"; | |||
| return; | |||
| void ExportGraph(const std::string& file_name, const std::string&, const std::string& phase) { | |||
| #if (ENABLE_GE || ENABLE_D) | |||
| ExportDFGraph(file_name, phase); | |||
| #endif | |||
| MS_LOG(WARNING) << "In ut test no export_graph"; | |||
| } | |||
| void ReleaseGeTsd() { | |||
| auto context_ptr = MsContext::GetInstance(); | |||
| if (context_ptr != nullptr) { | |||
| (void)context_ptr->FinalizeGe(true); | |||
| (void)context_ptr->CloseTsd(true); | |||
| } | |||
| } | |||
| (void)ge_graph->SaveToFile(file_name); | |||
| void InitGe() { | |||
| // set python env flag | |||
| mindspore::parse::python_adapter::set_python_env_flag(true); | |||
| // open tsd before ge initialize | |||
| auto ms_context = MsContext::GetInstance(); | |||
| MS_EXCEPTION_IF_NULL(ms_context); | |||
| if (!ms_context->OpenTsd()) { | |||
| MS_LOG(EXCEPTION) << "open tsd failed"; | |||
| } | |||
| (void)ms_context->InitGe(); | |||
| } | |||
| MS_LOG(DEBUG) << "ExportGraph End"; | |||
| void FinalizeGe() { | |||
| auto context_ptr = MsContext::GetInstance(); | |||
| MS_EXCEPTION_IF_NULL(context_ptr); | |||
| (void)context_ptr->FinalizeGe(); | |||
| (void)context_ptr->CloseTsd(); | |||
| } | |||
| void ClearResAtexit() { | |||
| MS_LOG(DEBUG) << "Pipeline clear all resource"; | |||
| device::KernelRuntimeManager::Instance().ClearRuntimeResource(); | |||
| ad::g_k_prims.clear(); | |||
| abstract::ClearPrimEvaluatorMap(); | |||
| compile::ClearConvertCache(); | |||
| pipeline::GetMethodMap().clear(); | |||
| pipeline::ExecutorPy::ClearRes(); | |||
| #ifdef ENABLE_GE | |||
| transform::DfGraphManager::GetInstance().ClearGraph(); | |||
| transform::DfGraphConvertor::get_adpt_map().clear(); | |||
| #endif | |||
| ReleaseGeTsd(); | |||
| parse::python_adapter::ResetPythonScope(); | |||
| } | |||
| } // namespace pipeline | |||
| } // namespace mindspore | |||
| @@ -30,6 +30,7 @@ | |||
| #include "pipeline/action.h" | |||
| #include "vm/segment_runner.h" | |||
| #include "vm/transform.h" | |||
| #include "pipeline/base.h" | |||
| namespace mindspore { | |||
| extern const char kMsConvert[]; | |||
| @@ -55,14 +56,6 @@ class Pipeline { | |||
| std::vector<ActionItem> actions_; | |||
| }; | |||
| struct ExecutorInfo { | |||
| FuncGraphPtr func_graph; | |||
| ResourcePtr resource; | |||
| std::size_t arg_list_size; | |||
| }; | |||
| using ExecutorInfoPtr = std::shared_ptr<ExecutorInfo>; | |||
| // A function pipeline. | |||
| class ExecutorPy : public std::enable_shared_from_this<ExecutorPy> { | |||
| public: | |||
| @@ -80,11 +73,7 @@ class ExecutorPy : public std::enable_shared_from_this<ExecutorPy> { | |||
| bool CompileInner(const py::object& obj, const py::tuple& args, const py::object& phase, bool use_vm); | |||
| bool Compile(const py::object& obj, const py::tuple& args, const py::object& phase, bool use_vm); | |||
| // for graph mode | |||
| py::object ExecDFGraph(const py::tuple& args, const std::string& phase = "train"); | |||
| void ProcessVmArg(const py::tuple& args, const std::string& phase, VectorRef* arg_list); | |||
| void ProcessGeArg(const py::tuple& args, const std::string& phase, std::vector<tensor::TensorPtr>* inputs); | |||
| // for pynative mode when use_vm is on | |||
| py::object Run(const py::tuple& args, const py::object& phase); | |||
| @@ -95,9 +84,8 @@ class ExecutorPy : public std::enable_shared_from_this<ExecutorPy> { | |||
| compile::VmEvalFuncPtr GetVmEvalFunc(const std::string& phase); | |||
| bool HasCompiled(const std::string& phase) const; | |||
| bool AddDFGraph(const py::dict& init_params, const std::string& phase, const py::object& broadcast_params); | |||
| FuncGraphPtr BuildDFGraph(const py::dict& init_params, const std::string& phase, | |||
| const py::object& broadcast_params = {}); | |||
| FuncGraphPtr BuildGraph(const py::dict& init_params, const std::string& phase, | |||
| const py::object& broadcast_params = {}); | |||
| void RunInitGraph(const py::dict& init_params, const std::string& phase); | |||
| py::dict GetParameterLayout(const std::string& phase); | |||
| py::dict GetCNodeStrategy(const std::string& phase); | |||
| @@ -122,32 +110,29 @@ using ExecutorPyPtr = std::shared_ptr<ExecutorPy>; | |||
| py::tuple GenerateKey(const std::string& name, const std::unordered_map<std::string, py::object>& defaults); | |||
| py::bool_ VerifyInputSignature(const py::list input_signature, const py::tuple inputs); | |||
| void SetGeOption(const std::map<std::string, std::string>& options); | |||
| bool InitDistribute(const std::map<std::string, std::string>& options); | |||
| void ResetOpId(); | |||
| void InitGe(); | |||
| void FinalizeGe(); | |||
| void InitHccl(); | |||
| void FinalizeHccl(); | |||
| void InitGe(); | |||
| void FinalizeGe(); | |||
| void ClearResAtexit(); | |||
| void ReleaseGeTsd(); | |||
| void ExportGraph(const std::string& file_name, const std::string&, const std::string& phase); | |||
| // init and exec dataset sub graph | |||
| bool InitExecDataset(const std::string& queue_name, int64_t iter_num, int64_t batch_size, | |||
| const std::vector<TypePtr>& types, const std::vector<std::vector<int64_t>>& shapes, | |||
| const std::vector<int64_t>& input_indexes, const std::string& phase); | |||
| // init and exec dataset sub graph for GE backend | |||
| bool InitExecDatasetGe(const std::string& queue_name, int64_t size, int64_t batch_size, | |||
| const std::vector<TypePtr>& types, const std::vector<std::vector<int64_t>>& shapes, | |||
| const std::vector<int64_t>& input_indexes, const std::string& phase); | |||
| // Build and run dataset subgraph for ms backend | |||
| bool InitExecDatasetVm(const std::string& queue_name, int64_t size, int64_t batch_size, | |||
| const std::vector<TypePtr>& types, const std::vector<std::vector<int64_t>>& shapes, | |||
| const std::vector<int64_t>& input_indexes); | |||
| void ExportDFGraph(const std::string& file_name, const std::string&, const std::string& phase); | |||
| } // namespace pipeline | |||
| } // namespace mindspore | |||
| @@ -0,0 +1,545 @@ | |||
| /** | |||
| * 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 "pipeline/pipeline_ge.h" | |||
| #include <sstream> | |||
| #include <map> | |||
| #include <unordered_map> | |||
| #include <cstdlib> | |||
| #include <algorithm> | |||
| #include "debug/anf_ir_dump.h" | |||
| #include "ir/meta_tensor.h" | |||
| #include "transform/convert.h" | |||
| #include "transform/df_graph_manager.h" | |||
| #include "transform/graph_builder.h" | |||
| #include "transform/graph_runner.h" | |||
| #include "debug/draw.h" | |||
| #include "pipeline/static_analysis/abstract_value.h" | |||
| namespace mindspore { | |||
| namespace pipeline { | |||
| using Tensor = mindspore::tensor::Tensor; | |||
| using MetaTensor = mindspore::tensor::MetaTensor; | |||
| using TensorOrderMap = std::map<std::string, std::shared_ptr<Tensor>>; | |||
| using mindspore::abstract::AbstractTensor; | |||
| using mindspore::abstract::AbstractTuple; | |||
| using mindspore::abstract::AbstractTuplePtr; | |||
| using mindspore::transform::DfGraphConvertor; | |||
| using mindspore::transform::DfGraphManager; | |||
| using mindspore::transform::GeTensorPtr; | |||
| using mindspore::transform::MeTensorPtr; | |||
| using mindspore::transform::Status; | |||
| using mindspore::transform::TransformUtil; | |||
| void DoExecNonInputGraph(const std::string& phase) { | |||
| std::vector<GeTensorPtr> ge_tensors; | |||
| std::vector<GeTensorPtr> ge_outputs; | |||
| transform::RunOptions run_options; | |||
| run_options.name = phase; | |||
| auto graph_runner = DfGraphManager::GetInstance().GetGraphRunner(); | |||
| if (graph_runner == nullptr) { | |||
| MS_LOG(ERROR) << "Can not found GraphRunner"; | |||
| return; | |||
| } | |||
| { | |||
| // Release GIL before calling into (potentially long-running) C++ code | |||
| py::gil_scoped_release release; | |||
| Status ret = graph_runner->RunGraph(run_options, ge_tensors, &ge_outputs); | |||
| if (ret != Status::SUCCESS) { | |||
| MS_LOG(ERROR) << "Exec graph:" << run_options.name << " failed"; | |||
| return; | |||
| } | |||
| } | |||
| } | |||
| void SetGeOption(const std::map<std::string, std::string>& options) { | |||
| ConfigManager::GetInstance().set_ge_initialize_options(options); | |||
| } | |||
| Status CreateSessionAndGraphRunner(bool is_training = true) { | |||
| std::shared_ptr<ge::Session> sess = DfGraphManager::GetInstance().GetGeSession(); | |||
| if (sess == nullptr) { | |||
| transform::SessionOptions options; | |||
| if (is_training) { | |||
| options["ge.trainFlag"] = "1"; | |||
| options["ge.streamNum"] = "100"; | |||
| options["ge.enabledLocalFmkop"] = "1"; | |||
| options["ge.hcomParallel"] = "1"; | |||
| } else { | |||
| options["ge.trainFlag"] = "0"; | |||
| } | |||
| options["ge.enablePrintOpPass"] = "0"; | |||
| sess = transform::GraphRunner::NewSession(options); | |||
| if (sess == nullptr) { | |||
| MS_LOG(ERROR) << "Init data graph failed, because of create Ge session failed"; | |||
| return Status::FAILED; | |||
| } else { | |||
| DfGraphManager::GetInstance().SetGeSession(sess); | |||
| } | |||
| } | |||
| transform::GraphRunnerOptions options; | |||
| options.sess_ptr = sess; | |||
| auto graph_runner = std::make_shared<transform::GraphRunner>(options); | |||
| if (graph_runner == nullptr) { | |||
| MS_LOG(ERROR) << "Create new graph runner failed"; | |||
| return Status::FAILED; | |||
| } else { | |||
| DfGraphManager::GetInstance().SetGraphRunner(graph_runner); | |||
| } | |||
| return Status::SUCCESS; | |||
| } | |||
| bool InitExecDatasetGe(const std::string& queue_name, int64_t size, int64_t batch_size, | |||
| const std::vector<TypePtr>& types, const std::vector<std::vector<int64_t>>& shapes, | |||
| const std::vector<int64_t>& input_indexes, const std::string& phase) { | |||
| std::vector<int64_t> ge_types; | |||
| (void)std::transform(types.begin(), types.end(), std::back_inserter(ge_types), [](const TypePtr& i) -> int64_t { | |||
| return transform::TransformUtil::ConvertDataType(i->type_id()); | |||
| }); | |||
| ConfigManager::GetInstance().set_dataset_mode(DatasetMode::DS_GRAPH_MODE); | |||
| ConfigManager::GetInstance().set_iter_num(size); | |||
| ConfigManager::GetInstance().set_dataset_phase(phase); | |||
| DatasetGraphParam param(queue_name, size, batch_size, ge_types, shapes, input_indexes); | |||
| ConfigManager::GetInstance().set_dataset_param(param); | |||
| if (transform::BuildDatasetGraph(param, phase) != transform::SUCCESS) { | |||
| MS_LOG(ERROR) << "Build dateset graph failed."; | |||
| return false; | |||
| } | |||
| #if ENABLE_TRAIN | |||
| (void)setenv("GE_TRAIN", "1", 1); | |||
| #else | |||
| (void)setenv("GE_TRAIN", "0", 1); | |||
| #endif | |||
| if (CreateSessionAndGraphRunner(static_cast<bool>(ENABLE_TRAIN)) != Status::SUCCESS) { | |||
| MS_LOG(ERROR) << "Create GE Session or GraphRunner failed."; | |||
| return false; | |||
| } | |||
| MS_LOG(INFO) << "DoExecNonInputGraph:" << phase; | |||
| DoExecNonInputGraph(phase); | |||
| return true; | |||
| } | |||
| void ConvertObjectToTensors(const py::dict& dict, TensorOrderMap* const tensors) { | |||
| for (auto item : dict) { | |||
| if ((!py::isinstance<py::str>(item.first))) { | |||
| MS_LOG(WARNING) << "Type of key of py_dict is not string, ignore it."; | |||
| continue; | |||
| } | |||
| std::shared_ptr<Tensor> tensor; | |||
| std::string name = py::cast<std::string>(item.first); | |||
| if (py::isinstance<py::float_>(item.second.attr("default_input"))) { | |||
| // convert float to tensor with shape([1]) | |||
| tensor = std::make_shared<Tensor>(kNumberTypeFloat32, std::vector<int>({1})); | |||
| *(static_cast<float*>(tensor->data_c(true))) = py::cast<float>(item.second.attr("default_input")); | |||
| } else if (py::isinstance<py::int_>(item.second.attr("default_input"))) { | |||
| // convert int to tensor with shape([1]) | |||
| tensor = std::make_shared<Tensor>(kNumberTypeInt32, std::vector<int>({1})); | |||
| *(static_cast<float*>(tensor->data_c(true))) = py::cast<float>(item.second.attr("default_input")); | |||
| } else if (py::hasattr(item.second.attr("default_input"), PYTHON_TENSOR_FLAG)) { | |||
| // cast tensor | |||
| tensor = py::cast<std::shared_ptr<Tensor>>(item.second.attr("default_input")); | |||
| } | |||
| if (tensor == nullptr) { | |||
| MS_LOG(EXCEPTION) << "Get default value for " << name << " failed"; | |||
| } | |||
| (void)tensors->emplace(name, tensor); | |||
| } | |||
| } | |||
| bool AddDFGraph(const std::map<std::string, ExecutorInfoPtr>& info, const py::dict& init_params, | |||
| const std::string& phase, const py::object& broadcast_params) { | |||
| FuncGraphPtr anf_graph = info.at(phase)->func_graph; | |||
| DfGraphConvertor convertor(anf_graph); | |||
| size_t pos = phase.find('.'); | |||
| std::string net_id = ((pos == std::string::npos || pos == phase.size() - 1) ? phase : phase.substr(pos + 1)); | |||
| std::string phase_prefix = phase.substr(0, pos); | |||
| if (phase_prefix == "export") { | |||
| MS_LOG(INFO) << "Set DfGraphConvertor training : false"; | |||
| convertor.set_training(false); | |||
| } | |||
| TensorOrderMap init_tensors{}; | |||
| ConvertObjectToTensors(init_params, &init_tensors); | |||
| (void)convertor.ConvertAllNode().InitParam(init_tensors).BuildGraph(); | |||
| if (broadcast_params != py::none()) { | |||
| if (!py::isinstance<py::dict>(broadcast_params)) { | |||
| MS_LOG(ERROR) << "Invalid broadcast params, it must be py::dict type"; | |||
| return false; | |||
| } | |||
| py::dict broadcast = broadcast_params.cast<py::dict>(); | |||
| if (broadcast.empty()) { | |||
| (void)convertor.GenerateBroadcastGraph(init_tensors); | |||
| } else { | |||
| TensorOrderMap broadcast_tensors{}; | |||
| ConvertObjectToTensors(broadcast, &broadcast_tensors); | |||
| (void)convertor.GenerateBroadcastGraph(broadcast_tensors); | |||
| } | |||
| MS_LOG(INFO) << "Generate broadcast graph with params and broadcast_empty is " << broadcast.empty(); | |||
| } | |||
| (void)convertor.GenerateCheckpointGraph(); | |||
| if (convertor.ErrCode() != 0) { | |||
| DfGraphManager::GetInstance().ClearGraph(); | |||
| MS_LOG(ERROR) << "convert df graph failed, err:" << convertor.ErrCode(); | |||
| return false; | |||
| } | |||
| if (MsContext::GetInstance()->save_graphs_flag()) { | |||
| convertor.DrawComputeGraph(GetFilePathName("ge_graph.dot")); // for debug | |||
| convertor.DrawInitGraph(GetFilePathName("init_graph.dot")); // for debug | |||
| convertor.DrawSaveCheckpointGraph(GetFilePathName("save_checkpoint_graph.dot")); // for debug | |||
| } | |||
| std::string init_graph = "init_subgraph." + net_id; | |||
| std::string checkpoint_name = "save." + net_id; | |||
| if (phase.find("train") != std::string::npos) { | |||
| (void)DfGraphManager::GetInstance().AddGraph(phase, convertor.GetComputeGraph(), {{"ge.exec.variable_acc", "1"}}); | |||
| } else { | |||
| (void)DfGraphManager::GetInstance().AddGraph(phase, convertor.GetComputeGraph()); | |||
| } | |||
| (void)DfGraphManager::GetInstance().AddGraph(init_graph, convertor.GetInitGraph()); | |||
| (void)DfGraphManager::GetInstance().AddGraph(checkpoint_name, convertor.GetSaveCheckpointGraph()); | |||
| (void)DfGraphManager::GetInstance().AddGraph(BROADCAST_GRAPH_NAME, convertor.GetBroadcastGraph()); | |||
| DfGraphManager::GetInstance().SetAnfGraph(checkpoint_name, anf_graph); | |||
| return true; | |||
| } | |||
| FuncGraphPtr BuildDFGraph(const std::map<std::string, ExecutorInfoPtr>& info, const py::dict& init_params, | |||
| const std::string& phase, const py::object& broadcast_params) { | |||
| if (info.count(phase) == 0) { | |||
| MS_LOG(EXCEPTION) << "no phase in executor:" << GetPhasePrefix(phase); | |||
| } | |||
| FuncGraphPtr anf_graph = info.at(phase)->func_graph; | |||
| if (MsContext::GetInstance()->save_graphs_flag()) { | |||
| draw::Draw(GetFilePathName("anf_graph.dot"), anf_graph); // for debug | |||
| DumpIR(GetFilePathName("anf_graph.ir"), anf_graph, true); | |||
| } | |||
| if (!AddDFGraph(info, init_params, phase, broadcast_params)) { | |||
| MS_LOG(ERROR) << "GenConvertor failed"; | |||
| return nullptr; | |||
| } | |||
| #if ENABLE_TRAIN | |||
| (void)setenv("GE_TRAIN", "1", 1); | |||
| #else | |||
| (void)setenv("GE_TRAIN", "0", 1); | |||
| #endif | |||
| if (CreateSessionAndGraphRunner(static_cast<bool>(ENABLE_TRAIN)) != Status::SUCCESS) { | |||
| MS_LOG(ERROR) << "Create GE Session or GraphRunner failed."; | |||
| return nullptr; | |||
| } | |||
| return anf_graph; | |||
| } | |||
| void RunGEInitGraph(const py::dict& init_params, const std::string& phase) { | |||
| MS_LOG(DEBUG) << "ExecInitGraph start."; | |||
| TensorOrderMap inputs_with_name{}; | |||
| ConvertObjectToTensors(init_params, &inputs_with_name); | |||
| std::vector<tensor::TensorPtr> inputs; | |||
| (void)std::transform(inputs_with_name.begin(), inputs_with_name.end(), std::back_inserter(inputs), | |||
| [](const std::pair<std::string, tensor::TensorPtr>& item) { return item.second; }); | |||
| std::vector<GeTensorPtr> ge_tensors = TransformUtil::ConvertInputTensors(inputs, kOpFormat_NCHW); | |||
| if (ge_tensors.size() != inputs.size()) { | |||
| MS_LOG(ERROR) << "Args convert to ge tensor error."; | |||
| return; | |||
| } | |||
| MS_LOG(DEBUG) << "Run graph begin, inputs size is: " << inputs.size() << "."; | |||
| std::vector<GeTensorPtr> ge_outputs; | |||
| transform::RunOptions run_options; | |||
| run_options.name = phase; | |||
| if (DfGraphManager::GetInstance().GetGraphByName(phase) == nullptr) { | |||
| MS_LOG(WARNING) << "Can not find " << phase << " sub graph, don't need data init subgraph in INFER mode."; | |||
| return; | |||
| } | |||
| auto graph_runner = DfGraphManager::GetInstance().GetGraphRunner(); | |||
| if (graph_runner == nullptr) { | |||
| MS_LOG(EXCEPTION) << "Can not found GraphRunner."; | |||
| } | |||
| { | |||
| // Release GIL before calling into (potentially long-running) C++ code | |||
| py::gil_scoped_release release; | |||
| Status ret = graph_runner->RunGraph(run_options, ge_tensors, &ge_outputs); | |||
| if (ret != Status::SUCCESS) { | |||
| MS_LOG(EXCEPTION) << "Exec " << phase << " graph failed."; | |||
| } | |||
| MS_LOG(INFO) << "Exec " << phase << " graph success."; | |||
| if ((ConfigManager::GetInstance().parallel_strategy() == ParallelStrategy::DISTRIBUTION) && | |||
| (DfGraphManager::GetInstance().GetGraphByName(BROADCAST_GRAPH_NAME) != nullptr)) { | |||
| run_options.name = BROADCAST_GRAPH_NAME; | |||
| ret = graph_runner->RunGraph(run_options, ge_tensors, &ge_outputs); | |||
| if (ret != Status::SUCCESS) { | |||
| MS_LOG(EXCEPTION) << "Exec BROADCAST_GRAPH_NAME failed."; | |||
| } | |||
| MS_LOG(INFO) << "Exec broadcast graph success."; | |||
| } | |||
| } | |||
| } | |||
| py::object ExtractGeneralCnodeRet(const AbstractBasePtr& cnode_data, const py::tuple& data, size_t* count) { | |||
| MS_EXCEPTION_IF_NULL(cnode_data); | |||
| if (*count >= data.size()) { | |||
| MS_LOG(EXCEPTION) << "The number of elements in the outputs : " << data.size() | |||
| << " less than the number of elements required. "; | |||
| } | |||
| if (cnode_data->isa<AbstractTensor>()) { | |||
| BaseShapePtr shape = cnode_data->BuildShape(); | |||
| auto shape_act = shape->cast<abstract::ShapePtr>()->shape(); | |||
| Tensor tensor_exp = py::cast<Tensor>(data[*count]); | |||
| if (shape_act != tensor_exp.shape()) { | |||
| MS_LOG(EXCEPTION) << "The shape of the tensor returned from GE is not the same as " | |||
| "the shape of the tensor derived from ME."; | |||
| } | |||
| return data[(*count)++]; | |||
| } | |||
| if (!cnode_data->isa<AbstractTuple>()) { | |||
| MS_LOG(EXCEPTION) << "The output of operator in the final anf graph could " | |||
| << "only be a tensor or a tuple of tensor, but got " << cnode_data->BuildValue()->ToString() | |||
| << "."; | |||
| } | |||
| auto data_tp = cnode_data->cast<AbstractTuplePtr>(); | |||
| auto elements = data_tp->elements(); | |||
| size_t size = data_tp->size(); | |||
| py::tuple tp = py::tuple(size); | |||
| for (size_t i = 0; i < size; i++) { | |||
| tp[i] = ExtractGeneralCnodeRet(elements[i], data, count); | |||
| } | |||
| return std::move(tp); | |||
| } | |||
| py::object StructureOutput(const AnfNodePtr& output_node, const py::tuple& data, size_t* count) { | |||
| MS_EXCEPTION_IF_NULL(output_node); | |||
| if (output_node->isa<ValueNode>()) { | |||
| return ValuePtrToPyData(GetValueNode(output_node)); | |||
| } | |||
| if (*count >= data.size()) { | |||
| MS_LOG(EXCEPTION) << "The number of elements in the outputs : " << data.size() | |||
| << " less than the number of elements required. "; | |||
| } | |||
| if (output_node->isa<Parameter>()) { | |||
| return data[(*count)++]; | |||
| } | |||
| auto output_c = output_node->cast<CNodePtr>(); | |||
| if (output_c == nullptr) { | |||
| MS_LOG(EXCEPTION) << "The final anf graph could only have constant, parameter, and operator, but got " | |||
| << output_node->ToString(); | |||
| } | |||
| if (output_c->IsApply(prim::kPrimMakeTuple)) { | |||
| auto input_list = output_c->inputs(); | |||
| size_t size = input_list.size(); | |||
| py::tuple tp = py::tuple(size - 1); | |||
| for (size_t i = 1; i < size; i++) { | |||
| tp[i - 1] = StructureOutput(input_list[i], data, count); | |||
| } | |||
| return std::move(tp); | |||
| } | |||
| if (output_c->IsApply(prim::kPrimDepend)) { | |||
| return StructureOutput(output_c->input(1), data, count); | |||
| } | |||
| return ExtractGeneralCnodeRet(output_c->abstract(), data, count); | |||
| } | |||
| std::shared_ptr<py::object> DoExecGraph(const FuncGraphPtr& graph, const std::vector<MeTensorPtr>& inputs, | |||
| const std::string& phase) { | |||
| std::vector<GeTensorPtr> ge_tensors = TransformUtil::ConvertInputTensors(inputs, kOpFormat_NCHW); | |||
| if (ge_tensors.size() != inputs.size()) { | |||
| MS_LOG(ERROR) << "args convert to ge tensor error"; | |||
| return nullptr; | |||
| } | |||
| std::vector<GeTensorPtr> ge_outputs; | |||
| transform::RunOptions run_options; | |||
| run_options.name = phase; | |||
| auto graph_runner = DfGraphManager::GetInstance().GetGraphRunner(); | |||
| if (graph_runner == nullptr) { | |||
| MS_LOG(ERROR) << "Can not found GraphRunner"; | |||
| return nullptr; | |||
| } | |||
| { | |||
| // Release GIL before calling into (potentially long-running) C++ code | |||
| py::gil_scoped_release release; | |||
| MS_LOG(DEBUG) << "Run graph begin, inputs size is: " << inputs.size(); | |||
| Status ret = graph_runner->RunGraph(run_options, ge_tensors, &ge_outputs); | |||
| MS_LOG(DEBUG) << "Run graph finish, outputs size is: " << ge_outputs.size(); | |||
| if (ret != Status::SUCCESS) { | |||
| MS_LOG(ERROR) << "Exec graph failed"; | |||
| return nullptr; | |||
| } | |||
| } | |||
| std::vector<MeTensorPtr> me_outputs = TransformUtil::ConvertGeTensors(ge_outputs); | |||
| if (me_outputs.size() != ge_outputs.size()) { | |||
| MS_LOG(ERROR) << "Convert output Ge tensor to Me tensor failed"; | |||
| } | |||
| py::tuple outputs(me_outputs.size()); | |||
| for (std::size_t i = 0; i < outputs.size(); i++) { | |||
| outputs[i] = *me_outputs[i]; | |||
| } | |||
| std::shared_ptr<py::object> ret = nullptr; | |||
| #ifdef ENABLE_GE | |||
| AnfNodePtr root = graph->get_return(); | |||
| MS_EXCEPTION_IF_NULL(root); | |||
| AbstractBasePtr output = root->abstract(); | |||
| size_t count = 0; | |||
| py::object oj = StructureOutput(output, outputs, &count); | |||
| ret = std::make_shared<py::object>(oj); | |||
| #else | |||
| if (outputs.size() == 1) { | |||
| ret = std::make_shared<py::object>(outputs[0]); | |||
| } else { | |||
| ret = std::make_shared<py::object>(outputs); | |||
| } | |||
| #endif | |||
| return ret; | |||
| } | |||
| void ProcessGeArg(const std::map<std::string, ExecutorInfoPtr>& info, const py::tuple& args, const std::string& phase, | |||
| std::vector<tensor::TensorPtr>* inputs) { | |||
| // check the arg and use the ExecutorPy args | |||
| std::size_t size = args.size(); | |||
| if (info.count(phase) == 0) { | |||
| MS_LOG(EXCEPTION) << "no phase in executor:" << GetPhasePrefix(phase); | |||
| } | |||
| auto arg_size = info.at(phase)->arg_list_size; | |||
| if (size != arg_size) { | |||
| MS_LOG(EXCEPTION) << "The real arg num : size = " << size << ". graph_arg_size = " << arg_size; | |||
| } | |||
| // process the first args of tensor | |||
| // only in Dataset Feed Mode, fp_bp graph need input tensors | |||
| if (ConfigManager::GetInstance().dataset_mode() == DS_FEED_MODE) { | |||
| for (std::size_t i = 0; i < size; i++) { | |||
| ValuePtr converted = nullptr; | |||
| bool succ = parse::ConvertData(args[i], &converted); | |||
| if (!succ) { | |||
| MS_LOG(EXCEPTION) << "args convert error"; | |||
| } | |||
| if (converted->isa<tensor::Tensor>()) { | |||
| (*inputs).push_back(converted->cast<tensor::TensorPtr>()); | |||
| } else { | |||
| MS_LOG(EXCEPTION) << "args, " << converted->ToString() << " is not tensor"; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| py::object ExecDFGraph(const std::map<std::string, ExecutorInfoPtr>& info, const py::tuple& args, | |||
| const std::string& phase) { | |||
| std::string phase_prefix = GetPhasePrefix(phase); | |||
| if (phase_prefix == "save") { | |||
| DoExecNonInputGraph(phase); | |||
| ConfigManager::GetInstance().ResetConfig(); | |||
| return py::none(); | |||
| } | |||
| if (info.count(phase) == 0) { | |||
| MS_LOG(EXCEPTION) << "has no phase:" << phase; | |||
| } | |||
| FuncGraphPtr anf_graph = info.at(phase)->func_graph; | |||
| #if (!defined ENABLE_GE) || (defined ENABLE_INFER) | |||
| // Now don't use the graph because the exec ge function don't take effect | |||
| MS_EXCEPTION_IF_NULL(info.at(phase)->func_graph); | |||
| if (ENABLE_TRAIN != info.at(phase)->func_graph->flags()["training"]) { | |||
| MS_LOG(ERROR) << "Graph training mode mismatch mode of libraries"; | |||
| ConfigManager::GetInstance().ResetConfig(); | |||
| return py::none(); | |||
| } | |||
| #endif | |||
| std::shared_ptr<py::object> ret_val = std::make_shared<py::object>(); | |||
| // We will not execute graph when output is constant or just input itself. | |||
| if (IsGraphOutputValueNodeOrParameter(info.at(phase)->func_graph->output(), args, ret_val)) { | |||
| ConfigManager::GetInstance().ResetConfig(); | |||
| return *ret_val; | |||
| } | |||
| std::vector<tensor::TensorPtr> inputs; | |||
| ProcessGeArg(info, args, phase, &inputs); | |||
| std::shared_ptr<py::object> ret = DoExecGraph(anf_graph, inputs, phase); | |||
| ConfigManager::GetInstance().ResetConfig(); | |||
| if (ret != nullptr) { | |||
| return *ret; | |||
| } else { | |||
| MS_LOG(EXCEPTION) << "exec graph failed"; | |||
| } | |||
| } | |||
| void ExportDFGraph(const std::string& file_name, const std::string& phase) { | |||
| MS_LOG(DEBUG) << "ExportGraph Begin"; | |||
| transform::DfGraphWrapperPtr wrap_ptr = DfGraphManager::GetInstance().GetGraphByName(phase); | |||
| if (wrap_ptr == nullptr) { | |||
| MS_LOG(ERROR) << "Get graph form DfGraphManager failed!"; | |||
| return; | |||
| } | |||
| transform::DfGraphPtr ge_graph = wrap_ptr->graph_ptr_; | |||
| if (nullptr == ge_graph) { | |||
| MS_LOG(ERROR) << "The export graph is null"; | |||
| return; | |||
| } | |||
| (void)ge_graph->SaveToFile(file_name); | |||
| MS_LOG(DEBUG) << "ExportGraph End"; | |||
| } | |||
| } // namespace pipeline | |||
| } // namespace mindspore | |||
| @@ -0,0 +1,57 @@ | |||
| /** | |||
| * 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_PIPELINE_PIPELINE_GE_H_ | |||
| #define MINDSPORE_CCSRC_PIPELINE_PIPELINE_GE_H_ | |||
| #include <vector> | |||
| #include <utility> | |||
| #include <string> | |||
| #include <memory> | |||
| #include <unordered_map> | |||
| #include <map> | |||
| #include <mutex> | |||
| #include "pybind11/pybind11.h" | |||
| #include "pipeline/base.h" | |||
| #include "operator/ops.h" | |||
| namespace mindspore { | |||
| namespace pipeline { | |||
| namespace py = pybind11; | |||
| void SetGeOption(const std::map<std::string, std::string>& options); | |||
| void RunGEInitGraph(const py::dict& init_params, const std::string& phase); | |||
| py::object ExecDFGraph(const std::map<std::string, ExecutorInfoPtr>& info, const py::tuple& args, | |||
| const std::string& phase = "train"); | |||
| FuncGraphPtr BuildDFGraph(const std::map<std::string, ExecutorInfoPtr>& info, const py::dict& init_params, | |||
| const std::string& phase, const py::object& broadcast_params = {}); | |||
| // init and exec dataset sub graph for GE backend | |||
| bool InitExecDatasetGe(const std::string& queue_name, int64_t size, int64_t batch_size, | |||
| const std::vector<TypePtr>& types, const std::vector<std::vector<int64_t>>& shapes, | |||
| const std::vector<int64_t>& input_indexes, const std::string& phase); | |||
| void ExportDFGraph(const std::string& file_name, const std::string& phase); | |||
| } // namespace pipeline | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_PIPELINE_PIPELINE_GE_H_ | |||
| @@ -25,19 +25,13 @@ | |||
| #include "pipeline/parse/data_converter.h" | |||
| #include "operator/ops.h" | |||
| #include "utils/graph_utils.h" | |||
| #include "transform/convert.h" | |||
| #include "optimizer/ad/dfunctor.h" | |||
| #include "vm/segment_runner.h" | |||
| #include "utils/context/ms_context.h" | |||
| #include "transform/df_graph_manager.h" | |||
| #include "device/kernel_runtime_manager.h" | |||
| namespace mindspore { | |||
| // namespace to support opmap definition | |||
| namespace pipeline { | |||
| using MethodMap = std::unordered_map<int, std::unordered_map<std::string, Any>>; | |||
| MethodMap& GetMethodMap() { | |||
| static MethodMap method_map = {{kObjectTypeString, | |||
| { | |||
| @@ -255,28 +249,5 @@ void Resource::Clean() { | |||
| trace::ClearTraceStack(); | |||
| is_cleaned_ = true; | |||
| } | |||
| void ReleaseGeTsd() { | |||
| auto context_ptr = MsContext::GetInstance(); | |||
| if (context_ptr != nullptr) { | |||
| (void)context_ptr->FinalizeGe(true); | |||
| (void)context_ptr->CloseTsd(true); | |||
| } | |||
| } | |||
| void ClearResAtexit() { | |||
| MS_LOG(DEBUG) << "pipeline clear all resource"; | |||
| device::KernelRuntimeManager::Instance().ClearRuntimeResource(); | |||
| transform::DfGraphManager::GetInstance().ClearGraph(); | |||
| ad::g_k_prims.clear(); | |||
| abstract::ClearPrimEvaluatorMap(); | |||
| compile::ClearConvertCache(); | |||
| transform::DfGraphConvertor::get_adpt_map().clear(); | |||
| pipeline::GetMethodMap().clear(); | |||
| pipeline::ExecutorPy::ClearRes(); | |||
| ReleaseGeTsd(); | |||
| } | |||
| } // namespace pipeline | |||
| } // namespace mindspore | |||
| @@ -44,6 +44,10 @@ const char kOutput[] = "output"; | |||
| class InferenceResource; | |||
| using MethodMap = std::unordered_map<int, std::unordered_map<std::string, Any>>; | |||
| MethodMap& GetMethodMap(); | |||
| class ResourceBase { | |||
| public: | |||
| ResourceBase() { manager_ = MakeManager(); } | |||
| @@ -110,9 +114,6 @@ class Resource : public ResourceBase { | |||
| using ResourcePtr = std::shared_ptr<pipeline::Resource>; | |||
| void ClearResAtexit(); | |||
| void ReleaseGeTsd(); | |||
| } // namespace pipeline | |||
| } // namespace mindspore | |||
| @@ -21,7 +21,7 @@ | |||
| #include "pre_activate/ascend/ir_fission/bn_grad_split.h" | |||
| #include "pre_activate/ascend/ir_fusion/fused_batch_norm_fusion.h" | |||
| #include "pre_activate/ascend/ir_fission/layer_norm_grad_split.h" | |||
| #include "pre_activate/ascend/ir_fusion/allreduce_fusion.h" | |||
| #include "pre_activate/common/ir_fusion/allreduce_fusion.h" | |||
| #include "pre_activate/ascend/ir_fusion/square_sum_fusion.h" | |||
| #include "pre_activate/ascend/ir_fusion/clip_by_norm_no_div_square_sum_fusion.h" | |||
| #include "pre_activate/ascend/ir_fusion/lamb_update_with_lr_rule_fusion.h" | |||
| @@ -237,11 +237,11 @@ CNodePtr CreateFusionOp(const std::vector<AnfNodePtr> &inputs_list, const std::v | |||
| std::vector<std::string> input_names; | |||
| for (uint8_t i = 0; i < inputs_list.size(); i++) { | |||
| input_names.emplace_back("input" + to_string(i)); | |||
| input_names.emplace_back("input" + std::to_string(i)); | |||
| } | |||
| std::vector<std::string> output_names; | |||
| for (uint8_t i = 0; i < outputs_list.size(); i++) { | |||
| output_names.emplace_back("output" + to_string(i)); | |||
| output_names.emplace_back("output" + std::to_string(i)); | |||
| } | |||
| ValuePtr input_names_v = MakeValue(input_names); | |||
| @@ -13,7 +13,7 @@ | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #include "pre_activate/ascend/ir_fusion/allreduce_fusion.h" | |||
| #include "pre_activate/common/ir_fusion/allreduce_fusion.h" | |||
| #include <vector> | |||
| #include <string> | |||
| @@ -13,8 +13,8 @@ | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #ifndef MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FUSION_ALLREDUCE_FUSION_H_ | |||
| #define MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FUSION_ALLREDUCE_FUSION_H_ | |||
| #ifndef MINDSPORE_CCSRC_PRE_ACTIVATE_COMMON_IR_FUSION_ALLREDUCE_FUSION_H_ | |||
| #define MINDSPORE_CCSRC_PRE_ACTIVATE_COMMON_IR_FUSION_ALLREDUCE_FUSION_H_ | |||
| #include <vector> | |||
| #include "pre_activate/common/pass.h" | |||
| @@ -46,4 +46,4 @@ class AllReduceFusion : public Pass { | |||
| }; | |||
| } // namespace opt | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FUSION_ALLREDUCE_FUSION_H_ | |||
| #endif // MINDSPORE_CCSRC_PRE_ACTIVATE_COMMON_IR_FUSION_ALLREDUCE_FUSION_H_ | |||
| @@ -16,7 +16,7 @@ | |||
| #include "predict/converter/kernel2ms.h" | |||
| #include <algorithm> | |||
| #include "transform/convert.h" | |||
| #include "ir/anf.h" | |||
| #include "predict/converter/lite_model/op_attr_packer.h" | |||
| #include "mindspore/ccsrc/operator/ops.h" | |||
| @@ -135,7 +135,7 @@ void Kernel2Ms::GetRealInpoutsPtr(const AnfNodePtr &node, std::vector<AnfNodePtr | |||
| if (node->isa<CNode>()) { | |||
| auto c_node = node->cast<CNodePtr>(); | |||
| MS_EXCEPTION_IF_NULL(c_node); | |||
| std::string c_node_name = transform::GetCNodeFuncName(c_node); | |||
| std::string c_node_name = GetCNodeFuncName(c_node); | |||
| if (c_node_name == prim::kPrimTupleGetItem->name()) { | |||
| auto v_node = c_node->inputs()[kTupleGetItemIndex]->cast<ValueNodePtr>(); | |||
| MS_EXCEPTION_IF_NULL(v_node); | |||
| @@ -321,7 +321,7 @@ bool Kernel2Ms::SetGraphInputTensors(const KernelGraphPtr &kernel_graph_ptr, con | |||
| } | |||
| for (const auto &input_node : kernel_graph_ptr->inputs()) { | |||
| if (input_node->isa<Parameter>()) { | |||
| ParameterPtr pk_node = dynamic_pointer_cast<Parameter>(input_node); | |||
| ParameterPtr pk_node = std::dynamic_pointer_cast<Parameter>(input_node); | |||
| TensorPtr device_tensor; | |||
| if (convert_mode_ == kConvertCpuMode) { | |||
| device_tensor = predict::utils::GetParaCpuTensor(input_node); | |||
| @@ -0,0 +1,67 @@ | |||
| /** | |||
| * 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_PYNATIVE_BASE_H_ | |||
| #define MINDSPORE_CCSRC_PYNATIVE_BASE_H_ | |||
| #include <vector> | |||
| #include <utility> | |||
| #include <string> | |||
| #include <memory> | |||
| #include <unordered_map> | |||
| #include <unordered_set> | |||
| #include "pybind11/pybind11.h" | |||
| #include "ir/primitive.h" | |||
| #include "pipeline/static_analysis/abstract_value.h" | |||
| namespace mindspore { | |||
| namespace pynative { | |||
| namespace py = pybind11; | |||
| enum PynativeStatusCode { | |||
| PYNATIVE_SUCCESS = 0, | |||
| PYNATIVE_OP_NOT_IMPLEMENTED_ERR = 1, | |||
| PYNATIVE_OP_INPUTS_ERR = 2, | |||
| PYNATIVE_OP_PARAMS_ERR = 3, | |||
| PYNATIVE_OP_ATTRS_ERR = 4, | |||
| PYNATIVE_GRAPH_MANAGER_ERR = 5, | |||
| PYNATIVE_GRAPH_GE_BUILD_ERR = 6, | |||
| PYNATIVE_GRAPH_GE_RUN_ERR = 7, | |||
| PYNATIVE_UNKNOWN_STATE = 0XFF | |||
| }; | |||
| enum RunOpArgsEnum { PY_PRIM = 0, PY_NAME, PY_INPUTS, PY_INPUT_MASK, PY_ARGS_NUM }; | |||
| struct OpExecInfo { | |||
| PrimitivePyPtr py_primitive; | |||
| std::string op_name; | |||
| AbstractBasePtr abstract; | |||
| py::tuple op_inputs; | |||
| py::tuple inputs_mask; | |||
| py::dict op_attrs; | |||
| }; | |||
| using OpExecInfoPtr = std::shared_ptr<OpExecInfo>; | |||
| OpExecInfoPtr GenerateOpExecInfo(const py::args& args); | |||
| const std::unordered_set<std::string> ignore_infer_prim = {"partial"}; | |||
| } // namespace pynative | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_PYNATIVE_BASE_H_ | |||
| @@ -29,16 +29,18 @@ | |||
| #include "pipeline/static_analysis/prim.h" | |||
| #include "session/session_factory.h" | |||
| #include "pynative/base.h" | |||
| #ifdef ENABLE_GE | |||
| #include "pynative/pynative_execute_ge.h" | |||
| #endif | |||
| const char SINGLE_OP_GRAPH[] = "single_op_graph"; | |||
| // primitive unable to infer value for constant input in pynative mode | |||
| const std::unordered_set<std::string> ignore_infer_prim = {"partial"}; | |||
| const std::unordered_set<std::string> vm_operators = {"partial", "depend"}; | |||
| namespace mindspore { | |||
| namespace pynative { | |||
| using transform::GraphRunner; | |||
| using transform::GraphRunnerOptions; | |||
| using transform::OperatorPtr; | |||
| inline ValuePtr PyAttrValue(const py::object& obj) { | |||
| ValuePtr converted_ret = nullptr; | |||
| bool converted = parse::ConvertData(obj, &converted_ret); | |||
| @@ -48,32 +50,12 @@ inline ValuePtr PyAttrValue(const py::object& obj) { | |||
| return converted_ret; | |||
| } | |||
| MeTensorPtr ConvertPyObjToTensor(const py::object& obj) { | |||
| MeTensorPtr me_tensor_ptr = nullptr; | |||
| if (py::isinstance<MeTensor>(obj)) { | |||
| me_tensor_ptr = py::cast<MeTensorPtr>(obj); | |||
| } else if (py::isinstance<py::tuple>(obj)) { | |||
| me_tensor_ptr = std::make_shared<MeTensor>(py::cast<py::tuple>(obj), nullptr); | |||
| } else if (py::isinstance<py::float_>(obj)) { | |||
| me_tensor_ptr = std::make_shared<MeTensor>(py::cast<py::float_>(obj), nullptr); | |||
| } else if (py::isinstance<py::int_>(obj)) { | |||
| me_tensor_ptr = std::make_shared<MeTensor>(py::cast<py::int_>(obj), nullptr); | |||
| } else if (py::isinstance<py::list>(obj)) { | |||
| me_tensor_ptr = std::make_shared<MeTensor>(py::cast<py::list>(obj), nullptr); | |||
| } else if (py::isinstance<py::array>(obj)) { | |||
| me_tensor_ptr = std::make_shared<MeTensor>(py::cast<py::array>(obj), nullptr); | |||
| } else { | |||
| MS_LOG(EXCEPTION) << "run op inputs type is invalid!"; | |||
| } | |||
| return me_tensor_ptr; | |||
| } | |||
| void PynativeInfer(const PrimitivePyPtr& prim, const py::tuple& py_args, OpExecInfo* const op_exec_info) { | |||
| size_t size = py_args.size(); | |||
| AbstractBasePtrList args_spec_list; | |||
| for (size_t i = 0; i < size; i++) { | |||
| ValuePtr input_value = PyAttrValue(py_args[i]); | |||
| if (py::isinstance<MeTensor>(py_args[i])) { | |||
| if (py::isinstance<tensor::Tensor>(py_args[i])) { | |||
| args_spec_list.emplace_back(abstract::FromValueInside(input_value, true)); | |||
| } else { | |||
| args_spec_list.emplace_back(abstract::FromValueInside(input_value, false)); | |||
| @@ -140,241 +122,6 @@ std::string GetSingleOpGraphInfo(const OpExecInfoPtr& op_exec_info) { | |||
| return graph_info; | |||
| } | |||
| bool SetInputsForSingleOpGraph(const OpExecInfoPtr& op_exec_info, const std::vector<GeTensorPtr>& inputs, | |||
| const OperatorPtr& op, std::vector<GeOperator>* graph_input_nodes) { | |||
| MS_EXCEPTION_IF_NULL(op_exec_info); | |||
| MS_EXCEPTION_IF_NULL(graph_input_nodes); | |||
| auto op_inputs = op_exec_info->op_inputs; | |||
| std::string op_name = op_exec_info->op_name; | |||
| transform::OpAdapterPtr adapter = transform::DfGraphConvertor::FindAdapter(op_name, true); | |||
| if (adapter == nullptr) { | |||
| return false; | |||
| } | |||
| int op_input_idx = 1; | |||
| size_t size = inputs.size(); | |||
| for (size_t i = 0; i < size; i++) { | |||
| if (inputs[i] == nullptr) { | |||
| continue; | |||
| } | |||
| auto const_op = std::make_shared<transform::Constant>(); | |||
| MS_EXCEPTION_IF_NULL(const_op); | |||
| (void)const_op->set_attr_value(*inputs[i]); | |||
| MeTensorPtr me_tensor_ptr = ConvertPyObjToTensor(op_inputs[i]); | |||
| MS_EXCEPTION_IF_NULL(me_tensor_ptr); | |||
| auto const_op_desc = | |||
| transform::TransformUtil::GetGeTensorDesc(me_tensor_ptr->shape_c(), me_tensor_ptr->data_type(), kOpFormat_NCHW); | |||
| if (const_op_desc == nullptr) { | |||
| MS_LOG(ERROR) << "Create variable " << op_name << " ouptut descriptor failed!"; | |||
| return false; | |||
| } | |||
| auto pointer_cast_const_op = std::static_pointer_cast<transform::Constant>(const_op); | |||
| MS_EXCEPTION_IF_NULL(pointer_cast_const_op); | |||
| (void)pointer_cast_const_op->update_output_desc_y(*const_op_desc); | |||
| auto& input_map = adapter->getInputMap(); | |||
| if (input_map.find(op_input_idx) == input_map.end()) { | |||
| continue; | |||
| } | |||
| if (adapter->setInput(op, op_input_idx++, const_op)) { | |||
| MS_LOG(ERROR) << "fail to set params, index is " << op_input_idx; | |||
| return false; | |||
| } | |||
| graph_input_nodes->push_back(*const_op); | |||
| } | |||
| return true; | |||
| } | |||
| bool BuildSingleOpGraph(const OpExecInfoPtr& op_exec_info, const std::vector<GeTensorPtr>& inputs, | |||
| const std::unordered_map<std::string, ValuePtr>& attrs, const GeGraphPtr& graph) { | |||
| MS_EXCEPTION_IF_NULL(op_exec_info); | |||
| std::string op_name = op_exec_info->op_name; | |||
| auto op_inputs = op_exec_info->op_inputs; | |||
| transform::OpAdapterPtr adapter = transform::DfGraphConvertor::FindAdapter(op_name, true); | |||
| if (adapter == nullptr) { | |||
| MS_LOG(ERROR) << "Unable to find Adapter for " << ((std::string)py::str(op_name)); | |||
| return false; | |||
| } | |||
| OperatorPtr op = adapter->generate(op_name); | |||
| MS_EXCEPTION_IF_NULL(op); | |||
| std::vector<GeOperator> graph_input_nodes; | |||
| // hold param nodes after setting input and output for the graph | |||
| // set input | |||
| if (!SetInputsForSingleOpGraph(op_exec_info, inputs, op, &graph_input_nodes)) { | |||
| return false; | |||
| } | |||
| // set attributes | |||
| for (auto attr : attrs) { | |||
| (void)adapter->setAttr(op, attr.first, attr.second); | |||
| } | |||
| // set default attributes | |||
| auto extra_attrs = adapter->GetExtraAttr(); | |||
| for (auto attr : extra_attrs) { | |||
| (void)adapter->setAttr(op, attr.first, attr.second); | |||
| } | |||
| // set input attributes | |||
| auto& input_attr_map = adapter->getInputAttrMap(); | |||
| for (auto& it : input_attr_map) { | |||
| if (op_inputs.size() < it.first) { | |||
| continue; | |||
| } | |||
| auto const_value = PyAttrValue(op_inputs[it.first - 1]); | |||
| if (const_value->isa<None>()) { | |||
| continue; | |||
| } | |||
| it.second.set_attr(op, const_value); | |||
| } | |||
| // construct output data nodes | |||
| std::vector<GeOperator> graph_outputs{*op}; | |||
| // set input and output nodes for the graph | |||
| MS_EXCEPTION_IF_NULL(graph); | |||
| (void)graph->SetInputs(graph_input_nodes).SetOutputs(graph_outputs); | |||
| MS_LOG(INFO) << "BuildSingleOpGraph done"; | |||
| return true; | |||
| } | |||
| void ToTensorPtr(const OpExecInfoPtr op_exec_info, std::vector<GeTensorPtr>* const inputs) { | |||
| MS_EXCEPTION_IF_NULL(inputs); | |||
| MS_EXCEPTION_IF_NULL(op_exec_info); | |||
| auto op_inputs = op_exec_info->op_inputs; | |||
| size_t size = op_inputs.size(); | |||
| for (size_t i = 0; i < size; i++) { | |||
| if (py::isinstance<py::none>(op_inputs[i])) { | |||
| inputs->emplace_back(nullptr); | |||
| continue; | |||
| } | |||
| MeTensorPtr me_tensor_ptr = ConvertPyObjToTensor(op_inputs[i]); | |||
| auto ge_tensor_ptr = transform::TransformUtil::ConvertTensor(me_tensor_ptr, kOpFormat_NCHW); | |||
| if (ge_tensor_ptr == nullptr) { | |||
| MS_LOG(EXCEPTION) << "convert inputs to GE tensor failed in op " << op_exec_info->op_name << "."; | |||
| } | |||
| // set inputs for operator to build single node graph | |||
| inputs->push_back(ge_tensor_ptr); | |||
| } | |||
| } | |||
| PynativeStatusCode ConvertAttributes(const OpExecInfoPtr& op_exec_info, const std::vector<GeTensorPtr>& inputs) { | |||
| MS_EXCEPTION_IF_NULL(op_exec_info); | |||
| auto op_attrs = op_exec_info->op_attrs; | |||
| std::unordered_map<std::string, ValuePtr> attrs{}; | |||
| for (auto& item : op_attrs) { | |||
| if (!py::isinstance<py::str>(item.first)) { | |||
| MS_LOG(ERROR) << "type error in py dict convert"; | |||
| return PYNATIVE_OP_ATTRS_ERR; | |||
| } | |||
| std::string name = py::cast<std::string>(item.first); | |||
| auto attr_value = PyAttrValue(py::cast<py::object>(item.second)); | |||
| (void)attrs.emplace(name, attr_value); | |||
| } | |||
| // build graph | |||
| GeGraphPtr graph = std::make_shared<GeGraph>(op_exec_info->op_name); | |||
| if (BuildSingleOpGraph(op_exec_info, inputs, attrs, graph) == false) { | |||
| MS_LOG(ERROR) << "Fail to BuildSingleOpGraph"; | |||
| return PYNATIVE_GRAPH_GE_BUILD_ERR; | |||
| } | |||
| // add the single op graph into the graph manager, which will be iterated by session. | |||
| transform::Status ret = | |||
| transform::DfGraphManager::GetInstance().AddGraph(SINGLE_OP_GRAPH, std::shared_ptr<transform::DfGraph>(graph)); | |||
| if (ret != transform::SUCCESS) { | |||
| MS_LOG(ERROR) << "Fail to AddGraph into graph manager"; | |||
| return PYNATIVE_GRAPH_MANAGER_ERR; | |||
| } | |||
| return PYNATIVE_SUCCESS; | |||
| } | |||
| std::vector<MeTensorPtr> ConvertOutputTensors(const OpExecInfoPtr& op_exec_info, | |||
| const std::vector<GeTensorPtr>& ge_tensors) { | |||
| std::vector<MeTensorPtr> outputs; | |||
| AbstractBasePtr abs_base = op_exec_info->abstract; | |||
| std::vector<std::vector<int>> shapes; | |||
| if (abs_base != nullptr && abs_base->isa<abstract::AbstractTensor>()) { | |||
| auto arg_tensor = dyn_cast<abstract::AbstractTensor>(abs_base); | |||
| shapes.emplace_back(arg_tensor->shape()->shape()); | |||
| outputs = transform::TransformUtil::ConvertGeTensors(ge_tensors, shapes); | |||
| return outputs; | |||
| } | |||
| if (abs_base != nullptr && abs_base->isa<abstract::AbstractTuple>()) { | |||
| auto arg_tuple = dyn_cast<abstract::AbstractTuple>(abs_base); | |||
| size_t len = arg_tuple->size(); | |||
| for (size_t i = 0; i < len; i++) { | |||
| if (arg_tuple->elements()[i]->isa<abstract::AbstractTensor>()) { | |||
| auto arg_tensor = dyn_cast<abstract::AbstractTensor>(arg_tuple->elements()[i]); | |||
| shapes.emplace_back(arg_tensor->shape()->shape()); | |||
| } | |||
| } | |||
| outputs = transform::TransformUtil::ConvertGeTensors(ge_tensors, shapes); | |||
| return outputs; | |||
| } | |||
| for (auto& it : ge_tensors) { | |||
| auto tensor = transform::TransformUtil::ConvertGeTensor(it); | |||
| if (tensor != nullptr) { | |||
| outputs.emplace_back(tensor); | |||
| } | |||
| } | |||
| return outputs; | |||
| } | |||
| py::object RunOpInGE(const OpExecInfoPtr& op_exec_info, PynativeStatusCode* status) { | |||
| MS_LOG(INFO) << "RunOpInGe start"; | |||
| MS_EXCEPTION_IF_NULL(op_exec_info); | |||
| MS_EXCEPTION_IF_NULL(status); | |||
| // returns a null py::tuple on error | |||
| py::tuple err_ret(0); | |||
| auto op_name = op_exec_info->op_name; | |||
| transform::OpAdapterPtr adapter = transform::DfGraphConvertor::FindAdapter(op_name, true); | |||
| if (adapter == nullptr) { | |||
| MS_LOG(ERROR) << "Unable to find GE Adapter for " << ((std::string)py::str(op_name)); | |||
| *status = PYNATIVE_OP_NOT_IMPLEMENTED_ERR; | |||
| return std::move(err_ret); | |||
| } | |||
| std::vector<GeTensorPtr> inputs{}; | |||
| ToTensorPtr(op_exec_info, &inputs); | |||
| // convert me attr to ge AttrValue | |||
| PynativeStatusCode ret = ConvertAttributes(op_exec_info, inputs); | |||
| if (ret != PYNATIVE_SUCCESS) { | |||
| *status = ret; | |||
| return std::move(err_ret); | |||
| } | |||
| // run graph | |||
| transform::RunOptions run_options; | |||
| run_options.name = SINGLE_OP_GRAPH; | |||
| std::vector<GeTensorPtr> ge_inputs; | |||
| std::vector<GeTensorPtr> ge_outputs; | |||
| transform::GraphRunnerOptions graph_runner_options; | |||
| graph_runner_options.options["ge.trainFlag"] = "1"; | |||
| auto graph_runner = std::make_shared<transform::GraphRunner>(graph_runner_options); | |||
| transform::Status run_ret; | |||
| { | |||
| // Release GIL before calling into (potentially long-running) C++ code | |||
| py::gil_scoped_release release; | |||
| run_ret = graph_runner->RunGraph(run_options, ge_inputs, &ge_outputs); | |||
| } | |||
| if (run_ret != transform::Status::SUCCESS) { | |||
| MS_LOG(ERROR) << "GraphRunner Fails to Run Graph"; | |||
| *status = PYNATIVE_GRAPH_GE_RUN_ERR; | |||
| return std::move(err_ret); | |||
| } | |||
| std::vector<MeTensorPtr> graph_outputs = ConvertOutputTensors(op_exec_info, ge_outputs); | |||
| size_t output_size = graph_outputs.size(); | |||
| py::tuple result(output_size); | |||
| for (size_t i = 0; i < output_size; i++) { | |||
| MS_EXCEPTION_IF_NULL(graph_outputs[i]); | |||
| result[i] = *graph_outputs[i]; | |||
| } | |||
| *status = PYNATIVE_SUCCESS; | |||
| MS_LOG(INFO) << "RunOpInGe end"; | |||
| return std::move(result); | |||
| } | |||
| py::object RunOpInVM(const OpExecInfoPtr& op_exec_info, PynativeStatusCode* status) { | |||
| MS_LOG(INFO) << "RunOpInVM start"; | |||
| @@ -423,12 +170,6 @@ py::object RunOpWithBackendPolicy(MsBackendPolicy backend_policy, const OpExecIn | |||
| MS_EXCEPTION_IF_NULL(status); | |||
| py::object result; | |||
| switch (backend_policy) { | |||
| case kMsBackendGeOnly: { | |||
| // use GE only | |||
| MS_LOG(INFO) << "RunOp use GE only backend"; | |||
| result = RunOpInGE(op_exec_info, status); | |||
| break; | |||
| } | |||
| case kMsBackendVmOnly: { | |||
| // use vm only | |||
| MS_LOG(INFO) << "RunOp use VM only backend"; | |||
| @@ -436,22 +177,14 @@ py::object RunOpWithBackendPolicy(MsBackendPolicy backend_policy, const OpExecIn | |||
| break; | |||
| } | |||
| case kMsBackendGePrior: { | |||
| #ifdef ENABLE_GE | |||
| // use GE first, use vm when GE fails | |||
| MS_LOG(INFO) << "RunOp use GE first backend"; | |||
| result = RunOpInGE(op_exec_info, status); | |||
| if (*status != PYNATIVE_SUCCESS) { | |||
| result = RunOpInVM(op_exec_info, status); | |||
| } | |||
| break; | |||
| } | |||
| case kMsBackendVmPrior: { | |||
| // GE_VM_SILENT | |||
| // (should not use this policy) use vm first, use GE when vm fails | |||
| MS_LOG(INFO) << "RunOp use VM first backend"; | |||
| result = RunOpInVM(op_exec_info, status); | |||
| if (*status != PYNATIVE_SUCCESS) { | |||
| result = RunOpInGE(op_exec_info, status); | |||
| } | |||
| #endif | |||
| break; | |||
| } | |||
| case kMsBackendMsPrior: { | |||
| @@ -25,55 +25,14 @@ | |||
| #include "pybind11/pybind11.h" | |||
| #include "transform/convert.h" | |||
| #include "transform/graph_runner.h" | |||
| #include "transform/types.h" | |||
| #include "pynative/base.h" | |||
| #include "utils/context/ms_context.h" | |||
| namespace mindspore { | |||
| namespace pynative { | |||
| using MeTensor = mindspore::tensor::Tensor; | |||
| using MeTensorPtr = mindspore::tensor::TensorPtr; | |||
| using GeTensor = ge::Tensor; | |||
| using GeTensorPtr = std::shared_ptr<GeTensor>; | |||
| using GeGraph = ge::Graph; | |||
| using GeGraphPtr = std::shared_ptr<GeGraph>; | |||
| using GeOperator = ge::Operator; | |||
| using GeOperatorPtr = std::shared_ptr<GeOperator>; | |||
| namespace py = pybind11; | |||
| enum PynativeStatusCode { | |||
| PYNATIVE_SUCCESS = 0, | |||
| PYNATIVE_OP_NOT_IMPLEMENTED_ERR = 1, | |||
| PYNATIVE_OP_INPUTS_ERR = 2, | |||
| PYNATIVE_OP_PARAMS_ERR = 3, | |||
| PYNATIVE_OP_ATTRS_ERR = 4, | |||
| PYNATIVE_GRAPH_MANAGER_ERR = 5, | |||
| PYNATIVE_GRAPH_GE_BUILD_ERR = 6, | |||
| PYNATIVE_GRAPH_GE_RUN_ERR = 7, | |||
| PYNATIVE_UNKNOWN_STATE = 0XFF | |||
| }; | |||
| enum RunOpArgsEnum { PY_PRIM = 0, PY_NAME, PY_INPUTS, PY_INPUT_MASK, PY_ARGS_NUM }; | |||
| struct OpExecInfo { | |||
| PrimitivePyPtr py_primitive; | |||
| std::string op_name; | |||
| AbstractBasePtr abstract; | |||
| py::tuple op_inputs; | |||
| py::tuple inputs_mask; | |||
| py::dict op_attrs; | |||
| }; | |||
| using OpExecInfoPtr = std::shared_ptr<OpExecInfo>; | |||
| OpExecInfoPtr GenerateOpExecInfo(const py::args& args); | |||
| bool BuildSingleOpGraph(const OpExecInfoPtr& op_exec_info, const std::vector<GeTensorPtr>& inputs, | |||
| const std::unordered_map<std::string, ValuePtr>& attrs, const GeGraphPtr& graph); | |||
| py::object RunOpInGE(const OpExecInfoPtr& op_exec_info, PynativeStatusCode* status); | |||
| py::object RunOpInVM(const OpExecInfoPtr& op_exec_info, PynativeStatusCode* status); | |||
| py::tuple RunOp(const py::args& args); | |||
| @@ -0,0 +1,311 @@ | |||
| /** | |||
| * 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 "pynative/pynative_execute_ge.h" | |||
| #include <typeinfo> | |||
| #include <map> | |||
| #include <set> | |||
| #include <unordered_set> | |||
| #include "utils/any.h" | |||
| #include "utils/utils.h" | |||
| #include "utils/context/ms_context.h" | |||
| #include "operator/ops.h" | |||
| #include "pipeline/parse/data_converter.h" | |||
| #include "pipeline/static_analysis/prim.h" | |||
| #include "session/session_factory.h" | |||
| const char SINGLE_OP_GRAPH[] = "single_op_graph"; | |||
| namespace mindspore { | |||
| namespace pynative { | |||
| using MeTensor = mindspore::tensor::Tensor; | |||
| using MeTensorPtr = mindspore::tensor::TensorPtr; | |||
| using GeOperator = ge::Operator; | |||
| using GeOperatorPtr = std::shared_ptr<GeOperator>; | |||
| using transform::GraphRunner; | |||
| using transform::GraphRunnerOptions; | |||
| using transform::OperatorPtr; | |||
| static std::shared_ptr<session::SessionBasic> session = nullptr; | |||
| inline ValuePtr PyAttrValue(const py::object& obj) { | |||
| ValuePtr converted_ret = nullptr; | |||
| bool converted = parse::ConvertData(obj, &converted_ret); | |||
| if (!converted) { | |||
| MS_LOG(EXCEPTION) << "attribute convert error with type:" << std::string(py::str(obj)); | |||
| } | |||
| return converted_ret; | |||
| } | |||
| MeTensorPtr ConvertPyObjToTensor(const py::object& obj) { | |||
| MeTensorPtr me_tensor_ptr = nullptr; | |||
| if (py::isinstance<MeTensor>(obj)) { | |||
| me_tensor_ptr = py::cast<MeTensorPtr>(obj); | |||
| } else if (py::isinstance<py::tuple>(obj)) { | |||
| me_tensor_ptr = std::make_shared<MeTensor>(py::cast<py::tuple>(obj), nullptr); | |||
| } else if (py::isinstance<py::float_>(obj)) { | |||
| me_tensor_ptr = std::make_shared<MeTensor>(py::cast<py::float_>(obj), nullptr); | |||
| } else if (py::isinstance<py::int_>(obj)) { | |||
| me_tensor_ptr = std::make_shared<MeTensor>(py::cast<py::int_>(obj), nullptr); | |||
| } else if (py::isinstance<py::list>(obj)) { | |||
| me_tensor_ptr = std::make_shared<MeTensor>(py::cast<py::list>(obj), nullptr); | |||
| } else if (py::isinstance<py::array>(obj)) { | |||
| me_tensor_ptr = std::make_shared<MeTensor>(py::cast<py::array>(obj), nullptr); | |||
| } else { | |||
| MS_LOG(EXCEPTION) << "run op inputs type is invalid!"; | |||
| } | |||
| return me_tensor_ptr; | |||
| } | |||
| bool SetInputsForSingleOpGraph(const OpExecInfoPtr& op_exec_info, const std::vector<GeTensorPtr>& inputs, | |||
| const OperatorPtr& op, std::vector<GeOperator>* graph_input_nodes) { | |||
| MS_EXCEPTION_IF_NULL(op_exec_info); | |||
| MS_EXCEPTION_IF_NULL(graph_input_nodes); | |||
| auto op_inputs = op_exec_info->op_inputs; | |||
| std::string op_name = op_exec_info->op_name; | |||
| transform::OpAdapterPtr adapter = transform::DfGraphConvertor::FindAdapter(op_name, true); | |||
| if (adapter == nullptr) { | |||
| return false; | |||
| } | |||
| int op_input_idx = 1; | |||
| size_t size = inputs.size(); | |||
| for (size_t i = 0; i < size; i++) { | |||
| if (inputs[i] == nullptr) { | |||
| continue; | |||
| } | |||
| auto const_op = std::make_shared<transform::Constant>(); | |||
| MS_EXCEPTION_IF_NULL(const_op); | |||
| (void)const_op->set_attr_value(*inputs[i]); | |||
| MeTensorPtr me_tensor_ptr = ConvertPyObjToTensor(op_inputs[i]); | |||
| MS_EXCEPTION_IF_NULL(me_tensor_ptr); | |||
| auto const_op_desc = | |||
| transform::TransformUtil::GetGeTensorDesc(me_tensor_ptr->shape_c(), me_tensor_ptr->data_type(), kOpFormat_NCHW); | |||
| if (const_op_desc == nullptr) { | |||
| MS_LOG(ERROR) << "Create variable " << op_name << " ouptut descriptor failed!"; | |||
| return false; | |||
| } | |||
| auto pointer_cast_const_op = std::static_pointer_cast<transform::Constant>(const_op); | |||
| MS_EXCEPTION_IF_NULL(pointer_cast_const_op); | |||
| (void)pointer_cast_const_op->update_output_desc_y(*const_op_desc); | |||
| auto& input_map = adapter->getInputMap(); | |||
| if (input_map.find(op_input_idx) == input_map.end()) { | |||
| continue; | |||
| } | |||
| if (adapter->setInput(op, op_input_idx++, const_op)) { | |||
| MS_LOG(ERROR) << "fail to set params, index is " << op_input_idx; | |||
| return false; | |||
| } | |||
| graph_input_nodes->push_back(*const_op); | |||
| } | |||
| return true; | |||
| } | |||
| bool BuildSingleOpGraph(const OpExecInfoPtr& op_exec_info, const std::vector<GeTensorPtr>& inputs, | |||
| const std::unordered_map<std::string, ValuePtr>& attrs, const GeGraphPtr& graph) { | |||
| MS_EXCEPTION_IF_NULL(op_exec_info); | |||
| std::string op_name = op_exec_info->op_name; | |||
| auto op_inputs = op_exec_info->op_inputs; | |||
| transform::OpAdapterPtr adapter = transform::DfGraphConvertor::FindAdapter(op_name, true); | |||
| if (adapter == nullptr) { | |||
| MS_LOG(ERROR) << "Unable to find Adapter for " << ((std::string)py::str(op_name)); | |||
| return false; | |||
| } | |||
| OperatorPtr op = adapter->generate(op_name); | |||
| MS_EXCEPTION_IF_NULL(op); | |||
| std::vector<GeOperator> graph_input_nodes; | |||
| // hold param nodes after setting input and output for the graph | |||
| // set input | |||
| if (!SetInputsForSingleOpGraph(op_exec_info, inputs, op, &graph_input_nodes)) { | |||
| return false; | |||
| } | |||
| // set attributes | |||
| for (auto attr : attrs) { | |||
| (void)adapter->setAttr(op, attr.first, attr.second); | |||
| } | |||
| // set default attributes | |||
| auto extra_attrs = adapter->GetExtraAttr(); | |||
| for (auto attr : extra_attrs) { | |||
| (void)adapter->setAttr(op, attr.first, attr.second); | |||
| } | |||
| // set input attributes | |||
| auto& input_attr_map = adapter->getInputAttrMap(); | |||
| for (auto& it : input_attr_map) { | |||
| if (op_inputs.size() < it.first) { | |||
| continue; | |||
| } | |||
| auto const_value = PyAttrValue(op_inputs[it.first - 1]); | |||
| if (const_value->isa<None>()) { | |||
| continue; | |||
| } | |||
| it.second.set_attr(op, const_value); | |||
| } | |||
| // construct output data nodes | |||
| std::vector<GeOperator> graph_outputs{*op}; | |||
| // set input and output nodes for the graph | |||
| MS_EXCEPTION_IF_NULL(graph); | |||
| (void)graph->SetInputs(graph_input_nodes).SetOutputs(graph_outputs); | |||
| MS_LOG(INFO) << "BuildSingleOpGraph done"; | |||
| return true; | |||
| } | |||
| void ToTensorPtr(const OpExecInfoPtr op_exec_info, std::vector<GeTensorPtr>* const inputs) { | |||
| MS_EXCEPTION_IF_NULL(inputs); | |||
| MS_EXCEPTION_IF_NULL(op_exec_info); | |||
| auto op_inputs = op_exec_info->op_inputs; | |||
| size_t size = op_inputs.size(); | |||
| for (size_t i = 0; i < size; i++) { | |||
| if (py::isinstance<py::none>(op_inputs[i])) { | |||
| inputs->emplace_back(nullptr); | |||
| continue; | |||
| } | |||
| MeTensorPtr me_tensor_ptr = ConvertPyObjToTensor(op_inputs[i]); | |||
| auto ge_tensor_ptr = transform::TransformUtil::ConvertTensor(me_tensor_ptr, kOpFormat_NCHW); | |||
| if (ge_tensor_ptr == nullptr) { | |||
| MS_LOG(EXCEPTION) << "convert inputs to GE tensor failed in op " << op_exec_info->op_name << "."; | |||
| } | |||
| // set inputs for operator to build single node graph | |||
| inputs->push_back(ge_tensor_ptr); | |||
| } | |||
| } | |||
| PynativeStatusCode ConvertAttributes(const OpExecInfoPtr& op_exec_info, const std::vector<GeTensorPtr>& inputs) { | |||
| MS_EXCEPTION_IF_NULL(op_exec_info); | |||
| auto op_attrs = op_exec_info->op_attrs; | |||
| std::unordered_map<std::string, ValuePtr> attrs{}; | |||
| for (auto& item : op_attrs) { | |||
| if (!py::isinstance<py::str>(item.first)) { | |||
| MS_LOG(ERROR) << "type error in py dict convert"; | |||
| return PYNATIVE_OP_ATTRS_ERR; | |||
| } | |||
| std::string name = py::cast<std::string>(item.first); | |||
| auto attr_value = PyAttrValue(py::cast<py::object>(item.second)); | |||
| (void)attrs.emplace(name, attr_value); | |||
| } | |||
| // build graph | |||
| GeGraphPtr graph = std::make_shared<GeGraph>(op_exec_info->op_name); | |||
| if (BuildSingleOpGraph(op_exec_info, inputs, attrs, graph) == false) { | |||
| MS_LOG(ERROR) << "Fail to BuildSingleOpGraph"; | |||
| return PYNATIVE_GRAPH_GE_BUILD_ERR; | |||
| } | |||
| // add the single op graph into the graph manager, which will be iterated by session. | |||
| transform::Status ret = | |||
| transform::DfGraphManager::GetInstance().AddGraph(SINGLE_OP_GRAPH, std::shared_ptr<transform::DfGraph>(graph)); | |||
| if (ret != transform::SUCCESS) { | |||
| MS_LOG(ERROR) << "Fail to AddGraph into graph manager"; | |||
| return PYNATIVE_GRAPH_MANAGER_ERR; | |||
| } | |||
| return PYNATIVE_SUCCESS; | |||
| } | |||
| std::vector<MeTensorPtr> ConvertOutputTensors(const OpExecInfoPtr& op_exec_info, | |||
| const std::vector<GeTensorPtr>& ge_tensors) { | |||
| std::vector<MeTensorPtr> outputs; | |||
| AbstractBasePtr abs_base = op_exec_info->abstract; | |||
| std::vector<std::vector<int>> shapes; | |||
| if (abs_base != nullptr && abs_base->isa<abstract::AbstractTensor>()) { | |||
| auto arg_tensor = dyn_cast<abstract::AbstractTensor>(abs_base); | |||
| shapes.emplace_back(arg_tensor->shape()->shape()); | |||
| outputs = transform::TransformUtil::ConvertGeTensors(ge_tensors, shapes); | |||
| return outputs; | |||
| } | |||
| if (abs_base != nullptr && abs_base->isa<abstract::AbstractTuple>()) { | |||
| auto arg_tuple = dyn_cast<abstract::AbstractTuple>(abs_base); | |||
| size_t len = arg_tuple->size(); | |||
| for (size_t i = 0; i < len; i++) { | |||
| if (arg_tuple->elements()[i]->isa<abstract::AbstractTensor>()) { | |||
| auto arg_tensor = dyn_cast<abstract::AbstractTensor>(arg_tuple->elements()[i]); | |||
| shapes.emplace_back(arg_tensor->shape()->shape()); | |||
| } | |||
| } | |||
| outputs = transform::TransformUtil::ConvertGeTensors(ge_tensors, shapes); | |||
| return outputs; | |||
| } | |||
| for (auto& it : ge_tensors) { | |||
| auto tensor = transform::TransformUtil::ConvertGeTensor(it); | |||
| if (tensor != nullptr) { | |||
| outputs.emplace_back(tensor); | |||
| } | |||
| } | |||
| return outputs; | |||
| } | |||
| py::object RunOpInGE(const OpExecInfoPtr& op_exec_info, PynativeStatusCode* status) { | |||
| MS_LOG(INFO) << "RunOpInGe start"; | |||
| MS_EXCEPTION_IF_NULL(op_exec_info); | |||
| MS_EXCEPTION_IF_NULL(status); | |||
| // returns a null py::tuple on error | |||
| py::tuple err_ret(0); | |||
| auto op_name = op_exec_info->op_name; | |||
| transform::OpAdapterPtr adapter = transform::DfGraphConvertor::FindAdapter(op_name, true); | |||
| if (adapter == nullptr) { | |||
| MS_LOG(ERROR) << "Unable to find GE Adapter for " << ((std::string)py::str(op_name)); | |||
| *status = PYNATIVE_OP_NOT_IMPLEMENTED_ERR; | |||
| return std::move(err_ret); | |||
| } | |||
| std::vector<GeTensorPtr> inputs{}; | |||
| ToTensorPtr(op_exec_info, &inputs); | |||
| // convert me attr to ge AttrValue | |||
| PynativeStatusCode ret = ConvertAttributes(op_exec_info, inputs); | |||
| if (ret != PYNATIVE_SUCCESS) { | |||
| *status = ret; | |||
| return std::move(err_ret); | |||
| } | |||
| // run graph | |||
| transform::RunOptions run_options; | |||
| run_options.name = SINGLE_OP_GRAPH; | |||
| std::vector<GeTensorPtr> ge_inputs; | |||
| std::vector<GeTensorPtr> ge_outputs; | |||
| transform::GraphRunnerOptions graph_runner_options; | |||
| graph_runner_options.options["ge.trainFlag"] = "1"; | |||
| auto graph_runner = std::make_shared<transform::GraphRunner>(graph_runner_options); | |||
| transform::Status run_ret; | |||
| { | |||
| // Release GIL before calling into (potentially long-running) C++ code | |||
| py::gil_scoped_release release; | |||
| run_ret = graph_runner->RunGraph(run_options, ge_inputs, &ge_outputs); | |||
| } | |||
| if (run_ret != transform::Status::SUCCESS) { | |||
| MS_LOG(ERROR) << "GraphRunner Fails to Run Graph"; | |||
| *status = PYNATIVE_GRAPH_GE_RUN_ERR; | |||
| return std::move(err_ret); | |||
| } | |||
| std::vector<MeTensorPtr> graph_outputs = ConvertOutputTensors(op_exec_info, ge_outputs); | |||
| size_t output_size = graph_outputs.size(); | |||
| py::tuple result(output_size); | |||
| for (size_t i = 0; i < output_size; i++) { | |||
| MS_EXCEPTION_IF_NULL(graph_outputs[i]); | |||
| result[i] = *graph_outputs[i]; | |||
| } | |||
| *status = PYNATIVE_SUCCESS; | |||
| MS_LOG(INFO) << "RunOpInGe end"; | |||
| return std::move(result); | |||
| } | |||
| } // namespace pynative | |||
| } // namespace mindspore | |||
| @@ -0,0 +1,46 @@ | |||
| /** | |||
| * 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_PYNATIVE_PYNATIVE_EXECUTE_GE_H_ | |||
| #define MINDSPORE_CCSRC_PYNATIVE_PYNATIVE_EXECUTE_GE_H_ | |||
| #include <vector> | |||
| #include <utility> | |||
| #include <string> | |||
| #include <memory> | |||
| #include <unordered_map> | |||
| #include "pynative/base.h" | |||
| #include "transform/convert.h" | |||
| #include "transform/graph_runner.h" | |||
| #include "transform/types.h" | |||
| #include "utils/context/ms_context.h" | |||
| using GeTensor = ge::Tensor; | |||
| using GeTensorPtr = std::shared_ptr<GeTensor>; | |||
| using GeGraph = ge::Graph; | |||
| using GeGraphPtr = std::shared_ptr<GeGraph>; | |||
| namespace mindspore { | |||
| namespace pynative { | |||
| bool BuildSingleOpGraph(const OpExecInfoPtr& op_exec_info, const std::vector<GeTensorPtr>& inputs, | |||
| const std::unordered_map<std::string, ValuePtr>& attrs, const GeGraphPtr& graph); | |||
| py::object RunOpInGE(const OpExecInfoPtr& op_exec_info, PynativeStatusCode* status); | |||
| } // namespace pynative | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_PYNATIVE_PYNATIVE_EXECUTE_GE_H_ | |||
| @@ -35,6 +35,7 @@ | |||
| #include "pre_activate/common/helper.h" | |||
| #include "device/kernel_runtime_manager.h" | |||
| #include "kernel/tbe/tbe_python_funcs.h" | |||
| #include "utils/config_manager.h" | |||
| namespace mindspore { | |||
| namespace session { | |||
| @@ -19,7 +19,7 @@ | |||
| #include "device/gpu/gpu_kernel_runtime.h" | |||
| #include "pre_activate/common/optimizer.h" | |||
| #include "pre_activate/common/pass_manager.h" | |||
| #include "pre_activate/ascend/ir_fusion/allreduce_fusion.h" | |||
| #include "pre_activate/common/ir_fusion/allreduce_fusion.h" | |||
| #include "device/kernel_runtime_manager.h" | |||
| #include "predict/predict.h" | |||
| #include "common/utils.h" | |||
| @@ -381,24 +381,6 @@ std::unordered_map<std::string, OpAdapterDescPtr> &DfGraphConvertor::get_adpt_ma | |||
| } | |||
| // ---------------implement of DfGraphConvertor------------- | |||
| std::string GetCNodeFuncName(const CNodePtr cnode) { | |||
| if (cnode->inputs().empty()) { | |||
| return ""; | |||
| } | |||
| AnfNodePtr valuenode = cnode->input(0); | |||
| if (valuenode->isa<ValueNode>()) { | |||
| auto value = GetValueNode(valuenode); | |||
| // check whether the valuenode is primitive | |||
| if (value->isa<Primitive>()) { | |||
| return value->cast<PrimitivePtr>()->name(); | |||
| } else { | |||
| return value->ToString(); | |||
| } | |||
| } | |||
| return ""; | |||
| } | |||
| PrimType GetCNodeFuncType(const CNodePtr cnode) { | |||
| if (cnode->inputs().empty()) { | |||
| return kPrimTypeUnknown; | |||
| @@ -253,7 +253,6 @@ class DfGraphConvertor { | |||
| bool distribute_ = false; | |||
| }; | |||
| extern std::string GetCNodeFuncName(CNodePtr cnode); | |||
| } // namespace transform | |||
| } // namespace mindspore | |||
| @@ -20,16 +20,16 @@ | |||
| #include <memory> | |||
| #include <vector> | |||
| #include "pybind11/pybind11.h" | |||
| #ifdef ENABLE_GE | |||
| #include "transform/df_graph_manager.h" | |||
| #include "transform/util.h" | |||
| #endif | |||
| #include "pipeline/parse/data_converter.h" | |||
| #include "pipeline/parse/python_adapter.h" | |||
| #include "utils/visible.h" | |||
| namespace mindspore { | |||
| namespace callbacks { | |||
| using mindspore::transform::Status; | |||
| using mindspore::transform::TransformUtil; | |||
| const char PYTHON_MOD_CALLBACK_MODULE[] = "mindspore.train.callback"; | |||
| const char PYTHON_FUN_PROCESS_CHECKPOINT[] = "_checkpoint_cb_for_save_op"; | |||
| @@ -38,6 +38,10 @@ const char kSummary[] = "Summary"; | |||
| const char kCheckPoint[] = "Save"; | |||
| const int ONE_SHAPE = 1; | |||
| #ifdef ENABLE_GE | |||
| using mindspore::transform::Status; | |||
| using mindspore::transform::TransformUtil; | |||
| bool GetParameterShape(const FuncGraphPtr& graph, const std::string& param_name, | |||
| const std::shared_ptr<std::vector<int>>& shape) { | |||
| if (graph == nullptr) { | |||
| @@ -181,6 +185,7 @@ uint32_t MS_EXPORT SummarySaveCallback(uint32_t graph_id, const std::map<std::st | |||
| MS_LOG(DEBUG) << "End the summary save callback function."; | |||
| return Status::SUCCESS; | |||
| } | |||
| #endif | |||
| // Cache the summary callback data from ME session | |||
| // Remove the GE module on new architecture | |||
| @@ -208,10 +213,10 @@ uint32_t MS_EXPORT SummarySaveCallback(uint32_t graph_id, const std::map<std::st | |||
| auto bool_ret = py::cast<bool>(ret); | |||
| if (!bool_ret) { | |||
| MS_LOG(ERROR) << "Python checkpoint return false during callback"; | |||
| return Status::FAILED; | |||
| return kCallbackFalied; | |||
| } | |||
| MS_LOG(DEBUG) << "End the summary save callback function."; | |||
| return Status::SUCCESS; | |||
| return kCallbackOk; | |||
| } | |||
| } // namespace callbacks | |||
| } // namespace mindspore | |||
| @@ -20,8 +20,11 @@ | |||
| #include <string> | |||
| #include <vector> | |||
| #include <memory> | |||
| #include "ir/meta_tensor.h" | |||
| #ifdef ENABLE_GE | |||
| #include "transform/types.h" | |||
| #include "transform/util.h" | |||
| #endif | |||
| namespace mindspore { | |||
| namespace callbacks { | |||
| @@ -36,10 +39,16 @@ extern const char kSummary[]; | |||
| extern const char kCheckPoint[]; | |||
| extern const std::string kPythonCheckpointModuleName; | |||
| extern const std::string kPythonCheckpointFuncName; | |||
| const int kCallbackOk = 0; | |||
| const int kCallbackFalied = 1; | |||
| bool GetParameterShape(const FuncGraphPtr& anf_graph, const std::string& param_name, | |||
| const std::shared_ptr<std::vector<int>>& shape); | |||
| #ifdef ENABLE_GE | |||
| uint32_t CheckpointSaveCallback(uint32_t, const std::map<std::string, ge::Tensor>&); | |||
| uint32_t SummarySaveCallback(uint32_t, const std::map<std::string, ge::Tensor>&); | |||
| #endif | |||
| uint32_t SummarySaveCallback(uint32_t, const std::map<std::string, TensorPtr>&); | |||
| } // namespace callbacks | |||
| @@ -26,13 +26,15 @@ | |||
| #include "tdt/tdt_host_interface.h" | |||
| #include "tdt/data_common.h" | |||
| #endif | |||
| #ifdef ENABLE_GE | |||
| #include "transform/df_graph_manager.h" | |||
| #endif | |||
| #include "ir/meta_tensor.h" | |||
| namespace mindspore { | |||
| #ifdef ENABLE_GE | |||
| using mindspore::transform::DfGraphManager; | |||
| using transform::GraphRunner; | |||
| using transform::GraphRunnerOptions; | |||
| #endif | |||
| std::atomic<bool> thread_1_must_end(false); | |||
| @@ -81,6 +83,7 @@ MsContext::MsContext(const std::string& policy, const std::string& target) { | |||
| std::shared_ptr<MsContext> MsContext::GetInstance() { | |||
| if (inst_context_ == nullptr) { | |||
| MS_LOG(DEBUG) << "Create new mindspore context"; | |||
| #ifdef ENABLE_GE | |||
| inst_context_.reset(new (std::nothrow) MsContext("ge", kAscendDevice)); | |||
| #elif defined(ENABLE_D) | |||
| @@ -23,7 +23,6 @@ | |||
| #include <vector> | |||
| #include <string> | |||
| #include <utility> | |||
| #include "transform/graph_runner.h" | |||
| #include "utils/log_adapter.h" | |||
| namespace mindspore { | |||
| @@ -373,4 +373,45 @@ AbstractBasePtr PyListDtype2AbstractTensor(const py::object &shape_obj, const py | |||
| MS_LOG(EXCEPTION) << "Python evaluator return invalid shape or type. " << (std::string)py::str(type_obj); | |||
| } | |||
| } | |||
| bool IsGraphOutputValueNodeOrParameter(const AnfNodePtr &output, const py::tuple &args, | |||
| const std::shared_ptr<py::object> &ret_val) { | |||
| if (output->isa<ValueNode>()) { | |||
| MS_LOG(INFO) << "Graph's output is a constant. No need to execute."; | |||
| ValuePtr value = GetValueNode(output); | |||
| *ret_val = ValuePtrToPyData(value); | |||
| return true; | |||
| } | |||
| // Adapter will transform values in __init__() and construct() to parameters, this could cause | |||
| // inputs (a.k.a args in current function) size less than parameters'. | |||
| if (output->isa<Parameter>()) { | |||
| MS_LOG(INFO) << "Graph's output is a parameter. If all params are inputs, no need to execute."; | |||
| if (args.empty()) { | |||
| MS_LOG(EXCEPTION) << "Inputs size is 0, let graph to be executed."; | |||
| } | |||
| // Find the right parameter as ret_val. | |||
| auto func_graph = output->func_graph(); | |||
| MS_EXCEPTION_IF_NULL(func_graph); | |||
| auto params = func_graph->parameters(); | |||
| if (params.empty()) { | |||
| MS_EXCEPTION(UnknownError) << "Graph's parameters size is 0"; | |||
| } | |||
| if (args.size() != params.size()) { | |||
| MS_LOG(EXCEPTION) << "Input size " << args.size() << " not equal to params size " << params.size() | |||
| << ", let graph to be executed."; | |||
| } | |||
| auto it = std::find(params.begin(), params.end(), output); | |||
| if (it == params.end()) { | |||
| MS_EXCEPTION(UnknownError) << "When graph output is Parameter, it should be found in graph parameters"; | |||
| } | |||
| size_t index = it - params.cbegin(); | |||
| if (index >= args.size()) { | |||
| MS_EXCEPTION(UnknownError) << "Index " << index << " equal or larger than args size " << args.size() << "."; | |||
| } | |||
| *ret_val = args[index]; | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| } // namespace mindspore | |||
| @@ -18,6 +18,7 @@ | |||
| #define MINDSPORE_CCSRC_UTILS_CONVERT_UTILS_H_ | |||
| #include <limits> | |||
| #include <memory> | |||
| #include "pybind11/pybind11.h" | |||
| #include "utils/any.h" | |||
| @@ -120,6 +121,9 @@ inline uint8_t *AddressOffset(void *address, size_t offset) { | |||
| AbstractBasePtr PyListDtype2AbstractTensor(const py::object &shape_obj, const py::object &type_obj); | |||
| bool IsGraphOutputValueNodeOrParameter(const AnfNodePtr &output, const py::tuple &args, | |||
| const std::shared_ptr<py::object> &ret_val); | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_UTILS_CONVERT_UTILS_H_ | |||
| @@ -178,14 +178,12 @@ LinConvertResult Convert(const AnfNodePtrList& lst) { | |||
| } | |||
| LinkFuncType MsVmConvert = Convert<VM>; | |||
| LinkFuncType GeVmConvert = Convert<GeVM>; | |||
| std::unordered_map<std::string, LinkFuncType> backends = {{kMsVm, MsVmConvert}, {kGeVm, GeVmConvert}}; | |||
| std::unordered_map<std::string, LinkFuncType> backends = {{kMsVm, MsVmConvert}}; | |||
| std::set<std::string> backend_list = { | |||
| kMsConvert, | |||
| kMsVm, | |||
| kGeVm, | |||
| }; | |||
| } // namespace compile | |||
| @@ -24,7 +24,9 @@ | |||
| #include <vector> | |||
| #include "pipeline/static_analysis/abstract_value.h" | |||
| #ifdef ENABLE_GE | |||
| #include "transform/convert.h" | |||
| #endif | |||
| #include "utils/graph_utils.h" | |||
| #include "utils/context/ms_context.h" | |||
| #include "debug/trace.h" | |||
| @@ -55,7 +57,6 @@ CompileGraph::CompileGraph(const BackendPtr& backend, const std::vector<Primitiv | |||
| MS_LOG(INFO) << "Attribute 'is_gevm_convert' is true"; | |||
| is_gevm_convert_ = true; | |||
| } | |||
| is_graph_cut = false; | |||
| } | |||
| bool CompileGraph::IsCut(const AnfNodePtr& node) { | |||
| @@ -80,14 +81,15 @@ bool CompileGraph::IsCut(const AnfNodePtr& node) { | |||
| } | |||
| } | |||
| #ifdef ENABLE_GE | |||
| if (is_gevm_convert_) { | |||
| auto name = transform::GetCNodeFuncName(cnode); | |||
| auto name = GetCNodeFuncName(cnode); | |||
| auto adpt = transform::DfGraphConvertor::FindAdapter(name); | |||
| if (adpt == nullptr) { | |||
| is_graph_cut = true; | |||
| return true; | |||
| } | |||
| return true; | |||
| } | |||
| #endif | |||
| } | |||
| return false; | |||
| @@ -605,12 +607,6 @@ FinalVMPtr CompileGraphs::CompileAndLink(const FuncGraphPtr& graph) { | |||
| (void)WrapPrimitives(graph); | |||
| Compile(graph); | |||
| #ifdef ENABLE_GE | |||
| if (!transform_->IsGraphCut()) { | |||
| return nullptr; | |||
| } | |||
| #endif | |||
| FinalVMPtr rt = Link(graph); | |||
| Reset(); | |||
| MS_LOG(DEBUG) << "End"; | |||
| @@ -55,7 +55,6 @@ class CompileGraph { | |||
| InstSet Run(const FuncGraphPtr& func_graph); | |||
| InstSet GenMultiGraphsSinkInst(const FuncGraphPtr& graph); | |||
| bool IsGraphCut() const { return is_graph_cut; } | |||
| bool IsCut(const AnfNodePtr& node); | |||
| void Push(const AnfNodePtr& node); | |||
| void Tie(const AnfNodePtr& n1, const AnfNodePtr& n2) { slots_[n2] = slots_[n1]; } | |||
| @@ -101,7 +100,6 @@ class CompileGraph { | |||
| BackendPtr backend_; | |||
| LinkFuncType lin_convert_; | |||
| bool is_gevm_convert_; | |||
| bool is_graph_cut; | |||
| int height_{0}; | |||
| int max_height_{0}; | |||
| std::vector<PrimitivePtr> cut_list_; | |||
| @@ -26,8 +26,6 @@ | |||
| #include <memory> | |||
| #include <set> | |||
| #include "transform/graph_runner.h" | |||
| #include "transform/convert.h" | |||
| #include "ir/meta_tensor.h" | |||
| #include "operator/ops.h" | |||
| #include "ir/manager.h" | |||
| @@ -40,39 +38,6 @@ namespace compile { | |||
| using PrimitivePyPtr = std::shared_ptr<PrimitivePy>; | |||
| static const char SEGMENT_GRAPH_NAME[] = "runnable_segment"; | |||
| VectorRef GeVM::RunGraph(const FuncGraphPtr& anf_graph, const VectorRef& args) { | |||
| // Convert graph | |||
| transform::DfGraphConvertor convertor(anf_graph); | |||
| (void)convertor.ConvertAllNode().BuildGraph(); | |||
| if (convertor.ErrCode() == 0) { | |||
| (void)transform::DfGraphManager::GetInstance().AddGraph(SEGMENT_GRAPH_NAME, convertor.GetComputeGraph()); | |||
| } else { | |||
| MS_LOG(EXCEPTION) << "convert df graph failed"; | |||
| } | |||
| // Run graph | |||
| transform::GraphRunnerOptions options; | |||
| transform::GraphRunner graph_runner(options); | |||
| transform::RunOptions run_options; | |||
| run_options.name = SEGMENT_GRAPH_NAME; | |||
| std::vector<tensor::TensorPtr> inputs; | |||
| (void)std::transform(std::begin(args), std::end(args), std::back_inserter(inputs), | |||
| [](const BaseRef& arg) -> tensor::TensorPtr { | |||
| auto value_ref = utils::cast<PyObjectRef>(arg); | |||
| auto value = value_ref.object_; | |||
| return py::cast<tensor::TensorPtr>(value); | |||
| }); | |||
| std::vector<tensor::TensorPtr> outputs; | |||
| (void)graph_runner.RunGraph(run_options, inputs, &outputs); | |||
| std::vector<BaseRef> ret; | |||
| (void)std::copy(outputs.begin(), outputs.end(), std::back_inserter(ret)); | |||
| return VectorRef(ret); | |||
| } | |||
| // Indicate a call to a new frame. | |||
| struct CallWrap : public Base { | |||
| explicit CallWrap(const VMFramePtr& vm_frame) : frame(vm_frame) {} | |||
| @@ -64,12 +64,6 @@ class VMImpl { | |||
| virtual ~VMImpl() = default; | |||
| }; | |||
| class GeVM : public VMImpl { | |||
| public: | |||
| VectorRef RunGraph(const FuncGraphPtr& fg, const VectorRef& args) override; | |||
| ~GeVM() override = default; | |||
| }; | |||
| // An execution frame. | |||
| // This holds the state for an application of a graph. The nodes list | |||
| // must contain free variables of graphs encountered before the | |||
| @@ -22,7 +22,7 @@ from mindspore import context | |||
| from mindspore import log as logger | |||
| from mindspore.parallel._utils import _get_parallel_mode | |||
| from .._c_expression import generate_key, Executor_, Tensor, MetaTensor | |||
| from .._c_expression import verify_inputs_signature, init_exec_dataset, export_graph, _set_dataset_mode_config, init_ge | |||
| from .._c_expression import verify_inputs_signature, init_exec_dataset, _set_dataset_mode_config, init_ge | |||
| from .tensor import Tensor as MsTensor | |||
| # store ms_function class compiled pipeline cache | |||
| @@ -501,6 +501,7 @@ class _Executor: | |||
| file_name (str): File name of model to export | |||
| file_format (str): MindSpore currently support 'GEIR' and 'ONNX' format for exported model | |||
| """ | |||
| from .._c_expression import export_graph | |||
| phase = 'export' + '.' + str(net.create_time) | |||
| export_graph(file_name, file_format, phase) | |||
| @@ -155,6 +155,18 @@ class Parameter: | |||
| def data(self): | |||
| return self.default_input | |||
| def __add__(self, other): | |||
| return self.default_input + other | |||
| def __sub__(self, other): | |||
| return self.default_input - other | |||
| def __mul__(self, other): | |||
| return self.default_input * other | |||
| def __truediv__(self, other): | |||
| return self.default_input / other | |||
| def set_parameter_data(self, data): | |||
| if isinstance(data, (Tensor, list, int, float, | |||
| np.float16, np.float32, np.int32, np.int16, np.ndarray)) and not isinstance(data, bool): | |||
| @@ -89,6 +89,16 @@ class Tensor(Tensor_): | |||
| out = self.__mul__(other) | |||
| return out | |||
| def __truediv__(self, other): | |||
| if isinstance(other, (int, float)): | |||
| other_tensor = Tensor(other, self.dtype()) | |||
| elif isinstance(other, Tensor): | |||
| other_tensor = other | |||
| else: | |||
| raise TypeError("unsupported type for div operation") | |||
| out = tensor_operator_registry.get('__div__')(self, other_tensor) | |||
| return out | |||
| def __sub__(self, other): | |||
| if not isinstance(other, Tensor): | |||
| raise TypeError("input_data must be a tensor") | |||
| @@ -125,5 +125,5 @@ shape_mul = Primitive("shape_mul") | |||
| stop_gradient = Primitive("stop_gradient") | |||
| tensor_operator_registry.register('__add__', tensor_add) | |||
| tensor_operator_registry.register('__mul__', tensor_mul) | |||
| tensor_operator_registry.register('__div__', tensor_div) | |||
| @@ -161,6 +161,9 @@ class Model: | |||
| def _update_metrics(self, outputs): | |||
| """Update metrics local values.""" | |||
| if not isinstance(outputs, tuple): | |||
| raise ValueError("The `outputs` is not tuple.") | |||
| if self._eval_indexes is not None and len(outputs) < 3: | |||
| raise ValueError("The length of `outputs` must be greater than or equal to 3, \ | |||
| but got {}".format(len(outputs))) | |||
| @@ -231,7 +231,7 @@ void test_select(const CNodePtr &kernel_node, std::vector<std::shared_ptr<kernel | |||
| AnfAlgo::SetSelectKernelBuildInfo(selected_kernel_info_ptr, kernel_node.get()); | |||
| } | |||
| void SetParentAbstract(std::vector<AnfNodePtr> parent_list, std::vector<vector<size_t>> shapes, | |||
| void SetParentAbstract(std::vector<AnfNodePtr> parent_list, std::vector<std::vector<size_t>> shapes, | |||
| std::vector<TypeId> types) { | |||
| for (const auto &node : parent_list) { | |||
| AnfAlgo::SetOutputInferTypeAndShape(types, shapes, node.get()); | |||
| @@ -16,10 +16,10 @@ | |||
| #include <iostream> | |||
| #include <memory> | |||
| #include "./prof_reporter.h" | |||
| #include "common/common_test.h" | |||
| #include "device/ascend/profiling/profiling_manager.h" | |||
| #include "./common.h" | |||
| #include "./prof_reporter.h" | |||
| #define private public | |||
| #include "device/ascend/profiling/plugin_impl.h" | |||
| #undef private | |||
| @@ -20,7 +20,7 @@ | |||
| #include "ir/manager.h" | |||
| #include "debug/anf_ir_dump.h" | |||
| #include "session/anf_runtime_algorithm.h" | |||
| #include "pre_activate/ascend/ir_fusion/allreduce_fusion.h" | |||
| #include "pre_activate/common/ir_fusion/allreduce_fusion.h" | |||
| #include "pre_activate/common/optimizer.h" | |||
| #include "device/kernel_info.h" | |||
| #include "pre_activate/common/pass_manager.h" | |||
| @@ -105,7 +105,7 @@ TEST_F(TestHWConstInputToTensorInput, test_value_tuple_tensor_input) { | |||
| auto tensor = input1->cast<ValueNodePtr>()->value()->cast<tensor::TensorPtr>(); | |||
| ASSERT_TRUE(tensor != nullptr); | |||
| auto data = tensor->data_c(false); | |||
| EXPECT_EQ(vector<int>((int *)data, (int *)data + 4), vector<int>({2, 4, 2, 2})); | |||
| EXPECT_EQ(std::vector<int>((int *)data, (int *)data + 4), std::vector<int>({2, 4, 2, 2})); | |||
| } | |||
| } // namespace opt | |||
| } // namespace mindspore | |||
| @@ -24,6 +24,8 @@ import pytest | |||
| import mindspore as ms | |||
| import mindspore.common.api as me | |||
| import mindspore.nn as nn | |||
| from mindspore.common.parameter import Parameter | |||
| from mindspore.common.initializer import initializer | |||
| from ..ut_filter import non_graph_engine | |||
| @@ -199,6 +201,21 @@ def test_sub(): | |||
| z = x - y | |||
| assert isinstance(z, ms.Tensor) | |||
| @non_graph_engine | |||
| def test_div(): | |||
| x = ms.Tensor(np.array([[2,6,10],[12, 4, 8]]).astype(np.float32)) | |||
| y = ms.Tensor(np.array([[2,2,5],[6, 1, 2]]).astype(np.float32)) | |||
| z = x / y | |||
| z2 = x / 2 | |||
| assert isinstance(z, ms.Tensor) | |||
| assert isinstance(z2, ms.Tensor) | |||
| @non_graph_engine | |||
| def test_parameter(): | |||
| x = Parameter(initializer(1, [1], ms.float32), name="beta1_power") | |||
| z = x / 2 | |||
| print(z) | |||
| class Net(nn.Cell): | |||
| """Net definition""" | |||
| @@ -378,3 +395,4 @@ def test_tensor_dtype_fp32_to_bool(): | |||
| input = np.random.randn(2, 3, 4, 5).astype(np.float32) | |||
| input = ms.Tensor(input) | |||
| input_me = ms.Tensor(input, dtype=ms.bool_) | |||
| @@ -97,20 +97,6 @@ def test_select(): | |||
| assert np.all(output.asnumpy() == expect) | |||
| def test_scalar_cast_grad(): | |||
| """ test_scalar_cast_grad """ | |||
| input_x = 255.5 | |||
| input_t = get_py_obj_dtype(ms.int8) | |||
| def fx_cast(x): | |||
| output = F.scalar_cast(x, input_t) | |||
| return output | |||
| gfn = C.grad(fx_cast)(input_x) | |||
| expect_dx = 1 | |||
| assert gfn == expect_dx | |||
| class CustomOP(PrimitiveWithInfer): | |||
| __mindspore_signature__ = (sig_dtype.T, sig_dtype.T, sig_dtype.T1, | |||
| sig_dtype.T1, sig_dtype.T2, sig_dtype.T2, | |||
| @@ -13,11 +13,14 @@ | |||
| # limitations under the License. | |||
| import mindspore.context as context | |||
| from mindspore.parallel._utils import _reset_op_id | |||
| def setup_module(module): | |||
| context.set_context(mode=context.GRAPH_MODE) | |||
| context.set_context(mode=context.GRAPH_MODE, device_target="Ascend", save_graphs=False) | |||
| _reset_op_id() | |||
| def teardown_module(): | |||
| context.reset_auto_parallel_context() | |||
| _reset_op_id() | |||
| @@ -97,13 +97,10 @@ def test_all_to_all(): | |||
| strategys = all_to_all_common(strategy1) | |||
| print(strategys) | |||
| expect_dict = {'Default/network-_VirtualDatasetCell/_backbone-WithLossCell/_loss_fn-SoftmaxCrossEntropyWithLogits' | |||
| '/SoftmaxCrossEntropyWithLogits-op43': [[8, 1], [8, 1]], | |||
| 'Default/network-_VirtualDatasetCell/_backbone-WithLossCell/_loss_fn-SoftmaxCrossEntropyWithLogits' | |||
| '/OneHot-op44': [[8, 1], [], []], | |||
| 'Default/network-_VirtualDatasetCell/_backbone-WithLossCell/_backbone-AllToAllNet/Transpose-op1': | |||
| [[8, 1]], | |||
| 'Default/network-_VirtualDatasetCell/_backbone-WithLossCell/_backbone-AllToAllNet/MatMul-op0': | |||
| [[1, 1], [1, 8]]} | |||
| '/SoftmaxCrossEntropyWithLogits-op3': [[8, 1], [8, 1]], | |||
| 'Default/network-_VirtualDatasetCell/_backbone-WithLossCell/_loss_fn-SoftmaxCrossEntropyWithLogits/OneHot-op4': [[8, 1], [], []], | |||
| 'Default/network-_VirtualDatasetCell/_backbone-WithLossCell/_backbone-AllToAllNet/Transpose-op1': [[8, 1]], | |||
| 'Default/network-_VirtualDatasetCell/_backbone-WithLossCell/_backbone-AllToAllNet/MatMul-op0': [[1, 1], [1, 8]]} | |||
| assert (strategys == expect_dict) | |||
| context.set_context(save_graphs=False) | |||
| @@ -65,8 +65,8 @@ def test_auto_parallel_arithmetic(): | |||
| b = Tensor(np.ones([64, 128]), dtype=ms.float32) | |||
| _executor.compile(net, x, y, b, phase='train') | |||
| strategies = _executor._get_strategy(net) | |||
| expected_strategies = {'Default/network-Net/FloorDiv-op2': [[2, 4], [2, 4]], | |||
| 'Default/network-Net/MatMul-op3': [[2, 1], [1, 4]]} | |||
| expected_strategies = {'Default/network-Net/FloorDiv-op0': [[2, 4], [2, 4]], | |||
| 'Default/network-Net/MatMul-op1': [[2, 1], [1, 4]]} | |||
| assert strategies == expected_strategies | |||
| def test_auto_parallel_arithmetic_broadcast_both(): | |||
| @@ -91,8 +91,8 @@ def test_auto_parallel_arithmetic_broadcast_both(): | |||
| b = Tensor(np.ones([1, 64]), dtype=ms.float32) | |||
| _executor.compile(net, x, y, b, phase='train') | |||
| strategies = _executor._get_strategy(net) | |||
| expected_strategies = {'Default/network-Net/FloorDiv-op2': [[8, 1], [1, 1]], | |||
| 'Default/network-Net/MatMul-op3': [[8, 1], [1, 1]]} | |||
| expected_strategies = {'Default/network-Net/FloorDiv-op0': [[8, 1], [1, 1]], | |||
| 'Default/network-Net/MatMul-op1': [[8, 1], [1, 1]]} | |||
| assert strategies == expected_strategies | |||
| @@ -118,8 +118,8 @@ def test_auto_parallel_arithmetic_broadcast_right(): | |||
| b = Tensor(np.ones([32]), dtype=ms.float32) | |||
| _executor.compile(net, x, y, b, phase='train') | |||
| strategies = _executor._get_strategy(net) | |||
| expected_strategies = {'Default/network-Net/FloorDiv-op2': [[4, 2], [2]], | |||
| 'Default/network-Net/MatMul-op3': [[4, 1], [1, 2]]} | |||
| expected_strategies = {'Default/network-Net/FloorDiv-op0': [[4, 2], [2]], | |||
| 'Default/network-Net/MatMul-op1': [[4, 1], [1, 2]]} | |||
| assert strategies == expected_strategies | |||
| @@ -145,6 +145,6 @@ def test_auto_parallel_arithmetic_broadcast_left(): | |||
| b = Tensor(np.ones([128, 64, 32]), dtype=ms.float32) | |||
| _executor.compile(net, x, y, b, phase="train") | |||
| strategies = _executor._get_strategy(net) | |||
| expected_strategies = {'Default/network-Net/FloorDiv-op2': [[4, 2], [1, 4, 2]], | |||
| 'Default/network-Net/MatMul-op3': [[4, 1], [1, 2]]} | |||
| assert strategies == expected_strategies | |||
| expected_strategies = {'Default/network-Net/FloorDiv-op0': [[4, 2], [1, 4, 2]], | |||
| 'Default/network-Net/MatMul-op1': [[4, 1], [1, 2]]} | |||
| assert strategies == expected_strategies | |||
| @@ -12,6 +12,7 @@ | |||
| # See the License for the specific language governing permissions and | |||
| # limitations under the License. | |||
| import re | |||
| import numpy as np | |||
| from mindspore import context | |||
| import mindspore.nn as nn | |||
| @@ -55,6 +56,9 @@ def test_auto_parallel_assign_sub_with_ref_key(): | |||
| _executor.compile(net, x, phase="train") | |||
| strategies = _executor._get_strategy(net) | |||
| expected_strategies = {'Default/network-PReLU/PReLU-op2': [[1, 1, 1, 8], [1]], | |||
| 'Default/network-PReLU/ReLU-op3': [[1]]} | |||
| assert strategies == expected_strategies | |||
| for (k, v) in strategies.items(): | |||
| if re.search('PReLU-op', k) is not None: | |||
| assert v == [[1, 1, 1, 8], [1]] | |||
| elif re.search('ReLU-op', k) is not None: | |||
| assert v == [[1]] | |||
| @@ -75,9 +75,9 @@ def test_double_star_graph(): | |||
| _executor.compile(net, x, y, z, w, phase='train') | |||
| strategies = _executor._get_strategy(net) | |||
| expected_strategies = {'Default/network-Net/MatMul-op0': [[1, 8], [8, 1]], | |||
| 'Default/network-Net/Cast-op7': [[8, 1]], | |||
| 'Default/network-Net/MatMul-op8': [[8, 1], [1, 1]], | |||
| 'Default/network-Net/Cast-op9': [[1, 8]], | |||
| 'Default/network-Net/MatMul-op10': [[1, 1], [1, 8]]} | |||
| assert strategies == expected_strategies | |||
| expected_strategies = {'Default/network-Net/Cast-op1': [[8, 1]], | |||
| 'Default/network-Net/Cast-op3': [[1, 8]], | |||
| 'Default/network-Net/MatMul-op2': [[8, 1], [1, 1]], | |||
| 'Default/network-Net/MatMul-op4': [[1, 1], [1, 8]], | |||
| 'Default/network-Net/MatMul-op0': [[1, 8], [8, 1]]} | |||
| assert strategies == expected_strategies | |||
| @@ -12,6 +12,7 @@ | |||
| # See the License for the specific language governing permissions and | |||
| # limitations under the License. | |||
| import re | |||
| import numpy as np | |||
| from mindspore import context | |||
| import mindspore.nn as nn | |||
| @@ -66,7 +67,10 @@ def test_matmul_prelu(): | |||
| _executor.compile(net, x, y, b, phase='train') | |||
| strategies = _executor._get_strategy(net) | |||
| assert strategies['Default/network-Net/PReLU-op2'] == [[16, 1, 1, 1], [1]] | |||
| assert strategies['Default/network-Net/Mul-op3'] == [[16, 1, 1, 1], [16, 1, 1, 1]] | |||
| for (k, v) in strategies.items(): | |||
| if re.search('PReLU-op', k) is not None: | |||
| assert v == [[16, 1, 1, 1], [1]] | |||
| elif re.search('Mul-op', k) is not None: | |||
| assert v == [[16, 1, 1, 1], [16, 1, 1, 1]] | |||
| @@ -80,9 +80,9 @@ def test_common_parameter(): | |||
| _executor.compile(net, x, y, z, w, phase='train') | |||
| strategies = _executor._get_strategy(net) | |||
| expected_strategies = {'Default/network-Net/MatMul-op6': [[8, 1], [1, 1]], | |||
| 'Default/network-Net/MatMul-op8': [[8, 1], [1, 1]], | |||
| 'Default/network-Net/Cast-op7': [[1, 1]], | |||
| expected_strategies = {'Default/network-Net/MatMul-op1': [[8, 1], [1, 1]], | |||
| 'Default/network-Net/MatMul-op3': [[8, 1], [1, 1]], | |||
| 'Default/network-Net/Cast-op2': [[1, 1]], | |||
| 'Default/network-Net/MatMul-op0': [[8, 1], [1, 1]], | |||
| 'Default/network-Net/Cast-op9': [[1, 1]]} | |||
| 'Default/network-Net/Cast-op4': [[1, 1]]} | |||
| assert strategies == expected_strategies | |||
| @@ -71,8 +71,8 @@ def test_two_matmul_transpose(): | |||
| _executor.compile(net, x, y, b, phase='train') | |||
| strategies = _executor._get_strategy(net) | |||
| expected_strategies = {'Default/network-Net/Transpose-op4': [[1, 16]], | |||
| 'Default/network-Net/Transpose-op5': [[16, 1]], | |||
| 'Default/network-Net/MatMul-op6': [[16, 1], [1, 1]], | |||
| 'Default/network-Net/MatMul-op7': [[16, 1], [1, 1]]} | |||
| assert strategies == expected_strategies | |||
| expected_strategies = {'Default/network-Net/Transpose-op0': [[1, 16]], | |||
| 'Default/network-Net/Transpose-op1': [[16, 1]], | |||
| 'Default/network-Net/MatMul-op2': [[16, 1], [1, 1]], | |||
| 'Default/network-Net/MatMul-op3': [[16, 1], [1, 1]]} | |||
| assert strategies == expected_strategies | |||
| @@ -135,7 +135,6 @@ def test_two_matmul(): | |||
| _executor.compile(net, x, y, b, phase='train') | |||
| strategies = _executor._get_strategy(net) | |||
| expected_strategies = {'Default/network-Net/MatMul-op2': [[16, 1], [1, 1]], | |||
| 'Default/network-Net/MatMul-op3': [[16, 1], [1, 1]]} | |||
| expected_strategies = {'Default/network-Net/MatMul-op0': [[16, 1], [1, 1]], | |||
| 'Default/network-Net/MatMul-op1': [[16, 1], [1, 1]]} | |||
| assert strategies == expected_strategies | |||
| @@ -84,7 +84,7 @@ def loss_scale_manager_common(strategy1): | |||
| opt = Momentum(net.trainable_params(), learning_rate, momentum) | |||
| scale_manager = DynamicLossScaleManager(32, 2, 2000) | |||
| model = Model(net, loss, opt, loss_scale_manager=scale_manager) | |||
| # if no GE exists, outputs = self._train_network(*next_element) outputs is None, TypeError is caught. | |||
| # if no GE exists, outputs = self._train_network(*next_element) outputs inputs tensor. | |||
| try: | |||
| model.train(epoch_size, dataset, dataset_sink_mode=False) | |||
| except TypeError: | |||
| @@ -12,6 +12,7 @@ | |||
| # See the License for the specific language governing permissions and | |||
| # limitations under the License. | |||
| import re | |||
| from mindspore.train import Model, ParallelMode | |||
| from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits | |||
| from mindspore.nn.optim.momentum import Momentum | |||
| @@ -89,16 +90,13 @@ def all_to_all_common(): | |||
| def test_one_dev(): | |||
| _reset_op_id() | |||
| strategys = all_to_all_common() | |||
| expect_dict = {'Default/network-_VirtualDatasetCell/_backbone-WithLossCell/_loss_fn-SoftmaxCrossEntropyWithLogits' | |||
| '/SoftmaxCrossEntropyWithLogits-op9': [[1, 1], [1, 1]], | |||
| 'Default/network-_VirtualDatasetCell/_backbone-WithLossCell/_loss_fn-SoftmaxCrossEntropyWithLogits' | |||
| '/OneHot-op10': [[1, 1], [], []], | |||
| 'Default/network-_VirtualDatasetCell/_backbone-WithLossCell/_backbone-AllToAllNet/Transpose-op11': | |||
| [[1, 1]], | |||
| 'Default/network-_VirtualDatasetCell/_backbone-WithLossCell/_backbone-AllToAllNet/MatMul-op12': | |||
| [[1, 1], [1, 1]]} | |||
| assert (strategys == expect_dict) | |||
| strategies = all_to_all_common() | |||
| for (k, v) in strategies.items(): | |||
| if re.search('SoftmaxCrossEntropyWithLogits-op', k) is not None: | |||
| assert v == [[1, 1], [1, 1]] | |||
| elif re.search('Transpose-op', k) is not None: | |||
| assert v == [[1, 1]] | |||
| elif re.search('MatMul-op', k) is not None: | |||
| assert v == [[1, 1], [1, 1]] | |||
| @@ -24,6 +24,7 @@ | |||
| import logging | |||
| import numpy as np | |||
| import mindspore.nn as nn | |||
| from mindspore import context | |||
| from mindspore.ops import operations as P | |||
| from mindspore.common.api import ms_function | |||
| from mindspore.common.tensor import Tensor | |||
| @@ -50,6 +51,7 @@ class Net(nn.Cell): | |||
| def test_create_cell_object_on_construct(): | |||
| """ test_create_cell_object_on_construct """ | |||
| log.debug("begin test_create_object_on_construct") | |||
| context.set_context(mode=context.GRAPH_MODE) | |||
| np1 = np.random.randn(2, 3, 4, 5).astype(np.float32) | |||
| input_me = Tensor(np1) | |||
| @@ -118,6 +120,7 @@ class NetC(nn.Cell): | |||
| def test_create_cell_object_on_construct_use_many_parameter(): | |||
| """ test_create_cell_object_on_construct_use_many_parameter """ | |||
| log.debug("begin test_create_object_on_construct") | |||
| context.set_context(mode=context.GRAPH_MODE) | |||
| np1 = np.random.randn(2, 3, 4, 5).astype(np.float32) | |||
| input_me = Tensor(np1) | |||
| @@ -28,5 +28,4 @@ def try_type(): | |||
| def test_dtype_convert(): | |||
| with pytest.raises(RuntimeError): | |||
| try_type() | |||
| try_type() | |||
| @@ -19,8 +19,10 @@ from mindspore.common.api import ms_function | |||
| from mindspore import Tensor | |||
| from mindspore.ops import composite as C | |||
| from mindspore.ops.composite import grad_all_with_sens | |||
| from mindspore.common.dtype import get_py_obj_dtype | |||
| import mindspore.nn as nn | |||
| import mindspore.ops.operations as P | |||
| from mindspore.ops import functional as F | |||
| from ...ut_filter import non_graph_engine | |||
| @@ -78,6 +80,20 @@ def test_cast_grad(): | |||
| assert np.all(gout[0].asnumpy() == expect) | |||
| def test_scalar_cast_grad(): | |||
| """ test_scalar_cast_grad """ | |||
| input_x = 255.5 | |||
| input_t = get_py_obj_dtype(ms.int8) | |||
| def fx_cast(x): | |||
| output = F.scalar_cast(x, input_t) | |||
| return output | |||
| gfn = C.grad(fx_cast)(input_x) | |||
| expect_dx = 1 | |||
| assert gfn == expect_dx | |||
| @non_graph_engine | |||
| def test_reshape_grad(): | |||
| """ test_reshape_grad """ | |||
| @@ -163,12 +163,7 @@ def test_scalar_summary_use_invalid_tag_None(): | |||
| def test_scalar_summary_use_invalid_tag_Bool(): | |||
| log.debug("begin test_scalar_summary_use_invalid_tag_Bool") | |||
| net = SummaryDemoTag(True, True, True) | |||
| try: | |||
| run_case(net) | |||
| except: | |||
| assert True | |||
| else: | |||
| assert False | |||
| run_case(net) | |||
| log.debug("finished test_scalar_summary_use_invalid_tag_Bool") | |||
| @@ -176,12 +171,7 @@ def test_scalar_summary_use_invalid_tag_Bool(): | |||
| def test_scalar_summary_use_invalid_tag_null(): | |||
| log.debug("begin test_scalar_summary_use_invalid_tag_null") | |||
| net = SummaryDemoTag("", "", "") | |||
| try: | |||
| run_case(net) | |||
| except: | |||
| assert True | |||
| else: | |||
| assert False | |||
| run_case(net) | |||
| log.debug("finished test_scalar_summary_use_invalid_tag_null") | |||
| @@ -189,12 +179,7 @@ def test_scalar_summary_use_invalid_tag_null(): | |||
| def test_scalar_summary_use_invalid_tag_Int(): | |||
| log.debug("begin test_scalar_summary_use_invalid_tag_Int") | |||
| net = SummaryDemoTag(1, 2, 3) | |||
| try: | |||
| run_case(net) | |||
| except: | |||
| assert True | |||
| else: | |||
| assert False | |||
| run_case(net) | |||
| log.debug("finished test_scalar_summary_use_invalid_tag_Int") | |||
| @@ -30,7 +30,7 @@ from mindspore.nn import WithLossCell, TrainOneStepCell | |||
| from mindspore.train.callback import _CheckpointManager | |||
| from mindspore.train.serialization import save_checkpoint, load_checkpoint,load_param_into_net, \ | |||
| _exec_save_checkpoint, export, _save_graph | |||
| from ..ut_filter import run_on_onnxruntime | |||
| from ..ut_filter import run_on_onnxruntime, non_graph_engine | |||
| from mindspore import context | |||
| @@ -306,6 +306,7 @@ class MYNET(nn.Cell): | |||
| return out | |||
| @non_graph_engine | |||
| def test_export(): | |||
| net = MYNET() | |||
| input_data = Tensor(np.random.randint(0, 255, [1, 3, 224, 224]).astype(np.float32)) | |||