From f35554d0c6d0eb5d39d3d5f70443368edce5697d Mon Sep 17 00:00:00 2001 From: He Wei Date: Wed, 8 Dec 2021 16:36:04 +0800 Subject: [PATCH] Add more to MindAPI 1. `TensorType` and `TensorTypePtr`; 2. `utils::isa()`; 3. `utils::isa()`, `utils::cast()`; 4. `GetValue(value)`. --- mindspore/core/mindapi/ir/common.h | 1 + mindspore/core/mindapi/ir/type.h | 19 +++++++++++++++ mindspore/core/mindapi/ir/utils.h | 35 ++++++++++++++++++++++++---- mindspore/core/mindapi/ir/value.h | 20 +++++++++------- mindspore/core/mindapi/src/type.cc | 14 ++++++++++- tests/ut/cpp/mindapi/mindapi_test.cc | 19 +++++++++++++++ 6 files changed, 95 insertions(+), 13 deletions(-) diff --git a/mindspore/core/mindapi/ir/common.h b/mindspore/core/mindapi/ir/common.h index aa0c7a3f7cc..c346c1654a3 100644 --- a/mindspore/core/mindapi/ir/common.h +++ b/mindspore/core/mindapi/ir/common.h @@ -27,6 +27,7 @@ using AnfNodePtrList = std::vector; class Value; using ValuePtr = SharedPtr; +using ValuePtrList = std::vector; class Primitive; using PrimitivePtr = SharedPtr; diff --git a/mindspore/core/mindapi/ir/type.h b/mindspore/core/mindapi/ir/type.h index e314254fccd..e5fce01af96 100644 --- a/mindspore/core/mindapi/ir/type.h +++ b/mindspore/core/mindapi/ir/type.h @@ -52,5 +52,24 @@ class MIND_API Type : public Value { /// \return The data size in bytes for the Type. static size_t GetSize(TypeId id); }; + +/// \brief TensorType defines the type of a tensor. +class MIND_API TensorType : public Type { + public: + MIND_API_BASE_MEMBER(TensorType); + + /// \brief Construct TensorType from the given element type. + /// + /// \param[in] element_type The element type of the TensorType. + explicit TensorType(const TypePtr &element_type); + + /// \brief Get the element type of this TensorType. + /// + /// \return The element type of this TensorType. + TypePtr element() const; +}; + +using TensorTypePtr = SharedPtr; } // namespace mindspore::api + #endif // MINDSPORE_CORE_MINDAPI_IR_TYPE_H_ diff --git a/mindspore/core/mindapi/ir/utils.h b/mindspore/core/mindapi/ir/utils.h index 4714baa38dc..1e88b6b703d 100644 --- a/mindspore/core/mindapi/ir/utils.h +++ b/mindspore/core/mindapi/ir/utils.h @@ -30,12 +30,29 @@ namespace mindspore::api::utils { /// \param[in] ptr The pointer to the given object. /// /// \return True if the pointer is not null and the object is an instance of the given class, false otherwise. -template , T>> -bool isa(const BasePtr &ptr) { +template || is_wrapper_ptr::value>> +inline bool isa(const BasePtr &ptr) { if (ptr == nullptr) { return false; } - return ptr->isa(); + if constexpr (is_wrapper_ptr::value) { + return ptr->isa(); + } else { + return ptr->isa(); + } +} + +/// \brief Check whether the given object is an value of the given c++ type T. +/// +/// \param[in] ptr The pointer to the given value object. +/// +/// \return True if the pointer is not null and it is an value of the given c++ type, false otherwise. +template ::type::element_type> +inline bool isa(const ValuePtr &ptr) { + if (ptr == nullptr) { + return false; + } + return ptr->isa(); } /// \brief Cast the given object pointer to a pointer with the given class. @@ -44,13 +61,23 @@ bool isa(const BasePtr &ptr) { /// /// \return A non-null pointer if the input pointer is not null and cast success, nullptr otherwise. template ::value, T>> -T cast(const BasePtr &ptr) { +inline T cast(const BasePtr &ptr) { if (ptr == nullptr) { return nullptr; } return ptr->cast(); } +/// \brief Cast the given value to a C++ value. +/// +/// \param[in] ptr The pointer to the value to be casted. +/// +/// \return The C++ value according the input value. +template ::type> +inline T cast(const ValuePtr &ptr) { + return GetValue(ptr); +} + /// \brief Make a copy from the given function graph. /// /// \param[in] func_graph The graph to be cloned. diff --git a/mindspore/core/mindapi/ir/value.h b/mindspore/core/mindapi/ir/value.h index 70954999ad1..cdbcf6dddf1 100644 --- a/mindspore/core/mindapi/ir/value.h +++ b/mindspore/core/mindapi/ir/value.h @@ -243,11 +243,11 @@ inline T GetValue(const ValuePtr &value) { return imm->value(); } -/// \brief brief Get primitive element values from a ValueSequence object. +/// \brief brief Get element values from a ValueSequence object. /// /// \param[in] value The pointer to the ValueSequence object. /// -/// \return The primitive type values as a vector. +/// \return The values as a vector, empty if the input is not a ValueSequence. template , typename U = typename std::enable_if_t::value, typename S::value_type>> inline std::vector GetValue(const ValuePtr &value) { @@ -258,13 +258,17 @@ inline std::vector GetValue(const ValuePtr &value) { if (seq == nullptr) { return {}; } - auto elements = seq->value(); - std::vector result; - result.reserve(elements.size()); - for (auto &e : elements) { - result.emplace_back(GetValue(e)); + if constexpr (std::is_same_v) { + return seq->value(); + } else { + auto elements = seq->value(); + std::vector result; + result.reserve(elements.size()); + for (auto &e : elements) { + result.emplace_back(GetValue(e)); + } + return result; } - return result; } } // namespace mindspore::api #endif // MINDSPORE_CORE_MINDAPI_IR_VALUE_H_ diff --git a/mindspore/core/mindapi/src/type.cc b/mindspore/core/mindapi/src/type.cc index b8dcb677f63..9604d0bf7b7 100644 --- a/mindspore/core/mindapi/src/type.cc +++ b/mindspore/core/mindapi/src/type.cc @@ -17,12 +17,14 @@ #include "mindapi/ir/type.h" #include "mindapi/ir/value.h" #include "mindapi/src/helper.h" -#include "ir/dtype/type.h" #include "ir/dtype.h" +#include "ir/dtype/type.h" +#include "ir/dtype/tensor_type.h" #include "abstract/utils.h" namespace mindspore::api { using TypeImpl = mindspore::Type; +using TensorTypeImpl = mindspore::TensorType; MIND_API_BASE_IMPL(Type, TypeImpl, Value); @@ -36,4 +38,14 @@ TypePtr Type::GetType(TypeId id) { } size_t Type::GetSize(TypeId id) { return mindspore::abstract::TypeIdSize(id); } + +MIND_API_BASE_IMPL(TensorType, TensorTypeImpl, Type); + +TensorType::TensorType(const TypePtr &element_type) + : Type(std::make_shared(ToImpl(element_type))) {} + +TypePtr TensorType::element() const { + auto element_type_impl = ToRef(impl_).element(); + return ToWrapper(element_type_impl); +} } // namespace mindspore::api diff --git a/tests/ut/cpp/mindapi/mindapi_test.cc b/tests/ut/cpp/mindapi/mindapi_test.cc index 32bf32f5a70..ebe9355d68d 100644 --- a/tests/ut/cpp/mindapi/mindapi_test.cc +++ b/tests/ut/cpp/mindapi/mindapi_test.cc @@ -135,6 +135,12 @@ TEST_F(TestMindApi, test_values) { ASSERT_EQ(str_values[1], "is"); ASSERT_EQ(str_values[2], "mindspore"); ASSERT_EQ(str_values[3], "api"); + + auto value_list = GetValue(seq); + ASSERT_EQ(value_list.size(), 3); + ASSERT_EQ(utils::cast(value_list[0]), 3); + ASSERT_EQ(utils::cast(value_list[1]), 4); + ASSERT_EQ(utils::cast(value_list[2]), 5); } /// Feature: MindAPI @@ -325,6 +331,11 @@ TEST_F(TestMindApi, test_tensor_api) { tensor->set_shape(shape2); ASSERT_EQ(tensor->data_type(), kNumberTypeInt32); ASSERT_EQ(tensor->shape(), shape2); + + // TensorType. + TypePtr tensor_type = MakeShared(Type::GetType(TypeId::kNumberTypeFloat32)); + ASSERT_TRUE(tensor_type->isa()); + ASSERT_EQ(tensor_type->cast()->element()->type_id(), kNumberTypeFloat32); } /// Feature: MindAPI @@ -334,12 +345,20 @@ TEST_F(TestMindApi, test_api_utils) { // Test utils::isa, utils::cast. auto anf_node = NewValueNode("hello"); ASSERT_TRUE(utils::isa(anf_node)); + ASSERT_TRUE(utils::isa(anf_node)); ASSERT_FALSE(utils::isa(anf_node)); ASSERT_TRUE(utils::cast(anf_node) != nullptr); ASSERT_TRUE(utils::cast(anf_node) == nullptr); + ASSERT_TRUE(utils::isa(anf_node->value())); + ASSERT_EQ(utils::cast(anf_node->value()), "hello"); + + auto int_value = MakeValue(123); + ASSERT_TRUE(utils::isa(int_value)); + ASSERT_EQ(utils::cast(int_value), 123); anf_node = nullptr; ASSERT_FALSE(utils::isa(anf_node)); + ASSERT_FALSE(utils::isa(anf_node)); ASSERT_TRUE(utils::cast(anf_node) == nullptr); // Test clone graph.