1. Let 'isa<T>()' calls 'IsSameTypeId()' when T is final, and we add 'final' mark to some final classes derived from Base; 2. Generate type id at compile time using constexpr hash function, remove TypeIdManager and related code; 3. Add a tool script 'scripts/check_tid.sh' to check tid uniqueness; 4. Improve type search in 'proto_exporter.cc' and 'convert_utils_py.cc'; 5. Add some missed MS_DECLARE_PARENT; 6. Ensure calls of 'parent_t::IsFromTypeId()' are all inlined.tags/v1.6.0
| @@ -1,5 +1,5 @@ | |||
| /** | |||
| * Copyright 2020 Huawei Technologies Co., Ltd | |||
| * Copyright 2020-2021 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. | |||
| @@ -34,7 +34,7 @@ | |||
| namespace mindspore { | |||
| using TypeInfoToProtoTypeMap = std::vector<std::pair<const char *, debugger::DataType>>; | |||
| using TypeInfoToProtoTypeMap = std::vector<std::pair<uint32_t, debugger::DataType>>; | |||
| void SetOutputType(const TypePtr &node, const BaseShapePtr &shape, debugger::TypeProto *type_proto); | |||
| @@ -76,12 +76,12 @@ void SetListTypeProto(const TypePtr &type, debugger::TypeProto *type_proto) { | |||
| } | |||
| static TypeInfoToProtoTypeMap type_info_to_proto_type = { | |||
| {typeid(TensorType).name(), debugger::DT_TENSOR}, {typeid(Tuple).name(), debugger::DT_TUPLE}, | |||
| {typeid(TypeType).name(), debugger::DT_TYPE}, {typeid(List).name(), debugger::DT_LIST}, | |||
| {typeid(TypeAnything).name(), debugger::DT_ANYTHING}, {typeid(RefKeyType).name(), debugger::DT_REFKEY}, | |||
| {typeid(RefType).name(), debugger::DT_REF}, {typeid(Function).name(), debugger::DT_GRAPH}, | |||
| {typeid(TypeNone).name(), debugger::DT_NONE}, {typeid(String).name(), debugger::DT_STRING}, | |||
| {typeid(UMonadType).name(), debugger::DT_UMONAD}, {typeid(IOMonadType).name(), debugger::DT_IOMONAD}}; | |||
| {TensorType::kTypeId, debugger::DT_TENSOR}, {Tuple::kTypeId, debugger::DT_TUPLE}, | |||
| {TypeType::kTypeId, debugger::DT_TYPE}, {List::kTypeId, debugger::DT_LIST}, | |||
| {TypeAnything::kTypeId, debugger::DT_ANYTHING}, {RefKeyType::kTypeId, debugger::DT_REFKEY}, | |||
| {RefType::kTypeId, debugger::DT_REF}, {Function::kTypeId, debugger::DT_GRAPH}, | |||
| {TypeNone::kTypeId, debugger::DT_NONE}, {String::kTypeId, debugger::DT_STRING}, | |||
| {UMonadType::kTypeId, debugger::DT_UMONAD}, {IOMonadType::kTypeId, debugger::DT_IOMONAD}}; | |||
| void SetOutputType(const TypePtr &type, const BaseShapePtr &shape, debugger::TypeProto *type_proto) { | |||
| if (type_proto == nullptr) { | |||
| @@ -93,7 +93,7 @@ void SetOutputType(const TypePtr &type, const BaseShapePtr &shape, debugger::Typ | |||
| } | |||
| CheckIfValidType(type, type_proto); | |||
| for (auto &it : type_info_to_proto_type) { | |||
| if (type->IsFromTypeId(Base::GetTypeId(it.first))) { | |||
| if (type->IsFromTypeId(it.first)) { | |||
| type_proto->set_data_type(it.second); | |||
| break; | |||
| } | |||
| @@ -1,5 +1,5 @@ | |||
| /** | |||
| * Copyright 2020 Huawei Technologies Co., Ltd | |||
| * Copyright 2020-2021 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. | |||
| @@ -54,6 +54,7 @@ class Pattern : public Base { | |||
| public: | |||
| Pattern() : unique_name_(std::to_string(g_id_++)) {} | |||
| ~Pattern() = default; | |||
| MS_DECLARE_PARENT(Pattern, Base); | |||
| virtual MatchResultPtr match(const AnfNodePtr &node) { return nullptr; } | |||
| virtual bool operator==(const Pattern &other) const { return unique_name_ == other.unique_name_; } | |||
| string unique_name() const { return unique_name_; } | |||
| @@ -83,7 +84,7 @@ struct PatternHasher { | |||
| } | |||
| }; | |||
| class Prim : public Pattern { | |||
| class Prim final : public Pattern { | |||
| public: | |||
| Prim() { unique_name_ = std::to_string(g_id_++); } | |||
| ~Prim() = default; | |||
| @@ -118,7 +119,7 @@ class Prim : public Pattern { | |||
| PrimitivePyPtr matched_prim_{nullptr}; | |||
| }; | |||
| class Call : public Pattern { | |||
| class Call final : public Pattern { | |||
| public: | |||
| Call() { unique_name_ = std::to_string(g_id_++); } | |||
| ~Call() = default; | |||
| @@ -153,7 +154,7 @@ class Call : public Pattern { | |||
| string name_; | |||
| }; | |||
| class OneOf : public Pattern { | |||
| class OneOf final : public Pattern { | |||
| public: | |||
| OneOf() { unique_name_ = std::to_string(g_id_++); } | |||
| ~OneOf() = default; | |||
| @@ -170,7 +171,7 @@ class OneOf : public Pattern { | |||
| vector<PatternPtr> patterns_; | |||
| }; | |||
| class NoneOf : public Pattern { | |||
| class NoneOf final : public Pattern { | |||
| public: | |||
| NoneOf() { unique_name_ = std::to_string(g_id_++); } | |||
| ~NoneOf() = default; | |||
| @@ -187,7 +188,7 @@ class NoneOf : public Pattern { | |||
| vector<PatternPtr> patterns_; | |||
| }; | |||
| class Any : public Pattern { | |||
| class Any final : public Pattern { | |||
| public: | |||
| Any() { unique_name_ = std::to_string(g_id_++) + "_Any"; } | |||
| ~Any() = default; | |||
| @@ -195,7 +196,7 @@ class Any : public Pattern { | |||
| MatchResultPtr match(const AnfNodePtr &node) override; | |||
| }; | |||
| class NewTensor : public Pattern { | |||
| class NewTensor final : public Pattern { | |||
| public: | |||
| NewTensor() { unique_name_ = std::to_string(g_id_++); } | |||
| ~NewTensor() = default; | |||
| @@ -212,7 +213,7 @@ class NewTensor : public Pattern { | |||
| tensor::TensorPtr input_tensor_; | |||
| }; | |||
| class NewParameter : public Pattern { | |||
| class NewParameter final : public Pattern { | |||
| public: | |||
| NewParameter() { unique_name_ = std::to_string(g_id_++); } | |||
| explicit NewParameter(string para_name, tensor::TensorPtr default_tensor, bool requires_grad, bool layerwise_parallel) | |||
| @@ -245,7 +246,7 @@ class NewParameter : public Pattern { | |||
| tensor::TensorPtr default_tensor_; | |||
| }; | |||
| class Imm : public Pattern { | |||
| class Imm final : public Pattern { | |||
| public: | |||
| Imm() { unique_name_ = std::to_string(g_id_++); } | |||
| explicit Imm(int value) : value_(value) { unique_name_ = std::to_string(g_id_++) + "Imm_" + std::to_string(value); } | |||
| @@ -1,5 +1,5 @@ | |||
| /** | |||
| * Copyright 2019-2020 Huawei Technologies Co., Ltd | |||
| * Copyright 2019-2021 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. | |||
| @@ -37,7 +37,7 @@ using ResourceBasePtr = std::shared_ptr<ResourceBase>; | |||
| namespace mindspore { | |||
| namespace parse { | |||
| // NameSpace class for resolving python code. | |||
| class NameSpace : public Named { | |||
| class NameSpace final : public Named { | |||
| public: | |||
| NameSpace(const std::string &module, const py::object &obj, const py::object &module_obj = py::object()) | |||
| : Named(module), module_(module), obj_(obj), module_obj_(module_obj) {} | |||
| @@ -62,7 +62,7 @@ class NameSpace : public Named { | |||
| using NameSpacePtr = std::shared_ptr<NameSpace>; | |||
| // Symbol in NameSpace or Class which shall be resolved. | |||
| class Symbol : public Named { | |||
| class Symbol final : public Named { | |||
| public: | |||
| explicit Symbol(const std::string &symbol) : Named(symbol), symbol_(symbol) {} | |||
| Symbol(const std::string &symbol, const std::string &name) : Named(name), symbol_(symbol) {} | |||
| @@ -80,7 +80,7 @@ class Symbol : public Named { | |||
| }; | |||
| using SymbolPtr = std::shared_ptr<Symbol>; | |||
| class Script : public Named { | |||
| class Script final : public Named { | |||
| public: | |||
| explicit Script(const std::string &script) : Named(script), script_(script) {} | |||
| Script(const std::string &script, const std::string &name) : Named(name), script_(script) {} | |||
| @@ -113,7 +113,7 @@ class PyObjectWrapper : public Named { | |||
| }; | |||
| // InterpretedObject class wrappers interpreted python object. | |||
| class InterpretedObject : public PyObjectWrapper { | |||
| class InterpretedObject final : public PyObjectWrapper { | |||
| public: | |||
| explicit InterpretedObject(const py::object &obj, const std::string &name = "null") | |||
| : PyObjectWrapper(obj, "InterpretedObject: '" + name + "'") {} | |||
| @@ -127,7 +127,7 @@ class InterpretedObject : public PyObjectWrapper { | |||
| using InterpretedObjectPtr = std::shared_ptr<InterpretedObject>; | |||
| // ClassObject class wrappers dataclass | |||
| class ClassObject : public PyObjectWrapper { | |||
| class ClassObject final : public PyObjectWrapper { | |||
| public: | |||
| explicit ClassObject(const py::object &obj, const std::string &name = "Python dataclass") | |||
| : PyObjectWrapper(obj, name) {} | |||
| @@ -137,7 +137,7 @@ class ClassObject : public PyObjectWrapper { | |||
| }; | |||
| // ClassType class wrappers class name in python | |||
| class ClassType : public PyObjectWrapper { | |||
| class ClassType final : public PyObjectWrapper { | |||
| public: | |||
| explicit ClassType(const py::object &obj, const std::string &name = "Python class type") | |||
| : PyObjectWrapper(obj, name) {} | |||
| @@ -1,7 +1,7 @@ | |||
| /** | |||
| * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). | |||
| * | |||
| * Copyright 2019 Huawei Technologies Co., Ltd | |||
| * Copyright 2019-2021 Huawei Technologies Co., Ltd | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| @@ -30,7 +30,7 @@ | |||
| namespace mindspore { | |||
| namespace abstract { | |||
| class StandardPrimEvaluator : public TrivialPrimEvaluator { | |||
| class StandardPrimEvaluator final : public TrivialPrimEvaluator { | |||
| public: | |||
| StandardPrimEvaluator(const PrimitivePtr &primitive, const StandardPrimitiveImplReg &eval_impl) | |||
| : TrivialPrimEvaluator("StandardPrimEvaluator"), prim_(primitive), eval_impl_(eval_impl) {} | |||
| @@ -51,7 +51,7 @@ class StandardPrimEvaluator : public TrivialPrimEvaluator { | |||
| using StandardPrimEvaluatorPtr = std::shared_ptr<StandardPrimEvaluator>; | |||
| class PythonPrimEvaluator : public TrivialPrimEvaluator { | |||
| class PythonPrimEvaluator final : public TrivialPrimEvaluator { | |||
| public: | |||
| explicit PythonPrimEvaluator(const PrimitivePyPtr primitive) | |||
| : TrivialPrimEvaluator("PythonPrimEvaluator"), prim_py_(primitive) {} | |||
| @@ -66,10 +66,11 @@ class PythonPrimEvaluator : public TrivialPrimEvaluator { | |||
| PrimitivePyPtr prim_py_; | |||
| }; | |||
| class DoSignatureEvaluator : public Evaluator { | |||
| class DoSignatureEvaluator final : public Evaluator { | |||
| public: | |||
| explicit DoSignatureEvaluator(const PrimitivePtr primitive) : Evaluator("DoSignatureEvaluator"), prim_(primitive) {} | |||
| ~DoSignatureEvaluator() override = default; | |||
| MS_DECLARE_PARENT(DoSignatureEvaluator, Evaluator); | |||
| EvalResultPtr Run(AnalysisEnginePtr engine, const ConfigPtrList &argrefs, | |||
| const AnfNodeConfigPtr &out_config = nullptr) override; | |||
| @@ -81,10 +82,11 @@ class DoSignatureEvaluator : public Evaluator { | |||
| PrimitivePtr prim_; | |||
| }; | |||
| class UnpackGraphEvaluator : public Evaluator { | |||
| class UnpackGraphEvaluator final : public Evaluator { | |||
| public: | |||
| explicit UnpackGraphEvaluator(const PrimitivePtr primitive) : Evaluator("UnpackGraphEvaluator"), prim_(primitive) {} | |||
| ~UnpackGraphEvaluator() override = default; | |||
| MS_DECLARE_PARENT(UnpackGraphEvaluator, Evaluator); | |||
| EvalResultPtr Run(AnalysisEnginePtr engine, const ConfigPtrList &argrefs, | |||
| const AnfNodeConfigPtr &out_config = nullptr) override; | |||
| @@ -96,11 +98,12 @@ class UnpackGraphEvaluator : public Evaluator { | |||
| PrimitivePtr prim_; | |||
| }; | |||
| class MixedPrecisionCastEvaluator : public Evaluator { | |||
| class MixedPrecisionCastEvaluator final : public Evaluator { | |||
| public: | |||
| explicit MixedPrecisionCastEvaluator(const PrimitivePtr primitive) | |||
| : Evaluator("MixedPrecisionCastEvaluator"), prim_(primitive) {} | |||
| ~MixedPrecisionCastEvaluator() override = default; | |||
| MS_DECLARE_PARENT(MixedPrecisionCastEvaluator, Evaluator); | |||
| EvalResultPtr Run(AnalysisEnginePtr engine, const ConfigPtrList &argrefs, | |||
| const AnfNodeConfigPtr &out_config = nullptr) override; | |||
| @@ -117,7 +120,7 @@ bool IsInWhiteList(const PrimitivePtr &primitive); | |||
| using ValuePtrList = std::vector<ValuePtr>; | |||
| using PrimitiveImpl = ValuePtr (*)(const ValuePtrList &); | |||
| class UniformPrimEvaluator : public TrivialPrimEvaluator { | |||
| class UniformPrimEvaluator final : public TrivialPrimEvaluator { | |||
| public: | |||
| UniformPrimEvaluator(const FunctionPtr func_desc, PrimitiveImpl impl, bool eval_value, const TypePtr specify_out_type) | |||
| : TrivialPrimEvaluator("UniformPrimEvaluator"), | |||
| @@ -31,7 +31,7 @@ using StackFramePtr = std::shared_ptr<StackFrame>; | |||
| using EvaluatorWeakPtr = std::weak_ptr<Evaluator>; | |||
| using BaseFuncGraphEvaluatorPtr = std::shared_ptr<BaseFuncGraphEvaluator>; | |||
| class StackFrame : public Base { | |||
| class StackFrame final : public Base { | |||
| public: | |||
| StackFrame(const EvaluatorPtr &evaluator, const FuncGraphPtr &func_graph, const AnalysisContextPtr ¤t_context, | |||
| const AnalysisContextPtr &parent_context) | |||
| @@ -45,6 +45,8 @@ class StackFrame : public Base { | |||
| } | |||
| virtual ~StackFrame() = default; | |||
| MS_DECLARE_PARENT(StackFrame, Base); | |||
| void Load() { | |||
| node_slots_ = TopoSort(func_graph_->get_return(), SuccIncoming, [this](const AnfNodePtr &node) -> IncludeType { | |||
| if (node->isa<ValueNode>() || node->isa<Parameter>()) { | |||
| @@ -1,5 +1,5 @@ | |||
| /** | |||
| * Copyright 2019-2020 Huawei Technologies Co., Ltd | |||
| * Copyright 2019-2021 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. | |||
| @@ -108,49 +108,48 @@ py::object ScalarPtrToPyData(const ScalarPtr &value) { | |||
| } | |||
| using ConverterFunction = std::function<py::object(const ValuePtr &value)>; | |||
| using ValueNameToConverterVector = std::vector<std::pair<const char *, ConverterFunction>>; | |||
| using ValueNameToConverterVector = std::vector<std::pair<uint32_t, ConverterFunction>>; | |||
| // (Value Type Name) -> (Converter Function) | |||
| // The converter function is used to convert Value object to Python data object. | |||
| static ValueNameToConverterVector value_name_to_converter = { | |||
| // Scalar | |||
| {typeid(Scalar).name(), | |||
| [](const ValuePtr &value) -> py::object { return ScalarPtrToPyData(value->cast<ScalarPtr>()); }}, | |||
| {Scalar::kTypeId, [](const ValuePtr &value) -> py::object { return ScalarPtrToPyData(value->cast<ScalarPtr>()); }}, | |||
| // Tensor | |||
| {typeid(tensor::Tensor).name(), | |||
| {tensor::Tensor::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| auto tensor_ptr = value->cast<tensor::TensorPtr>(); | |||
| return TensorToPyData(tensor_ptr); | |||
| }}, | |||
| // MetaTenser | |||
| {typeid(tensor::MetaTensor).name(), | |||
| {tensor::MetaTensor::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| py::tuple tuple_container(1); | |||
| tuple_container[0] = value->cast<tensor::MetaTensorPtr>(); | |||
| return tuple_container[0]; | |||
| }}, | |||
| // RefKey | |||
| {typeid(RefKey).name(), | |||
| {RefKey::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| py::tuple tuple_container(1); | |||
| tuple_container[0] = value->cast<RefKeyPtr>(); | |||
| return tuple_container[0]; | |||
| }}, | |||
| // Type | |||
| {typeid(Type).name(), | |||
| {Type::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| py::tuple tuple_container(1); | |||
| tuple_container[0] = value->cast<TypePtr>(); | |||
| return tuple_container[0]; | |||
| }}, | |||
| // StringImm | |||
| {typeid(StringImm).name(), | |||
| {StringImm::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| py::str res = value->cast<StringImmPtr>()->value(); | |||
| return res; | |||
| }}, | |||
| // ValueSequeue | |||
| {typeid(ValueSequeue).name(), | |||
| {ValueSequeue::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| auto value_sequeue = value->cast<ValueSequeuePtr>()->value(); | |||
| py::tuple res_sequeue(value_sequeue.size()); | |||
| @@ -163,7 +162,7 @@ static ValueNameToConverterVector value_name_to_converter = { | |||
| return res_sequeue.cast<py::list>(); | |||
| }}, | |||
| // ValueDictionary | |||
| {typeid(ValueDictionary).name(), | |||
| {ValueDictionary::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| auto value_list = value->cast<ValueDictionaryPtr>()->value(); | |||
| py::dict res_dict; | |||
| @@ -173,7 +172,7 @@ static ValueNameToConverterVector value_name_to_converter = { | |||
| return res_dict; | |||
| }}, | |||
| // ValueSlice | |||
| {typeid(ValueSlice).name(), | |||
| {ValueSlice::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| auto slice = value->cast<ValueSlicePtr>(); | |||
| auto start = ValueToPyData(slice->start()); | |||
| @@ -183,7 +182,7 @@ static ValueNameToConverterVector value_name_to_converter = { | |||
| step); | |||
| }}, | |||
| // KeywordArg | |||
| {typeid(KeywordArg).name(), | |||
| {KeywordArg::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| auto abs_keyword_arg = value->ToAbstract()->cast<abstract::AbstractKeywordArgPtr>(); | |||
| auto key = abs_keyword_arg->get_key(); | |||
| @@ -194,40 +193,40 @@ static ValueNameToConverterVector value_name_to_converter = { | |||
| return kwargs; | |||
| }}, | |||
| // parse::NameSpace | |||
| {typeid(parse::NameSpace).name(), | |||
| {parse::NameSpace::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| auto ns = value->cast<parse::NameSpacePtr>(); | |||
| return ns->module_obj(); | |||
| }}, | |||
| // parse::ClassType | |||
| {typeid(parse::ClassType).name(), | |||
| {parse::ClassType::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| auto class_type = value->cast<parse::ClassTypePtr>(); | |||
| return class_type->obj(); | |||
| }}, | |||
| // parse::InterpretedObject | |||
| {typeid(parse::InterpretedObject).name(), | |||
| {parse::InterpretedObject::kTypeId, | |||
| [](const ValuePtr &value) -> py::object { | |||
| auto interpreted_object = value->cast<parse::InterpretedObjectPtr>(); | |||
| return interpreted_object->obj(); | |||
| }}, | |||
| // None | |||
| {typeid(None).name(), [](const ValuePtr &value) -> py::object { return py::none(); }}, | |||
| {None::kTypeId, [](const ValuePtr &value) -> py::object { return py::none(); }}, | |||
| // AnyValue | |||
| {typeid(AnyValue).name(), [](const ValuePtr &value) -> py::object { return py::none(); }}, | |||
| {AnyValue::kTypeId, [](const ValuePtr &value) -> py::object { return py::none(); }}, | |||
| // FuncGraph | |||
| {typeid(FuncGraph).name(), [](const ValuePtr &value) -> py::object { return py::none(); }}, | |||
| {FuncGraph::kTypeId, [](const ValuePtr &value) -> py::object { return py::none(); }}, | |||
| // Monad | |||
| {typeid(Monad).name(), [](const ValuePtr &value) -> py::object { return py::none(); }}, | |||
| {Monad::kTypeId, [](const ValuePtr &value) -> py::object { return py::none(); }}, | |||
| // Ellipsis | |||
| {typeid(Ellipsis).name(), [](const ValuePtr &value) -> py::object { return py::ellipsis(); }}}; | |||
| {Ellipsis::kTypeId, [](const ValuePtr &value) -> py::object { return py::ellipsis(); }}}; | |||
| py::object ValueToPyData(const ValuePtr &value) { | |||
| if (value == nullptr) { | |||
| MS_LOG(EXCEPTION) << "The `value` should not be null"; | |||
| } | |||
| for (auto &iter : value_name_to_converter) { | |||
| if (value->IsFromTypeId(Base::GetTypeId(iter.first))) { | |||
| if (value->IsFromTypeId(iter.first)) { | |||
| return iter.second(value); | |||
| } | |||
| } | |||
| @@ -33,15 +33,17 @@ namespace mindspore { | |||
| namespace compile { | |||
| // Indicate a call to a new frame. | |||
| struct CallWrap : public Base { | |||
| struct CallWrap final : public Base { | |||
| explicit CallWrap(const VMFramePtr &vm_frame) : frame(vm_frame) {} | |||
| MS_DECLARE_PARENT(CallWrap, Base); | |||
| VMFramePtr frame{nullptr}; | |||
| }; | |||
| using CallWrapPtr = std::shared_ptr<CallWrap>; | |||
| // Indicates a return with its value. | |||
| struct ReturnWrap : public Base { | |||
| struct ReturnWrap final : public Base { | |||
| explicit ReturnWrap(const BaseRef &r_value) : value(r_value) {} | |||
| MS_DECLARE_PARENT(ReturnWrap, Base); | |||
| BaseRef value{BaseRef()}; | |||
| }; | |||
| using ReturnWrapPtr = std::shared_ptr<ReturnWrap>; | |||
| @@ -50,7 +50,7 @@ class MS_CORE_API AbstractFuncAtom : public AbstractFunction { | |||
| }; | |||
| /// \brief AbstractFuncUnion defines interface for abstract of union function. | |||
| class MS_CORE_API AbstractFuncUnion : public AbstractFunction { | |||
| class MS_CORE_API AbstractFuncUnion final : public AbstractFunction { | |||
| public: | |||
| /// \brief Constructor AbstractFuncUnion from AbstractFuncAtom list. | |||
| /// | |||
| @@ -101,7 +101,7 @@ class MS_CORE_API AbstractFuncUnion : public AbstractFunction { | |||
| }; | |||
| /// \brief PrimitiveAbstractClosure defines interface for abstract of Primitive. | |||
| class MS_CORE_API PrimitiveAbstractClosure : public AbstractFuncAtom { | |||
| class MS_CORE_API PrimitiveAbstractClosure final : public AbstractFuncAtom { | |||
| public: | |||
| /// \brief Constructor of PrimitiveAbstractClosure | |||
| /// | |||
| @@ -142,7 +142,7 @@ class MS_CORE_API PrimitiveAbstractClosure : public AbstractFuncAtom { | |||
| using PrimitiveAbstractClosurePtr = std::shared_ptr<PrimitiveAbstractClosure>; | |||
| /// \brief FuncGraphAbstractClosure defines interface for abstract of FuncGraph. | |||
| class MS_CORE_API FuncGraphAbstractClosure : public AbstractFuncAtom { | |||
| class MS_CORE_API FuncGraphAbstractClosure final : public AbstractFuncAtom { | |||
| public: | |||
| /// \brief Constructor of FuncGraphAbstractClosure. | |||
| /// | |||
| @@ -196,7 +196,7 @@ class MS_CORE_API FuncGraphAbstractClosure : public AbstractFuncAtom { | |||
| using FuncGraphAbstractClosurePtr = std::shared_ptr<FuncGraphAbstractClosure>; | |||
| /// \brief MetaFuncGraphAbstractClosure defines interface for abstract of MetaFuncGraph. | |||
| class MS_CORE_API MetaFuncGraphAbstractClosure : public AbstractFuncAtom { | |||
| class MS_CORE_API MetaFuncGraphAbstractClosure final : public AbstractFuncAtom { | |||
| public: | |||
| /// \brief Constructor of FuncGraphAbstractClosure. | |||
| /// | |||
| @@ -245,7 +245,7 @@ class MS_CORE_API MetaFuncGraphAbstractClosure : public AbstractFuncAtom { | |||
| using MetaFuncGraphAbstractClosurePtr = std::shared_ptr<MetaFuncGraphAbstractClosure>; | |||
| /// \brief PartialAbstractClosure defines the abstract AbstractFuncAtom interface provided by some args in advance. | |||
| class MS_CORE_API PartialAbstractClosure : public AbstractFuncAtom { | |||
| class MS_CORE_API PartialAbstractClosure final : public AbstractFuncAtom { | |||
| public: | |||
| /// \brief Constructor of PartialAbstractClosure. | |||
| /// | |||
| @@ -302,7 +302,7 @@ using PartialAbstractClosurePtr = std::shared_ptr<PartialAbstractClosure>; | |||
| /// \brief JTransformedAbstractClosure defines interface for abstract of Function | |||
| /// transformed through the application of J. | |||
| class MS_CORE_API JTransformedAbstractClosure : public AbstractFuncAtom { | |||
| class MS_CORE_API JTransformedAbstractClosure final : public AbstractFuncAtom { | |||
| public: | |||
| /// \brief Constructor of JTransformedAbstractClosure | |||
| /// | |||
| @@ -332,7 +332,7 @@ class MS_CORE_API JTransformedAbstractClosure : public AbstractFuncAtom { | |||
| /// \brief VirtualAbstractClosure defines interface for function with an explicitly | |||
| /// fixed type signature. | |||
| class MS_CORE_API VirtualAbstractClosure : public AbstractFuncAtom { | |||
| class MS_CORE_API VirtualAbstractClosure final : public AbstractFuncAtom { | |||
| public: | |||
| /// \brief Constructor of VirtualAbstractClosure. | |||
| /// | |||
| @@ -380,7 +380,7 @@ using VirtualAbstractClosurePtr = std::shared_ptr<VirtualAbstractClosure>; | |||
| /// \brief TypedPrimitiveAbstractClosure defines interface for Primitive with an explicitly | |||
| /// fixed type signature. | |||
| class MS_CORE_API TypedPrimitiveAbstractClosure : public AbstractFuncAtom { | |||
| class MS_CORE_API TypedPrimitiveAbstractClosure final : public AbstractFuncAtom { | |||
| public: | |||
| /// \brief Constructor of TypedPrimitiveAbstractClosure. | |||
| /// | |||
| @@ -195,7 +195,7 @@ class MS_CORE_API AbstractBase : public Base { | |||
| }; | |||
| /// \brief Class AbstractScalar describes a scalar's type and value. | |||
| class MS_CORE_API AbstractScalar : public AbstractBase { | |||
| class MS_CORE_API AbstractScalar final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractScalar. | |||
| AbstractScalar() : AbstractBase(kAnyValue, kAnyType) {} | |||
| @@ -265,7 +265,7 @@ class MS_CORE_API AbstractScalar : public AbstractBase { | |||
| using AbstractScalarPtr = std::shared_ptr<AbstractScalar>; | |||
| /// \brief Class AbstractType describes the abstract value from a Typeof node. | |||
| class MS_CORE_API AbstractType : public AbstractBase { | |||
| class MS_CORE_API AbstractType final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractType. | |||
| /// | |||
| @@ -293,7 +293,7 @@ class MS_CORE_API AbstractType : public AbstractBase { | |||
| using AbstractTypePtr = std::shared_ptr<AbstractType>; | |||
| /// \brief Class AbstractError describes the abstract value from an error. | |||
| class MS_CORE_API AbstractError : public AbstractBase { | |||
| class MS_CORE_API AbstractError final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractError. | |||
| /// | |||
| @@ -325,7 +325,7 @@ class MS_CORE_API AbstractError : public AbstractBase { | |||
| }; | |||
| /// \brief Class AbstractScript describes the script node's type, shape and value. | |||
| class MS_CORE_API AbstractScript : public AbstractBase { | |||
| class MS_CORE_API AbstractScript final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractScript. | |||
| AbstractScript() : AbstractBase(kAnyValue, kAnyType) {} | |||
| @@ -453,7 +453,7 @@ using AbstractFunctionPtrList = std::vector<AbstractFunctionPtr>; | |||
| /// \brief Class AbstractKeywordArg describes an abstract value from a key-value node. | |||
| /// | |||
| /// Represents a key-value pair used in function's parameters. | |||
| class MS_CORE_API AbstractKeywordArg : public AbstractBase { | |||
| class MS_CORE_API AbstractKeywordArg final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractKeywordArg. | |||
| /// | |||
| @@ -770,7 +770,7 @@ class MS_CORE_API AbstractSequeue : public AbstractBase { | |||
| using AbstractSequeuePtr = std::shared_ptr<AbstractSequeue>; | |||
| /// \brief Class AbstractTuple describes a tuple. | |||
| class MS_CORE_API AbstractTuple : public AbstractSequeue { | |||
| class MS_CORE_API AbstractTuple final : public AbstractSequeue { | |||
| public: | |||
| /// \brief Constructor of AbstractTuple. | |||
| /// | |||
| @@ -810,7 +810,7 @@ class MS_CORE_API AbstractTuple : public AbstractSequeue { | |||
| using AbstractTuplePtr = std::shared_ptr<AbstractTuple>; | |||
| /// \brief Class AbstractList describes a list. | |||
| class MS_CORE_API AbstractList : public AbstractSequeue { | |||
| class MS_CORE_API AbstractList final : public AbstractSequeue { | |||
| public: | |||
| /// \brief Constructor of AbstractList. | |||
| /// | |||
| @@ -850,7 +850,7 @@ class MS_CORE_API AbstractList : public AbstractSequeue { | |||
| using AbstractListPtr = std::shared_ptr<AbstractList>; | |||
| /// \brief Class AbstractClass describes a class node's abstract value. | |||
| class MS_CORE_API AbstractClass : public AbstractBase { | |||
| class MS_CORE_API AbstractClass final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractClass. | |||
| /// | |||
| @@ -922,7 +922,7 @@ class MS_CORE_API AbstractClass : public AbstractBase { | |||
| using AbstractClassPtr = std::shared_ptr<AbstractClass>; | |||
| /// \brief Class AbstractDictionary describes a dictionary node's abstract value. | |||
| class MS_CORE_API AbstractDictionary : public AbstractBase { | |||
| class MS_CORE_API AbstractDictionary final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractDictionary. | |||
| /// | |||
| @@ -970,7 +970,7 @@ class MS_CORE_API AbstractDictionary : public AbstractBase { | |||
| using AbstractDictionaryPtr = std::shared_ptr<AbstractDictionary>; | |||
| /// \brief Class AbstractSlice describes a slice node's abstract value. | |||
| class MS_CORE_API AbstractSlice : public AbstractBase { | |||
| class MS_CORE_API AbstractSlice final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractSlice. | |||
| /// | |||
| @@ -1029,7 +1029,7 @@ class MS_CORE_API AbstractSlice : public AbstractBase { | |||
| using AbstractSlicePtr = std::shared_ptr<AbstractSlice>; | |||
| /// \brief Class AbstractJTagged describes a J node's abstract value. | |||
| class MS_CORE_API AbstractJTagged : public AbstractBase { | |||
| class MS_CORE_API AbstractJTagged final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractJTagged. | |||
| /// | |||
| @@ -1072,7 +1072,7 @@ class MS_CORE_API AbstractJTagged : public AbstractBase { | |||
| using AbstractJTaggedPtr = std::shared_ptr<AbstractJTagged>; | |||
| /// \brief Class AbstractNone describes a None node's abstract value. | |||
| class MS_CORE_API AbstractNone : public AbstractBase { | |||
| class MS_CORE_API AbstractNone final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractNone. | |||
| AbstractNone() : AbstractBase() { set_type(std::make_shared<TypeNone>()); } | |||
| @@ -1105,7 +1105,7 @@ using AbstractNonePtr = std::shared_ptr<AbstractNone>; | |||
| /// | |||
| /// The unassigned state value for variable, | |||
| /// which means the variable is not assigned. | |||
| class MS_CORE_API AbstractNull : public AbstractBase { | |||
| class MS_CORE_API AbstractNull final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractNull. | |||
| AbstractNull() : AbstractBase(kNull) { set_type(std::make_shared<TypeNull>()); } | |||
| @@ -1135,7 +1135,7 @@ using AbstractNullPtr = std::shared_ptr<AbstractNull>; | |||
| /// | |||
| /// The timeout state value for variable, which means | |||
| /// the variable is not assigned because it is timeout. | |||
| class MS_CORE_API AbstractTimeOut : public AbstractBase { | |||
| class MS_CORE_API AbstractTimeOut final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractTimeOut. | |||
| AbstractTimeOut() : AbstractBase(kNull) { set_type(std::make_shared<TypeNull>()); } | |||
| @@ -1162,7 +1162,7 @@ class MS_CORE_API AbstractTimeOut : public AbstractBase { | |||
| using AbstractTimeOutPtr = std::shared_ptr<AbstractTimeOut>; | |||
| /// \brief Class AbstractEllipsis describes a Ellipsis node's abstract value. | |||
| class MS_CORE_API AbstractEllipsis : public AbstractBase { | |||
| class MS_CORE_API AbstractEllipsis final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractEllipsis. | |||
| AbstractEllipsis() : AbstractBase(kEllipsis) { set_type(std::make_shared<TypeEllipsis>()); } | |||
| @@ -1189,7 +1189,7 @@ class MS_CORE_API AbstractEllipsis : public AbstractBase { | |||
| using AbstractEllipsisPtr = std::shared_ptr<AbstractEllipsis>; | |||
| /// \brief Class AbstractRefKey describes a RefKey node's abstract value. | |||
| class MS_CORE_API AbstractRefKey : public AbstractBase { | |||
| class MS_CORE_API AbstractRefKey final : public AbstractBase { | |||
| public: | |||
| /// \brief Constructor of AbstractRefKey. | |||
| AbstractRefKey() : AbstractBase(), ref_key_value_(nullptr) { set_type(std::make_shared<RefKeyType>()); } | |||
| @@ -1238,7 +1238,7 @@ class MS_CORE_API AbstractRefKey : public AbstractBase { | |||
| using AbstractRefKeyPtr = std::shared_ptr<AbstractRefKey>; | |||
| /// \brief Class AbstractRef describes a RefTensor's abstract value. | |||
| class MS_CORE_API AbstractRef : public AbstractTensor { | |||
| class MS_CORE_API AbstractRef final : public AbstractTensor { | |||
| public: | |||
| /// \brief Constructor of AbstractRef. | |||
| /// | |||
| @@ -1340,7 +1340,7 @@ MS_CORE_API std::size_t AbstractBasePtrListHash(const AbstractBasePtrList &args_ | |||
| MS_CORE_API bool AbstractBasePtrListDeepEqual(const AbstractBasePtrList &lhs, const AbstractBasePtrList &rhs); | |||
| /// \brief Class AbstractRowTensor describes a RowTensor's abstract value. | |||
| class MS_CORE_API AbstractRowTensor : public AbstractUndetermined { | |||
| class MS_CORE_API AbstractRowTensor final : public AbstractUndetermined { | |||
| public: | |||
| /// \brief Constructor of AbstractRowTensor. | |||
| /// | |||
| @@ -1410,7 +1410,7 @@ class MS_CORE_API AbstractRowTensor : public AbstractUndetermined { | |||
| }; | |||
| /// \brief Class AbstractSparseTensor describes a SparseTensor's abstract value. | |||
| class MS_CORE_API AbstractSparseTensor : public AbstractUndetermined { | |||
| class MS_CORE_API AbstractSparseTensor final : public AbstractUndetermined { | |||
| public: | |||
| /// \brief Constructor of AbstractSparseTensor. | |||
| /// | |||
| @@ -1499,7 +1499,7 @@ class AbstractMonad : public AbstractBase { | |||
| }; | |||
| using AbstractMonadPtr = std::shared_ptr<AbstractMonad>; | |||
| class AbstractUMonad : public AbstractMonad { | |||
| class AbstractUMonad final : public AbstractMonad { | |||
| public: | |||
| explicit AbstractUMonad(const ValuePtr &value = kUMonad) : AbstractMonad(value, kUMonadType) {} | |||
| ~AbstractUMonad() override = default; | |||
| @@ -1512,7 +1512,7 @@ class AbstractUMonad : public AbstractMonad { | |||
| }; | |||
| using AbstractUMonadPtr = std::shared_ptr<AbstractUMonad>; | |||
| class AbstractIOMonad : public AbstractMonad { | |||
| class AbstractIOMonad final : public AbstractMonad { | |||
| public: | |||
| explicit AbstractIOMonad(const ValuePtr &value = kIOMonad) : AbstractMonad(value, kIOMonadType) {} | |||
| ~AbstractIOMonad() override = default; | |||
| @@ -1,7 +1,7 @@ | |||
| /** | |||
| * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). | |||
| * | |||
| * Copyright 2019 Huawei Technologies Co., Ltd | |||
| * Copyright 2019-2021 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. | |||
| @@ -85,7 +85,7 @@ class MS_CORE_API BaseShape : public Base { | |||
| }; | |||
| /// \brief NoShape defines an invalid shape. | |||
| class MS_CORE_API NoShape : public BaseShape { | |||
| class MS_CORE_API NoShape final : public BaseShape { | |||
| public: | |||
| MS_DECLARE_PARENT(NoShape, BaseShape) | |||
| @@ -104,7 +104,7 @@ class MS_CORE_API NoShape : public BaseShape { | |||
| inline const std::shared_ptr<NoShape> kNoShape = std::make_shared<NoShape>(); | |||
| /// \brief Shape defines dimensions of tensor. | |||
| class MS_CORE_API Shape : public BaseShape { | |||
| class MS_CORE_API Shape final : public BaseShape { | |||
| public: | |||
| static const int64_t SHP_ANY = -1; | |||
| @@ -247,7 +247,7 @@ class MS_CORE_API SequeueShape : public BaseShape { | |||
| using SequeueShapePtr = std::shared_ptr<SequeueShape>; | |||
| /// \brief TupleShape defines shape used by tuple with tensor inside. | |||
| class MS_CORE_API TupleShape : public SequeueShape { | |||
| class MS_CORE_API TupleShape final : public SequeueShape { | |||
| public: | |||
| /// \brief Constructor of TupleShape. | |||
| TupleShape() : SequeueShape() {} | |||
| @@ -270,7 +270,7 @@ class MS_CORE_API TupleShape : public SequeueShape { | |||
| using TupleShapePtr = std::shared_ptr<TupleShape>; | |||
| /// \brief ListShape defines shape used by list with tensor inside. | |||
| class MS_CORE_API ListShape : public SequeueShape { | |||
| class MS_CORE_API ListShape final : public SequeueShape { | |||
| public: | |||
| /// \brief Constructor of ListShape. | |||
| ListShape() : SequeueShape() {} | |||
| @@ -1,5 +1,5 @@ | |||
| /** | |||
| * Copyright 2019 Huawei Technologies Co., Ltd | |||
| * Copyright 2019-2021 Huawei Technologies Co., Ltd | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| @@ -15,26 +15,4 @@ | |||
| */ | |||
| #include "base/base.h" | |||
| #include <atomic> | |||
| #include <mutex> | |||
| #include <string> | |||
| #include <unordered_map> | |||
| namespace mindspore { | |||
| const bool Base::IsFromTypeId(uint32_t tid) const { | |||
| static const uint32_t node_id = GetTypeId(typeid(Base).name()); | |||
| return tid == node_id; | |||
| } | |||
| uint32_t Base::GetTypeId(const char *const type_name) { | |||
| TypeIdManager *t = TypeIdManager::Get(); | |||
| std::lock_guard<std::mutex>(t->mutex); | |||
| auto it = t->map.find(type_name); | |||
| if (it != t->map.end()) { | |||
| return it->second; | |||
| } | |||
| uint32_t tid = std::hash<std::string>()(type_name); | |||
| t->map[type_name] = tid; | |||
| return tid; | |||
| } | |||
| } // namespace mindspore | |||
| // This file is kept to make cmake happy. | |||
| @@ -26,6 +26,8 @@ | |||
| #include <unordered_map> | |||
| #include <vector> | |||
| #include <utility> | |||
| #include <algorithm> | |||
| #include "utils/hashing.h" | |||
| #include "utils/visible.h" | |||
| #include "utils/log_adapter.h" | |||
| #include "utils/ordered_set.h" | |||
| @@ -40,6 +42,9 @@ struct is_shared_ptr<std::shared_ptr<T>> : public std::true_type {}; | |||
| /// \brief Base is a base class of many derived classes, which provides basic interfaces such as hash, and so on. | |||
| class MS_CORE_API Base : public std::enable_shared_from_this<Base> { | |||
| public: | |||
| /// \brief The type id of this class. | |||
| static constexpr uint32_t kTypeId = ConstStringHash("Base"); | |||
| /// \brief The constructor of Base. | |||
| /// | |||
| /// \return The instance of Base. | |||
| @@ -92,32 +97,36 @@ class MS_CORE_API Base : public std::enable_shared_from_this<Base> { | |||
| /// \return The text representation. | |||
| virtual std::string DumpText() const { return ToString(); } | |||
| /// \brief Judge whether a type id is the same as the type id of this object. | |||
| /// \brief Judge whether this object is an instance of class with the given type id. | |||
| /// | |||
| /// \param[in] tid Define a type id. | |||
| /// | |||
| /// \return The result of the judgment. | |||
| virtual bool IsFromTypeId(uint32_t tid) const { return Base::IsDerivedFrom(tid); } | |||
| /// \brief Judge whether the type id of this object is same as the given type id. | |||
| /// | |||
| /// \param[in] tid Define a type id. | |||
| /// | |||
| /// \return The result of the judgment. | |||
| virtual const bool IsFromTypeId(uint32_t tid) const; | |||
| virtual bool IsSameTypeId(uint32_t tid) const { return tid == Base::kTypeId; } | |||
| /// \brief Get the type name of this object. | |||
| /// | |||
| /// \return The type name. | |||
| virtual std::string type_name() const { return "Base"; } | |||
| /// \brief Get a type id which is a hash value from a type name. | |||
| /// | |||
| /// \param[in] type_key Define a string for the type name. | |||
| /// \brief Get the type id of this object. | |||
| /// | |||
| /// \return The type id. | |||
| static uint32_t GetTypeId(const char *const type_key); | |||
| virtual uint32_t tid() const { return Base::kTypeId; } | |||
| /// \brief Get the type id of this object. | |||
| /// \brief Judge whether this class is derived from class with the given type id. | |||
| /// | |||
| /// \return The type id. | |||
| virtual uint32_t tid() const { | |||
| static const uint32_t tid = GetTypeId(typeid(Base).name()); | |||
| return tid; | |||
| } | |||
| /// \param[in] tid Define a type id. | |||
| /// | |||
| /// \return The result of the judgment. | |||
| static bool IsDerivedFrom(uint32_t tid) __attribute__((__always_inline__)) { return tid == Base::kTypeId; } | |||
| /// \brief Judge whether this object is an instance of a given class which is derived from Base. | |||
| /// | |||
| @@ -125,8 +134,11 @@ class MS_CORE_API Base : public std::enable_shared_from_this<Base> { | |||
| template <typename T, | |||
| typename std::enable_if<!is_shared_ptr<T>::value && std::is_base_of<Base, T>::value, T>::type * = nullptr> | |||
| inline bool isa() const { | |||
| static const uint32_t tid = GetTypeId(typeid(T).name()); | |||
| return this->IsFromTypeId(tid); | |||
| if constexpr (std::is_final<T>::value) { | |||
| return this->IsSameTypeId(T::kTypeId); | |||
| } else { | |||
| return this->IsFromTypeId(T::kTypeId); | |||
| } | |||
| } | |||
| /// \brief Cast a shared_ptr of this object to a given class. | |||
| @@ -174,18 +186,14 @@ inline std::shared_ptr<T> dyn_cast(const std::shared_ptr<U> &r) { | |||
| } | |||
| } | |||
| #define MS_DECLARE_PARENT(current_t, parent_t) \ | |||
| uint32_t tid() const override { \ | |||
| static const uint32_t tid = GetTypeId(typeid(current_t).name()); \ | |||
| return tid; \ | |||
| } \ | |||
| const bool IsFromTypeId(uint32_t from_tid) const override { \ | |||
| static const uint32_t tid = Base::GetTypeId(typeid(current_t).name()); \ | |||
| if (tid == from_tid) { \ | |||
| return true; \ | |||
| } \ | |||
| return parent_t::IsFromTypeId(from_tid); \ | |||
| } \ | |||
| #define MS_DECLARE_PARENT(current_t, parent_t) \ | |||
| static constexpr uint32_t kTypeId = ConstStringHash(#parent_t "_" #current_t); \ | |||
| static bool IsDerivedFrom(uint32_t tid) __attribute__((__always_inline__)) { \ | |||
| return (tid == current_t::kTypeId) || parent_t::IsDerivedFrom(tid); \ | |||
| } \ | |||
| uint32_t tid() const override { return current_t::kTypeId; } \ | |||
| bool IsFromTypeId(uint32_t tid) const override { return current_t::IsDerivedFrom(tid); } \ | |||
| bool IsSameTypeId(uint32_t tid) const override { return tid == current_t::kTypeId; } \ | |||
| std::string type_name() const override { return #current_t; } | |||
| class Type; | |||
| @@ -208,22 +216,6 @@ using AbstractAttribute = std::pair<std::string, AbstractBasePtr>; | |||
| class AnalysisContext; | |||
| using AnalysisContextPtr = std::shared_ptr<AnalysisContext>; | |||
| } // namespace abstract | |||
| /// \brief TypeIdManager is a manager for saving and reading the type id. | |||
| struct MS_EXPORT TypeIdManager { | |||
| std::mutex mutex; | |||
| std::atomic<uint32_t> type_counter{0}; | |||
| std::unordered_map<std::string, uint32_t> map; | |||
| /// \brief Get the singleton pointer of TypeIdManager. | |||
| /// | |||
| /// \return The singleton pointer of TypeIdManager. | |||
| static TypeIdManager *Get(); | |||
| /// \brief The constructor of TypeIdManager. | |||
| /// | |||
| /// \return The instance of TypeIdManager. | |||
| TypeIdManager() : mutex(), type_counter(0), map() {} | |||
| }; | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CORE_BASE_BASE_H_ | |||
| @@ -231,8 +231,7 @@ bool isa(const BaseRef &handle) { | |||
| // isa<BaseRef>(handle), judge reference or ptr | |||
| template <typename T, typename std::enable_if<is_base_ref<T>::value, int64_t>::type = static_cast<int64_t>(0)> | |||
| bool isa(const BaseRef &handle) { | |||
| static const uint32_t tid = Base::GetTypeId(typeid(T).name()); | |||
| return handle.IsFromTypeId(tid) || (handle.m_ptr && handle.m_ptr->isa<T>()); | |||
| return handle.isa<T>() || (handle.m_ptr && handle.m_ptr->isa<T>()); | |||
| } | |||
| // valueref -> C++ type | |||
| @@ -1,5 +1,5 @@ | |||
| /** | |||
| * Copyright 2019 Huawei Technologies Co., Ltd | |||
| * Copyright 2019-2021 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. | |||
| @@ -14,17 +14,5 @@ | |||
| * limitations under the License. | |||
| */ | |||
| #include <vector> | |||
| #include <string> | |||
| #include <atomic> | |||
| #include <mutex> | |||
| #include <unordered_map> | |||
| #include "base/base.h" | |||
| namespace mindspore { | |||
| struct TypeIdManager *TypeIdManager::Get() { | |||
| static TypeIdManager manager; | |||
| return &manager; | |||
| } | |||
| } // namespace mindspore | |||
| // This file is kept to make cmake happy. | |||
| @@ -380,7 +380,7 @@ class MS_CORE_API AnfNode : public Base { | |||
| // stop_gradient_: a flag used to stop gradient. | |||
| // Using stop_gradient() to get this flag, mainly used in ad. | |||
| // Using set_stop_gradient() to set this flag. | |||
| class MS_CORE_API CNode : public AnfNode, public EffectInfoHolder { | |||
| class MS_CORE_API CNode final : public AnfNode, public EffectInfoHolder { | |||
| public: | |||
| /// \brief Constructor. | |||
| /// | |||
| @@ -705,7 +705,7 @@ class MS_CORE_API ANode : public AnfNode { | |||
| // Parameter represents the parameter inputs of a function. They have no value. | |||
| // Attributes: | |||
| // default_param_value_: used to hold the inputting tensor of the model. | |||
| class MS_CORE_API Parameter : public ANode { | |||
| class MS_CORE_API Parameter final : public ANode { | |||
| public: | |||
| /// \brief Constructor. | |||
| /// | |||
| @@ -897,7 +897,7 @@ class MS_CORE_API Value : public Base { | |||
| // ValueNode is used to hold value. Unlike CNode and Parameter, ValueNode | |||
| // does not belong to any particular function graph. | |||
| class MS_CORE_API ValueNode : public ANode { | |||
| class MS_CORE_API ValueNode final : public ANode { | |||
| public: | |||
| /// \brief Constructor of ValueNode. | |||
| /// | |||
| @@ -31,7 +31,7 @@ using abstract::AbstractBasePtr; | |||
| using abstract::AbstractBasePtrList; | |||
| /// \brief The Cell class of MindSpore is the base class for building all networks and the basic unit of a network. | |||
| class MS_CORE_API Cell : public Named { | |||
| class MS_CORE_API Cell final : public Named { | |||
| public: | |||
| /// \brief Constructor. | |||
| /// | |||
| @@ -57,7 +57,7 @@ MS_CORE_API TypePtr TypeIdToType(TypeId id); | |||
| MS_CORE_API std::string TypeIdToString(TypeId id, bool to_lower = false); | |||
| /// \brief String defines a type of string. | |||
| class MS_CORE_API String : public Object { | |||
| class MS_CORE_API String final : public Object { | |||
| public: | |||
| /// \brief The constructor of String. | |||
| /// | |||
| @@ -78,7 +78,7 @@ class MS_CORE_API String : public Object { | |||
| using StringPtr = std::shared_ptr<String>; | |||
| /// \brief Keyword defines a type of keyword. | |||
| class MS_CORE_API Keyword : public Object { | |||
| class MS_CORE_API Keyword final : public Object { | |||
| public: | |||
| /// \brief The constructor of Keyword. | |||
| /// | |||
| @@ -122,7 +122,7 @@ class MS_CORE_API Keyword : public Object { | |||
| using KeywordPtr = std::shared_ptr<Keyword>; | |||
| /// \brief Slice defines a type of slice. | |||
| class MS_CORE_API Slice : public Object { | |||
| class MS_CORE_API Slice final : public Object { | |||
| public: | |||
| /// \brief The constructor of Slice. | |||
| /// | |||
| @@ -175,7 +175,7 @@ class MS_CORE_API Slice : public Object { | |||
| using SlicePtr = std::shared_ptr<Slice>; | |||
| /// \brief Function defines a type of function. | |||
| class MS_CORE_API Function : public Object { | |||
| class MS_CORE_API Function final : public Object { | |||
| public: | |||
| /// \brief The constructor of Function. | |||
| /// | |||
| @@ -224,7 +224,7 @@ class MS_CORE_API Function : public Object { | |||
| using FunctionPtr = std::shared_ptr<Function>; | |||
| /// \brief JTagged defines a type representing an object is tagged with J. | |||
| class MS_CORE_API JTagged : public Object { | |||
| class MS_CORE_API JTagged final : public Object { | |||
| public: | |||
| /// \brief The constructor of JTagged. | |||
| /// | |||
| @@ -254,7 +254,7 @@ class MS_CORE_API JTagged : public Object { | |||
| using JTaggedPtr = std::shared_ptr<JTagged>; | |||
| /// \brief SymbolicKeyType defines a type of symbolic key. | |||
| class MS_CORE_API SymbolicKeyType : public Object { | |||
| class MS_CORE_API SymbolicKeyType final : public Object { | |||
| public: | |||
| /// \brief The constructor of SymbolicKeyType. | |||
| /// | |||
| @@ -272,7 +272,7 @@ class MS_CORE_API SymbolicKeyType : public Object { | |||
| }; | |||
| /// \brief EnvType defines a type of environment variable. | |||
| class MS_CORE_API EnvType : public Object { | |||
| class MS_CORE_API EnvType final : public Object { | |||
| public: | |||
| /// \brief The constructor of EnvType. | |||
| /// | |||
| @@ -290,7 +290,7 @@ class MS_CORE_API EnvType : public Object { | |||
| using EnvTypePtr = std::shared_ptr<EnvType>; | |||
| /// \brief TypeType defines a type of type itself. | |||
| class MS_CORE_API TypeType : public Type { | |||
| class MS_CORE_API TypeType final : public Type { | |||
| public: | |||
| /// \brief The constructor of TypeType. | |||
| /// | |||
| @@ -309,7 +309,7 @@ class MS_CORE_API TypeType : public Type { | |||
| using TypeTypePtr = std::shared_ptr<TypeType>; | |||
| /// \brief Problem defines a type of problem. | |||
| class MS_CORE_API Problem : public Type { | |||
| class MS_CORE_API Problem final : public Type { | |||
| public: | |||
| /// \brief The constructor of Problem. | |||
| /// | |||
| @@ -347,7 +347,7 @@ class MS_CORE_API Problem : public Type { | |||
| using ProblemPtr = std::shared_ptr<Problem>; | |||
| /// \brief External defines a type which is external. | |||
| class MS_CORE_API External : public Type { | |||
| class MS_CORE_API External final : public Type { | |||
| public: | |||
| /// \brief The constructor of External. | |||
| /// | |||
| @@ -35,7 +35,7 @@ | |||
| namespace mindspore { | |||
| /// \brief List defines interface for list data type. | |||
| class MS_CORE_API List : public Object { | |||
| class MS_CORE_API List final : public Object { | |||
| public: | |||
| /// \brief Default constructor for List. | |||
| List() : Object(kObjectTypeList) {} | |||
| @@ -91,7 +91,7 @@ using ListPtr = std::shared_ptr<List>; | |||
| using ClassAttrVector = std::vector<std::pair<std::string, TypePtr>>; | |||
| /// \brief Class defines interface for class data type. | |||
| class MS_CORE_API Class : public Object { | |||
| class MS_CORE_API Class final : public Object { | |||
| public: | |||
| /// \brief Constructor for Class. | |||
| Class() : Object(kObjectTypeClass), tag_(Named("Class")) {} | |||
| @@ -154,7 +154,7 @@ class MS_CORE_API Class : public Object { | |||
| using ClassPtr = std::shared_ptr<Class>; | |||
| /// \brief Tuple defines interface for tuple data type. | |||
| class MS_CORE_API Tuple : public Object { | |||
| class MS_CORE_API Tuple final : public Object { | |||
| public: | |||
| /// \brief Default constructor for Tuple. | |||
| Tuple() : Object(kObjectTypeTuple) {} | |||
| @@ -209,7 +209,7 @@ class MS_CORE_API Tuple : public Object { | |||
| using TuplePtr = std::shared_ptr<Tuple>; | |||
| /// \brief Dictionary defines interface for dictionary data type. | |||
| class MS_CORE_API Dictionary : public Object { | |||
| class MS_CORE_API Dictionary final : public Object { | |||
| public: | |||
| /// \brief Default constructor for Dictionary. | |||
| Dictionary() : Object(kObjectTypeDictionary) {} | |||
| @@ -28,7 +28,7 @@ | |||
| namespace mindspore { | |||
| // TypeRefKey type | |||
| /// \brief RefKeyType defines an Object class whose type is RefKey. | |||
| class MS_CORE_API RefKeyType : public Object { | |||
| class MS_CORE_API RefKeyType final : public Object { | |||
| public: | |||
| /// \brief Default constructor for RefKeyType. | |||
| RefKeyType() : Object(kObjectTypeRefKey) {} | |||
| @@ -45,7 +45,7 @@ class MS_CORE_API RefKeyType : public Object { | |||
| // TypeRef type | |||
| /// \brief RefType defines a TensorType class whose type is Ref. | |||
| class MS_CORE_API RefType : public TensorType { | |||
| class MS_CORE_API RefType final : public TensorType { | |||
| public: | |||
| /// \brief Default constructor for RefType. | |||
| RefType() : TensorType() {} | |||
| @@ -35,7 +35,7 @@ | |||
| namespace mindspore { | |||
| /// \brief UndeterminedType defines interface for tensor undetermined data type. | |||
| class MS_CORE_API UndeterminedType : public Object { | |||
| class MS_CORE_API UndeterminedType final : public Object { | |||
| public: | |||
| /// \brief Default constructor for UndeterminedType. | |||
| UndeterminedType() : Object(kObjectTypeUndeterminedType) {} | |||
| @@ -114,7 +114,7 @@ class MS_CORE_API TensorType : public Object { | |||
| using TensorTypePtr = std::shared_ptr<TensorType>; | |||
| /// \brief RowTensorType defines interface for row tensor data type. | |||
| class MS_CORE_API RowTensorType : public Object { | |||
| class MS_CORE_API RowTensorType final : public Object { | |||
| public: | |||
| /// \brief Default constructor for RowTensorType. | |||
| RowTensorType() : Object(kObjectTypeRowTensorType, kObjectTypeUndeterminedType) {} | |||
| @@ -153,7 +153,7 @@ class MS_CORE_API RowTensorType : public Object { | |||
| using RowTensorTypePtr = std::shared_ptr<RowTensorType>; | |||
| /// \brief SparseTensorType defines interface for sparse tensor data type. | |||
| class MS_CORE_API SparseTensorType : public Object { | |||
| class MS_CORE_API SparseTensorType final : public Object { | |||
| public: | |||
| /// \brief Default constructor for SparseTensorType. | |||
| SparseTensorType() : Object(kObjectTypeSparseTensorType, kObjectTypeUndeterminedType) {} | |||
| @@ -1,5 +1,5 @@ | |||
| /** | |||
| * Copyright 2019 Huawei Technologies Co., Ltd | |||
| * Copyright 2019-2021 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. | |||
| @@ -112,7 +112,7 @@ struct MS_CORE_API NamedEqual { | |||
| } | |||
| }; | |||
| /// \beief None defines interface for none data. | |||
| class MS_CORE_API None : public Named { | |||
| class MS_CORE_API None final : public Named { | |||
| public: | |||
| /// \beief The default constructor for None. | |||
| None() : Named("None") {} | |||
| @@ -124,7 +124,7 @@ class MS_CORE_API None : public Named { | |||
| inline const NamedPtr kNone = std::make_shared<None>(); | |||
| /// \beief Null defines interface for null data. | |||
| class MS_CORE_API Null : public Named { | |||
| class MS_CORE_API Null final : public Named { | |||
| public: | |||
| /// \beief The default constructor for Null. | |||
| Null() : Named("Null") {} | |||
| @@ -136,7 +136,7 @@ class MS_CORE_API Null : public Named { | |||
| inline const NamedPtr kNull = std::make_shared<Null>(); | |||
| /// \beief Ellipsis defines interface for ... data. | |||
| class MS_CORE_API Ellipsis : public Named { | |||
| class MS_CORE_API Ellipsis final : public Named { | |||
| public: | |||
| /// \beief The default constructor for Ellipsis. | |||
| Ellipsis() : Named("Ellipsis") {} | |||
| @@ -63,7 +63,7 @@ class MS_CORE_API Scalar : public Value { | |||
| using ScalarPtr = std::shared_ptr<Scalar>; | |||
| /// \beief BoolImm defines interface for bool data. | |||
| class MS_CORE_API BoolImm : public Scalar { | |||
| class MS_CORE_API BoolImm final : public Scalar { | |||
| public: | |||
| /// \brief The constructor of BoolImm. | |||
| /// | |||
| @@ -120,7 +120,7 @@ class MS_CORE_API IntergerImm : public Scalar { | |||
| }; | |||
| /// \beief Int8Imm defines interface for int8 data. | |||
| class MS_CORE_API Int8Imm : public IntergerImm { | |||
| class MS_CORE_API Int8Imm final : public IntergerImm { | |||
| public: | |||
| /// \beief The default constructor for Int8Imm. | |||
| Int8Imm() : IntergerImm(kInt8), v_(0) {} | |||
| @@ -158,7 +158,7 @@ class MS_CORE_API Int8Imm : public IntergerImm { | |||
| using Int8ImmPtr = std::shared_ptr<Int8Imm>; | |||
| IMM_TRAITS(Int8ImmPtr, int8_t) | |||
| /// \beief Int16Imm defines interface for int16 data. | |||
| class MS_CORE_API Int16Imm : public IntergerImm { | |||
| class MS_CORE_API Int16Imm final : public IntergerImm { | |||
| public: | |||
| /// \beief The default constructor for Int16Imm. | |||
| Int16Imm() : IntergerImm(kInt16), v_(0) {} | |||
| @@ -197,7 +197,7 @@ using Int16ImmPtr = std::shared_ptr<Int16Imm>; | |||
| IMM_TRAITS(Int16ImmPtr, int16_t) | |||
| /// \beief Int32Imm defines interface for int32 data. | |||
| class MS_CORE_API Int32Imm : public IntergerImm { | |||
| class MS_CORE_API Int32Imm final : public IntergerImm { | |||
| public: | |||
| /// \beief The default constructor for Int32Imm. | |||
| Int32Imm() : IntergerImm(kInt32), v_(0) {} | |||
| @@ -236,7 +236,7 @@ using Int32ImmPtr = std::shared_ptr<Int32Imm>; | |||
| IMM_TRAITS(Int32ImmPtr, int32_t) | |||
| /// \beief Int64Imm defines interface for int64 data. | |||
| class MS_CORE_API Int64Imm : public IntergerImm { | |||
| class MS_CORE_API Int64Imm final : public IntergerImm { | |||
| public: | |||
| /// \beief The default constructor for Int64Imm. | |||
| Int64Imm() : IntergerImm(kInt64), v_(0) {} | |||
| @@ -274,7 +274,7 @@ class MS_CORE_API Int64Imm : public IntergerImm { | |||
| using Int64ImmPtr = std::shared_ptr<Int64Imm>; | |||
| IMM_TRAITS(Int64ImmPtr, int64_t) | |||
| /// \beief UInt8Imm defines interface for uint8 data. | |||
| class MS_CORE_API UInt8Imm : public IntergerImm { | |||
| class MS_CORE_API UInt8Imm final : public IntergerImm { | |||
| public: | |||
| /// \beief The default constructor for UInt8Imm. | |||
| UInt8Imm() : IntergerImm(kUInt8), v_(0) {} | |||
| @@ -315,7 +315,7 @@ using UInt8ImmPtr = std::shared_ptr<UInt8Imm>; | |||
| IMM_TRAITS(UInt8ImmPtr, uint8_t); | |||
| /// \beief UInt16Imm defines interface for uint16 data. | |||
| class MS_CORE_API UInt16Imm : public IntergerImm { | |||
| class MS_CORE_API UInt16Imm final : public IntergerImm { | |||
| public: | |||
| /// \beief The default constructor for UInt16Imm. | |||
| UInt16Imm() : IntergerImm(kUInt16), v_(0) {} | |||
| @@ -356,7 +356,7 @@ using UInt16ImmPtr = std::shared_ptr<UInt16Imm>; | |||
| IMM_TRAITS(UInt16ImmPtr, uint16_t); | |||
| /// \beief UInt32Imm defines interface for uint32 data. | |||
| class MS_CORE_API UInt32Imm : public IntergerImm { | |||
| class MS_CORE_API UInt32Imm final : public IntergerImm { | |||
| public: | |||
| /// \beief The default constructor for UInt32Imm. | |||
| UInt32Imm() : IntergerImm(kUInt32), v_(0) {} | |||
| @@ -396,7 +396,7 @@ class MS_CORE_API UInt32Imm : public IntergerImm { | |||
| using UInt32ImmPtr = std::shared_ptr<UInt32Imm>; | |||
| IMM_TRAITS(UInt32ImmPtr, uint32_t); | |||
| /// \beief UInt64Imm defines interface for uint64 data. | |||
| class MS_CORE_API UInt64Imm : public IntergerImm { | |||
| class MS_CORE_API UInt64Imm final : public IntergerImm { | |||
| public: | |||
| /// \beief The default constructor for UInt64Imm. | |||
| UInt64Imm() : IntergerImm(kUInt64), v_(0) {} | |||
| @@ -451,7 +451,7 @@ class MS_CORE_API FloatImm : public Scalar { | |||
| using FloatImmPtr = std::shared_ptr<FloatImm>; | |||
| /// \beief FP32Imm defines interface for float32 data. | |||
| class MS_CORE_API FP32Imm : public FloatImm { | |||
| class MS_CORE_API FP32Imm final : public FloatImm { | |||
| public: | |||
| /// \beief The default constructor for FP32Imm. | |||
| FP32Imm() : FloatImm(kFloat32), v_(0.0) {} | |||
| @@ -489,7 +489,7 @@ class MS_CORE_API FP32Imm : public FloatImm { | |||
| using FP32ImmPtr = std::shared_ptr<FP32Imm>; | |||
| IMM_TRAITS(FP32ImmPtr, float) | |||
| /// \beief FP64Imm defines interface for float64 data. | |||
| class MS_CORE_API FP64Imm : public FloatImm { | |||
| class MS_CORE_API FP64Imm final : public FloatImm { | |||
| public: | |||
| /// \beief The default constructor for FP64Imm. | |||
| FP64Imm() : FloatImm(kFloat64), v_(0.0) {} | |||
| @@ -139,7 +139,7 @@ class WaitEvent : public ExceptionListener { | |||
| }; | |||
| // Tensor entity class | |||
| class MS_CORE_API Tensor : public MetaTensor { | |||
| class MS_CORE_API Tensor final : public MetaTensor { | |||
| public: | |||
| abstract::AbstractBasePtr ToAbstract() override; | |||
| @@ -376,7 +376,7 @@ class MS_CORE_API ValueDictionary : public Value { | |||
| using ValueDictionaryPtr = std::shared_ptr<ValueDictionary>; | |||
| /// \brief StringImm defines a Value class whose type is String. | |||
| class MS_CORE_API StringImm : public Value { | |||
| class MS_CORE_API StringImm final : public Value { | |||
| public: | |||
| /// \brief Constructor of StringImm. | |||
| /// | |||
| @@ -505,7 +505,7 @@ class MS_CORE_API Monad : public Value { | |||
| }; | |||
| /// \brief UMonad defines a Value class which related to memory side effect. | |||
| class MS_CORE_API UMonad : public Monad { | |||
| class MS_CORE_API UMonad final : public Monad { | |||
| public: | |||
| /// \brief Constructor of UMonad. | |||
| UMonad() : Monad(kUMonadType) {} | |||
| @@ -534,7 +534,7 @@ using UMonadPtr = std::shared_ptr<UMonad>; | |||
| extern const ValuePtr kUMonad; | |||
| /// \brief IOMonad defines a Value class which related to IO side effect. | |||
| class MS_CORE_API IOMonad : public Monad { | |||
| class MS_CORE_API IOMonad final : public Monad { | |||
| public: | |||
| /// \brief Constructor of IOMonad. | |||
| IOMonad() : Monad(kIOMonadType) {} | |||
| @@ -50,5 +50,15 @@ struct PointerHash<std::shared_ptr<T>> { | |||
| } | |||
| }; | |||
| // Generate hash code for a string literal at compile time. | |||
| // We using Java string hash algorithm here. | |||
| constexpr uint32_t ConstStringHash(const char *str) { | |||
| uint32_t hash = 0; | |||
| while (*str) { | |||
| hash = hash * 31 + static_cast<uint32_t>(*str++); | |||
| } | |||
| return hash; | |||
| } | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CORE_UTILS_HASHING_H_ | |||
| @@ -0,0 +1,38 @@ | |||
| #!/bin/bash | |||
| SCRIPT_DIR=$(dirname "$0") | |||
| MS_DIR=$(realpath ${SCRIPT_DIR}/..) | |||
| BUILD_DIR=${MS_DIR}/build | |||
| HASH_EXE=${BUILD_DIR}/gentid | |||
| HASH_SRC=${BUILD_DIR}/gentid.cc | |||
| mkdir -p ${BUILD_DIR} | |||
| echo "#include <iostream>" > ${HASH_SRC} | |||
| echo "#include \"${MS_DIR}/mindspore/core/utils/hashing.h\"" >> ${HASH_SRC} | |||
| echo "int main(int argc, char *argv[0]) { std::cout << mindspore::ConstStringHash(argv[1]) << std::endl; }" >> ${HASH_SRC} | |||
| g++ -std=c++17 -o ${HASH_EXE} ${HASH_SRC} | |||
| BASE_TID=$(${HASH_EXE} Base) | |||
| declare -A TIDMAP=( [${BASE_TID}]=Base ) | |||
| grep -r MS_DECLARE_PARENT --include=*.h --include=*.cc ${MS_DIR} | while read line | |||
| do | |||
| #echo $line | |||
| if [[ "$line" =~ .*\((.*)\,(.*)\).* ]] | |||
| then | |||
| CLASS_NAME=${BASH_REMATCH[2]}_${BASH_REMATCH[1]} | |||
| TID=$(${HASH_EXE} ${CLASS_NAME}) | |||
| if [ ${TIDMAP[${TID}]+_} ]; then | |||
| echo $line | |||
| echo Same tid $TID is used by $CLASS_NAME and ${TIDMAP[${TID}]}. | |||
| exit 1 | |||
| fi | |||
| TIDMAP[${TID}]=${CLASS_NAME} | |||
| echo ${TID} ${CLASS_NAME} | |||
| fi | |||
| done | |||
| if [ $? != 0 ];then | |||
| echo 'Check tid failed!' | |||
| exit 1 | |||
| fi | |||
| echo 'All tids are unique, check tid ok.' | |||