From 0907d568652ca989f7a56f2550ccab79de02e00b Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 22 Jul 2024 17:54:25 -0700 Subject: [PATCH 01/44] Bringing over Value/View Interface headers and tests from research branch. --- cmake/SetupSpheral.cmake | 10 + cmake/SpheralMacros.cmake | 87 +++ src/Field/SphArray.hh | 702 ++++++++++++++++++ src/Field/SphArrayInline.hh | 149 ++++ src/Field/SphArrayInst.cc.py | 32 + src/Utilities/ValueViewInterface.hh | 254 +++++++ src/config.hh.in | 13 + tests/CMakeLists.txt | 3 + tests/cpp/Field/CMakeLists.txt | 22 + .../Field/field_parallel_inheritance_tests.cc | 249 +++++++ tests/cpp/Field/field_tests.cc | 287 +++++++ tests/cpp/Field/fieldview_tests.cc | 202 +++++ tests/cpp/Field/managed_vector_tests.cc | 447 +++++++++++ tests/cpp/Kernel/CMakeLists.txt | 4 + .../kernel_parallel_inheritance_tests.cc | 206 +++++ tests/cpp/Utilities/CMakeLists.txt | 10 + .../ValueViewInterface/CMakeLists.txt | 12 + .../ManagedSharedPtrTests.cc | 88 +++ .../cpp/Utilities/ValueViewInterface/QInt.hh | 88 +++ .../quadratic_interpolator_example_tests.cc | 55 ++ .../Utilities/quadratic_interpolator_tests.cc | 107 +++ .../quadratic_interpolator_view_tests.hh | 184 +++++ tests/cpp/include/test-basic-exec-policies.hh | 16 + tests/cpp/include/test-utilities.hh | 89 +++ 24 files changed, 3316 insertions(+) create mode 100644 cmake/SpheralMacros.cmake create mode 100644 src/Field/SphArray.hh create mode 100644 src/Field/SphArrayInline.hh create mode 100644 src/Field/SphArrayInst.cc.py create mode 100644 src/Utilities/ValueViewInterface.hh create mode 100644 tests/CMakeLists.txt create mode 100644 tests/cpp/Field/CMakeLists.txt create mode 100644 tests/cpp/Field/field_parallel_inheritance_tests.cc create mode 100644 tests/cpp/Field/field_tests.cc create mode 100644 tests/cpp/Field/fieldview_tests.cc create mode 100644 tests/cpp/Field/managed_vector_tests.cc create mode 100644 tests/cpp/Kernel/CMakeLists.txt create mode 100644 tests/cpp/Kernel/kernel_parallel_inheritance_tests.cc create mode 100644 tests/cpp/Utilities/CMakeLists.txt create mode 100644 tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt create mode 100644 tests/cpp/Utilities/ValueViewInterface/ManagedSharedPtrTests.cc create mode 100644 tests/cpp/Utilities/ValueViewInterface/QInt.hh create mode 100644 tests/cpp/Utilities/ValueViewInterface/quadratic_interpolator_example_tests.cc create mode 100644 tests/cpp/Utilities/quadratic_interpolator_tests.cc create mode 100644 tests/cpp/Utilities/quadratic_interpolator_view_tests.hh create mode 100644 tests/cpp/include/test-basic-exec-policies.hh create mode 100644 tests/cpp/include/test-utilities.hh diff --git a/cmake/SetupSpheral.cmake b/cmake/SetupSpheral.cmake index b993e3296..e40b4fb31 100644 --- a/cmake/SetupSpheral.cmake +++ b/cmake/SetupSpheral.cmake @@ -11,6 +11,11 @@ if (NOT SPHERAL_CMAKE_MODULE_PATH) endif() list(APPEND CMAKE_MODULE_PATH "${SPHERAL_CMAKE_MODULE_PATH}") +#------------------------------------------------------------------------------- +# Add Spheral CMake Macros for tests and executables +#------------------------------------------------------------------------------- +include(SpheralMacros) + #------------------------------------------------------------------------------- # Set Compiler Flags / Options #------------------------------------------------------------------------------- @@ -82,6 +87,7 @@ if(ENABLE_CUDA) #set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -arch=${CUDA_ARCH} --expt-relaxed-constexpr --extended-lambda -Xcudafe --display_error_number") set(CMAKE_CUDA_STANDARD 17) list(APPEND SPHERAL_CXX_DEPENDS cuda) + set(SPHERAL_ENABLE_CUDA On) endif() #-------------------------------------------------------------------------------# @@ -137,6 +143,9 @@ set_property(GLOBAL PROPERTY SPHERAL_CXX_DEPENDS "${SPHERAL_CXX_DEPENDS}") #------------------------------------------------------------------------------- # Prepare to build the src #------------------------------------------------------------------------------- +configure_file(src/config.hh.in + ${PROJECT_BINARY_DIR}/src/config.hh) + add_subdirectory(${SPHERAL_ROOT_DIR}/src) #------------------------------------------------------------------------------- @@ -150,6 +159,7 @@ endif() # Build C++ tests and install tests to install directory #------------------------------------------------------------------------------- if (ENABLE_TESTS) + add_subdirectory(${SPHERAL_ROOT_DIR}/tests) add_subdirectory(${SPHERAL_ROOT_DIR}/tests/unit/CXXTests) # A macro to preserve directory structure when installing files diff --git a/cmake/SpheralMacros.cmake b/cmake/SpheralMacros.cmake new file mode 100644 index 000000000..759df3e0b --- /dev/null +++ b/cmake/SpheralMacros.cmake @@ -0,0 +1,87 @@ +macro(spheral_add_executable) + set(options ) + set(singleValueArgs NAME TEST REPRODUCER BENCHMARK) + set(multiValueArgs SOURCES DEPENDS_ON) + + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (ENABLE_OPENMP) + list (APPEND arg_DEPENDS_ON openmp) + endif () + + if (ENABLE_CUDA) + list (APPEND arg_DEPENDS_ON cuda) + endif () + + if (ENABLE_HIP) + list (APPEND arg_DEPENDS_ON blt::hip) + list (APPEND arg_DEPENDS_ON blt::hip_runtime) + endif () + + if (${arg_TEST}) + set (_output_dir ${CMAKE_BINARY_DIR}/test) + elseif (${arg_REPRODUCER}) + set (_output_dir ${CMAKE_BINARY_DIR}/reproducers) + elseif (${arg_BENCHMARK}) + set (_output_dir ${CMAKE_BINARY_DIR}/benchmark) + else () + set (_output_dir ${CMAKE_BINARY_DIR}/bin) + endif() + + blt_add_executable( + NAME ${arg_NAME} + SOURCES ${arg_SOURCES} + DEPENDS_ON ${arg_DEPENDS_ON} + OUTPUT_DIR ${_output_dir} + ) + + target_include_directories(${arg_NAME} SYSTEM PRIVATE ${SPHERAL_EXTERN_INCLUDES}) + target_include_directories(${arg_NAME} SYSTEM PRIVATE ${SPHERAL_ROOT_DIR}/src) + target_include_directories(${arg_NAME} SYSTEM PRIVATE ${PROJECT_BINARY_DIR}/src) + +endmacro(spheral_add_executable) + +macro(spheral_add_test) + set(options DEBUG_LINKER) + set(singleValueArgs NAME) + set(multiValueArgs SOURCES DEPENDS_ON) + + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(original_test_name ${arg_NAME}) + set(original_src ${arg_SOURCES}) + set(original_deps ${arg_DEPENDS_ON}) + + get_property(SPHERAL_BLT_DEPENDS GLOBAL PROPERTY SPHERAL_BLT_DEPENDS) + + blt_add_library( + NAME ${original_test_name}_lib + SOURCES ${TEST_LIB_SOURCE} + SOURCES ${CMAKE_SOURCE_DIR}/src/spheralCXX.cc + DEPENDS_ON ${SPHERAL_BLT_DEPENDS} ${original_deps} + SHARED False + ) + + target_link_options(${original_test_name}_lib PRIVATE "-Wl,--unresolved-symbols=ignore-in-object-files") + + spheral_add_executable( + NAME ${original_test_name}.exe + SOURCES ${original_src} + DEPENDS_ON gtest ${CMAKE_THREAD_LIBS_INIT} ${original_test_name}_lib + TEST On) + + blt_add_test( + NAME ${original_test_name} + COMMAND ${TEST_DRIVER} ${original_test_name}.exe) + + target_include_directories(${original_test_name}.exe SYSTEM PRIVATE ${SPHERAL_ROOT_DIR}/tests/cpp/include) + + if (${arg_DEBUG_LINKER}) + target_link_options(${original_test_name}.exe PUBLIC "-Wl,--warn-unresolved-symbols") + else() + target_link_options(${original_test_name}.exe PUBLIC "-Wl,--unresolved-symbols=ignore-all") + endif() + +endmacro(spheral_add_test) diff --git a/src/Field/SphArray.hh b/src/Field/SphArray.hh new file mode 100644 index 000000000..1e722234d --- /dev/null +++ b/src/Field/SphArray.hh @@ -0,0 +1,702 @@ +#ifndef __Spheral_lvarray_hh__ +#define __Spheral_lvarray_hh__ + +#include "config.hh" +//#include "LvArray/Array.hpp" +//#include "LvArray/ChaiBuffer.hpp" +#include "chai/ManagedArray.hpp" + +#include + +constexpr uint32_t pow2_ceil(uint32_t v) { + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + + return v; +} + +namespace Spheral { + +//#define SPHERAL_CALLBACK_ENABLED +#define STD_OUT_LOG + +#ifdef STD_OUT_LOG +#define SPHERAL_LOG(A, B) std::cout << #A << " : " << B << std::endl; +#else +#define SPHERAL_LOG(A, B) UMPIRE_LOG(A, B) +#endif + + + +//#define MV_VALUE_SEMANTICS + +template +class ManagedVector; + +template +ManagedVector deepCopy(ManagedVector const& array); + +template +class ManagedVector: + private chai::ManagedArray{ + using MA = chai::ManagedArray; + +public: + + inline static constexpr size_t initial_capacity = 8u; + + using MA::setUserCallback; + + using iterator = DataType*; + using const_iterator = const DataType*; + + iterator begin() { return MA::begin(); } + const_iterator begin() const { return MA::begin(); } + + iterator end() { return begin() + m_size; } + const_iterator end() const { return begin() + m_size; } + + // --------------------- + // Constructors + // --------------------- + SPHERAL_HOST_DEVICE ManagedVector() : + MA() + { +#if !defined(SPHERAL_GPU_ACTIVE) + setCallback(); + +#endif // SPHERAL_GPU_ACTIVE + } + + SPHERAL_HOST_DEVICE ManagedVector(size_t elems) : + MA(), + m_size(elems) + { +#if !defined(SPHERAL_GPU_ACTIVE) + MA::allocate(m_size < initial_capacity ? initial_capacity: pow2_ceil(m_size), chai::CPU, getCallback()); + for (size_t i = 0; i < m_size; i++) new (&MA::operator[](i)) DataType(); + MA::registerTouch(chai::CPU); +#endif // SPHERAL_GPU_ACTIVE + } + + SPHERAL_HOST ManagedVector(size_t elems, DataType identity) : + MA(), + m_size(elems) + { +#if !defined(SPHERAL_GPU_ACTIVE) + MA::allocate(m_size < initial_capacity ? initial_capacity: pow2_ceil(m_size), chai::CPU, getCallback()); + for (size_t i = 0; i < m_size; i++) new (&MA::operator[](i)) DataType(identity); + MA::registerTouch(chai::CPU); +#endif // SPHERAL_GPU_ACTIVE + } + +#ifdef MV_VALUE_SEMANTICS + // --------------------- + // Destructor + // --------------------- + SPHERAL_HOST ~ManagedVector() + { + MA::free(); + } +#endif + using MA::move; + using MA::free; + + // --------------------- + // Copy Constructor + // --------------------- +#ifdef MV_VALUE_SEMANTICS + SPHERAL_HOST_DEVICE constexpr inline ManagedVector(ManagedVector const& rhs) noexcept : + ManagedVector(rhs.m_size) + { + for (size_t i = 0; i < m_size; i++) new (&MA::operator[](i)) DataType(rhs[i]); + } +#else + SPHERAL_HOST_DEVICE constexpr inline ManagedVector(ManagedVector const& rhs) noexcept : MA(rhs), m_size(rhs.m_size) {} +#endif + + // --------------------- + // Assignment + // --------------------- +#ifdef MV_VALUE_SEMANTICS + SPHERAL_HOST_DEVICE ManagedVector& operator=(ManagedVector const& rhs) { + if (capacity() != rhs.capacity()) MA::reallocate(rhs.capacity()); + m_size = rhs.m_size; + for (size_t i = 0; i < m_size; i++) new (&MA::operator[](i)) DataType(rhs[i]); + return *this; + } +#else + SPHERAL_HOST_DEVICE ManagedVector& operator=(ManagedVector const& rhs) { + MA::operator=(rhs); + m_size = rhs.m_size; + return *this; + } +#endif + + // --------------------- + // Equivalence + // --------------------- +#ifdef MV_VALUE_SEMANTICS + SPHERAL_HOST bool operator==(ManagedVector const& rhs) const { + if (m_size != rhs.m_size) return false; + for (size_t i = 0; i < m_size; i++) { + if (MA::operator[](i) != rhs[i]) { + return false; + } + } + return true; + } +#else + SPHERAL_HOST_DEVICE bool operator==(ManagedVector const& rhs) const { + if (m_size != rhs.m_size) return false; + return MA::operator==(rhs); + } +#endif + SPHERAL_HOST_DEVICE bool operator!=(ManagedVector const& rhs) const { + return !(*this == rhs); + } + + SPHERAL_HOST void push_back(const DataType& value) { + if (capacity() == 0) MA::allocate(initial_capacity, chai::CPU, getCallback()); + if (m_size >= capacity()) MA::reallocate(pow2_ceil(m_size + 1)); + new(&MA::operator[](m_size)) DataType(value); + m_size++; + } + + SPHERAL_HOST void push_back(DataType&& value) { + if (capacity() == 0) MA::allocate(initial_capacity, chai::CPU, getCallback()); + if (m_size >= capacity()) MA::reallocate(pow2_ceil(m_size + 1)); + //MA::operator[](m_size) = std::move(value); + new(&MA::operator[](m_size)) DataType(value); + m_size++; + } + template + SPHERAL_HOST + DataType& emplace_back(Args&&... args) { + if (capacity() == 0) MA::allocate(initial_capacity, chai::CPU, getCallback()); + if (m_size >= capacity()) MA::reallocate(pow2_ceil(m_size + 1)); + + new(&MA::data()[m_size]) DataType(std::forward(args)...); + return MA::data()[m_size++]; + } + + SPHERAL_HOST + void reserve(size_t c) { + if (capacity() == 0) MA::allocate(c < initial_capacity ? initial_capacity: pow2_ceil(c), chai::CPU, getCallback()); + if (c >= capacity()) MA::reallocate(pow2_ceil(c)); + } + + SPHERAL_HOST + void resize(size_t size) { + const size_t old_size = m_size; + + if (old_size != size){ + if (old_size < size) { + if (capacity() == 0) MA::allocate(size < initial_capacity ? initial_capacity: pow2_ceil(size), chai::CPU, getCallback()); + else if (capacity() < size) MA::reallocate(pow2_ceil(size)); + for (size_t i = old_size; i < size; i++) new(&MA::data(chai::CPU, false)[i]) DataType(); + } + if (old_size > size) { + destroy(begin() + old_size, begin() + size); + } + m_size = size; + MA::registerTouch(chai::CPU); + } + } + + SPHERAL_HOST + void insert(iterator pos, DataType const& value) { + auto delta = std::distance(begin(), pos); + if (m_size == 0) { + push_back(value); + }else { + resize(m_size + 1); + for (iterator it = end() - 1; it > begin() + delta; it--) { + *it = std::move(*(it - 1)); + //*it = (*(it - 1)); + } + new(begin() + delta) DataType(value); + } + } + + SPHERAL_HOST + void clear() { + destroy(begin(), end()); + m_size = 0; + } + + SPHERAL_HOST + void erase(iterator pos) { + for (iterator it = pos; it < end(); it++) { + *it = std::move(*(it + 1)); + } + m_size--; + } + + SPHERAL_HOST_DEVICE size_t capacity() const {return MA::size();} + SPHERAL_HOST_DEVICE size_t size() const {return m_size;} + + SPHERAL_HOST_DEVICE DataType& operator[](size_t idx) {return MA::data()[idx]; } + SPHERAL_HOST_DEVICE DataType& operator[](size_t idx) const {return MA::data()[idx]; } + + + // ******************************************************* + // Required to Allow ManagedVector to be properly CHAICopyable + SPHERAL_HOST_DEVICE ManagedVector& operator=(std::nullptr_t) { MA::operator=(nullptr); return *this; } + SPHERAL_HOST_DEVICE void shallowCopy(const ManagedVector& other) { + m_size=other.m_size; + MA::shallowCopy(other); + } + // ******************************************************* + + //SPHERAL_HOST operator std::vector() const { return std::vector(begin(), end()); } + + template< typename U=ManagedVector< DataType > > + SPHERAL_HOST + void setCallback() { + MA::setUserCallback( getCallback() ); + } + + template< typename U=ManagedVector< DataType > > + SPHERAL_HOST + auto getCallback() { +//#ifdef SPHERAL_CALLBACK_ENABLED +// std::string const typeString = LvArray::system::demangleType< U >(); +// return [typeString] (const chai::PointerRecord* record, chai::Action action, chai::ExecutionSpace exec) { +// std::string const size = LvArray::system::calculateSize(record->m_size); +// std::string const paddedSize = std::string( 9 - size.size(), ' ' ) + size; +// char const * const spaceStr = ( exec == chai::CPU ) ? "HOST " : "DEVICE"; +// +// if (action == chai::Action::ACTION_MOVE){ +// SPHERAL_LOG(Info, "Moved " << paddedSize << " to the " << spaceStr << ": " << typeString << " @ " << record->m_pointers[exec] ) +// } +// if (action == chai::Action::ACTION_ALLOC){ +// SPHERAL_LOG(Info, "Allocated on " << spaceStr << " " << paddedSize << " : " << typeString << " @ " << record->m_pointers[exec] ) +// } +// if (action == chai::Action::ACTION_FREE){ +// SPHERAL_LOG(Info, "Deallocated " << paddedSize << " : " << typeString << " @ " << record->m_pointers[exec] ) +// } +// }; +//#else + return [](const chai::PointerRecord* , chai::Action , chai::ExecutionSpace ) {}; +//#endif + } + +private: + size_t m_size = 0; + + SPHERAL_HOST void destroy(iterator first, iterator last) { + if ( !std::is_trivially_destructible< DataType >::value ) { + for (iterator it = first; it < last; it++) { + *it = DataType(); + } + } + } + + ManagedVector(MA const& managed_array) : MA(managed_array), m_size(managed_array.size()) {} + + template + friend ManagedVector deepCopy(ManagedVector const& array); + + SPHERAL_HOST_DEVICE + friend bool compare(ManagedVector const& lhs, ManagedVector const& rhs) + { + if (lhs.m_size != rhs.m_size) return false; + for (size_t i = 0; i < lhs.m_size; i++) { + if (lhs[i] != rhs[i]) { + return false; + } + } + return true; + } + +}; + + +template +inline +ManagedVector deepCopy(ManagedVector const& array) +{ + ManagedVector copy(array.size()); + for (size_t i = 0; i < array.size(); i++) new (©[i]) U(array[i]); + return copy; +} + +template +class ManagedSmartPtr; + +template +ManagedSmartPtr deepCopy(ManagedSmartPtr const& rhs); + +template +ManagedSmartPtr make_ManagedSmartPtr(T* host_ptr); + +template +ManagedSmartPtr make_ManagedSmartPtr(Args... args); + +template +class ManagedSmartPtr : public chai::CHAICopyable +{ +public: + using element_type = T; +struct PrivateConstruct {}; + + SPHERAL_HOST_DEVICE ManagedSmartPtr() { +#if !defined(SPHERAL_GPU_ACTIVE) + //m_ref_count = new size_t(0); +#endif // SPHERAL_GPU_ACTIVE + } + + template + SPHERAL_HOST ManagedSmartPtr(PrivateConstruct, Args... args) { +#if !defined(SPHERAL_GPU_ACTIVE) + m_ptr = chai::ManagedArray(); + m_ptr.allocate(1, chai::CPU, getCallback()); + m_ptr[0] = T(args...); + m_ptr.registerTouch(chai::CPU); + m_ref_count = new size_t(1); + +#endif // SPHERAL_GPU_ACTIVE + } + + SPHERAL_HOST ManagedSmartPtr(PrivateConstruct, T* host_ptr) { +#if !defined(SPHERAL_GPU_ACTIVE) + m_ptr = chai::makeManagedArray(host_ptr, 1, chai::CPU, true); + m_ptr.setUserCallback(getCallback()); + m_ptr.registerTouch(chai::CPU); + m_ref_count = new size_t(1); +#endif // SPHERAL_GPU_ACTIVE + } + + +public: + SPHERAL_HOST void registerTouch(chai::ExecutionSpace space) { m_ptr.registerTouch(space); } + + SPHERAL_HOST_DEVICE ManagedSmartPtr& operator=(ManagedSmartPtr const& rhs) { + if (this != &rhs) { + if (m_ptr != rhs.m_ptr) discontinue_ownership(); + m_ptr = rhs.m_ptr; + m_ref_count = rhs.m_ref_count; + increment_ref_count(); + } + return *this; + } + + SPHERAL_HOST_DEVICE ManagedSmartPtr(ManagedSmartPtr const& rhs) : m_ptr(rhs.m_ptr), m_ref_count(rhs.m_ref_count) { + increment_ref_count(); + } + + SPHERAL_HOST void move(chai::ExecutionSpace space, bool touch = true) const { + m_ptr[0].move(space, touch); + } + + SPHERAL_HOST_DEVICE T* get() const { return (m_ref_count) ? (m_ptr.data()) : nullptr; } + SPHERAL_HOST_DEVICE T* operator->() { return get(); } + SPHERAL_HOST_DEVICE T* operator->() const { return get(); } + SPHERAL_HOST_DEVICE T& operator*() { return *get(); } + SPHERAL_HOST_DEVICE T& operator*() const { return *get(); } + + SPHERAL_HOST_DEVICE ~ManagedSmartPtr() { + discontinue_ownership(); + } + + SPHERAL_HOST_DEVICE ManagedSmartPtr& operator=(std::nullptr_t) { m_ref_count=nullptr; m_ptr=nullptr; return *this; } + SPHERAL_HOST_DEVICE void shallowCopy(ManagedSmartPtr const& rhs) { + *this = rhs; + } + + template< typename U=ManagedSmartPtr< T > > + SPHERAL_HOST + auto getCallback() { +//#ifdef SPHERAL_CALLBACK_ENABLED +// std::string const typeString = LvArray::system::demangleType< U >(); +// return [typeString] (const chai::PointerRecord* record, chai::Action action, chai::ExecutionSpace exec) { +// std::string const size = LvArray::system::calculateSize(record->m_size); +// std::string const paddedSize = std::string( 9 - size.size(), ' ' ) + size; +// char const * const spaceStr = ( exec == chai::CPU ) ? "HOST " : "DEVICE"; +// +// if (action == chai::Action::ACTION_MOVE){ +// SPHERAL_LOG(Info, "Moved " << paddedSize << " to the " << spaceStr << ": " << typeString << " @ " << record->m_pointers[exec] ) +// } +// if (action == chai::Action::ACTION_ALLOC){ +// SPHERAL_LOG(Info, "Allocated on " << spaceStr << " " << paddedSize << " : " << typeString << " @ " << record->m_pointers[exec] ) +// } +// if (action == chai::Action::ACTION_FREE){ +// SPHERAL_LOG(Info, "Deallocated " << paddedSize << " : " << typeString << " @ " << record->m_pointers[exec] ) +// } +// }; +//#else + return [](const chai::PointerRecord* , chai::Action , chai::ExecutionSpace ) {}; +//#endif + } +protected: + + SPHERAL_HOST_DEVICE void increment_ref_count() { +#if !defined(SPHERAL_GPU_ACTIVE) + if (m_ref_count != nullptr) (*m_ref_count)++; +#endif // SPHERAL_GPU_ACTIVE + } + + SPHERAL_HOST_DEVICE void discontinue_ownership() { +#if !defined(SPHERAL_GPU_ACTIVE) + if (m_ref_count != nullptr){ + (*m_ref_count)--; + if (*m_ref_count == 0) + { + m_ptr[0].free(); + m_ptr.free(); + delete m_ref_count; + m_ref_count = nullptr; + } + } +#endif // SPHERAL_GPU_ACTIVE + } + + + SPHERAL_HOST_DEVICE + friend bool compare(ManagedSmartPtr const& lhs, ManagedSmartPtr const& rhs) + { + // TODO : not safe + return compare(lhs.m_ptr[0], rhs.m_ptr[0]); + } + + chai::ManagedArray m_ptr; + size_t* m_ref_count = nullptr; + + template + friend ManagedSmartPtr deepCopy(ManagedSmartPtr const& rhs); + + template + friend ManagedSmartPtr make_ManagedSmartPtr(U* host_ptr); + + template + friend ManagedSmartPtr make_ManagedSmartPtr(Args... args); + +}; + + +template +ManagedSmartPtr make_ManagedSmartPtr(U* host_ptr) + { + ManagedSmartPtr ptr = ManagedSmartPtr(typename ManagedSmartPtr::PrivateConstruct(), host_ptr); + return ptr; + } + +template +ManagedSmartPtr make_ManagedSmartPtr(Args... args) + { + ManagedSmartPtr ptr = ManagedSmartPtr(typename ManagedSmartPtr::PrivateConstruct(), args...); + return ptr; + } + +template +ManagedSmartPtr deepCopy(ManagedSmartPtr const& rhs) +{ + // TODO : not safe + ManagedSmartPtr ptr = make_ManagedSmartPtr(deepCopy(*rhs)); + return ptr; + //return ManagedSmartPtr(typename ManagedSmartPtr::PrivateConstruct(), deepCopy(*rhs)); +} + + +template +class MVSmartRef : public ManagedSmartPtr> +{ + using Base = ManagedSmartPtr>; + SPHERAL_HOST_DEVICE ManagedVector & mv() { return Base::m_ptr[0]; } + SPHERAL_HOST_DEVICE ManagedVector const& mv() const { return Base::m_ptr[0]; } + +public: + + using Base::operator->; + using Base::operator*; + using Base::get; + using Base::move; + + using MV = Spheral::ManagedVector; + + SPHERAL_HOST_DEVICE MVSmartRef() = default; + + template + MVSmartRef(Args... args) : Base(make_ManagedSmartPtr(args...)) {mv().setCallback();} + + using iterator = typename MV::iterator; + using const_iterator = typename MV::const_iterator; + + iterator begin() { return mv().begin(); } + const_iterator begin() const { return mv().begin(); } + + iterator end() { return begin() + size(); } + const_iterator end() const { return begin() + size(); } + + SPHERAL_HOST_DEVICE T& operator[](size_t idx) {return mv()[idx]; } + SPHERAL_HOST_DEVICE T& operator[](size_t idx) const {return mv()[idx]; } + + SPHERAL_HOST_DEVICE size_t size() const { return mv().size(); } + + SPHERAL_HOST void resize(size_t sz) { + move(chai::CPU); + mv().resize(sz); + Base::m_ptr.registerTouch(chai::CPU); + } + + SPHERAL_HOST + void insert(iterator pos, T const& value) { + move(chai::CPU); + mv().insert(pos, value); + Base::m_ptr.registerTouch(chai::CPU); + } + + SPHERAL_HOST void push_back(T const& value) { + move(chai::CPU); + mv().push_back(value); + Base::m_ptr.registerTouch(chai::CPU); + } + + SPHERAL_HOST void push_back(T&& value) { + move(chai::CPU); + mv().push_back(value); + Base::m_ptr.registerTouch(chai::CPU); + } + + SPHERAL_HOST + void reserve(size_t c) { + move(chai::CPU); + mv().reserve(c); + Base::m_ptr.registerTouch(chai::CPU); + } + + SPHERAL_HOST + void clear() { + move(chai::CPU); + mv().clear(); + Base::m_ptr.registerTouch(chai::CPU); + } + + SPHERAL_HOST + void erase(iterator pos) { + move(chai::CPU); + mv().erase(pos); + Base::m_ptr.registerTouch(chai::CPU); + } + + SPHERAL_HOST_DEVICE MVSmartRef& operator=(std::nullptr_t) { Base::operator=(nullptr); return *this; } + SPHERAL_HOST_DEVICE void shallowCopy(MVSmartRef const& rhs) { + Base::shallowCopy(rhs); + } + + SPHERAL_HOST_DEVICE bool operator==(MVSmartRef const& rhs) const { return (mv() == rhs.mv()); } + SPHERAL_HOST_DEVICE bool operator!=(MVSmartRef const& rhs) const { return (mv() != rhs.mv()); } + +private: + + friend MVSmartRef deepCopy(MVSmartRef const& rhs) + { + // TODO : not safe + return MVSmartRef(deepCopy(rhs.m_ptr[0])); + } + + SPHERAL_HOST_DEVICE + friend bool compare(MVSmartRef const& lhs, MVSmartRef const& rhs) + { + // TODO : not safe + return compare(lhs.mv(), rhs.mv()); + } +}; + + + + +//template +//using SphArray = LvArray::Array, std::ptrdiff_t, LvArray::ChaiBuffer>; +// +//template +//using SphArrayView = LvArray::ArrayView; + +//template +//class SphArrayIterator { +//public: +// using iterator_category = std::random_access_iterator_tag; +// using value_type = typename sph_array_t::ValueType; +// using difference_type = std::ptrdiff_t; +// using pointer = value_type*; +// using reference = value_type&; +// +// SphArrayIterator(pointer ptr); +// +// SphArrayIterator& operator++(); +// SphArrayIterator operator++(int); +// +// SphArrayIterator& operator--(); +// SphArrayIterator operator--(int); +// +// SphArrayIterator operator+(const difference_type& index) const; +// SphArrayIterator operator-(const difference_type& index) const; +// +// difference_type operator-(const SphArrayIterator& it); +// +// reference operator[](int index); +// pointer operator->(); +// +// reference operator*() const; +// +// bool operator==(const SphArrayIterator& rhs) const; +// bool operator!=(const SphArrayIterator& rhs) const; +// bool operator<(const SphArrayIterator& rhs) const; +// bool operator<=(const SphArrayIterator& rhs) const; +// bool operator>(const SphArrayIterator& rhs) const; +// bool operator>=(const SphArrayIterator& rhs) const; +// +// operator SphArrayIterator() const; +// +//private: +// pointer mPtr; +//}; +// +//template +//class SphArrayFieldIterator { +//public: +// using iterator_category = std::input_iterator_tag; +// using value_type = typename sph_array_t::ValueType; +// using difference_type = std::ptrdiff_t; +// using pointer = value_type*; +// using reference = value_type&; +// +// using field_type = typename value_type::FieldType; +// using field_pointer = field_type*; +// using field_reference = field_type&; +// +// SphArrayFieldIterator(pointer ptr); +// +// field_reference operator*() const; +// field_pointer operator->(); +// +// SphArrayFieldIterator& operator++(); +// SphArrayFieldIterator operator++(int); +// +// bool operator==(const SphArrayFieldIterator& rhs) const; +// +//private: +// pointer mPtr; +//}; + + +} // namespace Spheral + +//#include "SphArrayInline.hh" + +#else + +//// Forward declare the SphArrayIterator class. +//namespace Spheral { +// template class SphArrayIterator ; +//} // namespace Spheral + +#endif // __Spheral_lvarray_hh__ + + diff --git a/src/Field/SphArrayInline.hh b/src/Field/SphArrayInline.hh new file mode 100644 index 000000000..56cb79033 --- /dev/null +++ b/src/Field/SphArrayInline.hh @@ -0,0 +1,149 @@ +namespace Spheral { + +template +inline +SphArrayIterator:: +SphArrayIterator(pointer ptr) + : mPtr(ptr) {} + +template +inline +SphArrayIterator& +SphArrayIterator:: +operator++() { mPtr++; return *this; } + +template +inline +SphArrayIterator +SphArrayIterator:: +operator++(int) { SphArrayIterator it = *this; operator++(); return it; } + +template +inline +SphArrayIterator& +SphArrayIterator:: +operator--() { mPtr--; return *this; } + +template +inline +SphArrayIterator +SphArrayIterator:: +operator--(int) { SphArrayIterator it = *this; operator--(); return it; } + +template +inline +SphArrayIterator +SphArrayIterator:: +operator+(const difference_type& index) const { SphArrayIterator it = *this; it.mPtr += index; return it; } + +template +inline +SphArrayIterator +SphArrayIterator:: +operator-(const difference_type& index) const { SphArrayIterator it = *this; it.mPtr -= index; return it; } + +template +inline +typename SphArrayIterator::difference_type +SphArrayIterator:: +operator-(const SphArrayIterator& it){ return std::distance(it.mPtr,mPtr); } + +template +inline +typename SphArrayIterator::reference +SphArrayIterator:: +operator[](int index){ return *(mPtr+index); } + +template +inline +typename SphArrayIterator::pointer +SphArrayIterator:: +operator->(){ return mPtr; } + +template +inline +typename SphArrayIterator::reference +SphArrayIterator:: +operator*() const { return *mPtr; } + +template +inline +bool +SphArrayIterator:: +operator==(const SphArrayIterator& rhs) const { return mPtr == rhs.mPtr; } + +template +inline +bool +SphArrayIterator:: +operator!=(const SphArrayIterator& rhs) const { return !(*this == rhs); } + +template +inline +bool +SphArrayIterator:: +operator<(const SphArrayIterator& rhs) const {return mPtr < rhs.mPtr; } + +template +inline +bool +SphArrayIterator:: +operator<=(const SphArrayIterator& rhs) const {return operator<(rhs) || operator==(rhs); } + +template +inline +bool +SphArrayIterator:: +operator>(const SphArrayIterator& rhs) const {return !(operator<(rhs) || operator==(rhs)); } + +template +inline +bool +SphArrayIterator:: +operator>=(const SphArrayIterator& rhs) const {return !operator<(rhs); } + +template +SphArrayIterator:: +operator SphArrayIterator() const {return SphArrayIterator(mPtr); } + +//------------------------- + +template +inline +SphArrayFieldIterator:: +SphArrayFieldIterator(pointer ptr) + : mPtr(ptr) {} + +template +inline +typename SphArrayFieldIterator::field_reference +SphArrayFieldIterator:: +operator*() const { return *(*mPtr); } + +template +inline +typename SphArrayFieldIterator::field_pointer +SphArrayFieldIterator:: +operator->(){ return (*mPtr).operator->(); } + +template +inline +SphArrayFieldIterator& +SphArrayFieldIterator:: +operator++() { mPtr++; return *this; } + +template +inline +SphArrayFieldIterator +SphArrayFieldIterator:: +operator++(int) { SphArrayFieldIterator it = *this; operator++(); return it; } + +template +inline +bool +SphArrayFieldIterator:: +operator==(const SphArrayFieldIterator& rhs) const { return mPtr == rhs.mPtr; } + + + +} // namespace Spheral diff --git a/src/Field/SphArrayInst.cc.py b/src/Field/SphArrayInst.cc.py new file mode 100644 index 000000000..b9d7a209c --- /dev/null +++ b/src/Field/SphArrayInst.cc.py @@ -0,0 +1,32 @@ +text = """ +//------------------------------------------------------------------------------ +// Explicit instantiation. +//------------------------------------------------------------------------------ +#include "Field/SphArray.hh" +#include "Geometry/Dimension.hh" + +namespace Spheral { +""" + +for DT in ("Dim< %(ndim)s >::Scalar", + "Dim< %(ndim)s >::Vector", + "Dim< %(ndim)s >::Tensor", + "Dim< %(ndim)s >::SymTensor"): + text += """ +template class SphArrayIterator< SphArray< %(DT)s > >; +template class SphArrayIterator< SphArrayView< %(DT)s > >; +""" % {"DT" : DT} + +#for FV in ("FieldView< Dim< %(ndim)s >, Dim< %(ndim)s >::Scalar >", +# "FieldView< Dim< %(ndim)s >, Dim< %(ndim)s >::Vector >", +# "FieldView< Dim< %(ndim)s >, Dim< %(ndim)s >::Tensor >", +# "FieldView< Dim< %(ndim)s >, Dim< %(ndim)s >::SymTensor >"): +# text += """ +#template class SphArrayFieldIterator< SphArray< %(FV)s > >; +#template class SphArrayFieldIterator< SphArrayView< %(FV)s > >; +#""" % {"FV" : FV} + +text += """ +} +""" + diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh new file mode 100644 index 000000000..ae60344f2 --- /dev/null +++ b/src/Utilities/ValueViewInterface.hh @@ -0,0 +1,254 @@ +#ifndef __SPHERAL_VALUEVIEWINTERFACE__ +#define __SPHERAL_VALUEVIEWINTERFACE__ + +//#include "Utilities/SharedPtr.hh" +#include "chai/ManagedSharedPtr.hpp" +#include "Field/SphArray.hh" +#include + +namespace Spheral { + +// Macro tool for unpacking types with multiple template arguments. +#define UNPACK( ... ) __VA_ARGS__ + +//----------------------------------------------------------------------------- +// Helper classes and Macros for defining a Value/View pattern in Spheral. +//----------------------------------------------------------------------------- + +// An interface class to ensure all required methods are defined by Data +// classes that need to be automatically copied by another CHAICopyable or +// SPHERALCopyable class. +template +class SPHERALCopyable : public chai::CHAICopyable{ + //virtual void free(); + //SPHERAL_HOST_DEVICE virtual T& operator=(std::nullptr_t) = 0; + //SPHERAL_HOST_DEVICE virtual void shallowCopy(T const& rhs) = 0; +}; + +// Interface class for View like objects. +// +// All View classes should inherit from SpheralViewInterface. It sets up useful +// type aliases and forwarding constructors to the underlying Data class. +// +// SpheralViewInterface children will want to use VIEW_DEFINE_ALLOC_CTOR +// in order to set up a forwarding constructor from the Value class ctor +// that passes in a "new DataObject" type. + +#define USE_CMSPTR + + +template +#if defined(USE_CMSPTR) +using SMART_PTR_TYPE = chai::ManagedSharedPtr; +#else +//using SMART_PTR_TYPE = Spheral::shared_ptr; +using SMART_PTR_TYPE = std::shared_ptr; +//using SMART_PTR_TYPE = ManagedSmartPtr; +#endif + +template +class SpheralViewInterface : public SMART_PTR_TYPE +{ +private: + using m_ImplType = impl_type; + +public: + using SmartPtrType = SMART_PTR_TYPE; + SPHERAL_HOST_DEVICE SmartPtrType & sptr() { return *this; } + SPHERAL_HOST_DEVICE SmartPtrType const& sptr() const { return *this; } + + SPHERAL_HOST_DEVICE m_ImplType & sptr_data() { return *(SmartPtrType::get()); } \ + SPHERAL_HOST_DEVICE m_ImplType & sptr_data() const { return *(SmartPtrType::get()); } + + SPHERAL_HOST_DEVICE SpheralViewInterface() = default; + SPHERAL_HOST SpheralViewInterface(SmartPtrType&& rhs) : SmartPtrType(std::forward(rhs)) {} +}; + + +// Interface class for Value like objects. +template +class SpheralValueInterface : public view_type +{ +private: + using m_ImplType = typename view_type::ImplType; + using m_SmartPtrType = typename view_type::SmartPtrType; + +protected: + using ViewType = typename view_type::ViewType; + +public: +#if !defined(USE_CMSPTR) + SPHERAL_HOST SpheralValueInterface(m_ImplType* rhs) : view_type((rhs)) {} +#endif + SPHERAL_HOST SpheralValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} +}; + + + + +#define SPTR_REF ViewInterface::sptr +#define SPTR_DATA_REF ViewInterface::sptr_data + +// Defines a ctor that will take a "new" Data object to create the underlying +// ManagedSmartPtr. +#if !defined(USE_CMSPTR) +#define VIEW_DEFINE_ALLOC_CTOR(view_t) \ +protected: \ + view_t(ImplType* rhs) : Base(SmartPtrType(rhs, [](ImplType *p) { p->free(); } )) {} + //view_t(ImplType* rhs) : Base(SmartPtrType(rhs, [](ImplType *p) { p->free(); } )) {} +#else +#define VIEW_DEFINE_ALLOC_CTOR(view_t) \ +public: \ + view_t(SmartPtrType&& rhs) : Base(std::forward(rhs)) {} +#endif + +#define VIEW_DEF_CTOR(view_t) \ + view_t() = default; + +#define VIEW_COPY_CTOR(view_t) \ + view_t(view_t const& rhs) = default; + +#define VIEW_ASSIGNEMT_OP() \ + SPHERAL_HOST_DEVICE ViewType& operator=(ViewType const& rhs) = default; + +#define VIEW_EQ_OP() \ + bool operator==(const ViewType& rhs) const \ + { return sptr_data() == rhs.sptr_data(); } + +#define VIEW_SHALLOW_COPY(view_t) \ +public: \ + void shallowCopy(view_t const& rhs) {*this = rhs;} + + +#define VIEW_INTERFACE_METACLASS(value_t, view_t, impl_t) \ +public: \ + using ImplType = UNPACK impl_t; \ + using ViewType = UNPACK view_t; \ + using ValueType = UNPACK value_t; \ +protected: \ + using Base = Spheral::SpheralViewInterface; \ + using ViewInterface = Base; \ + using SmartPtrType = typename Base::SmartPtrType; \ + friend class UNPACK value_t; \ + VIEW_DEFINE_ALLOC_CTOR(view_t) \ + SPHERAL_HOST_DEVICE VIEW_DEF_CTOR(view_t) \ + VIEW_SHALLOW_COPY(UNPACK view_t) \ + +#define VIEW_INTERFACE_METACLASS_DECLARATION_BEGIN(value_t, view_t, impl_t) \ +UNPACK view_t : public Spheral::SpheralViewInterface< UNPACK impl_t> { \ + VIEW_INTERFACE_METACLASS((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) \ + POINTER_SYNTAX_OPERATORS() + +#define VIEW_INTERFACE_METACLASS_DECLARATION_END() \ +}; + +#define VIEW_INTERFACE_METACLASS_DECLARATION(value_t, view_t, impl_t, code) \ + VIEW_INTERFACE_METACLASS_DECLARATION_BEGIN((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) \ + UNPACK code \ +} + + + +#define VALUE_TYPE_ALIASES(view_t) \ +public: \ + using ViewType = UNPACK view_t; \ + using ValueType = typename ViewType::ValueType; \ + using ImplType = typename ViewType::ImplType; \ +protected: \ + using Base = Spheral::SpheralValueInterface; \ + using ViewInterface = typename ViewType::ViewInterface; \ + using SmartPtrType = typename ViewType::SmartPtrType; \ + +#define UPCAST_CONVERSION_OP(parent_t) \ +public: \ + operator parent_t() const {return parent_t(this->sptr());} + +#define POINTER_SYNTAX_OPERATORS() \ +public: \ + SPHERAL_HOST_DEVICE ImplType& operator*() const { return SPTR_DATA_REF(); } \ + SPHERAL_HOST_DEVICE ImplType* operator->() const { return &SPTR_DATA_REF(); } + +#if !defined(USE_CMSPTR) +#define VALUE_DEF_CTOR(value_t) \ + value_t() : Base(new ImplType()) {} +#define VALUE_COPY_CTOR(value_t) \ + value_t(value_t const& rhs) : Base(new ImplType( deepCopy( rhs.SPTR_DATA_REF() ) )) {} +#define VALUE_ASSIGNEMT_OP() \ + ValueType& operator=(ValueType const& rhs) { \ + ViewType::operator=( ViewType::ViewType(new ImplType( deepCopy( rhs.SPTR_DATA_REF() )))); \ + return *this; \ + } + +#else +#define VALUE_DEF_CTOR(value_t) \ + value_t() : Base(chai::make_shared()) {} +#define VALUE_COPY_CTOR(value_t) \ + value_t(value_t const& rhs) : Base(chai::make_shared( deepCopy(rhs.SPTR_DATA_REF()) )) {} +#define VALUE_ASSIGNEMT_OP() \ + ValueType& operator=(ValueType const& rhs) { \ + ViewType::operator=( ViewType::ViewType(chai::make_shared( deepCopy( rhs.SPTR_DATA_REF() )))); \ + return *this; \ + } + +#endif + + +#define VALUE_EQ_OP() \ + bool operator==(const ValueType& rhs) const \ + { return compare(sptr_data(), rhs.sptr_data()); } + +#define VALUE_TOVIEW_OP() \ + ViewType toView() { return ViewType(*this); } + +#define VALUE_TYPE_DEFAULT_ASSIGNMENT_OP(value_t) \ + value_t& operator=(value_t const& rhs) { \ + ViewType::operator=( ViewType( new ImplType(deepCopy(rhs.ViewInterface::sptr_data())) ) ); \ + return *this; \ + } + + +#define VALUE_INTERFACE_METACLASS(view_t) \ +public: \ + using ViewType = UNPACK view_t; \ + using ValueType = typename ViewType::ValueType; \ + using ImplType = typename ViewType::ImplType; \ +protected: \ + using Base = Spheral::SpheralValueInterface; \ + using ViewInterface = typename ViewType::ViewInterface; \ + using SmartPtrType = typename ViewType::SmartPtrType; \ +public: \ + VALUE_TOVIEW_OP() \ + ViewType operator&() { return toView(); }\ + + +#define VALUE_INTERFACE_METACLASS_DECLARATION_BEGIN(value_t, view_t) \ +UNPACK value_t : public Spheral::SpheralValueInterface { \ + VALUE_INTERFACE_METACLASS((UNPACK view_t)) \ + + +#define VALUE_INTERFACE_METACLASS_DECLARATION_END() \ +}; + +#define VALUE_INTERFACE_METACLASS_DECLARATION(value_t, view_t, code) \ + VALUE_INTERFACE_METACLASS_DECLARATION_BEGIN((UNPACK value_t), (UNPACK view_t)) \ + UNPACK code \ +} + +#define DELETED_INTERFACE(type) \ +public: \ + type() = delete; \ + type(type const&) = delete; \ + type& operator=(type const&) = delete; \ + +#define DEFAULT() ; + +// It is assumed that the Base type is defined with from inheriting +// SpheralViewInterface or by explicitly defining : +// using Base = ManagedSmartPtr; +#define SMART_PTR_MEMBER_ACCESSOR(type, var) \ + SPHERAL_HOST_DEVICE type & var() { return Base::get()->var; } \ + SPHERAL_HOST_DEVICE type & var() const { return Base::get()->var; } + +} // namespace Spheral + +#endif // __SPHERAL_VALUEVIEWINTERFACE__ diff --git a/src/config.hh.in b/src/config.hh.in index 372a8618c..7b1fb0180 100644 --- a/src/config.hh.in +++ b/src/config.hh.in @@ -1,6 +1,19 @@ #ifndef SPHERAL_config_HPP #define SPHERAL_config_HPP +#include "RAJA/RAJA.hpp" + #define SPHERAL_CXX_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@" +#cmakedefine SPHERAL_ENABLE_OPENMP +#cmakedefine SPHERAL_ENABLE_CUDA + +#if defined(SPHERAL_ENABLE_CUDA) && defined(__CUDA_ARCH__) +#define SPHERAL_GPU_ACTIVE +#endif // SPHERAL_ENABLE_CUDA && __CUDACC__ + +#define SPHERAL_HOST_DEVICE RAJA_HOST_DEVICE +#define SPHERAL_HOST RAJA_HOST +#define SPHERAL_DEVICE RAJA_DEVICE + #endif // SPHERAL_config_HPP diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 000000000..4b1f40e25 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(cpp/Field) +add_subdirectory(cpp/Kernel) +add_subdirectory(cpp/Utilities) diff --git a/tests/cpp/Field/CMakeLists.txt b/tests/cpp/Field/CMakeLists.txt new file mode 100644 index 000000000..d80f75095 --- /dev/null +++ b/tests/cpp/Field/CMakeLists.txt @@ -0,0 +1,22 @@ +spheral_add_test( + NAME managed_vector_tests + SOURCES managed_vector_tests.cc +) + +spheral_add_test( + NAME field_parallel_inheritance_tests + SOURCES field_parallel_inheritance_tests.cc +) + +#spheral_add_test( +# NAME field_tests +# SOURCES field_tests.cc +# DEPENDS_ON Spheral_NodeList Spheral_Geometry Spheral_Hydro Spheral_DataOutput Spheral_Utilities +# #DEBUG_LINKER +#) +# +#spheral_add_test( +# NAME fieldview_tests +# SOURCES fieldview_tests.cc +# #DEBUG_LINKER +#) diff --git a/tests/cpp/Field/field_parallel_inheritance_tests.cc b/tests/cpp/Field/field_parallel_inheritance_tests.cc new file mode 100644 index 000000000..9a50bc003 --- /dev/null +++ b/tests/cpp/Field/field_parallel_inheritance_tests.cc @@ -0,0 +1,249 @@ +#include "test-utilities.hh" +#include "test-basic-exec-policies.hh" + + +#include "Field/SphArray.hh" +#include "Utilities/ValueViewInterface.hh" +#include + +namespace Spheral { + + +//----------------------------------------------------------------------------- +// Implementation of Existing Class in Spheral... +//----------------------------------------------------------------------------- + +namespace impl { + +class FB : chai::CHAIPoly{ + public: + SPHERAL_HOST_DEVICE FB() {} + FB(size_t h) : hash(h) {} + + SPHERAL_HOST_DEVICE size_t getHash() const { return hash; } + + size_t hash = 0; + + virtual void resize(size_t sz) = 0; + SPHERAL_HOST_DEVICE virtual size_t size() = 0; +}; + +template +class F : public FB, SPHERALCopyable>{ +public: + ManagedVector m_data; + + SPHERAL_HOST_DEVICE F() : FB() {} + F(size_t h, size_t sz) : FB(h), m_data(sz) {} + + SPHERAL_HOST_DEVICE T* data() { return &m_data[0]; } + SPHERAL_HOST_DEVICE T& operator()(size_t idx) { return m_data[idx]; } + + friend F deepCopy(F const& rhs) { + F result(rhs); + result.m_data = deepCopy(rhs.m_data); + return result; + } + + virtual void resize(size_t sz) override {std::cout << "Resize : " << sz << std::endl; m_data.resize(sz); } + SPHERAL_HOST_DEVICE virtual size_t size() override { return m_data.size(); } +}; + +} // namespace impl + + + +//----------------------------------------------------------------------------- +// Interface to support porting to the GPU. +//----------------------------------------------------------------------------- + +// We need to forward declare value classes for view interface definitions. +template +class F; +class FB; + +// Define Metaclass macros for Value/View relationships +#define FBV__(code) VIEW_INTERFACE_METACLASS_DECLARATION((FB), (FBV), (impl::FB), (code)) +#define FB__(code) VALUE_INTERFACE_METACLASS_DECLARATION((FB), (FBV), (code)) + +#define FV__(code) VIEW_INTERFACE_METACLASS_DECLARATION((F), (FV), (impl::F), (code)) +#define F__(code) VALUE_INTERFACE_METACLASS_DECLARATION((F), (FV), (code)) + + +// --- Interface definitions --- + +class FBV__( + DEFAULT() +); + +// This class instantiation exsists only to fulfil type information +// queries that might arise : e.g. `typename FB::ViewType` +class FB__( + // Because the underlying impl type is an abstract virtual we can not allow + // construction of FB class with default Ctor, Copy Ctor or assignment Op. + DELETED_INTERFACE(FB) +); + + +template +class FV__( + // Field inherits from FieldBase so we would like to be able to implicitly + // upcast a fieldview object to a fieldbaseview. + UPCAST_CONVERSION_OP(FBV) +); + +template +class F__( +public: + // Define Default semantic value type operations for def Ctor, Copy Ctor + // and assignment op. + VALUE_DEF_CTOR(F) + VALUE_COPY_CTOR(F) + VALUE_ASSIGNEMT_OP() + + // Custom Ctor, note we need to create the underlying implementation + // object on ctor of value interfaces. + F(size_t h, size_t sz) : Base(chai::make_shared(h, sz)) {} + + // Value semantics dictate that we free underlying data upon destruction. + ~F() { this->sptr()->m_data.free(); } + + // HOST only interface + void resize(size_t sz) { this->sptr_data().resize(sz); } + + // Moved from old View Interface pattern. + T* data() {return SPTR_DATA_REF().data(); } + T& operator()(size_t idx) { return this->sptr_data().operator()(idx); } + size_t size() const { return this->sptr_data().size(); } + + size_t getHash() const { return this->sptr_data().getHash(); } +); + + +}// namespace Spheral + + + +//----------------------------------------------------------------------------- +// TEST SUITE +//----------------------------------------------------------------------------- + +// Setting up G Test for QuadraticInterpolator +template +class FieldParallelInheritanceTypedTest : public::testing::Test {}; + +// All QuadraticInterpolatorTets cases will run over each type in EXEC_TYPES. +TYPED_TEST_CASE(FieldParallelInheritanceTypedTest, EXEC_TYPES); + +//TEST(FieldParallelInheritance, AccessPattern) +GPU_TYPED_TEST(FieldParallelInheritanceTypedTest, AccessPattern) +{ + { + + // -------------------------------------------------------------------------- + // Field Access + + using WORK_EXEC_POLICY = TypeParam; + + Spheral::F f(2, 200); + + auto f_v = &f; + Spheral::FB::ViewType fb_v = f_v; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + printf("--- GPU BEGIN ---\n"); + printf("%ld, %ld\n", fb_v->getHash(), fb_v->size()); + printf("--- GPU END ---\n"); + EXEC_IN_SPACE_END() + + std::cout << "fb_v : " << fb_v->getHash() << " , " << std::endl; + std::cout << "f_v : " << f_v->getHash() << " , " << f_v->data() << " , " << (*f_v).size() << std::endl; + std::cout << "f : " << f.getHash() << " , " << f.data() << " , " << f.size() << std::endl; + + fb_v->resize(1123); + + std::cout << "f : " << f.getHash() << " , " << f.data() << " , " << f.size() << std::endl; + std::cout << "f_v : " << f_v->getHash() << " , " << f_v->data() << " , " << f_v->size() << std::endl; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + printf("--- GPU BEGIN ---\n"); + printf("%ld, %ld\n", fb_v->getHash(), fb_v->size()); + printf("--- GPU END ---\n"); + EXEC_IN_SPACE_END() + // -------------------------------------------------------------------------- + + // -------------------------------------------------------------------------- + // Arrays of Fields + Spheral::F f0(0, 0); + Spheral::F f1(1, 1); + Spheral::F f2(2, 2); + Spheral::F f3(3, 3); + Spheral::F f4(4, 4); + + Spheral::ManagedVector vec_fbv; + vec_fbv.reserve(5); + Spheral::ManagedVector::ViewType> vec_fv; + vec_fv.reserve(5); + + vec_fbv.push_back( &f0 ); + vec_fbv.push_back( &f1 ); + vec_fbv.push_back( &f2 ); + vec_fbv.push_back( &f3 ); + vec_fbv.push_back( &f4 ); + + vec_fv.push_back( &f0 ); + vec_fv.push_back( &f1 ); + vec_fv.push_back( &f2 ); + vec_fv.push_back( &f3 ); + vec_fv.push_back( &f4 ); + + SPHERAL_ASSERT_EQ(vec_fbv.size(), vec_fv.size()); + for(int i = 0; i < vec_fbv.size(); i++) SPHERAL_ASSERT_EQ(vec_fbv[i]->size(), (*vec_fv[i]).size()); + std::cout << "Arr Map Sz : " << chai::ArrayManager::getInstance()->getPointerMap().size() << std::endl; + + for(int i = 0; i < vec_fbv.size(); i++) + { + auto& elem = *vec_fbv[i]; + + printf("%ld, %ld\n", elem.getHash(), elem.size()); + size_t sz = elem.size(); + elem.resize(sz*2); + } + std::cout << "Arr Map Sz : " << chai::ArrayManager::getInstance()->getPointerMap().size() << std::endl; + + for(size_t i = 0; i < f0.size(); i++) { f0(i) = f0.getHash(); } + for(size_t i = 0; i < f1.size(); i++) { f1(i) = f1.getHash(); } + for(size_t i = 0; i < f2.size(); i++) { f2(i) = f2.getHash(); } + for(size_t i = 0; i < f3.size(); i++) { f3(i) = f3.getHash(); } + for(size_t i = 0; i < f4.size(); i++) { f4(i) = f4.getHash(); } + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + printf("--- GPU BEGIN ---\n"); + printf("%ld\n", vec_fv.size()); + for(int i = 0; i < vec_fbv.size(); i++) + { + auto& elem_b = *vec_fbv[i]; + auto& elem_v = *vec_fv[i]; + + printf("%ld, %ld\n", elem_b.getHash(), elem_b.size()); + printf("%p\n", &elem_v(0)); + for(size_t j = 0; j < elem_v.size(); j++) { printf("%f, ",vec_fv[i]->operator()(j));} + printf("\n"); + } + printf("--- GPU END ---\n"); + EXEC_IN_SPACE_END() + + vec_fbv.free(); + vec_fv.free(); + + std::cout << f0.size() << std::endl; + std::cout << f1.size() << std::endl; + std::cout << f2.size() << std::endl; + std::cout << f3.size() << std::endl; + std::cout << f4.size() << std::endl; + // -------------------------------------------------------------------------- + + } + std::cout << "Sptr Map Sz : " << chai::SharedPtrManager::getInstance()->getPointerMap().size() << std::endl; + std::cout << "Arr Map Sz : " << chai::ArrayManager::getInstance()->getPointerMap().size() << std::endl; +} diff --git a/tests/cpp/Field/field_tests.cc b/tests/cpp/Field/field_tests.cc new file mode 100644 index 000000000..bf7c6fe7c --- /dev/null +++ b/tests/cpp/Field/field_tests.cc @@ -0,0 +1,287 @@ +#include "test-utilities.hh" +#include "test-basic-exec-policies.hh" + +#include "Field/Field.hh" +#include "NodeList/NodeList.hh" + +#include "Field/SphArray.hh" + +using DIM3 = Spheral::Dim<3>; +using FieldBase = Spheral::FieldBase; +using FieldDouble = Spheral::Field; +using FieldViewDouble = Spheral::FieldView; +using NodeList_t = Spheral::NodeList; + +class FieldTest : public::testing::Test{ + public: + NodeList_t test_node_list = NodeList_t("DataNodeList", 10, 0); + int someInt = 5; + + void SetUp() override { + + } + +}; + +// Setting up G Test for Fiedl +TYPED_TEST_SUITE_P(FieldTypedTest); +template +class FieldTypedTest : public FieldTest {}; + +TEST_F(FieldTest, NameCtor) +{ + { + std::string field_name = "Field::NameCtor"; + FieldDouble field(field_name); + std::cout << "check\n"; + SPHERAL_ASSERT_EQ(field.name(), field_name); + SPHERAL_ASSERT_EQ(field.size(), 0); + SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); + } + SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); +} + +TEST_F(FieldTest, NameNodeListCtor) +{ + { + std::string field_name = "Field::NodeListCtor"; + FieldDouble field(field_name, this->test_node_list); + SPHERAL_ASSERT_EQ(field.name(), field_name); + SPHERAL_ASSERT_EQ(field.size(), 10); + SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 6); + } + SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); +} + + + +GPU_TYPED_TEST_P(FieldTypedTest, NameNodeListValCtor) +{ + using WORK_EXEC_POLICY = TypeParam; + + { + std::string field_name = "Field::NodeListValCtor"; + FieldDouble field(field_name, gpu_this->test_node_list, 4); + SPHERAL_ASSERT_EQ(field.name(), field_name); + SPHERAL_ASSERT_EQ(field.size(), 10); + + auto field_v = field.toView(); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST_DEVICE (int i) { + SPHERAL_ASSERT_EQ(field_v[i], 4); + }); + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); + } + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); +} + + +GPU_TYPED_TEST_P(FieldTypedTest, CopyCtor) +{ + using WORK_EXEC_POLICY = TypeParam; + + { + std::string field_name = "Field::CopyCtor"; + FieldDouble field(field_name, gpu_this->test_node_list, 4); + + FieldDouble copy_field(field); + + SPHERAL_ASSERT_EQ(copy_field.name(), field_name); + SPHERAL_ASSERT_EQ(copy_field.size(), 10); + + auto field_v = field.toView(); + auto copy_field_v = copy_field.toView(); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST_DEVICE (int i) { + SPHERAL_ASSERT_EQ(copy_field_v[i], 4); + copy_field_v[i] = 5; + }); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST_DEVICE (int i) { + SPHERAL_ASSERT_EQ(field_v[i], 4); + SPHERAL_ASSERT_EQ(copy_field_v[i], 5); + }); + + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 7); + SPHERAL_ASSERT_NE(&field[0], ©_field[0]); + } + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); +} + + +GPU_TYPED_TEST_P(FieldTypedTest, FieldView) +{ + using WORK_EXEC_POLICY = TypeParam; + + { + std::string field_name = "Field::FieldView"; + FieldDouble field(field_name, gpu_this->test_node_list, 4); + + FieldViewDouble field_v(field); + + SPHERAL_ASSERT_EQ(field_v.size(), 10); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST_DEVICE (int i) { + field_v[i] = 5; + }); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST_DEVICE (int i) { + SPHERAL_ASSERT_EQ(field_v[i], 5); + }); + + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); + SPHERAL_ASSERT_EQ(&field[0], &field_v[0]); + } + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); +} + + +TEST_F(FieldTest, AssignmentFieldBase) +{ + { + std::string field_name = "Field::AssignmentFieldBase"; + FieldDouble field(field_name, this->test_node_list, 4); + + FieldBase* base = &field; + + SPHERAL_ASSERT_EQ(base->name(), field_name); + //SPHERAL_ASSERT_EQ(field.size(), 0); + SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 6); + } + SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); +} + +GPU_TYPED_TEST_P(FieldTypedTest, AssignmentField) +{ + using WORK_EXEC_POLICY = TypeParam; + + { + std::string field_name = "Field::AssignmentField"; + FieldDouble field(field_name, gpu_this->test_node_list, 4); + + FieldDouble copy_field = field; + + SPHERAL_ASSERT_EQ(copy_field.name(), field_name); + SPHERAL_ASSERT_EQ(copy_field.size(), 10); + + auto field_v = field.toView(); + auto copy_field_v = copy_field.toView(); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST_DEVICE (int i) { + SPHERAL_ASSERT_EQ(copy_field_v[i], 4); + copy_field_v[i] = 5; + }); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST_DEVICE (int i) { + SPHERAL_ASSERT_EQ(field_v[i], 4); + SPHERAL_ASSERT_EQ(copy_field_v[i], 5); + }); + + SPHERAL_ASSERT_NE(&field[0], ©_field[0]); + + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 7); + } + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); +} + +GPU_TYPED_TEST_P(FieldTypedTest, AssignmentContainerType) +{ + using WORK_EXEC_POLICY = TypeParam; + + { + std::string field_name = "Field::AssignmentContainer"; + FieldDouble field(field_name, gpu_this->test_node_list, 4); + + using ContainerType = FieldDouble::ContainerType; + ContainerType data(10); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST_DEVICE (int i) { + data[i] = i; + }); + + field = data; + auto field_v = field.toView(); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST_DEVICE (int i) { + field_v[i] *= 2; + }); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST_DEVICE (int i) { + //SPHERAL_ASSERT_EQ(field[i], i); // Should not change we deep copy in lambdas... + SPHERAL_ASSERT_EQ(field_v[i], i*2); + }); + + SPHERAL_ASSERT_NE(&field[0], &data[0]); + + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); + } + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); +} + +TEST_F(FieldTest, AssignmentDataType) +{ + SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); + { + std::string field_name = "Field::AssignmentDataType"; + FieldDouble field(field_name, this->test_node_list, 4); + + SPHERAL_ASSERT_EQ(field.size(), 10); + + auto field_v = field.toView(); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST (int i) { + SPHERAL_ASSERT_EQ(field_v[i], 4); + }); + + field = double(3); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST (int i) { + SPHERAL_ASSERT_EQ(field_v[i], 3); + }); + + } + SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); +} + +GPU_TYPED_TEST_P(FieldTypedTest, size) +{ + using WORK_EXEC_POLICY = TypeParam; + + { + std::string field_name = "Field::size"; + FieldDouble field(field_name, gpu_this->test_node_list); + auto field_v = field.toView(); + SPHERAL_ASSERT_EQ(field.size(), 10); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(field_v.size(), 10); + EXEC_IN_SPACE_END() + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); + } + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); +} + +REGISTER_TYPED_TEST_SUITE_P(FieldTypedTest, + NameNodeListValCtor, + CopyCtor, + FieldView, + //AssignmentFieldBase, + AssignmentField, + AssignmentContainerType, + size + ); + +INSTANTIATE_TYPED_TEST_SUITE_P(Field, FieldTypedTest, EXEC_TYPES); + diff --git a/tests/cpp/Field/fieldview_tests.cc b/tests/cpp/Field/fieldview_tests.cc new file mode 100644 index 000000000..d4dc26b39 --- /dev/null +++ b/tests/cpp/Field/fieldview_tests.cc @@ -0,0 +1,202 @@ +#include "test-utilities.hh" +#include "test-basic-exec-policies.hh" + +#include "Field/Field.hh" +#include "Field/FieldView.hh" + +using DIM3 = Spheral::Dim<3>; +using FieldDouble = Spheral::Field; +// +using FieldViewDouble = Spheral::FieldView; + +class FieldViewTest : public::testing::Test{}; + +// Setting up G Test for Fiedl +TYPED_TEST_SUITE_P(FieldViewTypedTest); +template +class FieldViewTypedTest : public FieldViewTest {}; + +// All ManagedVectorTets cases will run over each type in EXEC_TYPES. +//TYPED_TEST_CASE(FieldViewTypedTest, EXEC_TYPES); + + +GPU_TYPED_TEST_P(FieldViewTypedTest, DefaultCtor) +{ + using WORK_EXEC_POLICY = TypeParam; + + { + + std::shared_ptr sptr; + std::cout << sptr.get() << std::endl; + + FieldDouble field("test"); + FieldViewDouble fieldv = field.toView(); + SPHERAL_ASSERT_EQ(fieldv.size(), 0); + + RAJA::forall(TRS_UINT(0,10), + [=] SPHERAL_HOST_DEVICE (int i) { + SPHERAL_ASSERT_EQ(fieldv.size(), 0); + }); + } +} + + +//GPU_TYPED_TEST_P(FieldViewTypedTest, CopyCtor) +//{ +// using WORK_EXEC_POLICY = TypeParam; +// +// { +// FieldViewDouble field(); +// +// FieldViewDouble copy_field(field); +// +// SPHERAL_ASSERT_EQ(copy_field.size(), 10); +// +// RAJA::forall(TRS_UINT(0,10), +// [=] SPHERAL_HOST_DEVICE (int i) { +// copy_field[i] == 4; +// }); +// +// RAJA::forall(TRS_UINT(0,10), +// [=] SPHERAL_HOST_DEVICE (int i) { +// SPHERAL_ASSERT_EQ(field[i], 4); +// }); +// +// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 7); +// SPHERAL_ASSERT_EQ(&field[0], ©_field[0]); +// } +// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); +//} + + +// TODO: ... +//TEST_F(FieldViewTest, AssignmentFieldViewBase) +//{ +// { +// std::string field_name = "Field::AssignmentFieldBase"; +// FieldDouble field(field_name); +// SPHERAL_ASSERT_EQ(field.name(), field_name); +// SPHERAL_ASSERT_EQ(field.size(), 0); +// SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); +// } +// SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); +//} + +//GPU_TYPED_TEST_P(FieldTypedTest, AssignmentField) +//{ +// using WORK_EXEC_POLICY = TypeParam; +// +// { +// std::string field_name = "Field::CopyCtor"; +// FieldDouble field(field_name, gpu_this->test_node_list, 4); +// +// FieldDouble copy_field = field; +// +// SPHERAL_ASSERT_EQ(copy_field.name(), ""); +// SPHERAL_ASSERT_EQ(copy_field.size(), 10); +// +// RAJA::forall(TRS_UINT(0,10), +// [=] SPHERAL_HOST_DEVICE (int i) { +// copy_field[i] == 4; +// }); +// +// RAJA::forall(TRS_UINT(0,10), +// [=] SPHERAL_HOST_DEVICE (int i) { +// SPHERAL_ASSERT_EQ(field[i], 4); +// }); +// +// SPHERAL_ASSERT_EQ(&field[0], ©_field[0]); +// +// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 7); +// } +// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); +//} +// +//GPU_TYPED_TEST_P(FieldTypedTest, AssignmentContainerType) +//{ +// using WORK_EXEC_POLICY = TypeParam; +// +// { +// std::string field_name = "Field::CopyCtor"; +// FieldDouble field(field_name, gpu_this->test_node_list, 4); +// +// using ContainerType = FieldDouble::ContainerType; +// ContainerType data(10); +// +// RAJA::forall(TRS_UINT(0,10), +// [=] SPHERAL_HOST_DEVICE (int i) { +// data[i] = i; +// }); +// +// field = data; +// +// RAJA::forall(TRS_UINT(0,10), +// [=] SPHERAL_HOST_DEVICE (int i) { +// field[i] *= 2; +// }); +// +// RAJA::forall(TRS_UINT(0,10), +// [=] SPHERAL_HOST_DEVICE (int i) { +// SPHERAL_ASSERT_EQ(field[i], i*2); +// }); +// +// SPHERAL_ASSERT_EQ(&field[0], &data[0]); +// +// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); +// } +// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); +//} +// +//TEST_F(FieldTest, AssignmentDataType) +//{ +// { +// std::string field_name = "Field::NameCtor"; +// FieldDouble field(field_name, this->test_node_list, 4); +// +// SPHERAL_ASSERT_EQ(field.size(), 10); +// SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); +// +// RAJA::forall(TRS_UINT(0,10), +// [=] SPHERAL_HOST (int i) { +// SPHERAL_ASSERT_EQ(field[i], 4); +// }); +// +// field = double(3); +// +// SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 6); +// RAJA::forall(TRS_UINT(0,10), +// [=] SPHERAL_HOST (int i) { +// SPHERAL_ASSERT_EQ(field[i], 3); +// }); +// +// +// } +// SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); +//} +// +//GPU_TYPED_TEST_P(FieldTypedTest, size) +//{ +// using WORK_EXEC_POLICY = TypeParam; +// +// { +// std::string field_name = "Field::size"; +// FieldDouble field(field_name, gpu_this->test_node_list); +// EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) +// SPHERAL_ASSERT_EQ(field.size(), 10); +// EXEC_IN_SPACE_END() +// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); +// } +// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); +//} + +REGISTER_TYPED_TEST_SUITE_P(FieldViewTypedTest, + DefaultCtor//, + //CopyCtor, + ////AssignmentFieldBase, + //AssignmentField, + //AssignmentContainerType, + //size + ); + +INSTANTIATE_TYPED_TEST_SUITE_P(FieldView, FieldViewTypedTest, EXEC_TYPES); + diff --git a/tests/cpp/Field/managed_vector_tests.cc b/tests/cpp/Field/managed_vector_tests.cc new file mode 100644 index 000000000..baffd1d45 --- /dev/null +++ b/tests/cpp/Field/managed_vector_tests.cc @@ -0,0 +1,447 @@ +#include "test-utilities.hh" +#include "test-basic-exec-policies.hh" + +#include "Field/SphArray.hh" +#include "chai/managed_ptr.hpp" + +using MVDouble = Spheral::ManagedVector; + +#define assert_empty_map(IGNORED) ASSERT_EQ(chai::ArrayManager::getInstance()->getPointerMap().size(),0) + + +// Setting up G Test for ManagedVector +template +class ManagedVectorTypedTest : public::testing::Test {}; + +// All ManagedVectorTets cases will run over each type in EXEC_TYPES. +TYPED_TEST_CASE(ManagedVectorTypedTest, EXEC_TYPES); + + +GPU_TYPED_TEST(ManagedVectorTypedTest, DefaultConstructor) +{ + using WORK_EXEC_POLICY = TypeParam; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + MVDouble array; + + SPHERAL_ASSERT_EQ(array.size(), 0); + SPHERAL_ASSERT_EQ(array.capacity(), 0); + EXEC_IN_SPACE_END(); +} + + +TEST(ManagedVectorTest, SizeConstructor) +{ + // Size Constructor will allocate initial capacity if elements + // are below initial_capacity + MVDouble array(6); + SPHERAL_ASSERT_EQ(array.size(), 6u); + SPHERAL_ASSERT_EQ(array.capacity(), MVDouble::initial_capacity); + + // Size Constructor will allocate n elements if elements + // are above initial_capacity + MVDouble array2(MVDouble::initial_capacity + 1); + SPHERAL_ASSERT_EQ(array2.size(), MVDouble::initial_capacity + 1); + SPHERAL_ASSERT_EQ(array2.capacity(), MVDouble::initial_capacity * 2); +} + + + +TEST(ManagedVectorTest, IdentityConstructor) +{ + MVDouble array(6, 5); + SPHERAL_ASSERT_EQ(array.size(), 6u); + SPHERAL_ASSERT_EQ(array.capacity(), MVDouble::initial_capacity); + + for(auto& elem: array){ + SPHERAL_ASSERT_EQ(elem, 5); + } +} + + +GPU_TYPED_TEST(ManagedVectorTypedTest, IdentityConstructor) +{ + + using WORK_EXEC_POLICY = TypeParam; + + MVDouble array(6, 5); + MVDouble array2(6); + SPHERAL_ASSERT_EQ(array.size(), 6u); + SPHERAL_ASSERT_EQ(array.capacity(), MVDouble::initial_capacity); + + RAJA::forall(TRS_UINT(0,6), + [=] RAJA_HOST_DEVICE (unsigned idx){ + array2[idx] = array[idx]; + } + ); + RAJA::forall(TRS_UINT(0,6), + [=] RAJA_HOST (unsigned idx){ + SPHERAL_ASSERT_EQ(array2[idx], 5); + } + ); + +} + + +GPU_TYPED_TEST(ManagedVectorTypedTest, ManagedPtrArrayTest) +{ + using WORK_EXEC_POLICY = TypeParam; + + //Spheral::MVSmartRef array = Spheral::make_MVSmartRef(5, chai::CPU); + Spheral::MVSmartRef array; + //array = Spheral::make_MVSmartRef(5, chai::CPU); + array = Spheral::MVSmartRef(5, chai::CPU); + + Spheral::MVSmartRef copy_array(array); + + SPHERAL_ASSERT_EQ(array->size(), copy_array->size()); + + std::cout << "check0\n"; + RAJA::forall(TRS_UINT(0,array->size()), + [=] RAJA_HOST_DEVICE (unsigned i){ + array[i] = i*2; + Spheral::MVSmartRef copy_array_2 = array; + SPHERAL_ASSERT_EQ(copy_array_2[i], i*2); + } + ); + + + std::cout << "resize\n"; + array.resize(20); + + + std::cout << "check1\n"; + std::cout << copy_array->size(); + RAJA::forall(TRS_UINT(0,array->size()), + [=] RAJA_HOST_DEVICE (unsigned i){ + if (i >= 5) copy_array[i] = i*3; + //SPHERAL_ASSERT_TRUE (copy_array->size() == 20); + } + ); + + std::cout << "check1.5\n"; + RAJA::forall(TRS_UINT(0,array->size()), + [=] RAJA_HOST (unsigned i){ + if (i < 5) SPHERAL_ASSERT_EQ(copy_array[i], i*2); + else SPHERAL_ASSERT_EQ(copy_array[i], i*3); + } + ); + + std::cout << "check2\n"; + SPHERAL_ASSERT_EQ(&array[15], ©_array[15]); + SPHERAL_ASSERT_EQ(array->size(), copy_array->size()); + + Spheral::MVSmartRef deep_copy_array = deepCopy(array); + //Spheral::MVSmartRef deep_copy_array = Spheral::make_MVSmartRef(deepCopy(*array.get())); + SPHERAL_ASSERT_EQ(array->size(), deep_copy_array->size()); + + RAJA::forall(TRS_UINT(0,array->size()), + [=] RAJA_HOST (unsigned i){ + SPHERAL_ASSERT_EQ(deep_copy_array[i], array[i]); + } + ); + + deep_copy_array[5] = 1234; + SPHERAL_ASSERT_NE(deep_copy_array[5], array[5]); + SPHERAL_ASSERT_NE(&deep_copy_array[0], &array[0]); +} + +GPU_TYPED_TEST(ManagedVectorTypedTest, CopyConstructor) +{ + using WORK_EXEC_POLICY = TypeParam; + + MVDouble array(4); + MVDouble copy_array(array); + //MVDouble copy_array = array.slice(0, array.size()); + + array.resize(6); + + SPHERAL_ASSERT_EQ(&array[0], ©_array[0]); + SPHERAL_ASSERT_EQ(array.capacity(), copy_array.capacity()); + + RAJA::forall(TRS_UINT(0,6), + [=] RAJA_HOST_DEVICE (unsigned i){ + array[i] = i; + } + ); + + RAJA::forall(TRS_UINT(0,6), + [=] RAJA_HOST (unsigned i){ + SPHERAL_ASSERT_EQ(copy_array[i], i); + } + ); + + SPHERAL_ASSERT_EQ(&array[0], ©_array[0]); + + array.resize(20); + + SPHERAL_ASSERT_EQ(&array[0], ©_array[0]); +} + +GPU_TYPED_TEST(ManagedVectorTypedTest, AssignmentOperator) +{ + using WORK_EXEC_POLICY = TypeParam; + + MVDouble array(6, 5); + + MVDouble copy_array = array; + + RAJA::forall(TRS_UINT(0,6), + [=] RAJA_HOST_DEVICE (unsigned i){ + array[i] = i; + } + ); + + RAJA::forall(TRS_UINT(0,6), + [=] RAJA_HOST (unsigned i){ + SPHERAL_ASSERT_EQ(copy_array[i], i); + } + ); + + SPHERAL_ASSERT_EQ(&array[0], ©_array[0]); +} + +GPU_TYPED_TEST(ManagedVectorTypedTest, Equivalence) +{ + using WORK_EXEC_POLICY = TypeParam; + + MVDouble array(6, 5); + MVDouble array2(6, 3); + + MVDouble copy_array = array; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + + for (size_t i = 0; i < 6u; i++) { + array[i] = i; + array2[i] = i; + } + SPHERAL_ASSERT_TRUE (copy_array == array); + SPHERAL_ASSERT_FALSE(copy_array == array2); + EXEC_IN_SPACE_END() + + EXEC_IN_SPACE_BEGIN(LOOP_EXEC_POLICY) + ASSERT_TRUE (copy_array == array); + ASSERT_FALSE(copy_array == array2); + EXEC_IN_SPACE_END() +} + +GPU_TYPED_TEST(ManagedVectorTypedTest, PushBackDefault) +{ + using WORK_EXEC_POLICY = TypeParam; + + MVDouble array; + double val = 5; + + array.push_back(val); + + SPHERAL_ASSERT_EQ(array.size(), 1u); + SPHERAL_ASSERT_EQ(array.capacity(), MVDouble::initial_capacity); + SPHERAL_ASSERT_EQ(array[0], val); + + MVDouble array2; + + for(size_t i = 0; i < 10; i++) + array2.push_back(i); + + for(size_t i = 0; i < array2.size(); i++) + SPHERAL_ASSERT_EQ(array2[i], i); + + RAJA::forall(TRS_UINT(0,10), + [=] RAJA_HOST_DEVICE (unsigned idx){ + SPHERAL_ASSERT_EQ(array2.size(), 10u); + SPHERAL_ASSERT_EQ(array2[idx], idx); + array2[idx] *= 2; + } + ); + + RAJA::forall(TRS_UINT(0,6), + [=] RAJA_HOST (unsigned idx){ + SPHERAL_ASSERT_EQ(array2[idx], idx*2); + } + ); + + SPHERAL_ASSERT_EQ(array2.capacity(), MVDouble::initial_capacity * 2); +} + +TEST(ManagedVectorTest, PushBackMove) +{ + MVDouble array; + + array.push_back(std::move(5)); + + SPHERAL_ASSERT_EQ(array.size(), 1u); + SPHERAL_ASSERT_EQ(array.capacity(), MVDouble::initial_capacity); + SPHERAL_ASSERT_EQ(array[0], 5); + + MVDouble array2; + + for(size_t i = 0; i < 10; i++) + array2.push_back(std::move(i)); + + for(size_t i = 0; i < array2.size(); i++) + SPHERAL_ASSERT_EQ(array2[i], i); + + SPHERAL_ASSERT_EQ(array2.capacity(), MVDouble::initial_capacity * 2); +} + +GPU_TYPED_TEST(ManagedVectorTypedTest, ResizeLargerNoRealloc) +{ + using WORK_EXEC_POLICY = TypeParam; + + MVDouble array; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(array.size(), 0); + SPHERAL_ASSERT_EQ(array.capacity(), 0); + EXEC_IN_SPACE_END() + + array.move(chai::CPU); + array.resize(10); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(array.size(), 10); + SPHERAL_ASSERT_EQ(array.capacity(), 16); + EXEC_IN_SPACE_END() + + MVDouble array2(4); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(array2.size(), 4); + //SPHERAL_ASSERT_EQ(array2.capacity(), MVDouble::initial_capacity); + EXEC_IN_SPACE_END() + + array.move(chai::CPU); + array2.resize(6); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(array2.size(), 6); + //SPHERAL_ASSERT_EQ(array2.capacity(), MVDouble::initial_capacity); + EXEC_IN_SPACE_END() +} + +GPU_TYPED_TEST(ManagedVectorTypedTest, ResizeLargerRealloc) +{ + using WORK_EXEC_POLICY = TypeParam; + + MVDouble array(4); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(array.size(), 4); + //SPHERAL_ASSERT_EQ(array.capacity(), 0); + EXEC_IN_SPACE_END() + + array.move(chai::CPU); + array.resize(12); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(array.size(), 12); + SPHERAL_ASSERT_EQ(array.capacity(), 16); + EXEC_IN_SPACE_END() +} + +GPU_TYPED_TEST(ManagedVectorTypedTest, ResizeSmaller) +{ + using WORK_EXEC_POLICY = TypeParam; + + MVDouble array(4); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(array.size(), 4); + //SPHERAL_ASSERT_EQ(array.capacity(), 0); + EXEC_IN_SPACE_END() + + array.resize(2); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(array.size(), 2); + //SPHERAL_ASSERT_EQ(array.capacity(), MVDouble::initial_capacity); + EXEC_IN_SPACE_END() +} + +TEST(ManagedVectorTest, Erase) +{ + MVDouble array; + std::vector check = {0,1,2,3,4,5}; + + for (size_t i = 0; i < 6; i++) { + array.push_back(check[i]); + } + SPHERAL_ASSERT_EQ(array.size(), check.size()); + + // Erase the last element + array.erase(array.end() - 1); + + std::vector check2 = {0,1,2,3,4}; + SPHERAL_ASSERT_EQ(array.size(), check2.size()); + for (size_t i = 0; i < array.size(); i++) SPHERAL_ASSERT_EQ(array[i], check2[i]); + + // Erase the 3rd element + array.erase(array.begin() + 2); + + std::vector check3 = {0,1,3,4}; + SPHERAL_ASSERT_EQ(array.size(), check3.size()); + for (size_t i = 0; i < array.size(); i++) SPHERAL_ASSERT_EQ(array[i], check3[i]); + + // Erase the first element + array.erase(array.begin()); + + std::vector check4 = {1,3,4}; + SPHERAL_ASSERT_EQ(array.size(), check4.size()); + for (size_t i = 0; i < array.size(); i++) SPHERAL_ASSERT_EQ(array[i], check4[i]); +} + +TEST(ManagedVectorTest, Insert) +{ + MVDouble array; + std::vector check = {0,1,2,3,4,5}; + + for (size_t i = 0; i < 6; i++) { + array.insert(array.begin() + i, check[i]); + } + SPHERAL_ASSERT_EQ(array.size(), check.size()); + for (size_t i = 0; i < array.size(); i++) SPHERAL_ASSERT_EQ(array[i], check[i]); + + // Insert element at end + array.insert(array.end(), 6); + + std::vector check2 = {0,1,2,3,4,5,6}; + SPHERAL_ASSERT_EQ(array.size(), check2.size()); + for (size_t i = 0; i < array.size(); i++) SPHERAL_ASSERT_EQ(array[i], check2[i]); + + // Erase the 3rd element + array.insert(array.begin() + 2, 7); + + std::vector check3 = {0,1,7,2,3,4,5,6}; + SPHERAL_ASSERT_EQ(array.size(), check3.size()); + for (size_t i = 0; i < array.size(); i++) SPHERAL_ASSERT_EQ(array[i], check3[i]); + + // Erase the first element + array.insert(array.begin(), -1); + + std::vector check4 = {-1,0,1,7,2,3,4,5,6}; + SPHERAL_ASSERT_EQ(array.size(), check4.size()); + for (size_t i = 0; i < array.size(); i++) SPHERAL_ASSERT_EQ(array[i], check4[i]); +} + +TEST(ManagedVectorTest, DeepCopy) +{ + double init_val = 5; + MVDouble array(6, init_val); + + MVDouble copy_array(array); + MVDouble deep_copy_array(deepCopy(array)); + + for (size_t i = 0; i < 6u; i++) { + array[i] = 4; + } + + for (size_t i = 0; i < 6u; i++) { + ASSERT_NE(array[i], deep_copy_array[i]); + SPHERAL_ASSERT_EQ(deep_copy_array[i], init_val); + } + + ASSERT_FALSE(array == deep_copy_array); + ASSERT_NE(&array[0], &deep_copy_array[0]); +} + diff --git a/tests/cpp/Kernel/CMakeLists.txt b/tests/cpp/Kernel/CMakeLists.txt new file mode 100644 index 000000000..01b155a82 --- /dev/null +++ b/tests/cpp/Kernel/CMakeLists.txt @@ -0,0 +1,4 @@ +spheral_add_test( + NAME kernel_parallel_inheritance_tests + SOURCES kernel_parallel_inheritance_tests.cc +) diff --git a/tests/cpp/Kernel/kernel_parallel_inheritance_tests.cc b/tests/cpp/Kernel/kernel_parallel_inheritance_tests.cc new file mode 100644 index 000000000..c42cdd77c --- /dev/null +++ b/tests/cpp/Kernel/kernel_parallel_inheritance_tests.cc @@ -0,0 +1,206 @@ +#include "test-utilities.hh" +#include "test-basic-exec-policies.hh" + +#include "Field/SphArray.hh" +#include "Utilities/ValueViewInterface.hh" + +//-------------------------------- +// Impl Interface + +namespace impl { + +template +class Kernel : public Spheral::SPHERALCopyable> { + + SPHERAL_HOST_DEVICE Desc& asDesc() { + return static_cast(const_cast&>(*this)); + } +public: + SPHERAL_HOST_DEVICE void doSomething() { printf("Ki HD doSomething()\n"); asDesc().doSomething(); } + + friend Kernel deepCopy(Kernel const& rhs) { + Kernel result(rhs); + return result; + } + +}; + +template +class TableKernel : public Kernel> { +public: + TableKernel() = default; + SPHERAL_HOST_DEVICE void doSomething() { printf("TKi HD doSomething()\n"); printf("TableKernel doSomething\n"); } +}; + +template +class OtherKernel : public Kernel> { +public: + OtherKernel() = default; + SPHERAL_HOST_DEVICE void doSomething() { printf("OKi HD doSomething()\n"); printf("OtherKernel doSomething\n"); } +}; + +} // namespace impl + +//-------------------------------- +// View Interface + +template +class Kernel; +template +class TableKernel; +template +class OtherKernel; + +#define KernelView__(code) VIEW_INTERFACE_METACLASS_DECLARATION( (Kernel), (KernelView), (impl::Kernel), (code)) +#define TableKernelView__(code) VIEW_INTERFACE_METACLASS_DECLARATION( (TableKernel), (TableKernelView), (impl::TableKernel), (code)) +#define OtherKernelView__(code) VIEW_INTERFACE_METACLASS_DECLARATION( (OtherKernel), (OtherKernelView), (impl::OtherKernel), (code)) + +#define Kernel__(code) VALUE_INTERFACE_METACLASS_DECLARATION((Kernel), (KernelView), (code)) +#define TableKernel__(code) VALUE_INTERFACE_METACLASS_DECLARATION((TableKernel), (TableKernelView), (code)) +#define OtherKernel__(code) VALUE_INTERFACE_METACLASS_DECLARATION((OtherKernel), (OtherKernelView), (code)) + +template +class KernelView__( DEFAULT() ); + +template +class TableKernelView__( DEFAULT() ); + +template +class OtherKernelView__( DEFAULT() ); + +//-------------------------------- +// Value Interface + +template +class Kernel__( +public: + VALUE_DEF_CTOR(Kernel) + VALUE_COPY_CTOR(Kernel) + VALUE_ASSIGNEMT_OP() + + void doSomething() { printf("K H doSomething()\n"); this->sptr_data().doSomething(); } +); + +template +class TableKernel__( +public: + VALUE_DEF_CTOR(TableKernel) + VALUE_COPY_CTOR(TableKernel) + VALUE_ASSIGNEMT_OP() + + void doSomething() { printf("TK H doSomething()\n"); this->sptr_data().doSomething(); } +); + +template +class OtherKernel__( +public: + VALUE_DEF_CTOR(OtherKernel) + VALUE_COPY_CTOR(OtherKernel) + VALUE_ASSIGNEMT_OP() + + void doSomething() { printf("OK H doSomething()\n"); this->sptr_data().doSomething(); } +); + +class Dim1 {}; + +// +// Setting up G Test for QuadraticInterpolator +template +class KernelParallelInterface : public::testing::Test {}; + +// All QuadraticInterpolatorTets cases will run over each type in EXEC_TYPES. +TYPED_TEST_CASE(KernelParallelInterface, EXEC_TYPES); + + + +TEST(KernelParallelImpl, Impl) +{ + + impl::TableKernel tk_impl; + + tk_impl.doSomething(); + + impl::Kernel> k_impl; + + k_impl.doSomething(); + +} + +GPU_TYPED_TEST(KernelParallelInterface, TableKernelInterface) +{ + using WORK_EXEC_POLICY = TypeParam; + + TableKernel tk; + + tk.doSomething(); + + TableKernelView tkv = &tk; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + tkv->doSomething(); + EXEC_IN_SPACE_END() +} + +GPU_TYPED_TEST(KernelParallelInterface, KernelInterface) +{ + using WORK_EXEC_POLICY = TypeParam; + + Kernel> k; + + k.doSomething(); + + KernelView> kv = &k; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + kv->doSomething(); + EXEC_IN_SPACE_END() + + KernelView> kv_tkv = &k; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + kv_tkv->doSomething(); + EXEC_IN_SPACE_END() + + Kernel> k_tkv; + + k_tkv->doSomething(); + + KernelView> kv_tkv2 = &k_tkv; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + kv_tkv2->doSomething(); + EXEC_IN_SPACE_END() + +} + +GPU_TYPED_TEST(KernelParallelInterface, OtherKernelInterface) +{ + using WORK_EXEC_POLICY = TypeParam; + + Kernel> k; + + k->doSomething(); + + KernelView> kv = &k; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + kv->doSomething(); + EXEC_IN_SPACE_END() + + KernelView> kv_tkv = &k; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + kv_tkv->doSomething(); + EXEC_IN_SPACE_END() + + Kernel> k_tkv; + + k_tkv->doSomething(); + + KernelView> kv_tkv2 = &k_tkv; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + kv_tkv2->doSomething(); + EXEC_IN_SPACE_END() + +} diff --git a/tests/cpp/Utilities/CMakeLists.txt b/tests/cpp/Utilities/CMakeLists.txt new file mode 100644 index 000000000..885aed776 --- /dev/null +++ b/tests/cpp/Utilities/CMakeLists.txt @@ -0,0 +1,10 @@ +spheral_add_test( + NAME quadratic_interpolator_tests + SOURCES quadratic_interpolator_tests.cc + DEPENDS_ON Spheral_Utilities + DEBUG_LINKER +) + +add_subdirectory(ValueViewInterface) + + diff --git a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt new file mode 100644 index 000000000..62d62d5e9 --- /dev/null +++ b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt @@ -0,0 +1,12 @@ +spheral_add_test( + NAME quadratic_interpolator_example_tests + SOURCES quadratic_interpolator_example_tests.cc + #DEBUG_LINKER +) + +spheral_add_test( + NAME shared_ptr_tests + SOURCES ManagedSharedPtrTests.cc + #SOURCES shared_ptr_tests.cc + #DEBUG_LINKER +) diff --git a/tests/cpp/Utilities/ValueViewInterface/ManagedSharedPtrTests.cc b/tests/cpp/Utilities/ValueViewInterface/ManagedSharedPtrTests.cc new file mode 100644 index 000000000..1cf1b2732 --- /dev/null +++ b/tests/cpp/Utilities/ValueViewInterface/ManagedSharedPtrTests.cc @@ -0,0 +1,88 @@ +#include "test-utilities.hh" +#include "test-basic-exec-policies.hh" + +#include +#include + +//#include "Utilities/SharedPtr.hh" +#include "chai/ManagedSharedPtr.hpp" + +template +using shared_ptr_t = chai::ManagedSharedPtr; + + +class Base { +public: + SPHERAL_HOST_DEVICE Base() {printf("CTor Base\n");} + SPHERAL_HOST_DEVICE void doSomething(){ printf("Base doSomething\n"); } + SPHERAL_HOST_DEVICE ~Base() { printf("DTor Base\n"); } +}; + +class Derived : public Base { +public: + SPHERAL_HOST_DEVICE Derived() {printf("CTor Derived\n");} + SPHERAL_HOST_DEVICE void doSomething(){ printf("Derived doSomething\n"); } + SPHERAL_HOST_DEVICE ~Derived() { printf("DTor Derived\n"); } +}; + + +TEST(SharedPtrTest, BasicCount) +{ + shared_ptr_t< Derived > s_ptr = chai::make_shared(); + + s_ptr->doSomething(); + SPHERAL_ASSERT_EQ(s_ptr.use_count(), 1); + + shared_ptr_t< Derived > s_ptr2 = s_ptr; + + s_ptr2->doSomething(); + + SPHERAL_ASSERT_EQ(s_ptr.use_count(), 2); + SPHERAL_ASSERT_EQ(s_ptr2.use_count(), 2); + + SPHERAL_ASSERT_EQ(s_ptr.get(), s_ptr2.get()); +} + +TEST(SharedPtrTest, UpcastCtor) +{ + shared_ptr_t< Base > s_ptr = chai::make_shared(); + + s_ptr->doSomething(); + SPHERAL_ASSERT_EQ(s_ptr.use_count(), 1); +} + +TEST(SharedPtrTest, UpcastCopyCtor) +{ + shared_ptr_t< Derived > s_ptr = chai::make_shared(); + + s_ptr->doSomething(); + SPHERAL_ASSERT_EQ(s_ptr.use_count(), 1); + + shared_ptr_t< Base > s_ptr_b = s_ptr; + + s_ptr_b->doSomething(); + + SPHERAL_ASSERT_EQ(s_ptr.use_count(), 2); + SPHERAL_ASSERT_EQ(s_ptr_b.use_count(), 2); + + SPHERAL_ASSERT_EQ(s_ptr.get(), s_ptr_b.get()); +} + +//TEST(SharedPtrTest, SharedCount) +//{ +// +// //Spheral::__shared_count(new Derived(), [](Derived* d){printf("Custom Deleter\n"); d->~Derived();}); +// Spheral::__shared_ptr sptr(new Derived(), [](Derived* d){printf("Custom Deleter\n"); d->~Derived();}); +// +// +// +//} + + +// Setting up G Test for SharedPtr +template +class SharedPtrTypedTest : public::testing::Test {}; + +// All SharedPtrTets cases will run over each type in EXEC_TYPES. +TYPED_TEST_CASE(SharedPtrTypedTest, EXEC_TYPES); + diff --git a/tests/cpp/Utilities/ValueViewInterface/QInt.hh b/tests/cpp/Utilities/ValueViewInterface/QInt.hh new file mode 100644 index 000000000..f00668ba7 --- /dev/null +++ b/tests/cpp/Utilities/ValueViewInterface/QInt.hh @@ -0,0 +1,88 @@ +//----------------------------------------------------------------------------- +// Quadratic Interpolator Example implementation +//----------------------------------------------------------------------------- + +#include "Utilities/ValueViewInterface.hh" + +namespace Spheral { + +// The Data class needs to be CHAICopyable in order to trigger nested copies for Copyable +// members within. +class QIntData : public SPHERALCopyable{ +public: + + SPHERAL_HOST_DEVICE QIntData() = default; + SPHERAL_HOST_DEVICE QIntData(QIntData const& rhs) = default; + SPHERAL_HOST_DEVICE QIntData& operator=(QIntData const& rhs) = default; + + using CoeffsType = ManagedVector; + + double mXmin, mXmax, mXstep; + CoeffsType mcoeffs; + + SPHERAL_HOST void initialize(size_t min) + { + mXmin = min; + mcoeffs.resize(10); + mcoeffs[0] = 0.1; + mcoeffs[1] = 0.2; + mcoeffs[2] = 0.3; + mcoeffs[9] = 0.19; + } + + SPHERAL_HOST void editData(size_t min) + { + mXmin = min; + mcoeffs[9] = 91; + } + + SPHERAL_HOST_DEVICE double xmin() const { return mXmin; } + SPHERAL_HOST_DEVICE double xmax() const { return mXmax; } + SPHERAL_HOST_DEVICE CoeffsType const& coeffs() const { return mcoeffs; } + + // Define the required interface for a SPHERALCopyable object. + void free() { mcoeffs.free(); } + SPHERAL_HOST_DEVICE QIntData& operator=(std::nullptr_t) { mcoeffs=nullptr; return *this; } + SPHERAL_HOST_DEVICE void shallowCopy(QIntData const& rhs) { *this = rhs; } +}; + + +class QInt; + +class QIntView : public SpheralViewInterface +{ + VIEW_INTERFACE_METACLASS((QInt), (QIntView), (QIntData)) +public: + friend class QInt; + using CoeffsType = typename QIntData::CoeffsType; +protected: + //VIEW_DEFINE_ALLOC_CTOR(QIntView) + // Interal interface for accessing the underlying members of QIntData + SMART_PTR_MEMBER_ACCESSOR(CoeffsType, mcoeffs) + +public: + // Forward View capable methods + SPHERAL_HOST_DEVICE double xmin() const { return sptr_data().xmin(); } + SPHERAL_HOST_DEVICE double xmax() const { return sptr_data().xmax(); } + SPHERAL_HOST_DEVICE CoeffsType const& coeffs() const { return sptr_data().coeffs(); } +}; + + + +class QInt : public SpheralValueInterface +{ + VALUE_TYPE_ALIASES((QIntView)) +public: + VALUE_DEF_CTOR(QInt) + //VALUE_COPY_CTOR(QInt, QIntData) + //VALUE_ASSIGNEMT_OP(QInt, QIntData) + VALUE_TOVIEW_OP() + + // Forward Value capable methods + SPHERAL_HOST void initialize(size_t min) const { return sptr_data().initialize(min); } + SPHERAL_HOST void editData(size_t min) const { return sptr_data().editData(min); } + SPHERAL_HOST CoeffsType coeffs() const { return deepCopy(sptr_data().coeffs()); } +}; + +} // namespace Spheral + diff --git a/tests/cpp/Utilities/ValueViewInterface/quadratic_interpolator_example_tests.cc b/tests/cpp/Utilities/ValueViewInterface/quadratic_interpolator_example_tests.cc new file mode 100644 index 000000000..9c8aeb1f1 --- /dev/null +++ b/tests/cpp/Utilities/ValueViewInterface/quadratic_interpolator_example_tests.cc @@ -0,0 +1,55 @@ +#include "test-utilities.hh" +#include "test-basic-exec-policies.hh" + +#include "QInt.hh" + +// Setting up G Test for QuadraticInterpolator +template +class QIntExampleTypedTest : public::testing::Test {}; + +// All QuadraticInterpolatorTets cases will run over each type in EXEC_TYPES. +TYPED_TEST_CASE(QIntExampleTypedTest, EXEC_TYPES); + + +GPU_TYPED_TEST(QIntExampleTypedTest, SmartCopySemantics) +{ + using WORK_EXEC_POLICY = TypeParam; + + Spheral::QInt::CoeffsType c; + { + Spheral::QInt qq_int; + + auto qq_int_v = qq_int.toView(); + auto qq_int_v2 = qq_int_v; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(qq_int_v.xmin(), 0); + SPHERAL_ASSERT_EQ(qq_int_v.coeffs().size(), 0); + EXEC_IN_SPACE_END(); + + qq_int.initialize(4); + SPHERAL_ASSERT_EQ(qq_int_v.coeffs().size(), 10); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + printf("xmin : %lf\n", qq_int_v.xmin()); + SPHERAL_ASSERT_EQ(qq_int_v.xmin(), 4); + SPHERAL_ASSERT_EQ(qq_int_v.coeffs().size(), 10); + SPHERAL_ASSERT_EQ(qq_int_v.coeffs()[9], 0.19); + + EXEC_IN_SPACE_END(); + + qq_int.editData(2); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(qq_int_v.xmin(), 2); + SPHERAL_ASSERT_EQ(qq_int_v.coeffs()[9], 91); + printf("xmin : %lf\n", qq_int_v.xmin()); + printf("coeffs[19] : %lf\n", qq_int_v.coeffs()[9]); + EXEC_IN_SPACE_END(); + + for (auto elem : qq_int.coeffs()) std::cout << elem << std::endl; + c = qq_int.coeffs(); + } + for (auto elem : c) std::cout << elem << std::endl; +} + diff --git a/tests/cpp/Utilities/quadratic_interpolator_tests.cc b/tests/cpp/Utilities/quadratic_interpolator_tests.cc new file mode 100644 index 000000000..e185e1b1d --- /dev/null +++ b/tests/cpp/Utilities/quadratic_interpolator_tests.cc @@ -0,0 +1,107 @@ +#include "test-utilities.hh" +#include "test-basic-exec-policies.hh" + +#include "Utilities/QuadraticInterpolator.hh" + +TEST(QuadraticInterpolatorTest, DefaultConstructor) +{ + Spheral::QuadraticInterpolator q_int; + SPHERAL_ASSERT_EQ(q_int.coeffs().size(), 0); +} + +TEST(QuadraticInterpolatorTest, Initialize) +{ + Spheral::QuadraticInterpolator q_int; + q_int.initialize(0,4,{0,1,2}); + + SPHERAL_ASSERT_EQ(q_int.xmin(), 0); + SPHERAL_ASSERT_EQ(q_int.xmax(), 4); + SPHERAL_ASSERT_EQ(q_int.coeffs().size(), 3); + SPHERAL_ASSERT_EQ(q_int.coeffs()[0], 0); + SPHERAL_ASSERT_EQ(q_int.coeffs()[1], 0.5); + SPHERAL_ASSERT_EQ(q_int.coeffs()[2], 0); +} + +TEST(QuadraticInterpolatorTest, CopySemantics) +{ + Spheral::QuadraticInterpolator q_int; + q_int.initialize(0,4,{0,1,2}); + + Spheral::QuadraticInterpolator q_int2 = q_int; + SPHERAL_ASSERT_EQ(q_int.xmin(), 0); + SPHERAL_ASSERT_EQ(q_int.xmax(), 4); + SPHERAL_ASSERT_EQ(q_int.coeffs().size(), 3); + SPHERAL_ASSERT_EQ(q_int.coeffs()[0], 0); + SPHERAL_ASSERT_EQ(q_int.coeffs()[1], 0.5); + SPHERAL_ASSERT_EQ(q_int.coeffs()[2], 0); + + SPHERAL_ASSERT_EQ(q_int.xmin(), q_int2.xmin()); + SPHERAL_ASSERT_EQ(q_int.xmax(), q_int2.xmax()); + SPHERAL_ASSERT_EQ(q_int.coeffs().size(), q_int2.coeffs().size()); + SPHERAL_ASSERT_EQ(q_int.coeffs()[0], q_int2.coeffs()[0]); + SPHERAL_ASSERT_EQ(q_int.coeffs()[1], q_int2.coeffs()[1]); + SPHERAL_ASSERT_EQ(q_int.coeffs()[2], q_int2.coeffs()[2]); + + SPHERAL_ASSERT_NE(&(q_int.coeffs()[0]), &(q_int2.coeffs()[0])); +} + +TEST(QuadraticInterpolatorTest, AssignmentSemantics) +{ + Spheral::QuadraticInterpolator q_int; + q_int.initialize(0,4,{0,1,2}); + + Spheral::QuadraticInterpolator q_int2;// = q_int; + q_int2 = q_int; + SPHERAL_ASSERT_EQ(q_int.xmin(), 0); + SPHERAL_ASSERT_EQ(q_int.xmax(), 4); + SPHERAL_ASSERT_EQ(q_int.coeffs().size(), 3); + SPHERAL_ASSERT_EQ(q_int.coeffs()[0], 0); + SPHERAL_ASSERT_EQ(q_int.coeffs()[1], 0.5); + SPHERAL_ASSERT_EQ(q_int.coeffs()[2], 0); + + SPHERAL_ASSERT_EQ(q_int.xmin(), q_int2.xmin()); + SPHERAL_ASSERT_EQ(q_int.xmax(), q_int2.xmax()); + SPHERAL_ASSERT_EQ(q_int.coeffs().size(), q_int2.coeffs().size()); + SPHERAL_ASSERT_EQ(q_int.coeffs()[0], q_int2.coeffs()[0]); + SPHERAL_ASSERT_EQ(q_int.coeffs()[1], q_int2.coeffs()[1]); + SPHERAL_ASSERT_EQ(q_int.coeffs()[2], q_int2.coeffs()[2]); + + SPHERAL_ASSERT_NE(&(q_int.coeffs()[0]), &(q_int2.coeffs()[0])); +} + +TEST(QuadraticInterpolatorTest, Equivalence) +{ + Spheral::QuadraticInterpolator q_int; + Spheral::QuadraticInterpolator q_int2; + Spheral::QuadraticInterpolator q_int3; + q_int.initialize(0,4,{0,1,2}); + q_int2.initialize(0,4,{0,1,2}); + q_int3.initialize(0,4,{0,1,3}); + + SPHERAL_ASSERT_TRUE(q_int == q_int2); + SPHERAL_ASSERT_FALSE(q_int == q_int3); +} + +TEST(QuadraticInterpolatorTest, OperatorParen) +{ + Spheral::QuadraticInterpolator q_int; + q_int.initialize(0,4,{0,1,2}); + + SPHERAL_ASSERT_EQ(q_int(1), 0.5); + SPHERAL_ASSERT_EQ(q_int(2), 1); + SPHERAL_ASSERT_EQ(q_int(3), 1.5); + SPHERAL_ASSERT_EQ(q_int(4), 2); + + SPHERAL_ASSERT_EQ(q_int(1, 0), 0.5); + SPHERAL_ASSERT_EQ(q_int(2, 0), 1); + SPHERAL_ASSERT_EQ(q_int(3, 0), 1.5); + SPHERAL_ASSERT_EQ(q_int(4, 0), 2); +} +// Setting up G Test for QuadraticInterpolator +template +class QuadraticInterpolatorTypedTest : public::testing::Test {}; + +// All QuadraticInterpolatorTets cases will run over each type in EXEC_TYPES. +TYPED_TEST_CASE(QuadraticInterpolatorTypedTest, EXEC_TYPES); + +//#include "quadratic_interpolator_view_tests.hh" diff --git a/tests/cpp/Utilities/quadratic_interpolator_view_tests.hh b/tests/cpp/Utilities/quadratic_interpolator_view_tests.hh new file mode 100644 index 000000000..c3c0a2488 --- /dev/null +++ b/tests/cpp/Utilities/quadratic_interpolator_view_tests.hh @@ -0,0 +1,184 @@ +#ifndef __SPHERAL_QUADRATIC_INTERPOLATOR_VIEW_TESTS_HH__ +#define __SPHERAL_QUADRATIC_INTERPOLATOR_VIEW_TESTS_HH__ + +GPU_TYPED_TEST(QuadraticInterpolatorTypedTest, DefaultConstructor) +{ + using WORK_EXEC_POLICY = TypeParam; + Spheral::QuadraticInterpolator q_int; + auto q_int_v = &q_int; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(q_int_v->coeffs().size(), 0); + EXEC_IN_SPACE_END(); +} + +GPU_TYPED_TEST(QuadraticInterpolatorTypedTest, Initialize) +{ + using WORK_EXEC_POLICY = TypeParam; + + Spheral::QuadraticInterpolator q_int; + q_int.initialize(0,4,{0,1,2}); + + auto q_int_v = &q_int; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(q_int_v->xmin(), 0); + SPHERAL_ASSERT_EQ(q_int_v->xmax(), 4); + SPHERAL_ASSERT_EQ(q_int_v->coeffs().size(), 3); + SPHERAL_ASSERT_EQ(q_int_v->coeffs()[0], 0); + SPHERAL_ASSERT_EQ(q_int_v->coeffs()[1], 0.5); + SPHERAL_ASSERT_EQ(q_int_v->coeffs()[2], 0); + EXEC_IN_SPACE_END(); +} + +GPU_TYPED_TEST(QuadraticInterpolatorTypedTest, CopySemantics) +{ + using WORK_EXEC_POLICY = TypeParam; + + Spheral::QuadraticInterpolator::CoeffsType c_copy; + { + Spheral::QuadraticInterpolator q_int; + auto q_int_v = &q_int; + q_int.initialize(0,4,{0,1,2}); + + Spheral::QuadraticInterpolator q_int2 = q_int; + + auto q_int2_v = &q_int2; + auto q_int_v2 = q_int_v; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(q_int_v->xmin(), 0); + SPHERAL_ASSERT_EQ(q_int_v->xmax(), 4); + SPHERAL_ASSERT_EQ(q_int_v->coeffs().size(), 3); + SPHERAL_ASSERT_EQ(q_int_v->coeffs()[0], 0); + SPHERAL_ASSERT_EQ(q_int_v->coeffs()[1], 0.5); + SPHERAL_ASSERT_EQ(q_int_v->coeffs()[2], 0); + + SPHERAL_ASSERT_EQ(q_int_v->xmin(), q_int2_v->xmin()); + SPHERAL_ASSERT_EQ(q_int_v->xmax(), q_int2_v->xmax()); + SPHERAL_ASSERT_EQ(q_int_v->coeffs().size(), q_int2_v->coeffs().size()); + SPHERAL_ASSERT_EQ(q_int_v->coeffs()[0], q_int2_v->coeffs()[0]); + SPHERAL_ASSERT_EQ(q_int_v->coeffs()[1], q_int2_v->coeffs()[1]); + SPHERAL_ASSERT_EQ(q_int_v->coeffs()[2], q_int2_v->coeffs()[2]); + + SPHERAL_ASSERT_NE(&(q_int_v->coeffs()[0]), &(q_int2_v->coeffs()[0])); + SPHERAL_ASSERT_EQ(&(q_int_v->coeffs()[0]), &(q_int_v2->coeffs()[0])); + EXEC_IN_SPACE_END(); + + c_copy = deepCopy(q_int.coeffs()); + } + SPHERAL_ASSERT_EQ(c_copy[0], 0); + SPHERAL_ASSERT_EQ(c_copy[1], 0.5); + SPHERAL_ASSERT_EQ(c_copy[2], 0); + + c_copy.free(); + +} + +GPU_TYPED_TEST(QuadraticInterpolatorTypedTest, Equivalence) +{ + using WORK_EXEC_POLICY = TypeParam; + + Spheral::QuadraticInterpolator q_int; + Spheral::QuadraticInterpolator q_int2; + Spheral::QuadraticInterpolator q_int3; + + auto q_int_v = &q_int; + auto q_int2_v = &q_int2; + auto q_int3_v = &q_int3; + + q_int.initialize(0,4,{0,1,2}); + q_int2.initialize(0,4,{0,1,2}); + q_int3.initialize(0,4,{0,1,3}); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_FALSE(q_int_v == q_int2_v); + SPHERAL_ASSERT_FALSE(q_int_v == q_int3_v); + EXEC_IN_SPACE_END(); +} + +GPU_TYPED_TEST(QuadraticInterpolatorTypedTest, OperatorParen) +{ + using WORK_EXEC_POLICY = TypeParam; + + Spheral::QuadraticInterpolator q_int; + auto q_int_v = &q_int; + + q_int.initialize(0,4,{0,1,2}); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + auto& q = *q_int_v; + SPHERAL_ASSERT_EQ(q(1), 0.5); + SPHERAL_ASSERT_EQ(q(2), 1); + SPHERAL_ASSERT_EQ(q(3), 1.5); + SPHERAL_ASSERT_EQ(q(4), 2); + + SPHERAL_ASSERT_EQ(q(1, 0), 0.5); + SPHERAL_ASSERT_EQ(q(2, 0), 1); + SPHERAL_ASSERT_EQ(q(3, 0), 1.5); + SPHERAL_ASSERT_EQ(q(4, 0), 2); + EXEC_IN_SPACE_END(); +} + +GPU_TYPED_TEST(QuadraticInterpolatorTypedTest, Prime) +{ + using WORK_EXEC_POLICY = TypeParam; + + Spheral::QuadraticInterpolator q_int; + auto q_int_v = &q_int; + + q_int.initialize(0,4,{0,1,2}); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(q_int_v->prime(1), 0.5); + SPHERAL_ASSERT_EQ(q_int_v->prime(2), 0.5); + SPHERAL_ASSERT_EQ(q_int_v->prime(3), 0.5); + SPHERAL_ASSERT_EQ(q_int_v->prime(4), 0.5); + + SPHERAL_ASSERT_EQ(q_int_v->prime(1, 0), 0.5); + SPHERAL_ASSERT_EQ(q_int_v->prime(2, 0), 0.5); + SPHERAL_ASSERT_EQ(q_int_v->prime(3, 0), 0.5); + SPHERAL_ASSERT_EQ(q_int_v->prime(4, 0), 0.5); + EXEC_IN_SPACE_END(); +} + +GPU_TYPED_TEST(QuadraticInterpolatorTypedTest, Prime2) +{ + using WORK_EXEC_POLICY = TypeParam; + + Spheral::QuadraticInterpolator q_int; + auto q_int_v = &q_int; + + q_int.initialize(0,4,{0,1,2}); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(q_int_v->prime2(1), 0); + SPHERAL_ASSERT_EQ(q_int_v->prime2(2), 0); + SPHERAL_ASSERT_EQ(q_int_v->prime2(3), 0); + SPHERAL_ASSERT_EQ(q_int_v->prime2(4), 0); + + SPHERAL_ASSERT_EQ(q_int_v->prime2(1, 0), 0); + SPHERAL_ASSERT_EQ(q_int_v->prime2(2, 0), 0); + SPHERAL_ASSERT_EQ(q_int_v->prime2(3, 0), 0); + SPHERAL_ASSERT_EQ(q_int_v->prime2(4, 0), 0); + EXEC_IN_SPACE_END(); +} + +GPU_TYPED_TEST(QuadraticInterpolatorTypedTest, LowerBound) +{ + using WORK_EXEC_POLICY = TypeParam; + + Spheral::QuadraticInterpolator q_int; + auto q_int_v = &q_int; + + q_int.initialize(0,4,{0,1,2}); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(q_int_v->lowerBound(1), 0); + SPHERAL_ASSERT_EQ(q_int_v->lowerBound(2), 0); + SPHERAL_ASSERT_EQ(q_int_v->lowerBound(3), 0); + SPHERAL_ASSERT_EQ(q_int_v->lowerBound(4), 0); + EXEC_IN_SPACE_END(); +} + +#endif // __SPHERAL_QUADRATIC_INTERPOLATOR_VIEW_TESTS_HH__ diff --git a/tests/cpp/include/test-basic-exec-policies.hh b/tests/cpp/include/test-basic-exec-policies.hh new file mode 100644 index 000000000..887b9f6ed --- /dev/null +++ b/tests/cpp/include/test-basic-exec-policies.hh @@ -0,0 +1,16 @@ +#ifndef SPHERAL_BASIC_EXEC_POL_HH +#define SPHERAL_BASIC_EXEC_POL_HH + +#include "RAJA/RAJA.hpp" + +using SEQ_EXEC_POLICY = RAJA::seq_exec; +// The list of execution types we want to possibly run these tests over. +using EXEC_TYPES = ::testing::Types< + SEQ_EXEC_POLICY +#ifdef SPHERAL_ENABLE_CUDA + ,RAJA::cuda_exec<512> +#endif +>; + + +#endif // SPHERAL_BASIC_EXEC_POL_HH diff --git a/tests/cpp/include/test-utilities.hh b/tests/cpp/include/test-utilities.hh new file mode 100644 index 000000000..bce661437 --- /dev/null +++ b/tests/cpp/include/test-utilities.hh @@ -0,0 +1,89 @@ +#ifndef SPHERAL_TEST_UTIILITIES_HH +#define SPHERAL_TEST_UTIILITIES_HH + + +#include "gtest/gtest.h" +#include "assert.h" +#include "RAJA/RAJA.hpp" +#include "config.hh" + +using TRS_UINT = RAJA::TypedRangeSegment; +using LOOP_EXEC_POLICY = RAJA::seq_exec; + +#define EXEC_IN_SPACE_BEGIN(POL) \ + RAJA::forall(TRS_UINT(0,1), [=] SPHERAL_HOST_DEVICE (int) { + +#define EXEC_IN_SPACE_END() \ + }); + + +template +inline +SPHERAL_HOST_DEVICE +void SPHERAL_ASSERT_EQ(T const& LHS, U const& RHS) { +#if !defined(SPHERAL_GPU_ACTIVE) + ASSERT_EQ(LHS, RHS); +#else + if (LHS != RHS) { + printf("ERROR @ cuda_assert\n"); + assert(0); + } +#endif +} + +template +SPHERAL_HOST_DEVICE +void SPHERAL_ASSERT_NE(T const& LHS, U const& RHS) { +#if !defined(SPHERAL_GPU_ACTIVE) + ASSERT_NE(LHS, RHS); +#else + if (LHS == RHS) { + printf("ERROR @ cuda_assert\n"); + assert(0); + } +#endif +} + +SPHERAL_HOST_DEVICE +void SPHERAL_ASSERT_TRUE(bool result) { +#if !defined(SPHERAL_GPU_ACTIVE) + ASSERT_TRUE(result); +#else + if (!result) { + printf("ERROR @ cuda_assert\n"); + assert(0); + } +#endif +} + +SPHERAL_HOST_DEVICE +void SPHERAL_ASSERT_FALSE(bool result) { +#if !defined(SPHERAL_GPU_ACTIVE) + ASSERT_FALSE(result); +#else + if (result) { + printf("ERROR @ cuda_assert\n"); + assert(0); + } +#endif +} + + +// Macro used throughout LLNLProjects to get around calling +// HOST_DEVICE lambdas from within the "Testing" class directly +#define GPU_TYPED_TEST(X, Y) \ + template \ + static void gpu_test_##X##Y(); \ + TYPED_TEST(X, Y) { gpu_test_##X##Y(); } \ + template \ + static void gpu_test_##X##Y() + +#define GPU_TYPED_TEST_P(X, Y) \ + template \ + static void gpu_test_##X##Y(TestFixture* gpu_this); \ + TYPED_TEST_P(X, Y) { gpu_test_##X##Y(this); } \ + template \ + static void gpu_test_##X##Y(TestFixture* gpu_this) + + +#endif // SPHERAL_TEST_UTIILITIES_HH From 8451ecfe195c751092dd74a0469455ab94b4be9c Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 22 Jul 2024 18:02:35 -0700 Subject: [PATCH 02/44] Deleting ManagedSmartPtr and MVSmartRef classes and tests. They will not be used in prod. --- src/Field/SphArray.hh | 359 ------------------------ tests/cpp/Field/managed_vector_tests.cc | 63 ----- 2 files changed, 422 deletions(-) diff --git a/src/Field/SphArray.hh b/src/Field/SphArray.hh index 1e722234d..84342e939 100644 --- a/src/Field/SphArray.hh +++ b/src/Field/SphArray.hh @@ -327,365 +327,6 @@ ManagedVector deepCopy(ManagedVector const& array) return copy; } -template -class ManagedSmartPtr; - -template -ManagedSmartPtr deepCopy(ManagedSmartPtr const& rhs); - -template -ManagedSmartPtr make_ManagedSmartPtr(T* host_ptr); - -template -ManagedSmartPtr make_ManagedSmartPtr(Args... args); - -template -class ManagedSmartPtr : public chai::CHAICopyable -{ -public: - using element_type = T; -struct PrivateConstruct {}; - - SPHERAL_HOST_DEVICE ManagedSmartPtr() { -#if !defined(SPHERAL_GPU_ACTIVE) - //m_ref_count = new size_t(0); -#endif // SPHERAL_GPU_ACTIVE - } - - template - SPHERAL_HOST ManagedSmartPtr(PrivateConstruct, Args... args) { -#if !defined(SPHERAL_GPU_ACTIVE) - m_ptr = chai::ManagedArray(); - m_ptr.allocate(1, chai::CPU, getCallback()); - m_ptr[0] = T(args...); - m_ptr.registerTouch(chai::CPU); - m_ref_count = new size_t(1); - -#endif // SPHERAL_GPU_ACTIVE - } - - SPHERAL_HOST ManagedSmartPtr(PrivateConstruct, T* host_ptr) { -#if !defined(SPHERAL_GPU_ACTIVE) - m_ptr = chai::makeManagedArray(host_ptr, 1, chai::CPU, true); - m_ptr.setUserCallback(getCallback()); - m_ptr.registerTouch(chai::CPU); - m_ref_count = new size_t(1); -#endif // SPHERAL_GPU_ACTIVE - } - - -public: - SPHERAL_HOST void registerTouch(chai::ExecutionSpace space) { m_ptr.registerTouch(space); } - - SPHERAL_HOST_DEVICE ManagedSmartPtr& operator=(ManagedSmartPtr const& rhs) { - if (this != &rhs) { - if (m_ptr != rhs.m_ptr) discontinue_ownership(); - m_ptr = rhs.m_ptr; - m_ref_count = rhs.m_ref_count; - increment_ref_count(); - } - return *this; - } - - SPHERAL_HOST_DEVICE ManagedSmartPtr(ManagedSmartPtr const& rhs) : m_ptr(rhs.m_ptr), m_ref_count(rhs.m_ref_count) { - increment_ref_count(); - } - - SPHERAL_HOST void move(chai::ExecutionSpace space, bool touch = true) const { - m_ptr[0].move(space, touch); - } - - SPHERAL_HOST_DEVICE T* get() const { return (m_ref_count) ? (m_ptr.data()) : nullptr; } - SPHERAL_HOST_DEVICE T* operator->() { return get(); } - SPHERAL_HOST_DEVICE T* operator->() const { return get(); } - SPHERAL_HOST_DEVICE T& operator*() { return *get(); } - SPHERAL_HOST_DEVICE T& operator*() const { return *get(); } - - SPHERAL_HOST_DEVICE ~ManagedSmartPtr() { - discontinue_ownership(); - } - - SPHERAL_HOST_DEVICE ManagedSmartPtr& operator=(std::nullptr_t) { m_ref_count=nullptr; m_ptr=nullptr; return *this; } - SPHERAL_HOST_DEVICE void shallowCopy(ManagedSmartPtr const& rhs) { - *this = rhs; - } - - template< typename U=ManagedSmartPtr< T > > - SPHERAL_HOST - auto getCallback() { -//#ifdef SPHERAL_CALLBACK_ENABLED -// std::string const typeString = LvArray::system::demangleType< U >(); -// return [typeString] (const chai::PointerRecord* record, chai::Action action, chai::ExecutionSpace exec) { -// std::string const size = LvArray::system::calculateSize(record->m_size); -// std::string const paddedSize = std::string( 9 - size.size(), ' ' ) + size; -// char const * const spaceStr = ( exec == chai::CPU ) ? "HOST " : "DEVICE"; -// -// if (action == chai::Action::ACTION_MOVE){ -// SPHERAL_LOG(Info, "Moved " << paddedSize << " to the " << spaceStr << ": " << typeString << " @ " << record->m_pointers[exec] ) -// } -// if (action == chai::Action::ACTION_ALLOC){ -// SPHERAL_LOG(Info, "Allocated on " << spaceStr << " " << paddedSize << " : " << typeString << " @ " << record->m_pointers[exec] ) -// } -// if (action == chai::Action::ACTION_FREE){ -// SPHERAL_LOG(Info, "Deallocated " << paddedSize << " : " << typeString << " @ " << record->m_pointers[exec] ) -// } -// }; -//#else - return [](const chai::PointerRecord* , chai::Action , chai::ExecutionSpace ) {}; -//#endif - } -protected: - - SPHERAL_HOST_DEVICE void increment_ref_count() { -#if !defined(SPHERAL_GPU_ACTIVE) - if (m_ref_count != nullptr) (*m_ref_count)++; -#endif // SPHERAL_GPU_ACTIVE - } - - SPHERAL_HOST_DEVICE void discontinue_ownership() { -#if !defined(SPHERAL_GPU_ACTIVE) - if (m_ref_count != nullptr){ - (*m_ref_count)--; - if (*m_ref_count == 0) - { - m_ptr[0].free(); - m_ptr.free(); - delete m_ref_count; - m_ref_count = nullptr; - } - } -#endif // SPHERAL_GPU_ACTIVE - } - - - SPHERAL_HOST_DEVICE - friend bool compare(ManagedSmartPtr const& lhs, ManagedSmartPtr const& rhs) - { - // TODO : not safe - return compare(lhs.m_ptr[0], rhs.m_ptr[0]); - } - - chai::ManagedArray m_ptr; - size_t* m_ref_count = nullptr; - - template - friend ManagedSmartPtr deepCopy(ManagedSmartPtr const& rhs); - - template - friend ManagedSmartPtr make_ManagedSmartPtr(U* host_ptr); - - template - friend ManagedSmartPtr make_ManagedSmartPtr(Args... args); - -}; - - -template -ManagedSmartPtr make_ManagedSmartPtr(U* host_ptr) - { - ManagedSmartPtr ptr = ManagedSmartPtr(typename ManagedSmartPtr::PrivateConstruct(), host_ptr); - return ptr; - } - -template -ManagedSmartPtr make_ManagedSmartPtr(Args... args) - { - ManagedSmartPtr ptr = ManagedSmartPtr(typename ManagedSmartPtr::PrivateConstruct(), args...); - return ptr; - } - -template -ManagedSmartPtr deepCopy(ManagedSmartPtr const& rhs) -{ - // TODO : not safe - ManagedSmartPtr ptr = make_ManagedSmartPtr(deepCopy(*rhs)); - return ptr; - //return ManagedSmartPtr(typename ManagedSmartPtr::PrivateConstruct(), deepCopy(*rhs)); -} - - -template -class MVSmartRef : public ManagedSmartPtr> -{ - using Base = ManagedSmartPtr>; - SPHERAL_HOST_DEVICE ManagedVector & mv() { return Base::m_ptr[0]; } - SPHERAL_HOST_DEVICE ManagedVector const& mv() const { return Base::m_ptr[0]; } - -public: - - using Base::operator->; - using Base::operator*; - using Base::get; - using Base::move; - - using MV = Spheral::ManagedVector; - - SPHERAL_HOST_DEVICE MVSmartRef() = default; - - template - MVSmartRef(Args... args) : Base(make_ManagedSmartPtr(args...)) {mv().setCallback();} - - using iterator = typename MV::iterator; - using const_iterator = typename MV::const_iterator; - - iterator begin() { return mv().begin(); } - const_iterator begin() const { return mv().begin(); } - - iterator end() { return begin() + size(); } - const_iterator end() const { return begin() + size(); } - - SPHERAL_HOST_DEVICE T& operator[](size_t idx) {return mv()[idx]; } - SPHERAL_HOST_DEVICE T& operator[](size_t idx) const {return mv()[idx]; } - - SPHERAL_HOST_DEVICE size_t size() const { return mv().size(); } - - SPHERAL_HOST void resize(size_t sz) { - move(chai::CPU); - mv().resize(sz); - Base::m_ptr.registerTouch(chai::CPU); - } - - SPHERAL_HOST - void insert(iterator pos, T const& value) { - move(chai::CPU); - mv().insert(pos, value); - Base::m_ptr.registerTouch(chai::CPU); - } - - SPHERAL_HOST void push_back(T const& value) { - move(chai::CPU); - mv().push_back(value); - Base::m_ptr.registerTouch(chai::CPU); - } - - SPHERAL_HOST void push_back(T&& value) { - move(chai::CPU); - mv().push_back(value); - Base::m_ptr.registerTouch(chai::CPU); - } - - SPHERAL_HOST - void reserve(size_t c) { - move(chai::CPU); - mv().reserve(c); - Base::m_ptr.registerTouch(chai::CPU); - } - - SPHERAL_HOST - void clear() { - move(chai::CPU); - mv().clear(); - Base::m_ptr.registerTouch(chai::CPU); - } - - SPHERAL_HOST - void erase(iterator pos) { - move(chai::CPU); - mv().erase(pos); - Base::m_ptr.registerTouch(chai::CPU); - } - - SPHERAL_HOST_DEVICE MVSmartRef& operator=(std::nullptr_t) { Base::operator=(nullptr); return *this; } - SPHERAL_HOST_DEVICE void shallowCopy(MVSmartRef const& rhs) { - Base::shallowCopy(rhs); - } - - SPHERAL_HOST_DEVICE bool operator==(MVSmartRef const& rhs) const { return (mv() == rhs.mv()); } - SPHERAL_HOST_DEVICE bool operator!=(MVSmartRef const& rhs) const { return (mv() != rhs.mv()); } - -private: - - friend MVSmartRef deepCopy(MVSmartRef const& rhs) - { - // TODO : not safe - return MVSmartRef(deepCopy(rhs.m_ptr[0])); - } - - SPHERAL_HOST_DEVICE - friend bool compare(MVSmartRef const& lhs, MVSmartRef const& rhs) - { - // TODO : not safe - return compare(lhs.mv(), rhs.mv()); - } -}; - - - - -//template -//using SphArray = LvArray::Array, std::ptrdiff_t, LvArray::ChaiBuffer>; -// -//template -//using SphArrayView = LvArray::ArrayView; - -//template -//class SphArrayIterator { -//public: -// using iterator_category = std::random_access_iterator_tag; -// using value_type = typename sph_array_t::ValueType; -// using difference_type = std::ptrdiff_t; -// using pointer = value_type*; -// using reference = value_type&; -// -// SphArrayIterator(pointer ptr); -// -// SphArrayIterator& operator++(); -// SphArrayIterator operator++(int); -// -// SphArrayIterator& operator--(); -// SphArrayIterator operator--(int); -// -// SphArrayIterator operator+(const difference_type& index) const; -// SphArrayIterator operator-(const difference_type& index) const; -// -// difference_type operator-(const SphArrayIterator& it); -// -// reference operator[](int index); -// pointer operator->(); -// -// reference operator*() const; -// -// bool operator==(const SphArrayIterator& rhs) const; -// bool operator!=(const SphArrayIterator& rhs) const; -// bool operator<(const SphArrayIterator& rhs) const; -// bool operator<=(const SphArrayIterator& rhs) const; -// bool operator>(const SphArrayIterator& rhs) const; -// bool operator>=(const SphArrayIterator& rhs) const; -// -// operator SphArrayIterator() const; -// -//private: -// pointer mPtr; -//}; -// -//template -//class SphArrayFieldIterator { -//public: -// using iterator_category = std::input_iterator_tag; -// using value_type = typename sph_array_t::ValueType; -// using difference_type = std::ptrdiff_t; -// using pointer = value_type*; -// using reference = value_type&; -// -// using field_type = typename value_type::FieldType; -// using field_pointer = field_type*; -// using field_reference = field_type&; -// -// SphArrayFieldIterator(pointer ptr); -// -// field_reference operator*() const; -// field_pointer operator->(); -// -// SphArrayFieldIterator& operator++(); -// SphArrayFieldIterator operator++(int); -// -// bool operator==(const SphArrayFieldIterator& rhs) const; -// -//private: -// pointer mPtr; -//}; - - } // namespace Spheral //#include "SphArrayInline.hh" diff --git a/tests/cpp/Field/managed_vector_tests.cc b/tests/cpp/Field/managed_vector_tests.cc index baffd1d45..a65866244 100644 --- a/tests/cpp/Field/managed_vector_tests.cc +++ b/tests/cpp/Field/managed_vector_tests.cc @@ -83,69 +83,6 @@ GPU_TYPED_TEST(ManagedVectorTypedTest, IdentityConstructor) } -GPU_TYPED_TEST(ManagedVectorTypedTest, ManagedPtrArrayTest) -{ - using WORK_EXEC_POLICY = TypeParam; - - //Spheral::MVSmartRef array = Spheral::make_MVSmartRef(5, chai::CPU); - Spheral::MVSmartRef array; - //array = Spheral::make_MVSmartRef(5, chai::CPU); - array = Spheral::MVSmartRef(5, chai::CPU); - - Spheral::MVSmartRef copy_array(array); - - SPHERAL_ASSERT_EQ(array->size(), copy_array->size()); - - std::cout << "check0\n"; - RAJA::forall(TRS_UINT(0,array->size()), - [=] RAJA_HOST_DEVICE (unsigned i){ - array[i] = i*2; - Spheral::MVSmartRef copy_array_2 = array; - SPHERAL_ASSERT_EQ(copy_array_2[i], i*2); - } - ); - - - std::cout << "resize\n"; - array.resize(20); - - - std::cout << "check1\n"; - std::cout << copy_array->size(); - RAJA::forall(TRS_UINT(0,array->size()), - [=] RAJA_HOST_DEVICE (unsigned i){ - if (i >= 5) copy_array[i] = i*3; - //SPHERAL_ASSERT_TRUE (copy_array->size() == 20); - } - ); - - std::cout << "check1.5\n"; - RAJA::forall(TRS_UINT(0,array->size()), - [=] RAJA_HOST (unsigned i){ - if (i < 5) SPHERAL_ASSERT_EQ(copy_array[i], i*2); - else SPHERAL_ASSERT_EQ(copy_array[i], i*3); - } - ); - - std::cout << "check2\n"; - SPHERAL_ASSERT_EQ(&array[15], ©_array[15]); - SPHERAL_ASSERT_EQ(array->size(), copy_array->size()); - - Spheral::MVSmartRef deep_copy_array = deepCopy(array); - //Spheral::MVSmartRef deep_copy_array = Spheral::make_MVSmartRef(deepCopy(*array.get())); - SPHERAL_ASSERT_EQ(array->size(), deep_copy_array->size()); - - RAJA::forall(TRS_UINT(0,array->size()), - [=] RAJA_HOST (unsigned i){ - SPHERAL_ASSERT_EQ(deep_copy_array[i], array[i]); - } - ); - - deep_copy_array[5] = 1234; - SPHERAL_ASSERT_NE(deep_copy_array[5], array[5]); - SPHERAL_ASSERT_NE(&deep_copy_array[0], &array[0]); -} - GPU_TYPED_TEST(ManagedVectorTypedTest, CopyConstructor) { using WORK_EXEC_POLICY = TypeParam; From d12c6872af0f72bc10829bef4b730b1cab94ea3b Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 22 Jul 2024 18:03:24 -0700 Subject: [PATCH 03/44] Adding testTRTField python test used during constexpr PYB11 development. This might be useful again. --- tests/unit/Field/testTRTField.py | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/unit/Field/testTRTField.py diff --git a/tests/unit/Field/testTRTField.py b/tests/unit/Field/testTRTField.py new file mode 100644 index 000000000..19243d288 --- /dev/null +++ b/tests/unit/Field/testTRTField.py @@ -0,0 +1,38 @@ +from Spheral import * + +import os +import unittest + +def main(): + WT1d = TableKernel1d(BSplineKernel1d(), 100) + eos1d = GammaLawGasMKS1d(2.0, 2.0) + nodes1d = makeFluidNodeList1d("nodes1d", eos1d) + nodes1d.numInternalNodes = 10 + + print(ThirdRankTensor1d.nDimensions) + print(FourthRankTensor1d.nDimensions) + print(FifthRankTensor1d.nDimensions) + + #x0 = vector_of_int(range(10)) + ##v0 = VectorIntField1d("vector field", nodes1d, x0) + #v0 = ThirdRankTensorField1d("third rank tensor field 1d control", nodes1d) + + #print(len(v0)) + + #print(v0[0].nDimensions) + #print(v0[1]) + #print(v0[2]) + #print(v0[3]) + + #for i in range(3,nodes1d.numInternalNodes): + # print(v0[i]) + + + + +#------------------------------------------------------------------------------- +# Run those tests. +#------------------------------------------------------------------------------- +if __name__ == "__main__": + main() + #unittest.main() From 01598a9b57af0a6ddb4b50ae4fcd2ac75d84b977 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 22 Jul 2024 18:07:16 -0700 Subject: [PATCH 04/44] Deleting SphArrayInline/Inst. We are not using the old iterator class; Moving SphArray.hh to Utilities/ManagedVector.hh --- src/Field/SphArrayInline.hh | 149 ------------------ src/Field/SphArrayInst.cc.py | 32 ---- .../ManagedVector.hh} | 0 3 files changed, 181 deletions(-) delete mode 100644 src/Field/SphArrayInline.hh delete mode 100644 src/Field/SphArrayInst.cc.py rename src/{Field/SphArray.hh => Utilities/ManagedVector.hh} (100%) diff --git a/src/Field/SphArrayInline.hh b/src/Field/SphArrayInline.hh deleted file mode 100644 index 56cb79033..000000000 --- a/src/Field/SphArrayInline.hh +++ /dev/null @@ -1,149 +0,0 @@ -namespace Spheral { - -template -inline -SphArrayIterator:: -SphArrayIterator(pointer ptr) - : mPtr(ptr) {} - -template -inline -SphArrayIterator& -SphArrayIterator:: -operator++() { mPtr++; return *this; } - -template -inline -SphArrayIterator -SphArrayIterator:: -operator++(int) { SphArrayIterator it = *this; operator++(); return it; } - -template -inline -SphArrayIterator& -SphArrayIterator:: -operator--() { mPtr--; return *this; } - -template -inline -SphArrayIterator -SphArrayIterator:: -operator--(int) { SphArrayIterator it = *this; operator--(); return it; } - -template -inline -SphArrayIterator -SphArrayIterator:: -operator+(const difference_type& index) const { SphArrayIterator it = *this; it.mPtr += index; return it; } - -template -inline -SphArrayIterator -SphArrayIterator:: -operator-(const difference_type& index) const { SphArrayIterator it = *this; it.mPtr -= index; return it; } - -template -inline -typename SphArrayIterator::difference_type -SphArrayIterator:: -operator-(const SphArrayIterator& it){ return std::distance(it.mPtr,mPtr); } - -template -inline -typename SphArrayIterator::reference -SphArrayIterator:: -operator[](int index){ return *(mPtr+index); } - -template -inline -typename SphArrayIterator::pointer -SphArrayIterator:: -operator->(){ return mPtr; } - -template -inline -typename SphArrayIterator::reference -SphArrayIterator:: -operator*() const { return *mPtr; } - -template -inline -bool -SphArrayIterator:: -operator==(const SphArrayIterator& rhs) const { return mPtr == rhs.mPtr; } - -template -inline -bool -SphArrayIterator:: -operator!=(const SphArrayIterator& rhs) const { return !(*this == rhs); } - -template -inline -bool -SphArrayIterator:: -operator<(const SphArrayIterator& rhs) const {return mPtr < rhs.mPtr; } - -template -inline -bool -SphArrayIterator:: -operator<=(const SphArrayIterator& rhs) const {return operator<(rhs) || operator==(rhs); } - -template -inline -bool -SphArrayIterator:: -operator>(const SphArrayIterator& rhs) const {return !(operator<(rhs) || operator==(rhs)); } - -template -inline -bool -SphArrayIterator:: -operator>=(const SphArrayIterator& rhs) const {return !operator<(rhs); } - -template -SphArrayIterator:: -operator SphArrayIterator() const {return SphArrayIterator(mPtr); } - -//------------------------- - -template -inline -SphArrayFieldIterator:: -SphArrayFieldIterator(pointer ptr) - : mPtr(ptr) {} - -template -inline -typename SphArrayFieldIterator::field_reference -SphArrayFieldIterator:: -operator*() const { return *(*mPtr); } - -template -inline -typename SphArrayFieldIterator::field_pointer -SphArrayFieldIterator:: -operator->(){ return (*mPtr).operator->(); } - -template -inline -SphArrayFieldIterator& -SphArrayFieldIterator:: -operator++() { mPtr++; return *this; } - -template -inline -SphArrayFieldIterator -SphArrayFieldIterator:: -operator++(int) { SphArrayFieldIterator it = *this; operator++(); return it; } - -template -inline -bool -SphArrayFieldIterator:: -operator==(const SphArrayFieldIterator& rhs) const { return mPtr == rhs.mPtr; } - - - -} // namespace Spheral diff --git a/src/Field/SphArrayInst.cc.py b/src/Field/SphArrayInst.cc.py deleted file mode 100644 index b9d7a209c..000000000 --- a/src/Field/SphArrayInst.cc.py +++ /dev/null @@ -1,32 +0,0 @@ -text = """ -//------------------------------------------------------------------------------ -// Explicit instantiation. -//------------------------------------------------------------------------------ -#include "Field/SphArray.hh" -#include "Geometry/Dimension.hh" - -namespace Spheral { -""" - -for DT in ("Dim< %(ndim)s >::Scalar", - "Dim< %(ndim)s >::Vector", - "Dim< %(ndim)s >::Tensor", - "Dim< %(ndim)s >::SymTensor"): - text += """ -template class SphArrayIterator< SphArray< %(DT)s > >; -template class SphArrayIterator< SphArrayView< %(DT)s > >; -""" % {"DT" : DT} - -#for FV in ("FieldView< Dim< %(ndim)s >, Dim< %(ndim)s >::Scalar >", -# "FieldView< Dim< %(ndim)s >, Dim< %(ndim)s >::Vector >", -# "FieldView< Dim< %(ndim)s >, Dim< %(ndim)s >::Tensor >", -# "FieldView< Dim< %(ndim)s >, Dim< %(ndim)s >::SymTensor >"): -# text += """ -#template class SphArrayFieldIterator< SphArray< %(FV)s > >; -#template class SphArrayFieldIterator< SphArrayView< %(FV)s > >; -#""" % {"FV" : FV} - -text += """ -} -""" - diff --git a/src/Field/SphArray.hh b/src/Utilities/ManagedVector.hh similarity index 100% rename from src/Field/SphArray.hh rename to src/Utilities/ManagedVector.hh From ee4a68ce32bacad4cc05ecd393af20721b69645b Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 22 Jul 2024 18:12:20 -0700 Subject: [PATCH 05/44] Changing header includes SphArray -> ManagedVector.hh --- tests/cpp/Field/field_parallel_inheritance_tests.cc | 2 +- tests/cpp/Field/managed_vector_tests.cc | 2 +- tests/cpp/Kernel/kernel_parallel_inheritance_tests.cc | 2 +- tests/cpp/Utilities/ValueViewInterface/QInt.hh | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/cpp/Field/field_parallel_inheritance_tests.cc b/tests/cpp/Field/field_parallel_inheritance_tests.cc index 9a50bc003..2d0dd94e0 100644 --- a/tests/cpp/Field/field_parallel_inheritance_tests.cc +++ b/tests/cpp/Field/field_parallel_inheritance_tests.cc @@ -2,8 +2,8 @@ #include "test-basic-exec-policies.hh" -#include "Field/SphArray.hh" #include "Utilities/ValueViewInterface.hh" +#include "Utilities/ManagedVector.hh" #include namespace Spheral { diff --git a/tests/cpp/Field/managed_vector_tests.cc b/tests/cpp/Field/managed_vector_tests.cc index a65866244..03c28717a 100644 --- a/tests/cpp/Field/managed_vector_tests.cc +++ b/tests/cpp/Field/managed_vector_tests.cc @@ -1,7 +1,7 @@ #include "test-utilities.hh" #include "test-basic-exec-policies.hh" -#include "Field/SphArray.hh" +#include "Utilities/ManagedVector.hh" #include "chai/managed_ptr.hpp" using MVDouble = Spheral::ManagedVector; diff --git a/tests/cpp/Kernel/kernel_parallel_inheritance_tests.cc b/tests/cpp/Kernel/kernel_parallel_inheritance_tests.cc index c42cdd77c..5e2f5c38e 100644 --- a/tests/cpp/Kernel/kernel_parallel_inheritance_tests.cc +++ b/tests/cpp/Kernel/kernel_parallel_inheritance_tests.cc @@ -1,8 +1,8 @@ #include "test-utilities.hh" #include "test-basic-exec-policies.hh" -#include "Field/SphArray.hh" #include "Utilities/ValueViewInterface.hh" +#include "Utilities/ManagedVector.hh" //-------------------------------- // Impl Interface diff --git a/tests/cpp/Utilities/ValueViewInterface/QInt.hh b/tests/cpp/Utilities/ValueViewInterface/QInt.hh index f00668ba7..8571ec5a0 100644 --- a/tests/cpp/Utilities/ValueViewInterface/QInt.hh +++ b/tests/cpp/Utilities/ValueViewInterface/QInt.hh @@ -3,6 +3,7 @@ //----------------------------------------------------------------------------- #include "Utilities/ValueViewInterface.hh" +#include "Utilities/ManagedVector.hh" namespace Spheral { From c800c082c2d3cba93968579b78e65a2257d3595c Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 22 Jul 2024 18:19:11 -0700 Subject: [PATCH 06/44] Re-organizing test locations, many tests are basic integration/example test for the new interface pattern. --- src/Utilities/ValueViewInterface.hh | 1 - tests/cpp/Field/CMakeLists.txt | 10 --- tests/cpp/Kernel/CMakeLists.txt | 4 - tests/cpp/Utilities/CMakeLists.txt | 6 ++ .../ValueViewInterface/CMakeLists.txt | 15 ++-- .../ManagedSharedPtrTests.cc | 88 ------------------- .../field_parallel_inheritance_tests.cc | 0 .../kernel_parallel_inheritance_tests.cc | 0 .../managed_vector_tests.cc | 0 9 files changed, 15 insertions(+), 109 deletions(-) delete mode 100644 tests/cpp/Utilities/ValueViewInterface/ManagedSharedPtrTests.cc rename tests/cpp/{Field => Utilities/ValueViewInterface}/field_parallel_inheritance_tests.cc (100%) rename tests/cpp/{Kernel => Utilities/ValueViewInterface}/kernel_parallel_inheritance_tests.cc (100%) rename tests/cpp/{Field => Utilities}/managed_vector_tests.cc (100%) diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh index ae60344f2..023e6e798 100644 --- a/src/Utilities/ValueViewInterface.hh +++ b/src/Utilities/ValueViewInterface.hh @@ -3,7 +3,6 @@ //#include "Utilities/SharedPtr.hh" #include "chai/ManagedSharedPtr.hpp" -#include "Field/SphArray.hh" #include namespace Spheral { diff --git a/tests/cpp/Field/CMakeLists.txt b/tests/cpp/Field/CMakeLists.txt index d80f75095..31d8d2ff0 100644 --- a/tests/cpp/Field/CMakeLists.txt +++ b/tests/cpp/Field/CMakeLists.txt @@ -1,13 +1,3 @@ -spheral_add_test( - NAME managed_vector_tests - SOURCES managed_vector_tests.cc -) - -spheral_add_test( - NAME field_parallel_inheritance_tests - SOURCES field_parallel_inheritance_tests.cc -) - #spheral_add_test( # NAME field_tests # SOURCES field_tests.cc diff --git a/tests/cpp/Kernel/CMakeLists.txt b/tests/cpp/Kernel/CMakeLists.txt index 01b155a82..e69de29bb 100644 --- a/tests/cpp/Kernel/CMakeLists.txt +++ b/tests/cpp/Kernel/CMakeLists.txt @@ -1,4 +0,0 @@ -spheral_add_test( - NAME kernel_parallel_inheritance_tests - SOURCES kernel_parallel_inheritance_tests.cc -) diff --git a/tests/cpp/Utilities/CMakeLists.txt b/tests/cpp/Utilities/CMakeLists.txt index 885aed776..73e848e1a 100644 --- a/tests/cpp/Utilities/CMakeLists.txt +++ b/tests/cpp/Utilities/CMakeLists.txt @@ -5,6 +5,12 @@ spheral_add_test( DEBUG_LINKER ) +spheral_add_test( + NAME managed_vector_tests + SOURCES managed_vector_tests.cc +) + + add_subdirectory(ValueViewInterface) diff --git a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt index 62d62d5e9..a95a7bb59 100644 --- a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt +++ b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt @@ -1,12 +1,15 @@ spheral_add_test( - NAME quadratic_interpolator_example_tests - SOURCES quadratic_interpolator_example_tests.cc - #DEBUG_LINKER + NAME kernel_parallel_inheritance_tests + SOURCES kernel_parallel_inheritance_tests.cc +) + +spheral_add_test( + NAME field_parallel_inheritance_tests + SOURCES field_parallel_inheritance_tests.cc ) spheral_add_test( - NAME shared_ptr_tests - SOURCES ManagedSharedPtrTests.cc - #SOURCES shared_ptr_tests.cc + NAME quadratic_interpolator_example_tests + SOURCES quadratic_interpolator_example_tests.cc #DEBUG_LINKER ) diff --git a/tests/cpp/Utilities/ValueViewInterface/ManagedSharedPtrTests.cc b/tests/cpp/Utilities/ValueViewInterface/ManagedSharedPtrTests.cc deleted file mode 100644 index 1cf1b2732..000000000 --- a/tests/cpp/Utilities/ValueViewInterface/ManagedSharedPtrTests.cc +++ /dev/null @@ -1,88 +0,0 @@ -#include "test-utilities.hh" -#include "test-basic-exec-policies.hh" - -#include -#include - -//#include "Utilities/SharedPtr.hh" -#include "chai/ManagedSharedPtr.hpp" - -template -using shared_ptr_t = chai::ManagedSharedPtr; - - -class Base { -public: - SPHERAL_HOST_DEVICE Base() {printf("CTor Base\n");} - SPHERAL_HOST_DEVICE void doSomething(){ printf("Base doSomething\n"); } - SPHERAL_HOST_DEVICE ~Base() { printf("DTor Base\n"); } -}; - -class Derived : public Base { -public: - SPHERAL_HOST_DEVICE Derived() {printf("CTor Derived\n");} - SPHERAL_HOST_DEVICE void doSomething(){ printf("Derived doSomething\n"); } - SPHERAL_HOST_DEVICE ~Derived() { printf("DTor Derived\n"); } -}; - - -TEST(SharedPtrTest, BasicCount) -{ - shared_ptr_t< Derived > s_ptr = chai::make_shared(); - - s_ptr->doSomething(); - SPHERAL_ASSERT_EQ(s_ptr.use_count(), 1); - - shared_ptr_t< Derived > s_ptr2 = s_ptr; - - s_ptr2->doSomething(); - - SPHERAL_ASSERT_EQ(s_ptr.use_count(), 2); - SPHERAL_ASSERT_EQ(s_ptr2.use_count(), 2); - - SPHERAL_ASSERT_EQ(s_ptr.get(), s_ptr2.get()); -} - -TEST(SharedPtrTest, UpcastCtor) -{ - shared_ptr_t< Base > s_ptr = chai::make_shared(); - - s_ptr->doSomething(); - SPHERAL_ASSERT_EQ(s_ptr.use_count(), 1); -} - -TEST(SharedPtrTest, UpcastCopyCtor) -{ - shared_ptr_t< Derived > s_ptr = chai::make_shared(); - - s_ptr->doSomething(); - SPHERAL_ASSERT_EQ(s_ptr.use_count(), 1); - - shared_ptr_t< Base > s_ptr_b = s_ptr; - - s_ptr_b->doSomething(); - - SPHERAL_ASSERT_EQ(s_ptr.use_count(), 2); - SPHERAL_ASSERT_EQ(s_ptr_b.use_count(), 2); - - SPHERAL_ASSERT_EQ(s_ptr.get(), s_ptr_b.get()); -} - -//TEST(SharedPtrTest, SharedCount) -//{ -// -// //Spheral::__shared_count(new Derived(), [](Derived* d){printf("Custom Deleter\n"); d->~Derived();}); -// Spheral::__shared_ptr sptr(new Derived(), [](Derived* d){printf("Custom Deleter\n"); d->~Derived();}); -// -// -// -//} - - -// Setting up G Test for SharedPtr -template -class SharedPtrTypedTest : public::testing::Test {}; - -// All SharedPtrTets cases will run over each type in EXEC_TYPES. -TYPED_TEST_CASE(SharedPtrTypedTest, EXEC_TYPES); - diff --git a/tests/cpp/Field/field_parallel_inheritance_tests.cc b/tests/cpp/Utilities/ValueViewInterface/field_parallel_inheritance_tests.cc similarity index 100% rename from tests/cpp/Field/field_parallel_inheritance_tests.cc rename to tests/cpp/Utilities/ValueViewInterface/field_parallel_inheritance_tests.cc diff --git a/tests/cpp/Kernel/kernel_parallel_inheritance_tests.cc b/tests/cpp/Utilities/ValueViewInterface/kernel_parallel_inheritance_tests.cc similarity index 100% rename from tests/cpp/Kernel/kernel_parallel_inheritance_tests.cc rename to tests/cpp/Utilities/ValueViewInterface/kernel_parallel_inheritance_tests.cc diff --git a/tests/cpp/Field/managed_vector_tests.cc b/tests/cpp/Utilities/managed_vector_tests.cc similarity index 100% rename from tests/cpp/Field/managed_vector_tests.cc rename to tests/cpp/Utilities/managed_vector_tests.cc From 5990faa0eac4500a8898838b04dcd853d3f2dc77 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 22 Jul 2024 18:24:03 -0700 Subject: [PATCH 07/44] Move QInt example class into test file. --- .../cpp/Utilities/ValueViewInterface/QInt.hh | 89 ------------------ .../quadratic_interpolator_example_tests.cc | 90 ++++++++++++++++++- 2 files changed, 87 insertions(+), 92 deletions(-) delete mode 100644 tests/cpp/Utilities/ValueViewInterface/QInt.hh diff --git a/tests/cpp/Utilities/ValueViewInterface/QInt.hh b/tests/cpp/Utilities/ValueViewInterface/QInt.hh deleted file mode 100644 index 8571ec5a0..000000000 --- a/tests/cpp/Utilities/ValueViewInterface/QInt.hh +++ /dev/null @@ -1,89 +0,0 @@ -//----------------------------------------------------------------------------- -// Quadratic Interpolator Example implementation -//----------------------------------------------------------------------------- - -#include "Utilities/ValueViewInterface.hh" -#include "Utilities/ManagedVector.hh" - -namespace Spheral { - -// The Data class needs to be CHAICopyable in order to trigger nested copies for Copyable -// members within. -class QIntData : public SPHERALCopyable{ -public: - - SPHERAL_HOST_DEVICE QIntData() = default; - SPHERAL_HOST_DEVICE QIntData(QIntData const& rhs) = default; - SPHERAL_HOST_DEVICE QIntData& operator=(QIntData const& rhs) = default; - - using CoeffsType = ManagedVector; - - double mXmin, mXmax, mXstep; - CoeffsType mcoeffs; - - SPHERAL_HOST void initialize(size_t min) - { - mXmin = min; - mcoeffs.resize(10); - mcoeffs[0] = 0.1; - mcoeffs[1] = 0.2; - mcoeffs[2] = 0.3; - mcoeffs[9] = 0.19; - } - - SPHERAL_HOST void editData(size_t min) - { - mXmin = min; - mcoeffs[9] = 91; - } - - SPHERAL_HOST_DEVICE double xmin() const { return mXmin; } - SPHERAL_HOST_DEVICE double xmax() const { return mXmax; } - SPHERAL_HOST_DEVICE CoeffsType const& coeffs() const { return mcoeffs; } - - // Define the required interface for a SPHERALCopyable object. - void free() { mcoeffs.free(); } - SPHERAL_HOST_DEVICE QIntData& operator=(std::nullptr_t) { mcoeffs=nullptr; return *this; } - SPHERAL_HOST_DEVICE void shallowCopy(QIntData const& rhs) { *this = rhs; } -}; - - -class QInt; - -class QIntView : public SpheralViewInterface -{ - VIEW_INTERFACE_METACLASS((QInt), (QIntView), (QIntData)) -public: - friend class QInt; - using CoeffsType = typename QIntData::CoeffsType; -protected: - //VIEW_DEFINE_ALLOC_CTOR(QIntView) - // Interal interface for accessing the underlying members of QIntData - SMART_PTR_MEMBER_ACCESSOR(CoeffsType, mcoeffs) - -public: - // Forward View capable methods - SPHERAL_HOST_DEVICE double xmin() const { return sptr_data().xmin(); } - SPHERAL_HOST_DEVICE double xmax() const { return sptr_data().xmax(); } - SPHERAL_HOST_DEVICE CoeffsType const& coeffs() const { return sptr_data().coeffs(); } -}; - - - -class QInt : public SpheralValueInterface -{ - VALUE_TYPE_ALIASES((QIntView)) -public: - VALUE_DEF_CTOR(QInt) - //VALUE_COPY_CTOR(QInt, QIntData) - //VALUE_ASSIGNEMT_OP(QInt, QIntData) - VALUE_TOVIEW_OP() - - // Forward Value capable methods - SPHERAL_HOST void initialize(size_t min) const { return sptr_data().initialize(min); } - SPHERAL_HOST void editData(size_t min) const { return sptr_data().editData(min); } - SPHERAL_HOST CoeffsType coeffs() const { return deepCopy(sptr_data().coeffs()); } -}; - -} // namespace Spheral - diff --git a/tests/cpp/Utilities/ValueViewInterface/quadratic_interpolator_example_tests.cc b/tests/cpp/Utilities/ValueViewInterface/quadratic_interpolator_example_tests.cc index 9c8aeb1f1..cc77bba43 100644 --- a/tests/cpp/Utilities/ValueViewInterface/quadratic_interpolator_example_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/quadratic_interpolator_example_tests.cc @@ -1,7 +1,91 @@ #include "test-utilities.hh" #include "test-basic-exec-policies.hh" -#include "QInt.hh" +//----------------------------------------------------------------------------- +// Quadratic Interpolator Example implementation +//----------------------------------------------------------------------------- + +#include "Utilities/ValueViewInterface.hh" +#include "Utilities/ManagedVector.hh" + +// The Data class needs to be CHAICopyable in order to trigger nested copies for Copyable +// members within. +class QIntData : public Spheral::SPHERALCopyable{ +public: + + SPHERAL_HOST_DEVICE QIntData() = default; + SPHERAL_HOST_DEVICE QIntData(QIntData const& rhs) = default; + SPHERAL_HOST_DEVICE QIntData& operator=(QIntData const& rhs) = default; + + using CoeffsType = Spheral::ManagedVector; + + double mXmin, mXmax, mXstep; + CoeffsType mcoeffs; + + SPHERAL_HOST void initialize(size_t min) + { + mXmin = min; + mcoeffs.resize(10); + mcoeffs[0] = 0.1; + mcoeffs[1] = 0.2; + mcoeffs[2] = 0.3; + mcoeffs[9] = 0.19; + } + + SPHERAL_HOST void editData(size_t min) + { + mXmin = min; + mcoeffs[9] = 91; + } + + SPHERAL_HOST_DEVICE double xmin() const { return mXmin; } + SPHERAL_HOST_DEVICE double xmax() const { return mXmax; } + SPHERAL_HOST_DEVICE CoeffsType const& coeffs() const { return mcoeffs; } + + // Define the required interface for a SPHERALCopyable object. + void free() { mcoeffs.free(); } + SPHERAL_HOST_DEVICE QIntData& operator=(std::nullptr_t) { mcoeffs=nullptr; return *this; } + SPHERAL_HOST_DEVICE void shallowCopy(QIntData const& rhs) { *this = rhs; } +}; + + +class QInt; + +class QIntView : public Spheral::SpheralViewInterface +{ + VIEW_INTERFACE_METACLASS((QInt), (QIntView), (QIntData)) +public: + friend class QInt; + using CoeffsType = typename QIntData::CoeffsType; +protected: + //VIEW_DEFINE_ALLOC_CTOR(QIntView) + // Interal interface for accessing the underlying members of QIntData + SMART_PTR_MEMBER_ACCESSOR(CoeffsType, mcoeffs) + +public: + // Forward View capable methods + SPHERAL_HOST_DEVICE double xmin() const { return sptr_data().xmin(); } + SPHERAL_HOST_DEVICE double xmax() const { return sptr_data().xmax(); } + SPHERAL_HOST_DEVICE CoeffsType const& coeffs() const { return sptr_data().coeffs(); } +}; + + + +class QInt : public Spheral::SpheralValueInterface +{ + VALUE_TYPE_ALIASES((QIntView)) +public: + VALUE_DEF_CTOR(QInt) + //VALUE_COPY_CTOR(QInt, QIntData) + //VALUE_ASSIGNEMT_OP(QInt, QIntData) + VALUE_TOVIEW_OP() + + // Forward Value capable methods + SPHERAL_HOST void initialize(size_t min) const { return sptr_data().initialize(min); } + SPHERAL_HOST void editData(size_t min) const { return sptr_data().editData(min); } + SPHERAL_HOST CoeffsType coeffs() const { return deepCopy(sptr_data().coeffs()); } +}; + // Setting up G Test for QuadraticInterpolator template @@ -15,9 +99,9 @@ GPU_TYPED_TEST(QIntExampleTypedTest, SmartCopySemantics) { using WORK_EXEC_POLICY = TypeParam; - Spheral::QInt::CoeffsType c; + QInt::CoeffsType c; { - Spheral::QInt qq_int; + QInt qq_int; auto qq_int_v = qq_int.toView(); auto qq_int_v2 = qq_int_v; From 5c04efef27ab82b5577f22523209ff31471c4f2e Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 22 Jul 2024 18:33:25 -0700 Subject: [PATCH 08/44] Re-naming value-view tests to identify the design pattern used. --- .../ValueViewInterface/CMakeLists.txt | 18 +++++++++++------- ...ests.cc => value_view_basic_class_tests.cc} | 0 ...sts.cc => value_view_crtp_pattern_tests.cc} | 0 ...> value_view_template_inheritance_tests.cc} | 0 4 files changed, 11 insertions(+), 7 deletions(-) rename tests/cpp/Utilities/ValueViewInterface/{quadratic_interpolator_example_tests.cc => value_view_basic_class_tests.cc} (100%) rename tests/cpp/Utilities/ValueViewInterface/{kernel_parallel_inheritance_tests.cc => value_view_crtp_pattern_tests.cc} (100%) rename tests/cpp/Utilities/ValueViewInterface/{field_parallel_inheritance_tests.cc => value_view_template_inheritance_tests.cc} (100%) diff --git a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt index a95a7bb59..380c2c085 100644 --- a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt +++ b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt @@ -1,15 +1,19 @@ +# This test is based off a basic implementation of Utilities/QuadraticInterpolator. spheral_add_test( - NAME kernel_parallel_inheritance_tests - SOURCES kernel_parallel_inheritance_tests.cc + NAME value_view_basic_class_tests + SOURCES value_view_basic_class_tests.cc + #DEBUG_LINKER ) +# This tests demonstrates CRTP as seen in Kernel. spheral_add_test( - NAME field_parallel_inheritance_tests - SOURCES field_parallel_inheritance_tests.cc + NAME value_view_crtp_pattern_tests + SOURCES value_view_crtp_pattern_tests.cc ) +# This test demonstrates use with a templated abstract base class. spheral_add_test( - NAME quadratic_interpolator_example_tests - SOURCES quadratic_interpolator_example_tests.cc - #DEBUG_LINKER + NAME value_view_template_inheritance_tests + SOURCES value_view_template_inheritance_tests.cc ) + diff --git a/tests/cpp/Utilities/ValueViewInterface/quadratic_interpolator_example_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc similarity index 100% rename from tests/cpp/Utilities/ValueViewInterface/quadratic_interpolator_example_tests.cc rename to tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc diff --git a/tests/cpp/Utilities/ValueViewInterface/kernel_parallel_inheritance_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc similarity index 100% rename from tests/cpp/Utilities/ValueViewInterface/kernel_parallel_inheritance_tests.cc rename to tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc diff --git a/tests/cpp/Utilities/ValueViewInterface/field_parallel_inheritance_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc similarity index 100% rename from tests/cpp/Utilities/ValueViewInterface/field_parallel_inheritance_tests.cc rename to tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc From a8ddc5f453753b878894b9f8b6c6939c4236cf3f Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 22 Jul 2024 19:13:15 -0700 Subject: [PATCH 09/44] Adding a basic value-view interface example using metaclass macros. --- .../ValueViewInterface/CMakeLists.txt | 7 + .../value_view_basic_class_tests.cc | 28 ++-- .../value_view_metaclass_basic_class_tests.cc | 128 ++++++++++++++++++ 3 files changed, 150 insertions(+), 13 deletions(-) create mode 100644 tests/cpp/Utilities/ValueViewInterface/value_view_metaclass_basic_class_tests.cc diff --git a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt index 380c2c085..5f7ff1b77 100644 --- a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt +++ b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt @@ -5,6 +5,13 @@ spheral_add_test( #DEBUG_LINKER ) +# This test is based off a basic implementation of Utilities/QuadraticInterpolator. +spheral_add_test( + NAME value_view_metaclass_basic_class_tests + SOURCES value_view_metaclass_basic_class_tests.cc + #DEBUG_LINKER +) + # This tests demonstrates CRTP as seen in Kernel. spheral_add_test( NAME value_view_crtp_pattern_tests diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc index cc77bba43..fc00d309b 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc @@ -8,14 +8,16 @@ #include "Utilities/ValueViewInterface.hh" #include "Utilities/ManagedVector.hh" +namespace impl { // The Data class needs to be CHAICopyable in order to trigger nested copies for Copyable // members within. -class QIntData : public Spheral::SPHERALCopyable{ + +class QInt : public Spheral::SPHERALCopyable{ public: - SPHERAL_HOST_DEVICE QIntData() = default; - SPHERAL_HOST_DEVICE QIntData(QIntData const& rhs) = default; - SPHERAL_HOST_DEVICE QIntData& operator=(QIntData const& rhs) = default; + SPHERAL_HOST_DEVICE QInt() = default; + SPHERAL_HOST_DEVICE QInt(QInt const& rhs) = default; + SPHERAL_HOST_DEVICE QInt& operator=(QInt const& rhs) = default; using CoeffsType = Spheral::ManagedVector; @@ -44,22 +46,23 @@ class QIntData : public Spheral::SPHERALCopyable{ // Define the required interface for a SPHERALCopyable object. void free() { mcoeffs.free(); } - SPHERAL_HOST_DEVICE QIntData& operator=(std::nullptr_t) { mcoeffs=nullptr; return *this; } - SPHERAL_HOST_DEVICE void shallowCopy(QIntData const& rhs) { *this = rhs; } + SPHERAL_HOST_DEVICE QInt& operator=(std::nullptr_t) { mcoeffs=nullptr; return *this; } + SPHERAL_HOST_DEVICE void shallowCopy(QInt const& rhs) { *this = rhs; } }; +} // namespace impl class QInt; -class QIntView : public Spheral::SpheralViewInterface +class QIntView : public Spheral::SpheralViewInterface { - VIEW_INTERFACE_METACLASS((QInt), (QIntView), (QIntData)) + VIEW_INTERFACE_METACLASS((QInt), (QIntView), (impl::QInt)) public: friend class QInt; - using CoeffsType = typename QIntData::CoeffsType; + using CoeffsType = typename impl::QInt::CoeffsType; protected: //VIEW_DEFINE_ALLOC_CTOR(QIntView) - // Interal interface for accessing the underlying members of QIntData + // Interal interface for accessing the underlying members of impl::QInt SMART_PTR_MEMBER_ACCESSOR(CoeffsType, mcoeffs) public: @@ -76,8 +79,8 @@ class QInt : public Spheral::SpheralValueInterface VALUE_TYPE_ALIASES((QIntView)) public: VALUE_DEF_CTOR(QInt) - //VALUE_COPY_CTOR(QInt, QIntData) - //VALUE_ASSIGNEMT_OP(QInt, QIntData) + //VALUE_COPY_CTOR(QInt, impl::QInt) + //VALUE_ASSIGNEMT_OP(QInt, impl::QInt) VALUE_TOVIEW_OP() // Forward Value capable methods @@ -86,7 +89,6 @@ class QInt : public Spheral::SpheralValueInterface SPHERAL_HOST CoeffsType coeffs() const { return deepCopy(sptr_data().coeffs()); } }; - // Setting up G Test for QuadraticInterpolator template class QIntExampleTypedTest : public::testing::Test {}; diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_metaclass_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_metaclass_basic_class_tests.cc new file mode 100644 index 000000000..daf8a1400 --- /dev/null +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_metaclass_basic_class_tests.cc @@ -0,0 +1,128 @@ +#include "test-utilities.hh" +#include "test-basic-exec-policies.hh" + +//----------------------------------------------------------------------------- +// Quadratic Interpolator Example implementation +//----------------------------------------------------------------------------- + +#include "Utilities/ValueViewInterface.hh" +#include "Utilities/ManagedVector.hh" + +namespace impl { +// The Data class needs to be CHAICopyable in order to trigger nested copies for Copyable +// members within. + +class QInt : public Spheral::SPHERALCopyable{ +public: + + SPHERAL_HOST_DEVICE QInt() = default; + SPHERAL_HOST_DEVICE QInt(QInt const& rhs) = default; + SPHERAL_HOST_DEVICE QInt& operator=(QInt const& rhs) = default; + + using CoeffsType = Spheral::ManagedVector; + + double mXmin, mXmax, mXstep; + CoeffsType mcoeffs; + + SPHERAL_HOST void initialize(size_t min) + { + mXmin = min; + mcoeffs.resize(10); + mcoeffs[0] = 0.1; + mcoeffs[1] = 0.2; + mcoeffs[2] = 0.3; + mcoeffs[9] = 0.19; + } + + SPHERAL_HOST void editData(size_t min) + { + mXmin = min; + mcoeffs[9] = 91; + } + + SPHERAL_HOST_DEVICE double xmin() const { return mXmin; } + SPHERAL_HOST_DEVICE double xmax() const { return mXmax; } + SPHERAL_HOST_DEVICE CoeffsType const& coeffs() const { return mcoeffs; } + + // Define the required interface for a SPHERALCopyable object. + void free() { mcoeffs.free(); } + SPHERAL_HOST_DEVICE QInt& operator=(std::nullptr_t) { mcoeffs=nullptr; return *this; } + SPHERAL_HOST_DEVICE void shallowCopy(QInt const& rhs) { *this = rhs; } +}; + +} // namespace impl + +class QInt; + +#define QIntView__(code) VIEW_INTERFACE_METACLASS_DECLARATION( (QInt), (QIntView), (impl::QInt), (code) ) +#define QInt__(code) VALUE_INTERFACE_METACLASS_DECLARATION( (QInt), (QIntView), (code) ) + +class QIntView__( + DEFAULT() +public: + using CoeffsType = typename impl::QInt::CoeffsType; +); + +class QInt__( +public: + VALUE_DEF_CTOR(QInt) + + SPHERAL_HOST_DEVICE double xmin() const { return sptr_data().xmin(); } + SPHERAL_HOST_DEVICE double xmax() const { return sptr_data().xmax(); } + + SPHERAL_HOST void initialize(size_t min) const { return sptr_data().initialize(min); } + SPHERAL_HOST void editData(size_t min) const { return sptr_data().editData(min); } + SPHERAL_HOST CoeffsType coeffs() const { return deepCopy(sptr_data().coeffs()); } +); + + +// Setting up G Test for QuadraticInterpolator +template +class QIntExampleTypedTest : public::testing::Test {}; + +// All QuadraticInterpolatorTets cases will run over each type in EXEC_TYPES. +TYPED_TEST_CASE(QIntExampleTypedTest, EXEC_TYPES); + + +GPU_TYPED_TEST(QIntExampleTypedTest, SmartCopySemantics) +{ + using WORK_EXEC_POLICY = TypeParam; + + QInt::CoeffsType c; + { + QInt qq_int; + + auto qq_int_v = &qq_int; + auto qq_int_v2 = qq_int_v; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(qq_int_v->xmin(), 0); + SPHERAL_ASSERT_EQ(qq_int_v->coeffs().size(), 0); + EXEC_IN_SPACE_END(); + + qq_int.initialize(4); + SPHERAL_ASSERT_EQ(qq_int_v->coeffs().size(), 10); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + printf("xmin : %lf\n", qq_int_v->xmin()); + SPHERAL_ASSERT_EQ(qq_int_v->xmin(), 4); + SPHERAL_ASSERT_EQ(qq_int_v->coeffs().size(), 10); + SPHERAL_ASSERT_EQ(qq_int_v->coeffs()[9], 0.19); + + EXEC_IN_SPACE_END(); + + qq_int.editData(2); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + SPHERAL_ASSERT_EQ(qq_int_v->xmin(), 2); + SPHERAL_ASSERT_EQ(qq_int_v->coeffs()[9], 91); + printf("xmin : %lf\n", qq_int_v->xmin()); + printf("coeffs[19] : %lf\n", qq_int_v->coeffs()[9]); + EXEC_IN_SPACE_END(); + + for (auto elem : qq_int.coeffs()) std::cout << elem << std::endl; + c = qq_int.coeffs(); + } + for (auto elem : c) std::cout << elem << std::endl; +} + From df6c88f3280139b5b11ab6d9e58d76cf19bccdbd Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Tue, 30 Jul 2024 10:18:43 -0700 Subject: [PATCH 10/44] Adding SCIP macros. --- cmake/CMakeDefinitions.cmake | 9 ++++ cmake/SetupSpheral.cmake | 2 + cmake/spheral/SpheralAddLibs.cmake | 18 ++++---- src/Utilities/ValueViewInterface.hh | 44 ++++++++++++------- src/config.hh.in | 3 ++ .../value_view_basic_class_tests.cc | 5 +-- .../value_view_metaclass_basic_class_tests.cc | 23 +++++----- 7 files changed, 64 insertions(+), 40 deletions(-) diff --git a/cmake/CMakeDefinitions.cmake b/cmake/CMakeDefinitions.cmake index d8b2f2340..a4bd427e4 100644 --- a/cmake/CMakeDefinitions.cmake +++ b/cmake/CMakeDefinitions.cmake @@ -16,6 +16,15 @@ else() add_definitions("-DDEBUG=0") endif() +if (SPHERAL_ENABLE_SCIP) + message("-- Semantic Class Interface Pattern (SCIP) : Enabled") + message("------ WARNING ------") + message("-- SCIP is an experimental implementation necessary for the GPU port. Use with caution!") + message("---------------------") +else() + message("-- Semantic Class Interface Pattern (SCIP) : Disabled") +endif() + # The DBC flag if (DBC_MODE STREQUAL "All") message("-- DBC (design by contract) set to All") diff --git a/cmake/SetupSpheral.cmake b/cmake/SetupSpheral.cmake index e40b4fb31..dd2862edb 100644 --- a/cmake/SetupSpheral.cmake +++ b/cmake/SetupSpheral.cmake @@ -88,7 +88,9 @@ if(ENABLE_CUDA) set(CMAKE_CUDA_STANDARD 17) list(APPEND SPHERAL_CXX_DEPENDS cuda) set(SPHERAL_ENABLE_CUDA On) + set(SPHERAL_ENABLE_SCIP On) endif() +message("Enable Semantic Class Interface Pattern (SCIP) : ${SPHERAL_ENABLE_SCIP}") #-------------------------------------------------------------------------------# # Set a default build type if none was specified diff --git a/cmake/spheral/SpheralAddLibs.cmake b/cmake/spheral/SpheralAddLibs.cmake index 6e8b9e545..862799ba7 100644 --- a/cmake/spheral/SpheralAddLibs.cmake +++ b/cmake/spheral/SpheralAddLibs.cmake @@ -107,16 +107,16 @@ function(spheral_add_cxx_library package_name _cxx_obj_list) endif() - ## This cleans up library targets created with object libs. It is turned off as it triggers - ## a failure on Werror and pedantic builds. - #set(_properties COMPILE_DEFINITIONS LINK_LIBRARIES LINK_OPTIONS INTERFACE_LINK_OPTIONS COMPILE_OPTIONS INTERFACE_COMPILE_OPTIONS) - #foreach(_prop ${_properties}) - # get_target_property(temp_prop Spheral_${package_name} ${_prop}) - # list(REMOVE_DUPLICATES temp_prop) - # set_target_properties(Spheral_${package_name} PROPERTIES ${_prop} "${temp_prop}") - #endforeach() + # This cleans up library targets created with object libs. It is turned off as it triggers + # a failure on Werror and pedantic builds. + set(_properties COMPILE_DEFINITIONS LINK_LIBRARIES LINK_OPTIONS INTERFACE_LINK_OPTIONS COMPILE_OPTIONS INTERFACE_COMPILE_OPTIONS) + foreach(_prop ${_properties}) + get_target_property(temp_prop Spheral_${package_name} ${_prop}) + list(REMOVE_DUPLICATES temp_prop) + set_target_properties(Spheral_${package_name} PROPERTIES ${_prop} "${temp_prop}") + endforeach() - #set_target_properties(Spheral_${package_name} PROPERTIES INTERFACE_LINK_LIBRARIES "") + set_target_properties(Spheral_${package_name} PROPERTIES INTERFACE_LINK_LIBRARIES "") # Convert package name to lower-case for export target name string(TOLOWER ${package_name} lower_case_package) diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh index 023e6e798..a0d805151 100644 --- a/src/Utilities/ValueViewInterface.hh +++ b/src/Utilities/ValueViewInterface.hh @@ -2,6 +2,8 @@ #define __SPHERAL_VALUEVIEWINTERFACE__ //#include "Utilities/SharedPtr.hh" +#include "ManagedVector.hh" +#include "config.hh" #include "chai/ManagedSharedPtr.hpp" #include @@ -18,11 +20,7 @@ namespace Spheral { // classes that need to be automatically copied by another CHAICopyable or // SPHERALCopyable class. template -class SPHERALCopyable : public chai::CHAICopyable{ - //virtual void free(); - //SPHERAL_HOST_DEVICE virtual T& operator=(std::nullptr_t) = 0; - //SPHERAL_HOST_DEVICE virtual void shallowCopy(T const& rhs) = 0; -}; +class SPHERALCopyable : public chai::CHAICopyable{}; // Interface class for View like objects. // @@ -33,26 +31,40 @@ class SPHERALCopyable : public chai::CHAICopyable{ // in order to set up a forwarding constructor from the Value class ctor // that passes in a "new DataObject" type. -#define USE_CMSPTR +#if defined(SPHERAL_ENABLE_SCIP) +#define SCIP_IMPL_BEGIN namespace impl { +#define SCIP_IMPL_END } // namespace impl +#else +#define SCIP_IMPL_BEGIN +#define SCIP_IMPL_END +#endif + +namespace util { +template +#if defined(SPHERAL_ENABLE_SCIP) +using shared_ptr = chai::ManagedSharedPtr; +#else +using shared_ptr = std::shared_ptr; +#endif template -#if defined(USE_CMSPTR) -using SMART_PTR_TYPE = chai::ManagedSharedPtr; +#if defined(SPHERAL_ENABLE_SCIP) +using vector = ManagedVector; #else -//using SMART_PTR_TYPE = Spheral::shared_ptr; -using SMART_PTR_TYPE = std::shared_ptr; -//using SMART_PTR_TYPE = ManagedSmartPtr; +using vector = std::vector; #endif +}// namespace util + template -class SpheralViewInterface : public SMART_PTR_TYPE +class SpheralViewInterface : public util::shared_ptr { private: using m_ImplType = impl_type; public: - using SmartPtrType = SMART_PTR_TYPE; + using SmartPtrType = util::shared_ptr; SPHERAL_HOST_DEVICE SmartPtrType & sptr() { return *this; } SPHERAL_HOST_DEVICE SmartPtrType const& sptr() const { return *this; } @@ -76,7 +88,7 @@ protected: using ViewType = typename view_type::ViewType; public: -#if !defined(USE_CMSPTR) +#if !defined(SPHERAL_ENABLE_SCIP) SPHERAL_HOST SpheralValueInterface(m_ImplType* rhs) : view_type((rhs)) {} #endif SPHERAL_HOST SpheralValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} @@ -90,7 +102,7 @@ public: // Defines a ctor that will take a "new" Data object to create the underlying // ManagedSmartPtr. -#if !defined(USE_CMSPTR) +#if !defined(SPHERAL_ENABLE_SCIP) #define VIEW_DEFINE_ALLOC_CTOR(view_t) \ protected: \ view_t(ImplType* rhs) : Base(SmartPtrType(rhs, [](ImplType *p) { p->free(); } )) {} @@ -167,7 +179,7 @@ public: \ SPHERAL_HOST_DEVICE ImplType& operator*() const { return SPTR_DATA_REF(); } \ SPHERAL_HOST_DEVICE ImplType* operator->() const { return &SPTR_DATA_REF(); } -#if !defined(USE_CMSPTR) +#if !defined(SPHERAL_ENABLE_SCIP) #define VALUE_DEF_CTOR(value_t) \ value_t() : Base(new ImplType()) {} #define VALUE_COPY_CTOR(value_t) \ diff --git a/src/config.hh.in b/src/config.hh.in index 7b1fb0180..04147a4bd 100644 --- a/src/config.hh.in +++ b/src/config.hh.in @@ -6,7 +6,9 @@ #define SPHERAL_CXX_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@" #cmakedefine SPHERAL_ENABLE_OPENMP + #cmakedefine SPHERAL_ENABLE_CUDA +#cmakedefine SPHERAL_ENABLE_SCIP #if defined(SPHERAL_ENABLE_CUDA) && defined(__CUDA_ARCH__) #define SPHERAL_GPU_ACTIVE @@ -16,4 +18,5 @@ #define SPHERAL_HOST RAJA_HOST #define SPHERAL_DEVICE RAJA_DEVICE + #endif // SPHERAL_config_HPP diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc index fc00d309b..de6a4c9c3 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc @@ -9,8 +9,6 @@ #include "Utilities/ManagedVector.hh" namespace impl { -// The Data class needs to be CHAICopyable in order to trigger nested copies for Copyable -// members within. class QInt : public Spheral::SPHERALCopyable{ public: @@ -19,7 +17,7 @@ class QInt : public Spheral::SPHERALCopyable{ SPHERAL_HOST_DEVICE QInt(QInt const& rhs) = default; SPHERAL_HOST_DEVICE QInt& operator=(QInt const& rhs) = default; - using CoeffsType = Spheral::ManagedVector; + using CoeffsType = Spheral::util::vector; double mXmin, mXmax, mXstep; CoeffsType mcoeffs; @@ -89,6 +87,7 @@ class QInt : public Spheral::SpheralValueInterface SPHERAL_HOST CoeffsType coeffs() const { return deepCopy(sptr_data().coeffs()); } }; + // Setting up G Test for QuadraticInterpolator template class QIntExampleTypedTest : public::testing::Test {}; diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_metaclass_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_metaclass_basic_class_tests.cc index daf8a1400..803a29dd3 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_metaclass_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_metaclass_basic_class_tests.cc @@ -6,11 +6,8 @@ //----------------------------------------------------------------------------- #include "Utilities/ValueViewInterface.hh" -#include "Utilities/ManagedVector.hh" -namespace impl { -// The Data class needs to be CHAICopyable in order to trigger nested copies for Copyable -// members within. +SCIP_IMPL_BEGIN class QInt : public Spheral::SPHERALCopyable{ public: @@ -19,7 +16,7 @@ class QInt : public Spheral::SPHERALCopyable{ SPHERAL_HOST_DEVICE QInt(QInt const& rhs) = default; SPHERAL_HOST_DEVICE QInt& operator=(QInt const& rhs) = default; - using CoeffsType = Spheral::ManagedVector; + using CoeffsType = Spheral::util::vector; double mXmin, mXmax, mXstep; CoeffsType mcoeffs; @@ -44,21 +41,20 @@ class QInt : public Spheral::SPHERALCopyable{ SPHERAL_HOST_DEVICE double xmax() const { return mXmax; } SPHERAL_HOST_DEVICE CoeffsType const& coeffs() const { return mcoeffs; } - // Define the required interface for a SPHERALCopyable object. - void free() { mcoeffs.free(); } - SPHERAL_HOST_DEVICE QInt& operator=(std::nullptr_t) { mcoeffs=nullptr; return *this; } - SPHERAL_HOST_DEVICE void shallowCopy(QInt const& rhs) { *this = rhs; } }; -} // namespace impl +SCIP_IMPL_END + + +#ifdef SPHERAL_ENABLE_SCIP class QInt; #define QIntView__(code) VIEW_INTERFACE_METACLASS_DECLARATION( (QInt), (QIntView), (impl::QInt), (code) ) #define QInt__(code) VALUE_INTERFACE_METACLASS_DECLARATION( (QInt), (QIntView), (code) ) class QIntView__( - DEFAULT() + DEFAULT() // This defines the default behavior of a reference semantics based interface. public: using CoeffsType = typename impl::QInt::CoeffsType; ); @@ -75,6 +71,10 @@ class QInt__( SPHERAL_HOST CoeffsType coeffs() const { return deepCopy(sptr_data().coeffs()); } ); +#endif //SPHERAL_ENABLE_SCIP + + + // Setting up G Test for QuadraticInterpolator template @@ -96,7 +96,6 @@ GPU_TYPED_TEST(QIntExampleTypedTest, SmartCopySemantics) auto qq_int_v2 = qq_int_v; EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) - SPHERAL_ASSERT_EQ(qq_int_v->xmin(), 0); SPHERAL_ASSERT_EQ(qq_int_v->coeffs().size(), 0); EXEC_IN_SPACE_END(); From 708cc2ad369c7622c833ffa65c20f4630ad54918 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Wed, 21 Aug 2024 17:02:30 -0700 Subject: [PATCH 11/44] Moving Value View Interface under vvi namespace; Naming convention and organization for VVI macros; Differentiating between Ptr and Ref syntax metaclasses with vvi pattern. --- src/Utilities/ValueViewInterface.hh | 239 +++++++++++------- .../ValueViewInterface/CMakeLists.txt | 11 +- .../value_view_crtp_pattern_tests.cc | 50 ++-- ...cc => value_view_ptr_basic_class_tests.cc} | 20 +- ...cc => value_view_ref_basic_class_tests.cc} | 36 +-- .../value_view_template_inheritance_tests.cc | 47 ++-- 6 files changed, 221 insertions(+), 182 deletions(-) rename tests/cpp/Utilities/ValueViewInterface/{value_view_metaclass_basic_class_tests.cc => value_view_ptr_basic_class_tests.cc} (77%) rename tests/cpp/Utilities/ValueViewInterface/{value_view_basic_class_tests.cc => value_view_ref_basic_class_tests.cc} (80%) diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh index a0d805151..a01807138 100644 --- a/src/Utilities/ValueViewInterface.hh +++ b/src/Utilities/ValueViewInterface.hh @@ -24,16 +24,16 @@ class SPHERALCopyable : public chai::CHAICopyable{}; // Interface class for View like objects. // -// All View classes should inherit from SpheralViewInterface. It sets up useful +// All View classes should inherit from ViewInterface. It sets up useful // type aliases and forwarding constructors to the underlying Data class. // -// SpheralViewInterface children will want to use VIEW_DEFINE_ALLOC_CTOR +// ViewInterface children will want to use VIEW_DEFINE_ALLOC_CTOR // in order to set up a forwarding constructor from the Value class ctor // that passes in a "new DataObject" type. #if defined(SPHERAL_ENABLE_SCIP) -#define SCIP_IMPL_BEGIN namespace impl { -#define SCIP_IMPL_END } // namespace impl +#define SCIP_IMPL_BEGIN namespace vvi { namespace impl { +#define SCIP_IMPL_END } } // namespace vvi::impl #else #define SCIP_IMPL_BEGIN #define SCIP_IMPL_END @@ -57,28 +57,33 @@ using vector = std::vector; }// namespace util +} // namespace Spheral + + +namespace vvi { + template -class SpheralViewInterface : public util::shared_ptr +class ViewInterface : public ::Spheral::util::shared_ptr { private: using m_ImplType = impl_type; public: - using SmartPtrType = util::shared_ptr; + using SmartPtrType = ::Spheral::util::shared_ptr; SPHERAL_HOST_DEVICE SmartPtrType & sptr() { return *this; } SPHERAL_HOST_DEVICE SmartPtrType const& sptr() const { return *this; } SPHERAL_HOST_DEVICE m_ImplType & sptr_data() { return *(SmartPtrType::get()); } \ SPHERAL_HOST_DEVICE m_ImplType & sptr_data() const { return *(SmartPtrType::get()); } - SPHERAL_HOST_DEVICE SpheralViewInterface() = default; - SPHERAL_HOST SpheralViewInterface(SmartPtrType&& rhs) : SmartPtrType(std::forward(rhs)) {} + SPHERAL_HOST_DEVICE ViewInterface() = default; + SPHERAL_HOST ViewInterface(SmartPtrType&& rhs) : SmartPtrType(std::forward(rhs)) {} }; // Interface class for Value like objects. template -class SpheralValueInterface : public view_type +class ValueInterface : public view_type { private: using m_ImplType = typename view_type::ImplType; @@ -89,177 +94,217 @@ protected: public: #if !defined(SPHERAL_ENABLE_SCIP) - SPHERAL_HOST SpheralValueInterface(m_ImplType* rhs) : view_type((rhs)) {} + SPHERAL_HOST ValueInterface(m_ImplType* rhs) : view_type((rhs)) {} #endif - SPHERAL_HOST SpheralValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} + SPHERAL_HOST ValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} }; +} // namespace vvi + +#define vvi_impl_SPTR_DATA_REF ViewInterfaceType::sptr_data + + -#define SPTR_REF ViewInterface::sptr -#define SPTR_DATA_REF ViewInterface::sptr_data // Defines a ctor that will take a "new" Data object to create the underlying // ManagedSmartPtr. #if !defined(SPHERAL_ENABLE_SCIP) -#define VIEW_DEFINE_ALLOC_CTOR(view_t) \ +#define vvi_impl_VIEW_DEFINE_ALLOC_CTOR(view_t) \ protected: \ view_t(ImplType* rhs) : Base(SmartPtrType(rhs, [](ImplType *p) { p->free(); } )) {} //view_t(ImplType* rhs) : Base(SmartPtrType(rhs, [](ImplType *p) { p->free(); } )) {} #else -#define VIEW_DEFINE_ALLOC_CTOR(view_t) \ +#define vvi_impl_VIEW_DEFINE_ALLOC_CTOR(view_t) \ public: \ view_t(SmartPtrType&& rhs) : Base(std::forward(rhs)) {} #endif -#define VIEW_DEF_CTOR(view_t) \ +#define vvi_impl_VIEW_SHALLOW_COPY(view_t) \ +public: \ + void shallowCopy(view_t const& rhs) {*this = rhs;} + + + + + +// ---------------------------------------------------------------------------- +// Behavioral macros : These are used to allow for pointer like behavior from +// interface classes +// ---------------------------------------------------------------------------- + +#define POINTER_SYNTAX_OPERATORS() \ +public: \ + SPHERAL_HOST_DEVICE ImplType& operator*() const { return vvi_impl_SPTR_DATA_REF(); } \ + SPHERAL_HOST_DEVICE ImplType* operator->() const { return &vvi_impl_SPTR_DATA_REF(); } + + +#define REF_OPERATOR() \ +public: \ + ViewType operator&() { return toView(); } + + +#define VVI_UPCAST_CONVERSION_OP(parent_t) \ +public: \ + operator parent_t() const {return parent_t(this->sptr());} + + +#define VVI_DELETED_INTERFACE(type) \ +public: \ + type() = delete; \ + type(type const&) = delete; \ + type& operator=(type const&) = delete; + +#define VVI_DEFAULT() ; + +#define VVI_MEMBER_ACCESSOR(type, var) \ + SPHERAL_HOST_DEVICE type & var() { return Base::get()->var; } \ + SPHERAL_HOST_DEVICE type & var() const { return Base::get()->var; } + +#define VVI_IMPL_INST this->sptr_data() + +// ---------------------------------------------------------------------------- +// VIEW class definition macros +// ---------------------------------------------------------------------------- + +#define VVI_VIEW_DEF_CTOR(view_t) \ view_t() = default; -#define VIEW_COPY_CTOR(view_t) \ +#define VVI_VIEW_COPY_CTOR(view_t) \ view_t(view_t const& rhs) = default; -#define VIEW_ASSIGNEMT_OP() \ +#define VVI_VIEW_ASSIGNEMT_OP() \ SPHERAL_HOST_DEVICE ViewType& operator=(ViewType const& rhs) = default; -#define VIEW_EQ_OP() \ +#define VVI_VIEW_EQ_OP() \ bool operator==(const ViewType& rhs) const \ { return sptr_data() == rhs.sptr_data(); } -#define VIEW_SHALLOW_COPY(view_t) \ -public: \ - void shallowCopy(view_t const& rhs) {*this = rhs;} + +// ---------------------------------------------------------------------------- +// VIEW class declaration macros +// ---------------------------------------------------------------------------- + #define VIEW_INTERFACE_METACLASS(value_t, view_t, impl_t) \ public: \ using ImplType = UNPACK impl_t; \ using ViewType = UNPACK view_t; \ using ValueType = UNPACK value_t; \ protected: \ - using Base = Spheral::SpheralViewInterface; \ - using ViewInterface = Base; \ + using Base = ::vvi::ViewInterface; \ + using ViewInterfaceType = Base; \ using SmartPtrType = typename Base::SmartPtrType; \ friend class UNPACK value_t; \ - VIEW_DEFINE_ALLOC_CTOR(view_t) \ - SPHERAL_HOST_DEVICE VIEW_DEF_CTOR(view_t) \ - VIEW_SHALLOW_COPY(UNPACK view_t) \ + vvi_impl_VIEW_DEFINE_ALLOC_CTOR(view_t) \ +private: -#define VIEW_INTERFACE_METACLASS_DECLARATION_BEGIN(value_t, view_t, impl_t) \ -UNPACK view_t : public Spheral::SpheralViewInterface< UNPACK impl_t> { \ - VIEW_INTERFACE_METACLASS((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) \ - POINTER_SYNTAX_OPERATORS() +#define VIEW_METACLASS_DECL_BEGIN(value_t, view_t, impl_t) \ +UNPACK view_t : public ::vvi::ViewInterface< UNPACK impl_t> { \ + VIEW_INTERFACE_METACLASS((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) -#define VIEW_INTERFACE_METACLASS_DECLARATION_END() \ +#define VIEW_METACLASS_DECL_END() \ }; -#define VIEW_INTERFACE_METACLASS_DECLARATION(value_t, view_t, impl_t, code) \ - VIEW_INTERFACE_METACLASS_DECLARATION_BEGIN((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) \ +#define PTR_VIEW_METACLASS_DECL(value_t, view_t, impl_t, code) \ + VIEW_METACLASS_DECL_BEGIN((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) \ + POINTER_SYNTAX_OPERATORS() \ UNPACK code \ -} + VIEW_METACLASS_DECL_END() +#define REF_VIEW_METACLASS_DECL(value_t, view_t, impl_t, code) \ + VIEW_METACLASS_DECL_BEGIN((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) \ + UNPACK code \ + VIEW_METACLASS_DECL_END() -#define VALUE_TYPE_ALIASES(view_t) \ -public: \ - using ViewType = UNPACK view_t; \ - using ValueType = typename ViewType::ValueType; \ - using ImplType = typename ViewType::ImplType; \ -protected: \ - using Base = Spheral::SpheralValueInterface; \ - using ViewInterface = typename ViewType::ViewInterface; \ - using SmartPtrType = typename ViewType::SmartPtrType; \ -#define UPCAST_CONVERSION_OP(parent_t) \ -public: \ - operator parent_t() const {return parent_t(this->sptr());} -#define POINTER_SYNTAX_OPERATORS() \ -public: \ - SPHERAL_HOST_DEVICE ImplType& operator*() const { return SPTR_DATA_REF(); } \ - SPHERAL_HOST_DEVICE ImplType* operator->() const { return &SPTR_DATA_REF(); } -#if !defined(SPHERAL_ENABLE_SCIP) -#define VALUE_DEF_CTOR(value_t) \ - value_t() : Base(new ImplType()) {} -#define VALUE_COPY_CTOR(value_t) \ - value_t(value_t const& rhs) : Base(new ImplType( deepCopy( rhs.SPTR_DATA_REF() ) )) {} -#define VALUE_ASSIGNEMT_OP() \ - ValueType& operator=(ValueType const& rhs) { \ - ViewType::operator=( ViewType::ViewType(new ImplType( deepCopy( rhs.SPTR_DATA_REF() )))); \ - return *this; \ - } -#else -#define VALUE_DEF_CTOR(value_t) \ + + +// ---------------------------------------------------------------------------- +// VALUE class definition macros +// ---------------------------------------------------------------------------- + +#define VVI_CTOR(value_t, params, args) \ + value_t(UNPACK params) : Base(chai::make_shared(UNPACK args)) {} + +#define VVI_CTOR_ARGS(args) \ + Base(chai::make_shared(UNPACK args)) + +#define VVI_DTOR(value_t, code) \ + ~value_t() { UNPACK code } + +#define VVI_VALUE_DEF_CTOR(value_t) \ value_t() : Base(chai::make_shared()) {} -#define VALUE_COPY_CTOR(value_t) \ - value_t(value_t const& rhs) : Base(chai::make_shared( deepCopy(rhs.SPTR_DATA_REF()) )) {} -#define VALUE_ASSIGNEMT_OP() \ + +#define VVI_VALUE_COPY_CTOR(value_t) \ + value_t(value_t const& rhs) : Base(chai::make_shared( deepCopy(rhs.vvi_impl_SPTR_DATA_REF()) )) {} + +#define VVI_VALUE_ASSIGNEMT_OP() \ ValueType& operator=(ValueType const& rhs) { \ - ViewType::operator=( ViewType::ViewType(chai::make_shared( deepCopy( rhs.SPTR_DATA_REF() )))); \ + ViewType::operator=( ViewType::ViewType(chai::make_shared( deepCopy( rhs.vvi_impl_SPTR_DATA_REF() )))); \ return *this; \ } -#endif - - -#define VALUE_EQ_OP() \ +#define VVI_VALUE_EQ_OP() \ bool operator==(const ValueType& rhs) const \ { return compare(sptr_data(), rhs.sptr_data()); } -#define VALUE_TOVIEW_OP() \ +#define VVI_VALUE_TOVIEW_OP() \ ViewType toView() { return ViewType(*this); } -#define VALUE_TYPE_DEFAULT_ASSIGNMENT_OP(value_t) \ +#define VVI_VALUE_TYPE_DEFAULT_ASSIGNMENT_OP(value_t) \ value_t& operator=(value_t const& rhs) { \ - ViewType::operator=( ViewType( new ImplType(deepCopy(rhs.ViewInterface::sptr_data())) ) ); \ + ViewType::operator=( ViewType( new ImplType(deepCopy(rhs.ViewInterfaceType::sptr_data())) ) ); \ return *this; \ } +// ---------------------------------------------------------------------------- +// VALUE class declaration macros +// ---------------------------------------------------------------------------- + #define VALUE_INTERFACE_METACLASS(view_t) \ public: \ using ViewType = UNPACK view_t; \ using ValueType = typename ViewType::ValueType; \ using ImplType = typename ViewType::ImplType; \ protected: \ - using Base = Spheral::SpheralValueInterface; \ - using ViewInterface = typename ViewType::ViewInterface; \ + using Base = ::vvi::ValueInterface; \ + using ViewInterfaceType = typename ViewType::ViewInterfaceType; \ using SmartPtrType = typename ViewType::SmartPtrType; \ public: \ - VALUE_TOVIEW_OP() \ - ViewType operator&() { return toView(); }\ + VVI_VALUE_TOVIEW_OP() \ +private: -#define VALUE_INTERFACE_METACLASS_DECLARATION_BEGIN(value_t, view_t) \ -UNPACK value_t : public Spheral::SpheralValueInterface { \ +#define VALUE_METACLASS_DECL_BEGIN(value_t, view_t) \ +UNPACK value_t : public ::vvi::ValueInterface { \ VALUE_INTERFACE_METACLASS((UNPACK view_t)) \ -#define VALUE_INTERFACE_METACLASS_DECLARATION_END() \ +#define VALUE_METACLASS_DECL_END() \ }; -#define VALUE_INTERFACE_METACLASS_DECLARATION(value_t, view_t, code) \ - VALUE_INTERFACE_METACLASS_DECLARATION_BEGIN((UNPACK value_t), (UNPACK view_t)) \ +#define PTR_VALUE_METACLASS_DECL(value_t, view_t, code) \ + VALUE_METACLASS_DECL_BEGIN((UNPACK value_t), (UNPACK view_t)) \ + REF_OPERATOR() \ UNPACK code \ -} + VALUE_METACLASS_DECL_END() + + +#define REF_VALUE_METACLASS_DECL(value_t, view_t, code) \ + VALUE_METACLASS_DECL_BEGIN((UNPACK value_t), (UNPACK view_t)) \ + UNPACK code \ + VALUE_METACLASS_DECL_END() -#define DELETED_INTERFACE(type) \ -public: \ - type() = delete; \ - type(type const&) = delete; \ - type& operator=(type const&) = delete; \ -#define DEFAULT() ; -// It is assumed that the Base type is defined with from inheriting -// SpheralViewInterface or by explicitly defining : -// using Base = ManagedSmartPtr; -#define SMART_PTR_MEMBER_ACCESSOR(type, var) \ - SPHERAL_HOST_DEVICE type & var() { return Base::get()->var; } \ - SPHERAL_HOST_DEVICE type & var() const { return Base::get()->var; } -} // namespace Spheral #endif // __SPHERAL_VALUEVIEWINTERFACE__ diff --git a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt index 5f7ff1b77..99e4a1b40 100644 --- a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt +++ b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt @@ -1,14 +1,16 @@ # This test is based off a basic implementation of Utilities/QuadraticInterpolator. spheral_add_test( - NAME value_view_basic_class_tests - SOURCES value_view_basic_class_tests.cc + NAME value_view_ptr_basic_class_tests + SOURCES value_view_ptr_basic_class_tests.cc #DEBUG_LINKER ) +if(SPHERAL_ENABLE_SCIP) + # This test is based off a basic implementation of Utilities/QuadraticInterpolator. spheral_add_test( - NAME value_view_metaclass_basic_class_tests - SOURCES value_view_metaclass_basic_class_tests.cc + NAME value_view_ref_basic_class_tests + SOURCES value_view_ref_basic_class_tests.cc #DEBUG_LINKER ) @@ -24,3 +26,4 @@ spheral_add_test( SOURCES value_view_template_inheritance_tests.cc ) +endif() diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc index 5e2f5c38e..69dfe75f2 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc @@ -7,7 +7,7 @@ //-------------------------------- // Impl Interface -namespace impl { +SCIP_IMPL_BEGIN template class Kernel : public Spheral::SPHERALCopyable> { @@ -39,7 +39,7 @@ class OtherKernel : public Kernel> { SPHERAL_HOST_DEVICE void doSomething() { printf("OKi HD doSomething()\n"); printf("OtherKernel doSomething\n"); } }; -} // namespace impl +SCIP_IMPL_END //-------------------------------- // View Interface @@ -51,22 +51,22 @@ class TableKernel; template class OtherKernel; -#define KernelView__(code) VIEW_INTERFACE_METACLASS_DECLARATION( (Kernel), (KernelView), (impl::Kernel), (code)) -#define TableKernelView__(code) VIEW_INTERFACE_METACLASS_DECLARATION( (TableKernel), (TableKernelView), (impl::TableKernel), (code)) -#define OtherKernelView__(code) VIEW_INTERFACE_METACLASS_DECLARATION( (OtherKernel), (OtherKernelView), (impl::OtherKernel), (code)) +#define KernelView__(code) PTR_VIEW_METACLASS_DECL( (Kernel), (KernelView), (vvi::impl::Kernel), (code)) +#define TableKernelView__(code) PTR_VIEW_METACLASS_DECL( (TableKernel), (TableKernelView), (vvi::impl::TableKernel), (code)) +#define OtherKernelView__(code) PTR_VIEW_METACLASS_DECL( (OtherKernel), (OtherKernelView), (vvi::impl::OtherKernel), (code)) -#define Kernel__(code) VALUE_INTERFACE_METACLASS_DECLARATION((Kernel), (KernelView), (code)) -#define TableKernel__(code) VALUE_INTERFACE_METACLASS_DECLARATION((TableKernel), (TableKernelView), (code)) -#define OtherKernel__(code) VALUE_INTERFACE_METACLASS_DECLARATION((OtherKernel), (OtherKernelView), (code)) +#define Kernel__(code) PTR_VALUE_METACLASS_DECL((Kernel), (KernelView), (code)) +#define TableKernel__(code) PTR_VALUE_METACLASS_DECL((TableKernel), (TableKernelView), (code)) +#define OtherKernel__(code) PTR_VALUE_METACLASS_DECL((OtherKernel), (OtherKernelView), (code)) template -class KernelView__( DEFAULT() ); +class KernelView__( VVI_DEFAULT() ); template -class TableKernelView__( DEFAULT() ); +class TableKernelView__( VVI_DEFAULT() ); template -class OtherKernelView__( DEFAULT() ); +class OtherKernelView__( VVI_DEFAULT() ); //-------------------------------- // Value Interface @@ -74,31 +74,31 @@ class OtherKernelView__( DEFAULT() ); template class Kernel__( public: - VALUE_DEF_CTOR(Kernel) - VALUE_COPY_CTOR(Kernel) - VALUE_ASSIGNEMT_OP() + VVI_VALUE_DEF_CTOR(Kernel) + VVI_VALUE_COPY_CTOR(Kernel) + VVI_VALUE_ASSIGNEMT_OP() - void doSomething() { printf("K H doSomething()\n"); this->sptr_data().doSomething(); } + void doSomething() { printf("K H doSomething()\n"); VVI_IMPL_INST.doSomething(); } ); template class TableKernel__( public: - VALUE_DEF_CTOR(TableKernel) - VALUE_COPY_CTOR(TableKernel) - VALUE_ASSIGNEMT_OP() + VVI_VALUE_DEF_CTOR(TableKernel) + VVI_VALUE_COPY_CTOR(TableKernel) + VVI_VALUE_ASSIGNEMT_OP() - void doSomething() { printf("TK H doSomething()\n"); this->sptr_data().doSomething(); } + void doSomething() { printf("TK H doSomething()\n"); VVI_IMPL_INST.doSomething(); } ); template class OtherKernel__( public: - VALUE_DEF_CTOR(OtherKernel) - VALUE_COPY_CTOR(OtherKernel) - VALUE_ASSIGNEMT_OP() + VVI_VALUE_DEF_CTOR(OtherKernel) + VVI_VALUE_COPY_CTOR(OtherKernel) + VVI_VALUE_ASSIGNEMT_OP() - void doSomething() { printf("OK H doSomething()\n"); this->sptr_data().doSomething(); } + void doSomething() { printf("OK H doSomething()\n"); VVI_IMPL_INST.doSomething(); } ); class Dim1 {}; @@ -116,11 +116,11 @@ TYPED_TEST_CASE(KernelParallelInterface, EXEC_TYPES); TEST(KernelParallelImpl, Impl) { - impl::TableKernel tk_impl; + vvi::impl::TableKernel tk_impl; tk_impl.doSomething(); - impl::Kernel> k_impl; + vvi::impl::Kernel> k_impl; k_impl.doSomething(); diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_metaclass_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc similarity index 77% rename from tests/cpp/Utilities/ValueViewInterface/value_view_metaclass_basic_class_tests.cc rename to tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc index 803a29dd3..3ba6724ed 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_metaclass_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc @@ -50,25 +50,25 @@ SCIP_IMPL_END #ifdef SPHERAL_ENABLE_SCIP class QInt; -#define QIntView__(code) VIEW_INTERFACE_METACLASS_DECLARATION( (QInt), (QIntView), (impl::QInt), (code) ) -#define QInt__(code) VALUE_INTERFACE_METACLASS_DECLARATION( (QInt), (QIntView), (code) ) +#define QIntView__(code) PTR_VIEW_METACLASS_DECL( (QInt), (QIntView), (vvi::impl::QInt), (code) ) +#define QInt__(code) PTR_VALUE_METACLASS_DECL( (QInt), (QIntView), (code) ) class QIntView__( - DEFAULT() // This defines the default behavior of a reference semantics based interface. + VVI_DEFAULT() // This defines the default behavior of a reference semantics based interface. public: - using CoeffsType = typename impl::QInt::CoeffsType; + using CoeffsType = typename ImplType::CoeffsType; ); class QInt__( public: - VALUE_DEF_CTOR(QInt) + VVI_VALUE_DEF_CTOR(QInt) - SPHERAL_HOST_DEVICE double xmin() const { return sptr_data().xmin(); } - SPHERAL_HOST_DEVICE double xmax() const { return sptr_data().xmax(); } + double xmin() const { return sptr_data().xmin(); } + double xmax() const { return sptr_data().xmax(); } - SPHERAL_HOST void initialize(size_t min) const { return sptr_data().initialize(min); } - SPHERAL_HOST void editData(size_t min) const { return sptr_data().editData(min); } - SPHERAL_HOST CoeffsType coeffs() const { return deepCopy(sptr_data().coeffs()); } + void initialize(size_t min) const { return sptr_data().initialize(min); } + void editData(size_t min) const { return sptr_data().editData(min); } + CoeffsType coeffs() const { return deepCopy(sptr_data().coeffs()); } ); #endif //SPHERAL_ENABLE_SCIP diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc similarity index 80% rename from tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc rename to tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc index de6a4c9c3..34a1f3a6b 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc @@ -8,7 +8,7 @@ #include "Utilities/ValueViewInterface.hh" #include "Utilities/ManagedVector.hh" -namespace impl { +SCIP_IMPL_BEGIN class QInt : public Spheral::SPHERALCopyable{ public: @@ -42,50 +42,40 @@ class QInt : public Spheral::SPHERALCopyable{ SPHERAL_HOST_DEVICE double xmax() const { return mXmax; } SPHERAL_HOST_DEVICE CoeffsType const& coeffs() const { return mcoeffs; } - // Define the required interface for a SPHERALCopyable object. - void free() { mcoeffs.free(); } - SPHERAL_HOST_DEVICE QInt& operator=(std::nullptr_t) { mcoeffs=nullptr; return *this; } - SPHERAL_HOST_DEVICE void shallowCopy(QInt const& rhs) { *this = rhs; } }; -} // namespace impl +SCIP_IMPL_END + class QInt; -class QIntView : public Spheral::SpheralViewInterface -{ - VIEW_INTERFACE_METACLASS((QInt), (QIntView), (impl::QInt)) +#define QIntView__(code) REF_VIEW_METACLASS_DECL( (QInt), (QIntView), (vvi::impl::QInt), (code) ) +#define QInt__(code) REF_VALUE_METACLASS_DECL( (QInt), (QIntView), (code) ) + +class QIntView__( public: - friend class QInt; - using CoeffsType = typename impl::QInt::CoeffsType; + using CoeffsType = typename ImplType::CoeffsType; protected: - //VIEW_DEFINE_ALLOC_CTOR(QIntView) // Interal interface for accessing the underlying members of impl::QInt - SMART_PTR_MEMBER_ACCESSOR(CoeffsType, mcoeffs) + VVI_MEMBER_ACCESSOR(CoeffsType, mcoeffs) public: // Forward View capable methods SPHERAL_HOST_DEVICE double xmin() const { return sptr_data().xmin(); } SPHERAL_HOST_DEVICE double xmax() const { return sptr_data().xmax(); } SPHERAL_HOST_DEVICE CoeffsType const& coeffs() const { return sptr_data().coeffs(); } -}; +); - -class QInt : public Spheral::SpheralValueInterface -{ - VALUE_TYPE_ALIASES((QIntView)) +class QInt__( public: - VALUE_DEF_CTOR(QInt) - //VALUE_COPY_CTOR(QInt, impl::QInt) - //VALUE_ASSIGNEMT_OP(QInt, impl::QInt) - VALUE_TOVIEW_OP() + VVI_VALUE_DEF_CTOR(QInt) // Forward Value capable methods SPHERAL_HOST void initialize(size_t min) const { return sptr_data().initialize(min); } SPHERAL_HOST void editData(size_t min) const { return sptr_data().editData(min); } SPHERAL_HOST CoeffsType coeffs() const { return deepCopy(sptr_data().coeffs()); } -}; +); // Setting up G Test for QuadraticInterpolator diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc index 2d0dd94e0..f86f78faf 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc @@ -13,7 +13,7 @@ namespace Spheral { // Implementation of Existing Class in Spheral... //----------------------------------------------------------------------------- -namespace impl { +SCIP_IMPL_BEGIN class FB : chai::CHAIPoly{ public: @@ -49,7 +49,7 @@ class F : public FB, SPHERALCopyable>{ SPHERAL_HOST_DEVICE virtual size_t size() override { return m_data.size(); } }; -} // namespace impl +SCIP_IMPL_END @@ -63,33 +63,34 @@ class F; class FB; // Define Metaclass macros for Value/View relationships -#define FBV__(code) VIEW_INTERFACE_METACLASS_DECLARATION((FB), (FBV), (impl::FB), (code)) -#define FB__(code) VALUE_INTERFACE_METACLASS_DECLARATION((FB), (FBV), (code)) +#define FBV__(code) PTR_VIEW_METACLASS_DECL((FB), (FBV), (vvi::impl::FB), (code)) +#define FB__(code) PTR_VALUE_METACLASS_DECL((FB), (FBV), (code)) -#define FV__(code) VIEW_INTERFACE_METACLASS_DECLARATION((F), (FV), (impl::F), (code)) -#define F__(code) VALUE_INTERFACE_METACLASS_DECLARATION((F), (FV), (code)) +#define FV__(code) PTR_VIEW_METACLASS_DECL((F), (FV), (vvi::impl::F), (code)) +#define F__(code) PTR_VALUE_METACLASS_DECL((F), (FV), (code)) // --- Interface definitions --- class FBV__( - DEFAULT() + VVI_VIEW_DEF_CTOR(FBV) ); // This class instantiation exsists only to fulfil type information // queries that might arise : e.g. `typename FB::ViewType` -class FB__( // Because the underlying impl type is an abstract virtual we can not allow // construction of FB class with default Ctor, Copy Ctor or assignment Op. - DELETED_INTERFACE(FB) +class FB__( + VVI_DELETED_INTERFACE(FB) ); template class FV__( + VVI_VIEW_DEF_CTOR(FV) // Field inherits from FieldBase so we would like to be able to implicitly // upcast a fieldview object to a fieldbaseview. - UPCAST_CONVERSION_OP(FBV) + VVI_UPCAST_CONVERSION_OP(FBV) ); template @@ -97,26 +98,26 @@ class F__( public: // Define Default semantic value type operations for def Ctor, Copy Ctor // and assignment op. - VALUE_DEF_CTOR(F) - VALUE_COPY_CTOR(F) - VALUE_ASSIGNEMT_OP() + VVI_VALUE_DEF_CTOR(F) + VVI_VALUE_COPY_CTOR(F) + VVI_VALUE_ASSIGNEMT_OP() // Custom Ctor, note we need to create the underlying implementation // object on ctor of value interfaces. - F(size_t h, size_t sz) : Base(chai::make_shared(h, sz)) {} + F(size_t h, size_t sz) : VVI_CTOR_ARGS( (h, sz) ) {} // Value semantics dictate that we free underlying data upon destruction. - ~F() { this->sptr()->m_data.free(); } + ~F() { VVI_IMPL_INST.m_data.free(); } // HOST only interface - void resize(size_t sz) { this->sptr_data().resize(sz); } + void resize(size_t sz) { VVI_IMPL_INST.resize(sz); } // Moved from old View Interface pattern. - T* data() {return SPTR_DATA_REF().data(); } - T& operator()(size_t idx) { return this->sptr_data().operator()(idx); } - size_t size() const { return this->sptr_data().size(); } + T* data() {return VVI_IMPL_INST.data(); } + T& operator()(size_t idx) { return VVI_IMPL_INST.operator()(idx); } + size_t size() const { return VVI_IMPL_INST.size(); } - size_t getHash() const { return this->sptr_data().getHash(); } + size_t getHash() const { return VVI_IMPL_INST.getHash(); } ); @@ -198,10 +199,10 @@ GPU_TYPED_TEST(FieldParallelInheritanceTypedTest, AccessPattern) vec_fv.push_back( &f4 ); SPHERAL_ASSERT_EQ(vec_fbv.size(), vec_fv.size()); - for(int i = 0; i < vec_fbv.size(); i++) SPHERAL_ASSERT_EQ(vec_fbv[i]->size(), (*vec_fv[i]).size()); + for(size_t i = 0; i < vec_fbv.size(); i++) SPHERAL_ASSERT_EQ(vec_fbv[i]->size(), (*vec_fv[i]).size()); std::cout << "Arr Map Sz : " << chai::ArrayManager::getInstance()->getPointerMap().size() << std::endl; - for(int i = 0; i < vec_fbv.size(); i++) + for(size_t i = 0; i < vec_fbv.size(); i++) { auto& elem = *vec_fbv[i]; @@ -220,7 +221,7 @@ GPU_TYPED_TEST(FieldParallelInheritanceTypedTest, AccessPattern) EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) printf("--- GPU BEGIN ---\n"); printf("%ld\n", vec_fv.size()); - for(int i = 0; i < vec_fbv.size(); i++) + for(size_t i = 0; i < vec_fbv.size(); i++) { auto& elem_b = *vec_fbv[i]; auto& elem_v = *vec_fv[i]; From 2b5d3e72ff576908e1aea0fe916c9d344fae25a1 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Thu, 22 Aug 2024 21:44:09 -0700 Subject: [PATCH 12/44] SCIP -> VVI; Organizing VVI pattern into header file and impl file, to provide a clearer API for using VVI to users. --- cmake/CMakeDefinitions.cmake | 8 +- cmake/SetupSpheral.cmake | 4 +- src/CMakeLists.txt | 2 + src/Utilities/ValueViewInterface.hh | 247 +++++------------- src/Utilities/ValueViewInterfaceImpl.hh | 147 +++++++++++ src/config.hh.in | 2 +- .../ValueViewInterface/CMakeLists.txt | 2 +- .../value_view_crtp_pattern_tests.cc | 12 +- .../value_view_ptr_basic_class_tests.cc | 10 +- .../value_view_ref_basic_class_tests.cc | 6 +- .../value_view_template_inheritance_tests.cc | 22 +- 11 files changed, 244 insertions(+), 218 deletions(-) create mode 100644 src/Utilities/ValueViewInterfaceImpl.hh diff --git a/cmake/CMakeDefinitions.cmake b/cmake/CMakeDefinitions.cmake index a4bd427e4..a31f75c29 100644 --- a/cmake/CMakeDefinitions.cmake +++ b/cmake/CMakeDefinitions.cmake @@ -16,13 +16,13 @@ else() add_definitions("-DDEBUG=0") endif() -if (SPHERAL_ENABLE_SCIP) - message("-- Semantic Class Interface Pattern (SCIP) : Enabled") +if (SPHERAL_ENABLE_VVI) + message("-- Value-View Interface Pattern (VVI) : Enabled") message("------ WARNING ------") - message("-- SCIP is an experimental implementation necessary for the GPU port. Use with caution!") + message("-- VVI is an experimental implementation necessary for the GPU port. Use with caution!") message("---------------------") else() - message("-- Semantic Class Interface Pattern (SCIP) : Disabled") + message("-- Semantic Class Interface Pattern (VVI) : Disabled") endif() # The DBC flag diff --git a/cmake/SetupSpheral.cmake b/cmake/SetupSpheral.cmake index dd2862edb..b4e22f24c 100644 --- a/cmake/SetupSpheral.cmake +++ b/cmake/SetupSpheral.cmake @@ -88,9 +88,9 @@ if(ENABLE_CUDA) set(CMAKE_CUDA_STANDARD 17) list(APPEND SPHERAL_CXX_DEPENDS cuda) set(SPHERAL_ENABLE_CUDA On) - set(SPHERAL_ENABLE_SCIP On) + set(SPHERAL_ENABLE_VVI On) endif() -message("Enable Semantic Class Interface Pattern (SCIP) : ${SPHERAL_ENABLE_SCIP}") +message("Enable Value-View Interface Pattern (VVI) : ${SPHERAL_ENABLE_VVI}") #-------------------------------------------------------------------------------# # Set a default build type if none was specified diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9d693ad7c..8f61c19cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,6 +71,8 @@ foreach(_package ${_packages}) add_subdirectory(${_package}) endforeach() +blt_print_target_properties(TARGET Spheral_Utilities) + if(NOT ENABLE_DEV_BUILD) # Retrieve the global list populated in spheral_obj_add_library get_property(SPHERAL_OBJ_LIBS GLOBAL PROPERTY SPHERAL_OBJ_LIBS) diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh index a01807138..f17ff9612 100644 --- a/src/Utilities/ValueViewInterface.hh +++ b/src/Utilities/ValueViewInterface.hh @@ -9,18 +9,10 @@ namespace Spheral { -// Macro tool for unpacking types with multiple template arguments. -#define UNPACK( ... ) __VA_ARGS__ - -//----------------------------------------------------------------------------- -// Helper classes and Macros for defining a Value/View pattern in Spheral. -//----------------------------------------------------------------------------- - // An interface class to ensure all required methods are defined by Data // classes that need to be automatically copied by another CHAICopyable or // SPHERALCopyable class. -template -class SPHERALCopyable : public chai::CHAICopyable{}; +using SPHERALCopyable = chai::CHAICopyable; // Interface class for View like objects. // @@ -31,25 +23,25 @@ class SPHERALCopyable : public chai::CHAICopyable{}; // in order to set up a forwarding constructor from the Value class ctor // that passes in a "new DataObject" type. -#if defined(SPHERAL_ENABLE_SCIP) -#define SCIP_IMPL_BEGIN namespace vvi { namespace impl { -#define SCIP_IMPL_END } } // namespace vvi::impl +#if defined(SPHERAL_ENABLE_VVI) +#define VVI_IMPL_BEGIN namespace vvi { namespace impl { +#define VVI_IMPL_END } } // namespace vvi::impl #else -#define SCIP_IMPL_BEGIN -#define SCIP_IMPL_END -#endif +#define VVI_IMPL_BEGIN +#define VVI_IMPL_END +#endif // defined(SPHERAL_ENABLE_VVI) namespace util { template -#if defined(SPHERAL_ENABLE_SCIP) +#if defined(SPHERAL_ENABLE_VVI) using shared_ptr = chai::ManagedSharedPtr; #else using shared_ptr = std::shared_ptr; #endif template -#if defined(SPHERAL_ENABLE_SCIP) +#if defined(SPHERAL_ENABLE_VVI) using vector = ManagedVector; #else using vector = std::vector; @@ -59,155 +51,29 @@ using vector = std::vector; } // namespace Spheral - -namespace vvi { - -template -class ViewInterface : public ::Spheral::util::shared_ptr -{ -private: - using m_ImplType = impl_type; - -public: - using SmartPtrType = ::Spheral::util::shared_ptr; - SPHERAL_HOST_DEVICE SmartPtrType & sptr() { return *this; } - SPHERAL_HOST_DEVICE SmartPtrType const& sptr() const { return *this; } - - SPHERAL_HOST_DEVICE m_ImplType & sptr_data() { return *(SmartPtrType::get()); } \ - SPHERAL_HOST_DEVICE m_ImplType & sptr_data() const { return *(SmartPtrType::get()); } - - SPHERAL_HOST_DEVICE ViewInterface() = default; - SPHERAL_HOST ViewInterface(SmartPtrType&& rhs) : SmartPtrType(std::forward(rhs)) {} -}; - - -// Interface class for Value like objects. -template -class ValueInterface : public view_type -{ -private: - using m_ImplType = typename view_type::ImplType; - using m_SmartPtrType = typename view_type::SmartPtrType; - -protected: - using ViewType = typename view_type::ViewType; - -public: -#if !defined(SPHERAL_ENABLE_SCIP) - SPHERAL_HOST ValueInterface(m_ImplType* rhs) : view_type((rhs)) {} -#endif - SPHERAL_HOST ValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} -}; - -} // namespace vvi - -#define vvi_impl_SPTR_DATA_REF ViewInterfaceType::sptr_data - - - - - - -// Defines a ctor that will take a "new" Data object to create the underlying -// ManagedSmartPtr. -#if !defined(SPHERAL_ENABLE_SCIP) -#define vvi_impl_VIEW_DEFINE_ALLOC_CTOR(view_t) \ -protected: \ - view_t(ImplType* rhs) : Base(SmartPtrType(rhs, [](ImplType *p) { p->free(); } )) {} - //view_t(ImplType* rhs) : Base(SmartPtrType(rhs, [](ImplType *p) { p->free(); } )) {} -#else -#define vvi_impl_VIEW_DEFINE_ALLOC_CTOR(view_t) \ -public: \ - view_t(SmartPtrType&& rhs) : Base(std::forward(rhs)) {} -#endif - -#define vvi_impl_VIEW_SHALLOW_COPY(view_t) \ -public: \ - void shallowCopy(view_t const& rhs) {*this = rhs;} - - - - - -// ---------------------------------------------------------------------------- -// Behavioral macros : These are used to allow for pointer like behavior from -// interface classes -// ---------------------------------------------------------------------------- - -#define POINTER_SYNTAX_OPERATORS() \ -public: \ - SPHERAL_HOST_DEVICE ImplType& operator*() const { return vvi_impl_SPTR_DATA_REF(); } \ - SPHERAL_HOST_DEVICE ImplType* operator->() const { return &vvi_impl_SPTR_DATA_REF(); } - - -#define REF_OPERATOR() \ -public: \ - ViewType operator&() { return toView(); } +#include "ValueViewInterfaceImpl.hh" -#define VVI_UPCAST_CONVERSION_OP(parent_t) \ -public: \ - operator parent_t() const {return parent_t(this->sptr());} - - -#define VVI_DELETED_INTERFACE(type) \ -public: \ - type() = delete; \ - type(type const&) = delete; \ - type& operator=(type const&) = delete; - -#define VVI_DEFAULT() ; - -#define VVI_MEMBER_ACCESSOR(type, var) \ - SPHERAL_HOST_DEVICE type & var() { return Base::get()->var; } \ - SPHERAL_HOST_DEVICE type & var() const { return Base::get()->var; } - -#define VVI_IMPL_INST this->sptr_data() - // ---------------------------------------------------------------------------- -// VIEW class definition macros +// VALUE class declaration macros // ---------------------------------------------------------------------------- -#define VVI_VIEW_DEF_CTOR(view_t) \ - view_t() = default; - -#define VVI_VIEW_COPY_CTOR(view_t) \ - view_t(view_t const& rhs) = default; - -#define VVI_VIEW_ASSIGNEMT_OP() \ - SPHERAL_HOST_DEVICE ViewType& operator=(ViewType const& rhs) = default; - -#define VVI_VIEW_EQ_OP() \ - bool operator==(const ViewType& rhs) const \ - { return sptr_data() == rhs.sptr_data(); } - +#define PTR_VALUE_METACLASS_DECL(value_t, view_t, code) \ + VALUE_METACLASS_DECL_BEGIN((UNPACK value_t), (UNPACK view_t)) \ + REF_OPERATOR() \ + UNPACK code \ + VALUE_METACLASS_DECL_END() +#define REF_VALUE_METACLASS_DECL(value_t, view_t, code) \ + VALUE_METACLASS_DECL_BEGIN((UNPACK value_t), (UNPACK view_t)) \ + UNPACK code \ + VALUE_METACLASS_DECL_END() // ---------------------------------------------------------------------------- // VIEW class declaration macros // ---------------------------------------------------------------------------- -#define VIEW_INTERFACE_METACLASS(value_t, view_t, impl_t) \ -public: \ - using ImplType = UNPACK impl_t; \ - using ViewType = UNPACK view_t; \ - using ValueType = UNPACK value_t; \ -protected: \ - using Base = ::vvi::ViewInterface; \ - using ViewInterfaceType = Base; \ - using SmartPtrType = typename Base::SmartPtrType; \ - friend class UNPACK value_t; \ - vvi_impl_VIEW_DEFINE_ALLOC_CTOR(view_t) \ -private: - -#define VIEW_METACLASS_DECL_BEGIN(value_t, view_t, impl_t) \ -UNPACK view_t : public ::vvi::ViewInterface< UNPACK impl_t> { \ - VIEW_INTERFACE_METACLASS((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) - -#define VIEW_METACLASS_DECL_END() \ -}; - #define PTR_VIEW_METACLASS_DECL(value_t, view_t, impl_t, code) \ VIEW_METACLASS_DECL_BEGIN((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) \ POINTER_SYNTAX_OPERATORS() \ @@ -224,8 +90,6 @@ UNPACK view_t : public ::vvi::ViewInterface< UNPACK impl_t> { \ - - // ---------------------------------------------------------------------------- // VALUE class definition macros // ---------------------------------------------------------------------------- @@ -233,7 +97,7 @@ UNPACK view_t : public ::vvi::ViewInterface< UNPACK impl_t> { \ #define VVI_CTOR(value_t, params, args) \ value_t(UNPACK params) : Base(chai::make_shared(UNPACK args)) {} -#define VVI_CTOR_ARGS(args) \ +#define VVI_VALUE_CTOR_ARGS(args) \ Base(chai::make_shared(UNPACK args)) #define VVI_DTOR(value_t, code) \ @@ -243,11 +107,11 @@ UNPACK view_t : public ::vvi::ViewInterface< UNPACK impl_t> { \ value_t() : Base(chai::make_shared()) {} #define VVI_VALUE_COPY_CTOR(value_t) \ - value_t(value_t const& rhs) : Base(chai::make_shared( deepCopy(rhs.vvi_impl_SPTR_DATA_REF()) )) {} + value_t(value_t const& rhs) : Base(chai::make_shared( deepCopy(rhs.VVI_SPTR_DATA_REF__()) )) {} #define VVI_VALUE_ASSIGNEMT_OP() \ ValueType& operator=(ValueType const& rhs) { \ - ViewType::operator=( ViewType::ViewType(chai::make_shared( deepCopy( rhs.vvi_impl_SPTR_DATA_REF() )))); \ + ViewType::operator=( ViewType::ViewType(chai::make_shared( deepCopy( rhs.VVI_SPTR_DATA_REF__() )))); \ return *this; \ } @@ -266,43 +130,54 @@ UNPACK view_t : public ::vvi::ViewInterface< UNPACK impl_t> { \ // ---------------------------------------------------------------------------- -// VALUE class declaration macros +// VIEW class definition macros // ---------------------------------------------------------------------------- -#define VALUE_INTERFACE_METACLASS(view_t) \ -public: \ - using ViewType = UNPACK view_t; \ - using ValueType = typename ViewType::ValueType; \ - using ImplType = typename ViewType::ImplType; \ -protected: \ - using Base = ::vvi::ValueInterface; \ - using ViewInterfaceType = typename ViewType::ViewInterfaceType; \ - using SmartPtrType = typename ViewType::SmartPtrType; \ -public: \ - VVI_VALUE_TOVIEW_OP() \ -private: +#define VVI_VIEW_DEF_CTOR(view_t) \ + view_t() = default; + +#define VVI_VIEW_COPY_CTOR(view_t) \ + view_t(view_t const& rhs) = default; +#define VVI_VIEW_ASSIGNEMT_OP() \ + SPHERAL_HOST_DEVICE ViewType& operator=(ViewType const& rhs) = default; -#define VALUE_METACLASS_DECL_BEGIN(value_t, view_t) \ -UNPACK value_t : public ::vvi::ValueInterface { \ - VALUE_INTERFACE_METACLASS((UNPACK view_t)) \ +#define VVI_VIEW_EQ_OP() \ + bool operator==(const ViewType& rhs) const \ + { return sptr_data() == rhs.sptr_data(); } -#define VALUE_METACLASS_DECL_END() \ -}; +// ---------------------------------------------------------------------------- +// Special case macros +// ---------------------------------------------------------------------------- -#define PTR_VALUE_METACLASS_DECL(value_t, view_t, code) \ - VALUE_METACLASS_DECL_BEGIN((UNPACK value_t), (UNPACK view_t)) \ - REF_OPERATOR() \ - UNPACK code \ - VALUE_METACLASS_DECL_END() +// This is used for allowing implicit upcast conversions to a Base Class +#define VVI_UPCAST_CONVERSION_OP(parent_t) \ +public: \ + operator parent_t() const {return parent_t(this->sptr());} +// This is used when declaring a Value interface of an abstract class. +#define VVI_DELETED_INTERFACE(type) \ +public: \ + type() = delete; \ + type(type const&) = delete; \ + type& operator=(type const&) = delete; + +// Used for allowing default class behavior from the compiler. Typically this +// will be used for invoking a basic view interface when using poiter syntax. +#define VVI_DEFAULT() ; + +// Creates a function that allows interface objects to access member variables. +// through a function of the same name as the variable itself. +#define VVI_MEMBER_ACCESSOR(type, var) \ + SPHERAL_HOST_DEVICE type & var() { return Base::get()->var; } \ + SPHERAL_HOST_DEVICE type & var() const { return Base::get()->var; } -#define REF_VALUE_METACLASS_DECL(value_t, view_t, code) \ - VALUE_METACLASS_DECL_BEGIN((UNPACK value_t), (UNPACK view_t)) \ - UNPACK code \ - VALUE_METACLASS_DECL_END() +// Grab the actual insatance of the implementation class the interface is accessing. +// Used when calling out to functions in the interface definitions. +//#define VVI_IMPL_INST this->sptr_data() +#define VVI_IMPL_INST VVI_SPTR_DATA_REF__ diff --git a/src/Utilities/ValueViewInterfaceImpl.hh b/src/Utilities/ValueViewInterfaceImpl.hh new file mode 100644 index 000000000..4f0d9be82 --- /dev/null +++ b/src/Utilities/ValueViewInterfaceImpl.hh @@ -0,0 +1,147 @@ +#ifndef __SPHERAL_VALUEVIEWINTERFACEIMPL__ +#define __SPHERAL_VALUEVIEWINTERFACEIMPL__ + +// Macro tool for unpacking types with multiple template arguments. +#define UNPACK( ... ) __VA_ARGS__ + + + +// ---------------------------------------------------------------------------- +// Class definitions for Value and View Intreface class structure. +// ---------------------------------------------------------------------------- + +namespace vvi { + +template +class ViewInterface : public ::Spheral::util::shared_ptr +{ +private: + using m_ImplType = impl_type; + +public: + using SmartPtrType = ::Spheral::util::shared_ptr; + SPHERAL_HOST_DEVICE SmartPtrType & sptr() { return *this; } + SPHERAL_HOST_DEVICE SmartPtrType const& sptr() const { return *this; } + + SPHERAL_HOST_DEVICE m_ImplType & sptr_data() { return *(SmartPtrType::get()); } \ + SPHERAL_HOST_DEVICE m_ImplType & sptr_data() const { return *(SmartPtrType::get()); } + + SPHERAL_HOST_DEVICE ViewInterface() = default; + SPHERAL_HOST ViewInterface(SmartPtrType&& rhs) : SmartPtrType(std::forward(rhs)) {} +}; + + +// Interface class for Value like objects. +template +class ValueInterface : public view_type +{ +private: + using m_ImplType = typename view_type::ImplType; + using m_SmartPtrType = typename view_type::SmartPtrType; + +protected: + using ViewType = typename view_type::ViewType; + +public: +#if !defined(SPHERAL_ENABLE_VVI) + SPHERAL_HOST ValueInterface(m_ImplType* rhs) : view_type((rhs)) {} +#endif + SPHERAL_HOST ValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} +}; + +} // namespace vvi + + +// Internale macro for accessing data +#define VVI_SPTR_DATA_REF__ ViewInterfaceType::sptr_data + + +// ---------------------------------------------------------------------------- +// VALUE class declaration macros +// ---------------------------------------------------------------------------- + +#define VALUE_INTERFACE_METACLASS(view_t) \ +public: \ + using ViewType = UNPACK view_t; \ + using ValueType = typename ViewType::ValueType; \ + using ImplType = typename ViewType::ImplType; \ +protected: \ + using Base = ::vvi::ValueInterface; \ + using ViewInterfaceType = typename ViewType::ViewInterfaceType; \ + using SmartPtrType = typename ViewType::SmartPtrType; \ +public: \ + VVI_VALUE_TOVIEW_OP() \ +private: + + +#define VALUE_METACLASS_DECL_BEGIN(value_t, view_t) \ +UNPACK value_t : public ::vvi::ValueInterface { \ + VALUE_INTERFACE_METACLASS((UNPACK view_t)) \ + + +#define VALUE_METACLASS_DECL_END() \ +}; + + + +// ---------------------------------------------------------------------------- +// VIEW class declaration macros +// ---------------------------------------------------------------------------- + +// Defines a ctor that will take a "new" Data object to create the underlying +// ManagedSmartPtr. +#if !defined(SPHERAL_ENABLE_VVI) +#define VVI_VIEW_DEFINE_ALLOC_CTOR__(view_t) \ +protected: \ + view_t(ImplType* rhs) : Base(SmartPtrType(rhs, [](ImplType *p) { p->free(); } )) {} + //view_t(ImplType* rhs) : Base(SmartPtrType(rhs, [](ImplType *p) { p->free(); } )) {} +#else +#define VVI_VIEW_DEFINE_ALLOC_CTOR__(view_t) \ +public: \ + view_t(SmartPtrType&& rhs) : Base(std::forward(rhs)) {} +#endif + +// TODO: Is this still relevant? +//#define VVI_VIEW_SHALLOW_COPY__(view_t) \ +//public: \ +// void shallowCopy(view_t const& rhs) {*this = rhs;} + +#define VIEW_INTERFACE_METACLASS(value_t, view_t, impl_t) \ +public: \ + using ImplType = UNPACK impl_t; \ + using ViewType = UNPACK view_t; \ + using ValueType = UNPACK value_t; \ +protected: \ + using Base = ::vvi::ViewInterface; \ + using ViewInterfaceType = Base; \ + using SmartPtrType = typename Base::SmartPtrType; \ + friend class UNPACK value_t; \ + VVI_VIEW_DEFINE_ALLOC_CTOR__(view_t) \ +private: + +#define VIEW_METACLASS_DECL_BEGIN(value_t, view_t, impl_t) \ +UNPACK view_t : public ::vvi::ViewInterface< UNPACK impl_t> { \ + VIEW_INTERFACE_METACLASS((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) + +#define VIEW_METACLASS_DECL_END() \ +}; + + +// ---------------------------------------------------------------------------- +// Behavioral macros : These are used to allow for pointer like behavior from +// interface classes +// ---------------------------------------------------------------------------- + +#define POINTER_SYNTAX_OPERATORS() \ +public: \ + SPHERAL_HOST_DEVICE ImplType& operator*() const { return VVI_SPTR_DATA_REF__(); } \ + SPHERAL_HOST_DEVICE ImplType* operator->() const { return &VVI_SPTR_DATA_REF__(); } + + +#define REF_OPERATOR() \ +public: \ + ViewType operator&() { return toView(); } + + +#endif // __SPHERAL_VALUEVIEWINTERFACEIMPL__ + diff --git a/src/config.hh.in b/src/config.hh.in index 04147a4bd..07b4a1d62 100644 --- a/src/config.hh.in +++ b/src/config.hh.in @@ -8,7 +8,7 @@ #cmakedefine SPHERAL_ENABLE_OPENMP #cmakedefine SPHERAL_ENABLE_CUDA -#cmakedefine SPHERAL_ENABLE_SCIP +#cmakedefine SPHERAL_ENABLE_VVI #if defined(SPHERAL_ENABLE_CUDA) && defined(__CUDA_ARCH__) #define SPHERAL_GPU_ACTIVE diff --git a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt index 99e4a1b40..4d6c96085 100644 --- a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt +++ b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt @@ -5,7 +5,7 @@ spheral_add_test( #DEBUG_LINKER ) -if(SPHERAL_ENABLE_SCIP) +if(SPHERAL_ENABLE_VVI) # This test is based off a basic implementation of Utilities/QuadraticInterpolator. spheral_add_test( diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc index 69dfe75f2..263db8ab9 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc @@ -7,10 +7,10 @@ //-------------------------------- // Impl Interface -SCIP_IMPL_BEGIN +VVI_IMPL_BEGIN template -class Kernel : public Spheral::SPHERALCopyable> { +class Kernel : public Spheral::SPHERALCopyable { SPHERAL_HOST_DEVICE Desc& asDesc() { return static_cast(const_cast&>(*this)); @@ -39,7 +39,7 @@ class OtherKernel : public Kernel> { SPHERAL_HOST_DEVICE void doSomething() { printf("OKi HD doSomething()\n"); printf("OtherKernel doSomething\n"); } }; -SCIP_IMPL_END +VVI_IMPL_END //-------------------------------- // View Interface @@ -78,7 +78,7 @@ class Kernel__( VVI_VALUE_COPY_CTOR(Kernel) VVI_VALUE_ASSIGNEMT_OP() - void doSomething() { printf("K H doSomething()\n"); VVI_IMPL_INST.doSomething(); } + void doSomething() { printf("K H doSomething()\n"); VVI_IMPL_INST().doSomething(); } ); template @@ -88,7 +88,7 @@ class TableKernel__( VVI_VALUE_COPY_CTOR(TableKernel) VVI_VALUE_ASSIGNEMT_OP() - void doSomething() { printf("TK H doSomething()\n"); VVI_IMPL_INST.doSomething(); } + void doSomething() { printf("TK H doSomething()\n"); VVI_IMPL_INST().doSomething(); } ); template @@ -98,7 +98,7 @@ class OtherKernel__( VVI_VALUE_COPY_CTOR(OtherKernel) VVI_VALUE_ASSIGNEMT_OP() - void doSomething() { printf("OK H doSomething()\n"); VVI_IMPL_INST.doSomething(); } + void doSomething() { printf("OK H doSomething()\n"); VVI_IMPL_INST().doSomething(); } ); class Dim1 {}; diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc index 3ba6724ed..c0067bb62 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc @@ -7,9 +7,9 @@ #include "Utilities/ValueViewInterface.hh" -SCIP_IMPL_BEGIN +VVI_IMPL_BEGIN -class QInt : public Spheral::SPHERALCopyable{ +class QInt : public Spheral::SPHERALCopyable{ public: SPHERAL_HOST_DEVICE QInt() = default; @@ -43,11 +43,11 @@ class QInt : public Spheral::SPHERALCopyable{ }; -SCIP_IMPL_END +VVI_IMPL_END -#ifdef SPHERAL_ENABLE_SCIP +#ifdef SPHERAL_ENABLE_VVI class QInt; #define QIntView__(code) PTR_VIEW_METACLASS_DECL( (QInt), (QIntView), (vvi::impl::QInt), (code) ) @@ -71,7 +71,7 @@ class QInt__( CoeffsType coeffs() const { return deepCopy(sptr_data().coeffs()); } ); -#endif //SPHERAL_ENABLE_SCIP +#endif //SPHERAL_ENABLE_VVI diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc index 34a1f3a6b..60e420f54 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc @@ -8,9 +8,9 @@ #include "Utilities/ValueViewInterface.hh" #include "Utilities/ManagedVector.hh" -SCIP_IMPL_BEGIN +VVI_IMPL_BEGIN -class QInt : public Spheral::SPHERALCopyable{ +class QInt : public Spheral::SPHERALCopyable { public: SPHERAL_HOST_DEVICE QInt() = default; @@ -44,7 +44,7 @@ class QInt : public Spheral::SPHERALCopyable{ }; -SCIP_IMPL_END +VVI_IMPL_END class QInt; diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc index f86f78faf..2b45bbdf7 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc @@ -13,7 +13,7 @@ namespace Spheral { // Implementation of Existing Class in Spheral... //----------------------------------------------------------------------------- -SCIP_IMPL_BEGIN +VVI_IMPL_BEGIN class FB : chai::CHAIPoly{ public: @@ -29,7 +29,7 @@ class FB : chai::CHAIPoly{ }; template -class F : public FB, SPHERALCopyable>{ +class F : public FB, SPHERALCopyable { public: ManagedVector m_data; @@ -49,10 +49,11 @@ class F : public FB, SPHERALCopyable>{ SPHERAL_HOST_DEVICE virtual size_t size() override { return m_data.size(); } }; -SCIP_IMPL_END +VVI_IMPL_END +#ifdef SPHERAL_ENABLE_VVI //----------------------------------------------------------------------------- // Interface to support porting to the GPU. //----------------------------------------------------------------------------- @@ -104,22 +105,23 @@ class F__( // Custom Ctor, note we need to create the underlying implementation // object on ctor of value interfaces. - F(size_t h, size_t sz) : VVI_CTOR_ARGS( (h, sz) ) {} + F(size_t h, size_t sz) : VVI_VALUE_CTOR_ARGS( (h, sz) ) {} // Value semantics dictate that we free underlying data upon destruction. - ~F() { VVI_IMPL_INST.m_data.free(); } + ~F() { VVI_IMPL_INST().m_data.free(); } // HOST only interface - void resize(size_t sz) { VVI_IMPL_INST.resize(sz); } + void resize(size_t sz) { VVI_IMPL_INST().resize(sz); } // Moved from old View Interface pattern. - T* data() {return VVI_IMPL_INST.data(); } - T& operator()(size_t idx) { return VVI_IMPL_INST.operator()(idx); } - size_t size() const { return VVI_IMPL_INST.size(); } + T* data() {return VVI_IMPL_INST().data(); } + T& operator()(size_t idx) { return VVI_IMPL_INST().operator()(idx); } + size_t size() const { return VVI_IMPL_INST().size(); } - size_t getHash() const { return VVI_IMPL_INST.getHash(); } + size_t getHash() const { return VVI_IMPL_INST().getHash(); } ); +#endif // !defined(SPHERAL_ENABLE_VVI) }// namespace Spheral From 1e33c49ebc35f463bf1124a05fb60595cd00a7c1 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Wed, 28 Aug 2024 10:35:21 -0700 Subject: [PATCH 13/44] namespace changes to match documentation; VVI_VIEW_DEFAULT explicitly defines VIEW Ctor, Copy and Assign. --- src/Utilities/ValueViewInterface.hh | 31 ++++++++++++------- src/Utilities/ValueViewInterfaceImpl.hh | 4 +-- .../value_view_crtp_pattern_tests.cc | 16 +++++----- .../value_view_ptr_basic_class_tests.cc | 6 ++-- .../value_view_ref_basic_class_tests.cc | 4 +-- .../value_view_template_inheritance_tests.cc | 17 +++++----- 6 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh index f17ff9612..c1c000cd6 100644 --- a/src/Utilities/ValueViewInterface.hh +++ b/src/Utilities/ValueViewInterface.hh @@ -7,6 +7,10 @@ #include "chai/ManagedSharedPtr.hpp" #include +#if defined(SPHERAL_ENABLE_VVI) +#define VVI_ENABLED +#endif + namespace Spheral { // An interface class to ensure all required methods are defined by Data @@ -14,6 +18,8 @@ namespace Spheral { // SPHERALCopyable class. using SPHERALCopyable = chai::CHAICopyable; +} // namespace Spheral + // Interface class for View like objects. // // All View classes should inherit from ViewInterface. It sets up useful @@ -22,34 +28,32 @@ using SPHERALCopyable = chai::CHAICopyable; // ViewInterface children will want to use VIEW_DEFINE_ALLOC_CTOR // in order to set up a forwarding constructor from the Value class ctor // that passes in a "new DataObject" type. - -#if defined(SPHERAL_ENABLE_VVI) -#define VVI_IMPL_BEGIN namespace vvi { namespace impl { -#define VVI_IMPL_END } } // namespace vvi::impl +#if defined(VVI_ENABLED) +#define VVI_IMPL_BEGIN namespace vvimpl { +#define VVI_IMPL_END } // namespace vvimpl #else #define VVI_IMPL_BEGIN #define VVI_IMPL_END -#endif // defined(SPHERAL_ENABLE_VVI) +#endif // defined(VVI_ENABLED) -namespace util { +namespace vvi { template -#if defined(SPHERAL_ENABLE_VVI) +#if defined(VVI_ENABLED) using shared_ptr = chai::ManagedSharedPtr; #else using shared_ptr = std::shared_ptr; #endif template -#if defined(SPHERAL_ENABLE_VVI) -using vector = ManagedVector; +#if defined(VVI_ENABLED) +using vector = ::Spheral::ManagedVector; #else using vector = std::vector; #endif -}// namespace util +}// namespace vvi -} // namespace Spheral #include "ValueViewInterfaceImpl.hh" @@ -165,7 +169,10 @@ public: \ // Used for allowing default class behavior from the compiler. Typically this // will be used for invoking a basic view interface when using poiter syntax. -#define VVI_DEFAULT() ; +#define VVI_VIEW_DEFAULT(view_t) \ + VVI_VIEW_DEF_CTOR(view_t) \ + VVI_VIEW_COPY_CTOR(view_t) \ + VVI_VIEW_ASSIGNEMT_OP() // Creates a function that allows interface objects to access member variables. // through a function of the same name as the variable itself. diff --git a/src/Utilities/ValueViewInterfaceImpl.hh b/src/Utilities/ValueViewInterfaceImpl.hh index 4f0d9be82..ed98419ad 100644 --- a/src/Utilities/ValueViewInterfaceImpl.hh +++ b/src/Utilities/ValueViewInterfaceImpl.hh @@ -13,13 +13,13 @@ namespace vvi { template -class ViewInterface : public ::Spheral::util::shared_ptr +class ViewInterface : public vvi::shared_ptr { private: using m_ImplType = impl_type; public: - using SmartPtrType = ::Spheral::util::shared_ptr; + using SmartPtrType = vvi::shared_ptr; SPHERAL_HOST_DEVICE SmartPtrType & sptr() { return *this; } SPHERAL_HOST_DEVICE SmartPtrType const& sptr() const { return *this; } diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc index 263db8ab9..cef966282 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc @@ -51,22 +51,22 @@ class TableKernel; template class OtherKernel; -#define KernelView__(code) PTR_VIEW_METACLASS_DECL( (Kernel), (KernelView), (vvi::impl::Kernel), (code)) -#define TableKernelView__(code) PTR_VIEW_METACLASS_DECL( (TableKernel), (TableKernelView), (vvi::impl::TableKernel), (code)) -#define OtherKernelView__(code) PTR_VIEW_METACLASS_DECL( (OtherKernel), (OtherKernelView), (vvi::impl::OtherKernel), (code)) +#define KernelView__(code) PTR_VIEW_METACLASS_DECL( (Kernel), (KernelView), (vvimpl::Kernel), (code)) +#define TableKernelView__(code) PTR_VIEW_METACLASS_DECL( (TableKernel), (TableKernelView), (vvimpl::TableKernel), (code)) +#define OtherKernelView__(code) PTR_VIEW_METACLASS_DECL( (OtherKernel), (OtherKernelView), (vvimpl::OtherKernel), (code)) #define Kernel__(code) PTR_VALUE_METACLASS_DECL((Kernel), (KernelView), (code)) #define TableKernel__(code) PTR_VALUE_METACLASS_DECL((TableKernel), (TableKernelView), (code)) #define OtherKernel__(code) PTR_VALUE_METACLASS_DECL((OtherKernel), (OtherKernelView), (code)) template -class KernelView__( VVI_DEFAULT() ); +class KernelView__( VVI_VIEW_DEFAULT(KernelView) ); template -class TableKernelView__( VVI_DEFAULT() ); +class TableKernelView__( VVI_VIEW_DEFAULT(TableKernelView) ); template -class OtherKernelView__( VVI_DEFAULT() ); +class OtherKernelView__( VVI_VIEW_DEFAULT(OtherKernelView) ); //-------------------------------- // Value Interface @@ -116,11 +116,11 @@ TYPED_TEST_CASE(KernelParallelInterface, EXEC_TYPES); TEST(KernelParallelImpl, Impl) { - vvi::impl::TableKernel tk_impl; + vvimpl::TableKernel tk_impl; tk_impl.doSomething(); - vvi::impl::Kernel> k_impl; + vvimpl::Kernel> k_impl; k_impl.doSomething(); diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc index c0067bb62..342d97e36 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc @@ -16,7 +16,7 @@ class QInt : public Spheral::SPHERALCopyable{ SPHERAL_HOST_DEVICE QInt(QInt const& rhs) = default; SPHERAL_HOST_DEVICE QInt& operator=(QInt const& rhs) = default; - using CoeffsType = Spheral::util::vector; + using CoeffsType = vvi::vector; double mXmin, mXmax, mXstep; CoeffsType mcoeffs; @@ -50,11 +50,11 @@ VVI_IMPL_END #ifdef SPHERAL_ENABLE_VVI class QInt; -#define QIntView__(code) PTR_VIEW_METACLASS_DECL( (QInt), (QIntView), (vvi::impl::QInt), (code) ) +#define QIntView__(code) PTR_VIEW_METACLASS_DECL( (QInt), (QIntView), (vvimpl::QInt), (code) ) #define QInt__(code) PTR_VALUE_METACLASS_DECL( (QInt), (QIntView), (code) ) class QIntView__( - VVI_DEFAULT() // This defines the default behavior of a reference semantics based interface. + VVI_VIEW_DEFAULT(QIntView) // This defines the default behavior of a reference semantics based interface. public: using CoeffsType = typename ImplType::CoeffsType; ); diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc index 60e420f54..ba9329629 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc @@ -17,7 +17,7 @@ class QInt : public Spheral::SPHERALCopyable { SPHERAL_HOST_DEVICE QInt(QInt const& rhs) = default; SPHERAL_HOST_DEVICE QInt& operator=(QInt const& rhs) = default; - using CoeffsType = Spheral::util::vector; + using CoeffsType = vvi::vector; double mXmin, mXmax, mXstep; CoeffsType mcoeffs; @@ -49,7 +49,7 @@ VVI_IMPL_END class QInt; -#define QIntView__(code) REF_VIEW_METACLASS_DECL( (QInt), (QIntView), (vvi::impl::QInt), (code) ) +#define QIntView__(code) REF_VIEW_METACLASS_DECL( (QInt), (QIntView), (vvimpl::QInt), (code) ) #define QInt__(code) REF_VALUE_METACLASS_DECL( (QInt), (QIntView), (code) ) class QIntView__( diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc index 2b45bbdf7..3618013c2 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc @@ -29,9 +29,9 @@ class FB : chai::CHAIPoly{ }; template -class F : public FB, SPHERALCopyable { +class F : public FB { public: - ManagedVector m_data; + vvi::vector m_data; SPHERAL_HOST_DEVICE F() : FB() {} F(size_t h, size_t sz) : FB(h), m_data(sz) {} @@ -64,17 +64,17 @@ class F; class FB; // Define Metaclass macros for Value/View relationships -#define FBV__(code) PTR_VIEW_METACLASS_DECL((FB), (FBV), (vvi::impl::FB), (code)) +#define FBV__(code) PTR_VIEW_METACLASS_DECL((FB), (FBV), (vvimpl::FB), (code)) #define FB__(code) PTR_VALUE_METACLASS_DECL((FB), (FBV), (code)) -#define FV__(code) PTR_VIEW_METACLASS_DECL((F), (FV), (vvi::impl::F), (code)) +#define FV__(code) PTR_VIEW_METACLASS_DECL((F), (FV), (vvimpl::F), (code)) #define F__(code) PTR_VALUE_METACLASS_DECL((F), (FV), (code)) // --- Interface definitions --- class FBV__( - VVI_VIEW_DEF_CTOR(FBV) + VVI_VIEW_DEFAULT(FBV) ); // This class instantiation exsists only to fulfil type information @@ -88,7 +88,7 @@ class FB__( template class FV__( - VVI_VIEW_DEF_CTOR(FV) + VVI_VIEW_DEFAULT(FV) // Field inherits from FieldBase so we would like to be able to implicitly // upcast a fieldview object to a fieldbaseview. VVI_UPCAST_CONVERSION_OP(FBV) @@ -149,6 +149,7 @@ GPU_TYPED_TEST(FieldParallelInheritanceTypedTest, AccessPattern) using WORK_EXEC_POLICY = TypeParam; Spheral::F f(2, 200); + auto f_2 = f; auto f_v = &f; Spheral::FB::ViewType fb_v = f_v; @@ -183,9 +184,9 @@ GPU_TYPED_TEST(FieldParallelInheritanceTypedTest, AccessPattern) Spheral::F f3(3, 3); Spheral::F f4(4, 4); - Spheral::ManagedVector vec_fbv; + vvi::vector vec_fbv; vec_fbv.reserve(5); - Spheral::ManagedVector::ViewType> vec_fv; + vvi::vector::ViewType> vec_fv; vec_fv.reserve(5); vec_fbv.push_back( &f0 ); From 55f51746fb252b9cd47c70aceedbb5943b1e3b0e Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Thu, 29 Aug 2024 21:54:15 -0700 Subject: [PATCH 14/44] Macros for wimplifying deepCopy and compare methods in Impl classes; Better default behavior for Value Interfaces, def copy-ctor, assign op and eq op behavior is baked in for free in the ValueInterface class. --- src/Utilities/ManagedVector.hh | 35 ++++-- src/Utilities/ValueViewInterface.hh | 89 +++++--------- src/Utilities/ValueViewInterfaceImpl.hh | 116 +++++++++++++++++- src/config.hh.in | 4 + .../value_view_crtp_pattern_tests.cc | 9 -- .../value_view_ptr_basic_class_tests.cc | 13 ++ .../value_view_template_inheritance_tests.cc | 22 ++-- 7 files changed, 193 insertions(+), 95 deletions(-) diff --git a/src/Utilities/ManagedVector.hh b/src/Utilities/ManagedVector.hh index 84342e939..9b99d7d23 100644 --- a/src/Utilities/ManagedVector.hh +++ b/src/Utilities/ManagedVector.hh @@ -41,6 +41,9 @@ class ManagedVector; template ManagedVector deepCopy(ManagedVector const& array); +template +bool compare(ManagedVector const&, ManagedVector const&); + template class ManagedVector: private chai::ManagedArray{ @@ -113,11 +116,11 @@ public: #ifdef MV_VALUE_SEMANTICS SPHERAL_HOST_DEVICE constexpr inline ManagedVector(ManagedVector const& rhs) noexcept : ManagedVector(rhs.m_size) - { + {printf("MV Copy w/ Value Semantics.\n"); for (size_t i = 0; i < m_size; i++) new (&MA::operator[](i)) DataType(rhs[i]); } #else - SPHERAL_HOST_DEVICE constexpr inline ManagedVector(ManagedVector const& rhs) noexcept : MA(rhs), m_size(rhs.m_size) {} + SPHERAL_HOST_DEVICE constexpr inline ManagedVector(ManagedVector const& rhs) noexcept : MA(rhs), m_size(rhs.m_size) {printf("MV Copy w/ Ref Semantics.\n");} #endif // --------------------- @@ -303,20 +306,26 @@ private: template friend ManagedVector deepCopy(ManagedVector const& array); - SPHERAL_HOST_DEVICE - friend bool compare(ManagedVector const& lhs, ManagedVector const& rhs) - { - if (lhs.m_size != rhs.m_size) return false; - for (size_t i = 0; i < lhs.m_size; i++) { - if (lhs[i] != rhs[i]) { - return false; - } - } - return true; - } + template + friend bool compare(ManagedVector const& lhs, ManagedVector const& rhs); }; +template +inline +bool compare(ManagedVector const& lhs, ManagedVector const& rhs) +{ + std::cout << "check\n"; + if (lhs.size() != rhs.size()) return false; + if (lhs.size() == 0) return true; + for (size_t i = 0; i < lhs.size(); i++) { + if (lhs[i] != rhs[i]) { + return false; + } + } + return true; +} + template inline diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh index c1c000cd6..9e570df38 100644 --- a/src/Utilities/ValueViewInterface.hh +++ b/src/Utilities/ValueViewInterface.hh @@ -1,15 +1,13 @@ #ifndef __SPHERAL_VALUEVIEWINTERFACE__ #define __SPHERAL_VALUEVIEWINTERFACE__ -//#include "Utilities/SharedPtr.hh" -#include "ManagedVector.hh" #include "config.hh" +#include "ManagedVector.hh" #include "chai/ManagedSharedPtr.hpp" +#include "ValueViewInterfaceImpl.hh" + #include -#if defined(SPHERAL_ENABLE_VVI) -#define VVI_ENABLED -#endif namespace Spheral { @@ -20,14 +18,10 @@ using SPHERALCopyable = chai::CHAICopyable; } // namespace Spheral -// Interface class for View like objects. -// -// All View classes should inherit from ViewInterface. It sets up useful -// type aliases and forwarding constructors to the underlying Data class. -// -// ViewInterface children will want to use VIEW_DEFINE_ALLOC_CTOR -// in order to set up a forwarding constructor from the Value class ctor -// that passes in a "new DataObject" type. +// ---------------------------------------------------------------------------- +// IMPL class declaration macros +// ---------------------------------------------------------------------------- + #if defined(VVI_ENABLED) #define VVI_IMPL_BEGIN namespace vvimpl { #define VVI_IMPL_END } // namespace vvimpl @@ -36,27 +30,17 @@ using SPHERALCopyable = chai::CHAICopyable; #define VVI_IMPL_END #endif // defined(VVI_ENABLED) -namespace vvi { - -template -#if defined(VVI_ENABLED) -using shared_ptr = chai::ManagedSharedPtr; -#else -using shared_ptr = std::shared_ptr; -#endif - -template -#if defined(VVI_ENABLED) -using vector = ::Spheral::ManagedVector; -#else -using vector = std::vector; -#endif - -}// namespace vvi - - -#include "ValueViewInterfaceImpl.hh" +#define VVI_IMPL_DEEPCOPY(impl_t, ...) \ + friend impl_t deepCopy(impl_t const& rhs) { \ + impl_t result(rhs); \ + VVI_IDC_EXPAND__(__VA_ARGS__) \ + return result; \ + } +#define VVI_IMPL_COMPARE(impl_t, ...) \ + friend bool compare(impl_t const& lhs, impl_t const& rhs) { \ + return VVI_ICOM_EXPAND__(__VA_ARGS__); \ + } // ---------------------------------------------------------------------------- // VALUE class declaration macros @@ -90,47 +74,43 @@ using vector = std::vector; VIEW_METACLASS_DECL_END() - - - - // ---------------------------------------------------------------------------- // VALUE class definition macros // ---------------------------------------------------------------------------- -#define VVI_CTOR(value_t, params, args) \ - value_t(UNPACK params) : Base(chai::make_shared(UNPACK args)) {} - +//#define VVI_VALUE_CTOR(value_t, params, args) \ +// value_t(UNPACK params) : Base(chai::make_shared(UNPACK args)) {} +// #define VVI_VALUE_CTOR_ARGS(args) \ Base(chai::make_shared(UNPACK args)) -#define VVI_DTOR(value_t, code) \ - ~value_t() { UNPACK code } - +//#define VVI_VALUE_DTOR(value_t, code) \ +// ~value_t() { UNPACK code } +// #define VVI_VALUE_DEF_CTOR(value_t) \ value_t() : Base(chai::make_shared()) {} #define VVI_VALUE_COPY_CTOR(value_t) \ - value_t(value_t const& rhs) : Base(chai::make_shared( deepCopy(rhs.VVI_SPTR_DATA_REF__()) )) {} + value_t(value_t const& rhs) : Base(rhs) {} + //value_t(value_t const& rhs) : Base(chai::make_shared( deepCopy(rhs.VVI_SPTR_DATA_REF__()) )) {} + //value_t(value_t const& rhs) : Base( deepCopy(rhs.VVI_SPTR_DATA_REF__()) ) {} #define VVI_VALUE_ASSIGNEMT_OP() \ ValueType& operator=(ValueType const& rhs) { \ - ViewType::operator=( ViewType::ViewType(chai::make_shared( deepCopy( rhs.VVI_SPTR_DATA_REF__() )))); \ + Base::operator=(rhs); \ return *this; \ } + //ViewType::operator=( ViewType::ViewType(chai::make_shared( deepCopy( rhs.VVI_SPTR_DATA_REF__() )))); \ #define VVI_VALUE_EQ_OP() \ bool operator==(const ValueType& rhs) const \ - { return compare(sptr_data(), rhs.sptr_data()); } + { return compare(VVI_SPTR_DATA_REF__(), rhs.VVI_SPTR_DATA_REF__()); } -#define VVI_VALUE_TOVIEW_OP() \ - ViewType toView() { return ViewType(*this); } - -#define VVI_VALUE_TYPE_DEFAULT_ASSIGNMENT_OP(value_t) \ - value_t& operator=(value_t const& rhs) { \ - ViewType::operator=( ViewType( new ImplType(deepCopy(rhs.ViewInterfaceType::sptr_data())) ) ); \ - return *this; \ - } +//#define VVI_VALUE_TYPE_DEFAULT_ASSIGNMENT_OP(value_t) \ +// value_t& operator=(value_t const& rhs) { \ +// ViewType::operator=( ViewType( new ImplType(deepCopy(rhs.ViewInterfaceType::sptr_data())) ) ); \ +// return *this; \ +// } // ---------------------------------------------------------------------------- @@ -188,5 +168,4 @@ public: \ - #endif // __SPHERAL_VALUEVIEWINTERFACE__ diff --git a/src/Utilities/ValueViewInterfaceImpl.hh b/src/Utilities/ValueViewInterfaceImpl.hh index ed98419ad..0ffd1fc23 100644 --- a/src/Utilities/ValueViewInterfaceImpl.hh +++ b/src/Utilities/ValueViewInterfaceImpl.hh @@ -4,6 +4,9 @@ // Macro tool for unpacking types with multiple template arguments. #define UNPACK( ... ) __VA_ARGS__ +// Macro tool for creating macro functions with an unknown number of arguments (Max 9) +#define MKFNS(fn,...) MKFN_N(fn,##__VA_ARGS__,9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__) +#define MKFN_N(fn, n1, n2, n3, n4, n5, n6, n7, n8, n9, n, ...) fn##n // ---------------------------------------------------------------------------- @@ -12,6 +15,21 @@ namespace vvi { +template +#if defined(VVI_ENABLED) +using shared_ptr = chai::ManagedSharedPtr; +#else +using shared_ptr = std::shared_ptr; +#endif + +template +#if defined(VVI_ENABLED) +using vector = ::Spheral::ManagedVector; +#else +using vector = std::vector; +#endif + + template class ViewInterface : public vvi::shared_ptr { @@ -44,33 +62,123 @@ protected: public: #if !defined(SPHERAL_ENABLE_VVI) - SPHERAL_HOST ValueInterface(m_ImplType* rhs) : view_type((rhs)) {} + ValueInterface(m_ImplType* rhs) : view_type((rhs)) {} #endif - SPHERAL_HOST ValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} + ValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} + ValueInterface(ValueInterface const& rhs) : ValueInterface(chai::make_shared( deepCopy(rhs.sptr_data()) )) {} + ValueInterface& operator=(ValueInterface const& rhs) { ViewType::operator=( chai::make_shared( deepCopy( rhs.sptr_data() ) ) ); return *this; } + bool operator==(ValueInterface const& rhs) const { return compare(this->sptr_data(), rhs.sptr_data()); } + }; +namespace detail { + + template + bool compare(T const& lhs, T const& rhs) + { return lhs == rhs; } + + template + bool compare(Spheral::ManagedVector const& lhs, Spheral::ManagedVector const& rhs) + { return ::Spheral::compare(lhs, rhs); } + +} + } // namespace vvi // Internale macro for accessing data #define VVI_SPTR_DATA_REF__ ViewInterfaceType::sptr_data +// ---------------------------------------------------------------------------- +// IMPL class declaration macros +// ---------------------------------------------------------------------------- + +// DeepCopy macro helpers + +#define VIDCH__(arg) result.arg = deepCopy(rhs.arg); + +#define VVI_IDC_EXPAND__(...) MKFNS(VVI_IDC_EXPAND__,##__VA_ARGS__) +#define VVI_IDC_EXPAND__1(arg1) \ + VIDCH__(arg1) +#define VVI_IDC_EXPAND__2(arg1, arg2) \ + VIDCH__(arg1) VIDCH__(arg2) +#define VVI_IDC_EXPAND__3(arg1, arg2, arg3) \ + VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) +#define VVI_IDC_EXPAND__4(arg1, arg2, arg3, arg4) \ + VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ + VIDCH__(arg4) +#define VVI_IDC_EXPAND__5(arg1, arg2, arg3, arg4, arg5) \ + VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ + VIDCH__(arg4) VIDCH__(arg5) +#define VVI_IDC_EXPAND__6(arg1, arg2, arg3, arg4, arg5, arg6) \ + VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ + VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) +#define VVI_IDC_EXPAND__7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ + VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) \ + VIDCH__(arg7) +#define VVI_IDC_EXPAND__8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ + VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ + VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) \ + VIDCH__(arg7) VIDCH__(arg8) +#define VVI_IDC_EXPAND__9(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ + VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ + VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) \ + VIDCH__(arg7) VIDCH__(arg8) VIDCH__(arg9) + +// Compare macro helpers + +#define VICOMH__(arg) vvi::detail::compare(lhs.arg, rhs.arg) + +#define VVI_ICOM_EXPAND__(...) MKFNS(VVI_ICOM_EXPAND__,##__VA_ARGS__) +#define VVI_ICOM_EXPAND__1(arg1) \ + VICOMH__(arg1) +#define VVI_ICOM_EXPAND__2(arg1, arg2) \ + VICOMH__(arg1) && VICOMH__(arg2) +#define VVI_ICOM_EXPAND__3(arg1, arg2, arg3) \ + VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) +#define VVI_ICOM_EXPAND__4(arg1, arg2, arg3, arg4) \ + VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ + VICOMH__(arg4) +#define VVI_ICOM_EXPAND__5(arg1, arg2, arg3, arg4, arg5) \ + VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ + VICOMH__(arg4) && VICOMH__(arg5) +#define VVI_ICOM_EXPAND__6(arg1, arg2, arg3, arg4, arg5, arg6) \ + VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) &&\ + VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) +#define VVI_ICOM_EXPAND__7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ + VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) && \ + VICOMH__(arg7) +#define VVI_ICOM_EXPAND__8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ + VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ + VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) && \ + VICOMH__(arg7) && VICOMH__(arg8) +#define VVI_ICOM_EXPAND__9(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ + VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ + VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) && \ + VICOMH__(arg7) && VICOMH__(arg8) && VICOMH__(arg9) + // ---------------------------------------------------------------------------- // VALUE class declaration macros // ---------------------------------------------------------------------------- +#define VVI_VALUE_TOVIEW_OP__() \ + ViewType toView() { return ViewType(*this); } + + #define VALUE_INTERFACE_METACLASS(view_t) \ public: \ using ViewType = UNPACK view_t; \ using ValueType = typename ViewType::ValueType; \ using ImplType = typename ViewType::ImplType; \ + using ViewInterfaceType = typename ViewType::ViewInterfaceType; \ protected: \ using Base = ::vvi::ValueInterface; \ - using ViewInterfaceType = typename ViewType::ViewInterfaceType; \ using SmartPtrType = typename ViewType::SmartPtrType; \ public: \ - VVI_VALUE_TOVIEW_OP() \ + VVI_VALUE_TOVIEW_OP__() \ private: diff --git a/src/config.hh.in b/src/config.hh.in index 07b4a1d62..75c7c9186 100644 --- a/src/config.hh.in +++ b/src/config.hh.in @@ -14,6 +14,10 @@ #define SPHERAL_GPU_ACTIVE #endif // SPHERAL_ENABLE_CUDA && __CUDACC__ +#if defined(SPHERAL_ENABLE_VVI) +#define VVI_ENABLED +#endif + #define SPHERAL_HOST_DEVICE RAJA_HOST_DEVICE #define SPHERAL_HOST RAJA_HOST #define SPHERAL_DEVICE RAJA_DEVICE diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc index cef966282..3e61888ce 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc @@ -75,9 +75,6 @@ template class Kernel__( public: VVI_VALUE_DEF_CTOR(Kernel) - VVI_VALUE_COPY_CTOR(Kernel) - VVI_VALUE_ASSIGNEMT_OP() - void doSomething() { printf("K H doSomething()\n"); VVI_IMPL_INST().doSomething(); } ); @@ -85,9 +82,6 @@ template class TableKernel__( public: VVI_VALUE_DEF_CTOR(TableKernel) - VVI_VALUE_COPY_CTOR(TableKernel) - VVI_VALUE_ASSIGNEMT_OP() - void doSomething() { printf("TK H doSomething()\n"); VVI_IMPL_INST().doSomething(); } ); @@ -95,9 +89,6 @@ template class OtherKernel__( public: VVI_VALUE_DEF_CTOR(OtherKernel) - VVI_VALUE_COPY_CTOR(OtherKernel) - VVI_VALUE_ASSIGNEMT_OP() - void doSomething() { printf("OK H doSomething()\n"); VVI_IMPL_INST().doSomething(); } ); diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc index 342d97e36..8c2c188ba 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc @@ -41,6 +41,8 @@ class QInt : public Spheral::SPHERALCopyable{ SPHERAL_HOST_DEVICE double xmax() const { return mXmax; } SPHERAL_HOST_DEVICE CoeffsType const& coeffs() const { return mcoeffs; } + VVI_IMPL_DEEPCOPY(QInt, mcoeffs) + VVI_IMPL_COMPARE(QInt, mcoeffs, mXmin, mXmax, mXstep) }; VVI_IMPL_END @@ -62,6 +64,9 @@ class QIntView__( class QInt__( public: VVI_VALUE_DEF_CTOR(QInt) + //VVI_VALUE_COPY_CTOR(QInt) + //VVI_VALUE_ASSIGNEMT_OP() + //VVI_VALUE_EQ_OP() double xmin() const { return sptr_data().xmin(); } double xmax() const { return sptr_data().xmax(); } @@ -102,6 +107,14 @@ GPU_TYPED_TEST(QIntExampleTypedTest, SmartCopySemantics) qq_int.initialize(4); SPHERAL_ASSERT_EQ(qq_int_v->coeffs().size(), 10); + //QInt qq_int2 = qq_int; + QInt qq_int2; + qq_int2 = qq_int; + SPHERAL_ASSERT_NE(qq_int.VVI_IMPL_INST().coeffs().begin(), qq_int2.VVI_IMPL_INST().coeffs().begin()); + SPHERAL_ASSERT_EQ(qq_int_v->coeffs().begin(), qq_int_v2->coeffs().begin()); + SPHERAL_ASSERT_TRUE(qq_int == qq_int2); + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) printf("xmin : %lf\n", qq_int_v->xmin()); SPHERAL_ASSERT_EQ(qq_int_v->xmin(), 4); diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc index 3618013c2..92fa09820 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc @@ -28,6 +28,7 @@ class FB : chai::CHAIPoly{ SPHERAL_HOST_DEVICE virtual size_t size() = 0; }; + template class F : public FB { public: @@ -39,14 +40,11 @@ class F : public FB { SPHERAL_HOST_DEVICE T* data() { return &m_data[0]; } SPHERAL_HOST_DEVICE T& operator()(size_t idx) { return m_data[idx]; } - friend F deepCopy(F const& rhs) { - F result(rhs); - result.m_data = deepCopy(rhs.m_data); - return result; - } - virtual void resize(size_t sz) override {std::cout << "Resize : " << sz << std::endl; m_data.resize(sz); } SPHERAL_HOST_DEVICE virtual size_t size() override { return m_data.size(); } + + VVI_IMPL_DEEPCOPY(F, m_data) + VVI_IMPL_COMPARE(F, m_data, hash) }; VVI_IMPL_END @@ -97,19 +95,13 @@ class FV__( template class F__( public: - // Define Default semantic value type operations for def Ctor, Copy Ctor - // and assignment op. - VVI_VALUE_DEF_CTOR(F) - VVI_VALUE_COPY_CTOR(F) - VVI_VALUE_ASSIGNEMT_OP() - // Custom Ctor, note we need to create the underlying implementation // object on ctor of value interfaces. F(size_t h, size_t sz) : VVI_VALUE_CTOR_ARGS( (h, sz) ) {} // Value semantics dictate that we free underlying data upon destruction. ~F() { VVI_IMPL_INST().m_data.free(); } - + // HOST only interface void resize(size_t sz) { VVI_IMPL_INST().resize(sz); } @@ -149,7 +141,9 @@ GPU_TYPED_TEST(FieldParallelInheritanceTypedTest, AccessPattern) using WORK_EXEC_POLICY = TypeParam; Spheral::F f(2, 200); - auto f_2 = f; + //auto f_2 = f; + Spheral::F f_2(2, 200); + std::cout << (f == f_2) << std::endl; auto f_v = &f; Spheral::FB::ViewType fb_v = f_v; From 383fed823616ce841a3308c4287d42900eb0fbf4 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Fri, 30 Aug 2024 06:49:37 -0700 Subject: [PATCH 15/44] Empty DEEPCOPY & COMPARE member case; adding DECL_DEFAULT example in crtp; Cleaning up VVI_VALUE_ macros. --- src/Utilities/ValueViewInterface.hh | 27 +++++----- src/Utilities/ValueViewInterfaceImpl.hh | 51 ++++++++++--------- .../value_view_crtp_pattern_tests.cc | 46 +++++++++-------- .../value_view_ptr_basic_class_tests.cc | 7 +-- 4 files changed, 65 insertions(+), 66 deletions(-) diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh index 9e570df38..62a8d2ed9 100644 --- a/src/Utilities/ValueViewInterface.hh +++ b/src/Utilities/ValueViewInterface.hh @@ -33,13 +33,13 @@ using SPHERALCopyable = chai::CHAICopyable; #define VVI_IMPL_DEEPCOPY(impl_t, ...) \ friend impl_t deepCopy(impl_t const& rhs) { \ impl_t result(rhs); \ - VVI_IDC_EXPAND__(__VA_ARGS__) \ + VVI_IDC_EXPAND__( void, ##__VA_ARGS__ ) \ return result; \ } #define VVI_IMPL_COMPARE(impl_t, ...) \ friend bool compare(impl_t const& lhs, impl_t const& rhs) { \ - return VVI_ICOM_EXPAND__(__VA_ARGS__); \ + return VVI_ICOM_EXPAND__( void, ##__VA_ARGS__); \ } // ---------------------------------------------------------------------------- @@ -73,38 +73,35 @@ using SPHERALCopyable = chai::CHAICopyable; UNPACK code \ VIEW_METACLASS_DECL_END() +#define PTR_VIEW_METACLASS_DECL_DEFAULT(value_t, view_t, impl_t) \ + PTR_VIEW_METACLASS_DECL( value_t, view_t, impl_t, ( VVI_VIEW_DEFAULT(UNPACK view_t) ) ) + //class VIEW_METACLASS_DECL_BEGIN((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) \ + //POINTER_SYNTAX_OPERATORS() \ + //VVI_VIEW_DEFAULT(view_t) \ + //VIEW_METACLASS_DECL_END() // ---------------------------------------------------------------------------- // VALUE class definition macros // ---------------------------------------------------------------------------- -//#define VVI_VALUE_CTOR(value_t, params, args) \ -// value_t(UNPACK params) : Base(chai::make_shared(UNPACK args)) {} -// #define VVI_VALUE_CTOR_ARGS(args) \ Base(chai::make_shared(UNPACK args)) -//#define VVI_VALUE_DTOR(value_t, code) \ -// ~value_t() { UNPACK code } -// #define VVI_VALUE_DEF_CTOR(value_t) \ - value_t() : Base(chai::make_shared()) {} + value_t() : Base() {} #define VVI_VALUE_COPY_CTOR(value_t) \ value_t(value_t const& rhs) : Base(rhs) {} - //value_t(value_t const& rhs) : Base(chai::make_shared( deepCopy(rhs.VVI_SPTR_DATA_REF__()) )) {} - //value_t(value_t const& rhs) : Base( deepCopy(rhs.VVI_SPTR_DATA_REF__()) ) {} #define VVI_VALUE_ASSIGNEMT_OP() \ ValueType& operator=(ValueType const& rhs) { \ Base::operator=(rhs); \ return *this; \ } - //ViewType::operator=( ViewType::ViewType(chai::make_shared( deepCopy( rhs.VVI_SPTR_DATA_REF__() )))); \ -#define VVI_VALUE_EQ_OP() \ - bool operator==(const ValueType& rhs) const \ - { return compare(VVI_SPTR_DATA_REF__(), rhs.VVI_SPTR_DATA_REF__()); } +//#define VVI_VALUE_EQ_OP() \ +// bool operator==(const ValueType& rhs) const \ +// { return compare(VVI_SPTR_DATA_REF__(), rhs.VVI_SPTR_DATA_REF__()); } //#define VVI_VALUE_TYPE_DEFAULT_ASSIGNMENT_OP(value_t) \ // value_t& operator=(value_t const& rhs) { \ diff --git a/src/Utilities/ValueViewInterfaceImpl.hh b/src/Utilities/ValueViewInterfaceImpl.hh index 0ffd1fc23..2b9109c7d 100644 --- a/src/Utilities/ValueViewInterfaceImpl.hh +++ b/src/Utilities/ValueViewInterfaceImpl.hh @@ -4,11 +4,6 @@ // Macro tool for unpacking types with multiple template arguments. #define UNPACK( ... ) __VA_ARGS__ -// Macro tool for creating macro functions with an unknown number of arguments (Max 9) -#define MKFNS(fn,...) MKFN_N(fn,##__VA_ARGS__,9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__) -#define MKFN_N(fn, n1, n2, n3, n4, n5, n6, n7, n8, n9, n, ...) fn##n - - // ---------------------------------------------------------------------------- // Class definitions for Value and View Intreface class structure. // ---------------------------------------------------------------------------- @@ -60,6 +55,8 @@ private: protected: using ViewType = typename view_type::ViewType; + ValueInterface() : ValueInterface(chai::make_shared()) {} + public: #if !defined(SPHERAL_ENABLE_VVI) ValueInterface(m_ImplType* rhs) : view_type((rhs)) {} @@ -68,7 +65,6 @@ public: ValueInterface(ValueInterface const& rhs) : ValueInterface(chai::make_shared( deepCopy(rhs.sptr_data()) )) {} ValueInterface& operator=(ValueInterface const& rhs) { ViewType::operator=( chai::make_shared( deepCopy( rhs.sptr_data() ) ) ); return *this; } bool operator==(ValueInterface const& rhs) const { return compare(this->sptr_data(), rhs.sptr_data()); } - }; namespace detail { @@ -93,35 +89,41 @@ namespace detail { // IMPL class declaration macros // ---------------------------------------------------------------------------- +// Macro tool for creating macro functions with an unknown number of arguments (Max 9) +#define MKFNS(fn,...) MKFN_N(fn,##__VA_ARGS__, 9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__) +#define MKFN_N(fn, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n, ...) fn##n + + // DeepCopy macro helpers #define VIDCH__(arg) result.arg = deepCopy(rhs.arg); #define VVI_IDC_EXPAND__(...) MKFNS(VVI_IDC_EXPAND__,##__VA_ARGS__) -#define VVI_IDC_EXPAND__1(arg1) \ +#define VVI_IDC_EXPAND__0(v) +#define VVI_IDC_EXPAND__1(void, arg1) \ VIDCH__(arg1) -#define VVI_IDC_EXPAND__2(arg1, arg2) \ +#define VVI_IDC_EXPAND__2(void, arg1, arg2) \ VIDCH__(arg1) VIDCH__(arg2) -#define VVI_IDC_EXPAND__3(arg1, arg2, arg3) \ +#define VVI_IDC_EXPAND__3(void, arg1, arg2, arg3) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) -#define VVI_IDC_EXPAND__4(arg1, arg2, arg3, arg4) \ +#define VVI_IDC_EXPAND__4(void, arg1, arg2, arg3, arg4) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) -#define VVI_IDC_EXPAND__5(arg1, arg2, arg3, arg4, arg5) \ +#define VVI_IDC_EXPAND__5(void, arg1, arg2, arg3, arg4, arg5) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) VIDCH__(arg5) -#define VVI_IDC_EXPAND__6(arg1, arg2, arg3, arg4, arg5, arg6) \ +#define VVI_IDC_EXPAND__6(void, arg1, arg2, arg3, arg4, arg5, arg6) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) -#define VVI_IDC_EXPAND__7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ +#define VVI_IDC_EXPAND__7(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) \ VIDCH__(arg7) -#define VVI_IDC_EXPAND__8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ +#define VVI_IDC_EXPAND__8(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) \ VIDCH__(arg7) VIDCH__(arg8) -#define VVI_IDC_EXPAND__9(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ +#define VVI_IDC_EXPAND__9(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) \ VIDCH__(arg7) VIDCH__(arg8) VIDCH__(arg9) @@ -131,30 +133,31 @@ namespace detail { #define VICOMH__(arg) vvi::detail::compare(lhs.arg, rhs.arg) #define VVI_ICOM_EXPAND__(...) MKFNS(VVI_ICOM_EXPAND__,##__VA_ARGS__) -#define VVI_ICOM_EXPAND__1(arg1) \ +#define VVI_ICOM_EXPAND__0(void) true +#define VVI_ICOM_EXPAND__1(void, arg1) \ VICOMH__(arg1) -#define VVI_ICOM_EXPAND__2(arg1, arg2) \ +#define VVI_ICOM_EXPAND__2(void, arg1, arg2) \ VICOMH__(arg1) && VICOMH__(arg2) -#define VVI_ICOM_EXPAND__3(arg1, arg2, arg3) \ +#define VVI_ICOM_EXPAND__3(void, arg1, arg2, arg3) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) -#define VVI_ICOM_EXPAND__4(arg1, arg2, arg3, arg4) \ +#define VVI_ICOM_EXPAND__4(void, arg1, arg2, arg3, arg4) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ VICOMH__(arg4) -#define VVI_ICOM_EXPAND__5(arg1, arg2, arg3, arg4, arg5) \ +#define VVI_ICOM_EXPAND__5(void, arg1, arg2, arg3, arg4, arg5) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ VICOMH__(arg4) && VICOMH__(arg5) -#define VVI_ICOM_EXPAND__6(arg1, arg2, arg3, arg4, arg5, arg6) \ +#define VVI_ICOM_EXPAND__6(void, arg1, arg2, arg3, arg4, arg5, arg6) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) &&\ VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) -#define VVI_ICOM_EXPAND__7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ +#define VVI_ICOM_EXPAND__7(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) && \ VICOMH__(arg7) -#define VVI_ICOM_EXPAND__8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ +#define VVI_ICOM_EXPAND__8(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) && \ VICOMH__(arg7) && VICOMH__(arg8) -#define VVI_ICOM_EXPAND__9(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ +#define VVI_ICOM_EXPAND__9(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) && \ VICOMH__(arg7) && VICOMH__(arg8) && VICOMH__(arg9) diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc index 3e61888ce..45f2a4c8a 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc @@ -18,24 +18,18 @@ class Kernel : public Spheral::SPHERALCopyable { public: SPHERAL_HOST_DEVICE void doSomething() { printf("Ki HD doSomething()\n"); asDesc().doSomething(); } - friend Kernel deepCopy(Kernel const& rhs) { - Kernel result(rhs); - return result; - } - + VVI_IMPL_DEEPCOPY(Kernel) }; template class TableKernel : public Kernel> { public: - TableKernel() = default; SPHERAL_HOST_DEVICE void doSomething() { printf("TKi HD doSomething()\n"); printf("TableKernel doSomething\n"); } }; template class OtherKernel : public Kernel> { public: - OtherKernel() = default; SPHERAL_HOST_DEVICE void doSomething() { printf("OKi HD doSomething()\n"); printf("OtherKernel doSomething\n"); } }; @@ -51,44 +45,38 @@ class TableKernel; template class OtherKernel; -#define KernelView__(code) PTR_VIEW_METACLASS_DECL( (Kernel), (KernelView), (vvimpl::Kernel), (code)) -#define TableKernelView__(code) PTR_VIEW_METACLASS_DECL( (TableKernel), (TableKernelView), (vvimpl::TableKernel), (code)) -#define OtherKernelView__(code) PTR_VIEW_METACLASS_DECL( (OtherKernel), (OtherKernelView), (vvimpl::OtherKernel), (code)) - -#define Kernel__(code) PTR_VALUE_METACLASS_DECL((Kernel), (KernelView), (code)) -#define TableKernel__(code) PTR_VALUE_METACLASS_DECL((TableKernel), (TableKernelView), (code)) -#define OtherKernel__(code) PTR_VALUE_METACLASS_DECL((OtherKernel), (OtherKernelView), (code)) - template -class KernelView__( VVI_VIEW_DEFAULT(KernelView) ); +class PTR_VIEW_METACLASS_DECL_DEFAULT( (Kernel), (KernelView), (vvimpl::Kernel) ); template -class TableKernelView__( VVI_VIEW_DEFAULT(TableKernelView) ); +class PTR_VIEW_METACLASS_DECL_DEFAULT( (TableKernel), (TableKernelView), (vvimpl::TableKernel) ); template -class OtherKernelView__( VVI_VIEW_DEFAULT(OtherKernelView) ); +class PTR_VIEW_METACLASS_DECL_DEFAULT( (OtherKernel), (OtherKernelView), (vvimpl::OtherKernel) ); + //-------------------------------- // Value Interface +#define Kernel__(code) PTR_VALUE_METACLASS_DECL((Kernel), (KernelView), (code)) +#define TableKernel__(code) PTR_VALUE_METACLASS_DECL((TableKernel), (TableKernelView), (code)) +#define OtherKernel__(code) PTR_VALUE_METACLASS_DECL((OtherKernel), (OtherKernelView), (code)) + template class Kernel__( public: - VVI_VALUE_DEF_CTOR(Kernel) void doSomething() { printf("K H doSomething()\n"); VVI_IMPL_INST().doSomething(); } ); template class TableKernel__( public: - VVI_VALUE_DEF_CTOR(TableKernel) void doSomething() { printf("TK H doSomething()\n"); VVI_IMPL_INST().doSomething(); } ); template class OtherKernel__( public: - VVI_VALUE_DEF_CTOR(OtherKernel) void doSomething() { printf("OK H doSomething()\n"); VVI_IMPL_INST().doSomething(); } ); @@ -132,6 +120,22 @@ GPU_TYPED_TEST(KernelParallelInterface, TableKernelInterface) EXEC_IN_SPACE_END() } +GPU_TYPED_TEST(KernelParallelInterface, TableKernelInterfaceCopy) +{ + using WORK_EXEC_POLICY = TypeParam; + + TableKernel tk; + TableKernel tk2 = tk; + + tk.doSomething(); + + TableKernelView tkv = &tk; + + EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + tkv->doSomething(); + EXEC_IN_SPACE_END() +} + GPU_TYPED_TEST(KernelParallelInterface, KernelInterface) { using WORK_EXEC_POLICY = TypeParam; diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc index 8c2c188ba..9c13c7661 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc @@ -56,18 +56,13 @@ class QInt; #define QInt__(code) PTR_VALUE_METACLASS_DECL( (QInt), (QIntView), (code) ) class QIntView__( - VVI_VIEW_DEFAULT(QIntView) // This defines the default behavior of a reference semantics based interface. + //VVI_VIEW_DEFAULT(QIntView) // This defines the default behavior of a reference semantics based interface. public: using CoeffsType = typename ImplType::CoeffsType; ); class QInt__( public: - VVI_VALUE_DEF_CTOR(QInt) - //VVI_VALUE_COPY_CTOR(QInt) - //VVI_VALUE_ASSIGNEMT_OP() - //VVI_VALUE_EQ_OP() - double xmin() const { return sptr_data().xmin(); } double xmax() const { return sptr_data().xmax(); } From c09dacb8aae9bb310d908046c57c39b10783c04c Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Fri, 30 Aug 2024 12:07:24 -0700 Subject: [PATCH 16/44] Using shorthand class defs in examples; Removing unnecessary macros for defining default Ctor, Copy, Ass and Eq operations. --- src/Utilities/ValueViewInterface.hh | 69 ++++++++-------- src/Utilities/ValueViewInterfaceImpl.hh | 80 ++++++++++--------- .../value_view_crtp_pattern_tests.cc | 6 +- .../value_view_ptr_basic_class_tests.cc | 2 - .../value_view_ref_basic_class_tests.cc | 2 - .../value_view_template_inheritance_tests.cc | 23 +----- 6 files changed, 83 insertions(+), 99 deletions(-) diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh index 62a8d2ed9..c3bfb10e8 100644 --- a/src/Utilities/ValueViewInterface.hh +++ b/src/Utilities/ValueViewInterface.hh @@ -73,12 +73,14 @@ using SPHERALCopyable = chai::CHAICopyable; UNPACK code \ VIEW_METACLASS_DECL_END() -#define PTR_VIEW_METACLASS_DECL_DEFAULT(value_t, view_t, impl_t) \ - PTR_VIEW_METACLASS_DECL( value_t, view_t, impl_t, ( VVI_VIEW_DEFAULT(UNPACK view_t) ) ) - //class VIEW_METACLASS_DECL_BEGIN((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) \ - //POINTER_SYNTAX_OPERATORS() \ - //VVI_VIEW_DEFAULT(view_t) \ - //VIEW_METACLASS_DECL_END() +#define PTR_VIEW_METACLASS_DEFAULT(value_t, view_t, impl_t) \ + PTR_VIEW_METACLASS_DECL( value_t, view_t, impl_t, ( ) ) + +#define PTR_VALUE_METACLASS_DEFAULT(value_t, view_t, impl_t) \ + PTR_VALUE_METACLASS_DECL( value_t, view_t, impl_t, ( ) ) + +#define PTR_VALUE_METACLASS_DELETED(value_t, view_t, impl_t) \ + PTR_VALUE_METACLASS_DECL( value_t, view_t, ( VVI_DELETED_INTERFACE(UNPACK value_t) ) ) // ---------------------------------------------------------------------------- // VALUE class definition macros @@ -87,17 +89,17 @@ using SPHERALCopyable = chai::CHAICopyable; #define VVI_VALUE_CTOR_ARGS(args) \ Base(chai::make_shared(UNPACK args)) -#define VVI_VALUE_DEF_CTOR(value_t) \ - value_t() : Base() {} - -#define VVI_VALUE_COPY_CTOR(value_t) \ - value_t(value_t const& rhs) : Base(rhs) {} - -#define VVI_VALUE_ASSIGNEMT_OP() \ - ValueType& operator=(ValueType const& rhs) { \ - Base::operator=(rhs); \ - return *this; \ - } +//#define VVI_VALUE_DEF_CTOR(value_t) \ +// value_t() : Base() {} +// +//#define VVI_VALUE_COPY_CTOR(value_t) \ +// value_t(value_t const& rhs) : Base(rhs) {} +// +//#define VVI_VALUE_ASSIGNEMT_OP() \ +// ValueType& operator=(ValueType const& rhs) { \ +// Base::operator=(rhs); \ +// return *this; \ +// } //#define VVI_VALUE_EQ_OP() \ // bool operator==(const ValueType& rhs) const \ @@ -114,18 +116,15 @@ using SPHERALCopyable = chai::CHAICopyable; // VIEW class definition macros // ---------------------------------------------------------------------------- -#define VVI_VIEW_DEF_CTOR(view_t) \ - view_t() = default; - -#define VVI_VIEW_COPY_CTOR(view_t) \ - view_t(view_t const& rhs) = default; - -#define VVI_VIEW_ASSIGNEMT_OP() \ - SPHERAL_HOST_DEVICE ViewType& operator=(ViewType const& rhs) = default; - -#define VVI_VIEW_EQ_OP() \ - bool operator==(const ViewType& rhs) const \ - { return sptr_data() == rhs.sptr_data(); } +//#define VVI_VIEW_COPY_CTOR(view_t) \ +// view_t(view_t const& rhs) = default; +// +//#define VVI_VIEW_ASSIGNEMT_OP() \ +// SPHERAL_HOST_DEVICE ViewType& operator=(ViewType const& rhs) = default; +// +//#define VVI_VIEW_EQ_OP() \ +// bool operator==(const ViewType& rhs) const \ +// { return sptr_data() == rhs.sptr_data(); } // ---------------------------------------------------------------------------- @@ -144,12 +143,12 @@ public: \ type(type const&) = delete; \ type& operator=(type const&) = delete; -// Used for allowing default class behavior from the compiler. Typically this -// will be used for invoking a basic view interface when using poiter syntax. -#define VVI_VIEW_DEFAULT(view_t) \ - VVI_VIEW_DEF_CTOR(view_t) \ - VVI_VIEW_COPY_CTOR(view_t) \ - VVI_VIEW_ASSIGNEMT_OP() +//// Used for allowing default class behavior from the compiler. Typically this +//// will be used for invoking a basic view interface when using poiter syntax. +//#define VVI_VIEW_DEFAULT(view_t) \ +// VVI_VIEW_DEF_CTOR(view_t) \ +// VVI_VIEW_COPY_CTOR(view_t) \ +// VVI_VIEW_ASSIGNEMT_OP() // Creates a function that allows interface objects to access member variables. // through a function of the same name as the variable itself. diff --git a/src/Utilities/ValueViewInterfaceImpl.hh b/src/Utilities/ValueViewInterfaceImpl.hh index 2b9109c7d..7cd468430 100644 --- a/src/Utilities/ValueViewInterfaceImpl.hh +++ b/src/Utilities/ValueViewInterfaceImpl.hh @@ -24,50 +24,50 @@ using vector = ::Spheral::ManagedVector; using vector = std::vector; #endif +namespace detail { -template -class ViewInterface : public vvi::shared_ptr -{ -private: - using m_ImplType = impl_type; + template + class ViewInterface : public vvi::shared_ptr + { + private: + using m_ImplType = impl_type; -public: - using SmartPtrType = vvi::shared_ptr; - SPHERAL_HOST_DEVICE SmartPtrType & sptr() { return *this; } - SPHERAL_HOST_DEVICE SmartPtrType const& sptr() const { return *this; } + public: + using SmartPtrType = vvi::shared_ptr; + SPHERAL_HOST_DEVICE SmartPtrType & sptr() { return *this; } + SPHERAL_HOST_DEVICE SmartPtrType const& sptr() const { return *this; } - SPHERAL_HOST_DEVICE m_ImplType & sptr_data() { return *(SmartPtrType::get()); } \ - SPHERAL_HOST_DEVICE m_ImplType & sptr_data() const { return *(SmartPtrType::get()); } + SPHERAL_HOST_DEVICE m_ImplType & sptr_data() { return *(SmartPtrType::get()); } \ + SPHERAL_HOST_DEVICE m_ImplType & sptr_data() const { return *(SmartPtrType::get()); } - SPHERAL_HOST_DEVICE ViewInterface() = default; - SPHERAL_HOST ViewInterface(SmartPtrType&& rhs) : SmartPtrType(std::forward(rhs)) {} -}; + SPHERAL_HOST_DEVICE ViewInterface() = default; + SPHERAL_HOST ViewInterface(SmartPtrType&& rhs) : SmartPtrType(std::forward(rhs)) {} + }; -// Interface class for Value like objects. -template -class ValueInterface : public view_type -{ -private: - using m_ImplType = typename view_type::ImplType; - using m_SmartPtrType = typename view_type::SmartPtrType; + // Interface class for Value like objects. + template + class ValueInterface : public view_type + { + private: + using m_ImplType = typename view_type::ImplType; + using m_SmartPtrType = typename view_type::SmartPtrType; -protected: - using ViewType = typename view_type::ViewType; + protected: + using ViewType = typename view_type::ViewType; - ValueInterface() : ValueInterface(chai::make_shared()) {} + ValueInterface() : ValueInterface(chai::make_shared()) {} -public: -#if !defined(SPHERAL_ENABLE_VVI) - ValueInterface(m_ImplType* rhs) : view_type((rhs)) {} -#endif - ValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} - ValueInterface(ValueInterface const& rhs) : ValueInterface(chai::make_shared( deepCopy(rhs.sptr_data()) )) {} - ValueInterface& operator=(ValueInterface const& rhs) { ViewType::operator=( chai::make_shared( deepCopy( rhs.sptr_data() ) ) ); return *this; } - bool operator==(ValueInterface const& rhs) const { return compare(this->sptr_data(), rhs.sptr_data()); } -}; + public: + #if !defined(SPHERAL_ENABLE_VVI) + ValueInterface(m_ImplType* rhs) : view_type((rhs)) {} + #endif + ValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} + ValueInterface(ValueInterface const& rhs) : ValueInterface(chai::make_shared( deepCopy(rhs.sptr_data()) )) {} + ValueInterface& operator=(ValueInterface const& rhs) { ViewType::operator=( chai::make_shared( deepCopy( rhs.sptr_data() ) ) ); return *this; } + bool operator==(ValueInterface const& rhs) const { return compare(this->sptr_data(), rhs.sptr_data()); } + }; -namespace detail { template bool compare(T const& lhs, T const& rhs) @@ -178,7 +178,7 @@ public: \ using ImplType = typename ViewType::ImplType; \ using ViewInterfaceType = typename ViewType::ViewInterfaceType; \ protected: \ - using Base = ::vvi::ValueInterface; \ + using Base = ::vvi::detail::ValueInterface; \ using SmartPtrType = typename ViewType::SmartPtrType; \ public: \ VVI_VALUE_TOVIEW_OP__() \ @@ -186,7 +186,7 @@ private: #define VALUE_METACLASS_DECL_BEGIN(value_t, view_t) \ -UNPACK value_t : public ::vvi::ValueInterface { \ +UNPACK value_t : public ::vvi::detail::ValueInterface { \ VALUE_INTERFACE_METACLASS((UNPACK view_t)) \ @@ -212,6 +212,9 @@ public: \ view_t(SmartPtrType&& rhs) : Base(std::forward(rhs)) {} #endif +#define VVI_VIEW_DEF_CTOR(view_t) \ + view_t() = default; + // TODO: Is this still relevant? //#define VVI_VIEW_SHALLOW_COPY__(view_t) \ //public: \ @@ -222,8 +225,9 @@ public: \ using ImplType = UNPACK impl_t; \ using ViewType = UNPACK view_t; \ using ValueType = UNPACK value_t; \ + VVI_VIEW_DEF_CTOR(view_t) \ protected: \ - using Base = ::vvi::ViewInterface; \ + using Base = ::vvi::detail::ViewInterface; \ using ViewInterfaceType = Base; \ using SmartPtrType = typename Base::SmartPtrType; \ friend class UNPACK value_t; \ @@ -231,7 +235,7 @@ protected: \ private: #define VIEW_METACLASS_DECL_BEGIN(value_t, view_t, impl_t) \ -UNPACK view_t : public ::vvi::ViewInterface< UNPACK impl_t> { \ +UNPACK view_t : public ::vvi::detail::ViewInterface< UNPACK impl_t> { \ VIEW_INTERFACE_METACLASS((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) #define VIEW_METACLASS_DECL_END() \ diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc index 45f2a4c8a..a7795a5da 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc @@ -46,13 +46,13 @@ template class OtherKernel; template -class PTR_VIEW_METACLASS_DECL_DEFAULT( (Kernel), (KernelView), (vvimpl::Kernel) ); +class PTR_VIEW_METACLASS_DEFAULT( (Kernel), (KernelView), (vvimpl::Kernel) ); template -class PTR_VIEW_METACLASS_DECL_DEFAULT( (TableKernel), (TableKernelView), (vvimpl::TableKernel) ); +class PTR_VIEW_METACLASS_DEFAULT( (TableKernel), (TableKernelView), (vvimpl::TableKernel) ); template -class PTR_VIEW_METACLASS_DECL_DEFAULT( (OtherKernel), (OtherKernelView), (vvimpl::OtherKernel) ); +class PTR_VIEW_METACLASS_DEFAULT( (OtherKernel), (OtherKernelView), (vvimpl::OtherKernel) ); //-------------------------------- diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc index 9c13c7661..49f209ab5 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_ptr_basic_class_tests.cc @@ -48,7 +48,6 @@ class QInt : public Spheral::SPHERALCopyable{ VVI_IMPL_END - #ifdef SPHERAL_ENABLE_VVI class QInt; @@ -56,7 +55,6 @@ class QInt; #define QInt__(code) PTR_VALUE_METACLASS_DECL( (QInt), (QIntView), (code) ) class QIntView__( - //VVI_VIEW_DEFAULT(QIntView) // This defines the default behavior of a reference semantics based interface. public: using CoeffsType = typename ImplType::CoeffsType; ); diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc index ba9329629..23f54b047 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_ref_basic_class_tests.cc @@ -69,8 +69,6 @@ class QIntView__( class QInt__( public: - VVI_VALUE_DEF_CTOR(QInt) - // Forward Value capable methods SPHERAL_HOST void initialize(size_t min) const { return sptr_data().initialize(min); } SPHERAL_HOST void editData(size_t min) const { return sptr_data().editData(min); } diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc index 92fa09820..9c30399d9 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc @@ -51,7 +51,7 @@ VVI_IMPL_END -#ifdef SPHERAL_ENABLE_VVI +#ifdef VVI_ENABLED //----------------------------------------------------------------------------- // Interface to support porting to the GPU. //----------------------------------------------------------------------------- @@ -62,36 +62,21 @@ class F; class FB; // Define Metaclass macros for Value/View relationships -#define FBV__(code) PTR_VIEW_METACLASS_DECL((FB), (FBV), (vvimpl::FB), (code)) -#define FB__(code) PTR_VALUE_METACLASS_DECL((FB), (FBV), (code)) +class PTR_VIEW_METACLASS_DEFAULT((FB), (FBV), (vvimpl::FB)) +class PTR_VALUE_METACLASS_DELETED((FB), (FBV), (vvimpl::FB)) #define FV__(code) PTR_VIEW_METACLASS_DECL((F), (FV), (vvimpl::F), (code)) #define F__(code) PTR_VALUE_METACLASS_DECL((F), (FV), (code)) -// --- Interface definitions --- - -class FBV__( - VVI_VIEW_DEFAULT(FBV) -); - -// This class instantiation exsists only to fulfil type information -// queries that might arise : e.g. `typename FB::ViewType` - // Because the underlying impl type is an abstract virtual we can not allow - // construction of FB class with default Ctor, Copy Ctor or assignment Op. -class FB__( - VVI_DELETED_INTERFACE(FB) -); - - template class FV__( - VVI_VIEW_DEFAULT(FV) // Field inherits from FieldBase so we would like to be able to implicitly // upcast a fieldview object to a fieldbaseview. VVI_UPCAST_CONVERSION_OP(FBV) ); + template class F__( public: From f3f5d3619efcea558471f297d1e1ed2affa2443c Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Thu, 5 Sep 2024 18:02:03 -0700 Subject: [PATCH 17/44] Implmenting VVI for QuadraticInterpolator; Resolving Pedantic for warnings as errors --- cmake/InstallTPLs.cmake | 2 + cmake/spheral/SpheralAddLibs.cmake | 16 ++-- src/Utilities/ManagedVector.hh | 2 - src/Utilities/QuadraticInterpolator.cc | 31 +------ src/Utilities/QuadraticInterpolator.hh | 89 +++++++++++++++---- src/Utilities/QuadraticInterpolatorInline.hh | 16 ++++ src/Utilities/ValueViewInterface.hh | 66 ++++++++------ src/Utilities/ValueViewInterfaceImpl.hh | 56 ++++++------ .../ValueViewInterface/CMakeLists.txt | 3 +- .../value_view_crtp_pattern_tests.cc | 9 +- .../value_view_template_inheritance_tests.cc | 2 +- 11 files changed, 179 insertions(+), 113 deletions(-) diff --git a/cmake/InstallTPLs.cmake b/cmake/InstallTPLs.cmake index 7c17fcd64..7ca7676e7 100644 --- a/cmake/InstallTPLs.cmake +++ b/cmake/InstallTPLs.cmake @@ -82,11 +82,13 @@ message("----------------------------------------------------------------------- find_package(RAJA REQUIRED NO_DEFAULT_PATH PATHS ${raja_DIR}) if (RAJA_FOUND) message("Found RAJA External Package.") + blt_convert_to_system_includes(TARGET RAJA) endif() message("-----------------------------------------------------------------------------") find_package(umpire REQUIRED NO_DEFAULT_PATH PATHS ${umpire_DIR}) if (umpire_FOUND) message("Found umpire External Package.") + blt_convert_to_system_includes(TARGET umpire) endif() message("-----------------------------------------------------------------------------") diff --git a/cmake/spheral/SpheralAddLibs.cmake b/cmake/spheral/SpheralAddLibs.cmake index 862799ba7..19fe2389d 100644 --- a/cmake/spheral/SpheralAddLibs.cmake +++ b/cmake/spheral/SpheralAddLibs.cmake @@ -107,14 +107,14 @@ function(spheral_add_cxx_library package_name _cxx_obj_list) endif() - # This cleans up library targets created with object libs. It is turned off as it triggers - # a failure on Werror and pedantic builds. - set(_properties COMPILE_DEFINITIONS LINK_LIBRARIES LINK_OPTIONS INTERFACE_LINK_OPTIONS COMPILE_OPTIONS INTERFACE_COMPILE_OPTIONS) - foreach(_prop ${_properties}) - get_target_property(temp_prop Spheral_${package_name} ${_prop}) - list(REMOVE_DUPLICATES temp_prop) - set_target_properties(Spheral_${package_name} PROPERTIES ${_prop} "${temp_prop}") - endforeach() + ## This cleans up library targets created with object libs. It is turned off as it triggers + ## a failure on Werror and pedantic builds. + #set(_properties COMPILE_DEFINITIONS LINK_LIBRARIES LINK_OPTIONS INTERFACE_LINK_OPTIONS COMPILE_OPTIONS INTERFACE_COMPILE_OPTIONS) + #foreach(_prop ${_properties}) + # get_target_property(temp_prop Spheral_${package_name} ${_prop}) + # list(REMOVE_DUPLICATES temp_prop) + # set_target_properties(Spheral_${package_name} PROPERTIES ${_prop} "${temp_prop}") + #endforeach() set_target_properties(Spheral_${package_name} PROPERTIES INTERFACE_LINK_LIBRARIES "") diff --git a/src/Utilities/ManagedVector.hh b/src/Utilities/ManagedVector.hh index 9b99d7d23..1070b8a27 100644 --- a/src/Utilities/ManagedVector.hh +++ b/src/Utilities/ManagedVector.hh @@ -315,9 +315,7 @@ template inline bool compare(ManagedVector const& lhs, ManagedVector const& rhs) { - std::cout << "check\n"; if (lhs.size() != rhs.size()) return false; - if (lhs.size() == 0) return true; for (size_t i = 0; i < lhs.size(); i++) { if (lhs[i] != rhs[i]) { return false; diff --git a/src/Utilities/QuadraticInterpolator.cc b/src/Utilities/QuadraticInterpolator.cc index 5785506b3..b6480fe0d 100644 --- a/src/Utilities/QuadraticInterpolator.cc +++ b/src/Utilities/QuadraticInterpolator.cc @@ -10,16 +10,7 @@ namespace Spheral { -//------------------------------------------------------------------------------ -// Default constructor -//------------------------------------------------------------------------------ -QuadraticInterpolator::QuadraticInterpolator(): - mN1(), - mXmin(), - mXmax(), - mXstep(), - mcoeffs() { -} +VVI_IMPL_BEGIN //------------------------------------------------------------------------------ // Initialize the interpolation to fit the given data @@ -63,22 +54,6 @@ QuadraticInterpolator::initialize(const double xmin, } } -//------------------------------------------------------------------------------ -// Destructor -//------------------------------------------------------------------------------ -QuadraticInterpolator::~QuadraticInterpolator() { -} +VVI_IMPL_END -//------------------------------------------------------------------------------ -// Equivalence -//------------------------------------------------------------------------------ -bool -QuadraticInterpolator:: -operator==(const QuadraticInterpolator& rhs) const { - return ((mN1 == rhs.mN1) and - (mXmin == rhs.mXmin) and - (mXmax == rhs.mXmax) and - (mcoeffs == rhs.mcoeffs)); -} - -} +} // namespace Spheral diff --git a/src/Utilities/QuadraticInterpolator.hh b/src/Utilities/QuadraticInterpolator.hh index 868725fb7..73fa5b417 100644 --- a/src/Utilities/QuadraticInterpolator.hh +++ b/src/Utilities/QuadraticInterpolator.hh @@ -12,8 +12,12 @@ #include #include +#include "Utilities/ValueViewInterface.hh" + namespace Spheral { +VVI_IMPL_BEGIN + class QuadraticInterpolator { public: //--------------------------- Public Interface ---------------------------// @@ -23,36 +27,38 @@ public: const double xmax, const size_t n, const Func& F); - QuadraticInterpolator(); - ~QuadraticInterpolator(); + + SPHERAL_HOST_DEVICE QuadraticInterpolator() = default; // Alternatively initialize from tabulated values void initialize(const double xmin, const double xmax, const std::vector& yvals); // Comparisons - bool operator==(const QuadraticInterpolator& rhs) const; + SPHERAL_HOST_DEVICE bool operator==(const QuadraticInterpolator& rhs) const; // Interpolate for the y value - double operator()(const double x) const; - double prime(const double x) const; // First derivative - double prime2(const double x) const; // Second derivative + SPHERAL_HOST_DEVICE double operator()(const double x) const; + SPHERAL_HOST_DEVICE double prime(const double x) const; // First derivative + SPHERAL_HOST_DEVICE double prime2(const double x) const; // Second derivative // Same as above, but use a pre-computed table position (from lowerBound) - double operator()(const double x, const size_t i0) const; - double prime(const double x, const size_t i0) const; // First derivative - double prime2(const double x, const size_t i0) const; // Second derivative + SPHERAL_HOST_DEVICE double operator()(const double x, const size_t i0) const; + SPHERAL_HOST_DEVICE double prime(const double x, const size_t i0) const; // First derivative + SPHERAL_HOST_DEVICE double prime2(const double x, const size_t i0) const; // Second derivative // Return the lower bound index in the table for the given x coordinate - size_t lowerBound(const double x) const; + SPHERAL_HOST_DEVICE size_t lowerBound(const double x) const; // Allow read access the internal data representation - size_t size() const; // The size of the tabulated coefficient arrays - double xmin() const; // Minimum x coordinate for table - double xmax() const; // Maximum x coordinate for table - double xstep() const; // delta x between tabulated values - const std::vector& coeffs() const; // the fitting coefficients + SPHERAL_HOST_DEVICE size_t size() const; // The size of the tabulated coefficient arrays + SPHERAL_HOST_DEVICE double xmin() const; // Minimum x coordinate for table + SPHERAL_HOST_DEVICE double xmax() const; // Maximum x coordinate for table + SPHERAL_HOST_DEVICE double xstep() const; // delta x between tabulated values + SPHERAL_HOST_DEVICE const std::vector& coeffs() const; // the fitting coefficients + VVI_IMPL_DEEPCOPY(QuadraticInterpolator) + VVI_IMPL_COMPARE(QuadraticInterpolator, mN1, mXmin, mXmax, mcoeffs) private: //--------------------------- Private Interface --------------------------// // Member data @@ -61,7 +67,58 @@ private: std::vector mcoeffs; }; -} +VVI_IMPL_END + +#ifdef VVI_ENABLED + +class QuadraticInterpolator; + +class PTR_VIEW_METACLASS_DEFAULT \ + ((QuadraticInterpolator), (QuadraticInterpolatorView), (vvimpl::QuadraticInterpolator)) + +#define QuadraticInterpolator__(code) PTR_VALUE_METACLASS_DECL \ + ((QuadraticInterpolator), (QuadraticInterpolatorView), (code)) + +class QuadraticInterpolator__( + template + QuadraticInterpolator(const double xmin, + const double xmax, + const size_t n, + const Func& F) + : VVI_VALUE_CTOR_ARGS((xmin,xmax,n,F)) {} + + VVI_VALUE_DEF_CTOR(QuadraticInterpolator) + + // Alternatively initialize from tabulated values + void initialize(const double xmin, const double xmax, + const std::vector& yvals) + { VVI_IMPL_INST().initialize(xmin, xmax, yvals); } + + // Interpolate for the y value + double operator()(const double x) const { return VVI_IMPL_INST()(x); } + double prime(const double x) const { return VVI_IMPL_INST().prime(x); } + double prime2(const double x) const { return VVI_IMPL_INST().prime2(x); } + + // Same as above, but use a pre-computed table position (from lowerBound) + double operator()(const double x, const size_t i0) const { return VVI_IMPL_INST()(x, i0); } + double prime(const double x, const size_t i0) const { return VVI_IMPL_INST().prime(x, i0); } + double prime2(const double x, const size_t i0) const { return VVI_IMPL_INST().prime2(x, i0); } + + // Return the lower bound index in the table for the given x coordinate + size_t lowerBound(const double x) const { return VVI_IMPL_INST().lowerBound(x); } + + // Allow read access the internal data representation + size_t size() const { return VVI_IMPL_INST().size(); } + double xmin() const { return VVI_IMPL_INST().xmin(); } + double xmax() const { return VVI_IMPL_INST().xmax(); } + double xstep() const { return VVI_IMPL_INST().xstep(); } + const std::vector& coeffs() const { return VVI_IMPL_INST().coeffs(); } +); + +#endif // VVI_ENABLED + + +} // namespace Spheral #include "QuadraticInterpolatorInline.hh" diff --git a/src/Utilities/QuadraticInterpolatorInline.hh b/src/Utilities/QuadraticInterpolatorInline.hh index 3fbd410e3..191393847 100644 --- a/src/Utilities/QuadraticInterpolatorInline.hh +++ b/src/Utilities/QuadraticInterpolatorInline.hh @@ -5,6 +5,8 @@ namespace Spheral { +VVI_IMPL_BEGIN + //------------------------------------------------------------------------------ // Construct to fit the given function //------------------------------------------------------------------------------ @@ -48,6 +50,18 @@ QuadraticInterpolator::QuadraticInterpolator(const double xmin, } } +//------------------------------------------------------------------------------ +// Equivalence +//------------------------------------------------------------------------------ +bool +inline +QuadraticInterpolator::operator==(const QuadraticInterpolator& rhs) const { + return ((mN1 == rhs.mN1) and + (mXmin == rhs.mXmin) and + (mXmax == rhs.mXmax) and + (mcoeffs == rhs.mcoeffs)); +} + //------------------------------------------------------------------------------ // Interpolate for the given x value. //------------------------------------------------------------------------------ @@ -147,4 +161,6 @@ QuadraticInterpolator::coeffs() const { return mcoeffs; } +VVI_IMPL_END + } diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh index c3bfb10e8..63b638a26 100644 --- a/src/Utilities/ValueViewInterface.hh +++ b/src/Utilities/ValueViewInterface.hh @@ -11,7 +11,7 @@ namespace Spheral { -// An interface class to ensure all required methods are defined by Data +// An interface cass to ensure all required methods are defined by Data // classes that need to be automatically copied by another CHAICopyable or // SPHERALCopyable class. using SPHERALCopyable = chai::CHAICopyable; @@ -30,17 +30,27 @@ using SPHERALCopyable = chai::CHAICopyable; #define VVI_IMPL_END #endif // defined(VVI_ENABLED) -#define VVI_IMPL_DEEPCOPY(impl_t, ...) \ +#if defined(VVI_ENABLED) + +#define VVI_IMPL_DEEPCOPY(...) VVI_IMPL_DEEPCOPY__( __VA_ARGS__ , void) + +#define VVI_IMPL_DEEPCOPY__(impl_t, ...) \ friend impl_t deepCopy(impl_t const& rhs) { \ impl_t result(rhs); \ - VVI_IDC_EXPAND__( void, ##__VA_ARGS__ ) \ + VVI_IDC_EXPAND__( __VA_ARGS__ ) \ return result; \ } -#define VVI_IMPL_COMPARE(impl_t, ...) \ +#define VVI_IMPL_COMPARE(...) VVI_IMPL_COMPARE__( __VA_ARGS__. void) + +#define VVI_IMPL_COMPARE__(impl_t, ...) \ friend bool compare(impl_t const& lhs, impl_t const& rhs) { \ - return VVI_ICOM_EXPAND__( void, ##__VA_ARGS__); \ + return VVI_ICOM_EXPAND__( __VA_ARGS__); \ } +#else +#define VVI_IMPL_DEEPCOPY(impl_t, ...) +#define VVI_IMPL_COMPARE(impl_t, ...) +#endif // ---------------------------------------------------------------------------- // VALUE class declaration macros @@ -74,42 +84,42 @@ using SPHERALCopyable = chai::CHAICopyable; VIEW_METACLASS_DECL_END() #define PTR_VIEW_METACLASS_DEFAULT(value_t, view_t, impl_t) \ - PTR_VIEW_METACLASS_DECL( value_t, view_t, impl_t, ( ) ) + PTR_VIEW_METACLASS_DECL( value_t, view_t, impl_t, ( ) ); #define PTR_VALUE_METACLASS_DEFAULT(value_t, view_t, impl_t) \ - PTR_VALUE_METACLASS_DECL( value_t, view_t, impl_t, ( ) ) + PTR_VALUE_METACLASS_DECL( value_t, view_t, impl_t, ( ) ); #define PTR_VALUE_METACLASS_DELETED(value_t, view_t, impl_t) \ - PTR_VALUE_METACLASS_DECL( value_t, view_t, ( VVI_DELETED_INTERFACE(UNPACK value_t) ) ) + PTR_VALUE_METACLASS_DECL( value_t, view_t, ( VVI_DELETED_INTERFACE(UNPACK value_t) ) ); // ---------------------------------------------------------------------------- // VALUE class definition macros // ---------------------------------------------------------------------------- #define VVI_VALUE_CTOR_ARGS(args) \ - Base(chai::make_shared(UNPACK args)) + Base(VVI_MAKE_SHARED(UNPACK args)) + +#define VVI_VALUE_DEF_CTOR(value_t) \ + value_t() : Base() {} + +#define VVI_VALUE_COPY_CTOR(value_t) \ + value_t(value_t const& rhs) : Base(rhs) {} -//#define VVI_VALUE_DEF_CTOR(value_t) \ -// value_t() : Base() {} +////#define VVI_VALUE_ASSIGNEMT_OP() \ +//// ValueType& operator=(ValueType const& rhs) { \ +//// Base::operator=(rhs); \ +//// return *this; \ +//// } // -//#define VVI_VALUE_COPY_CTOR(value_t) \ -// value_t(value_t const& rhs) : Base(rhs) {} +////#define VVI_VALUE_EQ_OP() \ +//// bool operator==(const ValueType& rhs) const \ +//// { return compare(VVI_SPTR_DATA_REF__(), rhs.VVI_SPTR_DATA_REF__()); } // -//#define VVI_VALUE_ASSIGNEMT_OP() \ -// ValueType& operator=(ValueType const& rhs) { \ -// Base::operator=(rhs); \ -// return *this; \ -// } - -//#define VVI_VALUE_EQ_OP() \ -// bool operator==(const ValueType& rhs) const \ -// { return compare(VVI_SPTR_DATA_REF__(), rhs.VVI_SPTR_DATA_REF__()); } - -//#define VVI_VALUE_TYPE_DEFAULT_ASSIGNMENT_OP(value_t) \ -// value_t& operator=(value_t const& rhs) { \ -// ViewType::operator=( ViewType( new ImplType(deepCopy(rhs.ViewInterfaceType::sptr_data())) ) ); \ -// return *this; \ -// } +////#define VVI_VALUE_TYPE_DEFAULT_ASSIGNMENT_OP(value_t) \ +//// value_t& operator=(value_t const& rhs) { \ +//// ViewType::operator=( ViewType( new ImplType(deepCopy(rhs.ViewInterfaceType::sptr_data())) ) ); \ +//// return *this; \ +//// } // ---------------------------------------------------------------------------- diff --git a/src/Utilities/ValueViewInterfaceImpl.hh b/src/Utilities/ValueViewInterfaceImpl.hh index 7cd468430..8108a7beb 100644 --- a/src/Utilities/ValueViewInterfaceImpl.hh +++ b/src/Utilities/ValueViewInterfaceImpl.hh @@ -13,13 +13,16 @@ namespace vvi { template #if defined(VVI_ENABLED) using shared_ptr = chai::ManagedSharedPtr; +#define VVI_MAKE_SHARED chai::make_shared #else using shared_ptr = std::shared_ptr; +#define VVI_MAKE_SHARED std::make_shared #endif template #if defined(VVI_ENABLED) using vector = ::Spheral::ManagedVector; +//using vector = std::vector; #else using vector = std::vector; #endif @@ -56,15 +59,16 @@ namespace detail { protected: using ViewType = typename view_type::ViewType; - ValueInterface() : ValueInterface(chai::make_shared()) {} + ValueInterface() : ValueInterface(VVI_MAKE_SHARED()) {} + //ValueInterface() : ValueInterface(chai::make_shared()) {} public: #if !defined(SPHERAL_ENABLE_VVI) ValueInterface(m_ImplType* rhs) : view_type((rhs)) {} #endif - ValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} - ValueInterface(ValueInterface const& rhs) : ValueInterface(chai::make_shared( deepCopy(rhs.sptr_data()) )) {} - ValueInterface& operator=(ValueInterface const& rhs) { ViewType::operator=( chai::make_shared( deepCopy( rhs.sptr_data() ) ) ); return *this; } + ValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {std::cout << "fwd Ctor\n";} + ValueInterface(ValueInterface const& rhs) : ValueInterface(VVI_MAKE_SHARED( deepCopy(rhs.sptr_data()) )) {std::cout << "Copy Ctor\n";} + ValueInterface& operator=(ValueInterface const& rhs) { ViewType::operator=( VVI_MAKE_SHARED( deepCopy( rhs.sptr_data() ) ) ); std::cout << "Ass Op/n"; return *this; } bool operator==(ValueInterface const& rhs) const { return compare(this->sptr_data(), rhs.sptr_data()); } }; @@ -90,7 +94,7 @@ namespace detail { // ---------------------------------------------------------------------------- // Macro tool for creating macro functions with an unknown number of arguments (Max 9) -#define MKFNS(fn,...) MKFN_N(fn,##__VA_ARGS__, 9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__) +#define MKFNS(fn,...) MKFN_N(fn,##__VA_ARGS__, 9,8,7,6,5,4,3,2,1,0, void)(__VA_ARGS__) #define MKFN_N(fn, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n, ...) fn##n @@ -99,31 +103,31 @@ namespace detail { #define VIDCH__(arg) result.arg = deepCopy(rhs.arg); #define VVI_IDC_EXPAND__(...) MKFNS(VVI_IDC_EXPAND__,##__VA_ARGS__) -#define VVI_IDC_EXPAND__0(v) -#define VVI_IDC_EXPAND__1(void, arg1) \ +#define VVI_IDC_EXPAND__0(void) +#define VVI_IDC_EXPAND__1(arg1, void) \ VIDCH__(arg1) -#define VVI_IDC_EXPAND__2(void, arg1, arg2) \ +#define VVI_IDC_EXPAND__2(arg1, arg2, void) \ VIDCH__(arg1) VIDCH__(arg2) -#define VVI_IDC_EXPAND__3(void, arg1, arg2, arg3) \ +#define VVI_IDC_EXPAND__3(arg1, arg2, arg3, void) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) -#define VVI_IDC_EXPAND__4(void, arg1, arg2, arg3, arg4) \ +#define VVI_IDC_EXPAND__4(arg1, arg2, arg3, arg4, void) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) -#define VVI_IDC_EXPAND__5(void, arg1, arg2, arg3, arg4, arg5) \ +#define VVI_IDC_EXPAND__5(arg1, arg2, arg3, arg4, arg5, void) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) VIDCH__(arg5) -#define VVI_IDC_EXPAND__6(void, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define VVI_IDC_EXPAND__6(arg1, arg2, arg3, arg4, arg5, arg6, void) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) -#define VVI_IDC_EXPAND__7(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ +#define VVI_IDC_EXPAND__7(arg1, arg2, arg3, arg4, arg5, arg6, arg7, void) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) \ VIDCH__(arg7) -#define VVI_IDC_EXPAND__8(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ +#define VVI_IDC_EXPAND__8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, void) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) \ VIDCH__(arg7) VIDCH__(arg8) -#define VVI_IDC_EXPAND__9(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ +#define VVI_IDC_EXPAND__9(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, void) \ VIDCH__(arg1) VIDCH__(arg2) VIDCH__(arg3) \ VIDCH__(arg4) VIDCH__(arg5) VIDCH__(arg6) \ VIDCH__(arg7) VIDCH__(arg8) VIDCH__(arg9) @@ -134,30 +138,30 @@ namespace detail { #define VVI_ICOM_EXPAND__(...) MKFNS(VVI_ICOM_EXPAND__,##__VA_ARGS__) #define VVI_ICOM_EXPAND__0(void) true -#define VVI_ICOM_EXPAND__1(void, arg1) \ +#define VVI_ICOM_EXPAND__1(arg1, void) \ VICOMH__(arg1) -#define VVI_ICOM_EXPAND__2(void, arg1, arg2) \ +#define VVI_ICOM_EXPAND__2(arg1, arg2, void) \ VICOMH__(arg1) && VICOMH__(arg2) -#define VVI_ICOM_EXPAND__3(void, arg1, arg2, arg3) \ +#define VVI_ICOM_EXPAND__3(arg1, arg2, arg3, void) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) -#define VVI_ICOM_EXPAND__4(void, arg1, arg2, arg3, arg4) \ +#define VVI_ICOM_EXPAND__4(arg1, arg2, arg3, arg4, void) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ VICOMH__(arg4) -#define VVI_ICOM_EXPAND__5(void, arg1, arg2, arg3, arg4, arg5) \ +#define VVI_ICOM_EXPAND__5(arg1, arg2, arg3, arg4, arg5, void) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ VICOMH__(arg4) && VICOMH__(arg5) -#define VVI_ICOM_EXPAND__6(void, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define VVI_ICOM_EXPAND__6(arg1, arg2, arg3, arg4, arg5, arg6, void) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) &&\ VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) -#define VVI_ICOM_EXPAND__7(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ +#define VVI_ICOM_EXPAND__7(arg1, arg2, arg3, arg4, arg5, arg6, arg7, void) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) && \ VICOMH__(arg7) -#define VVI_ICOM_EXPAND__8(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ +#define VVI_ICOM_EXPAND__8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, void) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) && \ VICOMH__(arg7) && VICOMH__(arg8) -#define VVI_ICOM_EXPAND__9(void, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ +#define VVI_ICOM_EXPAND__9(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, void) \ VICOMH__(arg1) && VICOMH__(arg2) && VICOMH__(arg3) && \ VICOMH__(arg4) && VICOMH__(arg5) && VICOMH__(arg6) && \ VICOMH__(arg7) && VICOMH__(arg8) && VICOMH__(arg9) @@ -191,7 +195,7 @@ UNPACK value_t : public ::vvi::detail::ValueInterface { \ #define VALUE_METACLASS_DECL_END() \ -}; +} @@ -239,7 +243,7 @@ UNPACK view_t : public ::vvi::detail::ViewInterface< UNPACK impl_t> { \ VIEW_INTERFACE_METACLASS((UNPACK value_t), (UNPACK view_t), (UNPACK impl_t)) #define VIEW_METACLASS_DECL_END() \ -}; +} // ---------------------------------------------------------------------------- diff --git a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt index 4d6c96085..61160c52a 100644 --- a/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt +++ b/tests/cpp/Utilities/ValueViewInterface/CMakeLists.txt @@ -1,3 +1,5 @@ +if(SPHERAL_ENABLE_VVI) + # This test is based off a basic implementation of Utilities/QuadraticInterpolator. spheral_add_test( NAME value_view_ptr_basic_class_tests @@ -5,7 +7,6 @@ spheral_add_test( #DEBUG_LINKER ) -if(SPHERAL_ENABLE_VVI) # This test is based off a basic implementation of Utilities/QuadraticInterpolator. spheral_add_test( diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc index a7795a5da..2a6af7d36 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_crtp_pattern_tests.cc @@ -16,6 +16,9 @@ class Kernel : public Spheral::SPHERALCopyable { return static_cast(const_cast&>(*this)); } public: + SPHERAL_HOST_DEVICE operator Desc() const { + return static_cast(const_cast&>(*this)); + } SPHERAL_HOST_DEVICE void doSomething() { printf("Ki HD doSomething()\n"); asDesc().doSomething(); } VVI_IMPL_DEEPCOPY(Kernel) @@ -46,13 +49,13 @@ template class OtherKernel; template -class PTR_VIEW_METACLASS_DEFAULT( (Kernel), (KernelView), (vvimpl::Kernel) ); +class PTR_VIEW_METACLASS_DEFAULT( (Kernel), (KernelView), (vvimpl::Kernel) ) template -class PTR_VIEW_METACLASS_DEFAULT( (TableKernel), (TableKernelView), (vvimpl::TableKernel) ); +class PTR_VIEW_METACLASS_DEFAULT( (TableKernel), (TableKernelView), (vvimpl::TableKernel) ) template -class PTR_VIEW_METACLASS_DEFAULT( (OtherKernel), (OtherKernelView), (vvimpl::OtherKernel) ); +class PTR_VIEW_METACLASS_DEFAULT( (OtherKernel), (OtherKernelView), (vvimpl::OtherKernel) ) //-------------------------------- diff --git a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc index 9c30399d9..0eaffb020 100644 --- a/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc +++ b/tests/cpp/Utilities/ValueViewInterface/value_view_template_inheritance_tests.cc @@ -209,7 +209,7 @@ GPU_TYPED_TEST(FieldParallelInheritanceTypedTest, AccessPattern) auto& elem_v = *vec_fv[i]; printf("%ld, %ld\n", elem_b.getHash(), elem_b.size()); - printf("%p\n", &elem_v(0)); + printf("%p\n", (void*)&elem_v(0)); for(size_t j = 0; j < elem_v.size(); j++) { printf("%f, ",vec_fv[i]->operator()(j));} printf("\n"); } From df81f957527a8d8a79689509d2c87cb45e562388 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Fri, 6 Sep 2024 21:45:21 -0700 Subject: [PATCH 18/44] Dealing w/ multi line comment warnings. --- src/Utilities/ValueViewInterface.hh | 82 ++++++++++++------------- src/Utilities/ValueViewInterfaceImpl.hh | 16 +++-- 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh index 63b638a26..e535838cc 100644 --- a/src/Utilities/ValueViewInterface.hh +++ b/src/Utilities/ValueViewInterface.hh @@ -33,23 +33,13 @@ using SPHERALCopyable = chai::CHAICopyable; #if defined(VVI_ENABLED) #define VVI_IMPL_DEEPCOPY(...) VVI_IMPL_DEEPCOPY__( __VA_ARGS__ , void) - -#define VVI_IMPL_DEEPCOPY__(impl_t, ...) \ - friend impl_t deepCopy(impl_t const& rhs) { \ - impl_t result(rhs); \ - VVI_IDC_EXPAND__( __VA_ARGS__ ) \ - return result; \ - } - #define VVI_IMPL_COMPARE(...) VVI_IMPL_COMPARE__( __VA_ARGS__. void) -#define VVI_IMPL_COMPARE__(impl_t, ...) \ - friend bool compare(impl_t const& lhs, impl_t const& rhs) { \ - return VVI_ICOM_EXPAND__( __VA_ARGS__); \ - } #else -#define VVI_IMPL_DEEPCOPY(impl_t, ...) -#define VVI_IMPL_COMPARE(impl_t, ...) + +#define VVI_IMPL_DEEPCOPY(...) +#define VVI_IMPL_COMPARE(...) + #endif // ---------------------------------------------------------------------------- @@ -105,37 +95,39 @@ using SPHERALCopyable = chai::CHAICopyable; #define VVI_VALUE_COPY_CTOR(value_t) \ value_t(value_t const& rhs) : Base(rhs) {} -////#define VVI_VALUE_ASSIGNEMT_OP() \ -//// ValueType& operator=(ValueType const& rhs) { \ -//// Base::operator=(rhs); \ -//// return *this; \ -//// } -// -////#define VVI_VALUE_EQ_OP() \ -//// bool operator==(const ValueType& rhs) const \ -//// { return compare(VVI_SPTR_DATA_REF__(), rhs.VVI_SPTR_DATA_REF__()); } -// -////#define VVI_VALUE_TYPE_DEFAULT_ASSIGNMENT_OP(value_t) \ -//// value_t& operator=(value_t const& rhs) { \ -//// ViewType::operator=( ViewType( new ImplType(deepCopy(rhs.ViewInterfaceType::sptr_data())) ) ); \ -//// return *this; \ -//// } +/* +#define VVI_VALUE_ASSIGNEMT_OP() \ + ValueType& operator=(ValueType const& rhs) { \ + Base::operator=(rhs); \ + return *this; \ + } +#define VVI_VALUE_EQ_OP() \ + bool operator==(const ValueType& rhs) const \ + { return compare(VVI_SPTR_DATA_REF__(), rhs.VVI_SPTR_DATA_REF__()); } + +#define VVI_VALUE_TYPE_DEFAULT_ASSIGNMENT_OP(value_t) \ + value_t& operator=(value_t const& rhs) { \ + ViewType::operator=( ViewType( new ImplType(deepCopy(rhs.ViewInterfaceType::sptr_data())) ) ); \ + return *this; \ + } +*/ // ---------------------------------------------------------------------------- // VIEW class definition macros // ---------------------------------------------------------------------------- -//#define VVI_VIEW_COPY_CTOR(view_t) \ -// view_t(view_t const& rhs) = default; -// -//#define VVI_VIEW_ASSIGNEMT_OP() \ -// SPHERAL_HOST_DEVICE ViewType& operator=(ViewType const& rhs) = default; -// -//#define VVI_VIEW_EQ_OP() \ -// bool operator==(const ViewType& rhs) const \ -// { return sptr_data() == rhs.sptr_data(); } +/* +#define VVI_VIEW_COPY_CTOR(view_t) \ + view_t(view_t const& rhs) = default; + +#define VVI_VIEW_ASSIGNEMT_OP() \ + SPHERAL_HOST_DEVICE ViewType& operator=(ViewType const& rhs) = default; +#define VVI_VIEW_EQ_OP() \ + bool operator==(const ViewType& rhs) const \ + { return sptr_data() == rhs.sptr_data(); } +*/ // ---------------------------------------------------------------------------- // Special case macros @@ -153,12 +145,14 @@ public: \ type(type const&) = delete; \ type& operator=(type const&) = delete; -//// Used for allowing default class behavior from the compiler. Typically this -//// will be used for invoking a basic view interface when using poiter syntax. -//#define VVI_VIEW_DEFAULT(view_t) \ -// VVI_VIEW_DEF_CTOR(view_t) \ -// VVI_VIEW_COPY_CTOR(view_t) \ -// VVI_VIEW_ASSIGNEMT_OP() +/* +// Used for allowing default class behavior from the compiler. Typically this +// will be used for invoking a basic view interface when using poiter syntax. +#define VVI_VIEW_DEFAULT(view_t) \ + VVI_VIEW_DEF_CTOR(view_t) \ + VVI_VIEW_COPY_CTOR(view_t) \ + VVI_VIEW_ASSIGNEMT_OP() +*/ // Creates a function that allows interface objects to access member variables. // through a function of the same name as the variable itself. diff --git a/src/Utilities/ValueViewInterfaceImpl.hh b/src/Utilities/ValueViewInterfaceImpl.hh index 8108a7beb..e45ae77d7 100644 --- a/src/Utilities/ValueViewInterfaceImpl.hh +++ b/src/Utilities/ValueViewInterfaceImpl.hh @@ -100,6 +100,13 @@ namespace detail { // DeepCopy macro helpers +#define VVI_IMPL_DEEPCOPY__(impl_t, ...) \ + friend impl_t deepCopy(impl_t const& rhs) { \ + impl_t result(rhs); \ + VVI_IDC_EXPAND__( __VA_ARGS__ ) \ + return result; \ + } + #define VIDCH__(arg) result.arg = deepCopy(rhs.arg); #define VVI_IDC_EXPAND__(...) MKFNS(VVI_IDC_EXPAND__,##__VA_ARGS__) @@ -134,6 +141,11 @@ namespace detail { // Compare macro helpers +#define VVI_IMPL_COMPARE__(impl_t, ...) \ + friend bool compare(impl_t const& lhs, impl_t const& rhs) { \ + return VVI_ICOM_EXPAND__( __VA_ARGS__); \ + } + #define VICOMH__(arg) vvi::detail::compare(lhs.arg, rhs.arg) #define VVI_ICOM_EXPAND__(...) MKFNS(VVI_ICOM_EXPAND__,##__VA_ARGS__) @@ -219,10 +231,6 @@ public: \ #define VVI_VIEW_DEF_CTOR(view_t) \ view_t() = default; -// TODO: Is this still relevant? -//#define VVI_VIEW_SHALLOW_COPY__(view_t) \ -//public: \ -// void shallowCopy(view_t const& rhs) {*this = rhs;} #define VIEW_INTERFACE_METACLASS(value_t, view_t, impl_t) \ public: \ From 43cd5439b54d5422c5294de911291d474a97ac93 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Fri, 6 Sep 2024 21:51:17 -0700 Subject: [PATCH 19/44] SPHERAL_ENABLE_VVI for cuda build. --- .gitlab/specs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/specs.yml b/.gitlab/specs.yml index 676b22488..898de1eba 100644 --- a/.gitlab/specs.yml +++ b/.gitlab/specs.yml @@ -36,7 +36,7 @@ .cuda_11_gcc_spectrum: variables: SPEC: 'gcc@$GCC_VERSION+cuda cuda_arch=70' - EXTRA_CMAKE_ARGS: '-DENABLE_TIMER=On' + EXTRA_CMAKE_ARGS: '-DENABLE_TIMER=On -DSPHERAL_ENABLE_VVI=On' .oneapi_2022_1_mvapich2: variables: From 4a43482cb0fe0484f0db683607db0f9b4393b005 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Fri, 6 Sep 2024 21:51:45 -0700 Subject: [PATCH 20/44] Deleting unused tests/ directory. --- tests/cpp/Kernel/CMakeLists.txt | 0 tests/unit/Field/testTRTField.py | 38 -------------------------------- 2 files changed, 38 deletions(-) delete mode 100644 tests/cpp/Kernel/CMakeLists.txt delete mode 100644 tests/unit/Field/testTRTField.py diff --git a/tests/cpp/Kernel/CMakeLists.txt b/tests/cpp/Kernel/CMakeLists.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/unit/Field/testTRTField.py b/tests/unit/Field/testTRTField.py deleted file mode 100644 index 19243d288..000000000 --- a/tests/unit/Field/testTRTField.py +++ /dev/null @@ -1,38 +0,0 @@ -from Spheral import * - -import os -import unittest - -def main(): - WT1d = TableKernel1d(BSplineKernel1d(), 100) - eos1d = GammaLawGasMKS1d(2.0, 2.0) - nodes1d = makeFluidNodeList1d("nodes1d", eos1d) - nodes1d.numInternalNodes = 10 - - print(ThirdRankTensor1d.nDimensions) - print(FourthRankTensor1d.nDimensions) - print(FifthRankTensor1d.nDimensions) - - #x0 = vector_of_int(range(10)) - ##v0 = VectorIntField1d("vector field", nodes1d, x0) - #v0 = ThirdRankTensorField1d("third rank tensor field 1d control", nodes1d) - - #print(len(v0)) - - #print(v0[0].nDimensions) - #print(v0[1]) - #print(v0[2]) - #print(v0[3]) - - #for i in range(3,nodes1d.numInternalNodes): - # print(v0[i]) - - - - -#------------------------------------------------------------------------------- -# Run those tests. -#------------------------------------------------------------------------------- -if __name__ == "__main__": - main() - #unittest.main() From dd823479630fc1d41f8928e4a7f84ab9ea47bb8e Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Fri, 6 Sep 2024 21:55:19 -0700 Subject: [PATCH 21/44] rm Kernel dir. --- tests/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4b1f40e25..66ff6d23d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,3 +1,2 @@ add_subdirectory(cpp/Field) -add_subdirectory(cpp/Kernel) add_subdirectory(cpp/Utilities) From d850f676d6c45b145740ff9a0c2426a34b6212c3 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 9 Sep 2024 10:33:20 -0700 Subject: [PATCH 22/44] QI tests for VVI on/off --- src/Utilities/QuadraticInterpolator.hh | 14 +++++++++----- src/Utilities/QuadraticInterpolatorInline.hh | 4 ++-- src/Utilities/ValueViewInterface.hh | 2 +- src/Utilities/ValueViewInterfaceImpl.hh | 9 +++++---- .../cpp/Utilities/quadratic_interpolator_tests.cc | 6 ++++-- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/Utilities/QuadraticInterpolator.hh b/src/Utilities/QuadraticInterpolator.hh index 73fa5b417..85b303bf1 100644 --- a/src/Utilities/QuadraticInterpolator.hh +++ b/src/Utilities/QuadraticInterpolator.hh @@ -20,6 +20,7 @@ VVI_IMPL_BEGIN class QuadraticInterpolator { public: + using CoeffsType = vvi::vector; //--------------------------- Public Interface ---------------------------// // Constructors, destructors template @@ -35,7 +36,7 @@ public: const std::vector& yvals); // Comparisons - SPHERAL_HOST_DEVICE bool operator==(const QuadraticInterpolator& rhs) const; + bool operator==(const QuadraticInterpolator& rhs) const; // Interpolate for the y value SPHERAL_HOST_DEVICE double operator()(const double x) const; @@ -55,16 +56,16 @@ public: SPHERAL_HOST_DEVICE double xmin() const; // Minimum x coordinate for table SPHERAL_HOST_DEVICE double xmax() const; // Maximum x coordinate for table SPHERAL_HOST_DEVICE double xstep() const; // delta x between tabulated values - SPHERAL_HOST_DEVICE const std::vector& coeffs() const; // the fitting coefficients + SPHERAL_HOST_DEVICE const CoeffsType& coeffs() const; // the fitting coefficients - VVI_IMPL_DEEPCOPY(QuadraticInterpolator) + VVI_IMPL_DEEPCOPY(QuadraticInterpolator, mcoeffs) VVI_IMPL_COMPARE(QuadraticInterpolator, mN1, mXmin, mXmax, mcoeffs) private: //--------------------------- Private Interface --------------------------// // Member data size_t mN1; double mXmin, mXmax, mXstep; - std::vector mcoeffs; + CoeffsType mcoeffs; }; VVI_IMPL_END @@ -80,6 +81,9 @@ class PTR_VIEW_METACLASS_DEFAULT \ ((QuadraticInterpolator), (QuadraticInterpolatorView), (code)) class QuadraticInterpolator__( + + using CoeffsType = typename ImplType::CoeffsType; + template QuadraticInterpolator(const double xmin, const double xmax, @@ -112,7 +116,7 @@ class QuadraticInterpolator__( double xmin() const { return VVI_IMPL_INST().xmin(); } double xmax() const { return VVI_IMPL_INST().xmax(); } double xstep() const { return VVI_IMPL_INST().xstep(); } - const std::vector& coeffs() const { return VVI_IMPL_INST().coeffs(); } + const vvi::vector& coeffs() const { return VVI_IMPL_INST().coeffs(); } ); #endif // VVI_ENABLED diff --git a/src/Utilities/QuadraticInterpolatorInline.hh b/src/Utilities/QuadraticInterpolatorInline.hh index 191393847..1b3a8b67b 100644 --- a/src/Utilities/QuadraticInterpolatorInline.hh +++ b/src/Utilities/QuadraticInterpolatorInline.hh @@ -123,7 +123,7 @@ QuadraticInterpolator::prime2(const double /*x*/, inline size_t QuadraticInterpolator::lowerBound(const double x) const { - const auto result = 3u*std::min(mN1, size_t(std::max(0.0, x - mXmin)/mXstep)); + const auto result = 3u*RAJA_MIN(mN1, size_t(RAJA_MAX(0.0, x - mXmin)/mXstep)); ENSURE(result <= 3u*mN1); return result; } @@ -156,7 +156,7 @@ QuadraticInterpolator::xstep() const { } inline -const std::vector& +const vvi::vector& QuadraticInterpolator::coeffs() const { return mcoeffs; } diff --git a/src/Utilities/ValueViewInterface.hh b/src/Utilities/ValueViewInterface.hh index e535838cc..e66027724 100644 --- a/src/Utilities/ValueViewInterface.hh +++ b/src/Utilities/ValueViewInterface.hh @@ -33,7 +33,7 @@ using SPHERALCopyable = chai::CHAICopyable; #if defined(VVI_ENABLED) #define VVI_IMPL_DEEPCOPY(...) VVI_IMPL_DEEPCOPY__( __VA_ARGS__ , void) -#define VVI_IMPL_COMPARE(...) VVI_IMPL_COMPARE__( __VA_ARGS__. void) +#define VVI_IMPL_COMPARE(...) VVI_IMPL_COMPARE__( __VA_ARGS__, void) #else diff --git a/src/Utilities/ValueViewInterfaceImpl.hh b/src/Utilities/ValueViewInterfaceImpl.hh index e45ae77d7..07b0cb800 100644 --- a/src/Utilities/ValueViewInterfaceImpl.hh +++ b/src/Utilities/ValueViewInterfaceImpl.hh @@ -45,6 +45,7 @@ namespace detail { SPHERAL_HOST_DEVICE ViewInterface() = default; SPHERAL_HOST ViewInterface(SmartPtrType&& rhs) : SmartPtrType(std::forward(rhs)) {} + SPHERAL_HOST_DEVICE bool operator==(ViewInterface const& rhs) const { return this->sptr_data() == rhs.sptr_data(); } }; @@ -66,9 +67,9 @@ namespace detail { #if !defined(SPHERAL_ENABLE_VVI) ValueInterface(m_ImplType* rhs) : view_type((rhs)) {} #endif - ValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {std::cout << "fwd Ctor\n";} - ValueInterface(ValueInterface const& rhs) : ValueInterface(VVI_MAKE_SHARED( deepCopy(rhs.sptr_data()) )) {std::cout << "Copy Ctor\n";} - ValueInterface& operator=(ValueInterface const& rhs) { ViewType::operator=( VVI_MAKE_SHARED( deepCopy( rhs.sptr_data() ) ) ); std::cout << "Ass Op/n"; return *this; } + ValueInterface(m_SmartPtrType&& s_ptr) : view_type(std::forward(s_ptr)) {} + ValueInterface(ValueInterface const& rhs) : ValueInterface(VVI_MAKE_SHARED( deepCopy(rhs.sptr_data()) )) {} + ValueInterface& operator=(ValueInterface const& rhs) { ViewType::operator=( VVI_MAKE_SHARED( deepCopy( rhs.sptr_data() ) ) ); return *this; } bool operator==(ValueInterface const& rhs) const { return compare(this->sptr_data(), rhs.sptr_data()); } }; @@ -78,7 +79,7 @@ namespace detail { { return lhs == rhs; } template - bool compare(Spheral::ManagedVector const& lhs, Spheral::ManagedVector const& rhs) + bool compare(::Spheral::ManagedVector const& lhs, ::Spheral::ManagedVector const& rhs) { return ::Spheral::compare(lhs, rhs); } } diff --git a/tests/cpp/Utilities/quadratic_interpolator_tests.cc b/tests/cpp/Utilities/quadratic_interpolator_tests.cc index e185e1b1d..182d371e9 100644 --- a/tests/cpp/Utilities/quadratic_interpolator_tests.cc +++ b/tests/cpp/Utilities/quadratic_interpolator_tests.cc @@ -97,11 +97,13 @@ TEST(QuadraticInterpolatorTest, OperatorParen) SPHERAL_ASSERT_EQ(q_int(3, 0), 1.5); SPHERAL_ASSERT_EQ(q_int(4, 0), 2); } + +#ifdef SPHERAL_ENABLE_VVI // Setting up G Test for QuadraticInterpolator template class QuadraticInterpolatorTypedTest : public::testing::Test {}; // All QuadraticInterpolatorTets cases will run over each type in EXEC_TYPES. TYPED_TEST_CASE(QuadraticInterpolatorTypedTest, EXEC_TYPES); - -//#include "quadratic_interpolator_view_tests.hh" +#include "quadratic_interpolator_view_tests.hh" +#endif From 9f4878175e7e673e15d627259e85e18d1d6f10fd Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 9 Sep 2024 11:14:30 -0700 Subject: [PATCH 23/44] Adding --test option to hcb.py to run make test during CI. --- .gitlab/scripts.yml | 2 +- scripts/devtools/host-config-build.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.gitlab/scripts.yml b/.gitlab/scripts.yml index f78314f5b..b6791f6e7 100644 --- a/.gitlab/scripts.yml +++ b/.gitlab/scripts.yml @@ -26,7 +26,7 @@ script: - CI_BUILD_DIR=$(cat ci-dir.txt) - cd $CI_BUILD_DIR && cat job-name.txt - - $BUILD_ALLOC ./$SCRIPT_DIR/devtools/host-config-build.py --host-config gitlab.cmake --build $EXTRA_CMAKE_ARGS + - $BUILD_ALLOC ./$SCRIPT_DIR/devtools/host-config-build.py --host-config gitlab.cmake --build --test $EXTRA_CMAKE_ARGS .build_and_test: extends: [.build] diff --git a/scripts/devtools/host-config-build.py b/scripts/devtools/host-config-build.py index 0c90c45e8..ea3b0f39b 100755 --- a/scripts/devtools/host-config-build.py +++ b/scripts/devtools/host-config-build.py @@ -31,6 +31,9 @@ def parse_args(): parser.add_argument('--build', action='store_true', help='Run make -j install after configuring build dirs.') + parser.add_argument('--test', action='store_true', + help='Run make test after building.') + parser.add_argument('--lc-modules', type=str, default="", help='LC Modules to use during build, install and smoke test. This is not used if --build is not enabled.') @@ -109,5 +112,13 @@ def main(): sexe("{0} {1} --build . -j 48 --target install".format(ml_cmd, cmake_cmd), echo=True, ret_output=False) + if args.test: + print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") + print("~~~~~ Running test Spheral") + print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") + + sexe("make test".format(), echo=True, ret_output=False) + + if __name__ == "__main__": main() From ad518f0752df2f71d60d98a82f7193aa1372c055 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 9 Sep 2024 11:27:02 -0700 Subject: [PATCH 24/44] Removing comment from MV impl. --- scripts/devtools/host-config-build.py | 2 +- src/Utilities/ManagedVector.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/devtools/host-config-build.py b/scripts/devtools/host-config-build.py index ea3b0f39b..9e04332b3 100755 --- a/scripts/devtools/host-config-build.py +++ b/scripts/devtools/host-config-build.py @@ -114,7 +114,7 @@ def main(): if args.test: print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") - print("~~~~~ Running test Spheral") + print("~~~~~ Running make test Spheral") print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") sexe("make test".format(), echo=True, ret_output=False) diff --git a/src/Utilities/ManagedVector.hh b/src/Utilities/ManagedVector.hh index 1070b8a27..ad0fc086a 100644 --- a/src/Utilities/ManagedVector.hh +++ b/src/Utilities/ManagedVector.hh @@ -120,7 +120,7 @@ public: for (size_t i = 0; i < m_size; i++) new (&MA::operator[](i)) DataType(rhs[i]); } #else - SPHERAL_HOST_DEVICE constexpr inline ManagedVector(ManagedVector const& rhs) noexcept : MA(rhs), m_size(rhs.m_size) {printf("MV Copy w/ Ref Semantics.\n");} + SPHERAL_HOST_DEVICE constexpr inline ManagedVector(ManagedVector const& rhs) noexcept : MA(rhs), m_size(rhs.m_size) {} #endif // --------------------- From 74201bbf6abcbbc42727d38784a063143adc3d25 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 9 Sep 2024 11:31:03 -0700 Subject: [PATCH 25/44] Turn off blt target printing. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8f61c19cd..17fd9211e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,7 +71,7 @@ foreach(_package ${_packages}) add_subdirectory(${_package}) endforeach() -blt_print_target_properties(TARGET Spheral_Utilities) +#blt_print_target_properties(TARGET Spheral_Utilities) if(NOT ENABLE_DEV_BUILD) # Retrieve the global list populated in spheral_obj_add_library From 3747afa7898040a45adfb468be07d9ab4f27a7a9 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 9 Sep 2024 16:41:50 -0700 Subject: [PATCH 26/44] Cleaning up field tests. --- extern/chai | 2 +- tests/cpp/Field/CMakeLists.txt | 18 +-- tests/cpp/Field/field_tests.cc | 105 +++------------ tests/cpp/Field/fieldview_tests.cc | 202 ----------------------------- 4 files changed, 24 insertions(+), 303 deletions(-) delete mode 100644 tests/cpp/Field/fieldview_tests.cc diff --git a/extern/chai b/extern/chai index 79cb51f83..2a53f5377 160000 --- a/extern/chai +++ b/extern/chai @@ -1 +1 @@ -Subproject commit 79cb51f8347c05b38ec2f0feaaa640b46bd1c440 +Subproject commit 2a53f53777a9fa98f0260a435a2283f05eb01feb diff --git a/tests/cpp/Field/CMakeLists.txt b/tests/cpp/Field/CMakeLists.txt index 31d8d2ff0..5e2604ae5 100644 --- a/tests/cpp/Field/CMakeLists.txt +++ b/tests/cpp/Field/CMakeLists.txt @@ -1,12 +1,6 @@ -#spheral_add_test( -# NAME field_tests -# SOURCES field_tests.cc -# DEPENDS_ON Spheral_NodeList Spheral_Geometry Spheral_Hydro Spheral_DataOutput Spheral_Utilities -# #DEBUG_LINKER -#) -# -#spheral_add_test( -# NAME fieldview_tests -# SOURCES fieldview_tests.cc -# #DEBUG_LINKER -#) +spheral_add_test( + NAME field_tests + SOURCES field_tests.cc + DEPENDS_ON Spheral_NodeList Spheral_Geometry Spheral_Hydro Spheral_DataOutput Spheral_Utilities + #DEBUG_LINKER +) diff --git a/tests/cpp/Field/field_tests.cc b/tests/cpp/Field/field_tests.cc index bf7c6fe7c..e9c99cadd 100644 --- a/tests/cpp/Field/field_tests.cc +++ b/tests/cpp/Field/field_tests.cc @@ -4,12 +4,9 @@ #include "Field/Field.hh" #include "NodeList/NodeList.hh" -#include "Field/SphArray.hh" - using DIM3 = Spheral::Dim<3>; using FieldBase = Spheral::FieldBase; using FieldDouble = Spheral::Field; -using FieldViewDouble = Spheral::FieldView; using NodeList_t = Spheral::NodeList; class FieldTest : public::testing::Test{ @@ -33,7 +30,6 @@ TEST_F(FieldTest, NameCtor) { std::string field_name = "Field::NameCtor"; FieldDouble field(field_name); - std::cout << "check\n"; SPHERAL_ASSERT_EQ(field.name(), field_name); SPHERAL_ASSERT_EQ(field.size(), 0); SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); @@ -65,12 +61,6 @@ GPU_TYPED_TEST_P(FieldTypedTest, NameNodeListValCtor) SPHERAL_ASSERT_EQ(field.name(), field_name); SPHERAL_ASSERT_EQ(field.size(), 10); - auto field_v = field.toView(); - - RAJA::forall(TRS_UINT(0,10), - [=] SPHERAL_HOST_DEVICE (int i) { - SPHERAL_ASSERT_EQ(field_v[i], 4); - }); SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); } SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); @@ -90,21 +80,6 @@ GPU_TYPED_TEST_P(FieldTypedTest, CopyCtor) SPHERAL_ASSERT_EQ(copy_field.name(), field_name); SPHERAL_ASSERT_EQ(copy_field.size(), 10); - auto field_v = field.toView(); - auto copy_field_v = copy_field.toView(); - - RAJA::forall(TRS_UINT(0,10), - [=] SPHERAL_HOST_DEVICE (int i) { - SPHERAL_ASSERT_EQ(copy_field_v[i], 4); - copy_field_v[i] = 5; - }); - - RAJA::forall(TRS_UINT(0,10), - [=] SPHERAL_HOST_DEVICE (int i) { - SPHERAL_ASSERT_EQ(field_v[i], 4); - SPHERAL_ASSERT_EQ(copy_field_v[i], 5); - }); - SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 7); SPHERAL_ASSERT_NE(&field[0], ©_field[0]); } @@ -112,35 +87,6 @@ GPU_TYPED_TEST_P(FieldTypedTest, CopyCtor) } -GPU_TYPED_TEST_P(FieldTypedTest, FieldView) -{ - using WORK_EXEC_POLICY = TypeParam; - - { - std::string field_name = "Field::FieldView"; - FieldDouble field(field_name, gpu_this->test_node_list, 4); - - FieldViewDouble field_v(field); - - SPHERAL_ASSERT_EQ(field_v.size(), 10); - - RAJA::forall(TRS_UINT(0,10), - [=] SPHERAL_HOST_DEVICE (int i) { - field_v[i] = 5; - }); - - RAJA::forall(TRS_UINT(0,10), - [=] SPHERAL_HOST_DEVICE (int i) { - SPHERAL_ASSERT_EQ(field_v[i], 5); - }); - - SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); - SPHERAL_ASSERT_EQ(&field[0], &field_v[0]); - } - SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); -} - - TEST_F(FieldTest, AssignmentFieldBase) { { @@ -150,7 +96,7 @@ TEST_F(FieldTest, AssignmentFieldBase) FieldBase* base = &field; SPHERAL_ASSERT_EQ(base->name(), field_name); - //SPHERAL_ASSERT_EQ(field.size(), 0); + SPHERAL_ASSERT_EQ(field.size(), base->size()); SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 6); } SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); @@ -164,29 +110,15 @@ GPU_TYPED_TEST_P(FieldTypedTest, AssignmentField) std::string field_name = "Field::AssignmentField"; FieldDouble field(field_name, gpu_this->test_node_list, 4); - FieldDouble copy_field = field; + FieldDouble copy_field("SomeOtherField"); + copy_field = field; - SPHERAL_ASSERT_EQ(copy_field.name(), field_name); SPHERAL_ASSERT_EQ(copy_field.size(), 10); - auto field_v = field.toView(); - auto copy_field_v = copy_field.toView(); - - RAJA::forall(TRS_UINT(0,10), - [=] SPHERAL_HOST_DEVICE (int i) { - SPHERAL_ASSERT_EQ(copy_field_v[i], 4); - copy_field_v[i] = 5; - }); - - RAJA::forall(TRS_UINT(0,10), - [=] SPHERAL_HOST_DEVICE (int i) { - SPHERAL_ASSERT_EQ(field_v[i], 4); - SPHERAL_ASSERT_EQ(copy_field_v[i], 5); - }); - SPHERAL_ASSERT_NE(&field[0], ©_field[0]); - SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 7); + // Is this behavior correct? Shouldn't it be 7? + SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); } SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); } @@ -199,26 +131,25 @@ GPU_TYPED_TEST_P(FieldTypedTest, AssignmentContainerType) std::string field_name = "Field::AssignmentContainer"; FieldDouble field(field_name, gpu_this->test_node_list, 4); - using ContainerType = FieldDouble::ContainerType; + using ContainerType = std::vector; ContainerType data(10); RAJA::forall(TRS_UINT(0,10), - [=] SPHERAL_HOST_DEVICE (int i) { + [&] SPHERAL_HOST (int i) { data[i] = i; }); field = data; - auto field_v = field.toView(); + auto field_v = &field; RAJA::forall(TRS_UINT(0,10), [=] SPHERAL_HOST_DEVICE (int i) { - field_v[i] *= 2; + field_v->at(i) *= 2; }); RAJA::forall(TRS_UINT(0,10), [=] SPHERAL_HOST_DEVICE (int i) { - //SPHERAL_ASSERT_EQ(field[i], i); // Should not change we deep copy in lambdas... - SPHERAL_ASSERT_EQ(field_v[i], i*2); + SPHERAL_ASSERT_EQ(field_v->at(i), i*2); }); SPHERAL_ASSERT_NE(&field[0], &data[0]); @@ -237,18 +168,18 @@ TEST_F(FieldTest, AssignmentDataType) SPHERAL_ASSERT_EQ(field.size(), 10); - auto field_v = field.toView(); + auto field_v = &field; RAJA::forall(TRS_UINT(0,10), [=] SPHERAL_HOST (int i) { - SPHERAL_ASSERT_EQ(field_v[i], 4); + SPHERAL_ASSERT_EQ(field_v->at(i), 4); }); field = double(3); RAJA::forall(TRS_UINT(0,10), [=] SPHERAL_HOST (int i) { - SPHERAL_ASSERT_EQ(field_v[i], 3); + SPHERAL_ASSERT_EQ(field_v->at(i), 3); }); } @@ -262,12 +193,12 @@ GPU_TYPED_TEST_P(FieldTypedTest, size) { std::string field_name = "Field::size"; FieldDouble field(field_name, gpu_this->test_node_list); - auto field_v = field.toView(); + //auto field_v = field.toView(); SPHERAL_ASSERT_EQ(field.size(), 10); - EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) - SPHERAL_ASSERT_EQ(field_v.size(), 10); - EXEC_IN_SPACE_END() + //EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) + // SPHERAL_ASSERT_EQ(field_v.size(), 10); + //EXEC_IN_SPACE_END() SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); } SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); @@ -276,8 +207,6 @@ GPU_TYPED_TEST_P(FieldTypedTest, size) REGISTER_TYPED_TEST_SUITE_P(FieldTypedTest, NameNodeListValCtor, CopyCtor, - FieldView, - //AssignmentFieldBase, AssignmentField, AssignmentContainerType, size diff --git a/tests/cpp/Field/fieldview_tests.cc b/tests/cpp/Field/fieldview_tests.cc deleted file mode 100644 index d4dc26b39..000000000 --- a/tests/cpp/Field/fieldview_tests.cc +++ /dev/null @@ -1,202 +0,0 @@ -#include "test-utilities.hh" -#include "test-basic-exec-policies.hh" - -#include "Field/Field.hh" -#include "Field/FieldView.hh" - -using DIM3 = Spheral::Dim<3>; -using FieldDouble = Spheral::Field; -// -using FieldViewDouble = Spheral::FieldView; - -class FieldViewTest : public::testing::Test{}; - -// Setting up G Test for Fiedl -TYPED_TEST_SUITE_P(FieldViewTypedTest); -template -class FieldViewTypedTest : public FieldViewTest {}; - -// All ManagedVectorTets cases will run over each type in EXEC_TYPES. -//TYPED_TEST_CASE(FieldViewTypedTest, EXEC_TYPES); - - -GPU_TYPED_TEST_P(FieldViewTypedTest, DefaultCtor) -{ - using WORK_EXEC_POLICY = TypeParam; - - { - - std::shared_ptr sptr; - std::cout << sptr.get() << std::endl; - - FieldDouble field("test"); - FieldViewDouble fieldv = field.toView(); - SPHERAL_ASSERT_EQ(fieldv.size(), 0); - - RAJA::forall(TRS_UINT(0,10), - [=] SPHERAL_HOST_DEVICE (int i) { - SPHERAL_ASSERT_EQ(fieldv.size(), 0); - }); - } -} - - -//GPU_TYPED_TEST_P(FieldViewTypedTest, CopyCtor) -//{ -// using WORK_EXEC_POLICY = TypeParam; -// -// { -// FieldViewDouble field(); -// -// FieldViewDouble copy_field(field); -// -// SPHERAL_ASSERT_EQ(copy_field.size(), 10); -// -// RAJA::forall(TRS_UINT(0,10), -// [=] SPHERAL_HOST_DEVICE (int i) { -// copy_field[i] == 4; -// }); -// -// RAJA::forall(TRS_UINT(0,10), -// [=] SPHERAL_HOST_DEVICE (int i) { -// SPHERAL_ASSERT_EQ(field[i], 4); -// }); -// -// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 7); -// SPHERAL_ASSERT_EQ(&field[0], ©_field[0]); -// } -// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); -//} - - -// TODO: ... -//TEST_F(FieldViewTest, AssignmentFieldViewBase) -//{ -// { -// std::string field_name = "Field::AssignmentFieldBase"; -// FieldDouble field(field_name); -// SPHERAL_ASSERT_EQ(field.name(), field_name); -// SPHERAL_ASSERT_EQ(field.size(), 0); -// SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); -// } -// SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); -//} - -//GPU_TYPED_TEST_P(FieldTypedTest, AssignmentField) -//{ -// using WORK_EXEC_POLICY = TypeParam; -// -// { -// std::string field_name = "Field::CopyCtor"; -// FieldDouble field(field_name, gpu_this->test_node_list, 4); -// -// FieldDouble copy_field = field; -// -// SPHERAL_ASSERT_EQ(copy_field.name(), ""); -// SPHERAL_ASSERT_EQ(copy_field.size(), 10); -// -// RAJA::forall(TRS_UINT(0,10), -// [=] SPHERAL_HOST_DEVICE (int i) { -// copy_field[i] == 4; -// }); -// -// RAJA::forall(TRS_UINT(0,10), -// [=] SPHERAL_HOST_DEVICE (int i) { -// SPHERAL_ASSERT_EQ(field[i], 4); -// }); -// -// SPHERAL_ASSERT_EQ(&field[0], ©_field[0]); -// -// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 7); -// } -// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); -//} -// -//GPU_TYPED_TEST_P(FieldTypedTest, AssignmentContainerType) -//{ -// using WORK_EXEC_POLICY = TypeParam; -// -// { -// std::string field_name = "Field::CopyCtor"; -// FieldDouble field(field_name, gpu_this->test_node_list, 4); -// -// using ContainerType = FieldDouble::ContainerType; -// ContainerType data(10); -// -// RAJA::forall(TRS_UINT(0,10), -// [=] SPHERAL_HOST_DEVICE (int i) { -// data[i] = i; -// }); -// -// field = data; -// -// RAJA::forall(TRS_UINT(0,10), -// [=] SPHERAL_HOST_DEVICE (int i) { -// field[i] *= 2; -// }); -// -// RAJA::forall(TRS_UINT(0,10), -// [=] SPHERAL_HOST_DEVICE (int i) { -// SPHERAL_ASSERT_EQ(field[i], i*2); -// }); -// -// SPHERAL_ASSERT_EQ(&field[0], &data[0]); -// -// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); -// } -// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); -//} -// -//TEST_F(FieldTest, AssignmentDataType) -//{ -// { -// std::string field_name = "Field::NameCtor"; -// FieldDouble field(field_name, this->test_node_list, 4); -// -// SPHERAL_ASSERT_EQ(field.size(), 10); -// SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); -// -// RAJA::forall(TRS_UINT(0,10), -// [=] SPHERAL_HOST (int i) { -// SPHERAL_ASSERT_EQ(field[i], 4); -// }); -// -// field = double(3); -// -// SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 6); -// RAJA::forall(TRS_UINT(0,10), -// [=] SPHERAL_HOST (int i) { -// SPHERAL_ASSERT_EQ(field[i], 3); -// }); -// -// -// } -// SPHERAL_ASSERT_EQ(this->test_node_list.numFields(), 5); -//} -// -//GPU_TYPED_TEST_P(FieldTypedTest, size) -//{ -// using WORK_EXEC_POLICY = TypeParam; -// -// { -// std::string field_name = "Field::size"; -// FieldDouble field(field_name, gpu_this->test_node_list); -// EXEC_IN_SPACE_BEGIN(WORK_EXEC_POLICY) -// SPHERAL_ASSERT_EQ(field.size(), 10); -// EXEC_IN_SPACE_END() -// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 6); -// } -// SPHERAL_ASSERT_EQ(gpu_this->test_node_list.numFields(), 5); -//} - -REGISTER_TYPED_TEST_SUITE_P(FieldViewTypedTest, - DefaultCtor//, - //CopyCtor, - ////AssignmentFieldBase, - //AssignmentField, - //AssignmentContainerType, - //size - ); - -INSTANTIATE_TYPED_TEST_SUITE_P(FieldView, FieldViewTypedTest, EXEC_TYPES); - From 9f2920772fd26cf05a220e82ea5bcab4018da83b Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 9 Sep 2024 21:28:15 -0700 Subject: [PATCH 27/44] Hopefully fixing segfault blt_mpi_smoke test on ruby; Silencing warnings in field_test --- .gitlab/machines.yml | 2 +- tests/cpp/Field/field_tests.cc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitlab/machines.yml b/.gitlab/machines.yml index 8657ceeb4..6a9b6e981 100644 --- a/.gitlab/machines.yml +++ b/.gitlab/machines.yml @@ -8,7 +8,7 @@ variables: HOSTNAME: 'ruby' PARTITION: pdebug - BUILD_ALLOC: srun -N 1 -c 36 -p pdebug -t 60 + BUILD_ALLOC: salloc -N 1 -p pdebug -t 60 --exclusive TEST_ALLOC: '' extends: [.on_toss_4_x86] diff --git a/tests/cpp/Field/field_tests.cc b/tests/cpp/Field/field_tests.cc index e9c99cadd..1941e2676 100644 --- a/tests/cpp/Field/field_tests.cc +++ b/tests/cpp/Field/field_tests.cc @@ -53,7 +53,7 @@ TEST_F(FieldTest, NameNodeListCtor) GPU_TYPED_TEST_P(FieldTypedTest, NameNodeListValCtor) { - using WORK_EXEC_POLICY = TypeParam; + //using WORK_EXEC_POLICY = TypeParam; { std::string field_name = "Field::NodeListValCtor"; @@ -69,7 +69,7 @@ GPU_TYPED_TEST_P(FieldTypedTest, NameNodeListValCtor) GPU_TYPED_TEST_P(FieldTypedTest, CopyCtor) { - using WORK_EXEC_POLICY = TypeParam; + //using WORK_EXEC_POLICY = TypeParam; { std::string field_name = "Field::CopyCtor"; @@ -104,7 +104,7 @@ TEST_F(FieldTest, AssignmentFieldBase) GPU_TYPED_TEST_P(FieldTypedTest, AssignmentField) { - using WORK_EXEC_POLICY = TypeParam; + //using WORK_EXEC_POLICY = TypeParam; { std::string field_name = "Field::AssignmentField"; @@ -188,7 +188,7 @@ TEST_F(FieldTest, AssignmentDataType) GPU_TYPED_TEST_P(FieldTypedTest, size) { - using WORK_EXEC_POLICY = TypeParam; + //using WORK_EXEC_POLICY = TypeParam; { std::string field_name = "Field::size"; From 78cbad26fa59bf76005a2fe0f3e5d2756955351f Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Tue, 10 Sep 2024 12:18:01 -0700 Subject: [PATCH 28/44] Adding documentation for using the Value-View Interface. --- .../include/appendecies/cmake_config.rst.inc | 3 + .../developer/design/value_view_interface.rst | 531 ++++++++++++++++++ docs/developer/design_docs.rst | 1 + 3 files changed, 535 insertions(+) create mode 100644 docs/developer/design/value_view_interface.rst diff --git a/docs/build_guide/include/appendecies/cmake_config.rst.inc b/docs/build_guide/include/appendecies/cmake_config.rst.inc index bcf0e8f60..2fa10bb4a 100644 --- a/docs/build_guide/include/appendecies/cmake_config.rst.inc +++ b/docs/build_guide/include/appendecies/cmake_config.rst.inc @@ -86,6 +86,9 @@ In this section we list the CMake variables that can be tweaked for a Spheral bu ``ENABLE_DEV_BUILD`` (On, *Off*) Builds separate internal C++ libraries for faster code development. +``SPHERAL_ENABLE_VVI`` (On, *Off*) + Builds Spheral with the experimental Value-View Interface for GPU porting capabilities. + ``_DIR`` Directory of previously built TPL. diff --git a/docs/developer/design/value_view_interface.rst b/docs/developer/design/value_view_interface.rst new file mode 100644 index 000000000..effc82f0a --- /dev/null +++ b/docs/developer/design/value_view_interface.rst @@ -0,0 +1,531 @@ + +Value-View Interface Documentation +================================== + +Introduction +------------ + +The Value-View Interface (VVI) pattern is a tool to aid in porting complex class structures and design patterns that are not traditionally conducive to execution on the GPU. It can also be used as a stepping stone for performing incremental integration of a large codebase to the GPU. Allowing a code to port it's existing CPU friendly patterns to the GPU without a major initial refactor. + +VVI's philosophy is based largely upon ideas from CHAI. VVI builds upon from CHAI's ability to perform implicit data migration between the CPU and GPU for CHAI containers (such as ``chai::ManagedArray``\ ) by extending that capability to user defined types. + +.. note:: + + CHAI is designed to integrate as a plugin to RAJA codes, therefore the use of RAJA and CHAI are **essential** for the VVI pattern. + + +``chai::ManagedSharedPtr`` (developed specifically for VVI) is the backbone of the VVI Pattern. It is a ``std::shared_ptr`` implementation that supports implicit copies of the owned object between the CPU and GPU as well as dynamic dispatch with base types on the GPU. + +.. note:: + + We also provided CHAI with ``chai::ManagedVector``\ , a ``std::vector`` like CHAI class. This was not necessary for VVI but was instrumental in the port for Spheral to the GPU and will be seen later in this document. + + +The VALUE Interface +------------------- + +The Value-View interface enables a class to switch between value (\ *VALUE*\ ) and reference (\ *VIEW*\ ) semantics. A *VALUE* interface allows use of objects in a way that is indicative of normal C++. The semantics of a *VIEW* interface allow us to use the same instance of an object with reference semantics and provides the ability to be implicitly copyable between the HOST and DEVICE. + +The VIEW Interface +------------------ + +There are two paths for defining a *VIEW* interface. Each has it's tradeoffs and should be selected based on situation. + +Reference Syntax Interface +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Reference Interface lets a View act like a reference, calling functions of a class similarly to how you would with any reference of a type. This interface is the more verbose and allows users to specify exactly which calls can and cannot be made by the View interface. This is a more type safe implementation. Compile time errors will be thrown if a function call that is only usable in the Value Interface is called from a View Interface. However, if your code targeted for offload to the GPU often references the Implementation class by pointer, this could require many tedious changes and the [[#Pointer Syntax Interface]] might be a better first step. + +Pointer Syntax Interface +^^^^^^^^^^^^^^^^^^^^^^^^ + +The pointer interface allows a View object to act like a pointer. The interface required to define this implementation can be considerably smaller for many classes. It does not provide type safety. Therefore, you *could* call a function that should only be used by a Value object from a View object (you should still get a ``__host__ __device__`` warning if this happens in a GPU context). It is up to the developer to understand what they can and cannot call from a view like object. This is the "quick and dirty" conversion but is really useful for rapid implementation of VVI in certain cases. + +Use Cases for VVI +----------------- + +VVI was designed to help overcome a variety of complex obstacles in regards to GPU porting, such as: + + +* Classes with dynamically resizable container members and metadata members associated with the class that need to be consistent across execution contexts. +* Dynamic container-like classes of pointers to other dynamic container-like classes that need to be accessed with double index notation. +* Polymorphic objects with complex implementations. Where they are accessed through base class pointers with dynamic dispatch. +* CRTP compile time polymorphism design patterns across a variety of core classes. + +VVI should be avoided when possible. Simple classes with trivial members should be converted to be GPU capable directly. VVI is most useful when a copy of an object could result in a considerable data reallocation or when the class structure is not conducive to traditional GPU use. + +Definitions +----------- + +Implementation Class (\ ``ImplType``\ ) +####################################### + +The Implementation Class is a class targeted for use with the VVI pattern. This is usually a pre-existing class that a developer wants to use on the GPU. VVI is required when it's current members or class hierarchy / structure are not conventionally suited for device side use. + +Value Class (\ ``ValueType``\ ) +############################### + +An interface to the underlying implmentation class. This class is named the same as the ``ImplType``\ , and thus should require no changes to the current user code to use this type. The ``ValueType`` uses traditional C++ value copy semantics by default. However the semantic interface of how the type should be used should directly match the semantic conditions of the original ``ImplType``. + +View Class (\ ``ViewType``\ ) +############################# + +The View interface is what allows VVI to work seamlessly with ``RAJA`` execution contexts. A ``ViewType`` will have reference semantic like behavior. Meaning that copy construction of a ``ViewType`` does not invoke an allocation of the underlying class data, it instead references the underlying ``ValueType`` instance that it is associated with. + +Preparing Implementation Class for VVI +-------------------------------------- + +Private Members +^^^^^^^^^^^^^^^ + + +* All data members must be private. They may be accessed through ``get`` and ``set`` methods. This should be done first as this may require some changes through the codebase. + +.. important:: + + When using VVI the ``ImplType`` members cannot be accessed directly from *VALUE* interfaces so we must expose public members by forwarding a function that returns a reference to them. If we don't make this change, usage of the ``ImplType`` will be different when VVI is enabled vs disabled. + + +.. code-block:: c++ + + class foo { + public: + int m_var = 1; + std::vector m_vec; + }; + + ... + + foo f; + f.m_var = 5; + +.. code-block:: c++ + + class foo { + int m_var = 1; + std::vector m_vec; + public: + int& var() {return m_var} + }; + + ... + + foo f; + f.var() = 5 + +std::vector members +^^^^^^^^^^^^^^^^^^^ + + +* ``std::vector``\ members should be converted to ``vvi::vector``. ``vvi::vector`` is an alias for ``chai::ManagedVector`` that will revert to ``std::vector`` when VVI is disabled. + +.. code-block:: c++ + + class foo { + int m_var = 1; + vvi::vector m_vec; + public: + int& var() {return m_var} + }; + + +* A ``deepCopy()`` method must be provided that calls ``deepCopy()`` on each ``vvi``\ member. When VVI is enabled the ``vvi`` types use reference semantics. ``deepCopy()`` allows the *VALUE* interface to copy the object correctly. + ### DeepCopy & Compare +* In order to correctly perform Copy and Equivalence operations from the *VALUE* interface, special ``deepCopy`` and ``compare`` method needs to be provided from the ``ImplType``. +* Helper macros have been developed to aid in declaring these in your classes. + #### DeepCopy + ``VVI_IMPL_DEEPCOPY(impl_t, )`` This deep copy macro first performs the ``ImplType`` Copy Ctor, It will then manually perform a deep-copy on any other ``vvi`` type that exists as a member of the ``ImplType`` defined in the list. + #### Compare + ``VVI_IMPL_COMPARE(impl_t, )`` This macro will perform a value based comparison on all member names given (you probably want to list all members...). + +.. code-block:: c++ + + class foo { + int m_var = 1; + vvi::vector m_vec; + + public: + int& var() {return m_var} + + VVI_IMPL_DEEPCOPY(foo, m_vec) + VVI_IMPL_COMPARE(foo, m_vec, m_var) + }; + +chai::CHAICopyable +^^^^^^^^^^^^^^^^^^ + + +* If you intend to use the class as the element type of a chai container then a **default constructor** must be provided. +* A class containing a ``vvi`` type member above needs to inherit from ``chai::CHAICopyable``. This allows CHAI to recursively copy the appropriate data . + +.. code-block:: c++ + + class foo : public chai::CHAICopyable { + int m_var = 1; + vvi::vector m_vec; + + public: + int& var() {return m_var} + + VVI_IMPL_DEEPCOPY(foo, m_vec) + VVI_IMPL_COMPARE(foo, m_vec, m_var) + }; + + ... + + chai::ManagedArray my_arr; + +Classes w/ virtual methods +^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +* If the class has a virtual method such that a virtual table would be present for it or its derived classes the class needs to inherit from ``chai::Poly``. + +.. code-block:: c++ + + class base { + virtual void fooBar() = 0; + }; + + class derived : public base { + virtual void fooBar() override {...} + }; + +.. code-block:: c++ + + class base : chai::Poly{ + virtual void fooBar() = 0; + }; + + class derived : public base { + virtual void fooBar() override {...} + }; + +.. note:: + + Inheriting from ``chai::CHAIPoly`` includes the behavior of ``chai::CHAICopyable``. + + +Value View Interface Declaration Examples +----------------------------------------- + +Basic Class Interface +^^^^^^^^^^^^^^^^^^^^^ + +Below we demonstrate how to implement the Value-View Interface (VVI) pattern on a very basic class. + +We need to wrap our implementation class between ``VVI_IMPL_BEGIN`` and ``VVI_IMPL_END``. These macros encapsulate the code within a namespace ``vvimpl``. This is to allow us to name the future *VALUE* interface class with the same typename as the original implementation. + +.. code-block:: c++ + + VVI_IMPL_BEGIN + class foo + { + void doSomething() {}; + } + VVI_IMPL_END + +We need to forward declare *VALUE* class names. VVI details should be guarded with a ``VVI_ENABLED`` preprocessor check. + +.. code-block:: c++ + + #ifdef VVI_ENABLED + class foo; + +Basic VIEW Interface +~~~~~~~~~~~~~~~~~~~~ + +*VIEW* interfaces inherit default constructor, copy constructor, and assignment operator behavior provided by the underlying ``ViewInterface`` type that all *VIEW* interface classes inherit from. + +Most of the Value and View Interface class structure is repeatable and can be rather convoluted to write by hand. ``(PTR/REF)_(VALUE/VIEW)_METACLASS_DECL`` macros are provided to allow users to declare the Value and View interfaces type. + +We use helper macros with the naming convention ``__`` to aid in writing interfaces. Below we pass the type names of ``()``\ , ``()``\ , ``()`` to each ``_METACLASS_DECL`` macro. The final argument ``(code)`` is used to forward the class definitions further below. + +.. note:: + + **ALL** arguments to the ``_METACLASS_DECL`` macros **MUST** be wrapped in ``()``. + + +.. code-block:: c++ + + #define fooView__(code) PTR_VIEW_METACLASS_DECL( \ + (foo), (fooView), (vvimpl::foo), (code) ) + + class fooView__(); + +.. note:: + + We are using the ``PTR_`` implementation of the VVI Pattern in this case. This means all members of the implementation class are available to view objects through ``operator->()``. This leads to many definitions of *VIEW* interfaces to be empty. + +.. tip:: + + For empty *VIEW* interfaces, using default behavior as above, we can consolidate the class declaration and definition into one line with ``PTR_VIEW_METACLASS_DEFAULT`` + + .. code-block:: c++ + + class PTR_VIEW_METACLASS_DEFAULT( (foo), (fooView), (vvimpl::foo) ) + + +Basic Value Interface +~~~~~~~~~~~~~~~~~~~~~ + +*VALUE* interface default behavior is inherited from the ``vvi::detail::ValueInterface`` class. If not defined a Default Constructor will be used for the *VALUE* interface. Copy constructor, Assignment and Equivalence behavior is baked in, assuming the appropriate ``DEEPCOPY`` and ``COMPARE`` interfaces have been defined in the ``ImplType``. + +VVI Supplies ``VVI_IMPL_INST`` as a way to access the underlying instantiation of the implementation class and should be used to forward functions to the interface as seen below. + +.. code-block:: c++ + + #define foo__(code) PTR_VALUE_METACLASS_DECL( \ + (foo), (fooView), (vvimpl::foo), (code) ) + + class foo__( + public: + void doSomething() { VVI_IMPL_INST().doSomething(); } + ); + #endif + +Class w/ Custom Constructor & Vector Member +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Here we demonstrate using VVI with a class containing a ``vvi::vector`` member and a non default constructor. We have already made the necessary changes for VVI preparation ([[#std vector members]]). We will also assume that this class may be used as an element type to another CHAI container, therefore it must inherit from ``chai::CHAICopyable``. + +.. code-block:: c++ + + VVI_IMPL_BEGIN + class foo : public chai::CHAICopyable + { + public: + using vec_t = vvi::vector; + + foo(size_t sz) : m_vec(sz) {} + + vec_t& vec() {return m_vec;} + void doSomething() {}; + + VVI_IMPL_DEEPCOPY(foo, m_vec) + private: + vec_t m_vec; + } + VVI_IMPL_END + +Type Alias View Interface +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Declaring the interface class names and the *VIEW* interface are the same as above. However we would like to expose the type information for ``vec_t``. Defining the type alias in the *VIEW* interface makes it publicly visible to both *VIEW* and *VALUE* interfaces. + +.. code-block:: c++ + + #ifdef VVI_ENABLED + class foo; + + #define fooView__(code) PTR_VIEW_METACLASS_DECL( \ + (foo), (fooView), (vvimpl::foo), (code) ) + + class fooView__( + public: + using vec_t = ImplType::vec_t; + ); + +Custom Ctor Value Interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When defining a non-default constructor for *VALUE* interfaces we need to forward the arguments with ``VVI_VALUE_CTOR_ARGS()`` as below. The argument list needs to be passed within ``()``. + +.. code-block:: c++ + + #define foo__(code) PTR_VALUE_METACLASS_DECL( \ + (foo), (fooView), (vvimpl::foo), (code) ) + + class foo__( + public: + foo(size_t sz) : VVI_VALUE_CTOR_ARGS( (sz) ) {} + +``vvi::vector`` is an alias to a CHAI container type when VVI is enabled. CHAI containers use reference semantics and need to have their allocations released manually. The containers lifetime should be tied to the lifetime of ``foo``. Therefore, we need to manually free the underlying ``m_vec`` member in the destructor of the value class. + +.. code-block:: c++ + + ~foo() { VVI_IMPL_INST().m_vec.free(); } + + void doSomething() { VVI_IMPL_INST().doSomething(); } + vvi::vector& vec() { return VVI_IMPL_INST().vec(); } + ); + #endif + +Template Class Interface +^^^^^^^^^^^^^^^^^^^^^^^^ + +Templated classes can be used with the VVI Pattern. + +.. code-block:: c++ + + VVI_IMPL_BEGIN + template + class foo + { + T doSomething() {}; + } + VVI_IMPL_END + +Remember to template the forward declaration. + +.. code-block:: c++ + + #ifdef VVI_ENABLED + template + class foo; + +Template Interface Declarations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When defining the ``_METACLASS_DECL`` macros we need to template the exclusive types to the interface we are representing: + + +* For the ``VIEW`` macro: template **only** the ``value`` and ``impl`` type-names. +* For the ``VALUE`` macro : Template **only** the ``view`` and ``impl`` type-names. + +.. code-block:: c++ + + #define fooView__(code) PTR_VIEW_METACLASS_DECL( \ + (foo), (fooView), (vvimpl::foo), (code) ) + + #define foo__(code) PTR_VALUE_METACLASS_DECL( \ + (foo), (fooView), (vvimpl::foo), (code) ) + +In the interface declarations we need to ensure we template the interfaces. + +.. code-block:: c++ + + template + class fooView__(); + + template + class foo__( + public: + T doSomething() { return VVI_IMPL_INST().doSomething(); } + ); + + #endif + +Abstract & Polymorphic Class Interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +One of the strongest features of the VVI Pattern is the ability to use abstract class interfaces on the GPU. Below we are converting a *very* basic example of a polymorphic class for use in VVI. + +Implmentation Classes w/ Virtual Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Base classes with virtual interfaces need to inherit from ``vvi::poly``. This allows VVI to perform a specialized copies between the host and device such that the vitual table is preserved across execution spaces. + +.. note:: + + The implementation classes **MUST** provide default constructors in order to be used with VVI. + + +.. code-block:: c++ + + VVI_IMPL_BEGIN + class base : public chai::CHAIPoly + { + virtual int doSomething() = 0; + }; + + class derived : public base + { + derived() : base () {} + virtual int doSomething() override {} + }; + VVI_IMPL_END + +We need to forward declare for both ``base`` and ``derived``. + +.. code-block:: c++ + + #ifdef VVI_ENABLED + class base; + class derived; + +.. code-block:: c++ + + #define baseView__(code) PTR_VIEW_METACLASS_DECL( \ + (base), (baseView), (vvimpl::base), (code) ) + #define base__(code) PTR_VALUE_METACLASS_DECL( \ + (base), (baseView), (vvimpl::base), (code) ) + + #define derivedView__(code) PTR_VIEW_METACLASS_DECL( \ + (derived), (derivedView), (vvimpl::derived), (code) ) + #define derived__(code) PTR_VALUE_METACLASS_DECL( \ + (derived), (derivedView), (vvimpl::derived), (code) ) + +Base Class Interface +~~~~~~~~~~~~~~~~~~~~ + +``base`` is an abstract interface class. It should **NEVER** be constructable. However, we may want to declare the class to query type name information. We use ``VVI_DELETED_INTERFACE()`` to ensure a ``base`` *VALUE* type is not constructed. + +.. code-block:: c++ + + class baseView__(); + + class base__( + VVI_DELETED_INTERFACE(base) + ); + + #endif + +.. tip:: + + There exist shorthand macros for interfaces, the set of which are detailed in sections below. + + .. code-block:: c++ + + class PTR_VIEW_METACLASS_DEFAULT( (base), (baseView), (vvimpl::base) ) + class PTR_VALUE_METACLASS_DELETED( (base), (baseView), (vvimpl::base) ) + + +Derived Class Interface +~~~~~~~~~~~~~~~~~~~~~~~ + +The ``derived`` interface can be defined similarly to other *VALUE* and *VIEW* interfaces. Here we add ``VVI_UPCAST_CONVERSION_OP()`` to allow us to upcast a derived type to the base. This allows conversion from ``derivedView -> baseView`` as well as conversions of ``derived -> baseView``. + +.. code-block:: c++ + + class derivedView__( + VVI_UPCAST_CONVERSION_OP(baseView) + ); + + class derived__( + public: + T doSomething() { return VVI_IMPL_INST().doSomething(); } + ); + + #endif + +Macro Definitions +----------------- + +VALUE Interface Definition Macros +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +* ``VVI_VALUE_CTOR_ARGS((args))`` : Forward arguments of a non-default constructor for a *VALUE* interface. +* ``VVI_VALUE_DEF_CTOR(value_t)`` : Define default constructor for a *VALUE* interface. + +Interface Behavior Macros +^^^^^^^^^^^^^^^^^^^^^^^^^ + + +* ``VVI_DELETED_INTERFACE(type)`` : Delete the constructor, copy constructor and assignment operator. +* ``VVI_UPCAST_CONVERSION_OP(parent_t)`` : Define an implicit conversion operator to the defined parent type. + +Class Declaration Macros +^^^^^^^^^^^^^^^^^^^^^^^^ + + +* ``PTR_VALUE_METACLASS_DECL((value_t), (view_t), (impl_t), (code))`` +* ``REF_VALUE_METACLASS_DECL((value_t), (view_t), (impl_t), (code))`` +* ``PTR_VIEW_METACLASS_DECL((value_t), (view_t), (impl_t), (code))`` +* ``REF_VIEW_METACLASS_DECL((value_t), (view_t), (impl_t), (code))`` + +* ``PTR_VIEW_METACLASS_DEFAULT((value_t), (view_t), (impl_t))`` +* ``PTR_VALUE_METACLASS_DEFAULT((value_t), (view_t), (impl_t))`` + +* ``PTR_VALUE_METACLASS_DELETED((value_t), (view_t), (impl_t))`` diff --git a/docs/developer/design_docs.rst b/docs/developer/design_docs.rst index 160d101d1..e2a43bfec 100644 --- a/docs/developer/design_docs.rst +++ b/docs/developer/design_docs.rst @@ -9,5 +9,6 @@ Welcome to Spheral's design documentation. This documentation is a work in progr design/python_module_install.rst design/spack_uberenv_design.rst + design/value_view_interface.rst From 6b5c8bd4873c91a21cc320dbda8ccb5bbe74d34c Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Wed, 11 Sep 2024 09:59:32 -0700 Subject: [PATCH 29/44] Fixing title levels. --- docs/developer/design/value_view_interface.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/developer/design/value_view_interface.rst b/docs/developer/design/value_view_interface.rst index effc82f0a..664f3530b 100644 --- a/docs/developer/design/value_view_interface.rst +++ b/docs/developer/design/value_view_interface.rst @@ -58,17 +58,17 @@ Definitions ----------- Implementation Class (\ ``ImplType``\ ) -####################################### +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The Implementation Class is a class targeted for use with the VVI pattern. This is usually a pre-existing class that a developer wants to use on the GPU. VVI is required when it's current members or class hierarchy / structure are not conventionally suited for device side use. Value Class (\ ``ValueType``\ ) -############################### +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ An interface to the underlying implmentation class. This class is named the same as the ``ImplType``\ , and thus should require no changes to the current user code to use this type. The ``ValueType`` uses traditional C++ value copy semantics by default. However the semantic interface of how the type should be used should directly match the semantic conditions of the original ``ImplType``. View Class (\ ``ViewType``\ ) -############################# +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The View interface is what allows VVI to work seamlessly with ``RAJA`` execution contexts. A ``ViewType`` will have reference semantic like behavior. Meaning that copy construction of a ``ViewType`` does not invoke an allocation of the underlying class data, it instead references the underlying ``ValueType`` instance that it is associated with. From bc65da2cccdfed53215d201d3997a9b5290a9b5d Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Wed, 11 Sep 2024 11:29:44 -0700 Subject: [PATCH 30/44] put config header in the correct directory when spheral is a submodule. --- cmake/SetupSpheral.cmake | 3 ++- cmake/SpheralMacros.cmake | 2 +- src/CMakeLists.txt | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/SetupSpheral.cmake b/cmake/SetupSpheral.cmake index 74ee82785..84a752809 100644 --- a/cmake/SetupSpheral.cmake +++ b/cmake/SetupSpheral.cmake @@ -148,8 +148,9 @@ set_property(GLOBAL PROPERTY SPHERAL_CXX_DEPENDS "${SPHERAL_CXX_DEPENDS}") #------------------------------------------------------------------------------- # Prepare to build the src #------------------------------------------------------------------------------- -configure_file(src/config.hh.in +configure_file(${SPHERAL_ROOT_DIR}/src/config.hh.in ${PROJECT_BINARY_DIR}/src/config.hh) +include_directories(${PROJECT_BINARY_DIR}/src) add_subdirectory(${SPHERAL_ROOT_DIR}/src) diff --git a/cmake/SpheralMacros.cmake b/cmake/SpheralMacros.cmake index 759df3e0b..a68a39c80 100644 --- a/cmake/SpheralMacros.cmake +++ b/cmake/SpheralMacros.cmake @@ -59,7 +59,7 @@ macro(spheral_add_test) blt_add_library( NAME ${original_test_name}_lib SOURCES ${TEST_LIB_SOURCE} - SOURCES ${CMAKE_SOURCE_DIR}/src/spheralCXX.cc + SOURCES ${SPHERAL_ROOT_DIR}/src/spheralCXX.cc DEPENDS_ON ${SPHERAL_BLT_DEPENDS} ${original_deps} SHARED False ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e43a632c2..8478bd6f6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,6 @@ include(${SPHERAL_CMAKE_MODULE_PATH}/spheral/SpheralAddLibs.cmake) include(${SPHERAL_CMAKE_MODULE_PATH}/spheral/SpheralInstallPythonFiles.cmake) include_directories(.) -include_directories(${PROJECT_BINARY_DIR}/src) set(SPHERAL_PYTHON_INSTALL ${PROJECT_BINARY_DIR}/lib) From b57181b8492356a68ba2325a844fe2db84b2e4ec Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Thu, 12 Sep 2024 15:56:18 -0700 Subject: [PATCH 31/44] Do not clear INTERFACE_LINK_LIBRARIES --- cmake/spheral/SpheralAddLibs.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/spheral/SpheralAddLibs.cmake b/cmake/spheral/SpheralAddLibs.cmake index 19fe2389d..6e8b9e545 100644 --- a/cmake/spheral/SpheralAddLibs.cmake +++ b/cmake/spheral/SpheralAddLibs.cmake @@ -116,7 +116,7 @@ function(spheral_add_cxx_library package_name _cxx_obj_list) # set_target_properties(Spheral_${package_name} PROPERTIES ${_prop} "${temp_prop}") #endforeach() - set_target_properties(Spheral_${package_name} PROPERTIES INTERFACE_LINK_LIBRARIES "") + #set_target_properties(Spheral_${package_name} PROPERTIES INTERFACE_LINK_LIBRARIES "") # Convert package name to lower-case for export target name string(TOLOWER ${package_name} lower_case_package) From d4cada370c1b4dcf8b225ca0a775b300548ba18f Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Fri, 13 Sep 2024 09:07:54 -0700 Subject: [PATCH 32/44] Updating Relaese notes for VVI PR. --- RELEASE_NOTES.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index df68e6781..1d674dbb1 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,6 +5,15 @@ Version vYYYY.MM.p -- Release date YYYY-MM-DD Notable changes include: * New features / API changes: + * Value-View Interface for wrapping comlex classes in a GPU compatible Interface. + * Enabled w/ `SPHERAL_ENABLE_VVI=On`. + * Example executables demonstrating : + * Basic class w/ ManagedVector member. + * CRTP pattern. + * `Spheral::Field` like structure w/ an abstract inferface base class. + * VVI Implmenetation of `Spheral::QuadraticInterpolator`. + * CTest unit tests for `QuadraticInterpolator` and `Field`. + * CTest runs during GitlabCI build stage. * MPI variables are now wrapped as ``` SPHERAL_OP_SUM, SPHERAL_OP_MAX, SPHERAL_OP_MIN From 3566f3d42063afbc3e66800049b7efa0955e3458 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 16 Sep 2024 09:50:48 -0700 Subject: [PATCH 33/44] Removing unnecessary comment and configuration of config.in --- src/CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8478bd6f6..b4f031cd3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -72,15 +72,10 @@ if(NOT ENABLE_CXXONLY) PYB11) endif() -configure_file(config.hh.in - ${PROJECT_BINARY_DIR}/src/config.hh) - foreach(_package ${_packages}) add_subdirectory(${_package}) endforeach() -#blt_print_target_properties(TARGET Spheral_Utilities) - if(NOT ENABLE_DEV_BUILD) # Retrieve the global list populated in spheral_obj_add_library get_property(SPHERAL_OBJ_LIBS GLOBAL PROPERTY SPHERAL_OBJ_LIBS) From d1dc378a0e0930cbf75a2ed7f2f7d1bfdbc0bc83 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Tue, 17 Sep 2024 16:46:51 -0700 Subject: [PATCH 34/44] Formatting vvi docs. --- .../developer/design/value_view_interface.rst | 95 ++++++++++--------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/docs/developer/design/value_view_interface.rst b/docs/developer/design/value_view_interface.rst index 664f3530b..5014ae615 100644 --- a/docs/developer/design/value_view_interface.rst +++ b/docs/developer/design/value_view_interface.rst @@ -1,9 +1,10 @@ - +================================== Value-View Interface Documentation ================================== +************ Introduction ------------- +************ The Value-View Interface (VVI) pattern is a tool to aid in porting complex class structures and design patterns that are not traditionally conducive to execution on the GPU. It can also be used as a stepping stone for performing incremental integration of a large codebase to the GPU. Allowing a code to port it's existing CPU friendly patterns to the GPU without a major initial refactor. @@ -21,28 +22,31 @@ VVI's philosophy is based largely upon ideas from CHAI. VVI builds upon from CHA We also provided CHAI with ``chai::ManagedVector``\ , a ``std::vector`` like CHAI class. This was not necessary for VVI but was instrumental in the port for Spheral to the GPU and will be seen later in this document. +******************* The VALUE Interface -------------------- +******************* The Value-View interface enables a class to switch between value (\ *VALUE*\ ) and reference (\ *VIEW*\ ) semantics. A *VALUE* interface allows use of objects in a way that is indicative of normal C++. The semantics of a *VIEW* interface allow us to use the same instance of an object with reference semantics and provides the ability to be implicitly copyable between the HOST and DEVICE. +****************** The VIEW Interface ------------------- +****************** There are two paths for defining a *VIEW* interface. Each has it's tradeoffs and should be selected based on situation. Reference Syntax Interface -^^^^^^^^^^^^^^^^^^^^^^^^^^ +========================== -The Reference Interface lets a View act like a reference, calling functions of a class similarly to how you would with any reference of a type. This interface is the more verbose and allows users to specify exactly which calls can and cannot be made by the View interface. This is a more type safe implementation. Compile time errors will be thrown if a function call that is only usable in the Value Interface is called from a View Interface. However, if your code targeted for offload to the GPU often references the Implementation class by pointer, this could require many tedious changes and the [[#Pointer Syntax Interface]] might be a better first step. +The Reference Interface lets a View act like a reference, calling functions of a class similarly to how you would with any reference of a type. This interface is the more verbose and allows users to specify exactly which calls can and cannot be made by the View interface. This is a more type safe implementation. Compile time errors will be thrown if a function call that is only usable in the Value Interface is called from a View Interface. However, if your code targeted for offload to the GPU often references the Implementation class by pointer, this could require many tedious changes and the Pointer Syntax Interface might be a better first step. Pointer Syntax Interface -^^^^^^^^^^^^^^^^^^^^^^^^ +======================== The pointer interface allows a View object to act like a pointer. The interface required to define this implementation can be considerably smaller for many classes. It does not provide type safety. Therefore, you *could* call a function that should only be used by a Value object from a View object (you should still get a ``__host__ __device__`` warning if this happens in a GPU context). It is up to the developer to understand what they can and cannot call from a view like object. This is the "quick and dirty" conversion but is really useful for rapid implementation of VVI in certain cases. +***************** Use Cases for VVI ------------------ +***************** VVI was designed to help overcome a variety of complex obstacles in regards to GPU porting, such as: @@ -54,29 +58,31 @@ VVI was designed to help overcome a variety of complex obstacles in regards to G VVI should be avoided when possible. Simple classes with trivial members should be converted to be GPU capable directly. VVI is most useful when a copy of an object could result in a considerable data reallocation or when the class structure is not conducive to traditional GPU use. +*********** Definitions ------------ +*********** Implementation Class (\ ``ImplType``\ ) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +======================================= The Implementation Class is a class targeted for use with the VVI pattern. This is usually a pre-existing class that a developer wants to use on the GPU. VVI is required when it's current members or class hierarchy / structure are not conventionally suited for device side use. Value Class (\ ``ValueType``\ ) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +=============================== An interface to the underlying implmentation class. This class is named the same as the ``ImplType``\ , and thus should require no changes to the current user code to use this type. The ``ValueType`` uses traditional C++ value copy semantics by default. However the semantic interface of how the type should be used should directly match the semantic conditions of the original ``ImplType``. View Class (\ ``ViewType``\ ) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +============================= The View interface is what allows VVI to work seamlessly with ``RAJA`` execution contexts. A ``ViewType`` will have reference semantic like behavior. Meaning that copy construction of a ``ViewType`` does not invoke an allocation of the underlying class data, it instead references the underlying ``ValueType`` instance that it is associated with. +************************************** Preparing Implementation Class for VVI --------------------------------------- +************************************** Private Members -^^^^^^^^^^^^^^^ +=============== * All data members must be private. They may be accessed through ``get`` and ``set`` methods. This should be done first as this may require some changes through the codebase. @@ -114,7 +120,7 @@ Private Members f.var() = 5 std::vector members -^^^^^^^^^^^^^^^^^^^ +=================== * ``std::vector``\ members should be converted to ``vvi::vector``. ``vvi::vector`` is an alias for ``chai::ManagedVector`` that will revert to ``std::vector`` when VVI is disabled. @@ -130,12 +136,14 @@ std::vector members * A ``deepCopy()`` method must be provided that calls ``deepCopy()`` on each ``vvi``\ member. When VVI is enabled the ``vvi`` types use reference semantics. ``deepCopy()`` allows the *VALUE* interface to copy the object correctly. - ### DeepCopy & Compare -* In order to correctly perform Copy and Equivalence operations from the *VALUE* interface, special ``deepCopy`` and ``compare`` method needs to be provided from the ``ImplType``. -* Helper macros have been developed to aid in declaring these in your classes. - #### DeepCopy + +DeepCopy & Compare + In order to correctly perform Copy and Equivalence operations from the *VALUE* interface, special ``deepCopy`` and ``compare`` method needs to be provided from the ``ImplType``. Helper macros have been developed to aid in declaring these in your classes. + +DeepCopy ``VVI_IMPL_DEEPCOPY(impl_t, )`` This deep copy macro first performs the ``ImplType`` Copy Ctor, It will then manually perform a deep-copy on any other ``vvi`` type that exists as a member of the ``ImplType`` defined in the list. - #### Compare + +Compare ``VVI_IMPL_COMPARE(impl_t, )`` This macro will perform a value based comparison on all member names given (you probably want to list all members...). .. code-block:: c++ @@ -152,7 +160,7 @@ std::vector members }; chai::CHAICopyable -^^^^^^^^^^^^^^^^^^ +================== * If you intend to use the class as the element type of a chai container then a **default constructor** must be provided. @@ -176,7 +184,7 @@ chai::CHAICopyable chai::ManagedArray my_arr; Classes w/ virtual methods -^^^^^^^^^^^^^^^^^^^^^^^^^^ +========================== * If the class has a virtual method such that a virtual table would be present for it or its derived classes the class needs to inherit from ``chai::Poly``. @@ -206,11 +214,12 @@ Classes w/ virtual methods Inheriting from ``chai::CHAIPoly`` includes the behavior of ``chai::CHAICopyable``. +***************************************** Value View Interface Declaration Examples ------------------------------------------ +***************************************** Basic Class Interface -^^^^^^^^^^^^^^^^^^^^^ +===================== Below we demonstrate how to implement the Value-View Interface (VVI) pattern on a very basic class. @@ -233,7 +242,7 @@ We need to forward declare *VALUE* class names. VVI details should be guarded wi class foo; Basic VIEW Interface -~~~~~~~~~~~~~~~~~~~~ +-------------------- *VIEW* interfaces inherit default constructor, copy constructor, and assignment operator behavior provided by the underlying ``ViewInterface`` type that all *VIEW* interface classes inherit from. @@ -267,7 +276,7 @@ We use helper macros with the naming convention ``__`` to aid in writing i Basic Value Interface -~~~~~~~~~~~~~~~~~~~~~ +--------------------- *VALUE* interface default behavior is inherited from the ``vvi::detail::ValueInterface`` class. If not defined a Default Constructor will be used for the *VALUE* interface. Copy constructor, Assignment and Equivalence behavior is baked in, assuming the appropriate ``DEEPCOPY`` and ``COMPARE`` interfaces have been defined in the ``ImplType``. @@ -285,9 +294,9 @@ VVI Supplies ``VVI_IMPL_INST`` as a way to access the underlying instantiation o #endif Class w/ Custom Constructor & Vector Member -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +=========================================== -Here we demonstrate using VVI with a class containing a ``vvi::vector`` member and a non default constructor. We have already made the necessary changes for VVI preparation ([[#std vector members]]). We will also assume that this class may be used as an element type to another CHAI container, therefore it must inherit from ``chai::CHAICopyable``. +Here we demonstrate using VVI with a class containing a ``vvi::vector`` member and a non default constructor. We have already made the necessary changes for VVI preparation. We will also assume that this class may be used as an element type to another CHAI container, therefore it must inherit from ``chai::CHAICopyable``. .. code-block:: c++ @@ -309,7 +318,7 @@ Here we demonstrate using VVI with a class containing a ``vvi::vector`` member a VVI_IMPL_END Type Alias View Interface -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- Declaring the interface class names and the *VIEW* interface are the same as above. However we would like to expose the type information for ``vec_t``. Defining the type alias in the *VIEW* interface makes it publicly visible to both *VIEW* and *VALUE* interfaces. @@ -327,7 +336,7 @@ Declaring the interface class names and the *VIEW* interface are the same as abo ); Custom Ctor Value Interface -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------- When defining a non-default constructor for *VALUE* interfaces we need to forward the arguments with ``VVI_VALUE_CTOR_ARGS()`` as below. The argument list needs to be passed within ``()``. @@ -352,7 +361,7 @@ When defining a non-default constructor for *VALUE* interfaces we need to forwar #endif Template Class Interface -^^^^^^^^^^^^^^^^^^^^^^^^ +======================== Templated classes can be used with the VVI Pattern. @@ -375,7 +384,7 @@ Remember to template the forward declaration. class foo; Template Interface Declarations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- When defining the ``_METACLASS_DECL`` macros we need to template the exclusive types to the interface we are representing: @@ -407,12 +416,12 @@ In the interface declarations we need to ensure we template the interfaces. #endif Abstract & Polymorphic Class Interface -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +====================================== One of the strongest features of the VVI Pattern is the ability to use abstract class interfaces on the GPU. Below we are converting a *very* basic example of a polymorphic class for use in VVI. Implmentation Classes w/ Virtual Functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------ Base classes with virtual interfaces need to inherit from ``vvi::poly``. This allows VVI to perform a specialized copies between the host and device such that the vitual table is preserved across execution spaces. @@ -457,7 +466,7 @@ We need to forward declare for both ``base`` and ``derived``. (derived), (derivedView), (vvimpl::derived), (code) ) Base Class Interface -~~~~~~~~~~~~~~~~~~~~ +-------------------- ``base`` is an abstract interface class. It should **NEVER** be constructable. However, we may want to declare the class to query type name information. We use ``VVI_DELETED_INTERFACE()`` to ensure a ``base`` *VALUE* type is not constructed. @@ -482,7 +491,7 @@ Base Class Interface Derived Class Interface -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- The ``derived`` interface can be defined similarly to other *VALUE* and *VIEW* interfaces. Here we add ``VVI_UPCAST_CONVERSION_OP()`` to allow us to upcast a derived type to the base. This allows conversion from ``derivedView -> baseView`` as well as conversions of ``derived -> baseView``. @@ -499,26 +508,26 @@ The ``derived`` interface can be defined similarly to other *VALUE* and *VIEW* i #endif +***************** Macro Definitions ------------------ +***************** VALUE Interface Definition Macros -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +================================= * ``VVI_VALUE_CTOR_ARGS((args))`` : Forward arguments of a non-default constructor for a *VALUE* interface. * ``VVI_VALUE_DEF_CTOR(value_t)`` : Define default constructor for a *VALUE* interface. -Interface Behavior Macros -^^^^^^^^^^^^^^^^^^^^^^^^^ +Interface Behavior Macros +========================= * ``VVI_DELETED_INTERFACE(type)`` : Delete the constructor, copy constructor and assignment operator. * ``VVI_UPCAST_CONVERSION_OP(parent_t)`` : Define an implicit conversion operator to the defined parent type. -Class Declaration Macros -^^^^^^^^^^^^^^^^^^^^^^^^ +Class Declaration Macros +======================== * ``PTR_VALUE_METACLASS_DECL((value_t), (view_t), (impl_t), (code))`` * ``REF_VALUE_METACLASS_DECL((value_t), (view_t), (impl_t), (code))`` From 0bbe7d668add2465fc6e33e2832020f4752d24a1 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 30 Sep 2024 10:40:16 -0700 Subject: [PATCH 35/44] Fixing CMake tests merge issue. --- cmake/SetupSpheral.cmake | 1 - tests/CMakeLists.txt | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/SetupSpheral.cmake b/cmake/SetupSpheral.cmake index 99ee8ab78..5aa1fccc1 100644 --- a/cmake/SetupSpheral.cmake +++ b/cmake/SetupSpheral.cmake @@ -166,7 +166,6 @@ endif() #------------------------------------------------------------------------------- if (ENABLE_TESTS) add_subdirectory(${SPHERAL_ROOT_DIR}/tests) - add_subdirectory(${SPHERAL_ROOT_DIR}/tests/unit/CXXTests) # A macro to preserve directory structure when installing files macro(install_with_directory) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 66ff6d23d..b71a1f74c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(cpp/Field) add_subdirectory(cpp/Utilities) +add_subdirectory(unit) From c9c6e61e28a80450b83fc249c6d8a3edec711664 Mon Sep 17 00:00:00 2001 From: Mike Owen Date: Mon, 14 Oct 2024 15:06:20 -0700 Subject: [PATCH 36/44] Fixed typo --- RELEASE_NOTES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 9e1ec74dc..46ebe0695 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,7 +5,7 @@ Version vYYYY.MM.p -- Release date YYYY-MM-DD Notable changes include: * New features / API changes: - * Value-View Interface for wrapping comlex classes in a GPU compatible Interface. + * Value-View Interface for wrapping complex classes in a GPU compatible Interface. * Enabled w/ `SPHERAL_ENABLE_VVI=On`. * Example executables demonstrating : * Basic class w/ ManagedVector member. From 59d37d5e0d34e7d2449a6d3b9e09f228b427f29e Mon Sep 17 00:00:00 2001 From: Mike Owen Date: Wed, 16 Oct 2024 13:46:47 -0700 Subject: [PATCH 37/44] Moving ENABLE_DEV_BUILD CI test to clang on toss4 --- .gitlab/specs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/specs.yml b/.gitlab/specs.yml index 41bd0d10b..d5e39beba 100644 --- a/.gitlab/specs.yml +++ b/.gitlab/specs.yml @@ -24,11 +24,11 @@ .gcc_spectrum: variables: SPEC: 'gcc@$GCC_VERSION^spectrum-mpi' - EXTRA_CMAKE_ARGS: '-DENABLE_DEV_BUILD=On' .clang_mvapich2: variables: SPEC: 'clang@$CLANG_VERSION^mvapich2' + EXTRA_CMAKE_ARGS: '-DENABLE_DEV_BUILD=On' .cuda_11_gcc_~mpi: variables: From 0139307d993920fb4a7b8c0243d5304d1c4435b3 Mon Sep 17 00:00:00 2001 From: Landon Owen Date: Mon, 21 Oct 2024 16:22:40 -0700 Subject: [PATCH 38/44] Change gcc version on ansel to 10.2.1 --- .gitlab/os.yml | 10 +--------- extern/chai | 2 +- scripts/devtools/spec-list.json | 12 +++--------- .../spack/configs/blueos_3_ppc64le_ib/compilers.yaml | 10 +++++----- .../spack/configs/blueos_3_ppc64le_ib/packages.yaml | 7 ++++--- 5 files changed, 14 insertions(+), 27 deletions(-) diff --git a/.gitlab/os.yml b/.gitlab/os.yml index 8ba613b90..e7a6a8fda 100644 --- a/.gitlab/os.yml +++ b/.gitlab/os.yml @@ -7,14 +7,6 @@ UPSTREAM_DIR: /usr/WS2/sduser/Spheral/spack_upstream/0.22 DISPLAY: ':0.0' -.on_toss_3_x86: - variables: - ARCH: 'toss_3_x86_64_ib' - GCC_VERSION: '8.3.1' - CLANG_VERSION: '9.0.0' - SPHERAL_BUILDS_DIR: /p/lustre1/sphapp/spheral-ci-builds - extends: [.sys_config] - .on_toss_4_x86: variables: ARCH: 'toss_4_x86_64_ib' @@ -26,7 +18,7 @@ .on_blueos_3_ppc64: variables: ARCH: 'blueos_3_ppc64le_ib_p9' - GCC_VERSION: '8.3.1' + GCC_VERSION: '10.2.1' CLANG_VERSION: '9.0.0' SPHERAL_BUILDS_DIR: /p/gpfs1/sphapp/spheral-ci-builds extends: [.sys_config] diff --git a/extern/chai b/extern/chai index 2a53f5377..79cb51f83 160000 --- a/extern/chai +++ b/extern/chai @@ -1 +1 @@ -Subproject commit 2a53f53777a9fa98f0260a435a2283f05eb01feb +Subproject commit 79cb51f8347c05b38ec2f0feaaa640b46bd1c440 diff --git a/scripts/devtools/spec-list.json b/scripts/devtools/spec-list.json index d243b1242..395d5d0cd 100644 --- a/scripts/devtools/spec-list.json +++ b/scripts/devtools/spec-list.json @@ -6,16 +6,10 @@ "clang@14.0.6" ] , - "toss_3_x86_64_ib": [ - "gcc@8.3.1", - "gcc@8.3.1~mpi", - "clang@9.0.0" - ] - , "blueos_3_ppc64le_ib_p9": [ - "gcc@8.3.1", - "gcc@8.3.1+cuda~mpi cuda_arch=70", - "gcc@8.3.1+cuda cuda_arch=70" + "gcc@10.2.1", + "gcc@10.2.1+cuda~mpi cuda_arch=70", + "gcc@10.2.1+cuda cuda_arch=70" ] } } diff --git a/scripts/spack/configs/blueos_3_ppc64le_ib/compilers.yaml b/scripts/spack/configs/blueos_3_ppc64le_ib/compilers.yaml index b876f15bc..84c1b8b70 100644 --- a/scripts/spack/configs/blueos_3_ppc64le_ib/compilers.yaml +++ b/scripts/spack/configs/blueos_3_ppc64le_ib/compilers.yaml @@ -13,12 +13,12 @@ compilers: environment: {} extra_rpaths: [] - compiler: - spec: gcc@8.3.1 + spec: gcc@10.2.1 paths: - cc: /usr/tce/packages/gcc/gcc-8.3.1/bin/gcc - cxx: /usr/tce/packages/gcc/gcc-8.3.1/bin/g++ - f77: /usr/tce/packages/gcc/gcc-8.3.1/bin/gfortran - fc: /usr/tce/packages/gcc/gcc-8.3.1/bin/gfortran + cc: /usr/tce/packages/gcc/gcc-10.2.1/bin/gcc + cxx: /usr/tce/packages/gcc/gcc-10.2.1/bin/g++ + f77: /usr/tce/packages/gcc/gcc-10.2.1/bin/gfortran + fc: /usr/tce/packages/gcc/gcc-10.2.1/bin/gfortran flags: {} operating_system: rhel7 target: ppc64le diff --git a/scripts/spack/configs/blueos_3_ppc64le_ib/packages.yaml b/scripts/spack/configs/blueos_3_ppc64le_ib/packages.yaml index 79fbd0e36..54f6fd19c 100644 --- a/scripts/spack/configs/blueos_3_ppc64le_ib/packages.yaml +++ b/scripts/spack/configs/blueos_3_ppc64le_ib/packages.yaml @@ -37,17 +37,16 @@ packages: - 11.1.0 - 11.0.2 - 10.1.243 - - 10.1.168 buildable: false externals: + - spec: cuda@11.4.1+allow-unsupported-compilers + prefix: /usr/tce/packages/cuda/cuda-11.4.1 - spec: cuda@11.1.0~allow-unsupported-compilers prefix: /usr/tce/packages/cuda/cuda-11.1.0 - spec: cuda@11.0.2~allow-unsupported-compilers prefix: /usr/tce/packages/cuda/cuda-11.0.2 - spec: cuda@10.1.243~allow-unsupported-compilers prefix: /usr/tce/packages/cuda/cuda-10.1.243 - - spec: cuda@10.1.168+allow-unsupported-compilers - prefix: /usr/tce/packages/cuda/cuda-10.1.168 spectrum-mpi: externals: @@ -59,6 +58,8 @@ packages: prefix: /usr/tce/packages/spectrum-mpi/spectrum-mpi-rolling-release-gcc-8.3.1 - spec: spectrum-mpi@10.3.1.03rtm0%gcc@4.9.3 prefix: /usr/tce/packages/spectrum-mpi/spectrum-mpi-rolling-release-gcc-4.9.3 + - spec: spectrum-mpi@10.3.1.03rtm0%gcc@10.2.1 + prefix: /usr/tce/packages/spectrum-mpi/spectrum-mpi-rolling-release-gcc-10.2.1 - spec: spectrum-mpi@10.3.1.03rtm0%clang@9.0.0 prefix: /usr/tce/packages/spectrum-mpi/spectrum-mpi-rolling-release-clang-9.0.0 - spec: spectrum-mpi@10.3.1.03rtm0%clang@9.0.0-ibm From 3ec887db89c5194708c1d51894019278cdc17e18 Mon Sep 17 00:00:00 2001 From: Landon Owen Date: Tue, 22 Oct 2024 10:09:03 -0700 Subject: [PATCH 39/44] Bring blueos gcc version back to 8.3.1 --- .gitlab/os.yml | 2 +- scripts/devtools/spec-list.json | 6 +++--- .../spack/configs/blueos_3_ppc64le_ib/compilers.yaml | 10 +++++----- .../spack/configs/blueos_3_ppc64le_ib/packages.yaml | 2 -- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/.gitlab/os.yml b/.gitlab/os.yml index e7a6a8fda..9bc4b8146 100644 --- a/.gitlab/os.yml +++ b/.gitlab/os.yml @@ -18,7 +18,7 @@ .on_blueos_3_ppc64: variables: ARCH: 'blueos_3_ppc64le_ib_p9' - GCC_VERSION: '10.2.1' + GCC_VERSION: '8.3.1' CLANG_VERSION: '9.0.0' SPHERAL_BUILDS_DIR: /p/gpfs1/sphapp/spheral-ci-builds extends: [.sys_config] diff --git a/scripts/devtools/spec-list.json b/scripts/devtools/spec-list.json index 395d5d0cd..59f681eb8 100644 --- a/scripts/devtools/spec-list.json +++ b/scripts/devtools/spec-list.json @@ -7,9 +7,9 @@ ] , "blueos_3_ppc64le_ib_p9": [ - "gcc@10.2.1", - "gcc@10.2.1+cuda~mpi cuda_arch=70", - "gcc@10.2.1+cuda cuda_arch=70" + "gcc@8.3.1", + "gcc@8.3.1+cuda~mpi cuda_arch=70", + "gcc@8.3.1+cuda cuda_arch=70" ] } } diff --git a/scripts/spack/configs/blueos_3_ppc64le_ib/compilers.yaml b/scripts/spack/configs/blueos_3_ppc64le_ib/compilers.yaml index 84c1b8b70..b876f15bc 100644 --- a/scripts/spack/configs/blueos_3_ppc64le_ib/compilers.yaml +++ b/scripts/spack/configs/blueos_3_ppc64le_ib/compilers.yaml @@ -13,12 +13,12 @@ compilers: environment: {} extra_rpaths: [] - compiler: - spec: gcc@10.2.1 + spec: gcc@8.3.1 paths: - cc: /usr/tce/packages/gcc/gcc-10.2.1/bin/gcc - cxx: /usr/tce/packages/gcc/gcc-10.2.1/bin/g++ - f77: /usr/tce/packages/gcc/gcc-10.2.1/bin/gfortran - fc: /usr/tce/packages/gcc/gcc-10.2.1/bin/gfortran + cc: /usr/tce/packages/gcc/gcc-8.3.1/bin/gcc + cxx: /usr/tce/packages/gcc/gcc-8.3.1/bin/g++ + f77: /usr/tce/packages/gcc/gcc-8.3.1/bin/gfortran + fc: /usr/tce/packages/gcc/gcc-8.3.1/bin/gfortran flags: {} operating_system: rhel7 target: ppc64le diff --git a/scripts/spack/configs/blueos_3_ppc64le_ib/packages.yaml b/scripts/spack/configs/blueos_3_ppc64le_ib/packages.yaml index 54f6fd19c..7a8d3d6bf 100644 --- a/scripts/spack/configs/blueos_3_ppc64le_ib/packages.yaml +++ b/scripts/spack/configs/blueos_3_ppc64le_ib/packages.yaml @@ -39,8 +39,6 @@ packages: - 10.1.243 buildable: false externals: - - spec: cuda@11.4.1+allow-unsupported-compilers - prefix: /usr/tce/packages/cuda/cuda-11.4.1 - spec: cuda@11.1.0~allow-unsupported-compilers prefix: /usr/tce/packages/cuda/cuda-11.1.0 - spec: cuda@11.0.2~allow-unsupported-compilers From 47fe343fa53c62c0ec11dc31f4ad2340f068abbd Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 11 Nov 2024 15:53:00 -0800 Subject: [PATCH 40/44] Fixing bad merge in QInt. --- src/Utilities/QuadraticInterpolator.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Utilities/QuadraticInterpolator.hh b/src/Utilities/QuadraticInterpolator.hh index b872e95e6..bb4a0672c 100644 --- a/src/Utilities/QuadraticInterpolator.hh +++ b/src/Utilities/QuadraticInterpolator.hh @@ -27,7 +27,6 @@ public: QuadraticInterpolator(double xmin, double xmax, size_t n, const Func& F); QuadraticInterpolator(double xmin, double xmax, const std::vector& yvals); SPHERAL_HOST_DEVICE QuadraticInterpolator() = default; - ~QuadraticInterpolator(); // Initialize after construction, either with a function or tabulated values template From fcb1a3b4faa792189c26fdd91f37469b4c2599f7 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Wed, 13 Nov 2024 18:12:43 -0800 Subject: [PATCH 41/44] Clang + Gtest + pedantic warning fix. --- tests/cpp/Field/field_tests.cc | 2 +- tests/cpp/Utilities/managed_vector_tests.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cpp/Field/field_tests.cc b/tests/cpp/Field/field_tests.cc index 1941e2676..0099a41f7 100644 --- a/tests/cpp/Field/field_tests.cc +++ b/tests/cpp/Field/field_tests.cc @@ -212,5 +212,5 @@ REGISTER_TYPED_TEST_SUITE_P(FieldTypedTest, size ); -INSTANTIATE_TYPED_TEST_SUITE_P(Field, FieldTypedTest, EXEC_TYPES); +INSTANTIATE_TYPED_TEST_SUITE_P(Field, FieldTypedTest, EXEC_TYPES,); diff --git a/tests/cpp/Utilities/managed_vector_tests.cc b/tests/cpp/Utilities/managed_vector_tests.cc index 03c28717a..11f43a512 100644 --- a/tests/cpp/Utilities/managed_vector_tests.cc +++ b/tests/cpp/Utilities/managed_vector_tests.cc @@ -14,7 +14,7 @@ template class ManagedVectorTypedTest : public::testing::Test {}; // All ManagedVectorTets cases will run over each type in EXEC_TYPES. -TYPED_TEST_CASE(ManagedVectorTypedTest, EXEC_TYPES); +TYPED_TEST_SUITE(ManagedVectorTypedTest, EXEC_TYPES,); GPU_TYPED_TEST(ManagedVectorTypedTest, DefaultConstructor) From 66b8309f14e8958160038cfe2b14c32cac477d63 Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Wed, 13 Nov 2024 19:59:36 -0800 Subject: [PATCH 42/44] Having to revert some of the lambda changes in TableKernel. --- src/Kernel/TableKernel.cc | 30 +++++++++++++++++++++++--- src/Utilities/QuadraticInterpolator.hh | 6 ++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/Kernel/TableKernel.cc b/src/Kernel/TableKernel.cc index 7ff2796c9..fe9bf9545 100644 --- a/src/Kernel/TableKernel.cc +++ b/src/Kernel/TableKernel.cc @@ -169,6 +169,30 @@ gradf1Integral(const KernelType& W, numbins); } +//------------------------------------------------------------------------------ +// Functors for building interpolation of kernel +//------------------------------------------------------------------------------ +template +struct Wlookup { + const KernelType& mW; + Wlookup(const KernelType& W): mW(W) {} + double operator()(const double x) const { return mW(x, 1.0); } +}; + +template +struct gradWlookup { + const KernelType& mW; + gradWlookup(const KernelType& W): mW(W) {} + double operator()(const double x) const { return mW.grad(x, 1.0); } +}; + +template +struct grad2Wlookup { + const KernelType& mW; + grad2Wlookup(const KernelType& W): mW(W) {} + double operator()(const double x) const { return mW.grad2(x, 1.0); } +}; + } // anonymous //------------------------------------------------------------------------------ @@ -184,9 +208,9 @@ TableKernel::TableKernel(const KernelType& kernel, mNumPoints(numPoints), mMinNperh(std::max(minNperh, 1.1/kernel.kernelExtent())), mMaxNperh(maxNperh), - mInterp(0.0, kernel.kernelExtent(), numPoints, [&](const double x) { return kernel(x, 1.0); }), - mGradInterp(0.0, kernel.kernelExtent(), numPoints, [&](const double x) { return kernel.grad(x, 1.0); }), - mGrad2Interp(0.0, kernel.kernelExtent(), numPoints, [&](const double x) { return kernel.grad2(x, 1.0); }), + mInterp(0.0, kernel.kernelExtent(), numPoints, Wlookup(kernel)), + mGradInterp(0.0, kernel.kernelExtent(), numPoints, gradWlookup(kernel)), + mGrad2Interp(0.0, kernel.kernelExtent(), numPoints, grad2Wlookup(kernel)), mNperhLookup(), mWsumLookup() { diff --git a/src/Utilities/QuadraticInterpolator.hh b/src/Utilities/QuadraticInterpolator.hh index bb4a0672c..fb2e3d51c 100644 --- a/src/Utilities/QuadraticInterpolator.hh +++ b/src/Utilities/QuadraticInterpolator.hh @@ -25,6 +25,7 @@ public: // Constructors, destructors template QuadraticInterpolator(double xmin, double xmax, size_t n, const Func& F); + QuadraticInterpolator(double xmin, double xmax, const std::vector& yvals); SPHERAL_HOST_DEVICE QuadraticInterpolator() = default; @@ -89,6 +90,11 @@ class QuadraticInterpolator__( const Func& F) : VVI_VALUE_CTOR_ARGS((xmin,xmax,n,F)) {} + QuadraticInterpolator(double xmin, + double xmax, + const std::vector& yvals) + : VVI_VALUE_CTOR_ARGS((xmin,xmax,yvals)) {} + VVI_VALUE_DEF_CTOR(QuadraticInterpolator) // Alternatively initialize from tabulated values From 52383b9cfef732191d94665ede1f865e51023e9d Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Wed, 13 Nov 2024 21:29:36 -0800 Subject: [PATCH 43/44] Pointing chai at latest changes. --- extern/chai | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/chai b/extern/chai index 79cb51f83..2a53f5377 160000 --- a/extern/chai +++ b/extern/chai @@ -1 +1 @@ -Subproject commit 79cb51f8347c05b38ec2f0feaaa640b46bd1c440 +Subproject commit 2a53f53777a9fa98f0260a435a2283f05eb01feb From 5990fce1ec4bc53f701b187d09d64fc530d74c5e Mon Sep 17 00:00:00 2001 From: mdavis36 Date: Mon, 18 Nov 2024 09:24:13 -0800 Subject: [PATCH 44/44] Need to disable tests when ENABLE_DEV_BUILD=On, .so libs cannot resolve undeifned symbols when theyre dynamically loaded. --- cmake/SpheralMacros.cmake | 58 +++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/cmake/SpheralMacros.cmake b/cmake/SpheralMacros.cmake index a68a39c80..ec2b955aa 100644 --- a/cmake/SpheralMacros.cmake +++ b/cmake/SpheralMacros.cmake @@ -54,34 +54,38 @@ macro(spheral_add_test) set(original_src ${arg_SOURCES}) set(original_deps ${arg_DEPENDS_ON}) - get_property(SPHERAL_BLT_DEPENDS GLOBAL PROPERTY SPHERAL_BLT_DEPENDS) - - blt_add_library( - NAME ${original_test_name}_lib - SOURCES ${TEST_LIB_SOURCE} - SOURCES ${SPHERAL_ROOT_DIR}/src/spheralCXX.cc - DEPENDS_ON ${SPHERAL_BLT_DEPENDS} ${original_deps} - SHARED False - ) - - target_link_options(${original_test_name}_lib PRIVATE "-Wl,--unresolved-symbols=ignore-in-object-files") - - spheral_add_executable( - NAME ${original_test_name}.exe - SOURCES ${original_src} - DEPENDS_ON gtest ${CMAKE_THREAD_LIBS_INIT} ${original_test_name}_lib - TEST On) - - blt_add_test( - NAME ${original_test_name} - COMMAND ${TEST_DRIVER} ${original_test_name}.exe) - - target_include_directories(${original_test_name}.exe SYSTEM PRIVATE ${SPHERAL_ROOT_DIR}/tests/cpp/include) - - if (${arg_DEBUG_LINKER}) - target_link_options(${original_test_name}.exe PUBLIC "-Wl,--warn-unresolved-symbols") + if (ENABLE_DEV_BUILD) + message("Skipping ${original_test_name} : NOT compatible with ENABLE_DEV_BUILD.") else() - target_link_options(${original_test_name}.exe PUBLIC "-Wl,--unresolved-symbols=ignore-all") + get_property(SPHERAL_BLT_DEPENDS GLOBAL PROPERTY SPHERAL_BLT_DEPENDS) + + blt_add_library( + NAME ${original_test_name}_lib + SOURCES ${TEST_LIB_SOURCE} + SOURCES ${SPHERAL_ROOT_DIR}/src/spheralCXX.cc + DEPENDS_ON ${SPHERAL_BLT_DEPENDS} ${original_deps} + SHARED False + ) + + target_link_options(${original_test_name}_lib PRIVATE "-Wl,--unresolved-symbols=ignore-in-object-files") + + spheral_add_executable( + NAME ${original_test_name}.exe + SOURCES ${original_src} + DEPENDS_ON gtest ${CMAKE_THREAD_LIBS_INIT} ${original_test_name}_lib + TEST On) + + blt_add_test( + NAME ${original_test_name} + COMMAND ${TEST_DRIVER} ${original_test_name}.exe) + + target_include_directories(${original_test_name}.exe SYSTEM PRIVATE ${SPHERAL_ROOT_DIR}/tests/cpp/include) + + if (${arg_DEBUG_LINKER}) + target_link_options(${original_test_name}.exe PUBLIC "-Wl,--warn-unresolved-symbols") + else() + target_link_options(${original_test_name}.exe PUBLIC "-Wl,--unresolved-symbols=ignore-all") + endif() endif() endmacro(spheral_add_test)