diff --git a/cmake/package_lite.cmake b/cmake/package_lite.cmake index 426e5a1b5d2..3538343c678 100644 --- a/cmake/package_lite.cmake +++ b/cmake/package_lite.cmake @@ -221,6 +221,8 @@ if(PLATFORM_ARM64) endif() install(FILES ${TOP_DIR}/mindspore/core/ir/dtype/type_id.h DESTINATION ${RUNTIME_INC_DIR}/ir/dtype COMPONENT ${RUNTIME_COMPONENT_NAME}) + install(FILES ${TOP_DIR}/mindspore/core/mindapi/base/type_id.h DESTINATION ${RUNTIME_INC_DIR}/mindapi/base + COMPONENT ${RUNTIME_COMPONENT_NAME}) install(DIRECTORY ${TOP_DIR}/include/api/ DESTINATION ${RUNTIME_INC_DIR}/api COMPONENT ${RUNTIME_COMPONENT_NAME} FILES_MATCHING PATTERN "*.h" PATTERN "ops*" EXCLUDE) install(DIRECTORY ${TOP_DIR}/include/c_api/ DESTINATION ${RUNTIME_INC_DIR}/c_api @@ -298,6 +300,8 @@ elseif(PLATFORM_ARM32) endif() install(FILES ${TOP_DIR}/mindspore/core/ir/dtype/type_id.h DESTINATION ${RUNTIME_INC_DIR}/ir/dtype COMPONENT ${RUNTIME_COMPONENT_NAME}) + install(FILES ${TOP_DIR}/mindspore/core/mindapi/base/type_id.h DESTINATION ${RUNTIME_INC_DIR}/mindapi/base + COMPONENT ${RUNTIME_COMPONENT_NAME}) install(DIRECTORY ${TOP_DIR}/include/api/ DESTINATION ${RUNTIME_INC_DIR}/api COMPONENT ${RUNTIME_COMPONENT_NAME} FILES_MATCHING PATTERN "*.h" PATTERN "ops*" EXCLUDE) install(DIRECTORY ${TOP_DIR}/include/c_api/ DESTINATION ${RUNTIME_INC_DIR}/c_api @@ -365,6 +369,8 @@ elseif(WIN32) COMPONENT ${RUNTIME_COMPONENT_NAME}) install(FILES ${TOP_DIR}/mindspore/core/ir/dtype/type_id.h DESTINATION ${RUNTIME_INC_DIR}/ir/dtype COMPONENT ${RUNTIME_COMPONENT_NAME}) + install(FILES ${TOP_DIR}/mindspore/core/mindapi/base/type_id.h DESTINATION ${RUNTIME_INC_DIR}/mindapi/base + COMPONENT ${RUNTIME_COMPONENT_NAME}) install(DIRECTORY ${TOP_DIR}/include/api/ DESTINATION ${RUNTIME_INC_DIR}/api COMPONENT ${RUNTIME_COMPONENT_NAME} FILES_MATCHING PATTERN "*.h" PATTERN "ops*" EXCLUDE) install(DIRECTORY ${TOP_DIR}/include/c_api/ DESTINATION ${RUNTIME_INC_DIR}/c_api @@ -409,6 +415,8 @@ else() COMPONENT ${RUNTIME_COMPONENT_NAME}) install(FILES ${TOP_DIR}/mindspore/core/ir/dtype/type_id.h DESTINATION ${RUNTIME_INC_DIR}/ir/dtype COMPONENT ${RUNTIME_COMPONENT_NAME}) + install(FILES ${TOP_DIR}/mindspore/core/mindapi/base/type_id.h DESTINATION ${RUNTIME_INC_DIR}/mindapi/base + COMPONENT ${RUNTIME_COMPONENT_NAME}) install(DIRECTORY ${TOP_DIR}/include/api/ DESTINATION ${RUNTIME_INC_DIR}/api COMPONENT ${RUNTIME_COMPONENT_NAME} FILES_MATCHING PATTERN "*.h" PATTERN "ops*" EXCLUDE) install(DIRECTORY ${TOP_DIR}/include/c_api/ DESTINATION ${RUNTIME_INC_DIR}/c_api @@ -430,6 +438,10 @@ else() PATTERN "train*" EXCLUDE PATTERN "delegate.h" EXCLUDE PATTERN "lite_session.h" EXCLUDE) install(FILES ${API_HEADER} DESTINATION ${CONVERTER_ROOT_DIR}/include/api COMPONENT ${RUNTIME_COMPONENT_NAME}) + install(FILES ${MINDAPI_BASE_HEADER} DESTINATION ${CONVERTER_ROOT_DIR}/include/core/mindapi/base + COMPONENT ${RUNTIME_COMPONENT_NAME}) + install(FILES ${MINDAPI_IR_HEADER} DESTINATION ${CONVERTER_ROOT_DIR}/include/core/mindapi/ir + COMPONENT ${RUNTIME_COMPONENT_NAME}) install(FILES ${ABSTRACT_HEADER} DESTINATION ${CONVERTER_ROOT_DIR}/include/core/abstract COMPONENT ${RUNTIME_COMPONENT_NAME}) install(FILES ${API_IR_HEADER} DESTINATION ${CONVERTER_ROOT_DIR}/include/core/api/ir diff --git a/mindspore/core/CMakeLists.txt b/mindspore/core/CMakeLists.txt index 3cc9b6ffa7c..e054c65a6a0 100644 --- a/mindspore/core/CMakeLists.txt +++ b/mindspore/core/CMakeLists.txt @@ -23,6 +23,7 @@ file(GLOB_RECURSE CORE_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "ir/*.cc" "utils/*.cc" "load_mindir/*.cc" + "mindapi/src/*.cc" ) if(ENABLE_SECURITY) diff --git a/mindspore/core/api/ir/func_graph.h b/mindspore/core/api/ir/func_graph.h index 5e5927aabc2..a5dfdd82eda 100644 --- a/mindspore/core/api/ir/func_graph.h +++ b/mindspore/core/api/ir/func_graph.h @@ -24,8 +24,7 @@ #include "utils/visible.h" #include "api/ir/func_graph_manager.h" -namespace mindspore::api { - +namespace mindspore::deprecated::api { /// \brief FuncGraph defines interface for a function graph. class MS_CORE_API FuncGraph { public: @@ -147,5 +146,12 @@ class MS_CORE_API FuncGraph { /// \return The function graph if the input is value node that holds the graph, nullptr otherwise. static FuncGraphPtr GetFuncGraphFromAnfNode(const AnfNodePtr &input); }; -} // namespace mindspore::api + +#ifndef USE_DEPRECATED_API +#define USE_DEPRECATED_API +namespace mindspore { +namespace api = deprecated::api; +} +#endif +} // namespace mindspore::deprecated::api #endif // MINDSPORE_CORE_API_IR_FUNC_GRAPH_H_ diff --git a/mindspore/core/api/ir/func_graph_manager.h b/mindspore/core/api/ir/func_graph_manager.h index 6d64112ffa6..b8697a01429 100644 --- a/mindspore/core/api/ir/func_graph_manager.h +++ b/mindspore/core/api/ir/func_graph_manager.h @@ -26,8 +26,7 @@ #include "utils/hashing.h" #include "ir/anf.h" -namespace mindspore::api { - +namespace mindspore::deprecated::api { class FuncGraph; using FuncGraphPtr = std::shared_ptr; @@ -80,7 +79,13 @@ class MS_CORE_API FuncGraphManager { /// \return The manager that manages the given function graph. static FuncGraphManagerPtr Manage(const FuncGraphPtr &func_graph, bool manage = true); }; +} // namespace mindspore::deprecated::api -} // namespace mindspore::api +#ifndef USE_DEPRECATED_API +#define USE_DEPRECATED_API +namespace mindspore { +namespace api = deprecated::api; +} +#endif #endif // MINDSPORE_CORE_API_IR_FUNC_GRAPH_MANAGER_H_ diff --git a/mindspore/core/gvar/log_adapter_common.cc b/mindspore/core/gvar/log_adapter_common.cc index 1c4312afddd..402c4117516 100644 --- a/mindspore/core/gvar/log_adapter_common.cc +++ b/mindspore/core/gvar/log_adapter_common.cc @@ -52,6 +52,7 @@ static const std::vector sub_module_names = { "HCCL_ADPT", // SM_HCCL_ADPT "RUNTIME_FRAMEWORK", // SM_RUNTIME_FRAMEWORK "GE", // SM_GE + "API", // SM_API }; const std::string GetSubModuleName(SubModuleId module_id) { return sub_module_names[(module_id % NUM_SUBMODUES)]; } diff --git a/mindspore/core/ir/dtype/type_id.h b/mindspore/core/ir/dtype/type_id.h index a9268d05c91..fb1670fec00 100644 --- a/mindspore/core/ir/dtype/type_id.h +++ b/mindspore/core/ir/dtype/type_id.h @@ -1,7 +1,7 @@ /** * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). * - * 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. @@ -19,87 +19,6 @@ #ifndef MINDSPORE_CORE_IR_DTYPE_TYPE_ID_H_ #define MINDSPORE_CORE_IR_DTYPE_TYPE_ID_H_ -namespace mindspore { -// -// Supported meta type -// -enum TypeId : int { - kTypeUnknown = 0, - kMetaTypeBegin = kTypeUnknown, - kMetaTypeType, // Type - kMetaTypeAnything, - kMetaTypeObject, - kMetaTypeTypeType, // TypeType - kMetaTypeProblem, - kMetaTypeExternal, - kMetaTypeNone, - kMetaTypeNull, - kMetaTypeEllipsis, - kMetaTypeEnd, - // - // Object types - // - kObjectTypeBegin = kMetaTypeEnd, - kObjectTypeNumber, - kObjectTypeString, - kObjectTypeList, - kObjectTypeTuple, - kObjectTypeSlice, - kObjectTypeKeyword, - kObjectTypeTensorType, - kObjectTypeRowTensorType, - kObjectTypeSparseTensorType, - kObjectTypeUndeterminedType, - kObjectTypeClass, - kObjectTypeDictionary, - kObjectTypeFunction, - kObjectTypeJTagged, - kObjectTypeSymbolicKeyType, - kObjectTypeEnvType, - kObjectTypeRefKey, - kObjectTypeRef, - kObjectTypeEnd, - // - // Number Types - // - kNumberTypeBegin = kObjectTypeEnd, - kNumberTypeBool, - kNumberTypeInt, - kNumberTypeInt8, - kNumberTypeInt16, - kNumberTypeInt32, - kNumberTypeInt64, - kNumberTypeUInt, - kNumberTypeUInt8, - kNumberTypeUInt16, - kNumberTypeUInt32, - kNumberTypeUInt64, - kNumberTypeFloat, - kNumberTypeFloat16, - kNumberTypeFloat32, - kNumberTypeFloat64, - kNumberTypeComplex, - kNumberTypeComplex64, - kNumberTypeComplex128, - kNumberTypeInt4, - kNumberTypeGLUInt, - kNumberTypeEnd, - // - // Monad Types - // - kMonadTypeBegin = kNumberTypeEnd, - kObjectTypeMonad, - kObjectTypeUMonad, - kObjectTypeIOMonad, - kMonadTypeEnd, - // - // Sparse Types - // - // Sparse types is placed at the end of enum, - // in order to keep fit with the type of existing model on the lite side. - kSparseTypeBegin = kMonadTypeEnd, - kObjectTypeCSRTensorType, - kSparseTypeEnd -}; -} // namespace mindspore +#include "mindapi/base/type_id.h" + #endif // MINDSPORE_CORE_IR_DTYPE_TYPE_ID_H_ diff --git a/mindspore/core/ir/func_graph.h b/mindspore/core/ir/func_graph.h index d318d335dd5..62974c36feb 100644 --- a/mindspore/core/ir/func_graph.h +++ b/mindspore/core/ir/func_graph.h @@ -153,7 +153,7 @@ class FuncGraphBase : public Value { MS_DECLARE_PARENT(FuncGraphBase, Value); }; -class FuncGraph : public api::FuncGraph, public FuncGraphBase, public EffectInfoHolder { +class FuncGraph : public deprecated::api::FuncGraph, public FuncGraphBase, public EffectInfoHolder { public: using Drawer = std::function; @@ -265,7 +265,7 @@ class FuncGraph : public api::FuncGraph, public FuncGraphBase, public EffectInfo FuncGraphManagerPtr manager() const { return manager_.lock(); } void set_manager(const FuncGraphManagerPtr &m) { manager_ = std::weak_ptr(m); } - api::FuncGraphManagerPtr get_manager() const final { return manager_.lock(); } + deprecated::api::FuncGraphManagerPtr get_manager() const final { return manager_.lock(); } std::string ToString() const override; GraphDebugInfoPtr debug_info(); diff --git a/mindspore/core/ir/manager.h b/mindspore/core/ir/manager.h index 6e7f5f536f0..2ff904e1f4f 100644 --- a/mindspore/core/ir/manager.h +++ b/mindspore/core/ir/manager.h @@ -55,9 +55,9 @@ class FuncGraphTransaction; class FuncGraphManager; using FuncGraphManagerPtr = std::shared_ptr; -using AnfNodeIndexSet = api::AnfNodeIndexSet; +using AnfNodeIndexSet = deprecated::api::AnfNodeIndexSet; // NodeUsersMap, for node B input i use node A, it will be one item in map with key: A, and value: (B, i) -using NodeUsersMap = api::NodeUsersMap; +using NodeUsersMap = deprecated::api::NodeUsersMap; using FuncGraphSetPair = std::pair; using FuncGraphSetPtr = std::shared_ptr; @@ -277,7 +277,8 @@ class FuncGraphJTotalComputer final : public DepComputer { bool SeekJ(const FuncGraphPtr &fg, size_t seen_num); }; -class FuncGraphManager : public std::enable_shared_from_this, public api::FuncGraphManager { +class FuncGraphManager : public std::enable_shared_from_this, + public deprecated::api::FuncGraphManager { public: explicit FuncGraphManager(const std::vector &roots, bool manage = true); ~FuncGraphManager() { diff --git a/mindspore/core/mindapi/base/base.h b/mindspore/core/mindapi/base/base.h new file mode 100644 index 00000000000..4ed554bd1fd --- /dev/null +++ b/mindspore/core/mindapi/base/base.h @@ -0,0 +1,89 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_BASE_BASE_H_ +#define MINDSPORE_CORE_MINDAPI_BASE_BASE_H_ + +#include +#include +#include +#include "mindapi/base/macros.h" +#include "mindapi/base/type_traits.h" +#include "mindapi/base/shared_ptr.h" + +namespace mindspore { +class Base; +} + +namespace mindspore::api { +/// \brief Base is the base class of many api classes, which provides basic interfaces. +class MIND_API Base { + public: + /// \brief Create an instance from the given implementation object. + /// + /// \param[in] impl The shared_ptr to the implementation object. + explicit Base(const std::shared_ptr &impl); + + /// \brief Destructor of Base. + virtual ~Base() = default; + + /// \brief Get the id of this class. + /// + /// \return The id of this class. + static uint32_t ClassId(); + + /// \brief Get the shared_ptr to the underly implementation object. + /// + /// \return The shared_ptr to the underly implementation object. + const std::shared_ptr &impl() const { return impl_; } + + /// \brief Get the string representation of this object. + /// + /// \return The string representation. + std::string ToString() const; + + /// \brief Check whether this object is an instance of the given class. + /// + /// \return True if this object is an instance of the given class, false otherwise. + template , T>> + inline bool isa() const { + return IsFromClassId(T::ClassId()); + } + + /// \brief Cast this object to a pointer with the given pointer class. + /// + /// \return A non-null pointer if cast success, nullptr otherwise. + template ::value, typename T::element_type>> + inline T cast() { + if (isa()) { + return MakeShared(impl_); + } + return nullptr; + } + + protected: + bool IsFromClassId(uint32_t class_id) const; + const std::shared_ptr impl_; +}; + +#define MIND_API_BASE_MEMBER(current_class) \ + explicit current_class(const std::shared_ptr &impl); \ + ~current_class() override = default; \ + static uint32_t ClassId() + +using BasePtr = SharedPtr; +} // namespace mindspore::api +#endif // MINDSPORE_CORE_MINDAPI_BASE_BASE_H_ diff --git a/mindspore/core/mindapi/base/logging.h b/mindspore/core/mindapi/base/logging.h new file mode 100644 index 00000000000..79b82afd083 --- /dev/null +++ b/mindspore/core/mindapi/base/logging.h @@ -0,0 +1,104 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_BASE_LOGGING_H_ +#define MINDSPORE_CORE_MINDAPI_BASE_LOGGING_H_ + +#include +#include +#include +#include +#include "mindapi/base/macros.h" + +namespace mindspore::api { +enum class LogLevel : uint8_t { DEBUG = 0, INFO, WARNING, ERROR, EXCEPTION }; + +class LogWriterImpl; + +/// \brief LogStream represents a stream to write log messages. +/// This class is not expected for directly use, use MS_LOG instead. +class LogStream { + public: + /// \brief Write log message to this LogStream. + /// + /// \param[in] value The object to be written. + template + LogStream &operator<<(T &&value) noexcept { + (void)stream_.operator<<(std::forward(value)); + return *this; + } + + private: + friend class LogWriterImpl; + std::stringstream stream_; +}; + +/// \brief LogWriter defines interface for log message output. +/// This class is not expected for directly use, use MS_LOG instead. +class MIND_API LogWriter { + public: + /// \brief Create a LogWriter with the given log level, file name, line number and function name. + /// + /// \param[in] level The log level. + /// \param[in] file The file name. + /// \param[in] line The line number. + /// \param[in] func The function name. + LogWriter(LogLevel level, const char *file, int line, const char *func); + + /// \brief Destructor for LogWriter. + ~LogWriter(); + + /// \brief Output log message from the input log stream. + /// + /// \param[in] stream The input log stream. + void operator<(const LogStream &stream) const noexcept; + + /// \brief Output log message from the input log stream and then throw exception. + /// + /// \param[in] stream The input log stream. + void operator^(const LogStream &stream) const __attribute__((noreturn)); + + /// \brief Check whether the given log level is enabled or not. + /// + /// \return True if the log level is enabled, false otherwise. + static bool IsEnabled(LogLevel level); + + private: + std::unique_ptr impl_; +}; + +#define MIND_LOG_STREAM mindspore::api::LogStream() +#define MIND_LOG_WRITER mindspore::api::LogWriter +#define MIND_LOG_LEVEL(L) mindspore::api::LogLevel::L + +#define MIND_LOG_THROW(L) MIND_LOG_WRITER(MIND_LOG_LEVEL(L), __FILE__, __LINE__, __FUNCTION__) ^ MIND_LOG_STREAM +#define MIND_LOG_WRITE(L) MIND_LOG_WRITER(MIND_LOG_LEVEL(L), __FILE__, __LINE__, __FUNCTION__) < MIND_LOG_STREAM +#define MIND_LOG_IF(L) \ + if (MIND_LOG_WRITER::IsEnabled(MIND_LOG_LEVEL(L))) MIND_LOG_WRITE(L) + +#define MIND_LOG_DEBUG MIND_LOG_IF(DEBUG) +#define MIND_LOG_INFO MIND_LOG_IF(INFO) +#define MIND_LOG_WARNING MIND_LOG_IF(WARNING) +#define MIND_LOG_ERROR MIND_LOG_IF(ERROR) +#define MIND_LOG_EXCEPTION MIND_LOG_THROW(EXCEPTION) +#define MIND_LOG(level) MIND_LOG_##level + +#if !defined(MIND_LOG_NO_MS_LOG) && !defined(MS_LOG) +#define MS_LOG(level) MIND_LOG_##level +#endif +} // namespace mindspore::api + +#endif // MINDSPORE_CORE_MINDAPI_BASE_LOGGING_H_ diff --git a/mindspore/core/mindapi/base/macros.h b/mindspore/core/mindapi/base/macros.h new file mode 100644 index 00000000000..4dd7901e35f --- /dev/null +++ b/mindspore/core/mindapi/base/macros.h @@ -0,0 +1,30 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_BASE_MACROS_H_ +#define MINDSPORE_CORE_MINDAPI_BASE_MACROS_H_ + +#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)) +#ifdef BUILDING_DLL +#define MIND_API __declspec(dllexport) +#else +#define MIND_API __declspec(dllimport) +#endif +#else +#define MIND_API __attribute__((visibility("default"))) +#endif + +#endif // MINDSPORE_CORE_MINDAPI_BASE_MACROS_H_ diff --git a/mindspore/core/mindapi/base/shape_vector.h b/mindspore/core/mindapi/base/shape_vector.h new file mode 100644 index 00000000000..4a2fdf9a888 --- /dev/null +++ b/mindspore/core/mindapi/base/shape_vector.h @@ -0,0 +1,25 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_BASE_SHAPE_VECTOR_H_ +#define MINDSPORE_CORE_MINDAPI_BASE_SHAPE_VECTOR_H_ + +#include +#include + +using ShapeVector = std::vector; + +#endif // MINDSPORE_CORE_MINDAPI_BASE_SHAPE_VECTOR_H_ diff --git a/mindspore/core/mindapi/base/shared_ptr.h b/mindspore/core/mindapi/base/shared_ptr.h new file mode 100644 index 00000000000..fabf24ac411 --- /dev/null +++ b/mindspore/core/mindapi/base/shared_ptr.h @@ -0,0 +1,180 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_BASE_SHARED_PTR_H_ +#define MINDSPORE_CORE_MINDAPI_BASE_SHARED_PTR_H_ + +#include +#include +#include +#include +#include + +namespace mindspore::api { +/// \brief SharedPtr wraps a std::shared_ptr and provides wrapper functions according the underlying implementation. +template +class SharedPtr { + public: + using element_type = T; + constexpr SharedPtr() noexcept = default; + constexpr SharedPtr(std::nullptr_t) noexcept : SharedPtr() {} // NOLINT + template + explicit SharedPtr(std::shared_ptr &&ptr) : ptr_(std::move(ptr)) {} + template + SharedPtr(const SharedPtr &other) : ptr_(other.ptr_) {} + template + SharedPtr(SharedPtr &&other) : ptr_(std::move(other.ptr_)) {} + template + SharedPtr &operator=(const SharedPtr &other) { + ptr_ = other.ptr_; + return *this; + } + template + SharedPtr &operator=(SharedPtr &&other) { + ptr_ = std::move(other.ptr_); + return *this; + } + ~SharedPtr() = default; + + std::uintptr_t addr() const { return (ptr_ == nullptr) ? 0 : reinterpret_cast(ptr_->impl().get()); } + element_type &operator*() const noexcept { return *ptr_; } + element_type *operator->() const noexcept { return ptr_.get(); } + element_type *get() const noexcept { return ptr_.get(); } + explicit operator bool() const { return addr() != 0; } + + private: + template + friend class SharedPtr; + std::shared_ptr ptr_; +}; + +template +inline bool operator==(const SharedPtr &a, const SharedPtr &b) noexcept { + return a.addr() == b.addr(); +} + +template +inline bool operator==(const SharedPtr &a, std::nullptr_t) noexcept { + return a.addr() == 0; +} + +template +inline bool operator==(std::nullptr_t, const SharedPtr &a) noexcept { + return a.addr() == 0; +} + +template +inline bool operator!=(const SharedPtr &a, const SharedPtr &b) noexcept { + return a.addr() != b.addr(); +} + +template +inline bool operator!=(const SharedPtr &a, std::nullptr_t) noexcept { + return a.addr() != 0; +} + +template +inline bool operator!=(std::nullptr_t, const SharedPtr &a) noexcept { + return a.addr() != 0; +} + +template +inline bool operator<(const SharedPtr &a, const SharedPtr &b) noexcept { + return a.addr() < b.addr(); +} + +template +inline bool operator<(const SharedPtr &a, std::nullptr_t) noexcept { + return a.addr() < 0; +} + +template +inline bool operator<(std::nullptr_t, const SharedPtr &a) noexcept { + // 'nullptr < ptr' is false only when ptr is nullptr. + return a.addr() != 0; +} + +template +inline bool operator>(const SharedPtr &a, const SharedPtr &b) noexcept { + return a.addr() > b.addr(); +} + +template +inline bool operator>(const SharedPtr &a, std::nullptr_t) noexcept { + return a.addr() > 0; +} + +template +inline bool operator>(std::nullptr_t, const SharedPtr &a) noexcept { + // 'nullptr > ptr' is always false. + return false; +} + +template +inline bool operator<=(const SharedPtr &a, const SharedPtr &b) noexcept { + return a.addr() <= b.addr(); +} + +template +inline bool operator<=(const SharedPtr &a, std::nullptr_t) noexcept { + return a.addr() <= 0; +} + +template +inline bool operator<=(std::nullptr_t, const SharedPtr &a) noexcept { + // 'nullptr <= ptr' is always true. + return true; +} + +template +inline bool operator>=(const SharedPtr &a, const SharedPtr &b) noexcept { + return a.addr() >= b.addr(); +} + +template +inline bool operator>=(const SharedPtr &a, std::nullptr_t) noexcept { + return a.addr() >= 0; +} + +template +inline bool operator>=(std::nullptr_t, const SharedPtr &a) noexcept { + // 'nullptr >= ptr' is true only when ptr is nullptr. + return a.addr() == 0; +} + +template +inline std::basic_ostream &operator<<(std::basic_ostream &os, const SharedPtr &a) { + return (os << reinterpret_cast(a.addr())); +} + +/// \brief Constructs an object of type T and wraps it in a SharedPtr. +/// +/// \param[in] args The parameter list for the constructor of T. +template +inline SharedPtr MakeShared(Args &&... args) { + auto ptr = std::make_shared(std::forward(args)...); + return SharedPtr(std::move(ptr)); +} +} // namespace mindspore::api + +namespace std { +template +struct hash> { + size_t operator()(const mindspore::api::SharedPtr &ptr) const noexcept { return static_cast(ptr.addr()); } +}; +} // namespace std + +#endif // MINDSPORE_CORE_MINDAPI_BASE_SHARED_PTR_H_ diff --git a/mindspore/core/mindapi/base/type_id.h b/mindspore/core/mindapi/base/type_id.h new file mode 100644 index 00000000000..1b668eb6175 --- /dev/null +++ b/mindspore/core/mindapi/base/type_id.h @@ -0,0 +1,104 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_BASE_TYPE_ID_H_ +#define MINDSPORE_CORE_MINDAPI_BASE_TYPE_ID_H_ + +namespace mindspore { +/// \brief TypeId defines data type identifiers. +enum TypeId : int { + kTypeUnknown = 0, + // + // Meta types. + // + kMetaTypeBegin = kTypeUnknown, + kMetaTypeType, // Type + kMetaTypeAnything, + kMetaTypeObject, + kMetaTypeTypeType, // TypeType + kMetaTypeProblem, + kMetaTypeExternal, + kMetaTypeNone, + kMetaTypeNull, + kMetaTypeEllipsis, + kMetaTypeEnd, + // + // Object types + // + kObjectTypeBegin = kMetaTypeEnd, + kObjectTypeNumber, + kObjectTypeString, + kObjectTypeList, + kObjectTypeTuple, + kObjectTypeSlice, + kObjectTypeKeyword, + kObjectTypeTensorType, + kObjectTypeRowTensorType, + kObjectTypeSparseTensorType, + kObjectTypeUndeterminedType, + kObjectTypeClass, + kObjectTypeDictionary, + kObjectTypeFunction, + kObjectTypeJTagged, + kObjectTypeSymbolicKeyType, + kObjectTypeEnvType, + kObjectTypeRefKey, + kObjectTypeRef, + kObjectTypeEnd, + // + // Number Types + // + kNumberTypeBegin = kObjectTypeEnd, + kNumberTypeBool, + kNumberTypeInt, + kNumberTypeInt8, + kNumberTypeInt16, + kNumberTypeInt32, + kNumberTypeInt64, + kNumberTypeUInt, + kNumberTypeUInt8, + kNumberTypeUInt16, + kNumberTypeUInt32, + kNumberTypeUInt64, + kNumberTypeFloat, + kNumberTypeFloat16, + kNumberTypeFloat32, + kNumberTypeFloat64, + kNumberTypeComplex, + kNumberTypeComplex64, + kNumberTypeComplex128, + kNumberTypeInt4, + kNumberTypeGLUInt, + kNumberTypeEnd, + // + // Monad Types + // + kMonadTypeBegin = kNumberTypeEnd, + kObjectTypeMonad, + kObjectTypeUMonad, + kObjectTypeIOMonad, + kMonadTypeEnd, + // + // Sparse Types + // + // Sparse types is placed at the end of enum, + // in order to keep fit with the type of existing model on the lite side. + kSparseTypeBegin = kMonadTypeEnd, + kObjectTypeCSRTensorType, + kSparseTypeEnd +}; +} // namespace mindspore +#endif // MINDSPORE_CORE_MINDAPI_BASE_TYPE_ID_H_ diff --git a/mindspore/core/mindapi/base/type_traits.h b/mindspore/core/mindapi/base/type_traits.h new file mode 100644 index 00000000000..2707512d769 --- /dev/null +++ b/mindspore/core/mindapi/base/type_traits.h @@ -0,0 +1,42 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_BASE_TYPE_TRAITS_H_ +#define MINDSPORE_CORE_MINDAPI_BASE_TYPE_TRAITS_H_ + +#include +#include +#include +#include "mindapi/base/shared_ptr.h" + +namespace mindspore::api { +template +struct is_wrapper_ptr : public std::false_type {}; +template +struct is_wrapper_ptr> : public std::true_type {}; + +template +struct is_shared_ptr : public std::false_type {}; +template +struct is_shared_ptr> : public std::true_type {}; + +template +struct is_vector : public std::false_type {}; +template +struct is_vector> : public std::true_type {}; +} // namespace mindspore::api + +#endif // MINDSPORE_CORE_MINDAPI_BASE_TYPE_TRAITS_H_ diff --git a/mindspore/core/mindapi/ir/abstract.h b/mindspore/core/mindapi/ir/abstract.h new file mode 100644 index 00000000000..512b9067232 --- /dev/null +++ b/mindspore/core/mindapi/ir/abstract.h @@ -0,0 +1,101 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_IR_ABSTRACT_H_ +#define MINDSPORE_CORE_MINDAPI_IR_ABSTRACT_H_ + +#include "mindapi/base/base.h" +#include "mindapi/ir/common.h" +#include "mindapi/ir/shape.h" +#include "mindapi/ir/type.h" +#include "mindapi/ir/value.h" + +namespace mindspore::api { +/// \brief AbstractBase defines base interfaces for abstract of an anf node. +class MIND_API AbstractBase : public Base { + public: + MIND_API_BASE_MEMBER(AbstractBase); + + /// \brief Clone an abstract from this abstract. + /// + /// \return A pointer to the cloned abstract. + AbstractBasePtr Clone() const; + + /// \brief Get the abstract type. + /// + /// \return A pointer to the Type. + TypePtr type() const; + + /// \brief Get the abstract value. + /// + /// \return A pointer to the Value. + ValuePtr value() const; + + /// \brief Set the type for this abstract. + /// + /// \param[in] type The type to be set. + void set_type(const TypePtr &type); + + /// \brief Set the value for this abstract. + /// + /// \param[in] value The value to be set. + void set_value(const ValuePtr &value); +}; + +/// \brief AbstractTensor describes a tensor's type, shape and value. +class MIND_API AbstractTensor : public AbstractBase { + public: + MIND_API_BASE_MEMBER(AbstractTensor); + + /// \brief Create AbstractTensor from the given type and shape. + /// + /// \param[in] type The data type id of the tensor. + /// \param[in] shape The shape of the tensor. + AbstractTensor(TypeId type, const ShapeVector &shape); + + /// \brief Get the element abstract. + /// + /// \return A pointer to the element abstract. + AbstractBasePtr element() const; + + /// \brief Get the shape of the abstract. + /// + /// \return A pointer to the shape. + ShapePtr shape() const; +}; + +using AbstractTensorPtr = SharedPtr; + +/// \brief AbstractSequence describes the abstract for a tuple or list. +class MIND_API AbstractSequence : public AbstractBase { + public: + MIND_API_BASE_MEMBER(AbstractSequence); + + /// \brief Get element abstracts. + /// + /// \return A vector of element abstracts. + AbstractBasePtrList elements() const; +}; + +using AbstractSequencePtr = SharedPtr; + +/// \brief AbstractTuple describes the abstract for a tuple. +class MIND_API AbstractTuple : public AbstractSequence { + public: + MIND_API_BASE_MEMBER(AbstractTuple); +}; +} // namespace mindspore::api +#endif // MINDSPORE_CORE_MINDAPI_IR_ABSTRACT_H_ diff --git a/mindspore/core/mindapi/ir/anf.h b/mindspore/core/mindapi/ir/anf.h new file mode 100644 index 00000000000..c00a5f40488 --- /dev/null +++ b/mindspore/core/mindapi/ir/anf.h @@ -0,0 +1,232 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_IR_ANF_H_ +#define MINDSPORE_CORE_MINDAPI_IR_ANF_H_ + +#include +#include +#include "mindapi/base/base.h" +#include "mindapi/ir/common.h" +#include "mindapi/ir/abstract.h" +#include "mindapi/ir/primitive.h" +#include "mindapi/ir/value.h" + +namespace mindspore::api { +/// \brief AnfNode is the basic class of the IR graph node. +class MIND_API AnfNode : public Base { + public: + MIND_API_BASE_MEMBER(AnfNode); + + /// \brief Obtain detailed information about scope namespace. + /// + /// \return Detailed information about scope namespace. + std::string fullname_with_scope() const; + + /// \brief Obtain the inferred abstract value of this AnfNode. + /// + /// \return The inferred abstract value. + AbstractBasePtr abstract() const; + + /// \brief Set the abstract value of this AnfNode. + /// + /// \param[in] abs New abstract value. + void set_abstract(const AbstractBasePtr &abs); +}; + +/// \brief CNode represents a compute node with a set of input nodes. +class MIND_API CNode : public AnfNode { + public: + MIND_API_BASE_MEMBER(CNode); + + /// \brief Get the number of inputs. + /// + /// \return The number of inputs in this CNode. + size_t size() const; + + /// \brief Get the input node of the given index. + /// + /// \param[in] i The given index. + /// + /// \return The input node of the given index. + AnfNodePtr input(size_t i) const; + + /// \brief Get the input nodes. + /// + /// \return The input nodes of this CNode. + std::vector inputs() const; + + /// \brief Set the input nodes for this CNode. + /// + /// \param[in] inputs Input nodes. + void set_inputs(const std::vector &inputs); + + /// \brief Add an input node to this CNode. + /// + /// \param[in] input the input node to be added. + void add_input(const AnfNodePtr &input); + + /// \brief Set fullname_with_scope for this CNode. + /// + /// \param[in] full_name The fullname_with_scope. + void set_fullname_with_scope(const std::string &full_name); + + /// \brief Add a new attribute to this CNode. + /// + /// \param[in] name The name of the new attribute. + /// \param[in] attr The value of the new attribute. + void AddAttr(const std::string &name, const ValuePtr &attr); + + /// \brief Erase the attribute with the given name. + /// + /// \param[in] name The name of attribute. + void EraseAttr(const std::string &name); + + /// \brief Get the attribute with the given name. + /// + /// \param[in] name The name of attribute. + /// \return Attribute. + ValuePtr GetAttr(const std::string &name) const; +}; + +using CNodePtr = SharedPtr; + +/// \brief Parameter represents the parameter inputs of a function. +class MIND_API Parameter : public AnfNode { + public: + MIND_API_BASE_MEMBER(Parameter); + + /// \brief Get the name of this Parameter. + /// + /// \return The name. + std::string name() const; + + /// \brief Set the name of this Parameter. + /// + /// \param[in] The name. + void set_name(const std::string &name); + + /// \brief Check if there is a default parameter. + /// + /// \return True if this Parameter has a default parameter, otherwise false. + bool has_default() const; + + /// \brief Set the default parameter. + /// + /// \param[in] param The default parameter. + void set_default_param(const ValuePtr ¶m); + + /// \brief Get the default parameter. + /// + /// \return The default parameter. + ValuePtr default_param() const; +}; + +using ParameterPtr = SharedPtr; + +/// \brief ValueNode is a graph node that hold a value. +class MIND_API ValueNode : public AnfNode { + public: + MIND_API_BASE_MEMBER(ValueNode); + + /// \brief Create ValueNode with the given value. + /// + /// \param[in] value The value of this ValueNode. + explicit ValueNode(const ValuePtr &value); + + /// \brief Get the value of this ValueNode. + /// + /// \return The value. + ValuePtr value() const; +}; + +using ValueNodePtr = SharedPtr; + +// === ANF utility functions === // + +/// \brief Create a ValueNode with the given value. +/// +/// \param[in] value The given value. +/// +/// \return The created ValueNode. +inline ValueNodePtr NewValueNode(const ValuePtr &value) { return MakeShared(value); } + +/// \brief Create a ValueNode with the given primitive type value. +/// +/// \param[in] value The given primitive type value. +/// +/// \return The created ValueNode. +template +inline ValueNodePtr NewValueNode(T value) { + return NewValueNode(MakeValue(value)); +} + +/// \brief Get the value from a node if it is a ValueNode. +/// +/// \param[in] node The node which may hold a value. +/// +/// \return A pointer to the value, nullptr if the node is not a ValueNode, or value not set. +inline ValuePtr GetValueNode(const AnfNodePtr &node) { + if (node == nullptr) { + return nullptr; + } + auto value_node = node->cast(); + if (value_node == nullptr) { + return nullptr; + } + return value_node->value(); +} + +/// \brief Get the value with the given type from a node if it is a ValueNode. +/// +/// \param[in] node The node which may hold a value. +/// +/// \return A pointer to the value, nullptr if the node is not a ValueNode, or value not set, or value type is mismatch. +template ::value && std::is_base_of_v, T>> +inline T GetValueNode(const AnfNodePtr &node) { + auto value = GetValueNode(node); + if (value == nullptr) { + return nullptr; + } + return value->cast(); +} + +/// \brief Check whether the given node is a cnode with the given Primitive as the first input. +/// +/// \param[in] node The given node to be checked. +/// \param[in] prim The Primitive value, nullptr means match any Primitive. +/// +/// \return True if the node is cnode and the first input is the given Primitive, false otherwise. +MIND_API bool IsPrimitiveCNode(const AnfNodePtr &node, const PrimitivePtr &prim = nullptr); + +/// \brief Check whether the given node is a ValueNode with the given Primitive. +/// +/// \param[in] node The given node to be checked. +/// \param[in] prim The Primitive value. +/// +/// \return True if the given node is a ValueNode with the given Primitive, false otherwise. +MIND_API bool IsPrimitive(const AnfNodePtr &node, const PrimitivePtr &prim); + +/// \brief Check if a node is a data node. +/// Some nodes may be used internally to pass some non-data states, those nodes are not data nodes. +/// +/// \param[in] node The node to be checked. +/// +/// \return True if the node is a data node, false otherwise. +MIND_API bool IsDataNode(const AnfNodePtr &node); +} // namespace mindspore::api +#endif // MINDSPORE_CORE_MINDAPI_IR_ANF_H_ diff --git a/mindspore/core/mindapi/ir/common.h b/mindspore/core/mindapi/ir/common.h new file mode 100644 index 00000000000..aa0c7a3f7cc --- /dev/null +++ b/mindspore/core/mindapi/ir/common.h @@ -0,0 +1,50 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_IR_COMMON_H_ +#define MINDSPORE_CORE_MINDAPI_IR_COMMON_H_ + +#include +#include "mindapi/base/shared_ptr.h" + +namespace mindspore::api { +class AnfNode; +using AnfNodePtr = SharedPtr; +using AnfNodePtrList = std::vector; + +class Value; +using ValuePtr = SharedPtr; + +class Primitive; +using PrimitivePtr = SharedPtr; + +class Type; +using TypePtr = SharedPtr; + +class AbstractBase; +using AbstractBasePtr = SharedPtr; +using AbstractBasePtrList = std::vector; + +class Shape; +using ShapePtr = SharedPtr; + +class FuncGraph; +using FuncGraphPtr = SharedPtr; + +class FuncGraphManager; +using FuncGraphManagerPtr = SharedPtr; +} // namespace mindspore::api +#endif // MINDSPORE_CORE_MINDAPI_IR_COMMON_H_ diff --git a/mindspore/core/mindapi/ir/func_graph.h b/mindspore/core/mindapi/ir/func_graph.h new file mode 100644 index 00000000000..4919b8ea022 --- /dev/null +++ b/mindspore/core/mindapi/ir/func_graph.h @@ -0,0 +1,193 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_IR_FUNC_GRAPH_H_ +#define MINDSPORE_CORE_MINDAPI_IR_FUNC_GRAPH_H_ + +#include +#include +#include +#include +#include "mindapi/base/base.h" +#include "mindapi/ir/common.h" +#include "mindapi/ir/anf.h" +#include "mindapi/ir/primitive.h" +#include "mindapi/ir/value.h" +#include "mindapi/ir/utils.h" + +namespace mindspore { +class FuncGraphManager; +} + +namespace mindspore::api { +/// \brief FuncGraph defines interface for a function graph. +class MIND_API FuncGraph : public Value { + public: + MIND_API_BASE_MEMBER(FuncGraph); + + /// \brief Get the input parameters. + /// + /// \return Input parameters of this graph. + std::vector get_inputs() const; + + /// \brief Get all parameters. + /// + /// \return All parameters of this graph. + std::vector parameters() const; + + /// \brief Adds a parameter to this graph. + /// + /// \param[in] p The parameter to be added. + void add_parameter(const ParameterPtr &p); + + /// \brief Adds a new parameter to this graph. + /// + /// \return The new added parameter. + ParameterPtr add_parameter(); + + /// \brief Get the output node. + /// + /// \return The output node, nullptr if output not set. + AnfNodePtr output() const; + + /// \brief Get the return CNode. + /// + /// \return The return CNode, nullptr if no return node. + CNodePtr get_return() const; + + /// \brief Set the output node. + /// + /// \param[in] value The output node to be set. + /// \param[in] force_new_ret If true, a new return node is always created. + void set_output(const AnfNodePtr &value, bool force_new_ret = false); + + /// \brief Set the return node. + /// + /// \param[in] cnode The return CNode to be set. + void set_return(const CNodePtr &cnode); + + /// \brief Creates a new CNode in this graph. + /// + /// \param[in] inputs The input nodes of the new CNode. + /// + /// \return The created CNode. + CNodePtr NewCNode(const std::vector &inputs = std::vector()); + + /// \brief Creates a new primitive CNode in this graph. + /// + /// \param[in] primitive The primitive of the new CNode. + /// \param[in] prim_inputs The argument inputs of the primitive CNode. + /// + /// \return The created primitive CNode. + CNodePtr NewCNode(const PrimitivePtr &primitive, const std::vector &prim_inputs); + + /// \brief Get all nodes in this graph. + /// + /// \return All nodes in this graph. + std::vector nodes() const; + + /// \brief Check whether an attribute is set for this graph. + /// + /// \param[in] key The attribute key (name). + /// + /// \return True if the attribute with the given key is set, false otherwise. + bool has_attr(const std::string &key) const; + + /// \brief Get an attribute value by its key. + /// + /// \param[in] key The attribute key (name). + /// + /// \return The attribute value for the given key, nullptr if attribute not found. + ValuePtr get_attr(const std::string &key) const; + + /// \brief Set an attribute value. + /// + /// \param[in] key The attribute key (name). + /// \param[in] value The attribute value. + void set_attr(const std::string &key, const ValuePtr &value); + + /// \brief Get the manager for this graph. + /// + /// \return The manager of this graph, nullptr if not set. + FuncGraphManagerPtr manager() const; + + /// \brief Creates an empty function graph. + /// + /// \return The created function graph. + static FuncGraphPtr Create(); + + /// \brief Topological sort a graph from the given end node. + /// + /// \param[in] node The end node of the graph to be sorted. + /// + /// \return The sorted nodes. + static std::vector TopoSort(const AnfNodePtr &node); +}; + +/// \brief FuncGraphManager defines interface for function graph management. +class MIND_API FuncGraphManager { + public: + /// \brief Create FuncGraphManager with the given implementor object. + /// + /// \param[in] impl The pointer to the implementor object. + explicit FuncGraphManager(const std::shared_ptr &impl); + + /// \brief Get the shared_ptr to the underly implementation object. + /// + /// \return The shared_ptr to the underly implementation object. + const std::shared_ptr &impl() const { return impl_; } + + /// \brief Replace an old node with a new node, related edges are all updated. + /// + /// \param[in] old_node The old node to be replaced. + /// \param[in] new_node The new node that replace the old one. + /// + /// \return True if the node is successfully replaced, false otherwise. + bool Replace(const AnfNodePtr &old_node, const AnfNodePtr &new_node); + + /// \brief Change an existed edge by replace its input node. + /// + /// \param[in] node The output node of the edge. + /// \param[in] index The input index in output node. + /// \param[in] value The new input node of the edge. + void SetEdge(const AnfNodePtr &node, int index, const AnfNodePtr &value); + + /// \brief Adds a new edge between the given two nodes. + /// + /// \param[in] node The output node of the edge. + /// \param[in] value The input node of the edge. + void AddEdge(const AnfNodePtr &node, const AnfNodePtr &value); + + /// \brief Find users of the given node. + /// + /// \param[in] node The node. + /// + /// \return Users of the given node, empty if user not found. + std::vector> GetUsers(const AnfNodePtr &node) const; + + /// \brief Manage the give function graph. + /// + /// \param[in] func_graph The function graph to be managed. + /// \param[in] manage If true, the created manager will be set in the graph. + /// + /// \return The manager that manages the given function graph. + static FuncGraphManagerPtr Manage(const FuncGraphPtr &func_graph, bool manage = true); + + private: + const std::shared_ptr impl_; +}; +} // namespace mindspore::api +#endif // MINDSPORE_CORE_MINDAPI_IR_FUNC_GRAPH_H_ diff --git a/mindspore/core/mindapi/ir/primitive.h b/mindspore/core/mindapi/ir/primitive.h new file mode 100644 index 00000000000..8c039129540 --- /dev/null +++ b/mindspore/core/mindapi/ir/primitive.h @@ -0,0 +1,79 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_IR_PRIMITIVE_H_ +#define MINDSPORE_CORE_MINDAPI_IR_PRIMITIVE_H_ + +#include +#include +#include +#include "mindapi/base/base.h" +#include "mindapi/ir/common.h" +#include "mindapi/ir/value.h" + +namespace mindspore::api { +/// \brief Primitive defines a primitive operator. +class MIND_API Primitive : public Value { + public: + MIND_API_BASE_MEMBER(Primitive); + + /// \brief Create primitive with the given name. + /// + /// \param[in] name The primitive name. + explicit Primitive(const std::string &name); + + /// \brief Get name of the primitive. + /// + /// \return The name of primitive. + const std::string &name() const; + + /// \brief Add attribute to primitive. + /// + /// \param[in] name The attribute name. + /// \param[in] attr The attribute value. + /// \return The primitive to which attribute has been added. + Primitive &AddAttr(const std::string &name, const ValuePtr &attr); + + /// \brief Add attributes by using a map, all elements of the map will be added to this primitive. + /// + /// \param[in] attrs The attribute map needs to be added in the primitive attribute. + /// \return The primitive to which attribute has been added. + Primitive &SetAttrs(const std::unordered_map &attrs); + + /// \brief Erase attribute to the primitive attribute map. + /// + /// \param[in] name The attribute name. + void EraseAttr(const std::string &name); + + /// \brief Get attribute value by name. + /// + /// \param[in] name the attribute name. + /// \return The value of the attribute, null if attribute name not found. + ValuePtr GetAttr(const std::string &name) const; + + /// \brief Check If Primitive has an attribute with then given name. + /// + /// \param[in] name The attribute name. + /// \return True if there is an attribute with the given name, otherwise false. + bool HasAttr(const std::string &name) const; + + /// \brief Get all attributes of this primitive as a map. + /// + /// \return The attribute map of this primitive. + std::unordered_map attrs() const; +}; +} // namespace mindspore::api +#endif // MINDSPORE_CORE_MINDAPI_IR_PRIMITIVE_H_ diff --git a/mindspore/core/mindapi/ir/shape.h b/mindspore/core/mindapi/ir/shape.h new file mode 100644 index 00000000000..bf90e5114e1 --- /dev/null +++ b/mindspore/core/mindapi/ir/shape.h @@ -0,0 +1,36 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_IR_SHAPE_H_ +#define MINDSPORE_CORE_MINDAPI_IR_SHAPE_H_ + +#include "mindapi/base/base.h" +#include "mindapi/base/shape_vector.h" +#include "mindapi/ir/common.h" + +namespace mindspore::api { +/// \brief Shape defines dimensions of a tensor. +class MIND_API Shape : public Base { + public: + MIND_API_BASE_MEMBER(Shape); + + /// \brief Get the shape dimensions. + /// + /// \return The shape dimensions. + const ShapeVector &shape() const; +}; +} // namespace mindspore::api +#endif // MINDSPORE_CORE_MINDAPI_IR_SHAPE_H_ diff --git a/mindspore/core/mindapi/ir/tensor.h b/mindspore/core/mindapi/ir/tensor.h new file mode 100644 index 00000000000..dd43755594f --- /dev/null +++ b/mindspore/core/mindapi/ir/tensor.h @@ -0,0 +1,93 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_IR_TENSOR_H_ +#define MINDSPORE_CORE_MINDAPI_IR_TENSOR_H_ + +#include +#include "mindapi/base/base.h" +#include "mindapi/base/shape_vector.h" +#include "mindapi/base/type_id.h" +#include "mindapi/ir/common.h" +#include "mindapi/ir/value.h" + +namespace mindspore::api { +/// \brief Tensor represents a multi-dimensional array of elements. +class MIND_API Tensor : public Value { + public: + MIND_API_BASE_MEMBER(Tensor); + + /// \brief Create a lazy allocated tensor. + /// + /// \param[in] data_type [TypeId] Data type of the tensor. + /// \param[in] shape The shape represented by ShapeVector of the tensor. + Tensor(TypeId data_type, const ShapeVector &shape); + + /// \brief Create a tensor with input data buffer. + /// + /// \param[in] data_type [TypeId] Data type of the tensor. + /// \param[in] shape The shape represented by ShapeVector of the tensor. + /// \param[in] data The input data to be copied into tensor. + /// \param[in] data_len The length of data in bytes. + Tensor(TypeId data_type, const ShapeVector &shape, void *data, size_t data_len); + + /// \brief Get the shape of the tensor. + /// The shape of a tensor is stored in a vector. Each element of the + /// vector represents the size of a dimension of the tensor. The order of each + /// element in the vector is the same as the the dimension's order it represents. + /// + /// \return A vector which represents the shape of the tensor. + const ShapeVector &shape() const; + + /// \brief Set the shape of tensor. + /// + /// \param[in] shape The shape to be set. + void set_shape(const ShapeVector &shape); + + /// \brief Get the data type of the tensor. + /// + /// \return The data type of the tensor. + TypeId data_type() const; + + /// \brief Set the data type of the tensor. + /// + /// \param[in] data_type The data type to be set. + void set_data_type(const TypeId data_type); + + /// \brief Get The pointer to the underlying memory block for data storage. + /// + /// \return The pointer to the underlying data. + const void *data() const; + + /// \brief Get The pointer to the underlying memory block for data storage. + /// + /// \return The pointer to the underlying data. + void *data(); + + /// \brief Get tensor data size. + /// + /// \return The total number of elements in the tensor. + int DataSize() const; + + /// \brief Get tensor data size in bytes. + /// + /// \return The total number of bytes for the tensor data. + std::size_t Size() const; +}; + +using TensorPtr = SharedPtr; +} // namespace mindspore::api +#endif // MINDSPORE_CORE_MINDAPI_IR_TENSOR_H_ diff --git a/mindspore/core/mindapi/ir/type.h b/mindspore/core/mindapi/ir/type.h new file mode 100644 index 00000000000..e314254fccd --- /dev/null +++ b/mindspore/core/mindapi/ir/type.h @@ -0,0 +1,56 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_IR_TYPE_H_ +#define MINDSPORE_CORE_MINDAPI_IR_TYPE_H_ + +#include "mindapi/base/base.h" +#include "mindapi/base/type_id.h" +#include "mindapi/ir/common.h" +#include "mindapi/ir/value.h" + +namespace mindspore::api { +/// \brief Type defines the type of a value. +class MIND_API Type : public Value { + public: + MIND_API_BASE_MEMBER(Type); + + /// \brief Get the id of the Type object. + /// + /// \return The id of the Type object. + TypeId type_id() const; + + /// \brief Get the number type of the Type object. + /// + /// \return The number type of this Type object, kTypeUnknown if this is not a number type. + TypeId number_type() const; + + /// \brief Get the Type according to a TypeId. + /// + /// \param[in] id The id of the type. + /// + /// \return The pointer to the Type. + static TypePtr GetType(TypeId id); + + /// \brief Get data size in bytes for the type according to a TypeId. + /// + /// \param[in] id The id of the type. + /// + /// \return The data size in bytes for the Type. + static size_t GetSize(TypeId id); +}; +} // 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 new file mode 100644 index 00000000000..4714baa38dc --- /dev/null +++ b/mindspore/core/mindapi/ir/utils.h @@ -0,0 +1,70 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_IR_UTILS_H_ +#define MINDSPORE_CORE_MINDAPI_IR_UTILS_H_ + +#include "mindapi/base/base.h" +#include "mindapi/base/shared_ptr.h" +#include "mindapi/base/type_traits.h" +#include "mindapi/ir/anf.h" +#include "mindapi/ir/value.h" +#include "mindapi/ir/func_graph.h" + +namespace mindspore::api::utils { +/// \brief Check whether the given object is an instance of the given class. +/// +/// \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) { + if (ptr == nullptr) { + return false; + } + return ptr->isa(); +} + +/// \brief Cast the given object pointer to a pointer with the given class. +/// +/// \param[in] ptr The pointer to the object to casted. +/// +/// \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) { + if (ptr == nullptr) { + return nullptr; + } + return ptr->cast(); +} + +/// \brief Make a copy from the given function graph. +/// +/// \param[in] func_graph The graph to be cloned. +/// +/// \return The cloned graph. +MIND_API FuncGraphPtr CloneGraph(const FuncGraphPtr &func_graph); + +/// \brief Get pad mode id from a value holds the pad mode name or id. +/// +/// \param[in] value The value holds the pad mode name or id. +/// \param[in] is_upper Indicates whether the name is uppercase or lowercase, default is false for lowercase. +/// +/// \return The pad mode id. +MIND_API int64_t GetPadMode(const ValuePtr &value, bool is_upper = false); +} // namespace mindspore::api::utils + +#endif // MINDSPORE_CORE_MINDAPI_IR_UTILS_H_ diff --git a/mindspore/core/mindapi/ir/value.h b/mindspore/core/mindapi/ir/value.h new file mode 100644 index 00000000000..df29cb86cd2 --- /dev/null +++ b/mindspore/core/mindapi/ir/value.h @@ -0,0 +1,270 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_IR_VALUE_H_ +#define MINDSPORE_CORE_MINDAPI_IR_VALUE_H_ + +#include +#include +#include +#include "mindapi/base/base.h" +#include "mindapi/ir/common.h" + +namespace mindspore::api { +template +struct ImmTrait {}; + +#define MIND_API_IMM_TRAIT(typeimm, prototype) \ + template <> \ + struct ImmTrait { \ + using type = SharedPtr; \ + } + +/// \brief Value represents a value in expression. +class MIND_API Value : public Base { + public: + MIND_API_BASE_MEMBER(Value); + + /// \brief Get the type of this Value. + /// + /// \return The type. + TypePtr type() const; + + /// \brief Get the abstract of this Value. + /// + /// \return Abstract of this Value. + AbstractBasePtr ToAbstract() const; +}; + +/// \brief ValueSequence represents a sequence of values. +class MIND_API ValueSequence : public Value { + public: + MIND_API_BASE_MEMBER(ValueSequence); + + /// \brief Get the size of this ValueSequence. + /// + /// \return The size as the number of elements. + std::size_t size() const; + + /// \brief Get the list of values in this ValueSequence. + /// + /// \return The list of element values. + std::vector value() const; +}; + +using ValueSequencePtr = SharedPtr; + +/// \brief ValueTuple represents a value tuple. +class MIND_API ValueTuple : public ValueSequence { + public: + MIND_API_BASE_MEMBER(ValueTuple); + + /// \brief Constructor of ValueTuple. + /// + /// \param[in] elements The elements of the tuple. + explicit ValueTuple(const std::vector &elements); +}; + +using ValueTuplePtr = SharedPtr; + +/// \brief StringImm defines a Value whose type is string. +class MIND_API StringImm : public Value { + public: + MIND_API_BASE_MEMBER(StringImm); + + /// \brief Create StringImm with the given string. + /// + /// \param[in] str The given string value. + explicit StringImm(const std::string &str); + + /// \brief Get the string value of this StringImm. + /// + /// \return The string value of this StringImm. + const std::string &value() const; +}; + +using StringImmPtr = SharedPtr; + +MIND_API_IMM_TRAIT(StringImm, std::string); + +/// \beief Scalar defines interface for scalar data. +class MIND_API Scalar : public Value { + public: + MIND_API_BASE_MEMBER(Scalar); +}; + +/// \beief BoolImm defines interface for bool data. +class MIND_API BoolImm : public Scalar { + public: + MIND_API_BASE_MEMBER(BoolImm); + + /// \brief Create BoolImm with the given bool value. + /// + /// \param[in] b The given bool value. + explicit BoolImm(bool b); + + /// \brief Get the bool value of this BoolImm. + /// + /// \return The bool value of this BoolImm. + bool value() const; +}; + +using BoolImmPtr = SharedPtr; + +MIND_API_IMM_TRAIT(BoolImm, bool); + +/// \beief IntegerImm defines interface for integer data. +class MIND_API IntegerImm : public Scalar { + public: + MIND_API_BASE_MEMBER(IntegerImm); +}; + +/// \beief Int64Imm defines interface for int64 data. +class MIND_API Int64Imm : public IntegerImm { + public: + MIND_API_BASE_MEMBER(Int64Imm); + + /// \brief Create Int64Imm with the given int64 value. + /// + /// \param[in] value The given bool value. + explicit Int64Imm(int64_t value); + + /// \brief Get the int64 value of this Int64Imm. + /// + /// \return The int64 value of this Int64Imm. + int64_t value() const; +}; + +using Int64ImmPtr = SharedPtr; + +MIND_API_IMM_TRAIT(Int64Imm, int64_t); + +/// \beief FloatImm defines interface for float data. +class MIND_API FloatImm : public Scalar { + public: + MIND_API_BASE_MEMBER(FloatImm); +}; + +/// \beief FP32Imm defines interface for float32 data. +class MIND_API FP32Imm : public FloatImm { + public: + MIND_API_BASE_MEMBER(FP32Imm); + + /// \brief Create FP32Imm with the given float value. + /// + /// \param[in] value The given float value. + explicit FP32Imm(float value); + + /// \brief Get the float value of this FP32Imm. + /// + /// \return The float value of this FP32Imm. + float value() const; +}; + +using FP32ImmPtr = SharedPtr; + +MIND_API_IMM_TRAIT(FP32Imm, float); + +// === Utility functions for Value === // + +/// \brief brief Create a Value object from a primitive type value. +/// +/// \param[in] v The primitive type value. +/// +/// \return The created Value object with the given primitive type value. +template ::type::element_type> +inline ValuePtr MakeValue(T v) { + return MakeShared(v); +} + +/// \brief brief Create a StringImm Value object from a C string. +/// +/// \param[in] s The C string. +/// +/// \return The created StringImm Value object. +inline ValuePtr MakeValue(const char *s) { return MakeShared(std::string(s)); } + +/// \brief brief Create a Int64Imm Value object from a int value. +/// +/// \param[in] i The int value. +/// +/// \return The created Int64Imm Value object. +inline ValuePtr MakeValue(int i) { return MakeShared(static_cast(i)); } + +/// \brief brief Create a ValueSequence object from a vector of values. +/// +/// \param[in] values The vector of values. +/// +/// \return The created ValueSequence object. +inline ValuePtr MakeValue(const std::vector &values) { return MakeShared(values); } + +/// \brief Create a ValueSequence object from a vector of primitive type values. +/// +/// \param[in] values The vector of primitive values. +/// +/// \return The created ValueSequence object. +template ::value, T>> +inline ValuePtr MakeValue(const T &values) { + std::vector value_vector; + value_vector.reserve(values.size()); + for (auto &value : values) { + value_vector.emplace_back(MakeValue(value)); + } + return MakeShared(value_vector); +} + +/// \brief brief Get primitive type value from a Value object. +/// +/// \param[in] value The pointer to the Value object. +/// +/// \return The primitive type value of the Value object. +template ::type> +inline T GetValue(const ValuePtr &value) { + if (value == nullptr) { + return T(); + } + U imm = value->cast(); + if (imm == nullptr) { + return T(); + } + return imm->value(); +} + +/// \brief brief Get primitive element values from a ValueSequeue object. +/// +/// \param[in] value The pointer to the ValueSequeue object. +/// +/// \return The primitive type values as a vector. +template , + typename U = typename std::enable_if_t::value, typename S::value_type>> +inline std::vector GetValue(const ValuePtr &value) { + if (value == nullptr) { + return {}; + } + auto seq = value->cast(); + if (seq == nullptr) { + return {}; + } + auto elements = seq->value(); + std::vector result; + result.reserve(elements.size()); + for (auto &e : elements) { + result.emplace_back(GetValue(e)); + } + return result; +} +} // namespace mindspore::api +#endif // MINDSPORE_CORE_MINDAPI_IR_VALUE_H_ diff --git a/mindspore/core/mindapi/src/abstract.cc b/mindspore/core/mindapi/src/abstract.cc new file mode 100644 index 00000000000..e07e671d7eb --- /dev/null +++ b/mindspore/core/mindapi/src/abstract.cc @@ -0,0 +1,84 @@ +/** + * Copyright 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. + * 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 "mindapi/ir/abstract.h" +#include "mindapi/src/helper.h" +#include "abstract/abstract_value.h" +#include "ir/dtype.h" +#include "ir/value.h" + +namespace mindspore::api { +using TypeImpl = mindspore::Type; +using ValueImpl = mindspore::Value; +using AbstractBaseImpl = mindspore::abstract::AbstractBase; + +MIND_API_BASE_IMPL(AbstractBase, AbstractBaseImpl, Base); + +AbstractBasePtr AbstractBase::Clone() const { + auto abs = ToRef(impl_).Clone(); + return ToWrapper(abs); +} + +TypePtr AbstractBase::type() const { + auto t = ToRef(impl_).BuildType(); + return ToWrapper(t); +} + +ValuePtr AbstractBase::value() const { + auto v = ToRef(impl_).BuildValue(); + return ToWrapper(v); +} + +void AbstractBase::set_type(const TypePtr &type) { + auto type_impl = ToImpl(type); + ToRef(impl_).set_type(type_impl); +} + +void AbstractBase::set_value(const ValuePtr &value) { + auto value_impl = ToImpl(value); + ToRef(impl_).set_value(value_impl); +} + +using AbstractTensorImpl = mindspore::abstract::AbstractTensor; + +MIND_API_BASE_IMPL(AbstractTensor, AbstractTensorImpl, AbstractBase); + +AbstractTensor::AbstractTensor(TypeId type, const ShapeVector &shape) + : AbstractBase(std::make_shared(mindspore::TypeIdToType(type), shape)) {} + +AbstractBasePtr AbstractTensor::element() const { + auto abs = ToRef(impl_).element(); + return ToWrapper(abs); +} + +ShapePtr AbstractTensor::shape() const { + auto s = ToRef(impl_).shape(); + return ToWrapper(s); +} + +using AbstractSequenceImpl = mindspore::abstract::AbstractSequeue; + +MIND_API_BASE_IMPL(AbstractSequence, AbstractSequenceImpl, AbstractBase); + +AbstractBasePtrList AbstractSequence::elements() const { + auto &impl_elements = ToRef(impl_).elements(); + return ToWrapperVector(impl_elements); +} + +using AbstractTupleImpl = mindspore::abstract::AbstractTuple; + +MIND_API_BASE_IMPL(AbstractTuple, AbstractTupleImpl, AbstractSequence); +} // namespace mindspore::api diff --git a/mindspore/core/mindapi/src/anf.cc b/mindspore/core/mindapi/src/anf.cc new file mode 100644 index 00000000000..b5e68b57b6a --- /dev/null +++ b/mindspore/core/mindapi/src/anf.cc @@ -0,0 +1,135 @@ +/** + * Copyright 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. + * 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 "mindapi/ir/anf.h" +#include "mindapi/src/helper.h" +#include "ir/anf.h" +#include "ir/value.h" +#include "ir/primitive.h" +#include "abstract/abstract_value.h" + +namespace mindspore::api { +using ValueImpl = mindspore::Value; +using AnfNodeImpl = mindspore::AnfNode; +using PrimitiveImpl = mindspore::Primitive; +using AbstractBaseImpl = mindspore::abstract::AbstractBase; + +MIND_API_BASE_IMPL(AnfNode, AnfNodeImpl, Base); + +std::string AnfNode::fullname_with_scope() const { return ToRef(impl_).fullname_with_scope(); } + +AbstractBasePtr AnfNode::abstract() const { + const auto &abs = ToRef(impl_).abstract(); + return ToWrapper(abs); +} + +void AnfNode::set_abstract(const AbstractBasePtr &abs) { + ToRef(impl_).set_abstract(ToImpl(abs)); +} + +using CNodeImpl = mindspore::CNode; + +MIND_API_BASE_IMPL(CNode, CNodeImpl, AnfNode); + +size_t CNode::size() const { return ToRef(impl_).size(); } + +AnfNodePtr CNode::input(size_t i) const { + auto &input = ToRef(impl_).input(i); + return ToWrapper(input); +} + +std::vector CNode::inputs() const { + auto &impl_inputs = ToRef(impl_).inputs(); + return ToWrapperVector(impl_inputs); +} + +void CNode::set_inputs(const std::vector &inputs) { + auto impl_inputs = ToImplVector(inputs); + ToRef(impl_).set_inputs(impl_inputs); +} + +void CNode::add_input(const AnfNodePtr &input) { + auto impl_input = ToImpl(input); + MS_EXCEPTION_IF_NULL(impl_input); + ToRef(impl_).add_input(impl_input); +} + +void CNode::set_fullname_with_scope(const std::string &full_name) { + ToRef(impl_).set_fullname_with_scope(full_name); +} + +void CNode::AddAttr(const std::string &name, const ValuePtr &attr) { + auto impl_attr = ToImpl(attr); + MS_EXCEPTION_IF_NULL(impl_attr); + ToRef(impl_).AddAttr(name, impl_attr); +} + +void CNode::EraseAttr(const std::string &name) { ToRef(impl_).EraseAttr(name); } + +ValuePtr CNode::GetAttr(const std::string &name) const { + auto v = ToRef(impl_).GetAttr(name); + return ToWrapper(v); +} + +using ParameterImpl = mindspore::Parameter; + +MIND_API_BASE_IMPL(Parameter, ParameterImpl, AnfNode); + +std::string Parameter::name() const { return ToRef(impl_).name(); } + +void Parameter::set_name(const std::string &name) { ToRef(impl_).set_name(name); } + +bool Parameter::has_default() const { return ToRef(impl_).has_default(); } + +void Parameter::set_default_param(const ValuePtr ¶m) { + auto v = ToImpl(param); + ToRef(impl_).set_default_param(v); +} + +ValuePtr Parameter::default_param() const { + auto v = ToRef(impl_).default_param(); + return ToWrapper(v); +} + +using ValueNodeImpl = mindspore::ValueNode; + +MIND_API_BASE_IMPL(ValueNode, ValueNodeImpl, AnfNode); + +ValueNode::ValueNode(const ValuePtr &value) : AnfNode(std::make_shared(ToImpl(value))) {} + +ValuePtr ValueNode::value() const { + auto v = ToRef(impl_).value(); + return ToWrapper(v); +} + +bool IsPrimitiveCNode(const AnfNodePtr &node, const PrimitivePtr &prim) { + auto node_impl = ToImpl(node); + auto prim_impl = ToImpl(prim); + return mindspore::IsPrimitiveCNode(node_impl, prim_impl); +} + +bool IsPrimitive(const AnfNodePtr &node, const PrimitivePtr &prim) { + auto node_impl = ToImpl(node); + auto prim_impl = ToImpl(prim); + return mindspore::IsPrimitive(node_impl, prim_impl); +} + +bool IsDataNode(const AnfNodePtr &node) { + auto node_impl = ToImpl(node); + // We assume that node with monad abstract is not a data node. + return !HasAbstractMonad(node_impl); +} +} // namespace mindspore::api diff --git a/mindspore/core/mindapi/src/base.cc b/mindspore/core/mindapi/src/base.cc new file mode 100644 index 00000000000..ee74fe05c6c --- /dev/null +++ b/mindspore/core/mindapi/src/base.cc @@ -0,0 +1,28 @@ +/** + * Copyright 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. + * 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 "mindapi/base/base.h" +#include "base/base.h" + +namespace mindspore::api { +Base::Base(const std::shared_ptr &impl) : impl_(impl) { MS_EXCEPTION_IF_NULL(impl_); } + +uint32_t Base::ClassId() { return mindspore::Base::kTypeId; } + +bool Base::IsFromClassId(uint32_t class_id) const { return impl_->IsFromTypeId(class_id); } + +std::string Base::ToString() const { return impl_->ToString(); } +} // namespace mindspore::api diff --git a/mindspore/core/mindapi/src/func_graph.cc b/mindspore/core/mindapi/src/func_graph.cc new file mode 100644 index 00000000000..e1f239a53b3 --- /dev/null +++ b/mindspore/core/mindapi/src/func_graph.cc @@ -0,0 +1,170 @@ +/** + * Copyright 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. + * 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 +#include "mindapi/ir/func_graph.h" +#include "mindapi/src/helper.h" +#define USE_DEPRECATED_API +#include "ir/anf.h" +#include "ir/value.h" +#include "ir/func_graph.h" +#include "ir/manager.h" +#include "ir/primitive.h" +#include "ir/graph_utils.h" + +namespace mindspore::api { +using ValueImpl = mindspore::Value; +using AnfNodeImpl = mindspore::AnfNode; +using CNodeImpl = mindspore::CNode; +using PrimitiveImpl = mindspore::Primitive; +using ParameterImpl = mindspore::Parameter; +using FuncGraphImpl = mindspore::FuncGraph; +using FuncGraphManagerImpl = mindspore::FuncGraphManager; + +MIND_API_BASE_IMPL(FuncGraph, FuncGraphImpl, Value); + +std::vector FuncGraph::get_inputs() const { + auto &inputs = ToRef(impl_).get_inputs(); + return ToWrapperVector(inputs); +} + +std::vector FuncGraph::parameters() const { + auto ¶ms = ToRef(impl_).parameters(); + return ToWrapperVector(params); +} + +void FuncGraph::add_parameter(const ParameterPtr &p) { + auto param_impl = ToImpl(p); + ToRef(impl_).add_parameter(param_impl); +} + +ParameterPtr FuncGraph::add_parameter() { + auto param_impl = ToRef(impl_).add_parameter(); + return ToWrapper(param_impl); +} + +AnfNodePtr FuncGraph::output() const { + auto output = ToRef(impl_).output(); + return ToWrapper(output); +} + +CNodePtr FuncGraph::get_return() const { + auto ret = ToRef(impl_).get_return(); + return ToWrapper(ret); +} + +void FuncGraph::set_output(const AnfNodePtr &value, bool force_new_ret) { + auto output = ToImpl(value); + ToRef(impl_).set_output(output); +} + +void FuncGraph::set_return(const CNodePtr &cnode) { + auto cnode_impl = ToImpl(cnode); + ToRef(impl_).set_return(cnode_impl); +} + +CNodePtr FuncGraph::NewCNode(const std::vector &inputs) { + auto inputs_impl = ToImplVector(inputs); + auto cnode_impl = ToRef(impl_).NewCNode(std::move(inputs_impl)); + return ToWrapper(cnode_impl); +} + +CNodePtr FuncGraph::NewCNode(const PrimitivePtr &primitive, const std::vector &prim_inputs) { + auto prim_impl = ToImpl(primitive); + auto prim_inputs_impl = ToImplVector(prim_inputs); + auto cnode_impl = ToRef(impl_).NewCNode(prim_impl, prim_inputs_impl); + return ToWrapper(cnode_impl); +} + +std::vector FuncGraph::nodes() const { + auto &nodes = ToRef(impl_).nodes(); + return ToWrapperVector(nodes); +} + +bool FuncGraph::has_attr(const std::string &key) const { return ToRef(impl_).has_attr(key); } + +ValuePtr FuncGraph::get_attr(const std::string &key) const { + auto v = ToRef(impl_).get_attr(key); + return ToWrapper(v); +} + +void FuncGraph::set_attr(const std::string &key, const ValuePtr &value) { + auto value_impl = ToImpl(value); + ToRef(impl_).set_attr(key, value_impl); +} + +FuncGraphManagerPtr FuncGraph::manager() const { + auto manager = ToRef(impl_).manager(); + if (manager == nullptr) { + return nullptr; + } + return MakeShared(manager); +} + +FuncGraphPtr FuncGraph::Create() { + auto fg = std::make_shared(); + return ToWrapper(fg); +} + +std::vector FuncGraph::TopoSort(const AnfNodePtr &node) { + auto node_impl = ToImpl(node); + if (node_impl == nullptr) { + return {}; + } + auto sorted = mindspore::TopoSort(node_impl); + return ToWrapperVector(sorted); +} + +// FuncGraphManager is not derived from Base, we implement it directly. +FuncGraphManager::FuncGraphManager(const std::shared_ptr &impl) : impl_(impl) { + MS_EXCEPTION_IF_NULL(impl_); +} + +bool FuncGraphManager::Replace(const AnfNodePtr &old_node, const AnfNodePtr &new_node) { + return impl_->Replace(ToImpl(old_node), ToImpl(new_node)); +} + +void FuncGraphManager::SetEdge(const AnfNodePtr &node, int index, const AnfNodePtr &value) { + return impl_->SetEdge(ToImpl(node), index, ToImpl(value)); +} + +void FuncGraphManager::AddEdge(const AnfNodePtr &node, const AnfNodePtr &value) { + return impl_->AddEdge(ToImpl(node), ToImpl(value)); +} + +std::vector> FuncGraphManager::GetUsers(const AnfNodePtr &node) const { + auto &node_users = impl_->node_users(); + auto iter = node_users.find(ToImpl(node)); + if (iter == node_users.end()) { + return {}; + } + auto &users_impl = iter->second; + std::vector> users; + users.reserve(users_impl.size()); + std::transform(users_impl.begin(), users_impl.end(), std::back_inserter(users), + [](const auto &user) { return std::make_pair(ToWrapper(user.first), user.second); }); + return users; +} + +FuncGraphManagerPtr FuncGraphManager::Manage(const FuncGraphPtr &func_graph, bool manage) { + auto fg_impl = ToImpl(func_graph); + auto mgr_impl = mindspore::Manage(fg_impl, manage); + if (mgr_impl == nullptr) { + return nullptr; + } + return MakeShared(mgr_impl); +} +} // namespace mindspore::api diff --git a/mindspore/core/mindapi/src/helper.h b/mindspore/core/mindapi/src/helper.h new file mode 100644 index 00000000000..a067abb225e --- /dev/null +++ b/mindspore/core/mindapi/src/helper.h @@ -0,0 +1,76 @@ +/** + * Copyright 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. + * 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_CORE_MINDAPI_IMPL_HELPER_H_ +#define MINDSPORE_CORE_MINDAPI_IMPL_HELPER_H_ + +#include +#include +#include +#include "mindapi/base/base.h" + +namespace mindspore::api { +template +T &ToRef(const std::shared_ptr &ptr) { + return static_cast(*ptr); +} + +template >, + typename = typename std::enable_if_t>> +std::shared_ptr ToImpl(const SharedPtr &wrapper) { + if (wrapper == nullptr || wrapper->impl() == nullptr) { + return nullptr; + } + return std::dynamic_pointer_cast(wrapper->impl()); +} + +template >> +SharedPtr ToWrapper(const std::shared_ptr &impl) { + if (impl == nullptr) { + return nullptr; + } + return MakeShared(impl); +} + +template +std::vector> ToImplVector(const U &wrapper_vector) { + std::vector> impl_vector; + impl_vector.reserve(wrapper_vector.size()); + for (auto &wrapper : wrapper_vector) { + impl_vector.emplace_back(ToImpl(wrapper)); + } + return impl_vector; +} + +template +std::vector> ToWrapperVector(const U &impl_vector) { + std::vector> wrapper_vector; + wrapper_vector.reserve(impl_vector.size()); + for (auto &impl : impl_vector) { + wrapper_vector.emplace_back(ToWrapper(impl)); + } + return wrapper_vector; +} + +#define MIND_API_BASE_IMPL(current_class, impl_class, base_class) \ + current_class::current_class(const std::shared_ptr &impl) : base_class(impl) { \ + if (!impl_->isa()) { \ + MS_LOG(EXCEPTION) << "Wrong impl " << impl_->type_name() << " for " << #current_class; \ + } \ + } \ + uint32_t current_class::ClassId() { return impl_class::kTypeId; } +} // namespace mindspore::api +#endif // MINDSPORE_CORE_MINDAPI_IMPL_HELPER_H_ diff --git a/mindspore/core/mindapi/src/logging.cc b/mindspore/core/mindapi/src/logging.cc new file mode 100644 index 00000000000..5c660527df9 --- /dev/null +++ b/mindspore/core/mindapi/src/logging.cc @@ -0,0 +1,75 @@ +/** + * Copyright 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. + * 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. + */ + +#define MIND_LOG_NO_MS_LOG +#include "mindapi/base/logging.h" +#include "utils/log_adapter.h" + +namespace mindspore::api { +static MsLogLevel ToMsLogLevel(LogLevel level) { + switch (level) { + case LogLevel::DEBUG: + return MsLogLevel::DEBUG; + case LogLevel::INFO: + return MsLogLevel::INFO; + case LogLevel::WARNING: + return MsLogLevel::WARNING; + case LogLevel::ERROR: + return MsLogLevel::ERROR; + case LogLevel::EXCEPTION: + return MsLogLevel::EXCEPTION; + default: + return MsLogLevel::EXCEPTION; + } +} + +class LogWriterImpl { + public: + LogWriterImpl(LogLevel level, const char *file, int line, const char *func) + : writer_(LocationInfo(file, line, func), ToMsLogLevel(level), SubModuleId::SM_API) {} + + ~LogWriterImpl() = default; + + void Write(const LogStream &stream) const noexcept { + mindspore::LogStream log_stream; + log_stream << stream.stream_.rdbuf(); + writer_ < log_stream; + } + + void WriteAndThrow(const LogStream &stream) const __attribute__((noreturn)) { + mindspore::LogStream log_stream; + log_stream << stream.stream_.rdbuf(); + writer_ ^ log_stream; + } + + private: + mindspore::LogWriter writer_; +}; + +LogWriter::LogWriter(LogLevel level, const char *file, int line, const char *func) + : impl_(std::make_unique(level, file, line, func)) {} + +LogWriter::~LogWriter() = default; + +void LogWriter::operator<(const LogStream &stream) const noexcept { impl_->Write(stream); } + +void LogWriter::operator^(const LogStream &stream) const { impl_->WriteAndThrow(stream); } + +bool LogWriter::IsEnabled(LogLevel level) { + auto log_level = ToMsLogLevel(level); + return IS_OUTPUT_ON(log_level); +} +} // namespace mindspore::api diff --git a/mindspore/core/mindapi/src/primitive.cc b/mindspore/core/mindapi/src/primitive.cc new file mode 100644 index 00000000000..e5a554ab536 --- /dev/null +++ b/mindspore/core/mindapi/src/primitive.cc @@ -0,0 +1,65 @@ +/** + * Copyright 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. + * 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 "mindapi/ir/primitive.h" +#include "mindapi/src/helper.h" +#include "ir/primitive.h" +#include "ir/value.h" + +namespace mindspore::api { +using ValueImpl = mindspore::Value; +using PrimitiveImpl = mindspore::Primitive; + +MIND_API_BASE_IMPL(Primitive, PrimitiveImpl, Value); + +Primitive::Primitive(const std::string &name) : Value(std::make_shared(name)) {} + +const std::string &Primitive::name() const { return ToRef(impl_).name(); } + +Primitive &Primitive::AddAttr(const std::string &name, const ValuePtr &attr) { + auto value = ToImpl(attr); + ToRef(impl_).set_attr(name, value); + return *this; +} + +Primitive &Primitive::SetAttrs(const std::unordered_map &attrs) { + for (auto &attr : attrs) { + auto value = ToImpl(attr.second); + ToRef(impl_).set_attr(attr.first, value); + } + return *this; +} + +void Primitive::EraseAttr(const std::string &name) { ToRef(impl_).EraseAttr(name); } + +ValuePtr Primitive::GetAttr(const std::string &name) const { + auto v = ToRef(impl_).GetAttr(name); + return ToWrapper(v); +} + +bool Primitive::HasAttr(const std::string &name) const { return ToRef(impl_).HasAttr(name); } + +std::unordered_map Primitive::attrs() const { + std::unordered_map attr_map; + auto &impl_attrs = ToRef(impl_).attrs(); + attr_map.reserve(impl_attrs.size()); + for (auto &attr : impl_attrs) { + auto value = ToWrapper(attr.second); + attr_map.emplace(attr.first, value); + } + return attr_map; +} +} // namespace mindspore::api diff --git a/mindspore/core/mindapi/src/shape.cc b/mindspore/core/mindapi/src/shape.cc new file mode 100644 index 00000000000..b902099dc4c --- /dev/null +++ b/mindspore/core/mindapi/src/shape.cc @@ -0,0 +1,27 @@ +/** + * Copyright 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. + * 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 "mindapi/ir/shape.h" +#include "mindapi/src/helper.h" +#include "abstract/dshape.h" + +namespace mindspore::api { +using ShapeImpl = mindspore::abstract::Shape; + +MIND_API_BASE_IMPL(Shape, ShapeImpl, Base); + +const ShapeVector &Shape::shape() const { return ToRef(impl_).shape(); } +} // namespace mindspore::api diff --git a/mindspore/core/mindapi/src/tensor.cc b/mindspore/core/mindapi/src/tensor.cc new file mode 100644 index 00000000000..d37da12c0d2 --- /dev/null +++ b/mindspore/core/mindapi/src/tensor.cc @@ -0,0 +1,47 @@ +/** + * Copyright 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. + * 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 +#include "mindapi/ir/tensor.h" +#include "mindapi/src/helper.h" +#include "ir/tensor.h" + +namespace mindspore::api { +using TensorImpl = mindspore::tensor::Tensor; + +MIND_API_BASE_IMPL(Tensor, TensorImpl, Value); + +Tensor::Tensor(TypeId data_type, const ShapeVector &shape) : Value(std::make_shared(data_type, shape)) {} + +Tensor::Tensor(TypeId data_type, const ShapeVector &shape, void *data, size_t data_len) + : Value(std::make_shared(data_type, shape, data, data_len)) {} + +const ShapeVector &Tensor::shape() const { return ToRef(impl_).shape(); } + +void Tensor::set_shape(const ShapeVector &shape) { (void)ToRef(impl_).set_shape(shape); } + +TypeId Tensor::data_type() const { return ToRef(impl_).data_type(); } + +void Tensor::set_data_type(const TypeId data_type) { (void)ToRef(impl_).set_data_type(data_type); } + +const void *Tensor::data() const { return ToRef(impl_).data_c(); } + +void *Tensor::data() { return ToRef(impl_).data_c(); } + +int Tensor::DataSize() const { return ToRef(impl_).DataSize(); } + +size_t Tensor::Size() const { return ToRef(impl_).Size(); } +} // namespace mindspore::api diff --git a/mindspore/core/mindapi/src/type.cc b/mindspore/core/mindapi/src/type.cc new file mode 100644 index 00000000000..b8dcb677f63 --- /dev/null +++ b/mindspore/core/mindapi/src/type.cc @@ -0,0 +1,39 @@ +/** + * Copyright 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. + * 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 "mindapi/ir/type.h" +#include "mindapi/ir/value.h" +#include "mindapi/src/helper.h" +#include "ir/dtype/type.h" +#include "ir/dtype.h" +#include "abstract/utils.h" + +namespace mindspore::api { +using TypeImpl = mindspore::Type; + +MIND_API_BASE_IMPL(Type, TypeImpl, Value); + +TypeId Type::type_id() const { return ToRef(impl_).type_id(); } + +TypeId Type::number_type() const { return ToRef(impl_).number_type(); } + +TypePtr Type::GetType(TypeId id) { + auto type_impl = mindspore::TypeIdToType(id); + return ToWrapper(type_impl); +} + +size_t Type::GetSize(TypeId id) { return mindspore::abstract::TypeIdSize(id); } +} // namespace mindspore::api diff --git a/mindspore/core/mindapi/src/utils.cc b/mindspore/core/mindapi/src/utils.cc new file mode 100644 index 00000000000..483ea44c8cd --- /dev/null +++ b/mindspore/core/mindapi/src/utils.cc @@ -0,0 +1,43 @@ +/** + * Copyright 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. + * 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 "mindapi/ir/utils.h" +#include "mindapi/src/helper.h" +#define USE_DEPRECATED_API +#include "ir/anf.h" +#include "ir/value.h" +#include "ir/func_graph_cloner.h" +#include "utils/check_convert_utils.h" + +namespace mindspore::api::utils { +using ValueImpl = mindspore::Value; +using FuncGraphImpl = mindspore::FuncGraph; + +MIND_API FuncGraphPtr CloneGraph(const FuncGraphPtr &func_graph) { + MS_EXCEPTION_IF_NULL(func_graph); + auto fg_impl = ToImpl(func_graph); + Cloner cloner({fg_impl}, false, true, true, std::make_shared(), nullptr); + auto cloned_fg = cloner[fg_impl]; + return ToWrapper(cloned_fg); +} + +int64_t GetPadMode(const api::ValuePtr &value, bool is_upper) { + int64_t result; + auto value_impl = ToImpl(value); + CheckAndConvertUtils::GetPadModEnumValue(value_impl, &result, is_upper); + return result; +} +} // namespace mindspore::api::utils diff --git a/mindspore/core/mindapi/src/value.cc b/mindspore/core/mindapi/src/value.cc new file mode 100644 index 00000000000..f7ffa5e1511 --- /dev/null +++ b/mindspore/core/mindapi/src/value.cc @@ -0,0 +1,94 @@ +/** + * Copyright 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. + * 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 "mindapi/ir/value.h" +#include "mindapi/ir/type.h" +#include "mindapi/ir/abstract.h" +#include "mindapi/src/helper.h" +#include "abstract/abstract_value.h" +#include "ir/anf.h" +#include "ir/dtype/type.h" +#include "ir/value.h" +#include "ir/scalar.h" + +namespace mindspore::api { +using ValueImpl = mindspore::Value; +using ValueSequenceImpl = mindspore::ValueSequeue; // 'Sequeue' is typo. +using ValueTupleImpl = mindspore::ValueTuple; +using StringImmImpl = mindspore::StringImm; +using ScalarImpl = mindspore::Scalar; +using BoolImmImpl = mindspore::BoolImm; +using IntegerImmImpl = mindspore::IntergerImm; // 'Interger' is typo. +using Int64ImmImpl = mindspore::Int64Imm; +using FloatImmImpl = mindspore::FloatImm; +using FP32ImmImpl = mindspore::FP32Imm; + +MIND_API_BASE_IMPL(Value, ValueImpl, Base); + +TypePtr Value::type() const { + auto t = ToRef(impl_).type(); + return ToWrapper(t); +} + +AbstractBasePtr Value::ToAbstract() const { + auto abs = ToRef(impl_).ToAbstract(); + return ToWrapper(abs); +} + +MIND_API_BASE_IMPL(ValueSequence, ValueSequenceImpl, Value); + +std::size_t ValueSequence::size() const { return ToRef(impl_).size(); } + +std::vector ValueSequence::value() const { + auto &elements = ToRef(impl_).value(); + return ToWrapperVector(elements); +} + +MIND_API_BASE_IMPL(ValueTuple, ValueTupleImpl, ValueSequence); + +ValueTuple::ValueTuple(const std::vector &elements) + : ValueSequence(std::make_shared(ToImplVector(elements))) {} + +MIND_API_BASE_IMPL(StringImm, StringImmImpl, Value); + +StringImm::StringImm(const std::string &str) : Value(std::make_shared(str)) {} + +const std::string &StringImm::value() const { return ToRef(impl_).value(); } + +MIND_API_BASE_IMPL(Scalar, ScalarImpl, Value); + +MIND_API_BASE_IMPL(BoolImm, BoolImmImpl, Scalar); + +BoolImm::BoolImm(bool b) : Scalar(std::make_shared(b)) {} + +bool BoolImm::value() const { return ToRef(impl_).value(); } + +MIND_API_BASE_IMPL(IntegerImm, IntegerImmImpl, Scalar); + +MIND_API_BASE_IMPL(Int64Imm, Int64ImmImpl, IntegerImm); + +Int64Imm::Int64Imm(int64_t value) : IntegerImm(std::make_shared(value)) {} + +int64_t Int64Imm::value() const { return ToRef(impl_).value(); } + +MIND_API_BASE_IMPL(FloatImm, FloatImmImpl, Scalar); + +MIND_API_BASE_IMPL(FP32Imm, FP32ImmImpl, FloatImm); + +FP32Imm::FP32Imm(float value) : FloatImm(std::make_shared(value)) {} + +float FP32Imm::value() const { return ToRef(impl_).value(); } +} // namespace mindspore::api diff --git a/mindspore/core/utils/log_adapter.h b/mindspore/core/utils/log_adapter.h index 169f1817ea8..1b3d7351daf 100644 --- a/mindspore/core/utils/log_adapter.h +++ b/mindspore/core/utils/log_adapter.h @@ -141,6 +141,7 @@ enum SubModuleId : int { SM_HCCL_ADPT, // Hccl Adapter SM_RUNTIME_FRAMEWORK, // Runtime framework SM_GE, // GraphEngine + SM_API, // MindAPI NUM_SUBMODUES // number of submodules }; diff --git a/mindspore/core/utils/shape_utils.h b/mindspore/core/utils/shape_utils.h index 2b34dad90b4..ca0fa5412e3 100644 --- a/mindspore/core/utils/shape_utils.h +++ b/mindspore/core/utils/shape_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2020 Huawei Technologies Co., Ltd + * Copyright 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. @@ -17,7 +17,6 @@ #ifndef MINDSPORE_SHAPE_UTILS_INFO_H_ #define MINDSPORE_SHAPE_UTILS_INFO_H_ -#include -using ShapeVector = std::vector; +#include "mindapi/base/shape_vector.h" #endif // MINDSPORE_SHAPE_UTILS_INFO_H_ diff --git a/mindspore/lite/cmake/file_list.cmake b/mindspore/lite/cmake/file_list.cmake index f66c93a62f3..548dbb2eb0b 100644 --- a/mindspore/lite/cmake/file_list.cmake +++ b/mindspore/lite/cmake/file_list.cmake @@ -16,6 +16,8 @@ set(API_IR_HEADER ${CORE_DIR}/api/ir/func_graph.h ${CORE_DIR}/api/ir/func_graph_manager.h ) +file(GLOB MINDAPI_BASE_HEADER ${CORE_DIR}/mindapi/base/*.h) +file(GLOB MINDAPI_IR_HEADER ${CORE_DIR}/mindapi/ir/*.h) set(BASE_HEADER ${CORE_DIR}/base/base.h ${CORE_DIR}/base/base_ref.h diff --git a/mindspore/lite/examples/train_lenet/Makefile b/mindspore/lite/examples/train_lenet/Makefile index 1f8414a6dd4..0fa1c170c87 100644 --- a/mindspore/lite/examples/train_lenet/Makefile +++ b/mindspore/lite/examples/train_lenet/Makefile @@ -15,6 +15,7 @@ OBJ:=$(SRC:.cc=.o) CFLAGS := -Ofast -std=c++17 \ -I . \ -I ./msl/runtime \ + -I ./msl/runtime/include \ -I ./msl/runtime/minddata \ -I ./msl/tools/third_party/flatbuffers/include diff --git a/mindspore/lite/examples/transfer_learning/Makefile b/mindspore/lite/examples/transfer_learning/Makefile index e13a6fa5f74..2caefe48536 100644 --- a/mindspore/lite/examples/transfer_learning/Makefile +++ b/mindspore/lite/examples/transfer_learning/Makefile @@ -15,6 +15,7 @@ OBJ:=$(SRC:.cc=.o) CFLAGS := -Ofast -std=c++17 \ -I . \ -I ./msl/runtime \ + -I ./msl/runtime/include \ -I ./msl/runtime/minddata \ -I ./msl/tools/third_party/flatbuffers/include diff --git a/mindspore/lite/examples/unified_api/Makefile b/mindspore/lite/examples/unified_api/Makefile index 9bfc2479657..465ece34d87 100644 --- a/mindspore/lite/examples/unified_api/Makefile +++ b/mindspore/lite/examples/unified_api/Makefile @@ -19,6 +19,7 @@ INF_OBJ:=$(INF_SRC:.cc=.o) CFLAGS := -Ofast -std=c++17 \ -I . \ -I ./msl/runtime \ + -I ./msl/runtime/include \ -I ./msl/runtime/minddata \ -I ./msl/tools/third_party/flatbuffers/include diff --git a/mindspore/lite/src/CMakeLists.txt b/mindspore/lite/src/CMakeLists.txt index dee2d9186b1..4a4b2db6738 100644 --- a/mindspore/lite/src/CMakeLists.txt +++ b/mindspore/lite/src/CMakeLists.txt @@ -289,6 +289,9 @@ if(APPLE) set(MINDSPORE_LITE_PUB_HDRS_IR_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/../../core/ir/dtype/type_id.h ) + set(MINDSPORE_LITE_PUB_HDRS_MINDAPI_HDRS + ${CMAKE_CURRENT_SOURCE_DIR}/../../core/mindapi/base/type_id.h + ) add_library(mindspore-lite_static STATIC ${LITE_SRC} ${MINDSPORE_LITE_PUB_HDRS} @@ -423,6 +426,9 @@ if(DEFINED ARCHS) FOREACH(HDR ${MINDSPORE_LITE_PUB_HDRS_IR_HDRS}) SET_SOURCE_FILES_PROPERTIES(${HDR} PROPERTIES MACOSX_PACKAGE_LOCATION Headers/include/ir/dtype/) ENDFOREACH() + FOREACH(HDR ${MINDSPORE_LITE_PUB_HDRS_MINDAPI_HDRS}) + SET_SOURCE_FILES_PROPERTIES(${HDR} PROPERTIES MACOSX_PACKAGE_LOCATION Headers/include/mindapi/base/) + ENDFOREACH() target_link_libraries(mindspore-lite_static) endif() diff --git a/tests/ut/cpp/CMakeLists.txt b/tests/ut/cpp/CMakeLists.txt index ee8eba0484e..ed2e14d0c79 100644 --- a/tests/ut/cpp/CMakeLists.txt +++ b/tests/ut/cpp/CMakeLists.txt @@ -71,6 +71,7 @@ if(ENABLE_MINDDATA) ./fl/*.cc ./cxx_api/*.cc ./tbe/*.cc + ./mindapi/*.cc ) if(NOT ENABLE_SECURITY) file(GLOB_RECURSE UT_SRCS_DEBUG RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/tests/ut/cpp/mindapi/mindapi_test.cc b/tests/ut/cpp/mindapi/mindapi_test.cc new file mode 100644 index 00000000000..dd5ea603a21 --- /dev/null +++ b/tests/ut/cpp/mindapi/mindapi_test.cc @@ -0,0 +1,394 @@ +/** + * Copyright 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. + * 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 +#include +#include +#include +#include "common/common_test.h" +#include "mindapi/base/logging.h" +#include "mindapi/ir/func_graph.h" +#include "mindapi/ir/tensor.h" +#include "mindapi/ir/utils.h" + +namespace mindspore::api { +class TestMindApi : public UT::Common { + public: + TestMindApi() = default; +}; + +/// Feature: MindAPI +/// Description: test basic 'is()' 'cast()' +/// Expectation: is/cast works correctly. +TEST_F(TestMindApi, test_base_isa_cast) { + auto value_node = MakeShared(MakeValue(0)); + auto base = MakeShared(value_node->impl()); + ASSERT_TRUE(base->isa()); + ASSERT_TRUE(base->isa()); + ASSERT_TRUE(base->isa()); + ASSERT_FALSE(base->isa()); + auto anf_node = base->cast(); + ASSERT_TRUE(anf_node != nullptr); + ASSERT_TRUE(anf_node->impl() == value_node->impl()); + ASSERT_TRUE(base->cast() == nullptr); +} + +/// Feature: MindAPI +/// Description: test graph construction. +/// Expectation: graph is constructed as expected. +TEST_F(TestMindApi, test_graph_construction) { + // fg(x) { return myprim(x, 1); } + auto fg = FuncGraph::Create(); + auto x = fg->add_parameter(); + x->set_name("x"); + auto prim = MakeShared("myprim"); + auto prim_node = MakeShared(prim); + auto value_node = MakeShared(MakeValue(1)); + auto cnode = fg->NewCNode({prim_node, x, value_node}); + fg->set_output(cnode); + + // Now we check the graph. + ASSERT_EQ(fg->parameters().size(), 1); + ASSERT_TRUE(fg->parameters()[0]->isa()); + ASSERT_EQ(fg->parameters()[0]->cast()->name(), "x"); + + auto ret_node = fg->get_return(); + ASSERT_TRUE(ret_node != nullptr); + auto output_node = fg->output(); + ASSERT_TRUE(output_node != nullptr); + ASSERT_TRUE(output_node->isa()); + + auto output_cnode = output_node->cast(); + ASSERT_EQ(output_cnode->inputs().size(), 3); + ASSERT_TRUE(output_cnode->input(0)->isa()); + ASSERT_TRUE(output_cnode->input(0)->cast()->value()->isa()); + ASSERT_EQ(output_cnode->input(0)->cast()->value()->cast()->name(), "myprim"); + ASSERT_TRUE(output_cnode->input(1)->isa()); + ASSERT_EQ(output_cnode->input(1)->cast()->name(), "x"); + ASSERT_TRUE(output_cnode->input(2)->isa()); + + ASSERT_EQ(output_cnode->impl(), cnode->impl()); +} + +/// Feature: MindAPI +/// Description: test value related functions. +/// Expectation: value related functions work as expected. +TEST_F(TestMindApi, test_values) { + int64_t one = 1; + auto s = MakeValue("hello"); + auto i = MakeValue(one); + auto i2 = MakeValue(2); + auto b = MakeValue(true); + auto f = MakeValue(3.14f); + auto seq = MakeValue(std::vector{3, 4, 5}); + auto seq_str = MakeValue(std::vector({"this", "is", "mindspore", "api"})); + + ASSERT_TRUE(s->isa()); + ASSERT_TRUE(i->isa()); + ASSERT_TRUE(i2->isa()); + ASSERT_TRUE(b->isa()); + ASSERT_TRUE(f->isa()); + ASSERT_TRUE(seq->isa()); + ASSERT_TRUE(seq_str->isa()); + + ASSERT_EQ(GetValue(s), "hello"); + ASSERT_EQ(GetValue(i), one); + ASSERT_EQ(GetValue(i2), 2); + ASSERT_TRUE(GetValue(b)); + ASSERT_TRUE(std::abs(GetValue(f) - 3.14f) < 0.00001f); + + ASSERT_EQ(GetValue(i), ""); + ASSERT_EQ(GetValue(s), 0); + ASSERT_FALSE(GetValue(s)); + ASSERT_EQ(GetValue(s), 0.0f); + + auto seq_ptr = seq->cast(); + ASSERT_TRUE(seq_ptr != nullptr); + ASSERT_EQ(seq_ptr->size(), 3); + ASSERT_EQ(seq_ptr->value().size(), 3); + ASSERT_TRUE(seq_ptr->value()[0]->isa()); + ASSERT_EQ(GetValue(seq_ptr->value()[0]), 3); + ASSERT_EQ(GetValue(seq_ptr->value()[1]), 4); + ASSERT_EQ(GetValue(seq_ptr->value()[2]), 5); + + auto seq_values = GetValue>(seq); + ASSERT_EQ(seq_values.size(), 3); + ASSERT_EQ(seq_values[0], 3); + ASSERT_EQ(seq_values[1], 4); + ASSERT_EQ(seq_values[2], 5); + + auto str_values = GetValue>(seq_str); + ASSERT_EQ(str_values.size(), 4); + ASSERT_EQ(str_values[0], "this"); + ASSERT_EQ(str_values[1], "is"); + ASSERT_EQ(str_values[2], "mindspore"); + ASSERT_EQ(str_values[3], "api"); +} + +/// Feature: MindAPI +/// Description: test graph manager functions. +/// Expectation: graph manager functions work as expected. +TEST_F(TestMindApi, test_func_graph_manager) { + // fg(x, y) { return myprim(add(x, y), 1); } + auto fg = FuncGraph::Create(); + auto x = fg->add_parameter(); + x->set_name("x"); + auto y = fg->add_parameter(); + y->set_name("y"); + auto add = MakeShared("add"); + auto add_node = MakeShared(add); + auto add_cnode = fg->NewCNode({add_node, x, y}); + auto prim = MakeShared("myprim"); + auto prim_node = MakeShared(prim); + auto value_node = MakeShared(MakeValue(1)); + auto cnode = fg->NewCNode({prim_node, add_cnode, value_node}); + fg->set_output(cnode); + + auto mgr = FuncGraphManager::Manage(fg); + ASSERT_TRUE(mgr != nullptr); + ASSERT_TRUE(fg->manager() != nullptr); + ASSERT_EQ(fg->manager()->impl(), mgr->impl()); + ASSERT_EQ(fg->manager(), mgr); + + ASSERT_EQ(cnode->input(1)->impl(), add_cnode->impl()); + mgr->Replace(add_cnode, x); + ASSERT_EQ(cnode->input(1)->impl(), x->impl()); + + mgr->SetEdge(cnode, 1, y); + ASSERT_EQ(cnode->input(1)->impl(), y->impl()); + + mgr->AddEdge(cnode, x); + ASSERT_EQ(cnode->size(), 4); + ASSERT_EQ(cnode->input(3)->impl(), x->impl()); + + auto users = mgr->GetUsers(value_node); + ASSERT_EQ(users.size(), 1); + ASSERT_EQ(users[0].first, cnode); + ASSERT_EQ(users[0].second, 2); +} + +/// Feature: MindAPI +/// Description: test value node utils. +/// Expectation: value node utils work as expected. +TEST_F(TestMindApi, test_value_node_utils) { + auto fg = FuncGraph::Create(); + auto fg_node = MakeShared(fg); + auto prim = MakeShared("myprim"); + auto prim_node = MakeShared(prim); + auto one = MakeShared(MakeValue(1)); + auto cnode = fg->NewCNode({fg_node, prim_node, one}); + + ASSERT_TRUE(GetValueNode(cnode) == nullptr); + + auto fg1 = GetValueNode(cnode->input(0)); + ASSERT_TRUE(fg1 != nullptr); + ASSERT_TRUE(fg1->isa()); + + auto prim1 = GetValueNode(cnode->input(1)); + ASSERT_TRUE(prim1 != nullptr); + ASSERT_TRUE(prim1->isa()); + + auto imm = GetValueNode(cnode->input(2)); + ASSERT_TRUE(imm != nullptr); + ASSERT_TRUE(imm->isa()); + ASSERT_EQ(imm->cast()->value(), 1); + + auto value = GetValueNode(cnode->input(2)); + ASSERT_TRUE(value != nullptr); + ASSERT_EQ(GetValue(value), 1); + + ASSERT_TRUE(GetValueNode(cnode->input(0)) == nullptr); + ASSERT_TRUE(GetValueNode(cnode->input(1)) == nullptr); + ASSERT_TRUE(GetValueNode(cnode->input(2)) == nullptr); + + // Test NewValueNode. + auto int_node = NewValueNode(1); + auto bool_node = NewValueNode(true); + auto float_node = NewValueNode(1.23f); + auto str_node = NewValueNode("hello"); + + ASSERT_TRUE(int_node->value()->isa()); + ASSERT_EQ(int_node->value()->cast()->value(), 1); + ASSERT_TRUE(bool_node->value()->isa()); + ASSERT_TRUE(bool_node->value()->cast()->value()); + ASSERT_TRUE(float_node->value()->isa()); + ASSERT_TRUE(std::abs(float_node->value()->cast()->value() - 1.23f) < 0.0000001f); + ASSERT_TRUE(str_node->value()->isa()); + ASSERT_EQ(str_node->value()->cast()->value(), "hello"); +} + +/// Feature: MindAPI +/// Description: test SharedPtr. +/// Expectation: SharedPtr work as expected. +TEST_F(TestMindApi, test_object_ptr) { + auto fg = FuncGraph::Create(); + auto fg_node = MakeShared(fg); + auto prim = MakeShared("myprim"); + auto prim_node = MakeShared(prim); + auto one = MakeShared(MakeValue(1)); + auto cnode = fg->NewCNode({fg_node, prim_node, one}); + + ASSERT_TRUE(fg != nullptr); + ASSERT_FALSE(!fg); + ASSERT_TRUE(fg ? true : false); + ASSERT_TRUE((*cnode).input(0) == fg_node); + ASSERT_TRUE(cnode->input(0) == fg_node); + ASSERT_TRUE(cnode.get()->input(0) == fg_node); + + ASSERT_EQ(cnode->input(0), fg_node); + ASSERT_EQ(cnode->input(1), prim_node); + ASSERT_EQ(cnode->input(2), one); + ASSERT_TRUE(cnode->input(0) != fg); + + AnfNodePtr p = fg_node; + ASSERT_TRUE(p == fg_node); + ASSERT_TRUE(p->isa()); + ASSERT_TRUE(p->cast() != nullptr); + ASSERT_TRUE(p->cast() == fg_node); + + p = cnode; + ASSERT_TRUE(p == cnode); + ASSERT_TRUE(p->isa()); + ASSERT_TRUE(p->cast() != nullptr); + ASSERT_TRUE(p->cast() == cnode); + ASSERT_TRUE(p.get() == cnode.get()); + + ASSERT_TRUE(p != nullptr); + ASSERT_FALSE(p == nullptr); + ASSERT_TRUE(p > nullptr); + ASSERT_FALSE(p < nullptr); + ASSERT_TRUE(p >= nullptr); + ASSERT_FALSE(p <= nullptr); + + ASSERT_TRUE(nullptr != p); + ASSERT_FALSE(nullptr == p); + ASSERT_TRUE(nullptr < p); + ASSERT_FALSE(nullptr > p); + ASSERT_TRUE(nullptr <= p); + ASSERT_FALSE(nullptr >= p); + + AnfNodePtr q = fg_node; + ASSERT_TRUE(p != q); + ASSERT_TRUE(p > q); + if (p.get()->impl() > q.get()->impl()) { + ASSERT_TRUE(p > q); + ASSERT_TRUE(p >= q); + ASSERT_TRUE(q < p); + ASSERT_TRUE(q <= p); + } else { + ASSERT_TRUE(p < q); + ASSERT_TRUE(p <= q); + ASSERT_TRUE(q > p); + ASSERT_TRUE(q >= p); + } + + std::stringstream ss1; + std::stringstream ss2; + ss1 << p; + ss2 << cnode.get()->impl().get(); + ASSERT_EQ(ss1.str(), ss2.str()); + + std::unordered_map mymap; + mymap.emplace(p, q); + mymap.emplace(q, p); + ASSERT_TRUE(mymap.find(p) != mymap.end()); + ASSERT_TRUE(mymap.find(q) != mymap.end()); + ASSERT_TRUE(mymap[p] == q); + ASSERT_TRUE(mymap[q] == p); +} + +/// Feature: MindAPI +/// Description: test Tensor API. +/// Expectation: Tensor API work as expected. +TEST_F(TestMindApi, test_tensor_api) { + ShapeVector shape{1, 2, 3}; + auto tensor = MakeShared(kNumberTypeFloat32, shape); + + ASSERT_EQ(tensor->data_type(), kNumberTypeFloat32); + ASSERT_EQ(tensor->shape(), shape); + ASSERT_EQ(tensor->DataSize(), 6); + ASSERT_EQ(tensor->Size(), 24); + + ShapeVector shape2{2, 3}; + tensor->set_data_type(kNumberTypeInt32); + tensor->set_shape(shape2); + ASSERT_EQ(tensor->data_type(), kNumberTypeInt32); + ASSERT_EQ(tensor->shape(), shape2); +} + +/// Feature: MindAPI +/// Description: test utils API. +/// Expectation: Tensor API work as expected. +TEST_F(TestMindApi, test_api_utils) { + // Test utils::isa, utils::cast. + auto anf_node = NewValueNode("hello"); + 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); + + anf_node = nullptr; + ASSERT_FALSE(utils::isa(anf_node)); + ASSERT_TRUE(utils::cast(anf_node) == nullptr); + + // Test clone graph. + auto fg = FuncGraph::Create(); + auto x = fg->add_parameter(); + x->set_name("x"); + auto y = fg->add_parameter(); + y->set_name("y"); + auto add = MakeShared("add"); + auto add_node = MakeShared(add); + auto add_cnode = fg->NewCNode({add_node, x, y}); + auto prim = MakeShared("myprim"); + auto prim_node = MakeShared(prim); + auto value_node = MakeShared(MakeValue(1)); + auto cnode = fg->NewCNode({prim_node, add_cnode, value_node}); + fg->set_output(cnode); + + auto cloned_fg = utils::CloneGraph(fg); + ASSERT_TRUE(cloned_fg != nullptr); + ASSERT_EQ(cloned_fg->parameters().size(), 2); + auto new_output = cloned_fg->output(); + ASSERT_TRUE(new_output != nullptr); + ASSERT_TRUE(new_output->isa()); + ASSERT_EQ(new_output->cast()->size(), cnode->size()); + ASSERT_TRUE(new_output != cnode); + ASSERT_TRUE(new_output->cast() != cnode); + + // Test get pad mode. + auto pm_lower = MakeValue("pad"); + auto pm_upper = MakeValue("PAD"); + ASSERT_EQ(utils::GetPadMode(pm_lower), 0); + ASSERT_EQ(utils::GetPadMode(pm_lower, false), 0); + ASSERT_EQ(utils::GetPadMode(pm_upper, true), 0); +} + +/// Feature: MindAPI +/// Description: test logging API. +/// Expectation: logging work as expected. +TEST_F(TestMindApi, test_api_logging) { + MS_LOG(DEBUG) << "hello debug"; + MS_LOG(INFO) << "hello info"; + MS_LOG(WARNING) << "hello warning"; + MS_LOG(ERROR) << "hello error"; + try { + MS_LOG(EXCEPTION) << "hello exception"; + ASSERT_TRUE(false); + } catch (...) { + } + ASSERT_TRUE(true); +} +} // namespace mindspore::api