Add more to MindAPI

1. `TensorType` and `TensorTypePtr`;
2. `utils::isa<TensorTypePtr>()`;
3. `utils::isa<int64_t>()`, `utils::cast<int64_t>()`;
4. `GetValue<ValuePtrList>(value)`.
This commit is contained in:
He Wei 2021-12-08 16:36:04 +08:00
parent 0edcd5ce74
commit f35554d0c6
6 changed files with 95 additions and 13 deletions

View File

@ -27,6 +27,7 @@ using AnfNodePtrList = std::vector<AnfNodePtr>;
class Value;
using ValuePtr = SharedPtr<Value>;
using ValuePtrList = std::vector<ValuePtr>;
class Primitive;
using PrimitivePtr = SharedPtr<Primitive>;

View File

@ -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<TensorType>;
} // namespace mindspore::api
#endif // MINDSPORE_CORE_MINDAPI_IR_TYPE_H_

View File

@ -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 <typename T, typename = typename std::enable_if_t<std::is_base_of_v<Base, T>, T>>
bool isa(const BasePtr &ptr) {
template <typename T, typename = typename std::enable_if_t<std::is_base_of_v<Base, T> || is_wrapper_ptr<T>::value>>
inline bool isa(const BasePtr &ptr) {
if (ptr == nullptr) {
return false;
}
return ptr->isa<T>();
if constexpr (is_wrapper_ptr<T>::value) {
return ptr->isa<typename T::element_type>();
} else {
return ptr->isa<T>();
}
}
/// \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 <typename T, typename U = typename ImmTrait<T>::type::element_type>
inline bool isa(const ValuePtr &ptr) {
if (ptr == nullptr) {
return false;
}
return ptr->isa<U>();
}
/// \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 <typename T, typename = typename std::enable_if_t<is_wrapper_ptr<T>::value, T>>
T cast(const BasePtr &ptr) {
inline T cast(const BasePtr &ptr) {
if (ptr == nullptr) {
return nullptr;
}
return ptr->cast<T>();
}
/// \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 <typename T, typename U = typename ImmTrait<T>::type>
inline T cast(const ValuePtr &ptr) {
return GetValue<T>(ptr);
}
/// \brief Make a copy from the given function graph.
///
/// \param[in] func_graph The graph to be cloned.

View File

@ -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 T, typename S = typename std::decay_t<T>,
typename U = typename std::enable_if_t<is_vector<S>::value, typename S::value_type>>
inline std::vector<U> GetValue(const ValuePtr &value) {
@ -258,13 +258,17 @@ inline std::vector<U> GetValue(const ValuePtr &value) {
if (seq == nullptr) {
return {};
}
auto elements = seq->value();
std::vector<U> result;
result.reserve(elements.size());
for (auto &e : elements) {
result.emplace_back(GetValue<U>(e));
if constexpr (std::is_same_v<ValuePtr, U>) {
return seq->value();
} else {
auto elements = seq->value();
std::vector<U> result;
result.reserve(elements.size());
for (auto &e : elements) {
result.emplace_back(GetValue<U>(e));
}
return result;
}
return result;
}
} // namespace mindspore::api
#endif // MINDSPORE_CORE_MINDAPI_IR_VALUE_H_

View File

@ -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<TensorTypeImpl>(ToImpl<TypeImpl>(element_type))) {}
TypePtr TensorType::element() const {
auto element_type_impl = ToRef<TensorTypeImpl>(impl_).element();
return ToWrapper<Type>(element_type_impl);
}
} // namespace mindspore::api

View File

@ -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<ValuePtrList>(seq);
ASSERT_EQ(value_list.size(), 3);
ASSERT_EQ(utils::cast<int64_t>(value_list[0]), 3);
ASSERT_EQ(utils::cast<int64_t>(value_list[1]), 4);
ASSERT_EQ(utils::cast<int64_t>(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<TensorType>(Type::GetType(TypeId::kNumberTypeFloat32));
ASSERT_TRUE(tensor_type->isa<TensorType>());
ASSERT_EQ(tensor_type->cast<TensorTypePtr>()->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<AnfNode>(anf_node));
ASSERT_TRUE(utils::isa<AnfNodePtr>(anf_node));
ASSERT_FALSE(utils::isa<AbstractBase>(anf_node));
ASSERT_TRUE(utils::cast<AnfNodePtr>(anf_node) != nullptr);
ASSERT_TRUE(utils::cast<AbstractBasePtr>(anf_node) == nullptr);
ASSERT_TRUE(utils::isa<std::string>(anf_node->value()));
ASSERT_EQ(utils::cast<std::string>(anf_node->value()), "hello");
auto int_value = MakeValue(123);
ASSERT_TRUE(utils::isa<int64_t>(int_value));
ASSERT_EQ(utils::cast<int64_t>(int_value), 123);
anf_node = nullptr;
ASSERT_FALSE(utils::isa<AnfNode>(anf_node));
ASSERT_FALSE(utils::isa<AnfNodePtr>(anf_node));
ASSERT_TRUE(utils::cast<AnfNodePtr>(anf_node) == nullptr);
// Test clone graph.