diff --git a/.gitmodules b/.gitmodules index df7212b083..c553d137c6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,9 +10,9 @@ [submodule "third_party/protobuf"] path = third_party/protobuf url = https://github.com/protocolbuffers/protobuf.git -[submodule "graphengine"] - path = graphengine - url = https://gitee.com/mindspore/graphengine.git [submodule "akg"] path = akg url = https://gitee.com/mindspore/akg.git +[submodule "graphengine"] + path = graphengine + url = https://gitee.com/mindspore/graphengine.git diff --git a/cmake/dependency_graphengine.cmake b/cmake/dependency_graphengine.cmake index 91a471d1f2..8e1faa92c6 100644 --- a/cmake/dependency_graphengine.cmake +++ b/cmake/dependency_graphengine.cmake @@ -15,6 +15,7 @@ include(${GE_SOURCE_DIR}/cmake/external_libs/securec.cmake) if (NOT ENABLE_D) set(GE_PREBUILD_PATH ${GE_SOURCE_DIR}/third_party/prebuild/${CMAKE_HOST_SYSTEM_PROCESSOR}) find_library(slog libslog.so ${GE_PREBUILD_PATH}) + find_library(error_manager liberror_manager.so ${GE_PREBUILD_PATH}) elseif (DEFINED ENV{D_LINK_PATH}) set(GE_LIB_PATH $ENV{D_LINK_PATH}) set(GE_SYS_ARCH "") diff --git a/cmake/package.cmake b/cmake/package.cmake index 62366f707a..7b3c2f7bb2 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -156,6 +156,7 @@ if (NOT ENABLE_GE) set(ASCEND_PATH /usr/local/Ascend) endif () set(ASCEND_DRIVER_PATH ${ASCEND_PATH}/driver/lib64/common) + set(ASCEND_FWK_PATH ${ASCEND_PATH}/fwkacllib/lib64) install( FILES @@ -164,6 +165,7 @@ if (NOT ENABLE_GE) ${CMAKE_BINARY_DIR}/graphengine/src/ge/ge_runtime/libge_runtime.so ${ASCEND_DRIVER_PATH}/libslog.so ${ASCEND_DRIVER_PATH}/libc_sec.so + ${ASCEND_FWK_PATH}/liberror_manager.so DESTINATION ${INSTALL_LIB_DIR} COMPONENT mindspore ) @@ -172,6 +174,7 @@ if (NOT ENABLE_GE) FILES ${CMAKE_BINARY_DIR}/graphengine/src/common/graph/libgraph.so ${CMAKE_SOURCE_DIR}/graphengine/third_party/prebuild/${CMAKE_HOST_SYSTEM_PROCESSOR}/libslog.so + ${CMAKE_SOURCE_DIR}/graphengine/third_party/prebuild/${CMAKE_HOST_SYSTEM_PROCESSOR}/liberror_manager.so ${CMAKE_SOURCE_DIR}/build/graphengine/libc_sec.so DESTINATION ${INSTALL_LIB_DIR} COMPONENT mindspore diff --git a/graphengine b/graphengine index 18cf690152..103f2d1019 160000 --- a/graphengine +++ b/graphengine @@ -1 +1 @@ -Subproject commit 18cf690152add623ffbddfbbb4674d1b34484ca7 +Subproject commit 103f2d1019dc50d781d7a964551d9f1f50b3b009 diff --git a/mindspore/_extends/parallel_compile/tbe_compiler/common.py b/mindspore/_extends/parallel_compile/tbe_compiler/common.py index 3d55cf60a2..7287bace95 100644 --- a/mindspore/_extends/parallel_compile/tbe_compiler/common.py +++ b/mindspore/_extends/parallel_compile/tbe_compiler/common.py @@ -40,7 +40,7 @@ def get_ddk_version(): with open(backup_ddk_info_file, "r") as fp: ddk_version = json.load(fp)["VERSION"] else: - ddk_version = "1.60.T17.B830" + ddk_version = "Ascend910" return ddk_version diff --git a/mindspore/ccsrc/CMakeLists.txt b/mindspore/ccsrc/CMakeLists.txt index 4702093c0d..1ad152d71a 100644 --- a/mindspore/ccsrc/CMakeLists.txt +++ b/mindspore/ccsrc/CMakeLists.txt @@ -185,7 +185,7 @@ if (ENABLE_GE) else () target_link_libraries(mindspore ge_client) endif () - target_link_libraries(mindspore graph tsdclient) + target_link_libraries(mindspore graph tsdclient datatransfer) endif() if (ENABLE_D) @@ -216,8 +216,9 @@ if (ENABLE_D) find_library(CCE_LIB cce ${ASCEND_RUNTIME_PATH}) find_library(RUNTIME_LIB runtime ${ASCEND_RUNTIME_PATH}) find_library(TSDCLIENT tsdclient HINTS ${ASCEND_RUNTIME_PATH} ${ASCEND_DRIVER_BACK_PATH}) + find_library(DATATRANSFER datatransfer HINTS ${ASCEND_RUNTIME_PATH} ${ASCEND_DRIVER_BACK_PATH}) find_library(PROFILING msprof ${ASCEND_DRIVER_PATH}) - target_link_libraries(mindspore ge_runtime ${CCE_LIB} ${RUNTIME_LIB} ${TSDCLIENT} ${PROFILING} ${HCCL} ${TSDCLIENT}) + target_link_libraries(mindspore ge_runtime ${CCE_LIB} ${RUNTIME_LIB} ${TSDCLIENT} ${PROFILING} ${HCCL} ${DATATRANSFER}) endif() # link protobuf diff --git a/mindspore/ccsrc/backend/kernel_compiler/tbe/tbe_kernel_select/tbe_kernel_select.cc b/mindspore/ccsrc/backend/kernel_compiler/tbe/tbe_kernel_select/tbe_kernel_select.cc index d0563e0ffa..21f2347629 100644 --- a/mindspore/ccsrc/backend/kernel_compiler/tbe/tbe_kernel_select/tbe_kernel_select.cc +++ b/mindspore/ccsrc/backend/kernel_compiler/tbe/tbe_kernel_select/tbe_kernel_select.cc @@ -292,7 +292,6 @@ bool TbeKernelSelect::TbeCheckSupported( parallel::TOPK, parallel::IN_TOPK, parallel::PACK, - parallel::GATHER_ND, parallel::UNSORTEF_SEGMENT_MIND, parallel::UNSORTEF_SEGMENT_PRODD, parallel::CAST}; diff --git a/mindspore/ccsrc/backend/optimizer/ascend/ascend_backend_optimization.cc b/mindspore/ccsrc/backend/optimizer/ascend/ascend_backend_optimization.cc index 46ef1d7d53..d88727df41 100644 --- a/mindspore/ccsrc/backend/optimizer/ascend/ascend_backend_optimization.cc +++ b/mindspore/ccsrc/backend/optimizer/ascend/ascend_backend_optimization.cc @@ -23,6 +23,7 @@ #include "backend/optimizer/ascend/ir_fission/batch_norm_grad_split.h" #include "backend/optimizer/ascend/ir_fission/batch_norm_bert_fission.h" #include "backend/optimizer/ascend/ir_fission/single_batch_norm_fission.h" +#include "backend/optimizer/ascend/ir_fission/tensor_scatter_update_fission.h" #include "backend/optimizer/ascend/ir_fusion/fused_batch_norm_fusion.h" #include "backend/optimizer/ascend/ir_fission/layer_norm_grad_split.h" #include "backend/optimizer/pass/communication_op_fusion.h" @@ -154,6 +155,7 @@ void AddAscendBackendOptionalIRFusion(PassManager *ir_fusion_pm) { ir_fusion_pm->AddPass(std::make_shared()); ir_fusion_pm->AddPass(std::make_shared()); ir_fusion_pm->AddPass(std::make_shared()); + ir_fusion_pm->AddPass(std::make_shared()); ir_fusion_pm->AddPass(std::make_shared()); ir_fusion_pm->AddPass(std::make_shared()); ir_fusion_pm->AddPass(std::make_shared()); @@ -303,6 +305,7 @@ void RunOpAscendBackendIRFusionOptimization(const std::shared_ptrAddPass(std::make_shared()); ir_fusion_pm->AddPass(std::make_shared()); ir_fusion_pm->AddPass(std::make_shared()); + ir_fusion_pm->AddPass(std::make_shared()); optimizer->AddPassManager(ir_fusion_pm); (void)optimizer->Optimize(kernel_graph); diff --git a/mindspore/ccsrc/backend/optimizer/ascend/format_type/deal_ref_trans_and_cast.cc b/mindspore/ccsrc/backend/optimizer/ascend/format_type/deal_ref_trans_and_cast.cc index 3dbe2d9f8a..4375a08031 100644 --- a/mindspore/ccsrc/backend/optimizer/ascend/format_type/deal_ref_trans_and_cast.cc +++ b/mindspore/ccsrc/backend/optimizer/ascend/format_type/deal_ref_trans_and_cast.cc @@ -94,7 +94,7 @@ AnfNodePtr AddAdditionalToRefOutput(const FuncGraphPtr &func_graph, const CNodeP origin_pair = FindRefOriginNode(input_node); MS_EXCEPTION_IF_NULL(origin_pair.first); if (!origin_pair.first->isa()) { - MS_LOG(EXCEPTION) << "ref op origin node is not parameter"; + MS_LOG(WARNING) << "ref op origin node is not parameter"; } MS_LOG(DEBUG) << "DealRefTransAndCast the node input index " << input_index << ", find origin op is " << origin_pair.first->DebugString() << ", index is " << origin_pair.second; diff --git a/mindspore/ccsrc/backend/optimizer/ascend/ir_fission/tensor_scatter_update_fission.cc b/mindspore/ccsrc/backend/optimizer/ascend/ir_fission/tensor_scatter_update_fission.cc new file mode 100644 index 0000000000..c9a879e921 --- /dev/null +++ b/mindspore/ccsrc/backend/optimizer/ascend/ir_fission/tensor_scatter_update_fission.cc @@ -0,0 +1,71 @@ +/** + * 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 "backend/optimizer/ascend/ir_fission/tensor_scatter_update_fission.h" +#include +#include +#include "backend/session/anf_runtime_algorithm.h" +#include "backend/optimizer/common/helper.h" + +namespace mindspore { +namespace opt { +namespace { +CNodePtr CreateTensorMove(const FuncGraphPtr &graph, const CNodePtr &tensor_scatter_update) { + MS_EXCEPTION_IF_NULL(graph); + MS_EXCEPTION_IF_NULL(tensor_scatter_update); + std::vector inputs = {NewValueNode(std::make_shared(kTensorMoveOpName)), + tensor_scatter_update->input(1)}; + auto tensor_move = graph->NewCNode(inputs); + MS_EXCEPTION_IF_NULL(tensor_move); + tensor_move->set_scope(tensor_scatter_update->scope()); + tensor_move->set_abstract(tensor_scatter_update->abstract()); + AnfAlgo::SetNodeAttr(kAttrUseLocking, MakeValue(false), tensor_move); + return tensor_move; +} + +CNodePtr CreateScatterNdUpdate(const FuncGraphPtr &graph, const CNodePtr &tensor_scatter_update, + const CNodePtr &tensor_move) { + MS_EXCEPTION_IF_NULL(graph); + MS_EXCEPTION_IF_NULL(tensor_scatter_update); + MS_EXCEPTION_IF_NULL(tensor_move); + std::vector inputs = {NewValueNode(std::make_shared(kScatterNdUpdateOpName)), tensor_move, + tensor_scatter_update->input(2), tensor_scatter_update->input(3)}; + auto scatter_nd_update = graph->NewCNode(inputs); + MS_EXCEPTION_IF_NULL(scatter_nd_update); + scatter_nd_update->set_scope(tensor_scatter_update->scope()); + scatter_nd_update->set_abstract(tensor_scatter_update->abstract()); + return scatter_nd_update; +} +} // namespace + +const BaseRef TensorScatterUpdateFission::DefinePattern() const { + VarPtr Xs = std::make_shared(); + auto prim = std::make_shared(kTensorScatterUpdateOpName); + return VectorRef({prim, Xs}); +} + +const AnfNodePtr TensorScatterUpdateFission::Process(const FuncGraphPtr &func_graph, const AnfNodePtr &node, + const EquivPtr &) const { + MS_EXCEPTION_IF_NULL(func_graph); + MS_EXCEPTION_IF_NULL(node); + auto tensor_scatter_update = node->cast(); + if (tensor_scatter_update == nullptr || tensor_scatter_update->size() != 4) { + return nullptr; + } + auto tensor_move = CreateTensorMove(func_graph, tensor_scatter_update); + return CreateScatterNdUpdate(func_graph, tensor_scatter_update, tensor_move); +} +} // namespace opt +} // namespace mindspore diff --git a/mindspore/ccsrc/backend/optimizer/ascend/ir_fission/tensor_scatter_update_fission.h b/mindspore/ccsrc/backend/optimizer/ascend/ir_fission/tensor_scatter_update_fission.h new file mode 100644 index 0000000000..0f7efb029c --- /dev/null +++ b/mindspore/ccsrc/backend/optimizer/ascend/ir_fission/tensor_scatter_update_fission.h @@ -0,0 +1,33 @@ +/** + * 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_PRE_ACTIVATE_ASCEND_IR_FISSION_TENSOR_SCATTER_UPDATE_FISSION_H_ +#define MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FISSION_TENSOR_SCATTER_UPDATE_FISSION_H_ + +#include "backend/optimizer/common/optimizer.h" + +namespace mindspore { +namespace opt { +class TensorScatterUpdateFission : public PatternProcessPass { + public: + explicit TensorScatterUpdateFission(bool multigraph = true) + : PatternProcessPass("tensor_scatter_update_fission", multigraph) {} + ~TensorScatterUpdateFission() override = default; + const BaseRef DefinePattern() const override; + const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override; +}; +} // namespace opt +} // namespace mindspore +#endif // MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_IR_FISSION_TENSOR_SCATTER_UPDATE_FISSION_H_ diff --git a/mindspore/ccsrc/operator/prim_structures.cc b/mindspore/ccsrc/operator/prim_structures.cc new file mode 100644 index 0000000000..68215d5e58 --- /dev/null +++ b/mindspore/ccsrc/operator/prim_structures.cc @@ -0,0 +1,707 @@ +/** + * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). + * + * 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. + */ + +#include "pipeline/static_analysis/prim.h" +#include "pipeline/static_analysis/utils.h" +#include "pipeline/static_analysis/param_validator.h" +#include "operator/ops.h" +#include "utils/convert_utils.h" +#include "ir/tensor_py.h" + +using mindspore::tensor::TensorPy; + +namespace mindspore { +namespace abstract { + +AbstractBasePtr InferImplStringEqual(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: two scalars whose value is a string. + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 2); + AbstractScalarPtr scalar_x = CheckArg(op_name, args_spec_list, 0); + AbstractScalarPtr scalar_y = CheckArg(op_name, args_spec_list, 1); + + ValuePtr value_x = scalar_x->BuildValue(); + ValuePtr value_y = scalar_y->BuildValue(); + if (!value_x->isa() || !value_y->isa()) { + MS_LOG(EXCEPTION) << op_name << " requires 2 parameters are string, but got param0: " << value_x->ToString() + << ", param1: " << value_y->ToString(); + } + + bool ret = (value_x->cast()->value() == value_y->cast()->value()); + return std::make_shared(ret); +} + +AbstractBasePtr InferImplStringConcat(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: two scalars whose value is a string. + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 2); + AbstractScalarPtr scalar_x = CheckArg(op_name, args_spec_list, 0); + AbstractScalarPtr scalar_y = CheckArg(op_name, args_spec_list, 1); + + ValuePtr value_x = scalar_x->BuildValue(); + ValuePtr value_y = scalar_y->BuildValue(); + if (!value_x->isa() || !value_y->isa()) { + MS_LOG(EXCEPTION) << op_name << " requires 2 parameters are string, but got param0: " << value_x->ToString() + << ", param1: " << value_y->ToString(); + } + + std::string ret = (value_x->cast()->value() + value_y->cast()->value()); + return std::make_shared(ret); +} + +AbstractBasePtr InferImplMakeTuple(const AnalysisEnginePtr &, const PrimitivePtr &, + const AbstractBasePtrList &args_spec_list) { + return std::make_shared(args_spec_list); +} + +AbstractBasePtr InferImplMakeList(const AnalysisEnginePtr &, const PrimitivePtr &, + const AbstractBasePtrList &args_spec_list) { + return std::make_shared(args_spec_list); +} + +AbstractBasePtr InferImplMakeDict(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: two tuples. + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 2); + AbstractTuplePtr keys = CheckArg(op_name, args_spec_list, 0); + AbstractTuplePtr values = CheckArg(op_name, args_spec_list, 1); + + size_t keys_size = keys->size(); + if (values->size() != keys_size) { + MS_LOG(EXCEPTION) << op_name << " evaluator keys' size is not equal with values' size"; + } + + std::vector key_value; + AbstractScalarPtr key; + AbstractBasePtrList key_list = keys->elements(); + AbstractBasePtrList value_list = values->elements(); + for (size_t index = 0; index < keys_size; index++) { + key = CheckArg(op_name + "key", key_list, index); + ValuePtr keyPtr = key->BuildValue(); + MS_EXCEPTION_IF_NULL(keyPtr); + if (!keyPtr->isa()) { + MS_LOG(EXCEPTION) << op_name << " evaluator keys should be string, but got " << keyPtr->ToString(); + } + std::string key_string = GetValue(keyPtr); + key_value.emplace_back(key_string, value_list[index]); + } + return std::make_shared(key_value); +} + +AbstractBasePtr InferImplMakeKwarg(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: a string and an object of a subclass of AbstractBase. + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 2); + AbstractScalarPtr key = CheckArg(op_name, args_spec_list, 0); + + ValuePtr keyPtr = key->BuildValue(); + if (!keyPtr->isa()) { + MS_LOG(EXCEPTION) << op_name << " evaluator key should be string, but got " << keyPtr->ToString(); + } + std::string key_string = GetValue(keyPtr); + return std::make_shared(key_string, args_spec_list[1]); +} + +AbstractBasePtr InferImplExtractKwarg(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: a string and a keyword. + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 2); + AbstractScalarPtr key = CheckArg(op_name, args_spec_list, 0); + AbstractKeywordArgPtr kwarg = CheckArg(op_name, args_spec_list, 1); + + ValuePtr key_value = key->BuildValue(); + if (!key_value->isa()) { + MS_LOG(EXCEPTION) << op_name << " evaluator key should be string, but got " << key_value->ToString(); + } + std::string key_input = GetValue(key_value); + std::string key_actual = kwarg->get_key(); + if (key_actual != key_input) { + MS_LOG(EXCEPTION) << op_name << " evaluator input key should be same as AbstractKeywordArg' key, but input is " + << key_input << ", AbstractKeywordArg' key is " << key_actual; + } + return kwarg->get_arg(); +} + +AbstractBasePtr InferImplMakeSlice(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: three scalars whose value is an int32 number. + CheckArgsSize(primitive->name(), args_spec_list, 3); + size_t args_size = args_spec_list.size(); + for (size_t index = 0; index < args_size; index++) { + MS_EXCEPTION_IF_NULL(args_spec_list[index]); + if (!args_spec_list[index]->isa() && !args_spec_list[index]->isa()) { + MS_LOG(EXCEPTION) << "MakeSlice eval " << index << " parameter is neither AbstractScalar nor AbstractNone."; + } + if (args_spec_list[index]->isa() && + !dyn_cast(args_spec_list[index])->BuildValue()->isa()) { + MS_LOG(EXCEPTION) << "MakeSlice eval " << index << " parameter is an AbstractScalar, but is not an int32 number."; + } + } + // Slice: start, end, step + return std::make_shared(args_spec_list[0], args_spec_list[1], args_spec_list[2]); +} + +// Eval the return type of make_record +AbstractBasePtr InferImplMakeRecord(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: at lease two objects of a subclass of AbstractBase. + if (args_spec_list.size() < 2) { + MS_LOG(EXCEPTION) << "Typeof evaluator requires more than 1 parameter, while the input size is " + << args_spec_list.size() << "."; + } + + // args_spec_list[0] maybe AbstractScalarPtr or AbstractTypePtr + MS_EXCEPTION_IF_NULL(args_spec_list[0]); + TypePtr type = args_spec_list[0]->GetTypeTrack(); + MS_EXCEPTION_IF_NULL(type); + if (type->type_id() != kMetaTypeTypeType) { + MS_LOG(EXCEPTION) << "Can not make type(" << type->ToString() << ")not TypeType"; + } + + ValuePtr value_track = args_spec_list[0]->GetValueTrack(); + MS_EXCEPTION_IF_NULL(value_track); + TypePtr type_ptr = value_track->cast(); + if (type_ptr == nullptr) { + MS_LOG(EXCEPTION) << "Value type error, not Me type:" << value_track->ToString(); + } + + auto cls = dyn_cast(type_ptr); + MS_EXCEPTION_IF_NULL(cls); + ClassAttrVector attributes = cls->GetAttributes(); + CheckArgsSize(primitive->name(), args_spec_list, attributes.size() + 1); + + std::vector abs_attributes; + for (size_t i = 0; i < attributes.size(); i++) { + AbstractAttribute elem(attributes[i].first, args_spec_list[i + 1]); + abs_attributes.push_back(elem); + } + + return std::make_shared(cls->tag(), abs_attributes, cls->methods()); +} + +template +AbstractBasePtr InferTupleOrListGetItem(const std::string &op_name, const AbstractBasePtrList &args_spec_list) { + // Inputs: a tuple or list and a scalar whose value is an int32 number. + CheckArgsSize(op_name, args_spec_list, 2); + auto queue = CheckArg(op_name, args_spec_list, 0); + AbstractScalarPtr index = CheckArg(op_name, args_spec_list, 1); + + ValuePtr index_value = index->BuildValue(); + if (!index_value->isa()) { + MS_EXCEPTION(IndexError) << op_name << " evaluator index should be an int32 number, but got " + << index_value->ToString(); + } + int idx_v = GetValue(index_value); + std::size_t nelems = queue->elements().size(); + if (idx_v >= SizeToInt(nelems) || idx_v < -SizeToInt(nelems)) { + MS_EXCEPTION(IndexError) << op_name << " evaluator index should be in range[-" << SizeToInt(nelems) << ", " + << SizeToInt(nelems) << "), but got " << idx_v << "."; + } + + std::size_t uidx_v = 0; + if (idx_v >= 0) { + uidx_v = IntToSize(idx_v); + } else { + uidx_v = IntToSize(idx_v + SizeToInt(nelems)); + } + return queue->elements()[uidx_v]; +} + +template +AbstractBasePtr InferTupleOrListSetItem(const std::string &op_name, const AbstractBasePtrList &args_spec_list) { + // Inputs: a tuple or list, a scalar whose value is an int32 number and an object of a subclass of AbstractBase. + CheckArgsSize(op_name, args_spec_list, 3); + auto queue = CheckArg(op_name, args_spec_list, 0); + AbstractScalarPtr index = CheckArg(op_name, args_spec_list, 1); + + ValuePtr index_value = index->BuildValue(); + if (!index_value->isa()) { + MS_EXCEPTION(IndexError) << op_name << " evaluator index should be an int32 number, but got " + << index_value->ToString(); + } + int idx_v = GetValue(index_value); + if (idx_v < 0) { + MS_EXCEPTION(IndexError) << "The index of " << typeid(T).name() << " should be positive number, but got " << idx_v + << "."; + } + + size_t uidx_v = IntToSize(idx_v); + AbstractBasePtrList elements = queue->elements(); + std::size_t nelems = elements.size(); + if (uidx_v >= nelems) { + MS_EXCEPTION(IndexError) << op_name << " evaluator the index: " << uidx_v << " to set out of range: " << nelems - 1 + << "."; + } + elements[uidx_v] = args_spec_list[2]; + return std::make_shared(elements); +} + +AbstractBasePtr InferImplTupleGetItem(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + return InferTupleOrListGetItem(primitive->name(), args_spec_list); +} + +AbstractBasePtr InferImplListGetItem(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + return InferTupleOrListGetItem(primitive->name(), args_spec_list); +} + +AbstractBasePtr InferImplTupleSetItem(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + return InferTupleOrListSetItem(primitive->name(), args_spec_list); +} + +AbstractBasePtr InferImplListSetItem(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + return InferTupleOrListSetItem(primitive->name(), args_spec_list); +} + +AbstractBasePtr InferImplDictGetItem(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: a dict and a scalar whose value is a string. + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 2); + AbstractDictionaryPtr dict = CheckArg(op_name, args_spec_list, 0); + AbstractScalarPtr key = CheckArg(op_name, args_spec_list, 1); + + ValuePtr key_value = key->BuildValue(); + if (!key_value->isa()) { + MS_LOG(EXCEPTION) << op_name << " evaluator key should be string, but got " << key_value->ToString(); + } + auto key_str = GetValue(key_value); + std::vector dict_elems = dict->elements(); + auto it = std::find_if(dict_elems.begin(), dict_elems.end(), + [key_str](const AbstractAttribute &item) { return item.first == key_str; }); + + if (it == dict_elems.end()) { + MS_LOG(EXCEPTION) << "The key " << key_str << " does not exist in the dict:" << args_spec_list[0]->ToString(); + } + return it->second; +} + +AbstractBasePtr InferImplDictSetItem(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: a dict and a scalar whose value is a string and an object of a subclass of AbstractBase. + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 3); + AbstractDictionaryPtr dict = CheckArg(op_name, args_spec_list, 0); + AbstractScalarPtr key = CheckArg(op_name, args_spec_list, 1); + + ValuePtr key_value = key->BuildValue(); + if (!key_value->isa()) { + MS_LOG(EXCEPTION) << op_name << " evaluator key should be string, but got " << key_value->ToString(); + } + std::string key_str = GetValue(key_value); + std::vector dict_elems = dict->elements(); + auto it = std::find_if(dict_elems.begin(), dict_elems.end(), + [key_str](AbstractAttribute &item) { return item.first == key_str; }); + + MS_EXCEPTION_IF_NULL(args_spec_list[2]); + auto new_ele = std::make_pair(key_str, args_spec_list[2]); + if (it != dict_elems.end()) { + int index = it - dict_elems.begin(); + dict_elems[IntToSize(index)] = new_ele; + } else { + dict_elems.push_back(new_ele); + } + return std::make_shared(dict_elems); +} + +AbstractBasePtr InferImplListAppend(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: a list and an object of a subclass of AbstractBase. + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 2); + AbstractListPtr list = CheckArg(op_name, args_spec_list, 0); + (void)AbstractJoin(list->elements()); + return list; +} + +template +AbstractBasePtr InferTupleOrListOrDictLen(const std::string &op_name, const AbstractBasePtrList &args_spec_list) { + // Inputs: a tuple or list or dict. + CheckArgsSize(op_name, args_spec_list, 1); + auto arg = CheckArg(op_name, args_spec_list, 0); + return std::make_shared(SizeToInt(arg->size())); +} + +AbstractBasePtr InferImplTupleLen(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + return InferTupleOrListOrDictLen(primitive->name(), args_spec_list); +} + +AbstractBasePtr InferImplListLen(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + return InferTupleOrListOrDictLen(primitive->name(), args_spec_list); +} + +AbstractBasePtr InferImplDictLen(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + return InferTupleOrListOrDictLen(primitive->name(), args_spec_list); +} + +AbstractBasePtr InferImplArrayLen(const AnalysisEnginePtr &, const PrimitivePtr &, + const AbstractBasePtrList &args_spec_list) { + return std::make_shared(kAnyValue, kInt32); +} + +AbstractBasePtr InferImplListMap(const AnalysisEnginePtr &engine, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: fn, list1, list2, ... + MS_EXCEPTION_IF_NULL(engine); + if (args_spec_list.size() <= 1) { + MS_LOG(EXCEPTION) << "List_map requires at least 1 list. while the input size is " << args_spec_list.size() << "."; + } + AbstractFunctionPtr fn = CheckArg(primitive->name(), args_spec_list, 0); + // check args from 1. + CheckArgsSpec(AbstractBasePtrList(args_spec_list.begin() + 1, args_spec_list.end())); + + AbstractBasePtrList subargs; + for (std::size_t i = 1; i < args_spec_list.size(); i++) { + AbstractListPtr l_ptr = dyn_cast(args_spec_list[i]); + if (l_ptr == nullptr) { + MS_LOG(EXCEPTION) << "Argument[" << i << "] of list_map should be a list."; + } + subargs.push_back(AbstractJoin(l_ptr->elements())); + } + EvalResultPtr engin_exc = engine->Execute(fn, subargs); + AbstractBasePtrList result; + for (std::size_t i = 1; i < args_spec_list.size(); i++) { + result.push_back(engin_exc->abstract()); + } + return std::make_shared(result); +} + +AbstractBasePtr InferImplListReduce(const AnalysisEnginePtr &engine, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: a fn, a list and an object of a subclass of a AbstractBase. + MS_EXCEPTION_IF_NULL(engine); + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 3); + AbstractFunctionPtr fn = CheckArg(op_name, args_spec_list, 0); + AbstractListPtr lst = CheckArg(op_name, args_spec_list, 1); + AbstractBasePtr dflt = args_spec_list[2]; + + AbstractBasePtr list_type = AbstractJoin(lst->elements()); + auto result1 = engine->Execute(fn, lst->elements()); + auto result2 = engine->Execute(fn, {dflt, list_type}); + MS_EXCEPTION_IF_NULL(result1->abstract()); + MS_EXCEPTION_IF_NULL(result2->abstract()); + return result1->abstract()->Join(result2->abstract()); +} + +AbstractBasePtr InferImplTupleReversed(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: a tuple + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 1); + AbstractTuplePtr input = CheckArg(op_name, args_spec_list, 0); + + auto tuple_elements = input->elements(); + AbstractBasePtrList elem_list; + (void)std::transform(tuple_elements.rbegin(), tuple_elements.rend(), std::back_inserter(elem_list), + [](const AbstractBasePtr &elem) { return elem->Clone(); }); + return std::make_shared(elem_list); +} + +AbstractBasePtr DoInferReduceShape(const AbstractTuplePtr &x_shape, const ValuePtr &x_shp_value, + const ValueTuplePtr &axis_value_ptr, const PrimitivePtr &primitive) { + size_t x_rank = x_shape->size(); + std::set axis_set; + auto axis_data = axis_value_ptr->value(); + if (axis_data.empty()) { + int size = 1; + AbstractBasePtrList values(x_rank, std::make_shared(size)); + return std::make_shared(values); + } + + for (auto &elem : axis_data) { + int e_value = CheckAxis(primitive->name(), elem, -SizeToInt(x_rank), SizeToInt(x_rank) - 1); + (void)axis_set.insert(e_value); + } + + auto x_shp_data = x_shp_value->cast()->value(); + if (x_shp_data.size() < x_rank) { + MS_LOG(EXCEPTION) << "x_shape_data.size() " << x_shp_data.size() << " less than x_shape.size() " << x_rank; + } + AbstractBasePtrList values; + for (size_t i = 0; i < x_rank; i++) { + if (axis_set.count(SizeToInt(i)) || axis_set.count(SizeToInt(i) - SizeToInt(x_rank))) { + auto axis_v = MakeValue(1); + values.push_back(std::make_shared(axis_v, axis_v->type())); + } else { + int dim_value = x_shp_data[i]->cast()->value(); + auto dim = MakeValue(dim_value); + values.push_back(std::make_shared(dim, dim->type())); + } + } + + return std::make_shared(values); +} + +AbstractBasePtr InferImplReduceShape(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: x_shape, axis + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 2); + AbstractTuplePtr shape_x = CheckArg(op_name, args_spec_list, 0); + MS_EXCEPTION_IF_NULL(args_spec_list[1]); + + auto x_shp_value = shape_x->BuildValue(); + if (x_shp_value->isa()) { + MS_LOG(EXCEPTION) << op_name + << " evaluator shape's data field can't be anything: " << args_spec_list[1]->ToString(); + } + + // Axis can be scalar, tuple or None + AbstractTuplePtr axis = nullptr; + if (args_spec_list[1]->isa()) { + MS_LOG(DEBUG) << op_name << " evaluator second parameter is scalar"; + AbstractBasePtrList axis_list = {dyn_cast(args_spec_list[1])}; + axis = std::make_shared(axis_list); + } else if (args_spec_list[1]->isa()) { + MS_LOG(DEBUG) << op_name << " evaluator second parameter is tuple"; + axis = args_spec_list[1]->cast(); + } else { + MS_LOG(EXCEPTION) << op_name << " evaluator second parameter should be a scalar or tuple, but got " + << args_spec_list[1]->ToString(); + } + + auto axis_value = axis->BuildValue(); + if (axis_value->isa()) { + MS_LOG(EXCEPTION) << op_name + << " evaluator shape's data field can't be anything: " << args_spec_list[1]->ToString(); + } + auto axis_value_ptr = axis_value->cast(); + MS_EXCEPTION_IF_NULL(axis_value_ptr); + + return DoInferReduceShape(shape_x, x_shp_value, axis_value_ptr, primitive); +} + +AbstractBasePtr InferImplTupleDiv(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: two tuples. + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 2); + AbstractTuplePtr shape_x = CheckArg(op_name, args_spec_list, 0); + AbstractTuplePtr div_shp = CheckArg(op_name, args_spec_list, 1); + MS_LOG(INFO) << "DivShape input:" << shape_x->ToString() << ", div:" << div_shp->ToString(); + + auto div_shp_value = div_shp->BuildValue(); + if (div_shp_value->isa()) { + MS_LOG(EXCEPTION) << "shape's data field can't be anythin: " << args_spec_list[0]->ToString(); + } + + auto shpx_value = shape_x->BuildValue(); + if (shpx_value->isa()) { + MS_LOG(EXCEPTION) << "shape's data field can't be anythin: " << args_spec_list[1]->ToString(); + } + + if (div_shp->size() != shape_x->size()) { + MS_LOG(EXCEPTION) << "tileshape elems shape must the same div_shp: " << div_shp->size() + << ", shapex: " << shape_x->size() << "."; + } + + auto shpx_data = shpx_value->cast()->value(); + auto div_shp_data = div_shp_value->cast()->value(); + AbstractBasePtrList values; + + for (size_t i = 0; i < div_shp_data.size(); i++) { + if (div_shp_data[i]->cast() == nullptr) { + MS_LOG(EXCEPTION) << "div_shp_shape data should be an int32 number, but it's " << args_spec_list[1]->ToString(); + } + int shapex_value = GetValue(shpx_data[i]); + int div_value = GetValue(div_shp_data[i]); + MS_LOG(DEBUG) << "div_shp_shape data shapex_value :" << shapex_value << " div_value: " << div_value; + if (div_value == 0) { + MS_LOG(EXCEPTION) << "error: division value should not be 0!"; + } + if ((shapex_value % div_value) != 0) { + MS_LOG(EXCEPTION) << "div_shp_shape data shapex must div int:" << shapex_value << " div_value: " << div_value; + } + + int result = shapex_value / div_value; + auto result_v = MakeValue(result); + values.push_back(std::make_shared(result_v, result_v->type())); + } + + return std::make_shared(values); +} + +AbstractBasePtr InferImplTuple2Array(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: a tuple + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 1); + AbstractTuplePtr input = CheckArg(op_name, args_spec_list, 0); + + py::tuple data_tuple = ValuePtrToPyData(input->BuildValue()); + py::array data = py::array(data_tuple); + auto tensor = TensorPy::MakeTensor(data); + auto ret = tensor->ToAbstract(); + ret->set_value(tensor); + MS_LOG(DEBUG) << "Tuple2arry result AbstractTensor: " << ret->ToString(); + return ret; +} + +AbstractBasePtr InferImplShapeMul(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: a tuple + // example: tuple = (1, 2, 3), shape_mul(tuple) = 1*2*3 = 6 + const std::string op_name = primitive->name(); + CheckArgsSize(op_name, args_spec_list, 1); + AbstractTuplePtr shape_x = CheckArg(op_name, args_spec_list, 0); + + auto shpx_value = shape_x->BuildValue(); + if (shpx_value->isa()) { + MS_LOG(EXCEPTION) << "shape's data field can't be anythin: " << shape_x->ToString(); + } + + auto shpx_data = shpx_value->cast()->value(); + + int result = 1; + for (size_t i = 0; i < shpx_data.size(); i++) { + int value = GetValue(shpx_data[i]); + result = IntMulWithOverflowCheck(result, value); + } + + auto result_v = MakeValue(result); + MS_LOG(DEBUG) << "shape mul result:" << result_v->ToString(); + return std::make_shared(result_v, result_v->type()); +} + +template +AbstractBasePtr InferImplTupleOrListEqual(const std::string &op_name, const AbstractBasePtrList &args_spec_list) { + // Inputs: two tuples or two lists. + CheckArgsSize(op_name, args_spec_list, 2); + auto input_x = CheckArg(op_name, args_spec_list, 0); + auto input_y = CheckArg(op_name, args_spec_list, 1); + + ValuePtr x_value = input_x->BuildValue(); + ValuePtr y_value = input_y->BuildValue(); + return std::make_shared(*x_value == *y_value); +} + +AbstractBasePtr InferImplTupleEqual(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + return InferImplTupleOrListEqual(primitive->name(), args_spec_list); +} + +AbstractBasePtr InferImplListEqual(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + return InferImplTupleOrListEqual(primitive->name(), args_spec_list); +} + +struct SlideInfo { + int start; + int step; + int stop; +}; + +void CalcSlidePara(const AbstractBasePtrList &args_spec_list, SlideInfo *slide) { + int arg1 = 0; + int arg2 = 0; + if (!args_spec_list.empty()) { + MS_EXCEPTION_IF_NULL(args_spec_list[0]); + auto arg_value = args_spec_list[0]->BuildValue(); + if (!arg_value->isa()) { + MS_LOG(EXCEPTION) << "Only supported input an int32 number."; + } + arg1 = GetValue(arg_value); + } + + if (args_spec_list.size() >= 2) { + MS_EXCEPTION_IF_NULL(args_spec_list[1]); + auto arg_value = args_spec_list[1]->BuildValue(); + if (!arg_value->isa()) { + MS_LOG(EXCEPTION) << "Only supported input an int32 number."; + } + arg2 = GetValue(arg_value); + } + + if (args_spec_list.size() == 3) { + MS_EXCEPTION_IF_NULL(args_spec_list[2]); + auto arg_value = args_spec_list[2]->BuildValue(); + if (!arg_value->isa()) { + MS_LOG(EXCEPTION) << "Only supported input an int32 number."; + } + slide->step = GetValue(arg_value); + slide->start = arg1; + slide->stop = arg2; + } + + if (args_spec_list.size() == 2) { + slide->start = arg1; + slide->stop = arg2; + } + + if (args_spec_list.size() == 1) { + slide->stop = arg1; + } +} + +AbstractBasePtr InferImplMakeRange(const AnalysisEnginePtr &, const PrimitivePtr &, + const AbstractBasePtrList &args_spec_list) { + if (args_spec_list.empty()) { + MS_LOG(EXCEPTION) << "Cannot make range from empty input."; + } + + if (args_spec_list.size() > 3) { + MS_LOG(EXCEPTION) << "Error args size of make range operational."; + } + + SlideInfo slide = {0, 1, 0}; + CalcSlidePara(args_spec_list, &slide); + + if (slide.step == 0) { + MS_LOG(EXCEPTION) << "Error, step value is 0."; + } + + AbstractBasePtrList args; + if (slide.start <= slide.stop) { + if (slide.step <= 0) { + MS_LOG(EXCEPTION) << "Error slice[" << slide.start << ", " << slide.stop << ", " << slide.step << "]"; + } + for (int i = slide.start; i < slide.stop; i += slide.step) { + args.push_back(abstract::FromValue(i)); + } + } else { + if (slide.step >= 0) { + MS_LOG(EXCEPTION) << "Error slice[" << slide.start << ", " << slide.stop << ", " << slide.step << "]"; + } + for (int i = slide.start; i > slide.stop; i += slide.step) { + args.push_back(abstract::FromValue(i)); + } + } + + return std::make_shared(args); +} + +AbstractBasePtr InferImplStopGradient(const AnalysisEnginePtr &, const PrimitivePtr &primitive, + const AbstractBasePtrList &args_spec_list) { + // Inputs: a tensor + CheckArgsSize(primitive->name(), args_spec_list, 1); + return args_spec_list[0]->Clone(); +} +} // namespace abstract +} // namespace mindspore diff --git a/mindspore/ccsrc/optimizer/irpass/ref_eliminate.h b/mindspore/ccsrc/optimizer/irpass/ref_eliminate.h new file mode 100644 index 0000000000..a9e4659eae --- /dev/null +++ b/mindspore/ccsrc/optimizer/irpass/ref_eliminate.h @@ -0,0 +1,93 @@ +/** + * 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_OPTIMIZER_IRPASS_REF_ELIMINATE_H_ +#define MINDSPORE_CCSRC_OPTIMIZER_IRPASS_REF_ELIMINATE_H_ + +#include + +#include "ir/pattern_matcher.h" +#include "optimizer/irpass.h" +#include "optimizer/optimizer.h" + +namespace mindspore { +namespace opt { +namespace irpass { +// {prim::kPrimMakeRef, X, Y, Z} -> Y +class MakeRefEliminater : public OptimizerCaller { + public: + AnfNodePtr operator()(const OptimizerPtr &, const AnfNodePtr &node) override { + PatternNode x, y, z; + MATCH_REPLACE(node, PPrimitive(prim::kPrimMakeRef, x, y, z), y); + return nullptr; + } +}; + +// {prim::kPrimGetRefValue, Parameter} -> Parameter +// {prim::kPrimGetRefOrigin, Parameter} -> Parameter +class GetRefParamEliminater : public OptimizerCaller { + public: + AnfNodePtr operator()(const OptimizerPtr &, const AnfNodePtr &node) override { + PatternNode x; + MATCH_REPLACE_IF(node, PPrimitive(prim::kPrimGetRefValue, x), x, x.CheckFunc(IsParam, node)); + MATCH_REPLACE_IF(node, PPrimitive(prim::kPrimGetRefOrigin, x), x, x.CheckFunc(IsParam, node)); + return nullptr; + } +}; + +// {prim::kPrimGetRefKey, {prim::kPrimMakeRef, X, Y, Z}} -> X +// {prim::kPrimGetRefValue, {prim::kPrimMakeRef, X, Y, Z}} -> Y +// {prim::kPrimGetRefOrigin, {prim::kPrimMakeRef, X, Y, Z}} -> Z +class GetMakeRefEliminater : public OptimizerCaller { + public: + AnfNodePtr operator()(const OptimizerPtr &, const AnfNodePtr &node) override { + PatternNode x, y, z; + MATCH_REPLACE(node, PPrimitive(prim::kPrimGetRefKey, PPrimitive(prim::kPrimMakeRef, x, y, z)), x); + MATCH_REPLACE(node, PPrimitive(prim::kPrimGetRefValue, PPrimitive(prim::kPrimMakeRef, x, y, z)), y); + MATCH_REPLACE(node, PPrimitive(prim::kPrimGetRefOrigin, PPrimitive(prim::kPrimMakeRef, x, y, z)), z); + return nullptr; + } +}; + +// IsValueNode +class ReplaceRefkeyByParam : public OptimizerCaller { + public: + AnfNodePtr operator()(const OptimizerPtr &optimizer, const AnfNodePtr &node) override { + auto RefKeyLambda = [&node, &optimizer]() -> AnfNodePtr { + auto refkey = GetValueNode(node); + auto resource = std::dynamic_pointer_cast(optimizer->resource()); + MS_EXCEPTION_IF_NULL(resource); + + auto top_graph = resource->func_graph(); + MS_EXCEPTION_IF_NULL(top_graph); + + for (const auto &tnode : top_graph->parameters()) { + auto para = tnode->cast(); + if (para != nullptr && para->name() == refkey->tag()) { + return para; + } + } + return nullptr; + }; + PatternNode x; + MATCH_REPLACE_LAMBDA_IF(node, x, RefKeyLambda, x.CheckFunc(IsValueNode, node)); + return nullptr; + } +}; +} // namespace irpass +} // namespace opt +} // namespace mindspore +#endif // MINDSPORE_CCSRC_OPTIMIZER_IRPASS_REF_ELIMINATE_H_ diff --git a/mindspore/ccsrc/parallel/graph_util/generate_graph.cc b/mindspore/ccsrc/parallel/graph_util/generate_graph.cc new file mode 100644 index 0000000000..4db912f63e --- /dev/null +++ b/mindspore/ccsrc/parallel/graph_util/generate_graph.cc @@ -0,0 +1,175 @@ +/** + * 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. + */ + +#include "parallel/graph_util/generate_graph.h" + +#include +#include +#include +#include + +using mindspore::tensor::Tensor; + +namespace mindspore { +namespace parallel { +std::string GetOpPythonPath(const OperatorName &op_name) { + // almost all ops are defined in two main paths + const std::string ops_module = OP_PATH; + const std::string inner_ops_module = INNER_OP_PATH; + py::module mod = py::module::import(common::SafeCStr(ops_module)); + py::module inner_mod = py::module::import(common::SafeCStr(inner_ops_module)); + if (!py::hasattr(inner_mod, common::SafeCStr(op_name))) { + if (!py::hasattr(mod, common::SafeCStr(op_name))) { + MS_LOG(EXCEPTION) << ops_module << " or " << inner_ops_module << " don't have op:" << op_name; + } + return ops_module; + } + return inner_ops_module; +} + +ValuePtr CreatOpInstance(const OperatorAttrs &attrs, const OperatorName &op_name, const std::string &instance_name) { + std::string op_path = GetOpPythonPath(op_name); + py::module mod = py::module::import(common::SafeCStr(op_path)); + if (!py::hasattr(mod, common::SafeCStr(op_name))) { + MS_LOG(ERROR) << "Failure: op_path:" << op_path << " don't have attr " << op_name; + return nullptr; + } + std::vector arg_list; + (void)std::transform(attrs.begin(), attrs.end(), std::back_inserter(arg_list), + [](const Attr &attr) { return ValuePtrToPyData(attr.second); }); + py::object obj = + parse::python_adapter::CallPyFn(GET_OP_FUNCTION_PATH, GET_OP_FUNCTION, op_name, op_path, instance_name, arg_list); + ValuePtr op_instance = nullptr; + bool succ = parse::ConvertData(obj, &op_instance); + if (!succ) { + MS_LOG(ERROR) << "Failure:get Python op " << op_path << " from " << op_name << " fail"; + return nullptr; + } + return op_instance; +} + +AnfNodePtr ValuePtrToAnfNodePtr(const ValuePtr &value_ptr) { + auto value_node = NewValueNode(value_ptr); + MS_EXCEPTION_IF_NULL(value_node); + return value_node->cast(); +} + +static std::unordered_map int_tensor_map = {}; +AnfNodePtr CreateInt32Tensor(int32_t value) { + auto it = int_tensor_map.find(value); + if (it != int_tensor_map.end()) { + return it->second; + } + mindspore::tensor::TensorPtr tensor_ptr = std::make_shared(py::int_(value), kInt32); + ValuePtr value_ptr = MakeValue(tensor_ptr); + auto anf_node_ptr = ValuePtrToAnfNodePtr(value_ptr); + int_tensor_map[value] = anf_node_ptr; + return anf_node_ptr; +} + +AnfNodePtr CreatTypeInt(int32_t value) { + ValuePtr value_ptr = MakeValue(std::make_shared(value)); + return ValuePtrToAnfNodePtr(value_ptr); +} + +AnfNodePtr CreatInt32Imm(int32_t value) { + ValuePtr value_ptr = MakeValue(std::make_shared(value)); + return ValuePtrToAnfNodePtr(value_ptr); +} + +std::string GetInstanceNameByCNode(const CNodePtr &cnode) { + PrimitivePtr prim = GetValueNode(cnode->input(0)); + if (!prim) { + MS_LOG(EXCEPTION) << "The first input of the cnode is not a PrimitivePtr."; + } + std::string instance_name = prim->instance_name(); + return HashInstanceName(instance_name); +} + +std::string HashInstanceName(const std::string &name) { + auto using_hash_name = common::GetEnv(USING_HASH_NAME); + std::string instance_name; + if ((using_hash_name.empty()) || (using_hash_name == "on")) { + instance_name = HashName(name); + } else { + instance_name = name; + } + return instance_name; +} + +Status GenerateGraph::Init(const CNodePtr &cnode) { + if (!cnode) { + MS_LOG(ERROR) << "Init:cnode is nullptr"; + return FAILED; + } + cnode_ = cnode; + func_graph_ = cnode->func_graph(); + if (!func_graph_) { + MS_LOG(ERROR) << "Init:func_graph_ is nullptr"; + return FAILED; + } + manager_ = func_graph_->manager(); + if (!manager_) { + MS_LOG(ERROR) << "Init:manager_ is nullptr"; + return FAILED; + } + scope_ = cnode_->scope(); + if (!scope_) { + MS_LOG(ERROR) << "Init:scope_ is nullptr"; + return FAILED; + } + virtual_input_node_ = std::make_shared(nullptr); + virtual_input_node_->set_scope(scope_); + instance_name_base_ = GetInstanceNameByCNode(cnode_); + name_idx_ = 0; + return SUCCESS; +} + +AnfNodePtr GenerateGraph::PushBack(const std::vector &inputs) { + CNodePtr cnode = func_graph_->NewCNode(inputs); // using NewCNode to creat anfnode + MS_EXCEPTION_IF_NULL(cnode); + cnode->set_scope(scope_); + if (inputs.size() < 2) { + MS_LOG(EXCEPTION) << "inputs.size() must be more than 1"; + } + (void)manager_->Replace(inputs.at(1), cnode); // using Replace function to insert cnode after inputs[0] + auto new_anf_node_ptr = cnode->cast(); + MS_EXCEPTION_IF_NULL(new_anf_node_ptr); + return new_anf_node_ptr; +} + +AnfNodePtr GenerateGraph::NewOpInst(const OperatorName &op_name, const OperatorAttrs &attrs) { + name_idx_++; + ValuePtr pyop_instance = CreatOpInstance(attrs, op_name, instance_name_base_ + op_name + std::to_string(name_idx_)); + if (pyop_instance == nullptr) { + MS_LOG(EXCEPTION) << "Failure:" << op_name << " CreatOpInstance failed"; + } + auto value_node = NewValueNode(pyop_instance); + return value_node->cast(); +} + +AnfNodePtr GenerateGraph::NewOpInst(const OperatorName &op_name) { + name_idx_++; + OperatorAttrs attrs; + ValuePtr pyop_instance = CreatOpInstance(attrs, op_name, instance_name_base_ + std::to_string(name_idx_)); + if (pyop_instance == nullptr) { + MS_LOG(EXCEPTION) << "Failure:" << op_name << " CreatOpInstance failed"; + } + auto value_node = NewValueNode(pyop_instance); + return value_node->cast(); +} +} // namespace parallel +} // namespace mindspore diff --git a/mindspore/ccsrc/transform/op_declare.cc b/mindspore/ccsrc/transform/op_declare.cc new file mode 100644 index 0000000000..9d86b30b17 --- /dev/null +++ b/mindspore/ccsrc/transform/op_declare.cc @@ -0,0 +1,1306 @@ +/** + * 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. + */ + +#include "transform/op_declare.h" + +#include + +#include "transform/all_ops.h" +#include "utils/utils.h" + +namespace mindspore { +namespace transform { +#define INPUT_MAP(T) \ + template <> \ + const std::unordered_map OpAdapter::input_map_ +#define EMPTY_INPUT_MAP std::unordered_map() +#define INPUT_DESC(name) \ + { \ +#name, \ + [](const OperatorPtr op, const OperatorPtr input) { \ + auto p = std::static_pointer_cast(op); \ + (void)p->set_input_##name(*input); \ + }, \ + [](const OperatorPtr op, const OutHandler& handle) { \ + auto p = std::static_pointer_cast(op); \ + (void)p->set_input_##name(*(handle.op), handle.out); \ + }, \ + [](const OperatorPtr op, const GeTensorDesc desc) { \ + auto p = std::static_pointer_cast(op); \ + (void)p->update_input_desc_##name(desc); \ + } \ + } + +#define DYN_INPUT_MAP(T) \ + template <> \ + const std::unordered_map OpAdapter::dyn_input_map_ +#define DYN_INPUT_DESC(name) \ + { \ +#name, \ + [](const OperatorPtr op, unsigned int num) { \ + auto p = std::static_pointer_cast(op); \ + (void)p->create_dynamic_input_##name(num); \ + }, \ + [](const OperatorPtr op, unsigned int index, const OperatorPtr input) { \ + auto p = std::static_pointer_cast(op); \ + (void)p->set_dynamic_input_##name(index, *input); \ + }, \ + [](const OperatorPtr op, unsigned int index, const OutHandler& handle) { \ + auto p = std::static_pointer_cast(op); \ + (void)p->set_dynamic_input_##name(index, *(handle.op), handle.out); \ + } \ + } + +#define ATTR_MAP(T) \ + template <> \ + const std::unordered_map OpAdapter::attr_map_ +#define EMPTY_ATTR_MAP std::unordered_map() +#define ATTR_DESC(name, ...) \ + { \ +#name, \ + [](const OperatorPtr op, const ValuePtr& value) { \ + auto p = std::static_pointer_cast(op); \ + (void)p->set_attr_##name(ConvertAny(value, __VA_ARGS__)); \ + } \ + } + +#define INPUT_ATTR_MAP(T) \ + template <> \ + const std::unordered_map OpAdapter::input_attr_map_ + +#define OUTPUT_MAP(T) \ + template <> \ + const std::unordered_map OpAdapter::output_map_ +#define OUTPUT_DESC(name) \ + { \ +#name, \ + [](const OperatorPtr op, const GeTensorDesc desc) { \ + auto p = std::static_pointer_cast(op); \ + (void)p->update_output_desc_##name(desc); \ + } \ + } + +#define DYN_OUTPUT_MAP(T) \ + template <> \ + const std::unordered_map OpAdapter::dyn_output_map_ + +#define DYN_OUTPUT_DESC(name) \ + { \ +#name, \ + [](const OperatorPtr op, unsigned int num) { \ + auto p = std::static_pointer_cast(op); \ + (void)p->create_dynamic_output_##name(num); \ + } \ + } + +template <> +std::unordered_map> OpAdapter::cus_input_map_{}; +template <> +std::unordered_map> OpAdapter::cus_output_map_{}; + +// --------------specialization for each operator---------- +// const +INPUT_MAP(Const) = EMPTY_INPUT_MAP; +ATTR_MAP(Const) = {{"value", ATTR_DESC(value, AnyTraits())}}; +OUTPUT_MAP(Const) = {{0, OUTPUT_DESC(y)}}; + +// Assign +INPUT_MAP(Assign) = {{1, INPUT_DESC(ref)}, {2, INPUT_DESC(value)}}; +ATTR_MAP(Assign) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Assign) = {{0, OUTPUT_DESC(ref)}}; + +// Constant +INPUT_MAP(Constant) = EMPTY_INPUT_MAP; +ATTR_MAP(Constant) = {{"value", ATTR_DESC(value, AnyTraits())}}; +OUTPUT_MAP(Constant) = {{0, OUTPUT_DESC(y)}}; + +// ApplyMomentumD +INPUT_MAP(ApplyMomentumD) = { + {1, INPUT_DESC(var)}, {2, INPUT_DESC(accum)}, {3, INPUT_DESC(lr)}, {4, INPUT_DESC(grad)}, {5, INPUT_DESC(momentum)}}; +ATTR_MAP(ApplyMomentumD) = {{"use_nesterov", ATTR_DESC(use_nesterov, AnyTraits())}, + {"use_locking", ATTR_DESC(use_locking, AnyTraits())}}; +OUTPUT_MAP(ApplyMomentumD) = {{0, OUTPUT_DESC(var)}, {1, OUTPUT_DESC(accum)}}; + +// ScalarSummary +INPUT_MAP(Summary) = {{2, INPUT_DESC(x)}}; +ATTR_MAP(Summary) = EMPTY_ATTR_MAP; + +// Data +INPUT_MAP(Data) = EMPTY_INPUT_MAP; +ATTR_MAP(Data) = EMPTY_ATTR_MAP; + +// BatchNorm +INPUT_MAP(BatchNorm) = {{1, INPUT_DESC(x)}, + {2, INPUT_DESC(scale)}, + {3, INPUT_DESC(offset)}, + {4, INPUT_DESC(mean)}, + {5, INPUT_DESC(variance)}}; +ATTR_MAP(BatchNorm) = {{"data_format", ATTR_DESC(data_format, AnyTraits())}, + {"epsilon", ATTR_DESC(epsilon, AnyTraits())}, + {"is_training", ATTR_DESC(is_training, AnyTraits())}}; +OUTPUT_MAP(BatchNorm) = {{0, OUTPUT_DESC(y)}, + {1, OUTPUT_DESC(batch_mean)}, + {2, OUTPUT_DESC(batch_variance)}, + {3, OUTPUT_DESC(reserve_space_1)}, + {4, OUTPUT_DESC(reserve_space_2)}}; + +// BatchNormGrad +INPUT_MAP(BatchNormGrad) = {{1, INPUT_DESC(y_backprop)}, + {2, INPUT_DESC(x)}, + {3, INPUT_DESC(scale)}, + {4, INPUT_DESC(reserve_space_1)}, + {5, INPUT_DESC(reserve_space_2)}}; +ATTR_MAP(BatchNormGrad) = {{"data_format", ATTR_DESC(data_format, AnyTraits())}, + {"epsilon", ATTR_DESC(epsilon, AnyTraits())}, + {"is_training", ATTR_DESC(is_training, AnyTraits())}}; +OUTPUT_MAP(BatchNormGrad) = {{0, OUTPUT_DESC(x_backprop)}, + {1, OUTPUT_DESC(scale_backprop)}, + {2, OUTPUT_DESC(offset_backprop)}, + {3, OUTPUT_DESC(reserve_space_4)}, + {4, OUTPUT_DESC(reserve_space_5)}}; + +// Relu +INPUT_MAP(Relu) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Relu) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Relu) = {{0, OUTPUT_DESC(y)}}; + +// Elu +INPUT_MAP(Elu) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Elu) = {{"alpha", ATTR_DESC(alpha, AnyTraits())}}; +OUTPUT_MAP(Elu) = {{0, OUTPUT_DESC(y)}}; + +// EluGrad +INPUT_MAP(EluGrad) = {{1, INPUT_DESC(grads)}, {2, INPUT_DESC(activations)}}; +ATTR_MAP(EluGrad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(EluGrad) = {{0, OUTPUT_DESC(y)}}; + +// PRelu +INPUT_MAP(PRelu) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(weight)}}; +ATTR_MAP(PRelu) = EMPTY_ATTR_MAP; +OUTPUT_MAP(PRelu) = {{0, OUTPUT_DESC(y)}}; + +// PReluGrad +INPUT_MAP(PReluGrad) = {{1, INPUT_DESC(grads)}, {2, INPUT_DESC(features)}, {3, INPUT_DESC(weights)}}; +ATTR_MAP(PReluGrad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(PReluGrad) = {{0, OUTPUT_DESC(dx)}, {1, OUTPUT_DESC(da)}}; + +// Sigmoid +INPUT_MAP(Sigmoid) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Sigmoid) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Sigmoid) = {{0, OUTPUT_DESC(y)}}; + +// SigmoidGrad +INPUT_MAP(SigmoidGrad) = {{1, INPUT_DESC(y)}, {2, INPUT_DESC(dy)}}; +ATTR_MAP(SigmoidGrad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(SigmoidGrad) = {{0, OUTPUT_DESC(z)}}; + +// L2NormalizeGrad +INPUT_MAP(L2NormalizeGrad) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(y)}, {3, INPUT_DESC(dy)}}; +ATTR_MAP(L2NormalizeGrad) = { + {"axis", ATTR_DESC(dim, AnyTraits>(), AnyTraits>())}, + {"epsilon", ATTR_DESC(eps, AnyTraits())}}; +OUTPUT_MAP(L2NormalizeGrad) = {{0, OUTPUT_DESC(dx)}}; + +// LarsV2Update +INPUT_MAP(LarsV2Update) = {{1, INPUT_DESC(w)}, + {2, INPUT_DESC(g)}, + {3, INPUT_DESC(w_square_sum)}, + {4, INPUT_DESC(g_square_sum)}, + {5, INPUT_DESC(weight_decay)}, + {6, INPUT_DESC(learning_rate)}}; +ATTR_MAP(LarsV2Update) = {{"epsilon", ATTR_DESC(epsilon, AnyTraits())}, + {"hyperpara", ATTR_DESC(hyperpara, AnyTraits())}, + {"use_clip", ATTR_DESC(use_clip, AnyTraits())}}; +OUTPUT_MAP(LarsV2Update) = {{0, OUTPUT_DESC(g_new)}}; + +// L2Normalize +INPUT_MAP(L2Normalize) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(L2Normalize) = { + {"axis", ATTR_DESC(axis, AnyTraits>(), AnyTraits>())}, + {"epsilon", ATTR_DESC(eps, AnyTraits())}}; +OUTPUT_MAP(L2Normalize) = {{0, OUTPUT_DESC(y)}}; + +// CumsumD +INPUT_MAP(CumsumD) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(CumsumD) = {{2, ATTR_DESC(axis, AnyTraits())}}; +ATTR_MAP(CumsumD) = {{"exclusive", ATTR_DESC(exclusive, AnyTraits())}, + {"reverse", ATTR_DESC(reverse, AnyTraits())}}; +OUTPUT_MAP(CumsumD) = {{0, OUTPUT_DESC(y)}}; + +// SoftmaxV2 +INPUT_MAP(SoftmaxV2) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(SoftmaxV2) = { + {"axis", ATTR_DESC(axes, AnyTraits>(), AnyTraits>())}, +}; +OUTPUT_MAP(SoftmaxV2) = {{0, OUTPUT_DESC(y)}}; + +// SoftmaxGrad +INPUT_MAP(SoftmaxGrad) = {{1, INPUT_DESC(softmax)}, {2, INPUT_DESC(grad_softmax)}}; +OUTPUT_MAP(SoftmaxGrad) = {{0, OUTPUT_DESC(grad_x)}}; +ATTR_MAP(SoftmaxGrad) = EMPTY_ATTR_MAP; + +// Flatten +INPUT_MAP(Flatten) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Flatten) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Flatten) = {{0, OUTPUT_DESC(y)}}; + +// add +INPUT_MAP(Add) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(Add) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Add) = {{0, OUTPUT_DESC(y)}}; + +// GatherV2 +INPUT_MAP(GatherV2) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(indices)}, {3, INPUT_DESC(axis)}}; +ATTR_MAP(GatherV2) = EMPTY_ATTR_MAP; +OUTPUT_MAP(GatherV2) = {{0, OUTPUT_DESC(y)}}; + +// ReduceSumD +INPUT_MAP(ReduceSumD) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(ReduceSumD) = { + {2, ATTR_DESC(axes, AnyTraits>(), AnyTraits>())}}; +ATTR_MAP(ReduceSumD) = {{"keep_dims", ATTR_DESC(keep_dims, AnyTraits())}}; +OUTPUT_MAP(ReduceSumD) = {{0, OUTPUT_DESC(y)}}; + +// ReduceProdD +INPUT_MAP(ReduceProdD) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(ReduceProdD) = { + {2, ATTR_DESC(axes, AnyTraits>(), AnyTraits>())}}; +ATTR_MAP(ReduceProdD) = {{"keep_dims", ATTR_DESC(keep_dims, AnyTraits())}}; +OUTPUT_MAP(ReduceProdD) = {{0, OUTPUT_DESC(y)}}; + +// CumprodD +INPUT_MAP(CumprodD) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(CumprodD) = {{2, ATTR_DESC(axis, AnyTraits())}}; +ATTR_MAP(CumprodD) = {{"exclusive", ATTR_DESC(exclusive, AnyTraits())}, + {"reverse", ATTR_DESC(reverse, AnyTraits())}}; +OUTPUT_MAP(CumprodD) = {{0, OUTPUT_DESC(y)}}; + +// SoftmaxCrossEntropyWithLogits +INPUT_MAP(SoftmaxCrossEntropyWithLogits) = {{1, INPUT_DESC(features)}, {2, INPUT_DESC(labels)}}; +ATTR_MAP(SoftmaxCrossEntropyWithLogits) = EMPTY_ATTR_MAP; +OUTPUT_MAP(SoftmaxCrossEntropyWithLogits) = {{0, OUTPUT_DESC(loss)}, {1, OUTPUT_DESC(backprop)}}; + +// MeanGrad +INPUT_MAP(MeanGrad) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(MeanGrad) = {{2, ATTR_DESC(mean_grad_output_shape_value, kOpFormat_NHWC, + AnyTraits>(), AnyTraits())}}; +ATTR_MAP(MeanGrad) = {{"mode", ATTR_DESC(mode, AnyTraits())}}; + +INPUT_MAP(SliceD) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(SliceD) = {{2, ATTR_DESC(offsets, AnyTraits(), AnyTraits>())}, + {3, ATTR_DESC(size, AnyTraits(), AnyTraits>())}}; +ATTR_MAP(SliceD) = EMPTY_ATTR_MAP; +OUTPUT_MAP(SliceD) = {{0, OUTPUT_DESC(y)}}; + +// MaxPool +INPUT_MAP(MaxPool) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(MaxPool) = {{"ksize", ATTR_DESC(ksize, AnyTraits(), AnyTraits>())}, + {"strides", ATTR_DESC(strides, AnyTraits(), AnyTraits>())}, + {"padding", ATTR_DESC(padding, AnyTraits())}, + {"data_format", ATTR_DESC(data_format, AnyTraits())}}; +OUTPUT_MAP(MaxPool) = {{0, OUTPUT_DESC(y)}}; + +// AvgPool +INPUT_MAP(AvgPool) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(AvgPool) = {{"ksize", ATTR_DESC(ksize, AnyTraits(), AnyTraits>())}, + {"strides", ATTR_DESC(strides, AnyTraits(), AnyTraits>())}, + {"padding", ATTR_DESC(padding, AnyTraits())}, + {"data_format", ATTR_DESC(data_format, AnyTraits())}}; +OUTPUT_MAP(AvgPool) = {{0, OUTPUT_DESC(y)}}; + +// GreaterEqual +INPUT_MAP(GreaterEqual) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(GreaterEqual) = EMPTY_ATTR_MAP; +OUTPUT_MAP(GreaterEqual) = {{0, OUTPUT_DESC(y)}}; + +// AssignAdd +INPUT_MAP(AssignAdd) = {{1, INPUT_DESC(ref)}, {2, INPUT_DESC(value)}}; +ATTR_MAP(AssignAdd) = EMPTY_ATTR_MAP; +OUTPUT_MAP(AssignAdd) = {{0, OUTPUT_DESC(ref)}}; + +// AssignSub +INPUT_MAP(AssignSub) = {{1, INPUT_DESC(var)}, {2, INPUT_DESC(value)}}; +ATTR_MAP(AssignSub) = EMPTY_ATTR_MAP; +OUTPUT_MAP(AssignSub) = {{0, OUTPUT_DESC(var)}}; + +// Cos +INPUT_MAP(Cos) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Cos) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Cos) = {{0, OUTPUT_DESC(y)}}; + +// Acos +INPUT_MAP(Acos) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Acos) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Acos) = {{0, OUTPUT_DESC(y)}}; + +// AcosGrad +INPUT_MAP(AcosGrad) = {{1, INPUT_DESC(y)}, {2, INPUT_DESC(dy)}}; +ATTR_MAP(AcosGrad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(AcosGrad) = {{0, OUTPUT_DESC(z)}}; + +// Acosh +INPUT_MAP(Acosh) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Acosh) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Acosh) = {{0, OUTPUT_DESC(y)}}; + +// AcoshGrad +INPUT_MAP(AcoshGrad) = {{1, INPUT_DESC(y)}, {2, INPUT_DESC(dy)}}; +ATTR_MAP(AcoshGrad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(AcoshGrad) = {{0, OUTPUT_DESC(z)}}; + +// Floor +INPUT_MAP(Floor) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Floor) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Floor) = {{0, OUTPUT_DESC(y)}}; + +// FloorDiv +INPUT_MAP(FloorDiv) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(FloorDiv) = EMPTY_ATTR_MAP; +OUTPUT_MAP(FloorDiv) = {{0, OUTPUT_DESC(y)}}; + +// FloorMod +INPUT_MAP(FloorMod) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(FloorMod) = EMPTY_ATTR_MAP; +OUTPUT_MAP(FloorMod) = {{0, OUTPUT_DESC(y)}}; + +// Sin +INPUT_MAP(Sin) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Sin) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Sin) = {{0, OUTPUT_DESC(y)}}; + +// Exp +INPUT_MAP(Exp) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Exp) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Exp) = {{0, OUTPUT_DESC(y)}}; + +// BoundingBoxEncode +INPUT_MAP(BoundingBoxEncode) = { + {1, INPUT_DESC(anchor_box)}, + {2, INPUT_DESC(ground_truth_box)}, +}; +ATTR_MAP(BoundingBoxEncode) = { + {"means", ATTR_DESC(means, AnyTraits>(), AnyTraits())}, + {"stds", ATTR_DESC(stds, AnyTraits>(), AnyTraits())}, +}; +OUTPUT_MAP(BoundingBoxEncode) = {{0, OUTPUT_DESC(delats)}}; + +// BoundingBoxDecode +INPUT_MAP(BoundingBoxDecode) = { + {1, INPUT_DESC(rois)}, + {2, INPUT_DESC(deltas)}, +}; +ATTR_MAP(BoundingBoxDecode) = { + {"means", ATTR_DESC(means, AnyTraits>(), AnyTraits())}, + {"stds", ATTR_DESC(stds, AnyTraits>(), AnyTraits())}, + {"max_shape", ATTR_DESC(max_shape, AnyTraits>(), AnyTraits>())}, + {"wh_ratio_clip", ATTR_DESC(wh_ratio_clip, AnyTraits())}, +}; +OUTPUT_MAP(BoundingBoxDecode) = {{0, OUTPUT_DESC(bboxes)}}; + +// TopK +INPUT_MAP(TopK) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(k)}}; +ATTR_MAP(TopK) = {{"sorted", ATTR_DESC(sorted, AnyTraits())}}; +OUTPUT_MAP(TopK) = {{0, OUTPUT_DESC(values)}, {1, OUTPUT_DESC(indices)}}; + +// Multiply +INPUT_MAP(Multiply) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(y)}}; +ATTR_MAP(Multiply) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Multiply) = {{0, OUTPUT_DESC(z)}}; + +// TileD +INPUT_MAP(TileD) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(TileD) = {{2, ATTR_DESC(multiples, AnyTraits(), AnyTraits>())}}; +ATTR_MAP(TileD) = EMPTY_ATTR_MAP; +OUTPUT_MAP(TileD) = {{0, OUTPUT_DESC(y)}}; + +// OneHot +INPUT_MAP(OneHot) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(depth)}, {3, INPUT_DESC(on_value)}, {4, INPUT_DESC(off_value)}}; +ATTR_MAP(OneHot) = {{"axis", ATTR_DESC(axis, AnyTraits())}}; +OUTPUT_MAP(OneHot) = {{0, OUTPUT_DESC(y)}}; + +// GatherV2D +INPUT_MAP(GatherV2D) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(indices)}}; +INPUT_ATTR_MAP(GatherV2D) = {{3, ATTR_DESC(axis, AnyTraits())}}; +ATTR_MAP(GatherV2D) = EMPTY_ATTR_MAP; +OUTPUT_MAP(GatherV2D) = {{0, OUTPUT_DESC(y)}}; + +// Reshape +INPUT_MAP(Reshape) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(shape)}}; +ATTR_MAP(Reshape) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Reshape) = {{0, OUTPUT_DESC(y)}}; + +// TransShape +INPUT_MAP(TransShape) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(TransShape) = {{2, ATTR_DESC(outShape, AnyTraits(), AnyTraits>())}}; +ATTR_MAP(TransShape) = EMPTY_ATTR_MAP; +OUTPUT_MAP(TransShape) = {{0, OUTPUT_DESC(y)}}; + +// BiasAdd +INPUT_MAP(BiasAdd) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(bias)}}; +ATTR_MAP(BiasAdd) = {{"data_format", ATTR_DESC(data_format, AnyTraits())}}; +OUTPUT_MAP(BiasAdd) = {{0, OUTPUT_DESC(y)}}; + +// Iou +INPUT_MAP(Iou) = {{1, INPUT_DESC(bboxes)}, {2, INPUT_DESC(gtboxes)}}; +ATTR_MAP(Iou) = {{"mode", ATTR_DESC(mode, AnyTraits())}}; +OUTPUT_MAP(Iou) = {{0, OUTPUT_DESC(overlap)}}; + +// ResizeNearestNeighborV2D +INPUT_MAP(ResizeNearestNeighborV2D) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(ResizeNearestNeighborV2D) = { + {"size", ATTR_DESC(size, AnyTraits>(), AnyTraits>())}, + {"align_corners", ATTR_DESC(align_corners, AnyTraits())}}; +OUTPUT_MAP(ResizeNearestNeighborV2D) = {{0, OUTPUT_DESC(y)}}; + +// ResizeNearestNeighborV2Grad +INPUT_MAP(ResizeNearestNeighborV2Grad) = {{1, INPUT_DESC(grads)}, {2, INPUT_DESC(size)}}; +ATTR_MAP(ResizeNearestNeighborV2Grad) = {{"align_corners", ATTR_DESC(align_corners, AnyTraits())}}; +OUTPUT_MAP(ResizeNearestNeighborV2Grad) = {{0, OUTPUT_DESC(y)}}; + +// ApplyAdam +INPUT_MAP(ApplyAdam) = {{1, INPUT_DESC(var)}, {2, INPUT_DESC(m)}, {3, INPUT_DESC(v)}, + {4, INPUT_DESC(beta1_power)}, {5, INPUT_DESC(beta2_power)}, {6, INPUT_DESC(lr)}, + {7, INPUT_DESC(beta1)}, {8, INPUT_DESC(beta2)}, {9, INPUT_DESC(epsilon)}, + {10, INPUT_DESC(grad)}}; +ATTR_MAP(ApplyAdam) = {{"use_locking", ATTR_DESC(use_locking, AnyTraits())}, + {"use_nesterov", ATTR_DESC(use_nesterov, AnyTraits())}}; +OUTPUT_MAP(ApplyAdam) = {{0, OUTPUT_DESC(var)}}; + +// ApplyAdamD +INPUT_MAP(ApplyAdamD) = {{1, INPUT_DESC(var)}, {2, INPUT_DESC(m)}, {3, INPUT_DESC(v)}, + {4, INPUT_DESC(beta1_power)}, {5, INPUT_DESC(beta2_power)}, {6, INPUT_DESC(lr)}, + {7, INPUT_DESC(beta1)}, {8, INPUT_DESC(beta2)}, {9, INPUT_DESC(epsilon)}, + {10, INPUT_DESC(grad)}}; +ATTR_MAP(ApplyAdamD) = {{"use_locking", ATTR_DESC(use_locking, AnyTraits())}, + {"use_nesterov", ATTR_DESC(use_nesterov, AnyTraits())}}; +OUTPUT_MAP(ApplyAdamD) = {{0, OUTPUT_DESC(var)}, {1, OUTPUT_DESC(m)}, {2, OUTPUT_DESC(v)}}; + +// Relu6 +INPUT_MAP(Relu6) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Relu6) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Relu6) = {{0, OUTPUT_DESC(y)}}; + +// Relu6Grad +INPUT_MAP(Relu6Grad) = {{1, INPUT_DESC(gradients)}, {2, INPUT_DESC(features)}}; +ATTR_MAP(Relu6Grad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Relu6Grad) = {{0, OUTPUT_DESC(backprops)}}; + +// ResizeBilinearV2Grad +INPUT_MAP(ResizeBilinearV2Grad) = {{1, INPUT_DESC(grads)}, {2, INPUT_DESC(original_image)}}; +ATTR_MAP(ResizeBilinearV2Grad) = {{"align_corners", ATTR_DESC(align_corners, AnyTraits())}}; +OUTPUT_MAP(ResizeBilinearV2Grad) = {{0, OUTPUT_DESC(y)}}; + +// ResizeBilinearV2D +INPUT_MAP(ResizeBilinearV2D) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(ResizeBilinearV2D) = { + {"size", ATTR_DESC(size, AnyTraits>(), AnyTraits>())}, + {"align_corners", ATTR_DESC(align_corners, AnyTraits())}}; +OUTPUT_MAP(ResizeBilinearV2D) = {{0, OUTPUT_DESC(y)}}; + +// ZerosLike +INPUT_MAP(ZerosLike) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(ZerosLike) = EMPTY_ATTR_MAP; +OUTPUT_MAP(ZerosLike) = {{0, OUTPUT_DESC(y)}}; + +// OnesLike +INPUT_MAP(OnesLike) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(OnesLike) = EMPTY_ATTR_MAP; +OUTPUT_MAP(OnesLike) = {{0, OUTPUT_DESC(y)}}; + +// NMSWithMask +INPUT_MAP(NMSWithMask) = {{1, INPUT_DESC(box_scores)}}; +ATTR_MAP(NMSWithMask) = {{"iou_threshold", ATTR_DESC(iou_threshold, AnyTraits())}}; +OUTPUT_MAP(NMSWithMask) = { + {0, OUTPUT_DESC(selected_boxes)}, {1, OUTPUT_DESC(selected_idx)}, {2, OUTPUT_DESC(selected_mask)}}; + +// Unpack +INPUT_MAP(Unpack) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Unpack) = {{"axis", ATTR_DESC(axis, AnyTraits())}, {"num", ATTR_DESC(num, AnyTraits())}}; +DYN_OUTPUT_MAP(Unpack) = {{0, DYN_OUTPUT_DESC(y)}}; + +// TensorScatterUpdate +INPUT_MAP(TensorScatterUpdate) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(indices)}, {3, INPUT_DESC(updates)}}; +ATTR_MAP(TensorScatterUpdate) = EMPTY_ATTR_MAP; +OUTPUT_MAP(TensorScatterUpdate) = {{0, OUTPUT_DESC(y)}}; + +// ScatterUpdate +INPUT_MAP(ScatterUpdate) = {{1, INPUT_DESC(var)}, {2, INPUT_DESC(indices)}, {3, INPUT_DESC(updates)}}; +ATTR_MAP(ScatterUpdate) = {{"use_locking", ATTR_DESC(use_locking, AnyTraits())}}; +OUTPUT_MAP(ScatterUpdate) = {{0, OUTPUT_DESC(var)}}; + +// ScatterNdUpdate +INPUT_MAP(ScatterNdUpdate) = {{1, INPUT_DESC(var)}, {2, INPUT_DESC(indices)}, {3, INPUT_DESC(updates)}}; +ATTR_MAP(ScatterNdUpdate) = {{"use_locking", ATTR_DESC(use_locking, AnyTraits())}}; +OUTPUT_MAP(ScatterNdUpdate) = {{0, OUTPUT_DESC(var)}}; + +// ScatterMax +INPUT_MAP(ScatterMax) = {{1, INPUT_DESC(var)}, {2, INPUT_DESC(indices)}, {3, INPUT_DESC(updates)}}; +ATTR_MAP(ScatterMax) = {{"use_locking", ATTR_DESC(use_locking, AnyTraits())}}; +OUTPUT_MAP(ScatterMax) = {{0, OUTPUT_DESC(var)}}; + +// CheckValid +INPUT_MAP(CheckValid) = {{1, INPUT_DESC(bbox_tensor)}, {2, INPUT_DESC(img_metas)}}; +ATTR_MAP(CheckValid) = EMPTY_ATTR_MAP; +OUTPUT_MAP(CheckValid) = {{0, OUTPUT_DESC(valid_tensor)}}; + +// SmoothL1Loss +INPUT_MAP(SmoothL1Loss) = {{1, INPUT_DESC(predict)}, {2, INPUT_DESC(label)}}; +ATTR_MAP(SmoothL1Loss) = {{"sigma", ATTR_DESC(sigma, AnyTraits())}}; +OUTPUT_MAP(SmoothL1Loss) = {{0, OUTPUT_DESC(loss)}}; + +// SmoothL1LossGrad +INPUT_MAP(SmoothL1LossGrad) = {{1, INPUT_DESC(predict)}, {2, INPUT_DESC(label)}, {3, INPUT_DESC(dout)}}; +ATTR_MAP(SmoothL1LossGrad) = {{"sigma", ATTR_DESC(sigma, AnyTraits())}}; +OUTPUT_MAP(SmoothL1LossGrad) = {{0, OUTPUT_DESC(gradient)}}; + +// SigmoidCrossEntropyWithLogits +INPUT_MAP(SigmoidCrossEntropyWithLogits) = {{1, INPUT_DESC(predict)}, {2, INPUT_DESC(target)}}; +ATTR_MAP(SigmoidCrossEntropyWithLogits) = EMPTY_ATTR_MAP; +OUTPUT_MAP(SigmoidCrossEntropyWithLogits) = {{0, OUTPUT_DESC(loss)}}; + +// SigmoidCrossEntropyWithLogitsGrad +INPUT_MAP(SigmoidCrossEntropyWithLogitsGrad) = { + {1, INPUT_DESC(predict)}, {2, INPUT_DESC(target)}, {3, INPUT_DESC(dout)}}; +ATTR_MAP(SigmoidCrossEntropyWithLogitsGrad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(SigmoidCrossEntropyWithLogitsGrad) = {{0, OUTPUT_DESC(gradient)}}; + +// ScatterNdD +INPUT_MAP(ScatterNdD) = {{1, INPUT_DESC(indices)}, {2, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(ScatterNdD) = { + {3, ATTR_DESC(shape, AnyTraits>(), AnyTraits>())}}; +ATTR_MAP(ScatterNdD) = EMPTY_ATTR_MAP; +OUTPUT_MAP(ScatterNdD) = {{0, OUTPUT_DESC(y)}}; + +// PadD +INPUT_MAP(PadD) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(PadD) = {{"paddings", ATTR_DESC(paddings, AnyTraits>>())}}; +OUTPUT_MAP(PadD) = {{0, OUTPUT_DESC(y)}}; + +// MirrorPad +INPUT_MAP(MirrorPad) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(paddings)}}; +ATTR_MAP(MirrorPad) = {{"mode", ATTR_DESC(mode, AnyTraits())}}; +OUTPUT_MAP(MirrorPad) = {{0, OUTPUT_DESC(y)}}; + +// MirrorPadGrad +INPUT_MAP(MirrorPadGrad) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(paddings)}}; +ATTR_MAP(MirrorPadGrad) = {{"mode", ATTR_DESC(mode, AnyTraits())}}; +OUTPUT_MAP(MirrorPadGrad) = {{0, OUTPUT_DESC(y)}}; + +// GatherNd +INPUT_MAP(GatherNd) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(indices)}}; +ATTR_MAP(GatherNd) = EMPTY_ATTR_MAP; +OUTPUT_MAP(GatherNd) = {{0, OUTPUT_DESC(y)}}; + +// ROIAlign +INPUT_MAP(ROIAlign) = {{1, INPUT_DESC(features)}, {2, INPUT_DESC(rois)}}; +OUTPUT_MAP(ROIAlign) = {{0, OUTPUT_DESC(y)}}; +ATTR_MAP(ROIAlign) = {{"pooled_height", ATTR_DESC(pooled_height, AnyTraits())}, + {"pooled_width", ATTR_DESC(pooled_width, AnyTraits())}, + {"spatial_scale", ATTR_DESC(spatial_scale, AnyTraits())}, + {"sample_num", ATTR_DESC(sample_num, AnyTraits())}}; + +// ROIAlignGrad +INPUT_MAP(ROIAlignGrad) = {{1, INPUT_DESC(ydiff)}, {2, INPUT_DESC(rois)}}; +OUTPUT_MAP(ROIAlignGrad) = {{0, OUTPUT_DESC(xdiff)}}; +ATTR_MAP(ROIAlignGrad) = { + {"xdiff_shape", ATTR_DESC(xdiff_shape, AnyTraits>(), AnyTraits>())}, + {"pooled_height", ATTR_DESC(pooled_height, AnyTraits())}, + {"pooled_width", ATTR_DESC(pooled_width, AnyTraits())}, + {"spatial_scale", ATTR_DESC(spatial_scale, AnyTraits())}, + {"sample_num", ATTR_DESC(sample_num, AnyTraits())}}; + +// ArgMaxD +INPUT_MAP(ArgMaxD) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(ArgMaxD) = {{"axis", ATTR_DESC(dimension, AnyTraits())}, + {"output_type", ATTR_DESC(dtype, AnyTraits())}}; +OUTPUT_MAP(ArgMaxD) = {{0, OUTPUT_DESC(y)}}; + +// ArgMinD +INPUT_MAP(ArgMinD) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(ArgMinD) = {{"axis", ATTR_DESC(dimension, AnyTraits())}, + {"output_type", ATTR_DESC(dtype, AnyTraits())}}; +OUTPUT_MAP(ArgMinD) = {{0, OUTPUT_DESC(y)}}; + +// ArgMaxWithValue +INPUT_MAP(ArgMaxWithValue) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(ArgMaxWithValue) = {{"axis", ATTR_DESC(dimension, AnyTraits())}, + {"keep_dims", ATTR_DESC(keep_dims, AnyTraits())}}; +OUTPUT_MAP(ArgMaxWithValue) = {{0, OUTPUT_DESC(indice)}, {1, OUTPUT_DESC(values)}}; + +// ArgMinWithValue +INPUT_MAP(ArgMinWithValue) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(ArgMinWithValue) = {{"axis", ATTR_DESC(dimension, AnyTraits())}, + {"keep_dims", ATTR_DESC(keep_dims, AnyTraits())}}; +OUTPUT_MAP(ArgMinWithValue) = {{0, OUTPUT_DESC(indice)}, {1, OUTPUT_DESC(values)}}; + +// ReduceAllD +INPUT_MAP(ReduceAllD) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(ReduceAllD) = { + {2, ATTR_DESC(axes, AnyTraits>(), AnyTraits>())}}; +ATTR_MAP(ReduceAllD) = {{"keep_dims", ATTR_DESC(keep_dims, AnyTraits())}}; +OUTPUT_MAP(ReduceAllD) = {{0, OUTPUT_DESC(y)}}; + +// ReduceMeanD +INPUT_MAP(ReduceMeanD) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(ReduceMeanD) = { + {2, ATTR_DESC(axes, AnyTraits>(), AnyTraits>())}}; +ATTR_MAP(ReduceMeanD) = {{"keep_dims", ATTR_DESC(keep_dims, AnyTraits())}}; +OUTPUT_MAP(ReduceMeanD) = {{0, OUTPUT_DESC(y)}}; + +// HCOMAllreduce +INPUT_MAP(HcomAllReduce) = {{1, INPUT_DESC(x)}}; +OUTPUT_MAP(HcomAllReduce) = {{0, OUTPUT_DESC(y)}}; +ATTR_MAP(HcomAllReduce) = {{"op", ATTR_DESC(reduction, AnyTraits())}, + {"group", ATTR_DESC(group, AnyTraits())}, + {"fusion", ATTR_DESC(fusion, AnyTraits())}}; + +// HCOMBraodcast +INPUT_MAP(HcomBroadcast) = EMPTY_INPUT_MAP; +DYN_INPUT_MAP(HcomBroadcast) = {{1, DYN_INPUT_DESC(x)}}; +DYN_OUTPUT_MAP(HcomBroadcast) = {{0, DYN_OUTPUT_DESC(y)}}; +ATTR_MAP(HcomBroadcast) = {{"root_rank", ATTR_DESC(root_rank, AnyTraits())}, + {"group", ATTR_DESC(group, AnyTraits())}}; + +// HCOMAllreduce +INPUT_MAP(HcomAllGather) = {{1, INPUT_DESC(x)}}; +OUTPUT_MAP(HcomAllGather) = {{0, OUTPUT_DESC(y)}}; +ATTR_MAP(HcomAllGather) = {{"group", ATTR_DESC(group, AnyTraits())}, + {"rank_size", ATTR_DESC(rank_size, AnyTraits())}}; + +// HCOMReduceScatter +INPUT_MAP(HcomReduceScatter) = {{1, INPUT_DESC(x)}}; +OUTPUT_MAP(HcomReduceScatter) = {{0, OUTPUT_DESC(y)}}; +ATTR_MAP(HcomReduceScatter) = {{"group", ATTR_DESC(group, AnyTraits())}, + {"op", ATTR_DESC(reduction, AnyTraits())}, + {"rank_size", ATTR_DESC(rank_size, AnyTraits())}}; + +// Variable +INPUT_MAP(Variable) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Variable) = EMPTY_ATTR_MAP; + +// ReluGrad +INPUT_MAP(ReluGrad) = {{1, INPUT_DESC(gradients)}, {2, INPUT_DESC(features)}}; +ATTR_MAP(ReluGrad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(ReluGrad) = {{0, OUTPUT_DESC(backprops)}}; + +// BiasAddGrad +INPUT_MAP(BiasAddGrad) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(BiasAddGrad) = {{"data_format", ATTR_DESC(data_format, AnyTraits())}}; +OUTPUT_MAP(BiasAddGrad) = {{0, OUTPUT_DESC(y)}}; + +// MaxPoolGrad +INPUT_MAP(MaxPoolGrad) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}, {3, INPUT_DESC(grad)}}; +ATTR_MAP(MaxPoolGrad) = {{"ksize", ATTR_DESC(ksize, AnyTraits(), AnyTraits>())}, + {"strides", ATTR_DESC(strides, AnyTraits(), AnyTraits>())}, + {"padding", ATTR_DESC(padding, AnyTraits())}, + {"data_format", ATTR_DESC(data_format, AnyTraits())}}; +OUTPUT_MAP(MaxPoolGrad) = {{0, OUTPUT_DESC(y)}}; + +// avgpoolgrad +INPUT_MAP(AvgPoolGrad) = {{1, INPUT_DESC(orig_input_shape)}, {2, INPUT_DESC(input_grad)}}; +ATTR_MAP(AvgPoolGrad) = {{"ksize", ATTR_DESC(ksize, AnyTraits(), AnyTraits>())}, + {"strides", ATTR_DESC(strides, AnyTraits(), AnyTraits>())}, + {"padding", ATTR_DESC(padding, AnyTraits())}, + {"data_format", ATTR_DESC(data_format, AnyTraits())}}; +OUTPUT_MAP(AvgPoolGrad) = {{0, OUTPUT_DESC(out_grad)}}; + +// MaxPoolWithArgmax +INPUT_MAP(MaxPoolWithArgmax) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(MaxPoolWithArgmax) = {{"ksize", ATTR_DESC(ksize, AnyTraits(), AnyTraits>())}, + {"strides", ATTR_DESC(strides, AnyTraits(), AnyTraits>())}, + {"padding", ATTR_DESC(padding, AnyTraits())}}; +OUTPUT_MAP(MaxPoolWithArgmax) = {{0, OUTPUT_DESC(y)}, {1, OUTPUT_DESC(argmax)}}; + +// MaxPoolGradWithArgmax +INPUT_MAP(MaxPoolGradWithArgmax) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(grad)}, {3, INPUT_DESC(argmax)}}; +ATTR_MAP(MaxPoolGradWithArgmax) = {{"ksize", ATTR_DESC(ksize, AnyTraits(), AnyTraits>())}, + {"strides", ATTR_DESC(strides, AnyTraits(), AnyTraits>())}, + {"padding", ATTR_DESC(padding, AnyTraits())}}; +OUTPUT_MAP(MaxPoolGradWithArgmax) = {{0, OUTPUT_DESC(y)}}; + +// ExtractImagePatches +INPUT_MAP(ExtractImagePatches) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(ExtractImagePatches) = {{"ksizes", ATTR_DESC(ksizes, AnyTraits(), AnyTraits>())}, + {"strides", ATTR_DESC(strides, AnyTraits(), AnyTraits>())}, + {"rates", ATTR_DESC(rates, AnyTraits(), AnyTraits>())}, + {"padding", ATTR_DESC(padding, AnyTraits())}}; +OUTPUT_MAP(ExtractImagePatches) = {{0, OUTPUT_DESC(y)}}; + +// Conv2D +INPUT_MAP(Conv2D) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(filter)}}; +ATTR_MAP(Conv2D) = { + {"stride", ATTR_DESC(strides, AnyTraits>(), AnyTraits>())}, + {"pad_list", ATTR_DESC(pads, AnyTraits>(), AnyTraits>())}, + {"dilation", ATTR_DESC(dilations, AnyTraits>(), AnyTraits>())}, + {"data_format", ATTR_DESC(data_format, AnyTraits())}, + {"group", ATTR_DESC(groups, AnyTraits())}, +}; +OUTPUT_MAP(Conv2D) = {{0, OUTPUT_DESC(y)}}; + +// Conv2DBackpropInputD +INPUT_MAP(Conv2DBackpropInputD) = {{1, INPUT_DESC(out_backprop)}, {2, INPUT_DESC(filter)}}; +INPUT_ATTR_MAP(Conv2DBackpropInputD) = { + {3, ATTR_DESC(input_size, AnyTraits>(), AnyTraits>())}}; +ATTR_MAP(Conv2DBackpropInputD) = { + {"pad_list", ATTR_DESC(pads, AnyTraits>(), AnyTraits>())}, + {"stride", ATTR_DESC(strides, "pad", AnyTraits>())}, + {"dilation", ATTR_DESC(dilations, AnyTraits>(), AnyTraits>())}, + {"data_format", ATTR_DESC(data_format, AnyTraits())}, + {"group", ATTR_DESC(groups, AnyTraits())}, +}; +OUTPUT_MAP(Conv2DBackpropInputD) = {{0, OUTPUT_DESC(y)}}; + +// Conv2DBackpropFilterD +INPUT_MAP(Conv2DBackpropFilterD) = {{1, INPUT_DESC(out_backprop)}, {2, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(Conv2DBackpropFilterD) = { + {3, ATTR_DESC(filter_size, AnyTraits>(), AnyTraits>())}}; +ATTR_MAP(Conv2DBackpropFilterD) = { + {"pad_list", ATTR_DESC(pads, AnyTraits>(), AnyTraits>())}, + {"stride", ATTR_DESC(strides, "pad", AnyTraits>())}, + {"dilation", ATTR_DESC(dilations, AnyTraits>(), AnyTraits>())}, + {"data_format", ATTR_DESC(data_format, AnyTraits())}, + {"group", ATTR_DESC(groups, AnyTraits())}, +}; +OUTPUT_MAP(Conv2DBackpropFilterD) = {{0, OUTPUT_DESC(y)}}; + +// DepthwiseConv2D +INPUT_MAP(DepthwiseConv2D) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(filter)}}; +ATTR_MAP(DepthwiseConv2D) = { + {"stride", ATTR_DESC(strides, AnyTraits>(), AnyTraits>())}, + {"pads", ATTR_DESC(pads, AnyTraits>(), AnyTraits>())}, + {"dilation", ATTR_DESC(dilations, AnyTraits>(), AnyTraits>())}, + {"data_format", ATTR_DESC(data_format, AnyTraits())}, +}; +OUTPUT_MAP(DepthwiseConv2D) = {{0, OUTPUT_DESC(y)}}; + +// DepthwiseConv2DBackpropInputD +INPUT_MAP(DepthwiseConv2DBackpropInputD) = {{2, INPUT_DESC(filter)}, {3, INPUT_DESC(out_backprop)}}; +INPUT_ATTR_MAP(DepthwiseConv2DBackpropInputD) = { + {1, ATTR_DESC(input_size, AnyTraits>(), AnyTraits>())}}; +ATTR_MAP(DepthwiseConv2DBackpropInputD) = { + {"stride", ATTR_DESC(strides, AnyTraits>(), AnyTraits>())}, + {"pads", ATTR_DESC(pads, AnyTraits>(), AnyTraits>())}, + {"dilation", ATTR_DESC(dilations, AnyTraits>(), AnyTraits>())}, +}; +OUTPUT_MAP(DepthwiseConv2DBackpropInputD) = {{0, OUTPUT_DESC(input_grad)}}; + +// DepthwiseConv2DBackpropFilterD +INPUT_MAP(DepthwiseConv2DBackpropFilterD) = {{1, INPUT_DESC(input)}, {3, INPUT_DESC(out_backprop)}}; +INPUT_ATTR_MAP(DepthwiseConv2DBackpropFilterD) = { + {2, ATTR_DESC(filter_size, AnyTraits>(), AnyTraits>())}}; +ATTR_MAP(DepthwiseConv2DBackpropFilterD) = { + {"stride", ATTR_DESC(strides, AnyTraits>(), AnyTraits>())}, + {"pads", ATTR_DESC(pads, AnyTraits>(), AnyTraits>())}, + {"dilation", ATTR_DESC(dilations, AnyTraits>(), AnyTraits>())}, +}; +OUTPUT_MAP(DepthwiseConv2DBackpropFilterD) = {{0, OUTPUT_DESC(filter_grad)}}; + +// MatMul +INPUT_MAP(MatMul) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(MatMul) = {{"transpose_a", ATTR_DESC(transpose_x1, AnyTraits())}, + {"transpose_b", ATTR_DESC(transpose_x2, AnyTraits())}}; +OUTPUT_MAP(MatMul) = {{0, OUTPUT_DESC(y)}}; + +// Merge +INPUT_MAP(Merge) = EMPTY_INPUT_MAP; +DYN_INPUT_MAP(Merge) = {{1, DYN_INPUT_DESC(x)}}; +ATTR_MAP(Merge) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Merge) = {{0, OUTPUT_DESC(y)}, {1, OUTPUT_DESC(value_index)}}; + +// Switch +INPUT_MAP(Switch) = {{1, INPUT_DESC(data)}, {2, INPUT_DESC(pred)}}; +OUTPUT_MAP(Switch) = {{0, OUTPUT_DESC(output_false)}, {1, OUTPUT_DESC(output_true)}}; +ATTR_MAP(Switch) = EMPTY_ATTR_MAP; + +// AddN +INPUT_MAP(AddN) = EMPTY_INPUT_MAP; +DYN_INPUT_MAP(AddN) = {{1, DYN_INPUT_DESC(x)}}; +ATTR_MAP(AddN) = {{"n", ATTR_DESC(N, AnyTraits())}}; +OUTPUT_MAP(AddN) = {{0, OUTPUT_DESC(y)}}; + +// Mul +INPUT_MAP(Mul) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(Mul) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Mul) = {{0, OUTPUT_DESC(y)}}; + +// RealDiv +INPUT_MAP(RealDiv) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(RealDiv) = EMPTY_ATTR_MAP; +OUTPUT_MAP(RealDiv) = {{0, OUTPUT_DESC(y)}}; + +// Cast +INPUT_MAP(Cast) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(Cast) = {{2, ATTR_DESC(dst_type, AnyTraits())}}; +ATTR_MAP(Cast) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Cast) = {{0, OUTPUT_DESC(y)}}; + +// Reciprocal +INPUT_MAP(Reciprocal) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Reciprocal) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Reciprocal) = {{0, OUTPUT_DESC(y)}}; + +// Sub +INPUT_MAP(Sub) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(Sub) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Sub) = {{0, OUTPUT_DESC(y)}}; + +// SplitD +INPUT_MAP(SplitD) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(SplitD) = {{"axis", ATTR_DESC(split_dim, AnyTraits())}, + {"output_num", ATTR_DESC(num_split, AnyTraits())}}; +DYN_OUTPUT_MAP(SplitD) = {{0, DYN_OUTPUT_DESC(y)}}; + +// Range +INPUT_MAP(RangeD) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(RangeD) = {{"start", ATTR_DESC(start, AnyTraits())}, + {"limit", ATTR_DESC(limit, AnyTraits())}, + {"delta", ATTR_DESC(delta, AnyTraits())}}; +OUTPUT_MAP(RangeD) = {{0, OUTPUT_DESC(y)}}; + +// Neg +INPUT_MAP(Neg) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Neg) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Neg) = {{0, OUTPUT_DESC(y)}}; + +// Transpose +INPUT_MAP(TransposeD) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(TransposeD) = {{2, ATTR_DESC(perm, AnyTraits(), AnyTraits>())}}; +ATTR_MAP(TransposeD) = EMPTY_ATTR_MAP; +// Do not set Transpose operator output descriptor + +// DropOutGenMask +INPUT_MAP(DropOutGenMask) = {{1, INPUT_DESC(shape)}, {2, INPUT_DESC(prob)}}; +ATTR_MAP(DropOutGenMask) = {{"Seed0", ATTR_DESC(seed, AnyTraits())}, + {"Seed1", ATTR_DESC(seed2, AnyTraits())}}; +OUTPUT_MAP(DropOutGenMask) = {{0, OUTPUT_DESC(y)}}; + +// Pack +INPUT_MAP(Pack) = EMPTY_INPUT_MAP; +DYN_INPUT_MAP(Pack) = {{1, DYN_INPUT_DESC(x)}}; +ATTR_MAP(Pack) = {{"num", ATTR_DESC(N, AnyTraits())}, {"axis", ATTR_DESC(axis, AnyTraits())}}; +OUTPUT_MAP(Pack) = {{0, OUTPUT_DESC(y)}}; + +// ConcatD +INPUT_MAP(ConcatD) = EMPTY_INPUT_MAP; +DYN_INPUT_MAP(ConcatD) = {{1, DYN_INPUT_DESC(x)}}; +ATTR_MAP(ConcatD) = { + {"axis", ATTR_DESC(concat_dim, AnyTraits())}, + {"inputNums", ATTR_DESC(N, AnyTraits())}, +}; +OUTPUT_MAP(ConcatD) = {{0, OUTPUT_DESC(y)}}; + +// Less +INPUT_MAP(Less) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(Less) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Less) = {{0, OUTPUT_DESC(y)}}; + +// Rsqrt +INPUT_MAP(Rsqrt) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Rsqrt) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Rsqrt) = {{0, OUTPUT_DESC(y)}}; + +// Sqrt +INPUT_MAP(Sqrt) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Sqrt) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Sqrt) = {{0, OUTPUT_DESC(y)}}; + +// Square +INPUT_MAP(Square) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Square) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Square) = {{0, OUTPUT_DESC(y)}}; + +// SquareSumAll +INPUT_MAP(SquareSumAll) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(SquareSumAll) = EMPTY_ATTR_MAP; +OUTPUT_MAP(SquareSumAll) = {{0, OUTPUT_DESC(y1)}, {1, OUTPUT_DESC(y2)}}; + +// Tanh +INPUT_MAP(Tanh) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Tanh) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Tanh) = {{0, OUTPUT_DESC(y)}}; + +// TanhGrad +INPUT_MAP(TanhGrad) = {{1, INPUT_DESC(y)}, {2, INPUT_DESC(dy)}}; +ATTR_MAP(TanhGrad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(TanhGrad) = {{0, OUTPUT_DESC(z)}}; + +// ReduceMinD +INPUT_MAP(ReduceMinD) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(ReduceMinD) = { + {2, ATTR_DESC(axes, AnyTraits>(), AnyTraits>())}}; +ATTR_MAP(ReduceMinD) = {{"keep_dims", ATTR_DESC(keep_dims, AnyTraits())}}; +OUTPUT_MAP(ReduceMinD) = {{0, OUTPUT_DESC(y)}}; + +// ReduceMaxD +INPUT_MAP(ReduceMaxD) = {{1, INPUT_DESC(x)}}; +INPUT_ATTR_MAP(ReduceMaxD) = { + {2, ATTR_DESC(axes, AnyTraits>(), AnyTraits>())}}; +ATTR_MAP(ReduceMaxD) = {{"keep_dims", ATTR_DESC(keep_dims, AnyTraits())}}; +OUTPUT_MAP(ReduceMaxD) = {{0, OUTPUT_DESC(y)}}; + +// Maximum +INPUT_MAP(Maximum) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(Maximum) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Maximum) = {{0, OUTPUT_DESC(y)}}; + +// Minimum +INPUT_MAP(Minimum) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(Minimum) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Minimum) = {{0, OUTPUT_DESC(y)}}; + +// MaximumGrad +INPUT_MAP(MaximumGrad) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}, {3, INPUT_DESC(grads)}}; +ATTR_MAP(MaximumGrad) = {{"grad_x", ATTR_DESC(grad_x, AnyTraits())}, + {"grad_y", ATTR_DESC(grad_y, AnyTraits())}}; +OUTPUT_MAP(MaximumGrad) = {{0, OUTPUT_DESC(y1)}, {1, OUTPUT_DESC(y2)}}; + +// MinimumGrad +INPUT_MAP(MinimumGrad) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}, {3, INPUT_DESC(grads)}}; +ATTR_MAP(MinimumGrad) = {{"grad_x", ATTR_DESC(grad_x, AnyTraits())}, + {"grad_y", ATTR_DESC(grad_y, AnyTraits())}}; +OUTPUT_MAP(MinimumGrad) = {{0, OUTPUT_DESC(y1)}, {1, OUTPUT_DESC(y2)}}; + +// Pow +INPUT_MAP(Pow) = { + {1, INPUT_DESC(x1)}, + {2, INPUT_DESC(x2)}, +}; +ATTR_MAP(Pow) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Pow) = {{0, OUTPUT_DESC(y)}}; + +// Equal +INPUT_MAP(Equal) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(Equal) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Equal) = {{0, OUTPUT_DESC(y)}}; + +// NotEqual +INPUT_MAP(NotEqual) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(NotEqual) = EMPTY_ATTR_MAP; +OUTPUT_MAP(NotEqual) = {{0, OUTPUT_DESC(y)}}; + +// Log +INPUT_MAP(Log) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Log) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Log) = {{0, OUTPUT_DESC(y)}}; + +// LogicalAnd +INPUT_MAP(LogicalAnd) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(LogicalAnd) = EMPTY_ATTR_MAP; +OUTPUT_MAP(LogicalAnd) = {{0, OUTPUT_DESC(y)}}; + +// LogicalOr +INPUT_MAP(LogicalOr) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(LogicalOr) = EMPTY_ATTR_MAP; +OUTPUT_MAP(LogicalOr) = {{0, OUTPUT_DESC(y)}}; + +// LogicalNot +INPUT_MAP(LogicalNot) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(LogicalNot) = EMPTY_ATTR_MAP; +OUTPUT_MAP(LogicalNot) = {{0, OUTPUT_DESC(y)}}; + +// Greater +INPUT_MAP(Greater) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(Greater) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Greater) = {{0, OUTPUT_DESC(y)}}; + +// LogSoftmaxGrad +INPUT_MAP(LogSoftmaxGrad) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(grad)}}; +ATTR_MAP(LogSoftmaxGrad) = { + {"axis", ATTR_DESC(axis, AnyTraits>(), AnyTraits>())}}; +OUTPUT_MAP(LogSoftmaxGrad) = {{0, OUTPUT_DESC(y)}}; + +// Select +INPUT_MAP(Select) = {{1, INPUT_DESC(condition)}, {2, INPUT_DESC(x1)}, {3, INPUT_DESC(x2)}}; +ATTR_MAP(Select) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Select) = {{0, OUTPUT_DESC(y)}}; + +// LessEqual +INPUT_MAP(LessEqual) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(LessEqual) = EMPTY_ATTR_MAP; +OUTPUT_MAP(LessEqual) = {{0, OUTPUT_DESC(y)}}; + +// LogSoftmaxV2 +INPUT_MAP(LogSoftmaxV2) = {{1, INPUT_DESC(logits)}}; +ATTR_MAP(LogSoftmaxV2) = { + {"axis", ATTR_DESC(axes, AnyTraits>(), AnyTraits>())}}; +OUTPUT_MAP(LogSoftmaxV2) = {{0, OUTPUT_DESC(logsoftmax)}}; + +// RandomChoiceWithMask +INPUT_MAP(RandomChoiceWithMask) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(RandomChoiceWithMask) = {{"count", ATTR_DESC(count, AnyTraits())}, + {"seed", ATTR_DESC(seed, AnyTraits())}, + {"seed2", ATTR_DESC(seed2, AnyTraits())}}; +OUTPUT_MAP(RandomChoiceWithMask) = {{0, OUTPUT_DESC(y)}, {1, OUTPUT_DESC(mask)}}; + +// TruncatedNormal +INPUT_MAP(TruncatedNormal) = {{1, INPUT_DESC(shape)}}; +ATTR_MAP(TruncatedNormal) = {{"seed", ATTR_DESC(seed, AnyTraits())}, + {"seed2", ATTR_DESC(seed2, AnyTraits())}}; +OUTPUT_MAP(TruncatedNormal) = {{0, OUTPUT_DESC(y)}}; + +// StridedSliceGrad +INPUT_MAP(StridedSliceGrad) = { + {1, INPUT_DESC(dy)}, {2, INPUT_DESC(shape)}, {3, INPUT_DESC(begin)}, {4, INPUT_DESC(end)}, {5, INPUT_DESC(strides)}}; +ATTR_MAP(StridedSliceGrad) = {{"begin_mask", ATTR_DESC(begin_mask, AnyTraits())}, + {"end_mask", ATTR_DESC(end_mask, AnyTraits())}, + {"ellipsis_mask", ATTR_DESC(ellipsis_mask, AnyTraits())}, + {"new_axis_mask", ATTR_DESC(new_axis_mask, AnyTraits())}, + {"shrink_axis_mask", ATTR_DESC(shrink_axis_mask, AnyTraits())}}; +OUTPUT_MAP(StridedSliceGrad) = {{0, OUTPUT_DESC(output)}}; + +// Gelu +INPUT_MAP(Gelu) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Gelu) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Gelu) = {{0, OUTPUT_DESC(y)}}; + +// GeluGrad +INPUT_MAP(GeluGrad) = {{1, INPUT_DESC(dy)}, {2, INPUT_DESC(x)}, {3, INPUT_DESC(y)}}; +ATTR_MAP(GeluGrad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(GeluGrad) = {{0, OUTPUT_DESC(z)}}; + +// StridedSlice +INPUT_MAP(StridedSlice) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(begin)}, {3, INPUT_DESC(end)}, {4, INPUT_DESC(strides)}}; +ATTR_MAP(StridedSlice) = {{"begin_mask", ATTR_DESC(begin_mask, AnyTraits())}, + {"end_mask", ATTR_DESC(end_mask, AnyTraits())}, + {"ellipsis_mask", ATTR_DESC(ellipsis_mask, AnyTraits())}, + {"new_axis_mask", ATTR_DESC(new_axis_mask, AnyTraits())}, + {"shrink_axis_mask", ATTR_DESC(shrink_axis_mask, AnyTraits())}}; +OUTPUT_MAP(StridedSlice) = {{0, OUTPUT_DESC(y)}}; + +// UnsortedSegmentSum +INPUT_MAP(UnsortedSegmentSumD) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(segment_ids)}}; +INPUT_ATTR_MAP(UnsortedSegmentSumD) = {{3, ATTR_DESC(num_segments, AnyTraits())}}; +ATTR_MAP(UnsortedSegmentSumD) = EMPTY_ATTR_MAP; +OUTPUT_MAP(UnsortedSegmentSumD) = {{0, OUTPUT_DESC(y)}}; + +// UnsortedSegmentMin +INPUT_MAP(UnsortedSegmentMin) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(segment_ids)}, {3, INPUT_DESC(num_segments)}}; +ATTR_MAP(UnsortedSegmentMin) = EMPTY_ATTR_MAP; +OUTPUT_MAP(UnsortedSegmentMin) = {{0, OUTPUT_DESC(y)}}; + +// ExpandDims +INPUT_MAP(ExpandDims) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(axis)}}; +ATTR_MAP(ExpandDims) = EMPTY_ATTR_MAP; +OUTPUT_MAP(ExpandDims) = {{0, OUTPUT_DESC(y)}}; + +// Squeeze +INPUT_MAP(Squeeze) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Squeeze) = {{"axis", ATTR_DESC(axis, AnyTraits(), AnyTraits>())}}; +OUTPUT_MAP(Squeeze) = {{0, OUTPUT_DESC(y)}}; + +// SGD +INPUT_MAP(SGD) = {{1, INPUT_DESC(parameters)}, {2, INPUT_DESC(gradient)}, {3, INPUT_DESC(learning_rate)}, + {4, INPUT_DESC(accum)}, {5, INPUT_DESC(momentum)}, {6, INPUT_DESC(stat)}}; +ATTR_MAP(SGD) = {{"dampening", ATTR_DESC(dampening, AnyTraits())}, + {"weight_decay", ATTR_DESC(weight_decay, AnyTraits())}, + {"nesterov", ATTR_DESC(nesterov, AnyTraits())}}; +OUTPUT_MAP(SGD) = {{0, OUTPUT_DESC(parameters)}}; + +// LayerNorm +INPUT_MAP(LayerNorm) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(gamma)}, {3, INPUT_DESC(beta)}}; +ATTR_MAP(LayerNorm) = {{"begin_norm_axis", ATTR_DESC(begin_norm_axis, AnyTraits())}, + {"begin_params_axis", ATTR_DESC(begin_params_axis, AnyTraits())}, + {"epsilon", ATTR_DESC(epsilon, AnyTraits())}}; +OUTPUT_MAP(LayerNorm) = {{0, OUTPUT_DESC(y)}, {1, OUTPUT_DESC(mean)}, {2, OUTPUT_DESC(variance)}}; + +// LayerNormGrad +INPUT_MAP(LayerNormGrad) = { + {1, INPUT_DESC(x)}, {2, INPUT_DESC(dy)}, {3, INPUT_DESC(variance)}, {4, INPUT_DESC(mean)}, {5, INPUT_DESC(gamma)}}; +ATTR_MAP(LayerNormGrad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(LayerNormGrad) = {{0, OUTPUT_DESC(pd_x)}, {1, OUTPUT_DESC(pd_gamma)}, {2, OUTPUT_DESC(pd_beta)}}; + +// BatchMatMul +INPUT_MAP(BatchMatMul) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(BatchMatMul) = {{"transpose_x1", ATTR_DESC(adj_x1, AnyTraits())}, + {"transpose_x2", ATTR_DESC(adj_x2, AnyTraits())}}; +OUTPUT_MAP(BatchMatMul) = {{0, OUTPUT_DESC(y)}}; + +// DropoutDoMask +INPUT_MAP(DropOutDoMask) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(mask)}, {3, INPUT_DESC(keep_prob)}}; +ATTR_MAP(DropOutDoMask) = EMPTY_ATTR_MAP; +OUTPUT_MAP(DropOutDoMask) = {{0, OUTPUT_DESC(y)}}; + +// NPUGetFloatStatus +INPUT_MAP(NPUGetFloatStatus) = {{1, INPUT_DESC(addr)}}; +OUTPUT_MAP(NPUGetFloatStatus) = {{0, OUTPUT_DESC(data)}}; +ATTR_MAP(NPUGetFloatStatus) = EMPTY_ATTR_MAP; + +// NPUAllocFloatStatus +INPUT_MAP(NPUAllocFloatStatus) = EMPTY_INPUT_MAP; +ATTR_MAP(NPUAllocFloatStatus) = EMPTY_ATTR_MAP; +OUTPUT_MAP(NPUAllocFloatStatus) = {{0, OUTPUT_DESC(data)}}; + +// NPUClearFloatStatus +INPUT_MAP(NPUClearFloatStatus) = {{1, INPUT_DESC(addr)}}; +OUTPUT_MAP(NPUClearFloatStatus) = {{0, OUTPUT_DESC(data)}}; +ATTR_MAP(NPUClearFloatStatus) = EMPTY_ATTR_MAP; + +// Abs +INPUT_MAP(Abs) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Abs) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Abs) = {{0, OUTPUT_DESC(y)}}; + +// AbsGrad +INPUT_MAP(AbsGrad) = {{1, INPUT_DESC(y)}, {2, INPUT_DESC(dy)}}; +ATTR_MAP(AbsGrad) = EMPTY_ATTR_MAP; +OUTPUT_MAP(AbsGrad) = {{0, OUTPUT_DESC(z)}}; + +// BinaryCrossEntropy +INPUT_MAP(BinaryCrossEntropy) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(y)}, {3, INPUT_DESC(weight)}}; +ATTR_MAP(BinaryCrossEntropy) = {{"reduction", ATTR_DESC(reduction, AnyTraits())}}; +OUTPUT_MAP(BinaryCrossEntropy) = {{0, OUTPUT_DESC(output)}}; + +// BinaryCrossEntropyGrad +INPUT_MAP(BinaryCrossEntropyGrad) = { + {1, INPUT_DESC(x)}, {2, INPUT_DESC(y)}, {3, INPUT_DESC(grad_output)}, {4, INPUT_DESC(weight)}}; +ATTR_MAP(BinaryCrossEntropyGrad) = {{"reduction", ATTR_DESC(reduction, AnyTraits())}}; +OUTPUT_MAP(BinaryCrossEntropyGrad) = {{0, OUTPUT_DESC(output)}}; + +// SparseApplyAdagradD +INPUT_MAP(SparseApplyAdagradD) = { + {1, INPUT_DESC(var)}, {2, INPUT_DESC(accum)}, {3, INPUT_DESC(grad)}, {4, INPUT_DESC(indices)}}; +ATTR_MAP(SparseApplyAdagradD) = {{"lr", ATTR_DESC(lr, AnyTraits())}, + {"use_locking", ATTR_DESC(use_locking, AnyTraits())}}; +OUTPUT_MAP(SparseApplyAdagradD) = {{0, OUTPUT_DESC(var)}, {1, OUTPUT_DESC(accum)}}; + +// ApplyProximalAdagradD +INPUT_MAP(ApplyProximalAdagradD) = {{1, INPUT_DESC(var)}, {2, INPUT_DESC(accum)}, {3, INPUT_DESC(lr)}, + {4, INPUT_DESC(l1)}, {5, INPUT_DESC(l2)}, {6, INPUT_DESC(grad)}}; +ATTR_MAP(ApplyProximalAdagradD) = {{"use_locking", ATTR_DESC(use_locking, AnyTraits())}}; +OUTPUT_MAP(ApplyProximalAdagradD) = {{0, OUTPUT_DESC(var)}, {1, OUTPUT_DESC(accum)}}; + +// SparseApplyFtrlD +INPUT_MAP(SparseApplyFtrlD) = {{1, INPUT_DESC(var)}, + {2, INPUT_DESC(accum)}, + {3, INPUT_DESC(linear)}, + {4, INPUT_DESC(grad)}, + {5, INPUT_DESC(indices)}}; +ATTR_MAP(SparseApplyFtrlD) = {{"use_locking", ATTR_DESC(use_locking, AnyTraits())}, + {"lr", ATTR_DESC(lr, AnyTraits())}, + {"l1", ATTR_DESC(l1, AnyTraits())}, + {"l2", ATTR_DESC(l2, AnyTraits())}, + {"lr_power", ATTR_DESC(lr_power, AnyTraits())}}; +OUTPUT_MAP(SparseApplyFtrlD) = {{0, OUTPUT_DESC(var)}}; + +// SpaceToDepth +INPUT_MAP(SpaceToDepth) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(SpaceToDepth) = {{"block_size", ATTR_DESC(block_size, AnyTraits())}}; +OUTPUT_MAP(SpaceToDepth) = {{0, OUTPUT_DESC(y)}}; + +// DepthToSpace +INPUT_MAP(DepthToSpace) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(DepthToSpace) = {{"block_size", ATTR_DESC(block_size, AnyTraits())}}; +OUTPUT_MAP(DepthToSpace) = {{0, OUTPUT_DESC(y)}}; + +// Sign +INPUT_MAP(Sign) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Sign) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Sign) = {{0, OUTPUT_DESC(y)}}; + +// Round +INPUT_MAP(Round) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Round) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Round) = {{0, OUTPUT_DESC(y)}}; + +// ApplyFtrlD +INPUT_MAP(ApplyFtrlD) = {{1, INPUT_DESC(var)}, {2, INPUT_DESC(accum)}, {3, INPUT_DESC(linear)}, + {4, INPUT_DESC(grad)}, {5, INPUT_DESC(lr)}, {6, INPUT_DESC(l1)}, + {7, INPUT_DESC(l2)}, {8, INPUT_DESC(lr_power)}}; +ATTR_MAP(ApplyFtrlD) = {{"use_locking", ATTR_DESC(use_locking, AnyTraits())}}; +OUTPUT_MAP(ApplyFtrlD) = {{0, OUTPUT_DESC(var)}, {1, OUTPUT_DESC(accum)}, {2, OUTPUT_DESC(linear)}}; + +// Diag +INPUT_MAP(Diag) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(Diag) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Diag) = {{0, OUTPUT_DESC(y)}}; + +// DiagPart +INPUT_MAP(DiagPart) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(DiagPart) = EMPTY_ATTR_MAP; +OUTPUT_MAP(DiagPart) = {{0, OUTPUT_DESC(y)}}; + +// SpaceToBatchD +INPUT_MAP(SpaceToBatchD) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(SpaceToBatchD) = { + {"block_size", ATTR_DESC(block_size, AnyTraits())}, + {"paddings", ATTR_DESC(paddings, AnyTraits>>(), AnyTraits>())}}; +OUTPUT_MAP(SpaceToBatchD) = {{0, OUTPUT_DESC(y)}}; + +// BatchToSpaceD +INPUT_MAP(BatchToSpaceD) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(BatchToSpaceD) = { + {"block_size", ATTR_DESC(block_size, AnyTraits())}, + {"crops", ATTR_DESC(crops, AnyTraits>>(), AnyTraits>())}}; +OUTPUT_MAP(BatchToSpaceD) = {{0, OUTPUT_DESC(y)}}; + +// Atan2 +INPUT_MAP(Atan2) = {{1, INPUT_DESC(x1)}, {2, INPUT_DESC(x2)}}; +ATTR_MAP(Atan2) = EMPTY_ATTR_MAP; +OUTPUT_MAP(Atan2) = {{0, OUTPUT_DESC(y)}}; + +// ApplyRMSPropD +INPUT_MAP(ApplyRMSPropD) = { + {1, INPUT_DESC(var)}, {2, INPUT_DESC(ms)}, {3, INPUT_DESC(mom)}, {4, INPUT_DESC(lr)}, {5, INPUT_DESC(grad)}}; +INPUT_ATTR_MAP(ApplyRMSPropD) = {{6, ATTR_DESC(rho, AnyTraits())}, + {7, ATTR_DESC(momentum, AnyTraits())}, + {8, ATTR_DESC(epsilon, AnyTraits())}}; +ATTR_MAP(ApplyRMSPropD) = {{"use_locking", ATTR_DESC(use_locking, AnyTraits())}}; +OUTPUT_MAP(ApplyRMSPropD) = {{0, OUTPUT_DESC(var)}}; + +// ApplyCenteredRMSProp +INPUT_MAP(ApplyCenteredRMSProp) = {{1, INPUT_DESC(var)}, {2, INPUT_DESC(mg)}, {3, INPUT_DESC(ms)}, + {4, INPUT_DESC(mom)}, {5, INPUT_DESC(grad)}, {6, INPUT_DESC(lr)}, + {7, INPUT_DESC(rho)}, {8, INPUT_DESC(momentum)}, {9, INPUT_DESC(epsilon)}}; +ATTR_MAP(ApplyCenteredRMSProp) = {{"use_locking", ATTR_DESC(use_locking, AnyTraits())}}; +OUTPUT_MAP(ApplyCenteredRMSProp) = {{0, OUTPUT_DESC(var)}}; + +// L2Loss +INPUT_MAP(L2Loss) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(L2Loss) = EMPTY_ATTR_MAP; +OUTPUT_MAP(L2Loss) = {{0, OUTPUT_DESC(y)}}; + +// CTCLoss +INPUT_MAP(CTCLoss) = {{1, INPUT_DESC(inputs)}, + {2, INPUT_DESC(labels_indices)}, + {3, INPUT_DESC(labels_values)}, + {4, INPUT_DESC(sequence_length)}}; +ATTR_MAP(CTCLoss) = { + {"preprocess_collapse_repeated", ATTR_DESC(preprocess_collapse_repeated, AnyTraits())}, + {"ctc_merge_repeated", ATTR_DESC(ctc_merge_repeated, AnyTraits())}, + {"ignore_longer_outputs_than_inputs", ATTR_DESC(ignore_longer_outputs_than_inputs, AnyTraits())}}; +OUTPUT_MAP(CTCLoss) = {{0, OUTPUT_DESC(loss)}, {1, OUTPUT_DESC(gradient)}}; + +// AscendQuant +INPUT_MAP(AscendQuant) = {{1, INPUT_DESC(x)}}; +ATTR_MAP(AscendQuant) = {{"scale", ATTR_DESC(scale, AnyTraits())}, + {"offset", ATTR_DESC(offset, AnyTraits())}, + {"sqrt_mode", ATTR_DESC(sqrt_mode, AnyTraits())}, + {"round_mode", ATTR_DESC(round_mode, AnyTraits())}}; +OUTPUT_MAP(AscendQuant) = {{0, OUTPUT_DESC(y)}}; + +// AscendDequant +INPUT_MAP(AscendDequant) = {{1, INPUT_DESC(x)}, {2, INPUT_DESC(deq_scale)}}; +ATTR_MAP(AscendDequant) = {{"sqrt_mode", ATTR_DESC(sqrt_mode, AnyTraits())}, + {"relu_flag", ATTR_DESC(relu_flag, AnyTraits())}}; +OUTPUT_MAP(AscendDequant) = {{0, OUTPUT_DESC(y)}}; +#ifdef ENABLE_GE +// Print +INPUT_MAP(Print) = EMPTY_INPUT_MAP; +DYN_INPUT_MAP(Print) = {{1, DYN_INPUT_DESC(x)}}; +ATTR_MAP(Print) = EMPTY_ATTR_MAP; +#endif +} // namespace transform +} // namespace mindspore diff --git a/mindspore/ccsrc/utils/context/ms_context.cc b/mindspore/ccsrc/utils/context/ms_context.cc index 37b6bf638b..d6381ec7e8 100644 --- a/mindspore/ccsrc/utils/context/ms_context.cc +++ b/mindspore/ccsrc/utils/context/ms_context.cc @@ -192,21 +192,18 @@ bool MsContext::OpenTsd() { } MS_LOG(INFO) << "Device id = " << device_id << ", rank size = " << rank_size << "."; - - TDT_StatusT status = tdt::TsdClient::GetInstance()->Open(device_id, rank_size); - if (status != TDT_OK) { - MS_LOG(EXCEPTION) << "Device " << device_id << " is occupied, open tsd failed, status = " << status << "."; - return false; - } - tsd_ref_++; -#ifdef ENABLE_TDTQUE int32_t initStatus = tdt::TdtHostInit(device_id); if (initStatus != TDT_OK_CODE) { MS_LOG(EXCEPTION) << "Init tsd failed, status = " << initStatus << "."; return false; } tdt_print_ = std::thread(TensorPrint()); -#endif + TDT_StatusT status = tdt::TsdClient::GetInstance()->Open(device_id, rank_size); + if (status != TDT_OK) { + MS_LOG(EXCEPTION) << "Device " << device_id << " is occupied, open tsd failed, status = " << status << "."; + return false; + } + tsd_ref_++; MS_LOG(INFO) << "Open and init tsd successful, tsd reference = " << tsd_ref_ << "."; return true; } diff --git a/mindspore/ccsrc/utils/utils.h b/mindspore/ccsrc/utils/utils.h index 82bfe7a891..9798823461 100644 --- a/mindspore/ccsrc/utils/utils.h +++ b/mindspore/ccsrc/utils/utils.h @@ -173,6 +173,9 @@ constexpr auto kSparseApplyProximalAdagradOpName = "SparseApplyProximalAdagrad"; constexpr auto kSparseApplyRMSPropOpName = "SparseApplyRMSProp"; constexpr auto kSparseApplyAdadeltaOpName = "SparseApplyAdadelta"; constexpr auto kApplyAdamWithAmsgradOpName = "ApplyAdamWithAmsgrad"; +constexpr auto kTensorMoveOpName = "TensorMove"; +constexpr auto kTensorScatterUpdateOpName = "TensorScatterUpdate"; +constexpr auto kScatterNdUpdateOpName = "ScatterNdUpdate"; constexpr auto kPushOpName = "Push"; constexpr auto kPullOpName = "Pull"; constexpr auto kEmbeddingLookupOpName = "EmbeddingLookup"; @@ -236,6 +239,8 @@ constexpr auto kAttrNumSplit = "num_split"; constexpr auto kAttrOutputNum = "output_num"; constexpr auto kAttrSizeSplits = "size_splits"; constexpr auto kAttrOutputDefault = "output_default"; +constexpr auto kAttrPrimitiveTarget = "primitive_target"; +constexpr auto kAttrUseLocking = "use_locking"; constexpr auto kAttrReduceScatterFlag = "reduce_scatter_flag"; constexpr auto kAttrOffset = "offset"; constexpr auto kAttrPsKey = "ps_key"; diff --git a/mindspore/nn/layer/conv.py b/mindspore/nn/layer/conv.py index 52ec9f2d63..77c6ace75d 100644 --- a/mindspore/nn/layer/conv.py +++ b/mindspore/nn/layer/conv.py @@ -18,11 +18,12 @@ from mindspore.ops import operations as P from mindspore.common.parameter import Parameter from mindspore.common.initializer import initializer from mindspore._checkparam import ParamValidator as validator, Rel -from mindspore._checkparam import check_bool, twice, check_int_positive, check_int_non_negative +from mindspore._checkparam import Validator +from mindspore._checkparam import check_bool, twice, check_int_positive from mindspore._extends import cell_attr_register from ..cell import Cell -__all__ = ['Conv2d', 'Conv2dTranspose', 'DepthwiseConv2d'] +__all__ = ['Conv2d', 'Conv2dTranspose', 'DepthwiseConv2d', 'Conv1d', 'Conv1dTranspose'] class _Conv(Cell): """ @@ -47,7 +48,16 @@ class _Conv(Cell): self.kernel_size = kernel_size self.stride = stride self.pad_mode = pad_mode - self.padding = check_int_non_negative(padding) + if isinstance(padding, int): + Validator.check_integer('padding', padding, 0, Rel.GE, self.cls_name) + self.padding = padding + elif isinstance(padding, tuple): + for pad in padding: + Validator.check_integer('padding item', pad, 0, Rel.GE, self.cls_name) + self.padding = padding + else: + raise TypeError("padding type must be int/tuple(int) cannot be {}!".format(type(padding))) + self.dilation = dilation self.group = check_int_positive(group) self.has_bias = has_bias @@ -141,7 +151,10 @@ class Conv2d(_Conv): - pad: Implicit paddings on both sides of the input. The number of `padding` will be padded to the input Tensor borders. `padding` should be greater than or equal to 0. - padding (int): Implicit paddings on both sides of the input. Default: 0. + padding (Union[int, tuple[int]]): Implicit paddings on both sides of the input. If `padding` is one integer, + the padding of top, bottom, left and right is same, equal to padding. If `padding` is tuple with + four integer, the padding of top, bottom, left and right equal to padding[0], padding[1], + padding[2], padding[3] with corresponding. Default: 0. dilation (Union[int, tuple[int]]): The data type is int or tuple with 2 integers. Specifies the dilation rate to use for dilated convolution. If set to be :math:`k > 1`, there will be :math:`k - 1` pixels skipped for each sampling location. Its value should @@ -241,6 +254,174 @@ class Conv2d(_Conv): return s +class Conv1d(_Conv): + r""" + 1D convolution layer. + + Applies a 1D convolution over an input tensor which is typically of shape :math:`(N, C_{in}, W_{in})`, + where :math:`N` is batch size and :math:`C_{in}` is channel number. For each batch of shape + :math:`(C_{in}, W_{in})`, the formula is defined as: + + .. math:: + + out_j = \sum_{i=0}^{C_{in} - 1} ccor(W_{ij}, X_i) + b_j, + + where :math:`ccor` is cross correlation operator, :math:`C_{in}` is the input channel number, :math:`j` ranges + from :math:`0` to :math:`C_{out} - 1`, :math:`W_{ij}` corresponds to :math:`i`-th channel of the :math:`j`-th + filter and :math:`out_{j}` corresponds to the :math:`j`-th channel of the output. :math:`W_{ij}` is a slice + of kernel and it has shape :math:`(\text{ks_w})`, where :math:`\text{ks_w}` are width of the convolution kernel. + The full kernel has shape :math:`(C_{out}, C_{in} // \text{group}, \text{ks_w})`, where group is the group number + to split the input in the channel dimension. + + If the 'pad_mode' is set to be "valid", the output width will be + :math:`\left \lfloor{1 + \frac{W_{in} + 2 \times \text{padding} - \text{ks_w} - + (\text{ks_w} - 1) \times (\text{dilation} - 1) }{\text{stride}}} \right \rfloor` respectively. + + The first introduction can be found in paper `Gradient Based Learning Applied to Document Recognition + `_. + + Args: + in_channels (int): The number of input channel :math:`C_{in}`. + out_channels (int): The number of output channel :math:`C_{out}`. + kernel_size (int): The data type is int. Specifies the + width of the 1D convolution window. + stride (int): The distance of kernel moving, an int number that represents + the width of movement. Default: 1. + pad_mode (str): Specifies padding mode. The optional values are + "same", "valid", "pad". Default: "same". + + - same: Adopts the way of completion. Output width will be the same as the input. + Total number of padding will be calculated for horizontal + direction and evenly distributed to left and right if possible. Otherwise, the + last extra padding will be done from the bottom and the right side. If this mode is set, `padding` + must be 0. + + - valid: Adopts the way of discarding. The possibly largest width of output will be return + without padding. Extra pixels will be discarded. If this mode is set, `padding` + must be 0. + + - pad: Implicit paddings on both sides of the input. The number of `padding` will be padded to the input + Tensor borders. `padding` should be greater than or equal to 0. + + padding (int): Implicit paddings on both sides of the input. Default: 0. + dilation (int): The data type is int. Specifies the dilation rate + to use for dilated convolution. If set to be :math:`k > 1`, there will + be :math:`k - 1` pixels skipped for each sampling location. Its value should + be greater or equal to 1 and bounded by the height and width of the + input. Default: 1. + group (int): Split filter into groups, `in_ channels` and `out_channels` should be + divisible by the number of groups. Default: 1. + has_bias (bool): Specifies whether the layer uses a bias vector. Default: False. + weight_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the convolution kernel. + It can be a Tensor, a string, an Initializer or a numbers.Number. When a string is specified, + values from 'TruncatedNormal', 'Normal', 'Uniform', 'HeUniform' and 'XavierUniform' distributions as well + as constant 'One' and 'Zero' distributions are possible. Alias 'xavier_uniform', 'he_uniform', 'ones' + and 'zeros' are acceptable. Uppercase and lowercase are both acceptable. Refer to the values of + Initializer for more details. Default: 'normal'. + bias_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the bias vector. Possible + Initializer and string are the same as 'weight_init'. Refer to the values of + Initializer for more details. Default: 'zeros'. + + Inputs: + - **input** (Tensor) - Tensor of shape :math:`(N, C_{in}, W_{in})`. + + Outputs: + Tensor of shape :math:`(N, C_{out}, W_{out})`. + + Examples: + >>> net = nn.Conv1d(120, 240, 4, has_bias=False, weight_init='normal') + >>> input = Tensor(np.ones([1, 120, 640]), mindspore.float32) + >>> net(input).shape + (1, 240, 640) + """ + @cell_attr_register + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride=1, + pad_mode='same', + padding=0, + dilation=1, + group=1, + has_bias=False, + weight_init='normal', + bias_init='zeros'): + + Validator.check_value_type("kernel_size", kernel_size, [int], self.cls_name) + Validator.check_value_type("stride", stride, [int], self.cls_name) + Validator.check_value_type("padding", padding, [int], self.cls_name) + Validator.check_value_type("dilation", dilation, [int], self.cls_name) + Validator.check_integer('kernel_size', kernel_size, 1, Rel.GE, self.cls_name) + Validator.check_integer('stride', stride, 1, Rel.GE, self.cls_name) + Validator.check_integer('padding', padding, 0, Rel.GE, self.cls_name) + Validator.check_integer('dilation', dilation, 1, Rel.GE, self.cls_name) + kernel_size = (1, kernel_size) + stride = (1, stride) + dilation = (1, dilation) + + super(Conv1d, self).__init__( + in_channels, + out_channels, + kernel_size, + stride, + pad_mode, + padding, + dilation, + group, + has_bias, + weight_init, + bias_init) + self.padding = (0, 0, padding, padding) + self.conv2d = P.Conv2D(out_channel=self.out_channels, + kernel_size=self.kernel_size, + mode=1, + pad_mode=self.pad_mode, + pad=self.padding, + stride=self.stride, + dilation=self.dilation, + group=self.group) + self.bias_add = P.BiasAdd() + if pad_mode not in ('valid', 'same', 'pad'): + raise ValueError('Attr \'pad_mode\' of \'Conv1d\' Op passed ' + + str(pad_mode) + ', should be one of values in \'valid\', \'same\', \'pad\'.') + self.expand_dims = P.ExpandDims() + self.squeeze = P.Squeeze(2) + self.shape = P.Shape() + + def construct(self, x): + x_shape = self.shape(x) + if len(x_shape) == 3: + x = self.expand_dims(x, 2) + output = self.conv2d(x, self.weight) + if self.has_bias: + output = self.bias_add(output, self.bias) + if len(x_shape) == 3: + output = self.squeeze(output) + return output + + def extend_repr(self): + s = 'input_channels={}, output_channels={}, kernel_size={},' \ + 'stride={}, pad_mode={}, padding={}, dilation={}, ' \ + 'group={}, has_bias={},' \ + 'weight_init={}, bias_init={}'.format( + self.in_channels, + self.out_channels, + self.kernel_size, + self.stride, + self.pad_mode, + self.padding, + self.dilation, + self.group, + self.has_bias, + self.weight, + self.bias) + + if self.has_bias: + s += ', bias={}'.format(self.bias) + return s + + class Conv2dTranspose(_Conv): r""" 2D transposed convolution layer. @@ -268,7 +449,10 @@ class Conv2dTranspose(_Conv): - same: Adopted the way of completion. - valid: Adopted the way of discarding. - padding (int): Implicit paddings on both sides of the input. Default: 0. + padding (Union[int, tuple[int]]): Implicit paddings on both sides of the input. If `padding` is one integer, + the padding of top, bottom, left and right is same, equal to padding. If `padding` is tuple with + four integer, the padding of top, bottom, left and right equal to padding[0], padding[1], + padding[2], padding[3] with corresponding. Default: 0. dilation (Union[int, tuple[int]]): The data type is int or tuple with 2 integers. Specifies the dilation rate to use for dilated convolution. If set to be :math:`k > 1`, there will be :math:`k - 1` pixels skipped for each sampling location. Its value should @@ -313,6 +497,9 @@ class Conv2dTranspose(_Conv): kernel_size = twice(kernel_size) stride = twice(stride) dilation = twice(dilation) + Validator.check_value_type('padding', padding, (int, tuple), self.cls_name) + if isinstance(padding, tuple): + Validator.check_integer('padding size', len(padding), 4, Rel.EQ, self.cls_name) # out_channels and in_channels swap. # cause Conv2DBackpropInput's out_channel refers to Conv2D's out_channel, # then Conv2dTranspose's out_channel refers to Conv2DBackpropInput's in_channel. @@ -352,12 +539,16 @@ class Conv2dTranspose(_Conv): dilation=dilation, group=group) self.bias_add = P.BiasAdd() + if isinstance(self.padding, int): + self.padding_top, self.padding_bottom, self.padding_left, self.padding_right = (self.padding,) * 4 + else: + self.padding_top, self.padding_bottom, self.padding_left, self.padding_right = self.padding def set_strategy(self, strategy): self.conv2d_transpose.set_strategy(strategy) return self - def _deconv_output_length(self, input_length, filter_size, stride_size, dilation_size): + def _deconv_output_length(self, input_length, filter_size, stride_size, dilation_size, padding): """Calculate the width and height of output.""" length = 0 filter_size = filter_size + (filter_size - 1) * (dilation_size - 1) @@ -369,14 +560,16 @@ class Conv2dTranspose(_Conv): elif self.is_same: length = input_length * stride_size elif self.is_pad: - length = input_length * stride_size - 2 * self.padding + filter_size - stride_size + length = input_length * stride_size - padding + filter_size - stride_size return length def construct(self, x): n, _, h, w = self.shape(x) - h_out = self._deconv_output_length(h, self.kernel_size[0], self.stride[0], self.dilation[0]) - w_out = self._deconv_output_length(w, self.kernel_size[1], self.stride[1], self.dilation[1]) + h_out = self._deconv_output_length(h, self.kernel_size[0], self.stride[0], self.dilation[0], + self.padding_top + self.padding_bottom) + w_out = self._deconv_output_length(w, self.kernel_size[1], self.stride[1], self.dilation[1], + self.padding_left + self.padding_right) if self.has_bias: return self.bias_add(self.conv2d_transpose(x, self.weight, (n, self.out_channels, h_out, w_out)), self.bias) @@ -400,6 +593,181 @@ class Conv2dTranspose(_Conv): return s +class Conv1dTranspose(_Conv): + r""" + 1D transposed convolution layer. + + Compute a 1D transposed convolution, which is also know as a deconvolution + (although it is not actual deconvolution). + + Input is typically of shape :math:`(N, C, W)`, where :math:`N` is batch size and :math:`C` is channel number. + + Args: + in_channels (int): The number of channels in the input space. + out_channels (int): The number of channels in the output space. + kernel_size (int): int, which specifies the width of the 1D convolution window. + stride (int): The distance of kernel moving, an int number that represents + the width of movement. Default: 1. + pad_mode (str): Select the mode of the pad. The optional values are + "pad", "same", "valid". Default: "same". + + - pad: Implicit paddings on both sides of the input. + + - same: Adopted the way of completion. + + - valid: Adopted the way of discarding. + padding (int): Implicit paddings on both sides of the input. Default: 0. + dilation (int): The data type is int. Specifies the dilation rate + to use for dilated convolution. If set to be :math:`k > 1`, there will + be :math:`k - 1` pixels skipped for each sampling location. Its value should + be greater or equal to 1 and bounded by the width of the + input. Default: 1. + group (int): Split filter into groups, `in_channels` and `out_channels` should be + divisible by the number of groups. This is not support for Davinci devices when group > 1. Default: 1. + has_bias (bool): Specifies whether the layer uses a bias vector. Default: False. + weight_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the convolution kernel. + It can be a Tensor, a string, an Initializer or a numbers.Number. When a string is specified, + values from 'TruncatedNormal', 'Normal', 'Uniform', 'HeUniform' and 'XavierUniform' distributions as well + as constant 'One' and 'Zero' distributions are possible. Alias 'xavier_uniform', 'he_uniform', 'ones' + and 'zeros' are acceptable. Uppercase and lowercase are both acceptable. Refer to the values of + Initializer for more details. Default: 'normal'. + bias_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the bias vector. Possible + Initializer and string are the same as 'weight_init'. Refer to the values of + Initializer for more details. Default: 'zeros'. + + Inputs: + - **input** (Tensor) - Tensor of shape :math:`(N, C_{in}, W_{in})`. + + Outputs: + Tensor of shape :math:`(N, C_{out}, W_{out})`. + + Examples: + >>> net = nn.Conv1dTranspose(3, 64, 4, has_bias=False, weight_init='normal') + >>> input = Tensor(np.ones([1, 3, 50]), mindspore.float32) + >>> net(input) + """ + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride=1, + pad_mode='same', + padding=0, + dilation=1, + group=1, + has_bias=False, + weight_init='normal', + bias_init='zeros'): + Validator.check_value_type("kernel_size", kernel_size, [int], self.cls_name) + Validator.check_value_type("stride", stride, [int], self.cls_name) + Validator.check_value_type("padding", padding, [int], self.cls_name) + Validator.check_value_type("dilation", dilation, [int], self.cls_name) + Validator.check_integer('kernel_size', kernel_size, 1, Rel.GE, self.cls_name) + Validator.check_integer('stride', stride, 1, Rel.GE, self.cls_name) + Validator.check_integer('padding', padding, 0, Rel.GE, self.cls_name) + Validator.check_integer('dilation', dilation, 1, Rel.GE, self.cls_name) + kernel_size = (1, kernel_size) + stride = (1, stride) + dilation = (1, dilation) + # out_channels and in_channels swap. + # cause Conv2DBackpropInput's out_channel refers to Conv2D's out_channel, + # then Conv1dTranspose's out_channel refers to Conv2DBackpropInput's in_channel. + super(Conv1dTranspose, self).__init__( + in_channels, + out_channels, + kernel_size, + stride, + pad_mode, + padding, + dilation, + group, + has_bias, + weight_init, + bias_init, + transposed=True) + self.padding = (0, 0, padding, padding) + self.in_channels = in_channels + self.out_channels = out_channels + self.shape = P.Shape() + if pad_mode not in ('valid', 'same', 'pad'): + raise ValueError('Attr \'pad_mode\' of \'Conv1dTranspose\' Op passed ' + + str(pad_mode) + ', should be one of values in \'valid\', \'same\', \'pad\'.') + self.is_valid = self.pad_mode == 'valid' + self.is_same = self.pad_mode == 'same' + self.is_pad = self.pad_mode == 'pad' + if check_bool(has_bias): + self.bias = Parameter(initializer(bias_init, [out_channels]), name='bias') + + # cause Conv2DBackpropInput's out_channel refers to Conv2D's out_channel. + self.conv2d_transpose = P.Conv2DBackpropInput(out_channel=in_channels, + kernel_size=kernel_size, + mode=1, + pad_mode=pad_mode, + pad=self.padding, + stride=stride, + dilation=dilation, + group=group) + self.bias_add = P.BiasAdd() + self.expand_dims = P.ExpandDims() + self.squeeze = P.Squeeze(2) + + def set_strategy(self, strategy): + self.conv2d_transpose.set_strategy(strategy) + return self + + def _deconv_output_length(self, input_length, filter_size, stride_size, dilation_size, padding): + """Calculate the width and height of output.""" + length = 0 + filter_size = filter_size + (filter_size - 1) * (dilation_size - 1) + if self.is_valid: + if filter_size - stride_size > 0: + length = input_length * stride_size + filter_size - stride_size + else: + length = input_length * stride_size + elif self.is_same: + length = input_length * stride_size + elif self.is_pad: + length = input_length * stride_size - padding + filter_size - stride_size + + return length + + def construct(self, x): + x_shape = self.shape(x) + if len(x_shape) == 3: + x = self.expand_dims(x, 2) + + n, _, h, w = self.shape(x) + + h_out = self._deconv_output_length(h, self.kernel_size[0], self.stride[0], self.dilation[0], + self.padding[0] + self.padding[1]) + w_out = self._deconv_output_length(w, self.kernel_size[1], self.stride[1], self.dilation[1], + self.padding[2] + self.padding[3]) + output = self.conv2d_transpose(x, self.weight, (n, self.out_channels, h_out, w_out)) + if self.has_bias: + output = self.bias_add(output, self.bias) + + if len(x_shape) == 3: + output = self.squeeze(output) + return output + + def extend_repr(self): + s = 'input_channels={}, output_channels={}, kernel_size={},' \ + 'stride={}, pad_mode={}, padding={}, dilation={}, ' \ + 'group={}, has_bias={},' \ + 'weight_init={}, bias_init={}'.format(self.in_channels, + self.out_channels, + self.kernel_size, + self.stride, + self.pad_mode, + self.padding, + self.dilation, + self.group, + self.has_bias, + self.weight, + self.bias) + return s + + class DepthwiseConv2d(Cell): r""" 2D depthwise convolution layer. diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index 6c26fcea67..1277dc9e35 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -283,6 +283,7 @@ class AvgPool1d(_PoolNd): self.reduce_mean = P.ReduceMean(keep_dims=True) self.slice = P.Slice() self.expand = P.ExpandDims() + self.squeeze = P.Squeeze(2) def construct(self, x): _shape_check(self.shape(x)) @@ -295,4 +296,5 @@ class AvgPool1d(_PoolNd): else: x = self.expand(x, 2) x = self.avg_pool(x) + x = self.squeeze(x) return x diff --git a/mindspore/nn/optim/optimizer.py b/mindspore/nn/optim/optimizer.py index 4dcff00edf..37a4aee699 100755 --- a/mindspore/nn/optim/optimizer.py +++ b/mindspore/nn/optim/optimizer.py @@ -393,7 +393,6 @@ class Optimizer(Cell): current_dynamic_lr = self.gather(self.learning_rate[i], self.global_step, 0) lr += (current_dynamic_lr,) F.control_depend(lr, self.assignadd(self.global_step, 1)) - else: lr = self.learning_rate if self.dynamic_lr: diff --git a/mindspore/ops/_grad/__init__.py b/mindspore/ops/_grad/__init__.py index c2c837b89c..de9e3ae8d0 100644 --- a/mindspore/ops/_grad/__init__.py +++ b/mindspore/ops/_grad/__init__.py @@ -15,7 +15,7 @@ """grad impl.""" from . import grad_array_ops, grad_comm_ops, grad_debug_ops, grad_implementations, \ - grad_math_ops, grad_nn_ops, grad_other_ops, grad_quant_ops + grad_inner_ops, grad_math_ops, grad_nn_ops, grad_other_ops, grad_quant_ops from .grad_base import get_bprop_fn __all__ = ['get_bprop_fn'] diff --git a/mindspore/ops/_grad/grad_array_ops.py b/mindspore/ops/_grad/grad_array_ops.py index 1560425ac2..03b97edb10 100644 --- a/mindspore/ops/_grad/grad_array_ops.py +++ b/mindspore/ops/_grad/grad_array_ops.py @@ -211,6 +211,25 @@ def get_bprop_embedding_lookup(self): return bprop_sparse +@bprop_getters.register(P.EmbeddingLookup) +def get_bprop_embedding_look_up(self): + """Generate bprop for EmbeddingLookup""" + sub_op = P.Sub() + reshape_op = P.Reshape() + def bprop(x, indices, offset, out, dout): + x_shp = shape_op(x) + new_indices = sub_op(indices, offset) + # Reshape the 'new_indices' + new_indices_shape_changed = (size_op(new_indices),) + new_indices = reshape_op(new_indices, new_indices_shape_changed) + actual_dout_shape_changed = new_indices_shape_changed + if len(x_shp) > 1: + actual_dout_shape_changed += x_shp[1:] + actual_dout = reshape_op(dout, actual_dout_shape_changed) + return (new_indices, actual_dout, x_shp), zeros_like(indices), zeros_like(offset) + return bprop + + @bprop_getters.register(P.Transpose) def get_bprop_transpose(self): """Generate bprop for Transpose""" diff --git a/mindspore/ops/_grad/grad_inner_ops.py b/mindspore/ops/_grad/grad_inner_ops.py new file mode 100644 index 0000000000..4a6a4c470e --- /dev/null +++ b/mindspore/ops/_grad/grad_inner_ops.py @@ -0,0 +1,39 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ + +"""array_ops""" + +from .. import operations as P +from ..operations import _grad_ops as G +from ..operations import _inner_ops as inner +from ..composite.multitype_ops.zeros_like_impl import zeros_like +from .grad_base import bprop_getters + + +@bprop_getters.register(inner.StridedSliceAICPU) +def get_bprop_strided_slice_aicpu(self): + """Generate bprop for StridedSlice""" + shape_op = P.Shape() + input_grad = G.StridedSliceGradAICPU(self.begin_mask, + self.end_mask, + self.ellipsis_mask, + self.new_axis_mask, + self.shrink_axis_mask) + + def bprop(x, begin, end, strides, out, dout): + dx = input_grad(dout, shape_op(x), begin, end, strides) + return dx, zeros_like(begin), zeros_like(end), zeros_like(strides) + + return bprop diff --git a/mindspore/ops/_grad/grad_nn_ops.py b/mindspore/ops/_grad/grad_nn_ops.py index 63e63770e4..61c7e40960 100755 --- a/mindspore/ops/_grad/grad_nn_ops.py +++ b/mindspore/ops/_grad/grad_nn_ops.py @@ -673,7 +673,7 @@ def get_bprop_mirror_pad(self): mirror_pad_grad = G.MirrorPadGrad(self.mode) def bprop(x, paddings, out, dout): - dx = mirror_pad_grad(dout, paddings, x) + dx = mirror_pad_grad(dout, paddings) return (dx, zeros_like(paddings)) return bprop diff --git a/mindspore/ops/_op_impl/aicpu/__init__.py b/mindspore/ops/_op_impl/aicpu/__init__.py index 8914ee8719..8eb08aea2f 100644 --- a/mindspore/ops/_op_impl/aicpu/__init__.py +++ b/mindspore/ops/_op_impl/aicpu/__init__.py @@ -14,6 +14,7 @@ """aicpu ops""" from .init_data_set_queue import _init_data_set_queue_aicpu +from .embedding_lookup import _embedding_lookup_aicpu from .dropout_genmask import _dropout_genmask_aicpu from .get_next import _get_next_aicpu from .print_tensor import _print_aicpu @@ -25,10 +26,20 @@ from .squeeze import _squeeze_aicpu from .expand_dims import _expand_dims_aicpu from .random_choice_with_mask import _random_choice_with_mask_aicpu from .pack import _pack_aicpu -from .normal import _normal_aicpu from .ctcloss import _ctcloss_aicpu from .reverse_sequence import _reverse_sequence_aicpu from .crop_and_resize import _crop_and_resize_aicpu -from .end_of_sequence import _end_of_sequence_aicpu from .rnnt_loss import _rnnt_loss_aicpu from .random_categorical import _random_categorical_aicpu +from .cast import _cast_aicpu +from .mirror_pad import _mirror_pad_aicpu +from .mirror_pad_grad import _mirror_pad_grad_aicpu +from .standard_normal import _standard_normal_aicpu +from .gamma import _gamma_aicpu +from .poisson import _poisson_aicpu +from .uniform_int import _uniform_int_aicpu +from .uniform_real import _uniform_real_aicpu +from .laplace import _laplace_aicpu +from .strided_slice import _strided_slice_aicpu +from .strided_slice_grad import _strided_slice_grad_aicpu +from .end_of_sequence import _end_of_sequence_aicpu diff --git a/mindspore/ops/_op_impl/aicpu/cast.py b/mindspore/ops/_op_impl/aicpu/cast.py new file mode 100644 index 0000000000..32dbea3147 --- /dev/null +++ b/mindspore/ops/_op_impl/aicpu/cast.py @@ -0,0 +1,172 @@ +# 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. +# ============================================================================ + +"""Cast op""" +from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType + +cast_op_info = AiCPURegOp("Cast") \ + .fusion_type("OPAQUE") \ + .input(0, "x", "required") \ + .output(0, "y", "required") \ + .dtype_format(DataType.U8_Default, DataType.U8_Default) \ + .dtype_format(DataType.U8_Default, DataType.U16_Default) \ + .dtype_format(DataType.U8_Default, DataType.U32_Default) \ + .dtype_format(DataType.U8_Default, DataType.U64_Default) \ + .dtype_format(DataType.U8_Default, DataType.I8_Default) \ + .dtype_format(DataType.U8_Default, DataType.I16_Default) \ + .dtype_format(DataType.U8_Default, DataType.I32_Default) \ + .dtype_format(DataType.U8_Default, DataType.I64_Default) \ + .dtype_format(DataType.U8_Default, DataType.F16_Default) \ + .dtype_format(DataType.U8_Default, DataType.F32_Default) \ + .dtype_format(DataType.U8_Default, DataType.F64_Default) \ + .dtype_format(DataType.U8_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.U16_Default, DataType.U8_Default) \ + .dtype_format(DataType.U16_Default, DataType.U16_Default) \ + .dtype_format(DataType.U16_Default, DataType.U32_Default) \ + .dtype_format(DataType.U16_Default, DataType.U64_Default) \ + .dtype_format(DataType.U16_Default, DataType.I8_Default) \ + .dtype_format(DataType.U16_Default, DataType.I16_Default) \ + .dtype_format(DataType.U16_Default, DataType.I32_Default) \ + .dtype_format(DataType.U16_Default, DataType.I64_Default) \ + .dtype_format(DataType.U16_Default, DataType.F16_Default) \ + .dtype_format(DataType.U16_Default, DataType.F32_Default) \ + .dtype_format(DataType.U16_Default, DataType.F64_Default) \ + .dtype_format(DataType.U16_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.U32_Default, DataType.U8_Default) \ + .dtype_format(DataType.U32_Default, DataType.U16_Default) \ + .dtype_format(DataType.U32_Default, DataType.U32_Default) \ + .dtype_format(DataType.U32_Default, DataType.U64_Default) \ + .dtype_format(DataType.U32_Default, DataType.I8_Default) \ + .dtype_format(DataType.U32_Default, DataType.I16_Default) \ + .dtype_format(DataType.U32_Default, DataType.I32_Default) \ + .dtype_format(DataType.U32_Default, DataType.I64_Default) \ + .dtype_format(DataType.U32_Default, DataType.F16_Default) \ + .dtype_format(DataType.U32_Default, DataType.F32_Default) \ + .dtype_format(DataType.U32_Default, DataType.F64_Default) \ + .dtype_format(DataType.U32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.U64_Default, DataType.U8_Default) \ + .dtype_format(DataType.U64_Default, DataType.U16_Default) \ + .dtype_format(DataType.U64_Default, DataType.U32_Default) \ + .dtype_format(DataType.U64_Default, DataType.U64_Default) \ + .dtype_format(DataType.U64_Default, DataType.I8_Default) \ + .dtype_format(DataType.U64_Default, DataType.I16_Default) \ + .dtype_format(DataType.U64_Default, DataType.I32_Default) \ + .dtype_format(DataType.U64_Default, DataType.I64_Default) \ + .dtype_format(DataType.U64_Default, DataType.F16_Default) \ + .dtype_format(DataType.U64_Default, DataType.F32_Default) \ + .dtype_format(DataType.U64_Default, DataType.F64_Default) \ + .dtype_format(DataType.U64_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I8_Default, DataType.U8_Default) \ + .dtype_format(DataType.I8_Default, DataType.U16_Default) \ + .dtype_format(DataType.I8_Default, DataType.U32_Default) \ + .dtype_format(DataType.I8_Default, DataType.U64_Default) \ + .dtype_format(DataType.I8_Default, DataType.I8_Default) \ + .dtype_format(DataType.I8_Default, DataType.I16_Default) \ + .dtype_format(DataType.I8_Default, DataType.I32_Default) \ + .dtype_format(DataType.I8_Default, DataType.I64_Default) \ + .dtype_format(DataType.I8_Default, DataType.F16_Default) \ + .dtype_format(DataType.I8_Default, DataType.F32_Default) \ + .dtype_format(DataType.I8_Default, DataType.F64_Default) \ + .dtype_format(DataType.I8_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I16_Default, DataType.U8_Default) \ + .dtype_format(DataType.I16_Default, DataType.U16_Default) \ + .dtype_format(DataType.I16_Default, DataType.U32_Default) \ + .dtype_format(DataType.I16_Default, DataType.U64_Default) \ + .dtype_format(DataType.I16_Default, DataType.I8_Default) \ + .dtype_format(DataType.I16_Default, DataType.I16_Default) \ + .dtype_format(DataType.I16_Default, DataType.I32_Default) \ + .dtype_format(DataType.I16_Default, DataType.I64_Default) \ + .dtype_format(DataType.I16_Default, DataType.F16_Default) \ + .dtype_format(DataType.I16_Default, DataType.F32_Default) \ + .dtype_format(DataType.I16_Default, DataType.F64_Default) \ + .dtype_format(DataType.I16_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I32_Default, DataType.U8_Default) \ + .dtype_format(DataType.I32_Default, DataType.U16_Default) \ + .dtype_format(DataType.I32_Default, DataType.U32_Default) \ + .dtype_format(DataType.I32_Default, DataType.U64_Default) \ + .dtype_format(DataType.I32_Default, DataType.I8_Default) \ + .dtype_format(DataType.I32_Default, DataType.I16_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_Default, DataType.I64_Default) \ + .dtype_format(DataType.I32_Default, DataType.F16_Default) \ + .dtype_format(DataType.I32_Default, DataType.F32_Default) \ + .dtype_format(DataType.I32_Default, DataType.F64_Default) \ + .dtype_format(DataType.I32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I64_Default, DataType.U8_Default) \ + .dtype_format(DataType.I64_Default, DataType.U16_Default) \ + .dtype_format(DataType.I64_Default, DataType.U32_Default) \ + .dtype_format(DataType.I64_Default, DataType.U64_Default) \ + .dtype_format(DataType.I64_Default, DataType.I8_Default) \ + .dtype_format(DataType.I64_Default, DataType.I16_Default) \ + .dtype_format(DataType.I64_Default, DataType.I32_Default) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default) \ + .dtype_format(DataType.I64_Default, DataType.F16_Default) \ + .dtype_format(DataType.I64_Default, DataType.F32_Default) \ + .dtype_format(DataType.I64_Default, DataType.F64_Default) \ + .dtype_format(DataType.I64_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F16_Default, DataType.U8_Default) \ + .dtype_format(DataType.F16_Default, DataType.U16_Default) \ + .dtype_format(DataType.F16_Default, DataType.U32_Default) \ + .dtype_format(DataType.F16_Default, DataType.U64_Default) \ + .dtype_format(DataType.F16_Default, DataType.I8_Default) \ + .dtype_format(DataType.F16_Default, DataType.I16_Default) \ + .dtype_format(DataType.F16_Default, DataType.I32_Default) \ + .dtype_format(DataType.F16_Default, DataType.I64_Default) \ + .dtype_format(DataType.F16_Default, DataType.F16_Default) \ + .dtype_format(DataType.F16_Default, DataType.F32_Default) \ + .dtype_format(DataType.F16_Default, DataType.F64_Default) \ + .dtype_format(DataType.F16_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F32_Default, DataType.U8_Default) \ + .dtype_format(DataType.F32_Default, DataType.U16_Default) \ + .dtype_format(DataType.F32_Default, DataType.U32_Default) \ + .dtype_format(DataType.F32_Default, DataType.U64_Default) \ + .dtype_format(DataType.F32_Default, DataType.I8_Default) \ + .dtype_format(DataType.F32_Default, DataType.I16_Default) \ + .dtype_format(DataType.F32_Default, DataType.I32_Default) \ + .dtype_format(DataType.F32_Default, DataType.I64_Default) \ + .dtype_format(DataType.F32_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F32_Default, DataType.F64_Default) \ + .dtype_format(DataType.F32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.F64_Default, DataType.U8_Default) \ + .dtype_format(DataType.F64_Default, DataType.U16_Default) \ + .dtype_format(DataType.F64_Default, DataType.U32_Default) \ + .dtype_format(DataType.F64_Default, DataType.U64_Default) \ + .dtype_format(DataType.F64_Default, DataType.I8_Default) \ + .dtype_format(DataType.F64_Default, DataType.I16_Default) \ + .dtype_format(DataType.F64_Default, DataType.I32_Default) \ + .dtype_format(DataType.F64_Default, DataType.I64_Default) \ + .dtype_format(DataType.F64_Default, DataType.F16_Default) \ + .dtype_format(DataType.F64_Default, DataType.F32_Default) \ + .dtype_format(DataType.F64_Default, DataType.F64_Default) \ + .dtype_format(DataType.F64_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.U8_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.U16_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.U32_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.U64_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.I8_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.I16_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.I32_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.I64_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.F16_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.F32_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.F64_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.BOOL_Default) \ + .get_op_info() + +@op_info_register(cast_op_info) +def _cast_aicpu(): + """Cast AiCPU register""" + return diff --git a/mindspore/ops/_op_impl/aicpu/embedding_lookup.py b/mindspore/ops/_op_impl/aicpu/embedding_lookup.py new file mode 100644 index 0000000000..8eecc5145d --- /dev/null +++ b/mindspore/ops/_op_impl/aicpu/embedding_lookup.py @@ -0,0 +1,102 @@ +# 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. +# ============================================================================ + +"""EmbeddingLookup op""" +from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType + +embeddingLookup_op_info = AiCPURegOp("EmbeddingLookup") \ + .fusion_type("OPAQUE") \ + .input(0, "params", "required") \ + .input(1, "indices", "required") \ + .input(2, "offset", "required") \ + .output(0, "output", "required") \ + .dtype_format(DataType.I8_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.I8_Default) \ + .dtype_format(DataType.I16_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.I16_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I64_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.I64_Default) \ + .dtype_format(DataType.U8_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.U8_Default) \ + .dtype_format(DataType.U16_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.U16_Default) \ + .dtype_format(DataType.U32_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.U32_Default) \ + .dtype_format(DataType.U64_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.U64_Default) \ + .dtype_format(DataType.F16_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F64_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.F64_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.I32_Default, \ + DataType.I32_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I8_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.I8_Default) \ + .dtype_format(DataType.I16_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.I16_Default) \ + .dtype_format(DataType.I32_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.I32_Default) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.I64_Default) \ + .dtype_format(DataType.U8_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.U8_Default) \ + .dtype_format(DataType.U16_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.U16_Default) \ + .dtype_format(DataType.U32_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.U32_Default) \ + .dtype_format(DataType.U64_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.U64_Default) \ + .dtype_format(DataType.F16_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.F32_Default) \ + .dtype_format(DataType.F64_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.F64_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.I64_Default, \ + DataType.I64_Default, DataType.BOOL_Default) \ + .dtype_format(DataType.I8_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.I8_Default) \ + .dtype_format(DataType.I16_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.I16_Default) \ + .dtype_format(DataType.I32_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.I64_Default) \ + .dtype_format(DataType.U8_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.U8_Default) \ + .dtype_format(DataType.U16_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.U16_Default) \ + .dtype_format(DataType.U32_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.U32_Default) \ + .dtype_format(DataType.U64_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.U64_Default) \ + .dtype_format(DataType.F16_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F64_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.F64_Default) \ + .dtype_format(DataType.BOOL_Default, DataType.I64_Default, \ + DataType.I32_Default, DataType.BOOL_Default) \ + .get_op_info() + +@op_info_register(embeddingLookup_op_info) +def _embedding_lookup_aicpu(): + """EmbeddingLookup AiCPU register""" + return diff --git a/mindspore/ops/_op_impl/aicpu/gamma.py b/mindspore/ops/_op_impl/aicpu/gamma.py new file mode 100644 index 0000000000..b6b92a9da4 --- /dev/null +++ b/mindspore/ops/_op_impl/aicpu/gamma.py @@ -0,0 +1,33 @@ +# 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. +# ============================================================================ + +"""RandomGamma op""" +from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType + +gamma_op_info = AiCPURegOp("Gamma") \ + .fusion_type("OPAQUE") \ + .input(0, "shape", "required") \ + .input(1, "alpha", "required") \ + .input(2, "beta", "required") \ + .output(0, "output", "required") \ + .attr("seed", "int") \ + .dtype_format(DataType.I32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.I32_NCHW, DataType.F32_NCHW, DataType.F32_NCHW, DataType.F32_NCHW) \ + .get_op_info() + +@op_info_register(gamma_op_info) +def _gamma_aicpu(): + """RandomGamma AiCPU register""" + return diff --git a/mindspore/ops/_op_impl/aicpu/normal.py b/mindspore/ops/_op_impl/aicpu/laplace.py similarity index 82% rename from mindspore/ops/_op_impl/aicpu/normal.py rename to mindspore/ops/_op_impl/aicpu/laplace.py index fdb96e362f..6bb284ed07 100644 --- a/mindspore/ops/_op_impl/aicpu/normal.py +++ b/mindspore/ops/_op_impl/aicpu/laplace.py @@ -13,21 +13,21 @@ # limitations under the License. # ============================================================================ -"""Normal op""" +"""RandomLaplace op""" from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType -normal_op_info = AiCPURegOp("Normal") \ +laplace_op_info = AiCPURegOp("Laplace") \ .fusion_type("OPAQUE") \ .input(0, "shape", "required") \ .input(1, "mean", "required") \ - .input(2, "stddev", "required") \ - .output(0, "y", "required") \ + .input(2, "lambda_param", "required") \ + .output(0, "output", "required") \ .attr("seed", "int") \ .dtype_format(DataType.I32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ .dtype_format(DataType.I32_NCHW, DataType.F32_NCHW, DataType.F32_NCHW, DataType.F32_NCHW) \ .get_op_info() -@op_info_register(normal_op_info) -def _normal_aicpu(): - """Normal AiCPU register""" +@op_info_register(laplace_op_info) +def _laplace_aicpu(): + """RandomLaplace AiCPU register""" return diff --git a/mindspore/ops/_op_impl/aicpu/mirror_pad.py b/mindspore/ops/_op_impl/aicpu/mirror_pad.py new file mode 100644 index 0000000000..6f3855cc2d --- /dev/null +++ b/mindspore/ops/_op_impl/aicpu/mirror_pad.py @@ -0,0 +1,52 @@ +# 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. +# ============================================================================ + +"""MirrorPad op""" +from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType +mirror_pad_op_info = AiCPURegOp("MirrorPad") \ + .fusion_type("OPAQUE") \ + .input(0, "x", "required") \ + .input(1, "paddings", "required") \ + .output(0, "y", "required") \ + .attr("mode", "str") \ + .dtype_format(DataType.I8_Default, DataType.I32_Default, DataType.I8_Default) \ + .dtype_format(DataType.I16_Default, DataType.I32_Default, DataType.I16_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I64_Default, DataType.I32_Default, DataType.I64_Default) \ + .dtype_format(DataType.U8_Default, DataType.I32_Default, DataType.U8_Default) \ + .dtype_format(DataType.U16_Default, DataType.I32_Default, DataType.U16_Default) \ + .dtype_format(DataType.U32_Default, DataType.I32_Default, DataType.U32_Default) \ + .dtype_format(DataType.U64_Default, DataType.I32_Default, DataType.U64_Default) \ + .dtype_format(DataType.F16_Default, DataType.I32_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.I32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F64_Default, DataType.I32_Default, DataType.F64_Default) \ + .dtype_format(DataType.I8_Default, DataType.I64_Default, DataType.I8_Default) \ + .dtype_format(DataType.I16_Default, DataType.I64_Default, DataType.I16_Default) \ + .dtype_format(DataType.I32_Default, DataType.I64_Default, DataType.I32_Default) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default, DataType.I64_Default) \ + .dtype_format(DataType.U8_Default, DataType.I64_Default, DataType.U8_Default) \ + .dtype_format(DataType.U16_Default, DataType.I64_Default, DataType.U16_Default) \ + .dtype_format(DataType.U32_Default, DataType.I64_Default, DataType.U32_Default) \ + .dtype_format(DataType.U64_Default, DataType.I64_Default, DataType.U64_Default) \ + .dtype_format(DataType.F16_Default, DataType.I64_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.I64_Default, DataType.F32_Default) \ + .dtype_format(DataType.F64_Default, DataType.I64_Default, DataType.F64_Default) \ + .get_op_info() + + +@op_info_register(mirror_pad_op_info) +def _mirror_pad_aicpu(): + """MirrorPad AiCPU register""" + return diff --git a/mindspore/ops/_op_impl/aicpu/mirror_pad_grad.py b/mindspore/ops/_op_impl/aicpu/mirror_pad_grad.py new file mode 100644 index 0000000000..f8b38d155b --- /dev/null +++ b/mindspore/ops/_op_impl/aicpu/mirror_pad_grad.py @@ -0,0 +1,52 @@ +# 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. +# ============================================================================ + +"""MirrorPadGrad op""" +from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType +mirror_pad_grad_op_info = AiCPURegOp("MirrorPadGrad") \ + .fusion_type("OPAQUE") \ + .input(0, "x", "required") \ + .input(1, "paddings", "required") \ + .output(0, "y", "required") \ + .attr("mode", "str") \ + .dtype_format(DataType.I8_Default, DataType.I32_Default, DataType.I8_Default) \ + .dtype_format(DataType.I16_Default, DataType.I32_Default, DataType.I16_Default) \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I64_Default, DataType.I32_Default, DataType.I64_Default) \ + .dtype_format(DataType.U8_Default, DataType.I32_Default, DataType.U8_Default) \ + .dtype_format(DataType.U16_Default, DataType.I32_Default, DataType.U16_Default) \ + .dtype_format(DataType.U32_Default, DataType.I32_Default, DataType.U32_Default) \ + .dtype_format(DataType.U64_Default, DataType.I32_Default, DataType.U64_Default) \ + .dtype_format(DataType.F16_Default, DataType.I32_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.I32_Default, DataType.F32_Default) \ + .dtype_format(DataType.F64_Default, DataType.I32_Default, DataType.F64_Default) \ + .dtype_format(DataType.I8_Default, DataType.I64_Default, DataType.I8_Default) \ + .dtype_format(DataType.I16_Default, DataType.I64_Default, DataType.I16_Default) \ + .dtype_format(DataType.I32_Default, DataType.I64_Default, DataType.I32_Default) \ + .dtype_format(DataType.I64_Default, DataType.I64_Default, DataType.I64_Default) \ + .dtype_format(DataType.U8_Default, DataType.I64_Default, DataType.U8_Default) \ + .dtype_format(DataType.U16_Default, DataType.I64_Default, DataType.U16_Default) \ + .dtype_format(DataType.U32_Default, DataType.I64_Default, DataType.U32_Default) \ + .dtype_format(DataType.U64_Default, DataType.I64_Default, DataType.U64_Default) \ + .dtype_format(DataType.F16_Default, DataType.I64_Default, DataType.F16_Default) \ + .dtype_format(DataType.F32_Default, DataType.I64_Default, DataType.F32_Default) \ + .dtype_format(DataType.F64_Default, DataType.I64_Default, DataType.F64_Default) \ + .get_op_info() + + +@op_info_register(mirror_pad_grad_op_info) +def _mirror_pad_grad_aicpu(): + """MirrorPadGrad AiCPU register""" + return diff --git a/mindspore/ops/_op_impl/aicpu/poisson.py b/mindspore/ops/_op_impl/aicpu/poisson.py new file mode 100644 index 0000000000..59d2c1b957 --- /dev/null +++ b/mindspore/ops/_op_impl/aicpu/poisson.py @@ -0,0 +1,32 @@ +# 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. +# ============================================================================ + +"""RandomPoisson op""" +from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType + +poisson_op_info = AiCPURegOp("Poisson") \ + .fusion_type("OPAQUE") \ + .input(0, "shape", "required") \ + .input(1, "mean", "required") \ + .output(0, "output", "required") \ + .attr("seed", "int") \ + .dtype_format(DataType.I32_Default, DataType.F32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_NCHW, DataType.F32_NCHW, DataType.I32_NCHW) \ + .get_op_info() + +@op_info_register(poisson_op_info) +def _poisson_aicpu(): + """RandomPoisson AiCPU register""" + return diff --git a/mindspore/ops/_op_impl/aicpu/standard_normal.py b/mindspore/ops/_op_impl/aicpu/standard_normal.py new file mode 100644 index 0000000000..5f5d571913 --- /dev/null +++ b/mindspore/ops/_op_impl/aicpu/standard_normal.py @@ -0,0 +1,32 @@ +# 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. +# ============================================================================ + +"""RandomNormal op""" +from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType + +normal_op_info = AiCPURegOp("StandardNormal") \ + .fusion_type("OPAQUE") \ + .input(0, "shape", "required") \ + .output(0, "output", "required") \ + .attr("seed", "int") \ + .attr("seed2", "int") \ + .dtype_format(DataType.I32_Default, DataType.F32_Default) \ + .dtype_format(DataType.I32_NCHW, DataType.F32_NCHW) \ + .get_op_info() + +@op_info_register(normal_op_info) +def _standard_normal_aicpu(): + """RandomNormal AiCPU register""" + return diff --git a/mindspore/ops/_op_impl/aicpu/strided_slice.py b/mindspore/ops/_op_impl/aicpu/strided_slice.py new file mode 100644 index 0000000000..0506e4104d --- /dev/null +++ b/mindspore/ops/_op_impl/aicpu/strided_slice.py @@ -0,0 +1,41 @@ +# 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. +# ============================================================================ + +"""StridedSlice op""" +from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType + +strided_slice_op_info = AiCPURegOp("StridedSliceAICPU") \ + .fusion_type("OPAQUE") \ + .input(0, "input", "required") \ + .input(1, "begin", "required") \ + .input(2, "end", "required") \ + .input(3, "stride", "required") \ + .output(0, "output", "required") \ + .attr("begin_mask", "int") \ + .attr("end_mask", "int") \ + .attr("ellipsis_mask", "int") \ + .attr("new_axis_mask", "int") \ + .attr("shrink_axis_mask", "int") \ + .dtype_format(DataType.F32_Default, + DataType.I32_Default, + DataType.I32_Default, + DataType.I32_Default, + DataType.F32_Default) \ + .get_op_info() + +@op_info_register(strided_slice_op_info) +def _strided_slice_aicpu(): + """StridedSlice AiCPU register""" + return diff --git a/mindspore/ops/_op_impl/aicpu/strided_slice_grad.py b/mindspore/ops/_op_impl/aicpu/strided_slice_grad.py new file mode 100644 index 0000000000..b94c5d4c4b --- /dev/null +++ b/mindspore/ops/_op_impl/aicpu/strided_slice_grad.py @@ -0,0 +1,43 @@ +# 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. +# ============================================================================ + +"""StridedSliceGrad op""" +from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType + +strided_slice_grad_op_info = AiCPURegOp("StridedSliceGradAICPU") \ + .fusion_type("OPAQUE") \ + .input(0, "dy", "required") \ + .input(1, "shape", "required") \ + .input(2, "begin", "required") \ + .input(3, "end", "required") \ + .input(4, "stride", "required") \ + .output(0, "output", "required") \ + .attr("begin_mask", "int") \ + .attr("end_mask", "int") \ + .attr("ellipsis_mask", "int") \ + .attr("new_axis_mask", "int") \ + .attr("shrink_axis_mask", "int") \ + .dtype_format(DataType.F32_Default, + DataType.I32_Default, + DataType.I32_Default, + DataType.I32_Default, + DataType.I32_Default, + DataType.F32_Default) \ + .get_op_info() + +@op_info_register(strided_slice_grad_op_info) +def _strided_slice_grad_aicpu(): + """StridedSliceGrad AiCPU register""" + return diff --git a/mindspore/ops/_op_impl/aicpu/uniform_int.py b/mindspore/ops/_op_impl/aicpu/uniform_int.py new file mode 100644 index 0000000000..35cfbec11c --- /dev/null +++ b/mindspore/ops/_op_impl/aicpu/uniform_int.py @@ -0,0 +1,33 @@ +# 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. +# ============================================================================ + +"""RandomUniformInt op""" +from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType + +uniform_int_op_info = AiCPURegOp("UniformInt") \ + .fusion_type("OPAQUE") \ + .input(0, "shape", "required") \ + .input(1, "a", "required") \ + .input(2, "b", "required") \ + .output(0, "output", "required") \ + .attr("seed", "int") \ + .dtype_format(DataType.I32_Default, DataType.I32_Default, DataType.I32_Default, DataType.I32_Default) \ + .dtype_format(DataType.I32_NCHW, DataType.I32_NCHW, DataType.I32_NCHW, DataType.I32_NCHW) \ + .get_op_info() + +@op_info_register(uniform_int_op_info) +def _uniform_int_aicpu(): + """RandomUniformInt AiCPU register""" + return diff --git a/mindspore/ops/_op_impl/aicpu/uniform_real.py b/mindspore/ops/_op_impl/aicpu/uniform_real.py new file mode 100644 index 0000000000..51824fbb2c --- /dev/null +++ b/mindspore/ops/_op_impl/aicpu/uniform_real.py @@ -0,0 +1,33 @@ +# 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. +# ============================================================================ + +"""RandomUniformReal op""" +from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType + +uniform_real_op_info = AiCPURegOp("UniformReal") \ + .fusion_type("OPAQUE") \ + .input(0, "shape", "required") \ + .input(1, "a", "required") \ + .input(2, "b", "required") \ + .output(0, "output", "required") \ + .attr("seed", "int") \ + .dtype_format(DataType.I32_Default, DataType.F32_Default, DataType.F32_Default, DataType.F32_Default) \ + .dtype_format(DataType.I32_NCHW, DataType.F32_NCHW, DataType.F32_NCHW, DataType.F32_NCHW) \ + .get_op_info() + +@op_info_register(uniform_real_op_info) +def _uniform_real_aicpu(): + """RandomUniformReal AiCPU register""" + return diff --git a/mindspore/ops/_op_impl/tbe/__init__.py b/mindspore/ops/_op_impl/tbe/__init__.py index 55c6e595be..578d312572 100644 --- a/mindspore/ops/_op_impl/tbe/__init__.py +++ b/mindspore/ops/_op_impl/tbe/__init__.py @@ -288,5 +288,6 @@ from .scatter_div import _scatter_div_tbe from .mod import _mod_tbe from .max_pool_grad_grad import _max_pool_grad_grad_tbe from .max_pool_grad_grad_with_argmax import _max_pool_grad_grad_with_argmax_tbe +from .tensor_move import _tensor_move_tbe from .population_count import _population_count_tbe from .parallel_concat import _parallel_concat_tbe diff --git a/mindspore/ops/_op_impl/tbe/avg_pool.py b/mindspore/ops/_op_impl/tbe/avg_pool.py index 5db5947b01..09fa83cf1b 100644 --- a/mindspore/ops/_op_impl/tbe/avg_pool.py +++ b/mindspore/ops/_op_impl/tbe/avg_pool.py @@ -28,8 +28,11 @@ avg_pool_op_info = TBERegOp("AvgPool") \ .attr("padding", "required", "str", "all") \ .attr("data_format", "optional", "str", "all") \ .input(0, "x", False, "required", "all") \ + .input(1, "filter", False, "optional", "all") \ + .input(2, "bias", False, "optional", "all") \ .output(0, "y", False, "required", "all") \ - .dtype_format(DataType.F16_5HD, DataType.F16_5HD) \ + .dtype_format(DataType.F16_5HD, DataType.F16_FracZ, DataType.F16_Default, DataType.F16_5HD) \ + .dtype_format(DataType.I8_5HD, DataType.I8_C1HWNCoC0, DataType.I32_Default, DataType.I32_5HD) \ .get_op_info() diff --git a/mindspore/ops/_op_impl/tbe/tensor_move.py b/mindspore/ops/_op_impl/tbe/tensor_move.py new file mode 100644 index 0000000000..536148927b --- /dev/null +++ b/mindspore/ops/_op_impl/tbe/tensor_move.py @@ -0,0 +1,41 @@ +# 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. +# ============================================================================ + +"""TensorMove op""" +from mindspore.ops.op_info_register import op_info_register, TBERegOp, DataType + +tensor_move_op_info = TBERegOp("TensorMove") \ + .fusion_type("OPAQUE") \ + .async_flag(False) \ + .binfile_name("tensor_move.so") \ + .compute_cost(10) \ + .kernel_name("tensor_move") \ + .partial_flag(True) \ + .input(0, "x", False, "required", "all") \ + .output(0, "y", False, "required", "all") \ + .op_pattern("formatAgnostic") \ + .dtype_format(DataType.I32_None, DataType.I32_None) \ + .dtype_format(DataType.F16_None, DataType.F16_None) \ + .dtype_format(DataType.F32_None, DataType.F32_None) \ + .dtype_format(DataType.I8_None, DataType.I8_None) \ + .dtype_format(DataType.U8_None, DataType.U8_None) \ + .dtype_format(DataType.BOOL_None, DataType.BOOL_None) \ + .get_op_info() + + +@op_info_register(tensor_move_op_info) +def _tensor_move_tbe(): + """TensorMove TBE register""" + return diff --git a/mindspore/ops/operations/__init__.py b/mindspore/ops/operations/__init__.py index 1e88128923..267593ab1a 100644 --- a/mindspore/ops/operations/__init__.py +++ b/mindspore/ops/operations/__init__.py @@ -27,8 +27,7 @@ from .array_ops import (Argmax, Argmin, Cast, Concat, Pack, Unpack, Rank, Reshape, ResizeNearestNeighbor, ArgMinWithValue, SameTypeShape, ScatterAdd, ScatterSub, ScatterMul, ScatterDiv, ScatterMax, ScatterMin, ScatterUpdate, ScalarToArray, ScalarToTensor, ScatterNd, ScatterNdUpdate, Select, - Shape, Size, Slice, Split, TransShape, - ParallelConcat, + Shape, Size, Slice, Split, TransShape, ParallelConcat, Squeeze, StridedSlice, Tile, TensorScatterUpdate, Transpose, TruncatedNormal, TupleToArray, UnsortedSegmentMin, UnsortedSegmentProd, UnsortedSegmentSum, SpaceToDepth, DepthToSpace, SpaceToBatch, BatchToSpace, @@ -55,7 +54,8 @@ from .math_ops import (Abs, ACos, Asin, Asinh, AddN, AccumulateNV2, AssignAdd, A Sin, Sqrt, Rsqrt, BesselI0e, BesselI1e, TruncateDiv, TruncateMod, Square, Sub, TensorAdd, Sign, Round, SquareSumAll, Atan, Atanh, Cosh, Sinh, Eps, Tan) -from .random_ops import (RandomChoiceWithMask, Normal, RandomCategorical) +from .random_ops import (RandomChoiceWithMask, Normal, Gamma, Poisson, UniformInt, UniformReal, + RandomCategorical, Laplace) from .nn_ops import (LSTM, SGD, Adam, SparseApplyAdam, SparseApplyLazyAdam, ApplyMomentum, BatchNorm, BiasAdd, Conv2D, DepthwiseConv2dNative, @@ -69,8 +69,7 @@ from .nn_ops import (LSTM, SGD, Adam, SparseApplyAdam, SparseApplyLazyAdam, Appl MaxPoolWithArgmax, OneHot, Pad, MirrorPad, PReLU, ReLU, ReLU6, ReLUV2, HSwish, HSigmoid, ResizeBilinear, Sigmoid, SigmoidCrossEntropyWithLogits, - SmoothL1Loss, Softmax, Softsign, Softplus, LRN, - RNNTLoss, + SmoothL1Loss, Softmax, Softsign, Softplus, LRN, RNNTLoss, SoftmaxCrossEntropyWithLogits, ROIAlign, SparseSoftmaxCrossEntropyWithLogits, Tanh, TopK, BinaryCrossEntropy, SparseApplyAdagrad, LARSUpdate, ApplyFtrl, SparseApplyFtrl, @@ -78,6 +77,8 @@ from .nn_ops import (LSTM, SGD, Adam, SparseApplyAdam, SparseApplyLazyAdam, Appl ApplyAdaMax, ApplyAdadelta, ApplyAdagrad, ApplyAdagradV2, ApplyAddSign, ApplyPowerSign, ApplyGradientDescent, ApplyProximalGradientDescent, ApplyRMSProp, ApplyCenteredRMSProp, BasicLSTMCell, InTopK) +from . import _quant_ops +from ._quant_ops import * from .other_ops import (Assign, IOU, BoundingBoxDecode, BoundingBoxEncode, PopulationCount, CheckValid, MakeRefKey, Partial, Depend, CheckBprop, Push, Pull) from .thor_ops import * @@ -135,6 +136,7 @@ __all__ = [ 'OneHot', 'GatherV2', 'SparseGatherV2', + 'EmbeddingLookup', 'Concat', 'Pack', 'Unpack', @@ -172,6 +174,11 @@ __all__ = [ 'Tanh', 'RandomChoiceWithMask', 'Normal', + 'Gamma', + 'Poisson', + 'UniformInt', + 'UniformReal', + 'Laplace', 'RandomCategorical', 'ResizeBilinear', 'ScalarSummary', @@ -320,6 +327,7 @@ __all__ = [ "ApplyCenteredRMSProp", "SpaceToBatchND", "BatchToSpaceND", + "ReverseSequence", "SquareSumAll", "BitwiseAnd", "BitwiseOr", @@ -335,6 +343,7 @@ __all__ = [ "ApproximateEqual", "InplaceUpdate", "InTopK", + "CropAndResize", "LRN", "Mod", "PopulationCount", diff --git a/mindspore/ops/operations/_grad_ops.py b/mindspore/ops/operations/_grad_ops.py index 8f9841b169..5e5e56f708 100644 --- a/mindspore/ops/operations/_grad_ops.py +++ b/mindspore/ops/operations/_grad_ops.py @@ -1204,6 +1204,54 @@ class StridedSliceGrad(PrimitiveWithInfer): 'value': None} +class StridedSliceGradAICPU(PrimitiveWithInfer): + """ + Performs grad of StridedSlice operation. + + Args: + begin_mask (int): Start indexing the slice. Default: 0. + end_mask (int): End indexing the slice. Default: 0. + ellipsis_mask (int): An int32 mask. Default: 0. + new_axis_mask (int): An int32 mask. Default: 0. + shrink_axis_mask (int): An int32 mask. Default: 0. + + Returns: + Tensor, has the same shape of input. + """ + + @prim_attr_register + def __init__(self, + begin_mask=0, + end_mask=0, + ellipsis_mask=0, + new_axis_mask=0, + shrink_axis_mask=0): + """init StrideSliceGrad""" + validator.check_value_type('begin_mask', begin_mask, [int], self.name) + validator.check_value_type('end_mask', end_mask, [int], self.name) + validator.check_value_type('ellipsis_mask', ellipsis_mask, [int], self.name) + validator.check_value_type('new_axis_mask', new_axis_mask, [int], self.name) + validator.check_value_type('shrink_axis_mask', shrink_axis_mask, [int], self.name) + self.init_prim_io_names(inputs=['dy', 'shapex', 'begin', 'end', 'strides'], outputs=['output']) + + def __infer__(self, dy, shapex, begin, end, strides): + args = {"dy": dy['dtype']} + validator.check_tensor_type_same(args, mstype.number_type, self.name) + + for idx, item in enumerate(shapex['value']): + validator.check_value_type("shapex[%d]" % idx, item, [int], self.name) + for idx, item in enumerate(begin['value']): + validator.check_value_type("begin[%d]" % idx, item, [int], self.name) + for idx, item in enumerate(end['value']): + validator.check_value_type("end[%d]" % idx, item, [int], self.name) + for idx, item in enumerate(strides['value']): + validator.check_value_type("strides[%d]" % idx, item, [int], self.name) + + return {'shape': shapex['value'], + 'dtype': dy['dtype'], + 'value': None} + + class SoftplusGrad(PrimitiveWithInfer): """Computes gradient for the Log Softmax activation.""" @@ -1246,11 +1294,20 @@ class MirrorPadGrad(PrimitiveWithInfer): validator.check_string('mode', mode, ['REFLECT', 'SYMMETRIC'], self.name) self.mode = mode - def __infer__(self, dout, paddings, x): + def __infer__(self, dout, paddings): validator.check_subclass("dout", dout['dtype'], mstype.tensor, self.name) validator.check_subclass("paddings", paddings['dtype'], mstype.tensor, self.name) - validator.check_subclass("input_x", x['dtype'], mstype.tensor, self.name) - return {'shape': x['shape'], + validator.check("paddings rank", len(paddings['shape']), "expected", 2, Rel.EQ, self.name) + validator.check("paddings dim_1", paddings['shape'][1], "expected", 2, Rel.EQ, self.name) + + if paddings['value'] is None: + raise ValueError(f"For {self.name}, paddings must be const.") + paddings_value = paddings['value'].asnumpy() + y_shape = () + dout_shape = dout['shape'] + for i, val in enumerate(dout_shape): + y_shape += (val - paddings_value[i][0] - paddings_value[i][1],) + return {'shape': y_shape, 'dtype': dout['dtype'], 'value': None} diff --git a/mindspore/ops/operations/_inner_ops.py b/mindspore/ops/operations/_inner_ops.py index 014998b4be..7ae59a6467 100644 --- a/mindspore/ops/operations/_inner_ops.py +++ b/mindspore/ops/operations/_inner_ops.py @@ -24,6 +24,137 @@ from ..._c_expression import signature_dtype as sig_dtype from ..primitive import PrimitiveWithInfer, prim_attr_register +class StridedSliceAICPU(PrimitiveWithInfer): + r""" + + Extracts a strided slice of a tensor. + + Given an input tensor, this operation inserts a dimension of length 1 at the dimension. + This operation extracts a fragment of size (end-begin)/stride from the given + 'input_tensor'. Starting from the position specified by the begin, the fragment + continues adding stride to the index until all dimensions are not less than end. + + Note: + The stride may be negative value, which causes reverse slicing. + The shape of `begin`, `end` and `strides` should be the same. + + Args: + begin_mask (int): Starting index of the slice. Default: 0. + end_mask (int): Ending index of the slice. Default: 0. + ellipsis_mask (int): An int mask. Default: 0. + new_axis_mask (int): An int mask. Default: 0. + shrink_axis_mask (int): An int mask. Default: 0. + Currently all the masks are not in used. Use default 0 only. + + Inputs: + - **input_x** (Tensor) - The input Tensor. + - **begin** (tuple[int]) - A tuple which represents the location where to start. Only + constant value is allowed. + - **end** (tuple[int]) - A tuple or which represents the maximum location where to stop. + Only constant value is allowed. + - **strides** (tuple[int]) - A tuple which represents the stride continuously added + before reach the maximum location. Only constant value is allowed. + + Outputs: + Tensor. + Explain with the following example. + - In the 0th dim, begin is 1, end is 2, and strides is 1, + because :math:`1+1=2\geq2`, the interval is :math:`[1,2)`. + Thus, return the element with :math:`index = 1` in 0th dim, i.e., [[3, 3, 3], [4, 4, 4]]. + - In the 1st dim, similarly, the interval is :math:`[0,1)`. + Based on the return value of the 0th dim, return the element with :math:`index = 0`, + i.e., [3, 3, 3]. + - In the 2nd dim, similarly, the interval is :math:`[0,3)`. + Based on the return value of the 1st dim, return the element with :math:`index = 0,1,2`, + i.e., [3, 3, 3]. + - Finally, the output is [3, 3, 3]. + + Examples + >>> input_x = Tensor([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]], + >>> [[5, 5, 5], [6, 6, 6]]], mindspore.float32) + >>> slice = P.StridedSliceAICPU() + >>> output = slice(input_x, (1, 0, 0), (2, 1, 3), (1, 1, 2)) + >>> output.shape + (1, 1, 2) + >>> output + [[[3, 3]]] + """ + + @prim_attr_register + def __init__(self, + begin_mask=0, + end_mask=0, + ellipsis_mask=0, + new_axis_mask=0, + shrink_axis_mask=0): + """init StrideSlice""" + self.init_prim_io_names(inputs=['x', 'begin', 'end', 'strides'], outputs=['output']) + validator.check_value_type('begin_mask', begin_mask, [int], self.name) + validator.check_value_type('end_mask', end_mask, [int], self.name) + validator.check_value_type('ellipsis_mask', ellipsis_mask, [int], self.name) + validator.check_value_type('new_axis_mask', new_axis_mask, [int], self.name) + validator.check_value_type('shrink_axis_mask', shrink_axis_mask, [int], self.name) + + def __infer__(self, x, begin, end, strides): + begin_v, end_v, strides_v = begin['value'], end['value'], strides['value'] + validator.check_value_type("begin", begin_v, [tuple], self.name) + validator.check_value_type("end", end_v, [tuple], self.name) + validator.check_value_type("strides", strides_v, [tuple], self.name) + + x_shape = x['shape'] + x_shp_len = len(x_shape) + if len(begin_v) != x_shp_len or len(end_v) != x_shp_len or len(strides_v) != x_shp_len: + raise ValueError(f"For \'{self.name}\' the length of begin index{begin_v}, end index{end_v} and " + f"strides{strides_v} must be equal to the dims({x_shp_len}) of input.") + + ret_shape = [] + append_dimensions = [] + shrink_pos = bin(self.shrink_axis_mask)[::-1] + new_pos = bin(self.new_axis_mask)[::-1] + for i in range(x_shp_len): + # After the integer is converted to binary, it is a str and the first two chars are the flag char '0b' + if i < (len(new_pos) - 2) and new_pos[i] == '1': + ret_shape.append(1) + append_dimensions.append(x_shape[x_shp_len - 1 - len(append_dimensions)]) + continue + if i < (len(shrink_pos) - 2) and shrink_pos[i] == '1': + validator.check_integer(f'begin[{i}]', begin_v[i], -x_shape[i], Rel.GE, self.name) + validator.check_integer(f'begin[{i}]', begin_v[i], x_shape[i], Rel.LT, self.name) + continue + + begin_idx = begin_v[i] + end_idx = end_v[i] + strides_idx = strides_v[i] + if self.begin_mask: + begin_idx = 0 + if self.end_mask: + end_idx = x_shape[i] + validator.check_integer(f'begin[{i}]', begin_idx, x_shape[i], Rel.LE, self.name) + validator.check_integer(f'end[{i}]', end_idx, x_shape[i], Rel.LE, self.name) + validator.check_integer(f'strides[{i}]', strides_idx, 0, Rel.NE, self.name) + if strides_idx > 0: + # If sliced forward , end_idx >= begin_idx + validator.check(f'begin[{i}]', begin_idx, f'end[{i}]', end_idx, Rel.LE) + if begin_idx < 0 < end_idx: + # Turn negative begin_idx into positive values + begin_idx = x_shape[i] + begin_idx + num_elems = (end_idx - begin_idx + strides_idx - 1) // strides_idx + else: + # If sliced backwards, end_idx <= begin_idx + validator.check(f'begin[{i}]', begin_idx, f'end[{i}]', end_idx, Rel.GE) + if end_idx < 0 < begin_idx: + # Turn negative end_idx into positive values + end_idx = x_shape[i] + end_idx + num_elems = (end_idx - begin_idx + strides_idx + 1) // strides_idx + + ret_shape.append(num_elems) + if append_dimensions: + ret_shape += append_dimensions[::-1] + return {'shape': ret_shape, + 'dtype': x['dtype'], + 'value': None} + + class ExtractImagePatches(PrimitiveWithInfer): """ Extract patches from images. diff --git a/mindspore/ops/operations/nn_ops.py b/mindspore/ops/operations/nn_ops.py index e06695e1e5..e2f6888c88 100644 --- a/mindspore/ops/operations/nn_ops.py +++ b/mindspore/ops/operations/nn_ops.py @@ -780,7 +780,9 @@ class Conv2D(PrimitiveWithInfer): mode (int): 0 Math convolutiuon, 1 cross-correlation convolution , 2 deconvolution, 3 depthwise convolution. Default: 1. pad_mode (str): "valid", "same", "pad" the mode to fill padding. Default: "valid". - pad (int): The pad value to fill. Default: 0. + pad (Union(int, tuple[int])): The pad value to fill. Default: 0. If `pad` is one integer, the padding of + top, bottom, left and right is same, equal to pad. If `pad` is tuple with four integer, the padding + of top, bottom, left and right equal to pad[0], pad[1], pad[2], pad[3] with corresponding. stride (Union(int, tuple[int])): The stride to apply conv filter. Default: 1. dilation (Union(int, tuple[int])): Specify the space to use between kernel elements. Default: 1. group (int): Split input into groups. Default: 1. @@ -820,11 +822,19 @@ class Conv2D(PrimitiveWithInfer): self.add_prim_attr('stride', self.stride) self.dilation = _check_positive_int_or_tuple('dilation', dilation, self.name, allow_four=True, ret_four=True) self.add_prim_attr('dilation', self.dilation) - validator.check_value_type('pad', pad, (int,), self.name) + validator.check_value_type('pad', pad, (int, tuple), self.name) + if isinstance(pad, int): + pad = (pad,) * 4 + else: + validator.check_integer('pad size', len(pad), 4, Rel.EQ, self.name) + self.padding = pad self.pad_mode = validator.check_string('pad_mode', pad_mode, ['valid', 'same', 'pad'], self.name) - self.pad = validator.check_pad_value_by_mode(pad_mode, pad, self.name) + + if pad_mode != 'pad' and pad != (0, 0, 0, 0): + raise ValueError(f"For '{self.name}', padding must be zero when pad_mode is '{pad_mode}'.") if self.pad_mode == 'pad': - validator.check_integer('pad', self.pad, 0, Rel.GE, self.name) + for item in pad: + validator.check_integer('pad item', item, 0, Rel.GE, self.name) self.mode = validator.check_integer('mode', mode, 1, Rel.EQ, self.name) self.add_prim_attr('data_format', "NCHW") @@ -862,11 +872,11 @@ class Conv2D(PrimitiveWithInfer): pad_left = math.floor(pad_needed_w / 2) pad_right = pad_needed_w - pad_left elif self.pad_mode == 'pad': - pad_top, pad_bottom, pad_left, pad_right = self.pad, self.pad, self.pad, self.pad + pad_top, pad_bottom, pad_left, pad_right = self.padding - h_out = 1 + (x_shape[2] + 2 * self.pad - kernel_size_h - (kernel_size_h - 1) * (dilation_h - 1)) \ + h_out = 1 + (x_shape[2] + pad_top + pad_bottom - kernel_size_h - (kernel_size_h - 1) * (dilation_h - 1)) \ / stride_h - w_out = 1 + (x_shape[3] + 2 * self.pad - kernel_size_w - (kernel_size_w - 1) * (dilation_w - 1)) \ + w_out = 1 + (x_shape[3] + pad_left + pad_right - kernel_size_w - (kernel_size_w - 1) * (dilation_w - 1)) \ / stride_w h_out = math.floor(h_out) w_out = math.floor(w_out) @@ -1279,7 +1289,9 @@ class Conv2DBackpropInput(PrimitiveWithInfer): out_channel (int): The dimensionality of the output space. kernel_size (Union[int, tuple[int]]): The size of the convolution window. pad_mode (str): "valid", "same", "pad" the mode to fill padding. Default: "valid". - pad (int): The pad value to fill. Default: 0. + pad (Union[int, tuple[int]]): The pad value to fill. Default: 0. If `pad` is one integer, the padding of + top, bottom, left and right is same, equal to pad. If `pad` is tuple with four integer, the padding + of top, bottom, left and right equal to pad[0], pad[1], pad[2], pad[3] with corresponding. mode (int): 0 Math convolutiuon, 1 cross-correlation convolution , 2 deconvolution, 3 depthwise convolution. Default: 1. stride (Union[int. tuple[int]]): The stride to apply conv filter. Default: 1. @@ -1316,9 +1328,21 @@ class Conv2DBackpropInput(PrimitiveWithInfer): self.add_prim_attr('stride', self.stride) self.dilation = _check_positive_int_or_tuple('dilation', dilation, self.name, allow_four=True, ret_four=True) self.add_prim_attr('dilation', self.dilation) - validator.check_value_type('pad', pad, (int,), self.name) + + validator.check_value_type('pad', pad, (int, tuple), self.name) + if isinstance(pad, int): + pad = (pad,) * 4 + self.padding = pad + else: + validator.check_integer('pad size', len(pad), 4, Rel.EQ, self.name) + self.pad_mode = validator.check_string('pad_mode', pad_mode, ['valid', 'same', 'pad'], self.name) - self.pad = validator.check_pad_value_by_mode(pad_mode, pad, self.name) + if pad_mode != 'pad' and pad != (0, 0, 0, 0): + raise ValueError(f"For '{self.name}', padding must be zero when pad_mode is '{pad_mode}'.") + if self.pad_mode == 'pad': + for item in pad: + validator.check_integer('pad item', item, 0, Rel.GE, self.name) + pad_mode = pad_mode.upper() self.add_prim_attr('pad_mode', pad_mode) self.mode = validator.check_integer('mode', mode, 1, Rel.EQ, self.name) @@ -1360,7 +1384,7 @@ class Conv2DBackpropInput(PrimitiveWithInfer): pad_right = pad_needed_w - pad_left pad_list = (pad_top, pad_bottom, pad_left, pad_right) elif self.pad_mode == 'PAD': - pad_list = (self.pad,) * 4 + pad_list = self.padding self.add_prim_attr('pad_list', pad_list) out = { 'value': None, @@ -1735,7 +1759,6 @@ class DataFormatDimMap(PrimitiveWithInfer): validator.check_tensor_type_same({"x": x_type}, valid_types, self.name) return x_type - class RNNTLoss(PrimitiveWithInfer): """ Computes the RNNTLoss and its gradient with respect to the softmax outputs. diff --git a/mindspore/ops/operations/random_ops.py b/mindspore/ops/operations/random_ops.py index 9ebe127228..6ce58ebd1a 100644 --- a/mindspore/ops/operations/random_ops.py +++ b/mindspore/ops/operations/random_ops.py @@ -19,6 +19,277 @@ from ..._checkparam import Validator as validator from ..._checkparam import Rel from ...common import dtype as mstype from ..primitive import PrimitiveWithInfer, prim_attr_register +from .._utils import get_broadcast_shape + + +class Laplace(PrimitiveWithInfer): + r""" + Generates random numbers according to the Laplace random number distribution. + It is defined as: + + .. math:: + \text{f}(x;μ,λ) = \frac{1}{2λ}\exp(-\frac{|x-μ|}{λ}), + + Args: + seed (int): Seed data is used as entropy source for Random number engines generating pseudo-random numbers. + Default: 0. + + Inputs: + - **shape** (tuple) - The shape of random tensor to be generated. Only constant value is allowed. + - **mean** (Tensor) - The mean μ distribution parameter, which specifies the location of the peak. + With float32 data type. + - **lambda_param** (Tensor) - The parameter used for controling the variance of this random distribution. The + variance of Laplace distribution is equal to twice the square of lambda_param. With float32 data type. + + Outputs: + Tensor, has the shape 'shape' input and dtype as float32. + + Examples: + >>> shape = (4, 16) + >>> mean = Tensor(1.0, mstype.float32) + >>> lambda_param = Tensor(1.0, mstype.float32) + >>> laplace = P.Laplace(seed=2) + >>> output = laplace(shape, mean, lambda_param) + """ + + @prim_attr_register + def __init__(self, seed=0): + """Init Laplace""" + self.init_prim_io_names(inputs=['shape', 'mean', 'lambda_param'], outputs=['output']) + validator.check_value_type('seed', seed, [int], self.name) + + def __infer__(self, shape, mean, lambda_param): + shape_v = shape["value"] + if shape_v is None: + raise ValueError(f"For {self.name}, shape must be const.") + validator.check_value_type("shape", shape_v, [tuple], self.name) + for i, shape_i in enumerate(shape_v): + validator.check_integer("shape[%d]" % i, shape_i, 0, Rel.GT, self.name) + validator.check_tensor_type_same({"mean": mean["dtype"]}, [mstype.float32], self.name) + validator.check_tensor_type_same({"lambda_param": lambda_param["dtype"]}, [mstype.float32], self.name) + broadcast_shape = get_broadcast_shape(mean['shape'], lambda_param['shape'], self.name) + broadcast_shape = get_broadcast_shape(broadcast_shape, shape_v, self.name) + out = { + 'shape': broadcast_shape, + 'dtype': mstype.float32, + 'value': None} + return out + + +class Gamma(PrimitiveWithInfer): + r""" + Produces random positive floating-point values x, distributed according to probability density function: + + .. math:: + \text{P}(x|α,β) = \frac{\exp(-x/β)}{{β^α}\cdot{\Gamma(α)}}\cdot{x^{α-1}}, + + Args: + seed (int): Seed data is used as entropy source for Random number engines generating pseudo-random numbers. + Default: 0. + + Inputs: + - **shape** (tuple) - The shape of random tensor to be generated. Only constant value is allowed. + - **alpha** (Tensor) - The α distribution parameter. + It is also known as the shape parameter. With float32 data type. + - **beta** (Tensor) - The β distribution parameter. + It is also known as the scale parameter. With float32 data type. + + Outputs: + Tensor. The shape should be the broadcasted shape of Input "shape" and shapes of alpha and beta. + The dtype is float32. + + Examples: + >>> shape = (4, 16) + >>> alpha = Tensor(1.0, mstype.float32) + >>> beta = Tensor(1.0, mstype.float32) + >>> gamma = P.Gamma(seed=3) + >>> output = Gamma(shape, alpha, beta) + """ + + @prim_attr_register + def __init__(self, seed=0): + """Init Gamma""" + self.init_prim_io_names(inputs=['shape', 'alpha', 'beta'], outputs=['output']) + validator.check_value_type('seed', seed, [int], self.name) + + def __infer__(self, shape, alpha, beta): + shape_v = shape["value"] + if shape_v is None: + raise ValueError(f"For {self.name}, shape must be const.") + validator.check_value_type("shape", shape_v, [tuple], self.name) + for i, shape_i in enumerate(shape_v): + validator.check_integer("shape[%d]" % i, shape_i, 0, Rel.GT, self.name) + validator.check_tensor_type_same({"alpha": alpha["dtype"]}, [mstype.float32], self.name) + validator.check_tensor_type_same({"beta": beta["dtype"]}, [mstype.float32], self.name) + broadcast_shape = get_broadcast_shape(alpha['shape'], beta['shape'], self.name) + broadcast_shape = get_broadcast_shape(broadcast_shape, shape_v, self.name) + out = { + 'shape': broadcast_shape, + 'dtype': mstype.float32, + 'value': None} + return out + + +class Poisson(PrimitiveWithInfer): + r""" + Produces random non-negative integer values i, distributed according to discrete probability function: + + .. math:: + \text{P}(i|μ) = \frac{\exp(-μ)μ^{i}}{i!}, + + Args: + seed (int): Seed data is used as entropy source for Random number engines generating pseudo-random numbers. + Default: 0. + + Inputs: + - **shape** (tuple) - The shape of random tensor to be generated. Only constant value is allowed. + - **mean** (Tensor) - μ parameter the distribution was constructed with. + The parameter defines mean number of occurrences of the event. With float32 data type. + + Outputs: + Tensor. The shape should be the broadcasted shape of Input "shape" and shape of mean. + The dtype is int32. + + Examples: + >>> shape = (4, 16) + >>> mean = Tensor(5.0, mstype.float32) + >>> poisson = P.Poisson(seed=5) + >>> output = poisson(shape, mean) + """ + + @prim_attr_register + def __init__(self, seed=0): + """Init Poisson""" + self.init_prim_io_names(inputs=['shape', 'mean'], outputs=['output']) + validator.check_value_type('seed', seed, [int], self.name) + + def __infer__(self, shape, mean): + shape_v = shape["value"] + if shape_v is None: + raise ValueError(f"For {self.name}, shape must be const.") + validator.check_value_type("shape", shape_v, [tuple], self.name) + for i, shape_i in enumerate(shape_v): + validator.check_integer("shape[%d]" % i, shape_i, 0, Rel.GT, self.name) + validator.check_tensor_type_same({"mean": mean["dtype"]}, [mstype.float32], self.name) + broadcast_shape = get_broadcast_shape(mean['shape'], shape_v, self.name) + out = { + 'shape': broadcast_shape, + 'dtype': mstype.int32, + 'value': None} + return out + + +class UniformInt(PrimitiveWithInfer): + r""" + Produces random integer values i, uniformly distributed on the closed interval [a, b], that is, + distributed according to the discrete probability function: + + .. math:: + \text{P}(i|a,b) = \frac{1}{b-a+1}, + + Note: + The number in tensor a should be strictly less than b at any position after broadcasting. + + Args: + seed (int): Seed data is used as entropy source for Random number engines generating pseudo-random numbers. + Default: 0. + + Inputs: + - **shape** (tuple) - The shape of random tensor to be generated. Only constant value is allowed. + - **a** (Tensor) - The a distribution parameter. + It defines the minimum possibly generated value. With int32 data type. + - **b** (Tensor) - The b distribution parameter. + It defines the maximum possibly generated value. With int32 data type. + + Outputs: + Tensor. The shape should be the broadcasted shape of Input "shape" and shapes of a and b. + The dtype is int32. + + Examples: + >>> shape = (4, 16) + >>> a = Tensor(1, mstype.int32) + >>> b = Tensor(5, mstype.int32) + >>> uniform_int = P.UniformInt(seed=10) + >>> output = uniform_int(shape, a, b) + """ + + @prim_attr_register + def __init__(self, seed=0): + """Init UniformInt""" + self.init_prim_io_names(inputs=['shape', 'a', 'b'], outputs=['output']) + validator.check_value_type('seed', seed, [int], self.name) + + def __infer__(self, shape, a, b): + shape_v = shape["value"] + if shape_v is None: + raise ValueError(f"For {self.name}, shape must be const.") + validator.check_value_type("shape", shape_v, [tuple], self.name) + for i, shape_i in enumerate(shape_v): + validator.check_integer("shape[%d]" % i, shape_i, 0, Rel.GT, self.name) + validator.check_tensor_type_same({"a": a["dtype"]}, [mstype.int32], self.name) + validator.check_tensor_type_same({"b": b["dtype"]}, [mstype.int32], self.name) + broadcast_shape = get_broadcast_shape(a['shape'], b['shape'], self.name) + broadcast_shape = get_broadcast_shape(broadcast_shape, shape_v, self.name) + out = { + 'shape': broadcast_shape, + 'dtype': mstype.int32, + 'value': None} + return out + + +class UniformReal(PrimitiveWithInfer): + r""" + Produces random floating-point values i, uniformly distributed on the interval [min(a, b), max(a, b)), that is,\ + distributed according to the probability density function: + + .. math:: + \text{P}(i|a,b) = \frac{1}{b-a}, + + Args: + seed (int): Seed data is used as entropy source for Random number engines generating pseudo-random numbers. + Default: 0. + + Inputs: + - **shape** (tuple) - The shape of random tensor to be generated. Only constant value is allowed. + - **a** (Tensor) - The a distribution parameter. + It defines the minimum possibly generated value. With float32 data type. + - **b** (Tensor) - The b distribution parameter. + It defines the maximum possibly generated value. With float32 data type. + + Outputs: + Tensor. The shape should be the broadcasted shape of Input "shape" and shapes of a and b. + The dtype is float32. + + Examples: + >>> shape = (4, 16) + >>> a = Tensor(1.0, mstype.float32) + >>> b = Tensor(5.0, mstype.float32) + >>> uniform_real = P.UniformReal(seed=10) + >>> output = uniform_real(shape, a, b) + """ + + @prim_attr_register + def __init__(self, seed=0): + """Init UniformReal""" + self.init_prim_io_names(inputs=['shape', 'a', 'b'], outputs=['output']) + validator.check_value_type('seed', seed, [int], self.name) + + def __infer__(self, shape, a, b): + shape_v = shape["value"] + if shape_v is None: + raise ValueError(f"For {self.name}, shape must be const.") + validator.check_value_type("shape", shape_v, [tuple], self.name) + for i, shape_i in enumerate(shape_v): + validator.check_integer("shape[%d]" % i, shape_i, 0, Rel.GT, self.name) + validator.check_tensor_type_same({"a": a["dtype"]}, [mstype.float32], self.name) + validator.check_tensor_type_same({"b": b["dtype"]}, [mstype.float32], self.name) + broadcast_shape = get_broadcast_shape(a['shape'], b['shape'], self.name) + broadcast_shape = get_broadcast_shape(broadcast_shape, shape_v, self.name) + out = { + 'shape': broadcast_shape, + 'dtype': mstype.float32, + 'value': None} + return out class RandomChoiceWithMask(PrimitiveWithInfer): @@ -66,50 +337,6 @@ class RandomChoiceWithMask(PrimitiveWithInfer): return (mstype.int32, mstype.bool_) -class Normal(PrimitiveWithInfer): - """ - Generates random samples from a normal(Gaussian) distribution. - - Args: - seed (int): Random seed. Default: 0. - - Inputs: - - **shape** (tuple[int]) - The shape of output tensor. Only constant value is allowed. - - **mean** (Tensor) - The mean of the distribution, with float32 data type. - - **stddev** (Tensor) - The standard deviation of the distribution, with float32 data type. - - Outputs: - Tensor, with the given shape from the specific distribution and float32 data type. - - Examples: - >>> normal = P.Normal() - >>> mean = Tensor(0., mstype.float32) - >>> stddev = Tensor(1., mstype.float32) - >>> out = normal((32, 3, 3), mean, stddev) - """ - - @prim_attr_register - def __init__(self, seed=0): - """Init Normal""" - validator.check_value_type("seed", seed, [int], self.name) - - def __infer__(self, shape, mean, stddev): - shape_value = shape["value"] - if shape_value is None: - raise ValueError(f"For {self.name}, shape must be const.") - validator.check_value_type("shape", shape_value, [tuple], self.name) - for i, shape_i in enumerate(shape_value): - validator.check_integer("shape[%d]" % i, shape_i, 0, Rel.GE, self.name) - - validator.check_tensor_type_same({"mean": mean["dtype"]}, [mstype.float32], self.name) - validator.check_tensor_type_same({"stddev": stddev["dtype"]}, [mstype.float32], self.name) - - out = {"shape": shape_value, - "dtype": mstype.float32, - "value": None} - return out - - class RandomCategorical(PrimitiveWithInfer): """ Generates random samples from a given categorical distribution tensor. @@ -166,3 +393,46 @@ class RandomCategorical(PrimitiveWithInfer): return {'shape': (x_shape), 'dtype': (self.dtype), 'value': None} + +class Normal(PrimitiveWithInfer): + """ + Generates random samples from a normal(Gaussian) distribution. + + Args: + seed (int): Random seed. Default: 0. + + Inputs: + - **shape** (tuple[int]) - The shape of output tensor. Only constant value is allowed. + - **mean** (Tensor) - The mean of the distribution, with float32 data type. + - **stddev** (Tensor) - The standard deviation of the distribution, with float32 data type. + + Outputs: + Tensor, with the given shape from the specific distribution and float32 data type. + + Examples: + >>> normal = P.Normal() + >>> mean = Tensor(0., mstype.float32) + >>> stddev = Tensor(1., mstype.float32) + >>> out = normal((32, 3, 3), mean, stddev) + """ + + @prim_attr_register + def __init__(self, seed=0): + """Init Normal""" + validator.check_value_type("seed", seed, [int], self.name) + + def __infer__(self, shape, mean, stddev): + shape_value = shape["value"] + if shape_value is None: + raise ValueError(f"For {self.name}, shape must be const.") + validator.check_value_type("shape", shape_value, [tuple], self.name) + for i, shape_i in enumerate(shape_value): + validator.check_integer("shape[%d]" % i, shape_i, 0, Rel.GE, self.name) + + validator.check_tensor_type_same({"mean": mean["dtype"]}, [mstype.float32], self.name) + validator.check_tensor_type_same({"stddev": stddev["dtype"]}, [mstype.float32], self.name) + + out = {"shape": shape_value, + "dtype": mstype.float32, + "value": None} + return out diff --git a/tests/st/networks/models/bert/test_bert_graph_kernel.py b/tests/st/networks/models/bert/test_bert_graph_kernel.py index ec71cbaa4f..4c9673e076 100644 --- a/tests/st/networks/models/bert/test_bert_graph_kernel.py +++ b/tests/st/networks/models/bert/test_bert_graph_kernel.py @@ -126,10 +126,6 @@ class ModelCallback(Callback): print("epoch: {}, outputs are: {}".format(cb_params.cur_epoch_num, str(cb_params.net_outputs))) -@pytest.mark.level0 -@pytest.mark.platform_arm_ascend_training -@pytest.mark.platform_x86_ascend_training -@pytest.mark.env_onecard def test_bert_tdt(): """test bert tdt""" np.random.seed(0) diff --git a/tests/st/networks/models/bert/test_bert_tdt_lossscale.py b/tests/st/networks/models/bert/test_bert_tdt_lossscale.py index 29b4e7a542..d4c56edbc1 100644 --- a/tests/st/networks/models/bert/test_bert_tdt_lossscale.py +++ b/tests/st/networks/models/bert/test_bert_tdt_lossscale.py @@ -154,10 +154,6 @@ class TimeMonitor(Callback): self.epoch_mseconds_list.append(epoch_mseconds) self.per_step_mseconds_list.append(epoch_mseconds / self.data_size) -@pytest.mark.level0 -@pytest.mark.platform_arm_ascend_training -@pytest.mark.platform_x86_ascend_training -@pytest.mark.env_onecard def test_bert_percision(): """test bert percision""" context.set_context(mode=context.GRAPH_MODE, device_target="Ascend", reserve_class_name_in_scope=False) diff --git a/tests/st/ops/ascend/test_aicpu_ops/test_cast.py b/tests/st/ops/ascend/test_aicpu_ops/test_cast.py new file mode 100644 index 0000000000..8c2687796b --- /dev/null +++ b/tests/st/ops/ascend/test_aicpu_ops/test_cast.py @@ -0,0 +1,75 @@ +# 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. +# ============================================================================ +import numpy as np +import mindspore.common.dtype as mstype +import mindspore.context as context +import mindspore.nn as nn +from mindspore import Tensor +from mindspore.ops import operations as P + +context.set_context(mode=context.PYNATIVE_MODE, device_target="Ascend") + +class Net(nn.Cell): + def __init__(self, x, dtype): + super(Net, self).__init__() + self.cast = P.Cast() + self.x = x + self.dtype = dtype + + def construct(self): + return self.cast(self.x, self.dtype) + +def test_net_f32_bool(): + x = np.random.randn(3, 4).astype(np.float32) + x[:, 1] = 0 + net = Net(Tensor(x), mstype.bool_) + output = net() + print(output.asnumpy()) + print(Tensor(x).dtype) + print(output.dtype) + +def test_net_f16_bool(): + x = np.random.randn(3, 4).astype(np.float16) + x[:, 1] = 0 + net = Net(Tensor(x), mstype.bool_) + output = net() + print(output.asnumpy()) + print(Tensor(x).dtype) + print(output.dtype) + +def test_net_f64_bool(): + x = np.random.randn(3, 4).astype(np.float64) + x[:, 1] = 0 + net = Net(Tensor(x), mstype.bool_) + output = net() + print(output.asnumpy()) + print(Tensor(x).dtype) + print(output.dtype) + +def test_net_int16_float16(): + x = np.random.randint(-512, 512, size=(3, 4)).astype(np.int16) + net = Net(Tensor(x), mstype.float16) + output = net() + print(output.asnumpy()) + print(Tensor(x).dtype) + print(output.dtype) + +def test_net_int64_float16(): + x = np.random.randint(-512, 512, size=(3, 4)).astype(np.int64) + net = Net(Tensor(x), mstype.float16) + output = net() + print(output.asnumpy()) + print(Tensor(x).dtype) + print(output.dtype) diff --git a/tests/st/ops/ascend/test_aicpu_ops/test_gamma.py b/tests/st/ops/ascend/test_aicpu_ops/test_gamma.py new file mode 100644 index 0000000000..2e2c16abac --- /dev/null +++ b/tests/st/ops/ascend/test_aicpu_ops/test_gamma.py @@ -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. +# ============================================================================ +import numpy as np + +import mindspore.context as context +import mindspore.nn as nn +from mindspore import Tensor +from mindspore.ops import operations as P +from mindspore.common import dtype as mstype + +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + + +class Net(nn.Cell): + def __init__(self, shape, seed=0): + super(Net, self).__init__() + self.gamma = P.Gamma(seed=seed) + self.shape = shape + + def construct(self, alpha, beta): + return self.gamma(self.shape, alpha, beta) + + +def test_net_1D(): + seed = 10 + shape = (3, 2, 4) + alpha = 1.0 + beta = 1.0 + net = Net(shape, seed) + talpha, tbeta = Tensor(alpha, mstype.float32), Tensor(beta, mstype.float32) + output = net(talpha, tbeta) + print(output.asnumpy()) + assert output.shape == (3, 2, 4) + + +def test_net_ND(): + seed = 10 + shape = (3, 1, 2) + alpha = np.array([[[1], [2]], [[3], [4]], [[5], [6]]]).astype(np.float32) + beta = np.array([1.0]).astype(np.float32) + net = Net(shape, seed) + talpha, tbeta = Tensor(alpha), Tensor(beta) + output = net(talpha, tbeta) + print(output.asnumpy()) + assert output.shape == (3, 2, 2) diff --git a/tests/st/ops/ascend/test_aicpu_ops/test_laplace.py b/tests/st/ops/ascend/test_aicpu_ops/test_laplace.py new file mode 100644 index 0000000000..75e207c451 --- /dev/null +++ b/tests/st/ops/ascend/test_aicpu_ops/test_laplace.py @@ -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. +# ============================================================================ +import numpy as np + +import mindspore.context as context +import mindspore.nn as nn +from mindspore import Tensor +from mindspore.ops import operations as P +from mindspore.common import dtype as mstype + +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + + +class Net(nn.Cell): + def __init__(self, shape, seed=0): + super(Net, self).__init__() + self.laplace = P.Laplace(seed=seed) + self.shape = shape + + def construct(self, mean, lambda_param): + return self.laplace(self.shape, mean, lambda_param) + + +def test_net_1D(): + seed = 10 + shape = (3, 2, 4) + mean = 1.0 + lambda_param = 1.0 + net = Net(shape, seed) + tmean, tlambda_param = Tensor(mean, mstype.float32), Tensor(lambda_param, mstype.float32) + output = net(tmean, tlambda_param) + print(output.asnumpy()) + assert output.shape == (3, 2, 4) + + +def test_net_ND(): + seed = 10 + shape = (3, 1, 2) + mean = np.array([[[1], [2]], [[3], [4]], [[5], [6]]]).astype(np.float32) + lambda_param = np.array([1.0]).astype(np.float32) + net = Net(shape, seed) + tmean, tlambda_param = Tensor(mean), Tensor(lambda_param) + output = net(tmean, tlambda_param) + print(output.asnumpy()) + assert output.shape == (3, 2, 2) diff --git a/tests/st/ops/ascend/test_aicpu_ops/test_normal.py b/tests/st/ops/ascend/test_aicpu_ops/test_normal.py index 66254caf21..a92664f589 100644 --- a/tests/st/ops/ascend/test_aicpu_ops/test_normal.py +++ b/tests/st/ops/ascend/test_aicpu_ops/test_normal.py @@ -12,32 +12,48 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================ + +import numpy as np +import pytest + import mindspore.context as context import mindspore.nn as nn -from mindspore.ops import operations as P -from mindspore.common import Tensor +from mindspore import Tensor from mindspore.common import dtype as mstype +from mindspore.ops import composite as C - -context.set_context(mode=context.PYNATIVE_MODE, device_target="Ascend") +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") class Net(nn.Cell): - def __init__(self, shape=None, mean=0.0, stddev=1.0, seed=0): + def __init__(self, shape, seed=0): super(Net, self).__init__() - self._mean = Tensor(mean, mstype.float32) - self._stddev = Tensor(stddev, mstype.float32) - self._normal = P.Normal(seed=seed) - self._shape = shape + self.shape = shape + self.seed = seed - def construct(self): - return self._normal(self._shape, self._mean, self._stddev) + def construct(self, mean, stddev): + return C.normal(self.shape, mean, stddev, self.seed) -def test_net_3x2x4(): - mean = 0.0 +def test_net_1D(): + seed = 10 + shape = (3, 2, 4) + mean = 1.0 stddev = 1.0 - seed = 0 - net = Net((3, 2, 4), mean, stddev, seed) - out = net() - assert out.shape == (3, 2, 4) + net = Net(shape, seed) + tmean, tstddev = Tensor(mean, mstype.float32), Tensor(stddev, mstype.float32) + output = net(tmean, tstddev) + print(output.asnumpy()) + assert output.shape == (3, 2, 4) + + +def test_net_ND(): + seed = 10 + shape = (3, 1, 2) + mean = np.array([[[1], [2]], [[3], [4]], [[5], [6]]]).astype(np.float32) + stddev = np.array([1.0]).astype(np.float32) + net = Net(shape, seed) + tmean, tstddev = Tensor(mean, mstype.float32), Tensor(stddev, mstype.float32) + output = net(tmean, tstddev) + print(output.asnumpy()) + assert output.shape == (3, 2, 2) diff --git a/tests/st/ops/ascend/test_aicpu_ops/test_pack.py b/tests/st/ops/ascend/test_aicpu_ops/test_pack.py index 750b911437..48f3560051 100644 --- a/tests/st/ops/ascend/test_aicpu_ops/test_pack.py +++ b/tests/st/ops/ascend/test_aicpu_ops/test_pack.py @@ -127,7 +127,6 @@ def test_net_int64(): print(output.asnumpy()) assert np.array_equal(output.asnumpy(), np.stack([x, y], axis)) - def test_net_uint64(): x = np.random.randn(3, 5, 4).astype(np.uint64) y = np.random.randn(3, 5, 4).astype(np.uint64) diff --git a/tests/st/ops/ascend/test_aicpu_ops/test_poisson.py b/tests/st/ops/ascend/test_aicpu_ops/test_poisson.py new file mode 100644 index 0000000000..68cd728701 --- /dev/null +++ b/tests/st/ops/ascend/test_aicpu_ops/test_poisson.py @@ -0,0 +1,53 @@ +# 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. +# ============================================================================ +import numpy as np + +import mindspore.context as context +import mindspore.nn as nn +from mindspore import Tensor +from mindspore.ops import operations as P +from mindspore.common import dtype as mstype + +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + + +class Net(nn.Cell): + def __init__(self, shape): + super(Net, self).__init__() + self.poisson = P.Poisson() + self.shape = shape + + def construct(self, mean): + return self.poisson(self.shape, mean) + + +def test_net_1(): + shape = (2, 16) + mean = np.array([5.0]).astype(np.float32) + net = Net(shape) + tmean = Tensor(mean) + output = net(tmean) + print(output.asnumpy()) + assert output.shape == (2, 16) + + +def test_net_2(): + shape = (4, 1) + mean = np.array([5.0, 10.0]).astype(np.float32) + net = Net(shape) + tmean = Tensor(mean) + output = net(tmean) + print(output.asnumpy()) + assert output.shape == (4, 2) diff --git a/tests/st/ops/ascend/test_aicpu_ops/test_standard_normal.py b/tests/st/ops/ascend/test_aicpu_ops/test_standard_normal.py new file mode 100644 index 0000000000..5cc21fac80 --- /dev/null +++ b/tests/st/ops/ascend/test_aicpu_ops/test_standard_normal.py @@ -0,0 +1,47 @@ +# 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. +# ============================================================================ + +import numpy as np +import pytest + +import mindspore.context as context +import mindspore.nn as nn +from mindspore import Tensor +from mindspore.common import dtype as mstype +from mindspore.ops import operations as P + +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + + +class Net(nn.Cell): + def __init__(self, shape, seed=0, seed2=0): + super(Net, self).__init__() + self.shape = shape + self.seed = seed + self.seed2 = seed2 + self.stdnormal = P.StandardNormal(seed, seed2) + + def construct(self): + return self.stdnormal(self.shape, self.seed, self.seed2) + + +def test_net(): + seed = 10 + seed2 = 10 + shape = (3, 2, 4) + net = Net(shape, seed, seed2) + output = net() + print(output.asnumpy()) + assert output.shape == (3, 2, 4) diff --git a/tests/st/ops/ascend/test_aicpu_ops/test_strided_slice.py b/tests/st/ops/ascend/test_aicpu_ops/test_strided_slice.py new file mode 100644 index 0000000000..f3d30e059d --- /dev/null +++ b/tests/st/ops/ascend/test_aicpu_ops/test_strided_slice.py @@ -0,0 +1,51 @@ +# 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. +# ============================================================================ +import numpy as np + +import mindspore.context as context +import mindspore.nn as nn +from mindspore import Tensor +from mindspore.ops.operations import _inner_ops as inner + +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + + +class Net(nn.Cell): + def __init__(self, begin, end, strides): + super(Net, self).__init__() + self.strided_slice = inner.StridedSliceAICPU() + self.begin = begin + self.end = end + self.strides = strides + + def construct(self, input): + return self.strided_slice(input, self.begin, self.end, self.strides) + + +input_x = np.array([[[0, 1, 2], [3, 4, 5]], + [[6, 7, 8], [9, 10, 11]], + [[12, 13, 14], [15, 16, 17]] + ]).astype(np.float32) +begin = (1, 0, 0) +end = (2, 2, 3) +strides = (1, 1, 2) + + +def test_net(): + net = Net(begin, end, strides) + tinput = Tensor(input_x) + output = net(tinput) + print(output.asnumpy()) + assert np.all([[[6, 8], [9, 11]]] == output.asnumpy()) diff --git a/tests/st/ops/ascend/test_aicpu_ops/test_strided_slice_grad.py b/tests/st/ops/ascend/test_aicpu_ops/test_strided_slice_grad.py new file mode 100644 index 0000000000..54ba40d91d --- /dev/null +++ b/tests/st/ops/ascend/test_aicpu_ops/test_strided_slice_grad.py @@ -0,0 +1,53 @@ +# 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. +# ============================================================================ +import numpy as np + +import mindspore.context as context +import mindspore.nn as nn +from mindspore import Tensor +from mindspore.ops.operations import _grad_ops as G + +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + + +class Net(nn.Cell): + def __init__(self, shape_x, begin, end, strides): + super(Net, self).__init__() + self.strided_slice_grad = G.StridedSliceGradAICPU() + self.shape_x = shape_x + self.begin = begin + self.end = end + self.strides = strides + + def construct(self, dy): + return self.strided_slice_grad(dy, self.shape_x, self.begin, self.end, self.strides) + + +dy = np.array([[[6, 8], [9, 11]]]).astype(np.float32) +shape_x = (3, 2, 3) +begin = (1, 0, 0) +end = (2, 2, 3) +strides = (1, 1, 2) + + +def test_net(): + net = Net(shape_x, begin, end, strides) + tdy = Tensor(dy) + output = net(tdy) + print(output.asnumpy()) + assert np.all([[[0, 0, 0], [0, 0, 0]], + [[6, 0, 8], [9, 0, 11]], + [[0, 0, 0], [0, 0, 0]] + ] == output.asnumpy()) diff --git a/tests/st/ops/ascend/test_aicpu_ops/test_uniform_int.py b/tests/st/ops/ascend/test_aicpu_ops/test_uniform_int.py new file mode 100644 index 0000000000..16b5359235 --- /dev/null +++ b/tests/st/ops/ascend/test_aicpu_ops/test_uniform_int.py @@ -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. +# ============================================================================ +import numpy as np + +import mindspore.context as context +import mindspore.nn as nn +from mindspore import Tensor +from mindspore.ops import operations as P +from mindspore.common import dtype as mstype + +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + + +class Net(nn.Cell): + def __init__(self, shape, seed=0): + super(Net, self).__init__() + self.uniformint = P.UniformInt(seed=seed) + self.shape = shape + + def construct(self, a, b): + return self.uniformint(self.shape, a, b) + + +def test_net_1D(): + seed = 10 + shape = (3, 2, 4) + a = 1 + b = 5 + net = Net(shape, seed) + ta, tb = Tensor(a, mstype.int32), Tensor(b, mstype.int32) + output = net(ta, tb) + print(output.asnumpy()) + assert output.shape == (3, 2, 4) + + +def test_net_ND(): + seed = 10 + shape = (3, 2, 1) + a = np.array([[[1, 2]], [[3, 4]], [[5, 6]]]).astype(np.int32) + b = np.array([10]).astype(np.int32) + net = Net(shape, seed) + ta, tb = Tensor(a), Tensor(b) + output = net(ta, tb) + print(output.asnumpy()) + assert output.shape == (3, 2, 2) diff --git a/tests/st/ops/ascend/test_aicpu_ops/test_uniform_real.py b/tests/st/ops/ascend/test_aicpu_ops/test_uniform_real.py new file mode 100644 index 0000000000..57c4325d59 --- /dev/null +++ b/tests/st/ops/ascend/test_aicpu_ops/test_uniform_real.py @@ -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. +# ============================================================================ +import numpy as np + +import mindspore.context as context +import mindspore.nn as nn +from mindspore import Tensor +from mindspore.ops import operations as P +from mindspore.common import dtype as mstype + +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + + +class Net(nn.Cell): + def __init__(self, shape, seed=0): + super(Net, self).__init__() + self.uniformreal = P.UniformReal(seed=seed) + self.shape = shape + + def construct(self, a, b): + return self.uniformreal(self.shape, a, b) + + +def test_net_1D(): + seed = 10 + shape = (3, 2, 4) + a = 1.0 + b = 5.0 + net = Net(shape, seed) + ta, tb = Tensor(a, mstype.float32), Tensor(b, mstype.float32) + output = net(ta, tb) + print(output.asnumpy()) + assert output.shape == (3, 2, 4) + + +def test_net_ND(): + seed = 10 + shape = (3, 2, 1) + a = np.array([[[1, 2]], [[3, 4]], [[5, 6]]]).astype(np.float32) + b = np.array([10]).astype(np.float32) + net = Net(shape, seed) + ta, tb = Tensor(a), Tensor(b) + output = net(ta, tb) + print(output.asnumpy()) + assert output.shape == (3, 2, 2) diff --git a/tests/st/ops/ascend/test_embedding_lookup.py b/tests/st/ops/ascend/test_embedding_lookup.py new file mode 100644 index 0000000000..6aee25d9da --- /dev/null +++ b/tests/st/ops/ascend/test_embedding_lookup.py @@ -0,0 +1,43 @@ +# 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. +# ============================================================================ +import numpy as np + +import mindspore.context as context +import mindspore.nn as nn +import mindspore.common.dtype as mstype +from mindspore import Tensor +from mindspore.ops import operations as P + +context.set_context(mode=context.GRAPH_MODE, + device_target="Ascend") + + +class Net(nn.Cell): + def __init__(self, offset): + super(Net, self).__init__() + self.embedding = P.EmbeddingLookup() + self.offset = offset + + def construct(self, param, index): + return self.embedding(param, index, self.offset) + + +def test_embedding_lookup_sparse(): + params = Tensor(np.array([[8, 9], [10, 11], [12, 13], [14, 15]]), mstype.int32) + indices = Tensor(np.array([[5, 2], [8, 5]]), mstype.int32) + offset = 4 + embedding = Net(offset) + out = embedding(params, indices) + assert(out.asnumpy() == [[[10, 11], [0, 0]], [[0, 0], [10, 11]]]).all() diff --git a/tests/ut/cpp/pre_activate/ascend/ir_fission/tensor_scatter_update_fission_test.cc b/tests/ut/cpp/pre_activate/ascend/ir_fission/tensor_scatter_update_fission_test.cc new file mode 100644 index 0000000000..1c928b581d --- /dev/null +++ b/tests/ut/cpp/pre_activate/ascend/ir_fission/tensor_scatter_update_fission_test.cc @@ -0,0 +1,56 @@ +/** + * 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 "common/backend_common_test.h" +#include "common/py_func_graph_fetcher.h" +#include "backend/optimizer/ascend/ir_fission/tensor_scatter_update_fission.h" +#include "debug/anf_ir_dump.h" + +namespace mindspore { +namespace opt { +class TestHWOptTensorScatterUpdateFission : public BackendCommon { + public: + TestHWOptTensorScatterUpdateFission() + : get_py_fun_("gtest_input.pre_activate.tensor_scatter_update_fission_test", true) {} + ~TestHWOptTensorScatterUpdateFission() override = default; + + UT::PyFuncGraphFetcher get_py_fun_; +}; + +TEST_F(TestHWOptTensorScatterUpdateFission, test_fission) { + FuncGraphPtr g = get_py_fun_.CallAndParseRet("test_tensor_scatter_update_fission", "before"); + EXPECT_NE(g, nullptr); + std::vector shp1{2, 3}; + std::vector shp2{2, 2}; + std::vector shp3{2}; + auto inputx = std::make_shared(kFloat32, shp1); + auto indices = std::make_shared(kInt32, shp2); + auto update = std::make_shared(kFloat32, shp3); + AbstractBasePtrList args_spec_list{inputx, indices, update}; + auto fg = GetKernelGraph(g, args_spec_list); + + auto optimizer = std::make_shared(); + auto pm = std::make_shared(); + pm->AddPass(std::make_shared()); + optimizer->AddPassManager(pm); + FuncGraphPtr new_graph = optimizer->Optimize(fg); + + FuncGraphPtr g_after = get_py_fun_.CallAndParseRet("test_tensor_scatter_update_fission", "after"); + EXPECT_NE(g_after, nullptr); + EXPECT_TRUE(CheckEqualGraph(g_after, new_graph)); +} +} // namespace opt +} // namespace mindspore diff --git a/tests/ut/cpp/python_input/gtest_input/pre_activate/tensor_scatter_update_fission_test.py b/tests/ut/cpp/python_input/gtest_input/pre_activate/tensor_scatter_update_fission_test.py new file mode 100644 index 0000000000..4a84f34607 --- /dev/null +++ b/tests/ut/cpp/python_input/gtest_input/pre_activate/tensor_scatter_update_fission_test.py @@ -0,0 +1,50 @@ +# 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. +# ============================================================================ +from mindspore.ops import Primitive +from mindspore.ops import operations as P + +tensor_scatter_update = P.TensorScatterUpdate() +tensor_move = Primitive('TensorMove') +scatter_nd_update = Primitive('ScatterNdUpdate') +make_tuple = Primitive('make_tuple') +tuple_getitem = Primitive('tuple_getitem') + + +class FnDict: + def __init__(self): + self.fnDict = {} + + def __call__(self, fn): + self.fnDict[fn.__name__] = fn + + def __getitem__(self, name): + return self.fnDict[name] + + +def test_tensor_scatter_update_fission(tag): + fns = FnDict() + + @fns + def before(x, indices, updates): + res = tensor_scatter_update(x, indices, updates) + return res + + @fns + def after(x, indices, updates): + res = tensor_move(x) + res = scatter_nd_update(res, indices, updates) + return make_tuple(res) + + return fns[tag] diff --git a/tests/ut/cpp/python_input/gtest_input/pynative/ops_test.py b/tests/ut/cpp/python_input/gtest_input/pynative/ops_test.py index be31b0f709..d27d6c5eca 100644 --- a/tests/ut/cpp/python_input/gtest_input/pynative/ops_test.py +++ b/tests/ut/cpp/python_input/gtest_input/pynative/ops_test.py @@ -22,11 +22,22 @@ from mindspore.ops.vm_impl_registry import vm_impl_registry as vm_impl_getters def im2col(img, filter_h, filter_w, stride=1, pad=0, dilation=1): """Rearranges an image to row vector""" + if isinstance(pad, int): + pad_top = pad + pad_bottom = pad + pad_left = pad + pad_right = pad + elif isinstance(pad, tuple) and len(pad) == 4: + pad_top, pad_bottom, pad_left, pad_right = pad + else: + raise ValueError(f"The \'pad\' should be an int number or " + f"a tuple of two or four int numbers, but got {pad}") + batch_num, channel, height, width = img.shape - out_h = (height + 2 * pad - filter_h - (filter_h - 1) * (dilation[2] - 1)) // stride[2] + 1 - out_w = (width + 2 * pad - filter_w - (filter_w - 1) * (dilation[3] - 1)) // stride[3] + 1 + out_h = (height + pad_top + pad_bottom - filter_h - (filter_h - 1) * (dilation[2] - 1)) // stride[2] + 1 + out_w = (width + pad_left + pad_right - filter_w - (filter_w - 1) * (dilation[3] - 1)) // stride[3] + 1 - img = np.pad(img, [(0, 0), (0, 0), (pad, pad), (pad, pad)], 'constant') + img = np.pad(img, [(0, 0), (0, 0), (pad_top, pad_bottom), (pad_left, pad_right)], 'constant') col = np.zeros((batch_num, channel, filter_h, filter_w, out_h, out_w)).astype(img.dtype) for y in range(filter_h): @@ -43,10 +54,21 @@ def im2col(img, filter_h, filter_w, stride=1, pad=0, dilation=1): def conv2d(x, weight, bias=None, stride=1, pad=0, dilation=1, groups=1, padding_mode='zeros'): """Convolution 2D""" + if isinstance(pad, int): + pad_top = pad + pad_bottom = pad + pad_left = pad + pad_right = pad + elif isinstance(pad, tuple) and len(pad) == 4: + pad_top, pad_bottom, pad_left, pad_right = pad + else: + raise ValueError(f"The \'pad\' should be an int number or " + f"a tuple of two or four int numbers, but got {pad}") + batch_num, _, x_h, x_w = x.shape filter_num, _, filter_h, filter_w = weight.shape - out_h = 1 + int((x_h + 2 * pad - filter_h - (filter_h - 1) * (dilation[2] - 1)) / stride[2]) - out_w = 1 + int((x_w + 2 * pad - filter_w - (filter_w - 1) * (dilation[3] - 1)) / stride[3]) + out_h = 1 + int((x_h + pad_top + pad_bottom - filter_h - (filter_h - 1) * (dilation[2] - 1)) / stride[2]) + out_w = 1 + int((x_w + pad_left + pad_right - filter_w - (filter_w - 1) * (dilation[3] - 1)) / stride[3]) col = im2col(x, filter_h, filter_w, stride, pad, dilation) col_w = np.reshape(weight, (filter_num, -1)).T out = np.dot(col, col_w) diff --git a/tests/ut/cpp/stub/hccl/hccl_stub.cc b/tests/ut/cpp/stub/hccl/hccl_stub.cc index e25ccc36c6..56f62910f2 100644 --- a/tests/ut/cpp/stub/hccl/hccl_stub.cc +++ b/tests/ut/cpp/stub/hccl/hccl_stub.cc @@ -103,7 +103,8 @@ hcclResult_t hcom_receive(const char *tag, void *outputPtr, u64 count, hcclDataT /* 获取梯度参数切分方案 */ hcclResult_t hcom_get_split_strategy(const char *group, const struct model_feature *feature, u32 maxSegmentNum, - u32 *segmentNum, u32 *segmentIdx, GradSplitForceMode force) { + u32 *segmentNum, u32 *segmentIdx, GradSplitForceMode force, + OriginalGraphShapeType shapeType) { return HCCL_SUCCESS; } diff --git a/tests/ut/python/ops/test_ops.py b/tests/ut/python/ops/test_ops.py index debc47185e..8972e4fd69 100755 --- a/tests/ut/python/ops/test_ops.py +++ b/tests/ut/python/ops/test_ops.py @@ -540,6 +540,61 @@ class NormalNet(nn.Cell): return out +class LaplaceNet(nn.Cell): + def __init__(self, shape=None, seed=0): + super(LaplaceNet, self).__init__() + self.laplace = P.Laplace(seed=seed) + self.shape = shape + + def construct(self, mean, lambda_param): + out = self.laplace(self.shape, mean, lambda_param) + return out + + +class GammaNet(nn.Cell): + def __init__(self, shape=None, seed=0): + super(GammaNet, self).__init__() + self.gamma = P.Gamma(seed=seed) + self.shape = shape + + def construct(self, alpha, beta): + out = self.gamma(self.shape, alpha, beta) + return out + + +class PoissonNet(nn.Cell): + def __init__(self, shape=None, seed=0): + super(PoissonNet, self).__init__() + self.poisson = P.Poisson(seed=seed) + self.shape = shape + + def construct(self, mean): + out = self.poisson(self.shape, mean) + return out + + +class UniformIntNet(nn.Cell): + def __init__(self, shape=None, seed=0): + super(UniformIntNet, self).__init__() + self.uniformint = P.UniformInt(seed=seed) + self.shape = shape + + def construct(self, a, b): + out = self.uniformint(self.shape, a, b) + return out + + +class UniformRealNet(nn.Cell): + def __init__(self, shape=None, seed=0): + super(UniformRealNet, self).__init__() + self.uniformreal = P.UniformReal(seed=seed) + self.shape = shape + + def construct(self, a, b): + out = self.uniformreal(self.shape, a, b) + return out + + class StridedSliceNet(nn.Cell): def __init__(self): super(StridedSliceNet, self).__init__() @@ -819,6 +874,26 @@ test_case_math_ops = [ 'block': NormalNet((3, 2, 4), 0), 'desc_inputs': [Tensor(0.0, mstype.float32), Tensor(1.0, mstype.float32)], 'skip': ['backward']}), + ('Laplace', { + 'block': LaplaceNet((3, 2, 4), 0), + 'desc_inputs': [Tensor(1.0, mstype.float32), Tensor(1.0, mstype.float32)], + 'skip': ['backward']}), + ('Gamma', { + 'block': GammaNet((3, 2, 4), 0), + 'desc_inputs': [Tensor(1.0, mstype.float32), Tensor(1.0, mstype.float32)], + 'skip': ['backward']}), + ('Poisson', { + 'block': PoissonNet((3, 2, 4), 0), + 'desc_inputs': [Tensor(2.0, mstype.float32)], + 'skip': ['backward']}), + ('UniformInt', { + 'block': UniformIntNet((3, 2, 4), 0), + 'desc_inputs': [Tensor(1, mstype.int32), Tensor(15, mstype.int32)], + 'skip': ['backward']}), + ('UniformReal', { + 'block': UniformRealNet((3, 2, 4), 0), + 'desc_inputs': [Tensor(1.0, mstype.float32), Tensor(5.0, mstype.float32)], + 'skip': ['backward']}), ('RandomChoiceWithMask', { 'block': P.RandomChoiceWithMask(256), 'desc_inputs': [Tensor(np.random.rand(24000, 4).astype(np.bool_))], diff --git a/tests/ut/python/optimizer/test_optimizer_with_parameter_groups.py b/tests/ut/python/optimizer/test_optimizer_with_parameter_groups.py index 0aef22284d..2f93eb6186 100644 --- a/tests/ut/python/optimizer/test_optimizer_with_parameter_groups.py +++ b/tests/ut/python/optimizer/test_optimizer_with_parameter_groups.py @@ -29,7 +29,6 @@ context.set_context(mode=context.GRAPH_MODE) class LeNet5(nn.Cell): """ LeNet5 definition """ - def __init__(self): super(LeNet5, self).__init__() self.conv1 = nn.Conv2d(1, 6, 5, pad_mode='valid') diff --git a/tests/vm_impl/vm_me.py b/tests/vm_impl/vm_me.py index ef173d493d..7216ec613b 100644 --- a/tests/vm_impl/vm_me.py +++ b/tests/vm_impl/vm_me.py @@ -169,16 +169,32 @@ def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0): raise ValueError(f"The \'stride\' should be an int number or " f"a tuple of two or four int numbers, but got {stride}") + if isinstance(pad, int): + pad_top = pad + pad_bottom = pad + pad_left = pad + pad_right = pad + elif isinstance(pad, tuple) and len(pad) == 2: + pad_top = pad[0] + pad_bottom = pad[0] + pad_left = pad[1] + pad_right = pad[1] + elif isinstance(pad, tuple) and len(pad) == 4: + pad_top, pad_bottom, pad_left, pad_right = pad + else: + raise ValueError(f"The \'pad\' should be an int number or " + f"a tuple of two or four int numbers, but got {pad}") + batch_num, channel, height, width = input_shape - out_h = (height + 2 * pad - filter_h) // stride_h + 1 - out_w = (width + 2 * pad - filter_w) // stride_w + 1 + out_h = (height + pad_top + pad_bottom - filter_h) // stride_h + 1 + out_w = (width + pad_left + pad_right - filter_w) // stride_w + 1 col = col.reshape(batch_num, out_h, out_w, channel, filter_h, filter_w) \ .transpose(0, 3, 4, 5, 1, 2) img = np.zeros((batch_num, channel, - height + 2 * pad + stride_h - 1, - width + 2 * pad + stride_w - 1)) \ + height + pad_top + pad_bottom + stride_h - 1, + width + pad_left + pad_right + stride_w - 1)) \ .astype(col.dtype) for y in range(filter_h): y_max = y + stride_h * out_h @@ -186,7 +202,7 @@ def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0): x_max = x + stride_h * out_w img[:, :, y:y_max:stride_h, x:x_max:stride_h] += col[:, :, y, x, :, :] - return img[:, :, pad:height + pad, pad:width + pad] + return img[:, :, pad_top:height + pad_bottom, pad_left:width + pad_right] def convolve(x, w, b=None, pad_mode="valid"): @@ -243,10 +259,21 @@ def conv2d(x, weight, bias=None, stride=1, pad=0, dilation_h = dilation[0] dilation_w = dilation[1] + if isinstance(pad, int): + pad_top = pad + pad_bottom = pad + pad_left = pad + pad_right = pad + elif isinstance(pad, tuple) and len(pad) == 4: + pad_top, pad_bottom, pad_left, pad_right = pad + else: + raise ValueError(f"The \'pad\' should be an int number or " + f"a tuple of two or four int numbers, but got {pad}") + batch_num, _, x_h, x_w = x.shape filter_num, _, filter_h, filter_w = weight.shape - out_h = 1 + int((x_h + 2 * pad - filter_h - (filter_h - 1) * (dilation_h - 1)) / stride_h) - out_w = 1 + int((x_w + 2 * pad - filter_w - (filter_w - 1) * (dilation_w - 1)) / stride_w) + out_h = 1 + int((x_h + pad_top + pad_bottom - filter_h - (filter_h - 1) * (dilation_h - 1)) / stride_h) + out_w = 1 + int((x_w + pad_left + pad_right - filter_w - (filter_w - 1) * (dilation_w - 1)) / stride_w) col = im2col(x, filter_h, filter_w, stride, pad, dilation) col_w = np.reshape(weight, (filter_num, -1)).T out = np.dot(col, col_w) @@ -348,11 +375,22 @@ def im2col(img, filter_h, filter_w, stride=1, pad=0, dilation=1): raise ValueError(f"The \'dilation\' should be an int number or " f"a tuple of two or four int numbers, but got {dilation}") + if isinstance(pad, int): + pad_top = pad + pad_bottom = pad + pad_left = pad + pad_right = pad + elif isinstance(pad, tuple) and len(pad) == 4: + pad_top, pad_bottom, pad_left, pad_right = pad + else: + raise ValueError(f"The \'pad\' should be an int number or " + f"a tuple of two or four int numbers, but got {pad}") + batch_num, channel, height, width = img.shape - out_h = (height + 2 * pad - filter_h - (filter_h - 1) * (dilation_h - 1)) // stride_h + 1 - out_w = (width + 2 * pad - filter_w - (filter_w - 1) * (dilation_w - 1)) // stride_w + 1 + out_h = (height + pad_top + pad_bottom - filter_h - (filter_h - 1) * (dilation_h - 1)) // stride_h + 1 + out_w = (width + pad_left + pad_right - filter_w - (filter_w - 1) * (dilation_w - 1)) // stride_w + 1 - img = np.pad(img, [(0, 0), (0, 0), (pad, pad), (pad, pad)], 'constant') + img = np.pad(img, [(0, 0), (0, 0), (pad_top, pad_bottom), (pad_left, pad_right)], 'constant') col = np.zeros((batch_num, channel, filter_h, filter_w, out_h, out_w)).astype(img.dtype) for y in range(filter_h):