This is an automated email from the ASF dual-hosted git repository. tqchen pushed a commit to branch refactor-s0 in repository https://gitbox.apache.org/repos/asf/tvm.git
commit f29e76f9f43d0eb73408404afaf82726df36be12 Author: tqchen <[email protected]> AuthorDate: Sat Sep 14 17:28:11 2024 -0400 [FFI] Formalize SafeCall handling Move all dll calls into c api. Leverage the TLS for safecall exception propagation so it works better for codegen. --- ffi/CMakeLists.txt | 12 +- ffi/include/tvm/ffi/base_details.h | 18 + ffi/include/tvm/ffi/c_api.h | 111 ++- ffi/include/tvm/ffi/container/optional.h | 2 + ffi/include/tvm/ffi/error.h | 38 +- ffi/include/tvm/ffi/function.h | 78 ++- ffi/include/tvm/ffi/object.h | 57 +- ffi/include/tvm/ffi/string.h | 2 +- ffi/include/tvm/ffi/type_traits.h | 6 +- ffi/scripts/run_tests.sh | 5 +- ffi/src/ffi/function.cc | 63 ++ ffi/src/ffi/object.cc | 25 +- ffi/src/ffi/traceback.cc | 20 +- ffi/tests/{example => backup_cpp}/CMakeLists.txt | 5 +- ffi/tests/{cpp => backup_cpp}/test_any.cc | 157 ++--- ffi/tests/{cpp => backup_cpp}/test_any_view.cc | 163 ++--- ffi/tests/{cpp => backup_cpp}/test_dict.cc | 21 +- ffi/tests/{cpp => backup_cpp}/test_func.cc | 58 +- ffi/tests/{cpp => backup_cpp}/test_list.cc | 69 +- ffi/tests/{cpp => backup_cpp}/test_ref.cc | 63 +- ffi/tests/{cpp => backup_cpp}/test_str.cc | 12 +- ffi/tests/{cpp => backup_cpp}/test_type_dyn.cc | 15 +- ffi/tests/{cpp => backup_cpp}/test_type_static.cc | 17 +- ffi/tests/cpp/CMakeLists.txt | 4 +- ffi/tests/cpp/test_any.cc | 794 +++++----------------- ffi/tests/{example => cpp}/test_array.cc | 0 ffi/tests/{example => cpp}/test_c_ffi_abi.cc | 0 ffi/tests/{example => cpp}/test_error.cc | 0 ffi/tests/{example => cpp}/test_function.cc | 0 ffi/tests/{example => cpp}/test_map.cc | 0 ffi/tests/{example => cpp}/test_object.cc | 2 +- ffi/tests/{example => cpp}/test_optional.cc | 0 ffi/tests/{example => cpp}/test_string.cc | 0 ffi/tests/{example => cpp}/testing_object.h | 0 ffi/tests/example/test_any.cc | 166 ----- 35 files changed, 739 insertions(+), 1244 deletions(-) diff --git a/ffi/CMakeLists.txt b/ffi/CMakeLists.txt index 89429d253b..b327c6667a 100644 --- a/ffi/CMakeLists.txt +++ b/ffi/CMakeLists.txt @@ -20,7 +20,6 @@ option(TVM_FFI_BUILD_REGISTRY ) option(TVM_FFI_USE_LIBBRACKTRACE "Enable libbacktrace" ON) option(TVM_FFI_BACKTRACE_ON_SEGFAULT "Set signal handler to print traceback on segfault" ON) -option(TVM_FFI_ALLOW_DYN_TYPE "Wehthert to allow dynamic features" ON) include(cmake/Utils/CxxWarning.cmake) include(cmake/Utils/Sanitizer.cmake) @@ -39,20 +38,13 @@ target_link_libraries(tvm_ffi INTERFACE dlpack_header) target_compile_features(tvm_ffi INTERFACE cxx_std_17) target_include_directories(tvm_ffi INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include") -if (TVM_FFI_ALLOW_DYN_TYPE) - message(STATUS "Setting C++ macro TVM_FFI_ALLOW_DYN_TYPE - 1") - target_compile_definitions(tvm_ffi INTERFACE TVM_FFI_ALLOW_DYN_TYPE=1) -else() - message(STATUS "Setting C++ macro TVM_FFI_ALLOW_DYN_TYPES - 0") - target_compile_definitions(tvm_ffi INTERFACE TVM_FFI_ALLOW_DYN_TYPE=0) -endif() - ########## Target: `tvm_ffi_registry` ########## if (TVM_FFI_BUILD_REGISTRY) add_library(tvm_ffi_registry_objs OBJECT "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/traceback.cc" "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/object.cc" + "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/function.cc" ) set_target_properties( tvm_ffi_registry_objs PROPERTIES @@ -101,6 +93,6 @@ if (${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME}) enable_testing() message(STATUS "Enable Testing") include(cmake/Utils/AddGoogleTest.cmake) - add_subdirectory(tests/example/) + add_subdirectory(tests/cpp/) endif() endif () diff --git a/ffi/include/tvm/ffi/base_details.h b/ffi/include/tvm/ffi/base_details.h index cf825fdea7..a779eb89ea 100644 --- a/ffi/include/tvm/ffi/base_details.h +++ b/ffi/include/tvm/ffi/base_details.h @@ -82,6 +82,23 @@ TypeName& operator=(const TypeName& other) = default; \ TypeName& operator=(TypeName&& other) = default; +/** + * \brief marks the begining of a C call that logs exception + */ +#define TVM_FFI_LOG_EXCEPTION_CALL_BEGIN() \ + try { \ + (void)0 + +/*! + * \brief Marks the end of a C call that logs exception + */ +#define TVM_FFI_LOG_EXCEPTION_CALL_END(Name) \ + } \ + catch (const std::exception& err) { \ + std::cout << "Exception caught during " << #Name << ":\n" << err.what() << std::endl; \ + throw err; \ + } + namespace tvm { namespace ffi { namespace details { @@ -221,6 +238,7 @@ TVM_FFI_INLINE uint64_t StableHashBytes(const char* data, size_t size) { } return result; } + } // namespace details } // namespace ffi } // namespace tvm diff --git a/ffi/include/tvm/ffi/c_api.h b/ffi/include/tvm/ffi/c_api.h index 20579bbe06..e6d3449ac3 100644 --- a/ffi/include/tvm/ffi/c_api.h +++ b/ffi/include/tvm/ffi/c_api.h @@ -20,8 +20,6 @@ /* * \file tvm/ffi/c_api.h * \brief This file defines the C convention of the FFI convention - * - * Only use the APIs when TVM_FFI_ALLOW_DYN_TYPE is set to true */ #ifndef TVM_FFI_C_API_H_ #define TVM_FFI_C_API_H_ @@ -29,14 +27,6 @@ #include <dlpack/dlpack.h> #include <stdint.h> -/*! - * \brief Macro defines whether we enable dynamic runtime features. - * \note Turning this one would mean that we need to link tvm_ffi_registry_shared - */ -#ifndef TVM_FFI_ALLOW_DYN_TYPE -#define TVM_FFI_ALLOW_DYN_TYPE 1 -#endif - #if !defined(TVM_FFI_DLL) && defined(__EMSCRIPTEN__) #include <emscripten/emscripten.h> #define TVM_FFI_DLL EMSCRIPTEN_KEEPALIVE @@ -92,9 +82,12 @@ typedef enum { } TVMFFITypeIndex; #endif +/*! \brief Handle to Object from C API's pov */ +typedef void* TVMFFIObjectHandle; + /*! * \brief C-based type of all FFI object types that allocates on heap. - * \note TVMFFIObject and TVMFFIAny share the common type_index_ header + * \note TVMFFIObject and TVMFFIAny share the common type_index header */ typedef struct TVMFFIObject { /*! @@ -164,6 +157,9 @@ typedef struct { const int32_t* type_acenstors; } TVMFFITypeInfo; +//------------------------------------------------------------ +// Section: User APIs to interact with the FFI +//------------------------------------------------------------ /*! * \brief Type that defines C-style safe call convention * @@ -176,11 +172,102 @@ typedef struct { * * \return The call return 0 if call is successful. * It returns non-zero value if there is an error. - * When error happens, the exception object will be stored in result. + * + * Possible return error of the API functions: + * * 0: success + * * -1: error happens, can be retrieved by TVMFFIGetLastError + * * -2: a frontend error occurred and recorded in the frontend. + * + * \note We decided to leverage TVMFFIGetLastError and TVMFFISetLastError + * for C function error propagation. This design choice, while + * introducing a dependency for TLS runtime, simplifies error + * propgation in chains of calls in compiler codegen. + * As we do not need to propagate error through argument but simply + * set them in the runtime environment. */ typedef int (*TVMFFISafeCallType)(void* func, int32_t num_args, const TVMFFIAny* args, TVMFFIAny* result); +/*! + * \brief Free an object handle by decreasing reference + * \param obj The object handle. + * \note Internally we decrease the reference counter of the object. + * The object will be freed when every reference to the object are removed. + * \return 0 when success, nonzero when failure happens + */ +TVM_FFI_DLL int TVMFFIObjectFree(TVMFFIObjectHandle obj); + +/*! + * \brief Move the last error from the environment to result. + * + * \param result The result error. + * + * \note This function clears the error stored in the TLS. + */ +TVM_FFI_DLL void TVMFFIMoveFromLastError(TVMFFIAny* result); + +/*! + * \brief Set the last error in TLS, which can be fetched by TVMFFIGetLastError. + * + * \param error_view The error in format of any view. + * It can be an object, or simply a raw c_str. + * \note + */ +TVM_FFI_DLL void TVMFFISetLastError(const TVMFFIAny* error_view); + +//------------------------------------------------------------ +// Section: Backend noexcept functions for internal use +// +// These functions are used internally and do not throw error +// instead the error will be logged and abort the process +// These are function are being called in startup or exit time +// so exception handling do not apply +//------------------------------------------------------------ +/*! + * \brief Get stack traceback in a string. + * \param filaname The current file name. + * \param func The current function + * \param lineno The current line number + * \return The traceback string + * + * \note filename func and lino are only used as a backup info, most cases they are not needed. + * The return value is set to const char* to be more compatible across dll boundaries. + */ +TVM_FFI_DLL const char* TVMFFITraceback(const char* filename, const char* func, int lineno); + +/*! + * \brief Initialize the type info during runtime. + * + * When the function is first time called for a type, + * it will register the type to the type table in the runtime. + * + * If the static_tindex is non-negative, the function will + * allocate a runtime type index. + * Otherwise, we will populate the type table and return the static index. + * + * \param type_key The type key. + * \param static_type_index Static type index if any, can be -1, which means this is a dynamic index + * \param num_child_slots Number of slots reserved for its children. + * \param child_slots_can_overflow Whether to allow child to overflow the slots. + * \param parent_type_index Parent type index, pass in -1 if it is root. + * \param result The output type index + * + * \return 0 if success, -1 if error occured + */ +TVM_FFI_DLL int32_t TVMFFIGetOrAllocTypeIndex(const char* type_key, int32_t static_type_index, + int32_t type_depth, int32_t num_child_slots, + int32_t child_slots_can_overflow, + int32_t parent_type_index); +/*! + * \brief Get dynamic type info by type index. + * + * \param type_index The type index + * \param result The output type information + * + * \return 0 when success, nonzero when failure happens + */ +TVM_FFI_DLL const TVMFFITypeInfo* TVMFFIGetTypeInfo(int32_t type_index); + #ifdef __cplusplus } // TVM_FFI_EXTERN_C #endif diff --git a/ffi/include/tvm/ffi/container/optional.h b/ffi/include/tvm/ffi/container/optional.h index 5f08db0a5b..a35d4f8ae2 100644 --- a/ffi/include/tvm/ffi/container/optional.h +++ b/ffi/include/tvm/ffi/container/optional.h @@ -28,6 +28,8 @@ #include <tvm/ffi/object.h> #include <optional> +#include <string> +#include <utility> namespace tvm { namespace ffi { diff --git a/ffi/include/tvm/ffi/error.h b/ffi/include/tvm/ffi/error.h index 1f703f1fac..aeed40f243 100644 --- a/ffi/include/tvm/ffi/error.h +++ b/ffi/include/tvm/ffi/error.h @@ -53,6 +53,17 @@ namespace tvm { namespace ffi { +/*! + * \brief Error already set in frontend env. + * + * This error can be thrown by EnvCheckSignals to indicate + * that there is an error set in the frontend environment(e.g. + * python interpreter). The TVM FFI should catch this error + * and return a proper code tell the frontend caller about + * this fact. + */ +struct EnvErrorAlreadySet : public std::exception {}; + /*! * \brief Error object class. */ @@ -128,33 +139,8 @@ class ErrorBuilder { bool log_before_throw_; }; -// Code section that depends on dynamic components that requires linking -#if TVM_FFI_ALLOW_DYN_TYPE -/*! - * \brief Get stack traceback in a string. - * \param filaname The current file name. - * \param func The current function - * \param lineno The current line number - * \return The traceback string - * - * \note filename func and lino are only used as a backup info, most cases they are not needed. - * The return value is set to const char* to be more compatible across dll boundaries. - */ -TVM_FFI_DLL const char* Traceback(const char* filename, const char* func, int lineno); // define traceback here as call into traceback function -#define TVM_FFI_TRACEBACK_HERE ::tvm::ffi::details::Traceback(__FILE__, TVM_FFI_FUNC_SIG, __LINE__) - -#else -// simple traceback when allow dyn type is set to false -inline std::string SimpleTraceback(const char* filename, const char* func, int lineno) { - std::ostringstream traceback; - // python style backtrace - traceback << " " << filename << ", line " << lineno << ", in " << func << '\n'; - return traceback.str(); -} -#define TVM_FFI_TRACEBACK_HERE \ - ::tvm::ffi::details::SimpleTraceback(__FILE__, TVM_FFI_FUNC_SIG, __LINE__) -#endif // TVM_FFI_ALLOW_DYN_TYPE +#define TVM_FFI_TRACEBACK_HERE TVMFFITraceback(__FILE__, TVM_FFI_FUNC_SIG, __LINE__) } // namespace details /*! diff --git a/ffi/include/tvm/ffi/function.h b/ffi/include/tvm/ffi/function.h index e2adee03c0..cb4cb2b937 100644 --- a/ffi/include/tvm/ffi/function.h +++ b/ffi/include/tvm/ffi/function.h @@ -29,12 +29,61 @@ #include <tvm/ffi/error.h> #include <tvm/ffi/function_details.h> +#include <functional> #include <string> #include <utility> namespace tvm { namespace ffi { +/** + * Helper macro to construct a safe call + * + * \brief Marks the begining of the safe call that catches exception explicitly + * + */ +#define TVM_FFI_SAFE_CALL_BEGIN() \ + try { \ + (void)0 + +/*! + * \brief Marks the end of safe call. + */ +#define TVM_FFI_SAFE_CALL_END() \ + return 0; \ + } \ + catch (const ::tvm::ffi::Error& err) { \ + ::tvm::ffi::AnyView error_as_any(err); \ + TVMFFISetLastError(reinterpret_cast<TVMFFIAny*>(&error_as_any)); \ + return -1; \ + } \ + catch (const ::tvm::ffi::EnvErrorAlreadySet&) { \ + return -2; \ + } \ + catch (const std::exception& err) { \ + ::tvm::ffi::Any error_as_any(tvm::ffi::Error("InternalError", err.what(), "")); \ + TVMFFISetLastError(reinterpret_cast<TVMFFIAny*>(&error_as_any)); \ + return -1; \ + } \ + TVM_FFI_UNREACHABLE() + +#define TVM_FFI_CHECK_SAFE_CALL(func) \ + { \ + int ret_code = (func); \ + if (ret_code != 0) { \ + if (ret_code == -2) { \ + throw ::tvm::ffi::EnvErrorAlreadySet(); \ + } \ + Any error_any; \ + TVMFFIMoveFromLastError(reinterpret_cast<TVMFFIAny*>(&error_any)); \ + if (std::optional<tvm::ffi::Error> error = error_any.TryAs<tvm::ffi::Error>()) { \ + throw std::move(*error); \ + } else { \ + TVM_FFI_THROW(RuntimeError) << "Error encountered"; \ + } \ + } \ + } + /*! * \brief Object container class that backs ffi::Function * \note Do not use this function directly, use ffi::Function @@ -61,20 +110,12 @@ class FunctionObj : public Object { FunctionObj() {} // Implementing safe call style - static int32_t SafeCall(void* func, int32_t num_args, const TVMFFIAny* args, TVMFFIAny* result) { + static int SafeCall(void* func, int32_t num_args, const TVMFFIAny* args, TVMFFIAny* result) { + TVM_FFI_SAFE_CALL_BEGIN(); FunctionObj* self = static_cast<FunctionObj*>(func); - try { - self->call(self, num_args, reinterpret_cast<const AnyView*>(args), - reinterpret_cast<Any*>(result)); - return 0; - } catch (const tvm::ffi::Error& err) { - Any(std::move(err)).MoveToTVMFFIAny(result); - return 1; - } catch (const std::runtime_error& err) { - Any(tvm::ffi::Error("RuntimeError", err.what(), "")).MoveToTVMFFIAny(result); - return 1; - } - TVM_FFI_UNREACHABLE(); + self->call(self, num_args, reinterpret_cast<const AnyView*>(args), + reinterpret_cast<Any*>(result)); + TVM_FFI_SAFE_CALL_END(); } friend class Function; @@ -119,15 +160,8 @@ template <typename Derived> struct RedirectCallToSafeCall { static void Call(const FunctionObj* func, int32_t num_args, const AnyView* args, Any* rv) { Derived* self = static_cast<Derived*>(const_cast<FunctionObj*>(func)); - int ret_code = self->RedirectSafeCall(num_args, reinterpret_cast<const TVMFFIAny*>(args), - reinterpret_cast<TVMFFIAny*>(rv)); - if (ret_code != 0) { - if (std::optional<tvm::ffi::Error> err = rv->TryAs<tvm::ffi::Error>()) { - throw std::move(*err); - } else { - TVM_FFI_THROW(RuntimeError) << "Error encountered when calling a tvm::ffi::Function"; - } - } + TVM_FFI_CHECK_SAFE_CALL(self->RedirectSafeCall( + num_args, reinterpret_cast<const TVMFFIAny*>(args), reinterpret_cast<TVMFFIAny*>(rv))); } static int32_t SafeCall(void* func, int32_t num_args, const TVMFFIAny* args, TVMFFIAny* rv) { diff --git a/ffi/include/tvm/ffi/object.h b/ffi/include/tvm/ffi/object.h index 07170dce8f..dbb940ab45 100644 --- a/ffi/include/tvm/ffi/object.h +++ b/ffi/include/tvm/ffi/object.h @@ -41,39 +41,6 @@ namespace details { // unsafe operations related to object struct ObjectUnsafe; -// Code section that depends on dynamic components -#if TVM_FFI_ALLOW_DYN_TYPE -/*! - * \brief Initialize the type info during runtime. - * - * When the function is first time called for a type, - * it will register the type to the type table in the runtime. - * - * If the static_tindex is non-negative, the function will - * allocate a runtime type index. - * Otherwise, we will populate the type table and return the static index. - * - * \param type_key The type key. - * \param static_type_index Static type index if any, can be -1, which means this is a dynamic index - * \param num_child_slots Number of slots reserved for its children. - * \param child_slots_can_overflow Whether to allow child to overflow the slots. - * \param parent_type_index Parent type index, pass in -1 if it is root. - * - * \return The allocated type index - */ -TVM_FFI_DLL int32_t ObjectGetOrAllocTypeIndex(const char* type_key, int32_t static_type_index, - int32_t type_depth, int32_t num_child_slots, - bool child_slots_can_overflow, - int32_t parent_type_index); - -/*! - * \brief Get Type information from type index. - * \param type_index The type index - * \return The type information - */ -TVM_FFI_DLL const TypeInfo* ObjectGetTypeInfo(int32_t type_index); -#endif // TVM_FFI_ALLOW_DYN_TYPE - /*! * Check if the type_index is an instance of TargetObjectType. * @@ -153,13 +120,9 @@ class Object { * \note this operation is expensive, can be used for error reporting. */ std::string GetTypeKey() const { -#if TVM_FFI_ALLOW_DYN_TYPE // the function checks that the info exists - const TypeInfo* type_info = details::ObjectGetTypeInfo(header_.type_index); + const TypeInfo* type_info = TVMFFIGetTypeInfo(header_.type_index); return type_info->type_key; -#else - return "<unknown>"; -#endif } // Information about the object @@ -462,19 +425,15 @@ inline ObjectPtr<BaseType> GetObjectPtr(ObjectType* ptr); "Need to set _type_child_slots when parent specifies it.") // If dynamic type is enabled, we still need to register the runtime type of parent -#if TVM_FFI_ALLOW_DYN_TYPE #define TVM_FFI_REGISTER_STATIC_TYPE_INFO(TypeName, ParentType) \ static int32_t _GetOrAllocRuntimeTypeIndex() { \ - static int32_t tindex = ::tvm::ffi::details::ObjectGetOrAllocTypeIndex( \ + static int32_t tindex = TVMFFIGetOrAllocTypeIndex( \ TypeName::_type_key, TypeName::_type_index, TypeName::_type_depth, \ TypeName::_type_child_slots, TypeName::_type_child_slots_can_overflow, \ ParentType::_GetOrAllocRuntimeTypeIndex()); \ return tindex; \ } \ static inline int32_t _register_type_index = _GetOrAllocRuntimeTypeIndex() -#else -#define TVM_FFI_REGISTER_STATIC_TYPE_INFO(TypeName, ParentType) -#endif /*! * \brief Helper macro to declare a object that comes with static type index. @@ -492,11 +451,9 @@ inline ObjectPtr<BaseType> GetObjectPtr(ObjectType* ptr); * \param ParentType The name of the ParentType */ #define TVM_FFI_DECLARE_BASE_OBJECT_INFO(TypeName, ParentType) \ - static_assert(TVM_FFI_ALLOW_DYN_TYPE, \ - "Dynamic object depend on TVM_FFI_ALLOW_DYN_TYPE cd set to 1"); \ TVM_FFI_OBJECT_STATIC_DEFS(TypeName, ParentType); \ static int32_t _GetOrAllocRuntimeTypeIndex() { \ - static int32_t tindex = ::tvm::ffi::details::ObjectGetOrAllocTypeIndex( \ + static int32_t tindex = TVMFFIGetOrAllocTypeIndex( \ TypeName::_type_key, -1, TypeName::_type_depth, TypeName::_type_child_slots, \ TypeName::_type_child_slots_can_overflow, ParentType::_GetOrAllocRuntimeTypeIndex()); \ return tindex; \ @@ -571,15 +528,11 @@ TVM_FFI_INLINE bool IsObjectInstance(int32_t object_type_index) { if (!TargetType::_type_child_slots_can_overflow) return false; // Invariance: parent index is always smaller than the child. if (object_type_index < target_type_index) return false; - // Do a runtime lookup of type information -#if TVM_FFI_ALLOW_DYN_TYPE + // Do a runtime lookup of type information // the function checks that the info exists - const TypeInfo* type_info = details::ObjectGetTypeInfo(object_type_index); + const TypeInfo* type_info = TVMFFIGetTypeInfo(object_type_index); return (type_info->type_depth > TargetType::_type_depth && type_info->type_acenstors[TargetType::_type_depth] == target_type_index); -#else - return false; -#endif } /*! * \brief Namespace to internally manipulate object class. diff --git a/ffi/include/tvm/ffi/string.h b/ffi/include/tvm/ffi/string.h index 6b43829ff8..7cbed2f7e8 100644 --- a/ffi/include/tvm/ffi/string.h +++ b/ffi/include/tvm/ffi/string.h @@ -165,7 +165,7 @@ class String : public ObjectRef { template <typename T> String& operator=(T&& other) { // copy-and-swap idiom - String(std::forward<T>(other)).swap(*this); + String(std::forward<T>(other)).swap(*this); // NOLINT(*) return *this; } diff --git a/ffi/include/tvm/ffi/type_traits.h b/ffi/include/tvm/ffi/type_traits.h index 68c83bc0df..a46d04ad83 100644 --- a/ffi/include/tvm/ffi/type_traits.h +++ b/ffi/include/tvm/ffi/type_traits.h @@ -59,12 +59,8 @@ inline std::string TypeIndex2TypeKey(int32_t type_index) { default: { TVM_FFI_ICHECK_GE(type_index, TypeIndex::kTVMFFIStaticObjectBegin) << "Uknown type_index=" << type_index; -#if TVM_FFI_ALLOW_DYN_TYPE - const TypeInfo* type_info = details::ObjectGetTypeInfo(type_index); + const TypeInfo* type_info = TVMFFIGetTypeInfo(type_index); return type_info->type_key; -#else - return "object.Object"; -#endif } } } diff --git a/ffi/scripts/run_tests.sh b/ffi/scripts/run_tests.sh index 8219afc90d..dc7e6cdc71 100755 --- a/ffi/scripts/run_tests.sh +++ b/ffi/scripts/run_tests.sh @@ -1,11 +1,10 @@ #!/bin/bash set -euxo pipefail -TVM_FFI_ALLOW_DYN_TYPE=ON -BUILD_TYPE=Release +BUILD_TYPE=RelWithDebugInfo rm -rf build/CMakeFiles build/CMakeCache.txt -cmake -G Ninja -S . -B build -DTVM_FFI_ALLOW_DYN_TYPE=${TVM_FFI_ALLOW_DYN_TYPE} -DTVM_FFI_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ +cmake -G Ninja -S . -B build -DTVM_FFI_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ -DTVM_FFI_BUILD_REGISTRY=ON \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_COMPILER_LAUNCHER=ccache cmake --build build --parallel 16 --clean-first --config ${BUILD_TYPE} --target tvm_ffi_tests diff --git a/ffi/src/ffi/function.cc b/ffi/src/ffi/function.cc new file mode 100644 index 0000000000..5da4e0178b --- /dev/null +++ b/ffi/src/ffi/function.cc @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +/* + * \file src/ffi/function.cc + * \brief Function call registry and safecall context + */ +#include <tvm/ffi/any.h> +#include <tvm/ffi/c_api.h> +#include <tvm/ffi/error.h> +#include <tvm/ffi/string.h> + +namespace tvm { +namespace ffi { + +class SafeCallContext { + public: + void SetLastError(const TVMFFIAny* error_view) { + last_error_ = Any(AnyView::CopyFromTVMFFIAny(error_view[0])); + // turn string into formal error. + if (std::optional<String> opt_str = last_error_.TryAs<String>()) { + last_error_ = ::tvm::ffi::Error("RuntimeError", *opt_str, ""); + } + } + + void MoveFromLastError(TVMFFIAny* result) { last_error_.MoveToTVMFFIAny(result); } + + static SafeCallContext* ThreadLocal() { + static thread_local SafeCallContext ctx; + return &ctx; + } + + private: + Any last_error_; +}; + +} // namespace ffi +} // namespace tvm + +extern "C" { +void TVMFFISetLastError(const TVMFFIAny* error_view) { + tvm::ffi::SafeCallContext::ThreadLocal()->SetLastError(error_view); +} + +void TVMFFIMoveFromLastError(TVMFFIAny* result) { + tvm::ffi::SafeCallContext::ThreadLocal()->MoveFromLastError(result); +} +} diff --git a/ffi/src/ffi/object.cc b/ffi/src/ffi/object.cc index f4e2ff3e30..d0782d1b50 100644 --- a/ffi/src/ffi/object.cc +++ b/ffi/src/ffi/object.cc @@ -22,6 +22,7 @@ */ #include <tvm/ffi/c_api.h> #include <tvm/ffi/error.h> +#include <tvm/ffi/function.h> #include <memory> #include <string> @@ -219,20 +220,24 @@ class TypeTable { std::vector<std::unique_ptr<Entry>> type_table_; std::unordered_map<std::string, int32_t> type_key2index_; }; +} // namespace ffi +} // namespace tvm -namespace details { +extern "C" { -int32_t ObjectGetOrAllocTypeIndex(const char* type_key, int32_t static_type_index, +int32_t TVMFFIGetOrAllocTypeIndex(const char* type_key, int32_t static_type_index, int32_t type_depth, int32_t num_child_slots, - bool child_slots_can_overflow, int32_t parent_index) { - return tvm::ffi::TypeTable::Global()->GetOrAllocTypeIndex(type_key, static_type_index, type_depth, - num_child_slots, - child_slots_can_overflow, parent_index); + int32_t child_slots_can_overflow, int32_t parent_type_index) { + TVM_FFI_LOG_EXCEPTION_CALL_BEGIN(); + return tvm::ffi::TypeTable::Global()->GetOrAllocTypeIndex( + type_key, static_type_index, type_depth, num_child_slots, child_slots_can_overflow, + parent_type_index); + TVM_FFI_LOG_EXCEPTION_CALL_END(TVMFFIGetOrAllocTypeIndex); } -const TypeInfo* ObjectGetTypeInfo(int32_t type_index) { +const TVMFFITypeInfo* TVMFFIGetTypeInfo(int32_t type_index) { + TVM_FFI_LOG_EXCEPTION_CALL_BEGIN(); return tvm::ffi::TypeTable::Global()->GetTypeInfo(type_index); + TVM_FFI_LOG_EXCEPTION_CALL_END(TVMFFIGetTypeInfo); } -} // namespace details -} // namespace ffi -} // namespace tvm +} // extern "C" diff --git a/ffi/src/ffi/traceback.cc b/ffi/src/ffi/traceback.cc index f2826957a2..70de055719 100644 --- a/ffi/src/ffi/traceback.cc +++ b/ffi/src/ffi/traceback.cc @@ -146,22 +146,20 @@ __attribute__((constructor)) void install_signal_handler(void) { } #endif // TVM_FFI_BACKTRACE_ON_SEGFAULT } // namespace +} // namespace ffi +} // namespace tvm -namespace details { -const char* Traceback(const char*, const char*, int) { +extern "C" { +const char* TVMFFITraceback(const char*, const char*, int) { static thread_local std::string traceback_str; traceback_str = ::tvm::ffi::Traceback(); return traceback_str.c_str(); } -} // namespace details -} // namespace ffi -} // namespace tvm +} // extern "C" #else -namespace tvm { -namespace ffi { -namespace details { +extern "C" { // fallback implementation simply print out the last trace -const char* Traceback(const char* filename, const char* func, int lineno) { +const char* TVMFFITraceback(const char* filename, const char* func, int lineno) { static thread_local std::string traceback_str; std::ostringstream traceback_stream; // python style backtrace @@ -169,8 +167,6 @@ const char* Traceback(const char* filename, const char* func, int lineno) { traceback_str = traceback_stream.str(); return traceback_str.c_str(); } -} // namespace details -} // namespace ffi -} // namespace tvm +} // extern "C" #endif // TVM_FFI_USE_LIBBACKTRACE #endif // _MSC_VER diff --git a/ffi/tests/example/CMakeLists.txt b/ffi/tests/backup_cpp/CMakeLists.txt similarity index 84% rename from ffi/tests/example/CMakeLists.txt rename to ffi/tests/backup_cpp/CMakeLists.txt index 62543756b9..cb17040090 100644 --- a/ffi/tests/example/CMakeLists.txt +++ b/ffi/tests/backup_cpp/CMakeLists.txt @@ -17,9 +17,8 @@ set_target_properties( add_cxx_warning(tvm_ffi_tests) add_sanitizer_address(tvm_ffi_tests) target_link_libraries(tvm_ffi_tests PRIVATE tvm_ffi) +add_sanitizer_address(tvm_ffi_registry_shared) +target_link_libraries(tvm_ffi_tests PRIVATE tvm_ffi_registry_shared) -if (TVM_FFI_BUILD_REGISTRY) - target_link_libraries(tvm_ffi_tests PRIVATE tvm_ffi_registry_shared) -endif() add_googletest(tvm_ffi_tests) diff --git a/ffi/tests/cpp/test_any.cc b/ffi/tests/backup_cpp/test_any.cc similarity index 84% copy from ffi/tests/cpp/test_any.cc copy to ffi/tests/backup_cpp/test_any.cc index a57829bd0a..d3c1e17002 100644 --- a/ffi/tests/cpp/test_any.cc +++ b/ffi/tests/backup_cpp/test_any.cc @@ -1,11 +1,12 @@ #include <gtest/gtest.h> + #include <tvm/ffi/ffi.hpp> namespace { using namespace tvm::ffi; template <typename SrcType, typename Checker> -void TestAnyConstructor(Checker check, TVMFFITypeIndex expected_type_index, const SrcType &source) { +void TestAnyConstructor(Checker check, TVMFFITypeIndex expected_type_index, const SrcType& source) { Any v(source); EXPECT_EQ(v.type_index, static_cast<int32_t>(expected_type_index)); EXPECT_EQ(v.ref_cnt, 0); @@ -19,7 +20,7 @@ std::vector<Any> AnyArrayFactory() { Any(nullptr), Any(1), Any(2.5), - Any(reinterpret_cast<void *>(FuncCall)), + Any(reinterpret_cast<void*>(FuncCall)), Any(DLDevice{kDLCPU, 0}), Any(DLDataType{kDLInt, 32, 1}), Any("Hello (raw str)"), @@ -31,22 +32,22 @@ std::vector<Any> AnyArrayFactory() { } template <typename SrcType> -void TestAnyStringify(const SrcType &source, TVMFFITypeIndex expected_type_index, - const std::string &expected) { +void TestAnyStringify(const SrcType& source, TVMFFITypeIndex expected_type_index, + const std::string& expected) { Any v(source); EXPECT_EQ(v.type_index, static_cast<int32_t>(expected_type_index)); EXPECT_EQ(v.str()->c_str(), expected); } template <typename SrcType, typename Checker> -void TestAnyStringifyChecker(const SrcType &source, TVMFFITypeIndex expected_type_index, +void TestAnyStringifyChecker(const SrcType& source, TVMFFITypeIndex expected_type_index, Checker check) { Any v(source); EXPECT_EQ(v.type_index, static_cast<int32_t>(expected_type_index)); check(v); } -void CheckAnyRefCnt(const TVMFFIAny *v) { +void CheckAnyRefCnt(const TVMFFIAny* v) { if (v->type_index >= static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStaticObjectBegin)) { EXPECT_EQ(v->v_obj->ref_cnt, 1); } @@ -98,17 +99,17 @@ TEST(Any_Constructor_2_AnyView, Move) { TEST(Any_Constructor_3_Ref, Copy) { Ref<Object> obj = Ref<Object>::New(); Any v(obj); - const TVMFFIAny *v_obj = v.v_obj; + const TVMFFIAny* v_obj = v.v_obj; EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject)); EXPECT_EQ(v.ref_cnt, 0); - EXPECT_EQ(v_obj, static_cast<const void *>(obj.get())); + EXPECT_EQ(v_obj, static_cast<const void*>(obj.get())); EXPECT_EQ(v_obj->ref_cnt, 2); } TEST(Any_Constructor_3_Ref, Move) { Ref<Object> obj = Ref<Object>::New(); Any v(std::move(obj)); - const TVMFFIAny *v_obj = v.v_obj; + const TVMFFIAny* v_obj = v.v_obj; EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject)); EXPECT_EQ(v.ref_cnt, 0); EXPECT_EQ(v_obj->ref_cnt, 1); @@ -116,7 +117,7 @@ TEST(Any_Constructor_3_Ref, Move) { } TEST(Any_Constructor_4_TypeTraits, Integer) { - auto check = [](TVMFFIAny *v, int64_t source) -> void { EXPECT_EQ(v->v_int64, source); }; + auto check = [](TVMFFIAny* v, int64_t source) -> void { EXPECT_EQ(v->v_int64, source); }; TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<int8_t>(1)); TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<int16_t>(2)); TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<int32_t>(3)); @@ -128,20 +129,20 @@ TEST(Any_Constructor_4_TypeTraits, Integer) { } TEST(Any_Constructor_4_TypeTraits, Float) { - auto check = [](TVMFFIAny *v, double source) -> void { EXPECT_EQ(v->v_float64, source); }; + auto check = [](TVMFFIAny* v, double source) -> void { EXPECT_EQ(v->v_float64, source); }; TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIFloat, static_cast<float>(3)); TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIFloat, static_cast<float>(4)); } TEST(Any_Constructor_4_TypeTraits, Ptr) { int p = 4; - auto check = [](TVMFFIAny *v, void *source) -> void { EXPECT_EQ(v->v_ptr, source); }; - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFINone, static_cast<void *>(nullptr)); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIPtr, static_cast<void *>(&p)); + auto check = [](TVMFFIAny* v, void* source) -> void { EXPECT_EQ(v->v_ptr, source); }; + TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFINone, static_cast<void*>(nullptr)); + TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIPtr, static_cast<void*>(&p)); } TEST(Any_Constructor_4_TypeTraits, Device) { - auto check = [](TVMFFIAny *v, const DLDevice &source) -> void { + auto check = [](TVMFFIAny* v, const DLDevice& source) -> void { EXPECT_EQ(v->v_device.device_type, source.device_type); EXPECT_EQ(v->v_device.device_id, source.device_id); }; @@ -150,7 +151,7 @@ TEST(Any_Constructor_4_TypeTraits, Device) { } TEST(Any_Constructor_4_TypeTraits, DataType) { - auto check = [](TVMFFIAny *v, const DLDataType &source) -> void { + auto check = [](TVMFFIAny* v, const DLDataType& source) -> void { EXPECT_EQ(v->v_dtype.code, source.code); EXPECT_EQ(v->v_dtype.bits, source.bits); EXPECT_EQ(v->v_dtype.lanes, source.lanes); @@ -160,19 +161,19 @@ TEST(Any_Constructor_4_TypeTraits, DataType) { } TEST(Any_Constructor_4_TypeTraits, RawStr) { - auto check = [](TVMFFIAny *v, const char *source) -> void { - Str *str = static_cast<Str *>(v->v_ptr); + auto check = [](TVMFFIAny* v, const char* source) -> void { + Str* str = static_cast<Str*>(v->v_ptr); EXPECT_STREQ(str->c_str(), source); }; - const char *empty = ""; - const char *hello = "hello"; + const char* empty = ""; + const char* hello = "hello"; TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIStr, empty); TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIStr, hello); } TEST(Any_Constructor_4_TypeTraits, CharArray) { - auto check = [](TVMFFIAny *v, const char *source) -> void { - Str *str = static_cast<Str *>(v->v_ptr); + auto check = [](TVMFFIAny* v, const char* source) -> void { + Str* str = static_cast<Str*>(v->v_ptr); EXPECT_STREQ(str->c_str(), source); }; const char empty[] = ""; @@ -182,8 +183,8 @@ TEST(Any_Constructor_4_TypeTraits, CharArray) { } TEST(Any_Constructor_4_TypeTraits, StdString) { - auto check = [](TVMFFIAny *v, const std::string &source) -> void { - Str *str = static_cast<Str *>(v->v_ptr); + auto check = [](TVMFFIAny* v, const std::string& source) -> void { + Str* str = static_cast<Str*>(v->v_ptr); EXPECT_EQ(str->c_str(), source); }; std::string empty = ""; @@ -194,7 +195,7 @@ TEST(Any_Constructor_4_TypeTraits, StdString) { TEST(Any_Constructor_5_Object_Ptr, Object) { Ref<Object> obj = Ref<Object>::New(); - TVMFFIAny *ptr = reinterpret_cast<TVMFFIAny *>(obj.get()); + TVMFFIAny* ptr = reinterpret_cast<TVMFFIAny*>(obj.get()); { Any v(obj.get()); EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject)); @@ -206,7 +207,7 @@ TEST(Any_Constructor_5_Object_Ptr, Object) { TEST(Any_Constructor_5_Object_Ptr, Func) { Ref<Func> func = Ref<Func>::New(FuncCall); - TVMFFIAny *ptr = reinterpret_cast<TVMFFIAny *>(func.get()); + TVMFFIAny* ptr = reinterpret_cast<TVMFFIAny*>(func.get()); { Any v(func.get()); EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFunc)); @@ -218,7 +219,7 @@ TEST(Any_Constructor_5_Object_Ptr, Func) { TEST(Any_Constructor_5_Object_Ptr, Str) { Ref<Str> str = Ref<Str>::New("hello"); - TVMFFIAny *ptr = reinterpret_cast<TVMFFIAny *>(str.get()); + TVMFFIAny* ptr = reinterpret_cast<TVMFFIAny*>(str.get()); { Any v(str.get()); EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)); @@ -230,7 +231,7 @@ TEST(Any_Constructor_5_Object_Ptr, Str) { TEST(Any_Converter_0_TypeTraits, Integer) { std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { + for (const Any& v : vs) { auto convert = [&]() -> int64_t { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)) { EXPECT_EQ(convert(), 1); @@ -238,7 +239,7 @@ TEST(Any_Converter_0_TypeTraits, Integer) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `int`"; EXPECT_EQ(ex.what(), os.str()); @@ -250,7 +251,7 @@ TEST(Any_Converter_0_TypeTraits, Integer) { TEST(Any_Converter_0_TypeTraits, Float) { std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { + for (const Any& v : vs) { auto convert = [&]() -> double { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)) { EXPECT_EQ(convert(), 1.0); @@ -260,7 +261,7 @@ TEST(Any_Converter_0_TypeTraits, Float) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `float`"; EXPECT_EQ(ex.what(), os.str()); @@ -272,19 +273,19 @@ TEST(Any_Converter_0_TypeTraits, Float) { TEST(Any_Converter_0_TypeTraits, Ptr) { std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { - auto convert = [&]() -> void * { return v; }; + for (const Any& v : vs) { + auto convert = [&]() -> void* { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { EXPECT_EQ(convert(), nullptr); } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIPtr)) { - EXPECT_EQ(convert(), reinterpret_cast<void *>(&FuncCall)); + EXPECT_EQ(convert(), reinterpret_cast<void*>(&FuncCall)); } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIRawStr)) { EXPECT_EQ(convert(), v.v_str); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `Ptr`"; EXPECT_EQ(ex.what(), os.str()); @@ -296,7 +297,7 @@ TEST(Any_Converter_0_TypeTraits, Ptr) { TEST(Any_Converter_0_TypeTraits, Device) { std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { + for (const Any& v : vs) { auto convert = [&]() -> DLDevice { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIDevice)) { EXPECT_EQ(convert().device_type, kDLCPU); @@ -305,7 +306,7 @@ TEST(Any_Converter_0_TypeTraits, Device) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `Device`"; EXPECT_EQ(ex.what(), os.str()); @@ -317,7 +318,7 @@ TEST(Any_Converter_0_TypeTraits, Device) { TEST(Any_Converter_0_TypeTraits, DataType) { std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { + for (const Any& v : vs) { auto convert = [&]() -> DLDataType { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIDataType)) { EXPECT_EQ(convert().code, kDLInt); @@ -327,7 +328,7 @@ TEST(Any_Converter_0_TypeTraits, DataType) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `dtype`"; EXPECT_EQ(ex.what(), os.str()); @@ -340,8 +341,8 @@ TEST(Any_Converter_0_TypeTraits, DataType) { TEST(Any_Converter_0_TypeTraits, RawStr) { std::vector<Any> vs = AnyArrayFactory(); int counter = 0; - for (const Any &v : vs) { - auto convert = [&]() -> const char * { return v; }; + for (const Any& v : vs) { + auto convert = [&]() -> const char* { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)) { ++counter; EXPECT_LE(counter, 3); @@ -356,7 +357,7 @@ TEST(Any_Converter_0_TypeTraits, RawStr) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `const char *`"; @@ -369,7 +370,7 @@ TEST(Any_Converter_0_TypeTraits, RawStr) { TEST(Any_Converter_1_AnyView, Any) { std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { + for (const Any& v : vs) { auto convert = [&]() -> AnyView { return v; }; { AnyView ret = convert(); @@ -384,20 +385,20 @@ TEST(Any_Converter_1_AnyView, Any) { TEST(Any_Converter_2_Ref, Object) { std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { + for (const Any& v : vs) { auto convert = [&]() -> Ref<Object> { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { Ref<Object> ret = convert(); EXPECT_EQ(ret.get(), nullptr); } else if (v.type_index >= static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStaticObjectBegin)) { Ref<Object> ret = convert(); - EXPECT_EQ(ret.get(), static_cast<void *>(v.v_obj)); + EXPECT_EQ(ret.get(), static_cast<void*>(v.v_obj)); EXPECT_EQ(v.v_obj->ref_cnt, 2); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Object`"; @@ -410,19 +411,19 @@ TEST(Any_Converter_2_Ref, Object) { TEST(Any_Converter_2_Ref, Func) { std::vector<Any> views = AnyArrayFactory(); - for (const Any &v : views) { + for (const Any& v : views) { auto convert = [&]() -> Ref<Func> { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { Ref<Func> ret = convert(); EXPECT_EQ(ret.get(), nullptr); } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFunc)) { Ref<Func> ret = convert(); - EXPECT_EQ(ret.get(), static_cast<void *>(v.v_obj)); + EXPECT_EQ(ret.get(), static_cast<void*>(v.v_obj)); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Func`"; @@ -436,7 +437,7 @@ TEST(Any_Converter_2_Ref, Func) { TEST(Any_Converter_2_Ref, Str) { int counter = 0; std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { + for (const Any& v : vs) { auto convert = [&]() -> Ref<Str> { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { Ref<Str> ret = convert(); @@ -456,7 +457,7 @@ TEST(Any_Converter_2_Ref, Str) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Str`"; @@ -469,20 +470,20 @@ TEST(Any_Converter_2_Ref, Str) { TEST(Any_Converter_3_Object_Ptr, Object) { std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { - auto convert = [&]() -> Object * { return v; }; + for (const Any& v : vs) { + auto convert = [&]() -> Object* { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Object *ret = convert(); + Object* ret = convert(); EXPECT_EQ(ret, nullptr); } else if (v.type_index >= static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStaticObjectBegin)) { - Object *ret = convert(); - EXPECT_EQ(ret, static_cast<void *>(v.v_obj)); + Object* ret = convert(); + EXPECT_EQ(ret, static_cast<void*>(v.v_obj)); EXPECT_EQ(v.v_obj->ref_cnt, 1); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Object *`"; @@ -495,19 +496,19 @@ TEST(Any_Converter_3_Object_Ptr, Object) { TEST(Any_Converter_3_Object_Ptr, Func) { std::vector<Any> views = AnyArrayFactory(); - for (const Any &v : views) { - auto convert = [&]() -> Func * { return v; }; + for (const Any& v : views) { + auto convert = [&]() -> Func* { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Func *ret = convert(); + Func* ret = convert(); EXPECT_EQ(ret, nullptr); } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFunc)) { - Func *ret = convert(); - EXPECT_EQ(ret, reinterpret_cast<Func *>(v.v_ptr)); + Func* ret = convert(); + EXPECT_EQ(ret, reinterpret_cast<Func*>(v.v_ptr)); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Func *`"; @@ -521,13 +522,13 @@ TEST(Any_Converter_3_Object_Ptr, Func) { TEST(Any_Converter_3_Object_Ptr, Str) { std::vector<Any> vs = AnyArrayFactory(); int counter = 0; - for (const Any &v : vs) { - auto convert = [&]() -> Str * { return v; }; + for (const Any& v : vs) { + auto convert = [&]() -> Str* { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Str *ret = convert(); + Str* ret = convert(); EXPECT_EQ(ret, nullptr); } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)) { - Str *ret = convert(); + Str* ret = convert(); ++counter; EXPECT_LE(counter, 3); if (counter == 1) { @@ -541,7 +542,7 @@ TEST(Any_Converter_3_Object_Ptr, Str) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Str *`"; @@ -560,7 +561,7 @@ TEST(Any_Stringify, Integer) { } TEST(Any_Stringify, Float) { - auto check = [](const Any &v) -> void { + auto check = [](const Any& v) -> void { std::string str = v.str()->c_str(); double f_str = std::stod(str); double f_src = v.v_float64; @@ -571,13 +572,13 @@ TEST(Any_Stringify, Float) { } TEST(Any_Stringify, Ptr) { - auto check = [](const Any &v) -> void { + auto check = [](const Any& v) -> void { std::string str = v.str()->c_str(); EXPECT_GT(str.size(), 2); }; - TestAnyStringify<void *>(nullptr, TVMFFITypeIndex::kTVMFFINone, "None"); - TestAnyStringifyChecker<void *>(reinterpret_cast<void *>(FuncCall), TVMFFITypeIndex::kTVMFFIPtr, - check); + TestAnyStringify<void*>(nullptr, TVMFFITypeIndex::kTVMFFINone, "None"); + TestAnyStringifyChecker<void*>(reinterpret_cast<void*>(FuncCall), TVMFFITypeIndex::kTVMFFIPtr, + check); } TEST(Any_Stringify, Device) { @@ -596,13 +597,13 @@ TEST(Any_Stringify, DataType) { } TEST(Any_Stringify, RawStr) { - TestAnyStringify<const char *>("Hello", TVMFFITypeIndex::kTVMFFIStr, "\"Hello\""); + TestAnyStringify<const char*>("Hello", TVMFFITypeIndex::kTVMFFIStr, "\"Hello\""); TestAnyStringify<char[6]>("Hello", TVMFFITypeIndex::kTVMFFIStr, "\"Hello\""); TestAnyStringify<const char[6]>("Hello", TVMFFITypeIndex::kTVMFFIStr, "\"Hello\""); } TEST(Any_Stringify, Object) { - auto check = [](const Any &v) -> void { + auto check = [](const Any& v) -> void { std::string expected_prefix = "object.Object@0"; int n = static_cast<int>(expected_prefix.size()); std::string str = v.str()->c_str(); @@ -613,7 +614,7 @@ TEST(Any_Stringify, Object) { } TEST(Any_Stringify, Func) { - auto check = [](const Any &v) -> void { + auto check = [](const Any& v) -> void { std::string expected_prefix = "object.Func@0"; int n = static_cast<int>(expected_prefix.size()); std::string str = v.str()->c_str(); @@ -624,7 +625,7 @@ TEST(Any_Stringify, Func) { } TEST(Any_Stringify, Str) { - auto check = [](const Any &v) -> void { + auto check = [](const Any& v) -> void { std::string str = v.str()->c_str(); EXPECT_EQ(str, "\"Hello World\""); }; @@ -632,4 +633,4 @@ TEST(Any_Stringify, Str) { check); } -} // namespace +} // namespace diff --git a/ffi/tests/cpp/test_any_view.cc b/ffi/tests/backup_cpp/test_any_view.cc similarity index 84% rename from ffi/tests/cpp/test_any_view.cc rename to ffi/tests/backup_cpp/test_any_view.cc index 67aaa9de3a..122c9ec368 100644 --- a/ffi/tests/cpp/test_any_view.cc +++ b/ffi/tests/backup_cpp/test_any_view.cc @@ -1,4 +1,5 @@ #include <gtest/gtest.h> + #include <tvm/ffi/ffi.hpp> namespace { @@ -6,7 +7,7 @@ using namespace tvm::ffi; template <typename SrcType, typename Checker> void TestAnyViewConstructor(Checker check, TVMFFITypeIndex expected_type_index, - const SrcType &source) { + const SrcType& source) { AnyView v(source); EXPECT_EQ(v.type_index, static_cast<int32_t>(expected_type_index)); EXPECT_EQ(v.ref_cnt, 0); @@ -16,7 +17,7 @@ void TestAnyViewConstructor(Checker check, TVMFFITypeIndex expected_type_index, int64_t FuncCall(int64_t x) { return x + 1; } std::vector<AnyView> AnyViewArrayFactory() { - static const char *raw_str = "Hello (raw str)"; + static const char* raw_str = "Hello (raw str)"; static std::string std_str = "World (std::string)"; static std::string ref_str = "Hello World (Ref<Str>)"; static Ref<Object> obj = Ref<Object>::New(); @@ -26,34 +27,34 @@ std::vector<AnyView> AnyViewArrayFactory() { AnyView(nullptr), AnyView(1), AnyView(2.5), - AnyView(reinterpret_cast<void *>(FuncCall)), + AnyView(reinterpret_cast<void*>(FuncCall)), AnyView(DLDevice{kDLCPU, 0}), AnyView(DLDataType{kDLInt, 32, 1}), AnyView(raw_str), AnyView(obj), AnyView(func), - AnyView(std_str), // TODO: disable AnyView(std::string&&) + AnyView(std_str), // TODO: disable AnyView(std::string&&) AnyView(str), }; } template <typename SrcType> -void TestAnyViewStringify(const SrcType &source, TVMFFITypeIndex expected_type_index, - const std::string &expected) { +void TestAnyViewStringify(const SrcType& source, TVMFFITypeIndex expected_type_index, + const std::string& expected) { AnyView v(source); EXPECT_EQ(v.type_index, static_cast<int32_t>(expected_type_index)); EXPECT_EQ(v.str()->c_str(), expected); } template <typename SrcType, typename Checker> -void TestAnyViewStringifyChecker(const SrcType &source, TVMFFITypeIndex expected_type_index, +void TestAnyViewStringifyChecker(const SrcType& source, TVMFFITypeIndex expected_type_index, Checker check) { AnyView v(source); EXPECT_EQ(v.type_index, static_cast<int32_t>(expected_type_index)); check(v); } -void CheckAnyViewRefCnt(const TVMFFIAny *v) { +void CheckAnyViewRefCnt(const TVMFFIAny* v) { if (v->type_index >= static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStaticObjectBegin)) { EXPECT_EQ(v->v_obj->ref_cnt, 1); } @@ -102,10 +103,10 @@ TEST(AnyView_Constructor_2_Any, Move) { TEST(AnyView_Constructor_3_Ref, Copy) { Ref<Object> obj = Ref<Object>::New(); AnyView v(obj); - const TVMFFIAny *v_obj = v.v_obj; + const TVMFFIAny* v_obj = v.v_obj; EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject)); EXPECT_EQ(v.ref_cnt, 0); - EXPECT_EQ(v_obj, static_cast<const void *>(obj.get())); + EXPECT_EQ(v_obj, static_cast<const void*>(obj.get())); EXPECT_EQ(v_obj->ref_cnt, 1); } @@ -116,7 +117,7 @@ TEST(AnyView_Constructor_3_Ref, Move) { } TEST(AnyView_Constructor_4_TypeTraits, Integer) { - auto check = [](TVMFFIAny *v, int64_t source) -> void { EXPECT_EQ(v->v_int64, source); }; + auto check = [](TVMFFIAny* v, int64_t source) -> void { EXPECT_EQ(v->v_int64, source); }; TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<int8_t>(1)); TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<int16_t>(2)); TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<int32_t>(3)); @@ -128,20 +129,20 @@ TEST(AnyView_Constructor_4_TypeTraits, Integer) { } TEST(AnyView_Constructor_4_TypeTraits, Float) { - auto check = [](TVMFFIAny *v, double source) -> void { EXPECT_EQ(v->v_float64, source); }; + auto check = [](TVMFFIAny* v, double source) -> void { EXPECT_EQ(v->v_float64, source); }; TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFIFloat, static_cast<float>(3)); TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFIFloat, static_cast<float>(4)); } TEST(AnyView_Constructor_4_TypeTraits, Ptr) { int p = 4; - auto check = [](TVMFFIAny *v, void *source) -> void { EXPECT_EQ(v->v_ptr, source); }; - TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFINone, static_cast<void *>(nullptr)); - TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFIPtr, static_cast<void *>(&p)); + auto check = [](TVMFFIAny* v, void* source) -> void { EXPECT_EQ(v->v_ptr, source); }; + TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFINone, static_cast<void*>(nullptr)); + TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFIPtr, static_cast<void*>(&p)); } TEST(AnyView_Constructor_4_TypeTraits, Device) { - auto check = [](TVMFFIAny *v, const DLDevice &source) -> void { + auto check = [](TVMFFIAny* v, const DLDevice& source) -> void { EXPECT_EQ(v->v_device.device_type, source.device_type); EXPECT_EQ(v->v_device.device_id, source.device_id); }; @@ -150,7 +151,7 @@ TEST(AnyView_Constructor_4_TypeTraits, Device) { } TEST(AnyView_Constructor_4_TypeTraits, DataType) { - auto check = [](TVMFFIAny *v, const DLDataType &source) -> void { + auto check = [](TVMFFIAny* v, const DLDataType& source) -> void { EXPECT_EQ(v->v_dtype.code, source.code); EXPECT_EQ(v->v_dtype.bits, source.bits); EXPECT_EQ(v->v_dtype.lanes, source.lanes); @@ -160,15 +161,15 @@ TEST(AnyView_Constructor_4_TypeTraits, DataType) { } TEST(AnyView_Constructor_4_TypeTraits, RawStr) { - auto check = [](TVMFFIAny *v, const char *source) -> void { EXPECT_EQ(v->v_str, source); }; - const char *empty = ""; - const char *hello = "hello"; + auto check = [](TVMFFIAny* v, const char* source) -> void { EXPECT_EQ(v->v_str, source); }; + const char* empty = ""; + const char* hello = "hello"; TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFIRawStr, empty); TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFIRawStr, hello); } TEST(AnyView_Constructor_4_TypeTraits, CharArray) { - auto check = [](TVMFFIAny *v, const char *source) -> void { EXPECT_EQ(v->v_str, source); }; + auto check = [](TVMFFIAny* v, const char* source) -> void { EXPECT_EQ(v->v_str, source); }; const char empty[] = ""; const char hello[] = "hello"; TestAnyViewConstructor(check, TVMFFITypeIndex::kTVMFFIRawStr, empty); @@ -176,7 +177,7 @@ TEST(AnyView_Constructor_4_TypeTraits, CharArray) { } TEST(AnyView_Constructor_4_TypeTraits, StdString) { - auto check = [](TVMFFIAny *v, const std::string &source) -> void { + auto check = [](TVMFFIAny* v, const std::string& source) -> void { EXPECT_EQ(v->v_str, source.data()); }; std::string empty = ""; @@ -190,7 +191,7 @@ TEST(AnyView_Constructor_5_Object_Ptr, Object) { AnyView v(obj.get()); EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject)); EXPECT_EQ(v.v_obj->ref_cnt, 1); - EXPECT_EQ(v.v_obj, static_cast<void *>(obj.get())); + EXPECT_EQ(v.v_obj, static_cast<void*>(obj.get())); } TEST(AnyView_Constructor_5_Object_Ptr, Func) { @@ -198,7 +199,7 @@ TEST(AnyView_Constructor_5_Object_Ptr, Func) { AnyView v(func.get()); EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFunc)); EXPECT_EQ(v.v_obj->ref_cnt, 1); - EXPECT_EQ(v.v_ptr, static_cast<void *>(func.get())); + EXPECT_EQ(v.v_ptr, static_cast<void*>(func.get())); } TEST(AnyView_Constructor_5_Object_Ptr, Str) { @@ -206,12 +207,12 @@ TEST(AnyView_Constructor_5_Object_Ptr, Str) { AnyView v(str.get()); EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)); EXPECT_EQ(v.v_obj->ref_cnt, 1); - EXPECT_EQ(v.v_obj, static_cast<void *>(str.get())); + EXPECT_EQ(v.v_obj, static_cast<void*>(str.get())); } TEST(AnyView_Converter_0_TypeTraits, Integer) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &v : views) { + for (const AnyView& v : views) { auto convert = [&]() -> int64_t { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)) { EXPECT_EQ(convert(), 1); @@ -219,7 +220,7 @@ TEST(AnyView_Converter_0_TypeTraits, Integer) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `int`"; EXPECT_EQ(ex.what(), os.str()); @@ -231,7 +232,7 @@ TEST(AnyView_Converter_0_TypeTraits, Integer) { TEST(AnyView_Converter_0_TypeTraits, Float) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &v : views) { + for (const AnyView& v : views) { auto convert = [&]() -> double { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)) { EXPECT_EQ(convert(), 1.0); @@ -241,7 +242,7 @@ TEST(AnyView_Converter_0_TypeTraits, Float) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `float`"; EXPECT_EQ(ex.what(), os.str()); @@ -253,19 +254,19 @@ TEST(AnyView_Converter_0_TypeTraits, Float) { TEST(AnyView_Converter_0_TypeTraits, Ptr) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &v : views) { - auto convert = [&]() -> void * { return v; }; + for (const AnyView& v : views) { + auto convert = [&]() -> void* { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { EXPECT_EQ(convert(), nullptr); } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIPtr)) { - EXPECT_EQ(convert(), reinterpret_cast<void *>(&FuncCall)); + EXPECT_EQ(convert(), reinterpret_cast<void*>(&FuncCall)); } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIRawStr)) { EXPECT_EQ(convert(), v.v_str); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `Ptr`"; EXPECT_EQ(ex.what(), os.str()); @@ -277,7 +278,7 @@ TEST(AnyView_Converter_0_TypeTraits, Ptr) { TEST(AnyView_Converter_0_TypeTraits, Device) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &v : views) { + for (const AnyView& v : views) { auto convert = [&]() -> DLDevice { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIDevice)) { EXPECT_EQ(convert().device_type, kDLCPU); @@ -286,7 +287,7 @@ TEST(AnyView_Converter_0_TypeTraits, Device) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `Device`"; EXPECT_EQ(ex.what(), os.str()); @@ -298,7 +299,7 @@ TEST(AnyView_Converter_0_TypeTraits, Device) { TEST(AnyView_Converter_0_TypeTraits, DataType) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &v : views) { + for (const AnyView& v : views) { auto convert = [&]() -> DLDataType { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIDataType)) { EXPECT_EQ(convert().code, kDLInt); @@ -308,7 +309,7 @@ TEST(AnyView_Converter_0_TypeTraits, DataType) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `dtype`"; EXPECT_EQ(ex.what(), os.str()); @@ -321,8 +322,8 @@ TEST(AnyView_Converter_0_TypeTraits, DataType) { TEST(AnyView_Converter_0_TypeTraits, RawStr) { std::vector<AnyView> views = AnyViewArrayFactory(); int counter = 0; - for (const AnyView &v : views) { - auto convert = [&]() -> const char * { return v; }; + for (const AnyView& v : views) { + auto convert = [&]() -> const char* { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIRawStr)) { counter += 1; EXPECT_LT(counter, 3); @@ -337,7 +338,7 @@ TEST(AnyView_Converter_0_TypeTraits, RawStr) { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `const char *`"; @@ -351,10 +352,10 @@ TEST(AnyView_Converter_0_TypeTraits, RawStr) { TEST(AnyView_Converter_0_TypeTraits, RawStrToStrStar_Fail) { AnyView v = "Hello"; try { - Str *v_str = v; + Str* v_str = v; (void)v_str; FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { EXPECT_STREQ(ex.what(), "Cannot convert from type `const char *` to `object.Str *`"); } } @@ -362,19 +363,19 @@ TEST(AnyView_Converter_0_TypeTraits, RawStrToStrStar_Fail) { TEST(AnyView_Converter_0_TypeTraits, RawStrToStrStar_WrithStorage) { Any storage; AnyView v = "Hello"; - Str *v_str = v.CastWithStorage<Str *>(&storage); + Str* v_str = v.CastWithStorage<Str*>(&storage); EXPECT_STREQ(v_str->c_str(), "Hello"); } TEST(AnyView_Converter_1_Any, Any) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &view : views) { + for (const AnyView& view : views) { auto convert = [&]() -> Any { return view; }; { Any ret = convert(); EXPECT_EQ(view.ref_cnt, 0); if (view.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIRawStr)) { - Str *str = ret; + Str* str = ret; EXPECT_EQ(ret.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)); EXPECT_STREQ(str->c_str(), view.v_str); EXPECT_EQ(ret.ref_cnt, 0); @@ -390,20 +391,20 @@ TEST(AnyView_Converter_1_Any, Any) { TEST(AnyView_Converter_2_Ref, Object) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &v : views) { + for (const AnyView& v : views) { auto convert = [&]() -> Ref<Object> { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { Ref<Object> ret = convert(); EXPECT_EQ(ret.get(), nullptr); } else if (v.type_index >= static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStaticObjectBegin)) { Ref<Object> ret = convert(); - EXPECT_EQ(ret.get(), static_cast<void *>(v.v_obj)); + EXPECT_EQ(ret.get(), static_cast<void*>(v.v_obj)); EXPECT_EQ(v.v_obj->ref_cnt, 2); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Object`"; @@ -416,19 +417,19 @@ TEST(AnyView_Converter_2_Ref, Object) { TEST(AnyView_Converter_2_Ref, Func) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &v : views) { + for (const AnyView& v : views) { auto convert = [&]() -> Ref<Func> { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { Ref<Func> ret = convert(); EXPECT_EQ(ret.get(), nullptr); } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFunc)) { Ref<Func> ret = convert(); - EXPECT_EQ(ret.get(), static_cast<void *>(v.v_obj)); + EXPECT_EQ(ret.get(), static_cast<void*>(v.v_obj)); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Func`"; @@ -441,7 +442,7 @@ TEST(AnyView_Converter_2_Ref, Func) { TEST(AnyView_Converter_2_Ref, Str) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &v : views) { + for (const AnyView& v : views) { auto convert = [&]() -> Ref<Str> { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { Ref<Str> ret = convert(); @@ -451,13 +452,13 @@ TEST(AnyView_Converter_2_Ref, Str) { EXPECT_STREQ(ret->c_str(), "Hello World (Ref<Str>)"); } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIRawStr)) { Ref<Str> ret = convert(); - EXPECT_EQ(reinterpret_cast<TVMFFIStr *>(ret.get())->ref_cnt, 1); + EXPECT_EQ(reinterpret_cast<TVMFFIStr*>(ret.get())->ref_cnt, 1); EXPECT_STREQ(ret->c_str(), v.v_str); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Str`"; @@ -470,20 +471,20 @@ TEST(AnyView_Converter_2_Ref, Str) { TEST(AnyView_Converter_3_Object_Ptr, Object) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &v : views) { - auto convert = [&]() -> Object * { return v; }; + for (const AnyView& v : views) { + auto convert = [&]() -> Object* { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Object *ret = convert(); + Object* ret = convert(); EXPECT_EQ(ret, nullptr); } else if (v.type_index >= static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStaticObjectBegin)) { - Object *ret = convert(); - EXPECT_EQ(ret, static_cast<void *>(v.v_obj)); + Object* ret = convert(); + EXPECT_EQ(ret, static_cast<void*>(v.v_obj)); EXPECT_EQ(v.v_obj->ref_cnt, 1); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Object *`"; @@ -496,19 +497,19 @@ TEST(AnyView_Converter_3_Object_Ptr, Object) { TEST(AnyView_Converter_3_Object_Ptr, Func) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &v : views) { - auto convert = [&]() -> Func * { return v; }; + for (const AnyView& v : views) { + auto convert = [&]() -> Func* { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Func *ret = convert(); + Func* ret = convert(); EXPECT_EQ(ret, nullptr); } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFunc)) { - Func *ret = convert(); - EXPECT_EQ(ret, reinterpret_cast<Func *>(v.v_ptr)); + Func* ret = convert(); + EXPECT_EQ(ret, reinterpret_cast<Func*>(v.v_ptr)); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Func *`"; @@ -521,19 +522,19 @@ TEST(AnyView_Converter_3_Object_Ptr, Func) { TEST(AnyView_Converter_3_Object_Ptr, Str) { std::vector<AnyView> views = AnyViewArrayFactory(); - for (const AnyView &v : views) { - auto convert = [&]() -> Str * { return v; }; + for (const AnyView& v : views) { + auto convert = [&]() -> Str* { return v; }; if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Str *ret = convert(); + Str* ret = convert(); EXPECT_EQ(ret, nullptr); } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)) { - Str *ret = convert(); + Str* ret = convert(); EXPECT_STREQ(ret->c_str(), "Hello World (Ref<Str>)"); } else { try { convert(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { std::ostringstream os; os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `object.Str *`"; @@ -552,7 +553,7 @@ TEST(AnyView_Stringify, Integer) { } TEST(AnyView_Stringify, Float) { - auto check = [](const AnyView &v) -> void { + auto check = [](const AnyView& v) -> void { std::string str = v.str()->c_str(); double f_str = std::stod(str); double f_src = v.v_float64; @@ -563,13 +564,13 @@ TEST(AnyView_Stringify, Float) { } TEST(AnyView_Stringify, Ptr) { - auto check = [](const AnyView &v) -> void { + auto check = [](const AnyView& v) -> void { std::string str = v.str()->c_str(); EXPECT_GT(str.size(), 2); }; - TestAnyViewStringify<void *>(nullptr, TVMFFITypeIndex::kTVMFFINone, "None"); - TestAnyViewStringifyChecker<void *>(reinterpret_cast<void *>(FuncCall), - TVMFFITypeIndex::kTVMFFIPtr, check); + TestAnyViewStringify<void*>(nullptr, TVMFFITypeIndex::kTVMFFINone, "None"); + TestAnyViewStringifyChecker<void*>(reinterpret_cast<void*>(FuncCall), TVMFFITypeIndex::kTVMFFIPtr, + check); } TEST(AnyView_Stringify, Device) { @@ -589,13 +590,13 @@ TEST(AnyView_Stringify, DataType) { } TEST(AnyView_Stringify, RawStr) { - TestAnyViewStringify<const char *>("Hello", TVMFFITypeIndex::kTVMFFIRawStr, "\"Hello\""); + TestAnyViewStringify<const char*>("Hello", TVMFFITypeIndex::kTVMFFIRawStr, "\"Hello\""); TestAnyViewStringify<char[6]>("Hello", TVMFFITypeIndex::kTVMFFIRawStr, "\"Hello\""); TestAnyViewStringify<const char[6]>("Hello", TVMFFITypeIndex::kTVMFFIRawStr, "\"Hello\""); } TEST(AnyView_Stringify, Object) { - auto check = [](const AnyView &v) -> void { + auto check = [](const AnyView& v) -> void { std::string expected_prefix = "object.Object@0"; int n = static_cast<int>(expected_prefix.size()); std::string str = v.str()->c_str(); @@ -607,7 +608,7 @@ TEST(AnyView_Stringify, Object) { } TEST(AnyView_Stringify, Func) { - auto check = [](const AnyView &v) -> void { + auto check = [](const AnyView& v) -> void { std::string expected_prefix = "object.Func@0"; int n = static_cast<int>(expected_prefix.size()); std::string str = v.str()->c_str(); @@ -619,7 +620,7 @@ TEST(AnyView_Stringify, Func) { } TEST(AnyView_Stringify, Str) { - auto check = [](const AnyView &v) -> void { + auto check = [](const AnyView& v) -> void { std::string str = v.str()->c_str(); EXPECT_EQ(str, "\"Hello World\""); }; @@ -627,4 +628,4 @@ TEST(AnyView_Stringify, Str) { check); } -} // namespace +} // namespace diff --git a/ffi/tests/cpp/test_dict.cc b/ffi/tests/backup_cpp/test_dict.cc similarity index 92% rename from ffi/tests/cpp/test_dict.cc rename to ffi/tests/backup_cpp/test_dict.cc index 04d5a2854f..53c4452401 100644 --- a/ffi/tests/cpp/test_dict.cc +++ b/ffi/tests/backup_cpp/test_dict.cc @@ -1,4 +1,5 @@ #include <gtest/gtest.h> + #include <tvm/ffi/ffi.hpp> #include <unordered_set> @@ -16,7 +17,7 @@ bool DTypeEqual(DLDataType a, DLDataType b) { TEST(Dict_Construtor, Default) { Ref<Dict> dict; ASSERT_EQ(dict.size(), 0); - TVMFFIDict *dict_ptr = reinterpret_cast<TVMFFIDict *>(dict.get()); + TVMFFIDict* dict_ptr = reinterpret_cast<TVMFFIDict*>(dict.get()); EXPECT_EQ(dict_ptr->type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIDict)); EXPECT_EQ(dict_ptr->ref_cnt, 1); EXPECT_NE(dict_ptr->deleter, nullptr); @@ -32,7 +33,7 @@ TEST(Dict_Construtor, InitializerList) { EXPECT_EQ(int(dict[3]), 4); bool found[3] = {false, false, false}; - for (const auto &kv : dict) { + for (const auto& kv : dict) { if (AnyEqual()(kv.first, Any("key1"))) { found[0] = true; EXPECT_EQ(int(kv.second), 1); @@ -65,7 +66,7 @@ TEST(Dict_Insert, New) { EXPECT_DOUBLE_EQ(double(dict[integer]), fp); EXPECT_PRED2(DTypeEqual, DLDataType(dict[str]), dtype); EXPECT_EQ(int(dict[null_obj]), 0); - EXPECT_EQ((Object *)(dict[device]), nullptr); + EXPECT_EQ((Object*)(dict[device]), nullptr); } TEST(Dict_Insert, Override) { @@ -98,7 +99,7 @@ TEST(Dict_At, NotFound) { try { dict.at("key3"); FAIL() << "Expected TVMError"; - } catch (const TVMError &e) { + } catch (const TVMError& e) { } } @@ -109,7 +110,7 @@ TEST(Dict_ReHash, POD) { } EXPECT_EQ(dict.size(), 1000); std::unordered_set<int64_t> keys; - for (auto &kv : dict) { + for (auto& kv : dict) { int64_t key = kv.first; int64_t value = kv.second; EXPECT_EQ(key, value); @@ -122,7 +123,7 @@ TEST(Dict_ReHash, POD) { TEST(Dict_ReHash, Object) { std::vector<Ref<Object>> objs; - std::unordered_map<Object *, int64_t> obj_map; + std::unordered_map<Object*, int64_t> obj_map; for (int j = 0; j < 1000; ++j) { objs.push_back(Ref<Object>::New()); obj_map[objs[j].get()] = j; @@ -132,8 +133,8 @@ TEST(Dict_ReHash, Object) { dict[objs[j]] = j; } EXPECT_EQ(dict.size(), 1000); - std::unordered_set<Object *> keys; - for (auto &kv : dict) { + std::unordered_set<Object*> keys; + for (auto& kv : dict) { Ref<Object> key = kv.first; int64_t value = kv.second; keys.insert(key.get()); @@ -160,7 +161,7 @@ TEST(Dict_Erase, POD) { TEST(Dict_Erase, Object) { std::vector<Ref<Object>> objs; - std::unordered_map<Object *, int64_t> obj_map; + std::unordered_map<Object*, int64_t> obj_map; for (int j = 0; j < 1000; ++j) { objs.push_back(Ref<Object>::New()); obj_map[objs[j].get()] = j; @@ -180,4 +181,4 @@ TEST(Dict_Erase, Object) { } } -} // namespace +} // namespace diff --git a/ffi/tests/cpp/test_func.cc b/ffi/tests/backup_cpp/test_func.cc similarity index 77% rename from ffi/tests/cpp/test_func.cc rename to ffi/tests/backup_cpp/test_func.cc index 32512d3dcf..0790692bb9 100644 --- a/ffi/tests/cpp/test_func.cc +++ b/ffi/tests/backup_cpp/test_func.cc @@ -1,12 +1,13 @@ #include <gtest/gtest.h> + #include <tvm/ffi/ffi.hpp> namespace { using namespace tvm::ffi; -const char *c_str_raw = "Hello"; +const char* c_str_raw = "Hello"; -double func_unpacked_0(int64_t a, double b, const char *c, const double &d) { +double func_unpacked_0(int64_t a, double b, const char* c, const double& d) { EXPECT_STREQ(c, c_str_raw); return a + b + d; } @@ -17,7 +18,7 @@ void func_unpacked_1(DLDataType dtype, DLDevice device, std::string str) { (void)str; } -void func_packed_0(int num_args, const AnyView *, Any *ret) { *ret = num_args; } +void func_packed_0(int num_args, const AnyView*, Any* ret) { *ret = num_args; } template <enum TVMFFITypeIndex type_index> void func_unpacked_anyview_arg(AnyView a) { @@ -30,8 +31,8 @@ void func_unpacked_any_arg(Any a) { AnyView func_unpacked_anyview_ret() { return AnyView(1); } Any func_unpacked_any_ret() { return Any(1); } -std::string func_unpacked_str_obj(Str *str, const char *str_2) { - EXPECT_EQ(reinterpret_cast<TVMFFIStr *>(str)->ref_cnt, 1); +std::string func_unpacked_str_obj(Str* str, const char* str_2) { + EXPECT_EQ(reinterpret_cast<TVMFFIStr*>(str)->ref_cnt, 1); EXPECT_STREQ(str->c_str(), str_2); return str->c_str(); } @@ -47,26 +48,23 @@ TEST(Func_Signature, 1) { } TEST(Func_Signature, AnyView_Arg) { - EXPECT_EQ(details::FuncFunctor<decltype(func_unpacked_anyview_arg< - TVMFFITypeIndex::kTVMFFIInt>)>::Sig(), - "(0: AnyView) -> void"); + EXPECT_EQ( + details::FuncFunctor<decltype(func_unpacked_anyview_arg<TVMFFITypeIndex::kTVMFFIInt>)>::Sig(), + "(0: AnyView) -> void"); } TEST(Func_Signature, AnyView_Ret) { - EXPECT_EQ(details::FuncFunctor<decltype(func_unpacked_anyview_ret)>::Sig(), - "() -> AnyView"); + EXPECT_EQ(details::FuncFunctor<decltype(func_unpacked_anyview_ret)>::Sig(), "() -> AnyView"); } TEST(Func_Signature, Any_Arg) { EXPECT_EQ( - details::FuncFunctor< - decltype(func_unpacked_any_arg<TVMFFITypeIndex::kTVMFFIInt>)>::Sig(), + details::FuncFunctor<decltype(func_unpacked_any_arg<TVMFFITypeIndex::kTVMFFIInt>)>::Sig(), "(0: Any) -> void"); } TEST(Func_Signature, Any_Ret) { - EXPECT_EQ(details::FuncFunctor<decltype(func_unpacked_any_ret)>::Sig(), - "() -> Any"); + EXPECT_EQ(details::FuncFunctor<decltype(func_unpacked_any_ret)>::Sig(), "() -> Any"); } TEST(Func_Unpacked_Invoke, Func0_RawStr) { @@ -98,8 +96,7 @@ TEST(Func_Unpacked_Invoke, Func1) { } TEST(Func_Unpacked_Invoke, AnyView_Arg) { - Ref<Func> func = - Ref<Func>::New(func_unpacked_anyview_arg<TVMFFITypeIndex::kTVMFFIInt>); + Ref<Func> func = Ref<Func>::New(func_unpacked_anyview_arg<TVMFFITypeIndex::kTVMFFIInt>); func(1); } @@ -110,8 +107,7 @@ TEST(Func_Unpacked_Invoke, AnyView_Ret) { } TEST(Func_Unpacked_Invoke, Any_Arg) { - Ref<Func> func = - Ref<Func>::New(func_unpacked_any_arg<TVMFFITypeIndex::kTVMFFIInt>); + Ref<Func> func = Ref<Func>::New(func_unpacked_any_arg<TVMFFITypeIndex::kTVMFFIInt>); func(1); } @@ -156,7 +152,7 @@ TEST(Func_Unpacked_Invoke_TypeError, TypeMismatch_0) { try { func(1.0, 2, c_str_raw, 4); FAIL() << "No execption thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { EXPECT_STREQ(ex.what(), "Mismatched type on argument #0 when calling: " "`(0: int, 1: float, 2: const char *, 3: float) -> float`. " @@ -169,10 +165,11 @@ TEST(Func_Unpacked_Invoke_TypeError, TypeMismatch_1) { try { func(DLDataType{kDLInt, 32, 1}, DLDevice{kDLCPU, 0}, 1); FAIL() << "No execption thrown"; - } catch (TVMError &ex) { - EXPECT_STREQ(ex.what(), "Mismatched type on argument #2 when calling: " - "`(0: dtype, 1: Device, 2: str) -> void`. " - "Expected `str` but got `int`"); + } catch (TVMError& ex) { + EXPECT_STREQ(ex.what(), + "Mismatched type on argument #2 when calling: " + "`(0: dtype, 1: Device, 2: str) -> void`. " + "Expected `str` but got `int`"); } } @@ -181,7 +178,7 @@ TEST(Func_Unpacked_Invoke_TypeError, ArgCountMismatch_0) { try { func(1, 2, c_str_raw); FAIL() << "No execption thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { EXPECT_STREQ(ex.what(), "Mismatched number of arguments when calling: " "`(0: int, 1: float, 2: const char *, 3: float) -> float`. " @@ -194,10 +191,11 @@ TEST(Func_Unpacked_Invoke_TypeError, ArgCountMismatch_1) { try { func(DLDataType{kDLInt, 32, 1}, DLDevice{kDLCPU, 0}); FAIL() << "No execption thrown"; - } catch (TVMError &ex) { - EXPECT_STREQ(ex.what(), "Mismatched number of arguments when calling: " - "`(0: dtype, 1: Device, 2: str) -> void`. " - "Expected 3 but got 2 arguments"); + } catch (TVMError& ex) { + EXPECT_STREQ(ex.what(), + "Mismatched number of arguments when calling: " + "`(0: dtype, 1: Device, 2: str) -> void`. " + "Expected 3 but got 2 arguments"); } } @@ -207,9 +205,9 @@ TEST(Func_Unpacked_Invoke_TypeError, ReturnTypeMismatch_0) { int ret = func(DLDataType{kDLInt, 32, 1}, DLDevice{kDLCPU, 0}, "Hello"); (void)ret; FAIL() << "No execption thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { EXPECT_STREQ(ex.what(), "Cannot convert from type `None` to `int`"); } } -} // namespace +} // namespace diff --git a/ffi/tests/cpp/test_list.cc b/ffi/tests/backup_cpp/test_list.cc similarity index 88% rename from ffi/tests/cpp/test_list.cc rename to ffi/tests/backup_cpp/test_list.cc index 53fd727af6..06b9d6a483 100644 --- a/ffi/tests/cpp/test_list.cc +++ b/ffi/tests/backup_cpp/test_list.cc @@ -1,4 +1,5 @@ #include <gtest/gtest.h> + #include <tvm/ffi/ffi.hpp> namespace { @@ -12,7 +13,7 @@ bool DeviceEqual(DLDevice a, DLDevice b) { return a.device_type == b.device_type && a.device_id == b.device_id; } -void TestSizeCapacityClear(Ref<List> *list, int64_t size, int64_t capacity) { +void TestSizeCapacityClear(Ref<List>* list, int64_t size, int64_t capacity) { EXPECT_EQ(list->size(), size); EXPECT_EQ(list->capacity(), capacity); EXPECT_EQ(list->empty(), size == 0); @@ -24,7 +25,7 @@ void TestSizeCapacityClear(Ref<List> *list, int64_t size, int64_t capacity) { TEST(List_Constructor, Default) { Ref<List> list = Ref<List>::New(); - TVMFFIList *list_ptr = reinterpret_cast<TVMFFIList *>(list.get()); + TVMFFIList* list_ptr = reinterpret_cast<TVMFFIList*>(list.get()); ASSERT_NE(list_ptr, nullptr); EXPECT_EQ(list_ptr->type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIList)); EXPECT_EQ(list_ptr->ref_cnt, 1); @@ -44,8 +45,8 @@ TEST(List_Constructor, InitializerList) { 100, 1.0f, "Hi", DLDataType{kDLInt, 32, 1}, DLDevice{kDLCPU, 0}, Ref<Object>::New(), Ref<Object>()}; - auto test = [](Ref<List> *src) { - auto *list_ptr = reinterpret_cast<const TVMFFIList *>(src->get()); + auto test = [](Ref<List>* src) { + auto* list_ptr = reinterpret_cast<const TVMFFIList*>(src->get()); ASSERT_NE(list_ptr, nullptr); EXPECT_EQ(list_ptr->type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIList)); EXPECT_EQ(list_ptr->ref_cnt, 1); @@ -53,7 +54,7 @@ TEST(List_Constructor, InitializerList) { EXPECT_EQ(list_ptr->list_capacity, 7); EXPECT_EQ(list_ptr->list_length, 7); EXPECT_EQ(list_ptr->pool_capacity, 7); - EXPECT_EQ(list_ptr->pool_length, 4); // string is not in the POD pool + EXPECT_EQ(list_ptr->pool_length, 4); // string is not in the POD pool EXPECT_EQ(src->size(), 7); EXPECT_EQ(src->capacity(), 7); EXPECT_EQ(src->empty(), false); @@ -68,7 +69,7 @@ TEST(List_PushBack, POD) { ASSERT_NE(list.get(), nullptr); list.push_back(100); list.push_back(1.0f); - TVMFFIList *list_ptr = reinterpret_cast<TVMFFIList *>(list.get()); + TVMFFIList* list_ptr = reinterpret_cast<TVMFFIList*>(list.get()); ASSERT_NE(list_ptr, nullptr); EXPECT_EQ(list_ptr->type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIList)); EXPECT_EQ(list_ptr->ref_cnt, 1); @@ -88,7 +89,7 @@ TEST(List_PushBack, Obj) { Ref<Object> obj2 = Ref<Object>::New(); list.push_back(obj1); list.push_back(obj2); - TVMFFIList *list_ptr = reinterpret_cast<TVMFFIList *>(list.get()); + TVMFFIList* list_ptr = reinterpret_cast<TVMFFIList*>(list.get()); ASSERT_NE(list_ptr, nullptr); EXPECT_EQ(list_ptr->type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIList)); EXPECT_EQ(list_ptr->ref_cnt, 1); @@ -97,8 +98,8 @@ TEST(List_PushBack, Obj) { EXPECT_EQ(list_ptr->list_length, 2); EXPECT_EQ(list_ptr->pool_capacity, 0); EXPECT_EQ(list_ptr->pool_length, 0); - EXPECT_EQ((Object *)(list[0]), obj1.get()); - EXPECT_EQ((Object *)(list[1]), obj2.get()); + EXPECT_EQ((Object*)(list[0]), obj1.get()); + EXPECT_EQ((Object*)(list[1]), obj2.get()); TestSizeCapacityClear(&list, 2, List::kMinCapacity); } @@ -138,9 +139,9 @@ TEST(List_PushBack, Heterogeneous) { std::string i_2 = list[i * k + 2]; DLDataType i_3 = list[i * k + 3]; DLDevice i_4 = list[i * k + 4]; - Object *i_5 = list[i * k + 5]; - Object *i_6 = list[i * k + 6]; - const char *i_7 = list[i * k + 7]; + Object* i_5 = list[i * k + 5]; + Object* i_6 = list[i * k + 6]; + const char* i_7 = list[i * k + 7]; EXPECT_EQ(i_0, integer); EXPECT_DOUBLE_EQ(i_1, fp); EXPECT_EQ(i_2, str); @@ -150,7 +151,7 @@ TEST(List_PushBack, Heterogeneous) { EXPECT_EQ(i_6, nullptr); EXPECT_STREQ(i_7, long_str.c_str()); } - auto *list_ptr = reinterpret_cast<const TVMFFIList *>(list.get()); + auto* list_ptr = reinterpret_cast<const TVMFFIList*>(list.get()); EXPECT_EQ(list_ptr->list_capacity, expected_capacity); EXPECT_EQ(list_ptr->list_length, expected_size); EXPECT_EQ(list_ptr->pool_capacity, expected_pool_capacity); @@ -160,7 +161,7 @@ TEST(List_PushBack, Heterogeneous) { TEST(List_Insert, Once) { Ref<List> values = {100, 1.0, - "Hi", // + "Hi", // DLDataType{kDLInt, 32, 1}, DLDevice{kDLCPU, 0}, Ref<Object>::New(), @@ -192,7 +193,7 @@ TEST(List_Insert, Error_0) { try { list.insert(-1, 1.0); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { EXPECT_STREQ(ex.what(), "Indexing `-1` of a list of size 3"); } } @@ -202,7 +203,7 @@ TEST(List_Insert, Error_1) { try { list.insert(4, 1.0); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { EXPECT_STREQ(ex.what(), "Indexing `4` of a list of size 3"); } } @@ -224,7 +225,7 @@ TEST(List_Resize, Expand) { EXPECT_EQ(int32_t(list[0]), 100); EXPECT_DOUBLE_EQ(double(list[1]), 1.0); EXPECT_STREQ(list[2], "Hi"); - EXPECT_EQ(list[3].operator void *(), nullptr); + EXPECT_EQ(list[3].operator void*(), nullptr); } TEST(List_Reserve, Shrink) { @@ -259,7 +260,7 @@ TEST(List_SetItem, PodToPod) { } EXPECT_EQ(list.size(), 3); EXPECT_EQ(list.capacity(), 3); - TVMFFIList *list_ptr = reinterpret_cast<TVMFFIList *>(list.get()); + TVMFFIList* list_ptr = reinterpret_cast<TVMFFIList*>(list.get()); EXPECT_EQ(list_ptr->list_capacity, 3); EXPECT_EQ(list_ptr->list_length, 3); EXPECT_EQ(list_ptr->pool_capacity, 24); @@ -267,7 +268,7 @@ TEST(List_SetItem, PodToPod) { } TEST(List_SetItem, ObjToPod) { - Ref<List> list = {100, 1.0, "Hi"}; // + Ref<List> list = {100, 1.0, "Hi"}; // for (int i = 0; i < 16; ++i) { list[2] = i; EXPECT_EQ(list.size(), 3); @@ -278,7 +279,7 @@ TEST(List_SetItem, ObjToPod) { } EXPECT_EQ(list.size(), 3); EXPECT_EQ(list.capacity(), 3); - TVMFFIList *list_ptr = reinterpret_cast<TVMFFIList *>(list.get()); + TVMFFIList* list_ptr = reinterpret_cast<TVMFFIList*>(list.get()); EXPECT_EQ(list_ptr->list_capacity, 3); EXPECT_EQ(list_ptr->list_length, 3); EXPECT_EQ(list_ptr->pool_capacity, 24); @@ -292,13 +293,13 @@ TEST(List_SetItem, PodToObj) { list[0] = obj; EXPECT_EQ(list.size(), 3); EXPECT_EQ(list.capacity(), 3); - EXPECT_EQ((Object *)(list[0]), obj.get()); + EXPECT_EQ((Object*)(list[0]), obj.get()); EXPECT_DOUBLE_EQ(double(list[1]), 1.0); EXPECT_STREQ(list[2], "Hi"); } EXPECT_EQ(list.size(), 3); EXPECT_EQ(list.capacity(), 3); - TVMFFIList *list_ptr = reinterpret_cast<TVMFFIList *>(list.get()); + TVMFFIList* list_ptr = reinterpret_cast<TVMFFIList*>(list.get()); EXPECT_EQ(list_ptr->list_capacity, 3); EXPECT_EQ(list_ptr->list_length, 3); EXPECT_EQ(list_ptr->pool_capacity, 3); @@ -314,11 +315,11 @@ TEST(List_SetItem, ObjToObj) { EXPECT_EQ(list.capacity(), 3); EXPECT_EQ(int32_t(list[0]), 100); EXPECT_DOUBLE_EQ(double(list[1]), 1.0); - EXPECT_EQ((Object *)(list[2]), obj.get()); + EXPECT_EQ((Object*)(list[2]), obj.get()); } EXPECT_EQ(list.size(), 3); EXPECT_EQ(list.capacity(), 3); - TVMFFIList *list_ptr = reinterpret_cast<TVMFFIList *>(list.get()); + TVMFFIList* list_ptr = reinterpret_cast<TVMFFIList*>(list.get()); EXPECT_EQ(list_ptr->list_capacity, 3); EXPECT_EQ(list_ptr->list_length, 3); EXPECT_EQ(list_ptr->pool_capacity, 3); @@ -356,10 +357,10 @@ TEST(List_PopBack, Heterogeneous) { EXPECT_PRED2(DeviceEqual, DLDevice(list[4]), device); } if (m > 5) { - EXPECT_EQ((Object *)(list[5]), obj.get()); + EXPECT_EQ((Object*)(list[5]), obj.get()); } if (m > 6) { - EXPECT_EQ((Object *)(list[6]), nullptr); + EXPECT_EQ((Object*)(list[6]), nullptr); } } EXPECT_EQ(list.size(), 0); @@ -369,7 +370,7 @@ TEST(List_PopBack, Heterogeneous) { try { list.pop_back(); FAIL() << "No exception thrown"; - } catch (TVMError &ex) { + } catch (TVMError& ex) { EXPECT_STREQ(ex.what(), "Indexing `-1` of a list of size 0"); } } @@ -390,8 +391,8 @@ TEST(List_Erase, Front) { EXPECT_STREQ(list[1], "Hi"); EXPECT_PRED2(DTypeEqual, DLDataType(list[2]), dtype); EXPECT_PRED2(DeviceEqual, DLDevice(list[3]), device); - EXPECT_EQ((Object *)(list[4]), obj.get()); - EXPECT_EQ((Object *)(list[5]), nullptr); + EXPECT_EQ((Object*)(list[4]), obj.get()); + EXPECT_EQ((Object*)(list[5]), nullptr); } TEST(List_Erase, Back) { @@ -410,8 +411,8 @@ TEST(List_Erase, Back) { EXPECT_STREQ(list[1], "Hi"); EXPECT_PRED2(DTypeEqual, DLDataType(list[2]), dtype); EXPECT_PRED2(DeviceEqual, DLDevice(list[3]), device); - EXPECT_EQ((Object *)(list[4]), obj.get()); - EXPECT_EQ((Object *)(list[5]), nullptr); + EXPECT_EQ((Object*)(list[4]), obj.get()); + EXPECT_EQ((Object*)(list[5]), nullptr); } TEST(List_Erase, Mid) { @@ -430,8 +431,8 @@ TEST(List_Erase, Mid) { EXPECT_DOUBLE_EQ(double(list[1]), 1.0); EXPECT_STREQ(list[2], "Hi"); EXPECT_PRED2(DeviceEqual, DLDevice(list[3]), device); - EXPECT_EQ((Object *)(list[4]), obj.get()); - EXPECT_EQ((Object *)(list[5]), nullptr); + EXPECT_EQ((Object*)(list[4]), obj.get()); + EXPECT_EQ((Object*)(list[5]), nullptr); } TEST(List_Iter, Test) { @@ -458,4 +459,4 @@ TEST(List_RevIter, Test) { } } -} // namespace +} // namespace diff --git a/ffi/tests/cpp/test_ref.cc b/ffi/tests/backup_cpp/test_ref.cc similarity index 80% rename from ffi/tests/cpp/test_ref.cc rename to ffi/tests/backup_cpp/test_ref.cc index 3c9dc0561d..197f2def88 100644 --- a/ffi/tests/cpp/test_ref.cc +++ b/ffi/tests/backup_cpp/test_ref.cc @@ -1,4 +1,5 @@ #include <gtest/gtest.h> + #include <tvm/ffi/ffi.hpp> #include <unordered_map> @@ -7,30 +8,30 @@ using namespace tvm::ffi; using tvm::ffi::details::StrPad; using tvm::ffi::details::StrStd; -using ObjDeleter = void (*)(void *); +using ObjDeleter = void (*)(void*); struct AllocRecorder { - std::unordered_map<void *, ObjDeleter> deleters; + std::unordered_map<void*, ObjDeleter> deleters; - void Alloc(void *ptr) { - deleters[ptr] = reinterpret_cast<TVMFFIAny *>(ptr)->deleter; - reinterpret_cast<TVMFFIAny *>(ptr)->deleter = AllocRecorder::Deleter; + void Alloc(void* ptr) { + deleters[ptr] = reinterpret_cast<TVMFFIAny*>(ptr)->deleter; + reinterpret_cast<TVMFFIAny*>(ptr)->deleter = AllocRecorder::Deleter; } - void Delete(void *ptr) { + void Delete(void* ptr) { ASSERT_EQ(deleters.count(ptr), 1); ObjDeleter d = this->deleters[ptr]; d(ptr); deleters.erase(ptr); } - bool IsDeletedImpl(void *ptr) { return deleters.count(ptr) == 0; } + bool IsDeletedImpl(void* ptr) { return deleters.count(ptr) == 0; } - static void Deleter(void *ptr) { AllocRecorder::Global()->Delete(ptr); } + static void Deleter(void* ptr) { AllocRecorder::Global()->Delete(ptr); } - static bool IsDeleted(void *ptr) { return AllocRecorder::Global()->IsDeletedImpl(ptr); } + static bool IsDeleted(void* ptr) { return AllocRecorder::Global()->IsDeletedImpl(ptr); } - static AllocRecorder *Global() { + static AllocRecorder* Global() { static AllocRecorder inst; return &inst; } @@ -41,15 +42,15 @@ struct TestAllocator { using Allocator = typename ::tvm::ffi::GetAllocator<ObjectType>::Type; template <typename... Args> - TVM_FFI_INLINE static ObjectType *New(Args &&...args) { - ObjectType *ret = Allocator::New(std::forward<Args>(args)...); + TVM_FFI_INLINE static ObjectType* New(Args&&... args) { + ObjectType* ret = Allocator::New(std::forward<Args>(args)...); AllocRecorder::Global()->Alloc(ret); return ret; } template <typename PadType, typename... Args> - TVM_FFI_INLINE static ObjectType *NewWithPad(size_t pad_size, Args &&...args) { - ObjectType *ret = + TVM_FFI_INLINE static ObjectType* NewWithPad(size_t pad_size, Args&&... args) { + ObjectType* ret = Allocator::template NewWithPad<PadType>(pad_size, std::forward<Args>(args)...); AllocRecorder::Global()->Alloc(ret); return ret; @@ -58,11 +59,11 @@ struct TestAllocator { int64_t FuncCall(int64_t x) { return x + 1; } -int32_t GetRefCount(void *obj) { return reinterpret_cast<TVMFFIAny *>(obj)->ref_cnt; } +int32_t GetRefCount(void* obj) { return reinterpret_cast<TVMFFIAny*>(obj)->ref_cnt; } -int32_t GetTypeIndex(void *obj) { return reinterpret_cast<TVMFFIAny *>(obj)->type_index; } +int32_t GetTypeIndex(void* obj) { return reinterpret_cast<TVMFFIAny*>(obj)->type_index; } -ObjDeleter GetDeleter(void *obj) { return reinterpret_cast<TVMFFIAny *>(obj)->deleter; } +ObjDeleter GetDeleter(void* obj) { return reinterpret_cast<TVMFFIAny*>(obj)->deleter; } TEST(Ref_Constructor_0_Default, Default) { Ref<Object> ref; @@ -70,7 +71,7 @@ TEST(Ref_Constructor_0_Default, Default) { } TEST(Ref_Constructor_1_Ptr, SameType) { - Object *obj = TestAllocator<Object>::New(); + Object* obj = TestAllocator<Object>::New(); { Ref<Object> ref(obj); EXPECT_EQ(ref.get(), obj); @@ -80,17 +81,17 @@ TEST(Ref_Constructor_1_Ptr, SameType) { } TEST(Ref_Constructor_1_Ptr, SubType) { - Str *obj = TestAllocator<Str>::New("Hello world"); + Str* obj = TestAllocator<Str>::New("Hello world"); { Ref<Object> ref(obj); - EXPECT_EQ(ref.get(), static_cast<void *>(obj)); + EXPECT_EQ(ref.get(), static_cast<void*>(obj)); EXPECT_EQ(GetRefCount(obj), 1); } EXPECT_TRUE(AllocRecorder::IsDeleted(obj)); } TEST(Ref_Constructor_2_Ref, SameType_Copy) { - Object *obj = TestAllocator<Object>::New(); + Object* obj = TestAllocator<Object>::New(); { Ref<Object> ref1(obj); EXPECT_EQ(GetRefCount(obj), 1); @@ -104,7 +105,7 @@ TEST(Ref_Constructor_2_Ref, SameType_Copy) { } TEST(Ref_Constructor_2_Ref, SameType_Move) { - Object *obj = TestAllocator<Object>::New(); + Object* obj = TestAllocator<Object>::New(); { Ref<Object> ref1(obj); EXPECT_EQ(GetRefCount(obj), 1); @@ -118,7 +119,7 @@ TEST(Ref_Constructor_2_Ref, SameType_Move) { } TEST(Ref_Constructor_2_Ref, SubType_Copy) { - Str *obj = TestAllocator<Str>::New("Hello world"); + Str* obj = TestAllocator<Str>::New("Hello world"); { Ref<Str> ref1(obj); EXPECT_EQ(GetRefCount(obj), 1); @@ -132,7 +133,7 @@ TEST(Ref_Constructor_2_Ref, SubType_Copy) { } TEST(Ref_Constructor_2_Ref, SubType_Move) { - Str *obj = TestAllocator<Str>::New("Hello world"); + Str* obj = TestAllocator<Str>::New("Hello world"); { Ref<Str> ref1(obj); EXPECT_EQ(GetRefCount(obj), 1); @@ -146,7 +147,7 @@ TEST(Ref_Constructor_2_Ref, SubType_Move) { } TEST(Ref_Constructor_3_AnyView, Copy) { - Object *obj = TestAllocator<Object>::New(); + Object* obj = TestAllocator<Object>::New(); { Ref<Object> ref1(obj); EXPECT_EQ(GetRefCount(obj), 1); @@ -161,7 +162,7 @@ TEST(Ref_Constructor_3_AnyView, Copy) { } TEST(Ref_Constructor_3_AnyView, Move) { - Object *obj = TestAllocator<Object>::New(); + Object* obj = TestAllocator<Object>::New(); { Ref<Object> ref1(obj); EXPECT_EQ(GetRefCount(obj), 1); @@ -182,7 +183,7 @@ TEST(Ref_Constructor_3_AnyView, Move) { } TEST(Ref_Constructor_4_Any, Copy) { - Object *obj = TestAllocator<Object>::New(); + Object* obj = TestAllocator<Object>::New(); { Ref<Object> ref1(obj); EXPECT_EQ(GetRefCount(obj), 1); @@ -198,7 +199,7 @@ TEST(Ref_Constructor_4_Any, Copy) { } TEST(Ref_Constructor_4_Any, Move) { - Object *obj = TestAllocator<Object>::New(); + Object* obj = TestAllocator<Object>::New(); { Ref<Object> ref1(obj); EXPECT_EQ(GetRefCount(obj), 1); @@ -231,7 +232,7 @@ TEST(Ref_New, Func) { } TEST(Ref_New, RawStr) { - const char *str = "Hello world"; + const char* str = "Hello world"; Ref<Str> ref = Ref<Str>::New(str); EXPECT_EQ(GetTypeIndex(ref.get()), static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)); EXPECT_EQ(GetRefCount(ref.get()), 1); @@ -283,11 +284,11 @@ TEST(Ref_Stringify, Str) { } TEST(Ref_Misc, MoveToRaw) { - TVMFFIAny *str = reinterpret_cast<TVMFFIAny *>(Ref<Str>::New("Hello world").MoveToRawObjPtr()); + TVMFFIAny* str = reinterpret_cast<TVMFFIAny*>(Ref<Str>::New("Hello world").MoveToRawObjPtr()); EXPECT_EQ(GetTypeIndex(str), static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)); EXPECT_EQ(GetRefCount(str), 1); EXPECT_EQ(GetDeleter(str), DefaultObjectAllocator<StrPad>::Deleter); str->deleter(str); } -} // namespace +} // namespace diff --git a/ffi/tests/cpp/test_str.cc b/ffi/tests/backup_cpp/test_str.cc similarity index 81% rename from ffi/tests/cpp/test_str.cc rename to ffi/tests/backup_cpp/test_str.cc index bd91f241f6..c0b38c2935 100644 --- a/ffi/tests/cpp/test_str.cc +++ b/ffi/tests/backup_cpp/test_str.cc @@ -1,11 +1,13 @@ #include <gtest/gtest.h> + #include <tvm/ffi/ffi.hpp> namespace { using namespace tvm::ffi; -const char c_str_long[] = "Hello, World! This is an extremely long string to " - "avoid any on-stack optimization."; +const char c_str_long[] = + "Hello, World! This is an extremely long string to " + "avoid any on-stack optimization."; TEST(Str, CopyFromStdString) { std::string std_str = "Hello, World!"; @@ -17,9 +19,9 @@ TEST(Str, CopyFromStdString) { TEST(Str, MoveFromStdString_0) { std::string std_str = c_str_long; - const void *data = std_str.data(); + const void* data = std_str.data(); Ref<Str> str = Ref<Str>::New(std::move(std_str)); - EXPECT_EQ(static_cast<const void *>(str->data()), data); + EXPECT_EQ(static_cast<const void*>(str->data()), data); EXPECT_STREQ(str->c_str(), c_str_long); } @@ -44,4 +46,4 @@ TEST(Str, CopyFromCharArray) { EXPECT_EQ(str->size(), 17); } -} // namespace +} // namespace diff --git a/ffi/tests/cpp/test_type_dyn.cc b/ffi/tests/backup_cpp/test_type_dyn.cc similarity index 82% rename from ffi/tests/cpp/test_type_dyn.cc rename to ffi/tests/backup_cpp/test_type_dyn.cc index 45910528b3..b93595dc3b 100644 --- a/ffi/tests/cpp/test_type_dyn.cc +++ b/ffi/tests/backup_cpp/test_type_dyn.cc @@ -1,4 +1,5 @@ #include <gtest/gtest.h> + #include <tvm/ffi/ffi.hpp> #if TVM_FFI_ALLOW_DYN_TYPE == 1 @@ -18,8 +19,7 @@ struct SubTestObj : public TestObj { TVM_FFI_DEF_DYN_TYPE(SubTestObj, TestObj, "test.SubTestObj"); }; -void CheckAncestor(int32_t num, const int32_t *ancestors, - std::vector<int32_t> expected) { +void CheckAncestor(int32_t num, const int32_t* ancestors, std::vector<int32_t> expected) { EXPECT_EQ(num, expected.size()); for (int i = 0; i < num; ++i) { EXPECT_EQ(ancestors[i], expected[i]); @@ -27,8 +27,7 @@ void CheckAncestor(int32_t num, const int32_t *ancestors, } TEST(DynTypeInfo, TestObj) { - EXPECT_GE(TestObj::_type_index, - static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIDynObjectBegin)); + EXPECT_GE(TestObj::_type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIDynObjectBegin)); EXPECT_STRCASEEQ(TestObj::_type_key, "test.TestObj"); EXPECT_EQ(TestObj::_type_depth, 1); CheckAncestor(TestObj::_type_depth, TestObj::_type_ancestors.data(), @@ -36,14 +35,12 @@ TEST(DynTypeInfo, TestObj) { } TEST(DynTypeInfo, SubTestObj) { - EXPECT_GE(SubTestObj::_type_index, - static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIDynObjectBegin)); + EXPECT_GE(SubTestObj::_type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIDynObjectBegin)); EXPECT_NE(SubTestObj::_type_index, TestObj::_type_index); EXPECT_STRCASEEQ(SubTestObj::_type_key, "test.SubTestObj"); EXPECT_EQ(SubTestObj::_type_depth, 2); CheckAncestor(SubTestObj::_type_depth, SubTestObj::_type_ancestors.data(), - {static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject), - TestObj::_type_index}); + {static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject), TestObj::_type_index}); } TEST(DynTypeInheritance, TestObj) { @@ -66,6 +63,6 @@ TEST(DynTypeInheritance, SubTestObj) { EXPECT_FALSE(obj->IsInstance<Str>()); } -} // namespace +} // namespace #endif diff --git a/ffi/tests/cpp/test_type_static.cc b/ffi/tests/backup_cpp/test_type_static.cc similarity index 87% rename from ffi/tests/cpp/test_type_static.cc rename to ffi/tests/backup_cpp/test_type_static.cc index aebeba7c3e..abb21af2f5 100644 --- a/ffi/tests/cpp/test_type_static.cc +++ b/ffi/tests/backup_cpp/test_type_static.cc @@ -1,4 +1,5 @@ #include <gtest/gtest.h> + #include <tvm/ffi/ffi.hpp> namespace { @@ -15,8 +16,7 @@ struct SubType : public Object { int64_t FuncCall(int64_t x) { return x + 1; } -void CheckAncestor(int32_t num, const int32_t *ancestors, - std::vector<int32_t> expected) { +void CheckAncestor(int32_t num, const int32_t* ancestors, std::vector<int32_t> expected) { EXPECT_EQ(num, expected.size()); for (int i = 0; i < num; ++i) { EXPECT_EQ(ancestors[i], expected[i]); @@ -28,16 +28,14 @@ static_assert(IsObject<Func>, "IsObject<Func> == true"); static_assert(IsObject<Str>, "IsObject<Str> == true"); TEST(StaticTypeInfo, Object) { - EXPECT_EQ(Object::_type_index, - static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject)); + EXPECT_EQ(Object::_type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject)); EXPECT_STRCASEEQ(Object::_type_key, "object.Object"); EXPECT_EQ(Object::_type_depth, 0); CheckAncestor(Object::_type_depth, Object::_type_ancestors.data(), {}); } TEST(StaticTypeInfo, Func) { - EXPECT_EQ(Func::_type_index, - static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFunc)); + EXPECT_EQ(Func::_type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFunc)); EXPECT_STRCASEEQ(Func::_type_key, "object.Func"); EXPECT_EQ(Func::_type_depth, 1); CheckAncestor(Func::_type_depth, Func::_type_ancestors.data(), @@ -45,8 +43,7 @@ TEST(StaticTypeInfo, Func) { } TEST(StaticTypeInfo, Str) { - EXPECT_EQ(Str::_type_index, - static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)); + EXPECT_EQ(Str::_type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)); EXPECT_STRCASEEQ(Str::_type_key, "object.Str"); EXPECT_EQ(Str::_type_depth, 1); CheckAncestor(Str::_type_depth, Str::_type_ancestors.data(), @@ -111,9 +108,9 @@ TEST(StaticTypeSubclass, Exception) { try { Ref<SubType>::New(1); FAIL() << "No exception thrown"; - } catch (std::runtime_error &ex) { + } catch (std::runtime_error& ex) { EXPECT_STREQ(ex.what(), "New Error"); } } -} // namespace +} // namespace diff --git a/ffi/tests/cpp/CMakeLists.txt b/ffi/tests/cpp/CMakeLists.txt index 539115f24d..62543756b9 100644 --- a/ffi/tests/cpp/CMakeLists.txt +++ b/ffi/tests/cpp/CMakeLists.txt @@ -17,8 +17,8 @@ set_target_properties( add_cxx_warning(tvm_ffi_tests) add_sanitizer_address(tvm_ffi_tests) target_link_libraries(tvm_ffi_tests PRIVATE tvm_ffi) -if (TVM_FFI_ALLOW_DYN_TYPE) - add_sanitizer_address(tvm_ffi_registry_shared) + +if (TVM_FFI_BUILD_REGISTRY) target_link_libraries(tvm_ffi_tests PRIVATE tvm_ffi_registry_shared) endif() diff --git a/ffi/tests/cpp/test_any.cc b/ffi/tests/cpp/test_any.cc index a57829bd0a..2cb3e8b95b 100644 --- a/ffi/tests/cpp/test_any.cc +++ b/ffi/tests/cpp/test_any.cc @@ -1,635 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 <gtest/gtest.h> -#include <tvm/ffi/ffi.hpp> +#include <tvm/ffi/any.h> +#include <tvm/ffi/memory.h> -namespace { -using namespace tvm::ffi; - -template <typename SrcType, typename Checker> -void TestAnyConstructor(Checker check, TVMFFITypeIndex expected_type_index, const SrcType &source) { - Any v(source); - EXPECT_EQ(v.type_index, static_cast<int32_t>(expected_type_index)); - EXPECT_EQ(v.ref_cnt, 0); - check(&v, source); -}; - -int64_t FuncCall(int64_t x) { return x + 1; } - -std::vector<Any> AnyArrayFactory() { - return std::vector<Any>{ - Any(nullptr), - Any(1), - Any(2.5), - Any(reinterpret_cast<void *>(FuncCall)), - Any(DLDevice{kDLCPU, 0}), - Any(DLDataType{kDLInt, 32, 1}), - Any("Hello (raw str)"), - Any(Ref<Object>::New()), - Any(Ref<Func>::New(FuncCall)), - Any(std::string("World (std::string)")), - Any(Ref<Str>::New("Hello World (Ref<Str>)")), - }; -} - -template <typename SrcType> -void TestAnyStringify(const SrcType &source, TVMFFITypeIndex expected_type_index, - const std::string &expected) { - Any v(source); - EXPECT_EQ(v.type_index, static_cast<int32_t>(expected_type_index)); - EXPECT_EQ(v.str()->c_str(), expected); -} - -template <typename SrcType, typename Checker> -void TestAnyStringifyChecker(const SrcType &source, TVMFFITypeIndex expected_type_index, - Checker check) { - Any v(source); - EXPECT_EQ(v.type_index, static_cast<int32_t>(expected_type_index)); - check(v); -} - -void CheckAnyRefCnt(const TVMFFIAny *v) { - if (v->type_index >= static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStaticObjectBegin)) { - EXPECT_EQ(v->v_obj->ref_cnt, 1); - } -} - -TEST(Any_Constructor_0_Default, Default) { - Any v; - EXPECT_EQ(v.type_index, 0); - EXPECT_EQ(v.ref_cnt, 0); - EXPECT_EQ(v.v_int64, 0); -} - -TEST(Any_Constructor_1_Any, Copy) { - Any v1(1); - Any v2(v1); - EXPECT_EQ(v1.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)); - EXPECT_EQ(v1.v_int64, 1); - EXPECT_EQ(v2.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)); - EXPECT_EQ(v2.v_int64, 1); -} - -TEST(Any_Constructor_1_Any, Move) { - Any v1(1); - Any v2(std::move(v1)); - EXPECT_EQ(v1.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)); - EXPECT_EQ(v1.v_int64, 0); - EXPECT_EQ(v2.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)); - EXPECT_EQ(v2.v_int64, 1); -} - -TEST(Any_Constructor_2_AnyView, Copy) { - AnyView v1(1); - Any v2(v1); - EXPECT_EQ(v1.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)); - EXPECT_EQ(v1.v_int64, 1); - EXPECT_EQ(v2.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)); - EXPECT_EQ(v2.v_int64, 1); -} - -TEST(Any_Constructor_2_AnyView, Move) { - AnyView v1(1); - Any v2(std::move(v1)); - EXPECT_EQ(v1.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)); - EXPECT_EQ(v1.v_int64, 0); - EXPECT_EQ(v2.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)); - EXPECT_EQ(v2.v_int64, 1); -} - -TEST(Any_Constructor_3_Ref, Copy) { - Ref<Object> obj = Ref<Object>::New(); - Any v(obj); - const TVMFFIAny *v_obj = v.v_obj; - EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject)); - EXPECT_EQ(v.ref_cnt, 0); - EXPECT_EQ(v_obj, static_cast<const void *>(obj.get())); - EXPECT_EQ(v_obj->ref_cnt, 2); -} +#include "./testing_object.h" -TEST(Any_Constructor_3_Ref, Move) { - Ref<Object> obj = Ref<Object>::New(); - Any v(std::move(obj)); - const TVMFFIAny *v_obj = v.v_obj; - EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject)); - EXPECT_EQ(v.ref_cnt, 0); - EXPECT_EQ(v_obj->ref_cnt, 1); - EXPECT_EQ(obj.get(), nullptr); -} - -TEST(Any_Constructor_4_TypeTraits, Integer) { - auto check = [](TVMFFIAny *v, int64_t source) -> void { EXPECT_EQ(v->v_int64, source); }; - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<int8_t>(1)); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<int16_t>(2)); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<int32_t>(3)); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<int64_t>(4)); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<uint8_t>(1)); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<uint16_t>(2)); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<uint32_t>(3)); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIInt, static_cast<uint64_t>(4)); -} - -TEST(Any_Constructor_4_TypeTraits, Float) { - auto check = [](TVMFFIAny *v, double source) -> void { EXPECT_EQ(v->v_float64, source); }; - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIFloat, static_cast<float>(3)); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIFloat, static_cast<float>(4)); -} - -TEST(Any_Constructor_4_TypeTraits, Ptr) { - int p = 4; - auto check = [](TVMFFIAny *v, void *source) -> void { EXPECT_EQ(v->v_ptr, source); }; - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFINone, static_cast<void *>(nullptr)); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIPtr, static_cast<void *>(&p)); -} - -TEST(Any_Constructor_4_TypeTraits, Device) { - auto check = [](TVMFFIAny *v, const DLDevice &source) -> void { - EXPECT_EQ(v->v_device.device_type, source.device_type); - EXPECT_EQ(v->v_device.device_id, source.device_id); - }; - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIDevice, DLDevice{kDLCPU, 0}); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIDevice, DLDevice{kDLCUDA, 1}); -} - -TEST(Any_Constructor_4_TypeTraits, DataType) { - auto check = [](TVMFFIAny *v, const DLDataType &source) -> void { - EXPECT_EQ(v->v_dtype.code, source.code); - EXPECT_EQ(v->v_dtype.bits, source.bits); - EXPECT_EQ(v->v_dtype.lanes, source.lanes); - }; - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIDataType, DLDataType{kDLInt, 32, 1}); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIDataType, DLDataType{kDLUInt, 0, 0}); -} - -TEST(Any_Constructor_4_TypeTraits, RawStr) { - auto check = [](TVMFFIAny *v, const char *source) -> void { - Str *str = static_cast<Str *>(v->v_ptr); - EXPECT_STREQ(str->c_str(), source); - }; - const char *empty = ""; - const char *hello = "hello"; - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIStr, empty); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIStr, hello); -} - -TEST(Any_Constructor_4_TypeTraits, CharArray) { - auto check = [](TVMFFIAny *v, const char *source) -> void { - Str *str = static_cast<Str *>(v->v_ptr); - EXPECT_STREQ(str->c_str(), source); - }; - const char empty[] = ""; - const char hello[] = "hello"; - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIStr, empty); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIStr, hello); -} - -TEST(Any_Constructor_4_TypeTraits, StdString) { - auto check = [](TVMFFIAny *v, const std::string &source) -> void { - Str *str = static_cast<Str *>(v->v_ptr); - EXPECT_EQ(str->c_str(), source); - }; - std::string empty = ""; - std::string hello = "hello"; - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIStr, hello); - TestAnyConstructor(check, TVMFFITypeIndex::kTVMFFIStr, empty); -} - -TEST(Any_Constructor_5_Object_Ptr, Object) { - Ref<Object> obj = Ref<Object>::New(); - TVMFFIAny *ptr = reinterpret_cast<TVMFFIAny *>(obj.get()); - { - Any v(obj.get()); - EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIObject)); - EXPECT_EQ(v.v_obj->ref_cnt, 2); - EXPECT_EQ(v.v_obj, ptr); - } - EXPECT_EQ(ptr->ref_cnt, 1); -} - -TEST(Any_Constructor_5_Object_Ptr, Func) { - Ref<Func> func = Ref<Func>::New(FuncCall); - TVMFFIAny *ptr = reinterpret_cast<TVMFFIAny *>(func.get()); - { - Any v(func.get()); - EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFunc)); - EXPECT_EQ(v.v_obj->ref_cnt, 2); - EXPECT_EQ(v.v_obj, ptr); - } - EXPECT_EQ(ptr->ref_cnt, 1); -} - -TEST(Any_Constructor_5_Object_Ptr, Str) { - Ref<Str> str = Ref<Str>::New("hello"); - TVMFFIAny *ptr = reinterpret_cast<TVMFFIAny *>(str.get()); - { - Any v(str.get()); - EXPECT_EQ(v.type_index, static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)); - EXPECT_EQ(v.v_obj->ref_cnt, 2); - EXPECT_EQ(v.v_obj, ptr); - } - EXPECT_EQ(ptr->ref_cnt, 1); -} - -TEST(Any_Converter_0_TypeTraits, Integer) { - std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { - auto convert = [&]() -> int64_t { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)) { - EXPECT_EQ(convert(), 1); - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `int`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_0_TypeTraits, Float) { - std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { - auto convert = [&]() -> double { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIInt)) { - EXPECT_EQ(convert(), 1.0); - } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFloat)) { - EXPECT_EQ(convert(), 2.5); - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `float`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_0_TypeTraits, Ptr) { - std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { - auto convert = [&]() -> void * { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - EXPECT_EQ(convert(), nullptr); - } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIPtr)) { - EXPECT_EQ(convert(), reinterpret_cast<void *>(&FuncCall)); - } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIRawStr)) { - EXPECT_EQ(convert(), v.v_str); - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `Ptr`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_0_TypeTraits, Device) { - std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { - auto convert = [&]() -> DLDevice { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIDevice)) { - EXPECT_EQ(convert().device_type, kDLCPU); - EXPECT_EQ(convert().device_id, 0); - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `Device`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_0_TypeTraits, DataType) { - std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { - auto convert = [&]() -> DLDataType { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIDataType)) { - EXPECT_EQ(convert().code, kDLInt); - EXPECT_EQ(convert().bits, 32); - EXPECT_EQ(convert().lanes, 1); - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) << "` to `dtype`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_0_TypeTraits, RawStr) { - std::vector<Any> vs = AnyArrayFactory(); - int counter = 0; - for (const Any &v : vs) { - auto convert = [&]() -> const char * { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)) { - ++counter; - EXPECT_LE(counter, 3); - if (counter == 1) { - EXPECT_STREQ(convert(), "Hello (raw str)"); - } else if (counter == 2) { - EXPECT_STREQ(convert(), "World (std::string)"); - } else if (counter == 3) { - EXPECT_STREQ(convert(), "Hello World (Ref<Str>)"); - } - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) - << "` to `const char *`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_1_AnyView, Any) { - std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { - auto convert = [&]() -> AnyView { return v; }; - { - AnyView ret = convert(); - EXPECT_EQ(ret.type_index, v.type_index); - EXPECT_EQ(ret.ref_cnt, 0); - EXPECT_EQ(v.ref_cnt, 0); - EXPECT_EQ(ret.v_obj, v.v_obj); - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_2_Ref, Object) { - std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { - auto convert = [&]() -> Ref<Object> { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Ref<Object> ret = convert(); - EXPECT_EQ(ret.get(), nullptr); - } else if (v.type_index >= static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStaticObjectBegin)) { - Ref<Object> ret = convert(); - EXPECT_EQ(ret.get(), static_cast<void *>(v.v_obj)); - EXPECT_EQ(v.v_obj->ref_cnt, 2); - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) - << "` to `object.Object`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_2_Ref, Func) { - std::vector<Any> views = AnyArrayFactory(); - for (const Any &v : views) { - auto convert = [&]() -> Ref<Func> { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Ref<Func> ret = convert(); - EXPECT_EQ(ret.get(), nullptr); - } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFunc)) { - Ref<Func> ret = convert(); - EXPECT_EQ(ret.get(), static_cast<void *>(v.v_obj)); - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) - << "` to `object.Func`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_2_Ref, Str) { - int counter = 0; - std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { - auto convert = [&]() -> Ref<Str> { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Ref<Str> ret = convert(); - EXPECT_EQ(ret.get(), nullptr); - } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)) { - Ref<Str> ret = convert(); - ++counter; - EXPECT_LE(counter, 3); - if (counter == 1) { - EXPECT_STREQ(ret->c_str(), "Hello (raw str)"); - } else if (counter == 2) { - EXPECT_STREQ(ret->c_str(), "World (std::string)"); - } else { - EXPECT_STREQ(ret->c_str(), "Hello World (Ref<Str>)"); - } - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) - << "` to `object.Str`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_3_Object_Ptr, Object) { - std::vector<Any> vs = AnyArrayFactory(); - for (const Any &v : vs) { - auto convert = [&]() -> Object * { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Object *ret = convert(); - EXPECT_EQ(ret, nullptr); - } else if (v.type_index >= static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStaticObjectBegin)) { - Object *ret = convert(); - EXPECT_EQ(ret, static_cast<void *>(v.v_obj)); - EXPECT_EQ(v.v_obj->ref_cnt, 1); - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) - << "` to `object.Object *`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_3_Object_Ptr, Func) { - std::vector<Any> views = AnyArrayFactory(); - for (const Any &v : views) { - auto convert = [&]() -> Func * { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Func *ret = convert(); - EXPECT_EQ(ret, nullptr); - } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIFunc)) { - Func *ret = convert(); - EXPECT_EQ(ret, reinterpret_cast<Func *>(v.v_ptr)); - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) - << "` to `object.Func *`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Converter_3_Object_Ptr, Str) { - std::vector<Any> vs = AnyArrayFactory(); - int counter = 0; - for (const Any &v : vs) { - auto convert = [&]() -> Str * { return v; }; - if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFINone)) { - Str *ret = convert(); - EXPECT_EQ(ret, nullptr); - } else if (v.type_index == static_cast<int32_t>(TVMFFITypeIndex::kTVMFFIStr)) { - Str *ret = convert(); - ++counter; - EXPECT_LE(counter, 3); - if (counter == 1) { - EXPECT_STREQ(ret->c_str(), "Hello (raw str)"); - } else if (counter == 2) { - EXPECT_STREQ(ret->c_str(), "World (std::string)"); - } else { - EXPECT_STREQ(ret->c_str(), "Hello World (Ref<Str>)"); - } - } else { - try { - convert(); - FAIL() << "No exception thrown"; - } catch (TVMError &ex) { - std::ostringstream os; - os << "Cannot convert from type `" << TypeIndex2TypeKey(v.type_index) - << "` to `object.Str *`"; - EXPECT_EQ(ex.what(), os.str()); - } - } - CheckAnyRefCnt(&v); - } -} - -TEST(Any_Stringify, Integer) { - TestAnyStringify<int8_t>(-13, TVMFFITypeIndex::kTVMFFIInt, "-13"); - TestAnyStringify<int16_t>(-5, TVMFFITypeIndex::kTVMFFIInt, "-5"); - TestAnyStringify<int32_t>(0, TVMFFITypeIndex::kTVMFFIInt, "0"); - TestAnyStringify<int64_t>(1, TVMFFITypeIndex::kTVMFFIInt, "1"); -} - -TEST(Any_Stringify, Float) { - auto check = [](const Any &v) -> void { - std::string str = v.str()->c_str(); - double f_str = std::stod(str); - double f_src = v.v_float64; - EXPECT_NEAR(f_src, f_str, 1e-5); - }; - TestAnyStringifyChecker<float>(float(-3.14), TVMFFITypeIndex::kTVMFFIFloat, check); - TestAnyStringifyChecker<double>(0.0, TVMFFITypeIndex::kTVMFFIFloat, check); -} - -TEST(Any_Stringify, Ptr) { - auto check = [](const Any &v) -> void { - std::string str = v.str()->c_str(); - EXPECT_GT(str.size(), 2); - }; - TestAnyStringify<void *>(nullptr, TVMFFITypeIndex::kTVMFFINone, "None"); - TestAnyStringifyChecker<void *>(reinterpret_cast<void *>(FuncCall), TVMFFITypeIndex::kTVMFFIPtr, - check); -} - -TEST(Any_Stringify, Device) { - TestAnyStringify<DLDevice>(DLDevice{kDLCPU, 0}, TVMFFITypeIndex::kTVMFFIDevice, "cpu:0"); - TestAnyStringify<DLDevice>(DLDevice{kDLCUDA, 1}, TVMFFITypeIndex::kTVMFFIDevice, "cuda:1"); -} - -TEST(Any_Stringify, DataType) { - TestAnyStringify<DLDataType>(DLDataType{kDLInt, 32, 1}, TVMFFITypeIndex::kTVMFFIDataType, - "int32"); - TestAnyStringify<DLDataType>(DLDataType{kDLUInt, 1, 1}, TVMFFITypeIndex::kTVMFFIDataType, "bool"); - TestAnyStringify<DLDataType>(DLDataType{kDLOpaqueHandle, 0, 0}, TVMFFITypeIndex::kTVMFFIDataType, - "void"); - TestAnyStringify<DLDataType>(DLDataType{kDLFloat, 8, 4}, TVMFFITypeIndex::kTVMFFIDataType, - "float8x4"); -} - -TEST(Any_Stringify, RawStr) { - TestAnyStringify<const char *>("Hello", TVMFFITypeIndex::kTVMFFIStr, "\"Hello\""); - TestAnyStringify<char[6]>("Hello", TVMFFITypeIndex::kTVMFFIStr, "\"Hello\""); - TestAnyStringify<const char[6]>("Hello", TVMFFITypeIndex::kTVMFFIStr, "\"Hello\""); -} - -TEST(Any_Stringify, Object) { - auto check = [](const Any &v) -> void { - std::string expected_prefix = "object.Object@0"; - int n = static_cast<int>(expected_prefix.size()); - std::string str = v.str()->c_str(); - EXPECT_GT(str.size(), n); - EXPECT_EQ(str.substr(0, n), expected_prefix); - }; - TestAnyStringifyChecker<Ref<Object>>(Ref<Object>::New(), TVMFFITypeIndex::kTVMFFIObject, check); -} - -TEST(Any_Stringify, Func) { - auto check = [](const Any &v) -> void { - std::string expected_prefix = "object.Func@0"; - int n = static_cast<int>(expected_prefix.size()); - std::string str = v.str()->c_str(); - EXPECT_GT(str.size(), n); - EXPECT_EQ(str.substr(0, n), expected_prefix); - }; - TestAnyStringifyChecker<Ref<Func>>(Ref<Func>::New(FuncCall), TVMFFITypeIndex::kTVMFFIFunc, check); -} - -TEST(Any_Stringify, Str) { - auto check = [](const Any &v) -> void { - std::string str = v.str()->c_str(); - EXPECT_EQ(str, "\"Hello World\""); - }; - TestAnyStringifyChecker<Ref<Str>>(Ref<Str>::New("Hello World"), TVMFFITypeIndex::kTVMFFIStr, - check); -} +namespace { -} // namespace +using namespace tvm::ffi; +using namespace tvm::ffi::testing; + +TEST(Any, Int) { + AnyView view0; + EXPECT_EQ(view0.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFINone); + + std::optional<int64_t> opt_v0 = view0.TryAs<int64_t>(); + EXPECT_TRUE(!opt_v0.has_value()); + + EXPECT_THROW( + { + try { + [[maybe_unused]] int64_t v0 = view0; + } catch (const Error& error) { + EXPECT_EQ(error->kind, "TypeError"); + std::string what = error.what(); + EXPECT_NE(what.find("Cannot convert from type `None` to `int`"), std::string::npos); + throw; + } + }, + ::tvm::ffi::Error); + + AnyView view1 = 1; + EXPECT_EQ(view1.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFIInt); + EXPECT_EQ(view1.CopyToTVMFFIAny().v_int64, 1); + + int32_t int_v1 = view1; + EXPECT_EQ(int_v1, 1); + + int64_t v1 = 2; + view0 = v1; + EXPECT_EQ(view0.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFIInt); + EXPECT_EQ(view0.CopyToTVMFFIAny().v_int64, 2); +} + +TEST(Any, Float) { + AnyView view0; + EXPECT_EQ(view0.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFINone); + + std::optional<double> opt_v0 = view0.TryAs<double>(); + EXPECT_TRUE(!opt_v0.has_value()); + + EXPECT_THROW( + { + try { + [[maybe_unused]] double v0 = view0; + } catch (const Error& error) { + EXPECT_EQ(error->kind, "TypeError"); + std::string what = error.what(); + EXPECT_NE(what.find("Cannot convert from type `None` to `float`"), std::string::npos); + throw; + } + }, + ::tvm::ffi::Error); + + AnyView view1_int = 1; + float float_v1 = view1_int; + EXPECT_EQ(float_v1, 1); + + AnyView view2 = 2.2; + EXPECT_EQ(view2.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFIFloat); + EXPECT_EQ(view2.CopyToTVMFFIAny().v_float64, 2.2); + + float v1 = 2; + view0 = v1; + EXPECT_EQ(view0.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFIFloat); + EXPECT_EQ(view0.CopyToTVMFFIAny().v_float64, 2); +} + +TEST(Any, Object) { + AnyView view0; + EXPECT_EQ(view0.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFINone); + + // int object is not nullable + std::optional<TInt> opt_v0 = view0.TryAs<TInt>(); + EXPECT_TRUE(!opt_v0.has_value()); + + TInt v1(11); + EXPECT_EQ(v1.use_count(), 1); + // view won't increase refcount + AnyView view1 = v1; + EXPECT_EQ(v1.use_count(), 1); + // any will trigger ref count increase + Any any1 = v1; + EXPECT_EQ(v1.use_count(), 2); + // copy to another view + AnyView view2 = any1; + EXPECT_EQ(v1.use_count(), 2); + + // convert to weak raw object ptr + const TIntObj* v1_ptr = view2; + EXPECT_EQ(v1.use_count(), 2); + EXPECT_EQ(v1_ptr->value, 11); + Any any2 = v1_ptr; + EXPECT_EQ(v1.use_count(), 3); + EXPECT_TRUE(any2.TryAs<TInt>().has_value()); + + // convert to raw opaque ptr + void* raw_v1_ptr = const_cast<TIntObj*>(v1_ptr); + any2 = raw_v1_ptr; + EXPECT_TRUE(any2.TryAs<void*>().value() == v1_ptr); + + // convert to ObjectPtr + ObjectPtr<TNumberObj> v1_obj_ptr = view2; + EXPECT_EQ(v1.use_count(), 3); + any2 = v1_obj_ptr; + EXPECT_EQ(v1.use_count(), 4); + EXPECT_TRUE(any2.TryAs<TInt>().has_value()); + any2.reset(); + v1_obj_ptr.reset(); + + // convert that triggers error + EXPECT_THROW( + { + try { + [[maybe_unused]] TFloat v0 = view1; + } catch (const Error& error) { + EXPECT_EQ(error->kind, "TypeError"); + std::string what = error.what(); + std::cout << what; + EXPECT_NE(what.find("Cannot convert from type `test.Int` to `test.Float`"), + std::string::npos); + throw; + } + }, + ::tvm::ffi::Error); + // Try to convert to number + TNumber number0 = any1; + EXPECT_EQ(v1.use_count(), 3); + EXPECT_TRUE(number0.as<TIntObj>()); + EXPECT_EQ(number0.as<TIntObj>()->value, 11); + EXPECT_TRUE(!any1.TryAs<int>().has_value()); + + TInt int1 = view2; + EXPECT_EQ(v1.use_count(), 4); + any1.reset(); + EXPECT_EQ(v1.use_count(), 3); +} + +} // namespace diff --git a/ffi/tests/example/test_array.cc b/ffi/tests/cpp/test_array.cc similarity index 100% rename from ffi/tests/example/test_array.cc rename to ffi/tests/cpp/test_array.cc diff --git a/ffi/tests/example/test_c_ffi_abi.cc b/ffi/tests/cpp/test_c_ffi_abi.cc similarity index 100% rename from ffi/tests/example/test_c_ffi_abi.cc rename to ffi/tests/cpp/test_c_ffi_abi.cc diff --git a/ffi/tests/example/test_error.cc b/ffi/tests/cpp/test_error.cc similarity index 100% rename from ffi/tests/example/test_error.cc rename to ffi/tests/cpp/test_error.cc diff --git a/ffi/tests/example/test_function.cc b/ffi/tests/cpp/test_function.cc similarity index 100% rename from ffi/tests/example/test_function.cc rename to ffi/tests/cpp/test_function.cc diff --git a/ffi/tests/example/test_map.cc b/ffi/tests/cpp/test_map.cc similarity index 100% rename from ffi/tests/example/test_map.cc rename to ffi/tests/cpp/test_map.cc diff --git a/ffi/tests/example/test_object.cc b/ffi/tests/cpp/test_object.cc similarity index 96% rename from ffi/tests/example/test_object.cc rename to ffi/tests/cpp/test_object.cc index f931c99419..ed3361a0ba 100644 --- a/ffi/tests/example/test_object.cc +++ b/ffi/tests/cpp/test_object.cc @@ -47,7 +47,7 @@ TEST(Object, RefCounter) { } TEST(Object, TypeInfo) { - const TypeInfo* info = tvm::ffi::details::ObjectGetTypeInfo(TIntObj::RuntimeTypeIndex()); + const TypeInfo* info = TVMFFIGetTypeInfo(TIntObj::RuntimeTypeIndex()); EXPECT_TRUE(info != nullptr); EXPECT_EQ(info->type_index, TIntObj::RuntimeTypeIndex()); EXPECT_EQ(info->type_depth, 2); diff --git a/ffi/tests/example/test_optional.cc b/ffi/tests/cpp/test_optional.cc similarity index 100% rename from ffi/tests/example/test_optional.cc rename to ffi/tests/cpp/test_optional.cc diff --git a/ffi/tests/example/test_string.cc b/ffi/tests/cpp/test_string.cc similarity index 100% rename from ffi/tests/example/test_string.cc rename to ffi/tests/cpp/test_string.cc diff --git a/ffi/tests/example/testing_object.h b/ffi/tests/cpp/testing_object.h similarity index 100% rename from ffi/tests/example/testing_object.h rename to ffi/tests/cpp/testing_object.h diff --git a/ffi/tests/example/test_any.cc b/ffi/tests/example/test_any.cc deleted file mode 100644 index 36d4783dc5..0000000000 --- a/ffi/tests/example/test_any.cc +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 <gtest/gtest.h> -#include <tvm/ffi/any.h> -#include <tvm/ffi/memory.h> - -#include "./testing_object.h" - -namespace { - -using namespace tvm::ffi; -using namespace tvm::ffi::testing; - -TEST(Any, Int) { - AnyView view0; - EXPECT_EQ(view0.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFINone); - - std::optional<int64_t> opt_v0 = view0.TryAs<int64_t>(); - EXPECT_TRUE(!opt_v0.has_value()); - - EXPECT_THROW( - { - try { - [[maybe_unused]] int64_t v0 = view0; - } catch (const Error& error) { - EXPECT_EQ(error->kind, "TypeError"); - std::string what = error.what(); - EXPECT_NE(what.find("Cannot convert from type `None` to `int`"), std::string::npos); - throw; - } - }, - ::tvm::ffi::Error); - - AnyView view1 = 1; - EXPECT_EQ(view1.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFIInt); - EXPECT_EQ(view1.CopyToTVMFFIAny().v_int64, 1); - - int32_t int_v1 = view1; - EXPECT_EQ(int_v1, 1); - - int64_t v1 = 2; - view0 = v1; - EXPECT_EQ(view0.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFIInt); - EXPECT_EQ(view0.CopyToTVMFFIAny().v_int64, 2); -} - -TEST(Any, Float) { - AnyView view0; - EXPECT_EQ(view0.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFINone); - - std::optional<double> opt_v0 = view0.TryAs<double>(); - EXPECT_TRUE(!opt_v0.has_value()); - - EXPECT_THROW( - { - try { - [[maybe_unused]] double v0 = view0; - } catch (const Error& error) { - EXPECT_EQ(error->kind, "TypeError"); - std::string what = error.what(); - EXPECT_NE(what.find("Cannot convert from type `None` to `float`"), std::string::npos); - throw; - } - }, - ::tvm::ffi::Error); - - AnyView view1_int = 1; - float float_v1 = view1_int; - EXPECT_EQ(float_v1, 1); - - AnyView view2 = 2.2; - EXPECT_EQ(view2.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFIFloat); - EXPECT_EQ(view2.CopyToTVMFFIAny().v_float64, 2.2); - - float v1 = 2; - view0 = v1; - EXPECT_EQ(view0.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFIFloat); - EXPECT_EQ(view0.CopyToTVMFFIAny().v_float64, 2); -} - -TEST(Any, Object) { - AnyView view0; - EXPECT_EQ(view0.CopyToTVMFFIAny().type_index, TypeIndex::kTVMFFINone); - - // int object is not nullable - std::optional<TInt> opt_v0 = view0.TryAs<TInt>(); - EXPECT_TRUE(!opt_v0.has_value()); - - TInt v1(11); - EXPECT_EQ(v1.use_count(), 1); - // view won't increase refcount - AnyView view1 = v1; - EXPECT_EQ(v1.use_count(), 1); - // any will trigger ref count increase - Any any1 = v1; - EXPECT_EQ(v1.use_count(), 2); - // copy to another view - AnyView view2 = any1; - EXPECT_EQ(v1.use_count(), 2); - - // convert to weak raw object ptr - const TIntObj* v1_ptr = view2; - EXPECT_EQ(v1.use_count(), 2); - EXPECT_EQ(v1_ptr->value, 11); - Any any2 = v1_ptr; - EXPECT_EQ(v1.use_count(), 3); - EXPECT_TRUE(any2.TryAs<TInt>().has_value()); - - // convert to raw opaque ptr - void* raw_v1_ptr = const_cast<TIntObj*>(v1_ptr); - any2 = raw_v1_ptr; - EXPECT_TRUE(any2.TryAs<void*>().value() == v1_ptr); - - // convert to ObjectPtr - ObjectPtr<TNumberObj> v1_obj_ptr = view2; - EXPECT_EQ(v1.use_count(), 3); - any2 = v1_obj_ptr; - EXPECT_EQ(v1.use_count(), 4); - EXPECT_TRUE(any2.TryAs<TInt>().has_value()); - any2.reset(); - v1_obj_ptr.reset(); - - // convert that triggers error - EXPECT_THROW( - { - try { - [[maybe_unused]] TFloat v0 = view1; - } catch (const Error& error) { - EXPECT_EQ(error->kind, "TypeError"); - std::string what = error.what(); - EXPECT_NE(what.find("Cannot convert from type `test.Int` to `test.Float`"), - std::string::npos); - throw; - } - }, - ::tvm::ffi::Error); - // Try to convert to number - TNumber number0 = any1; - EXPECT_EQ(v1.use_count(), 3); - EXPECT_TRUE(number0.as<TIntObj>()); - EXPECT_EQ(number0.as<TIntObj>()->value, 11); - EXPECT_TRUE(!any1.TryAs<int>().has_value()); - - TInt int1 = view2; - EXPECT_EQ(v1.use_count(), 4); - any1.reset(); - EXPECT_EQ(v1.use_count(), 3); -} - -} // namespace
