diff --git a/CMakeLists.txt b/CMakeLists.txt index dd1cb990..a2cbc5ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,6 +106,7 @@ endif() # Configure CHAI/Umpire for memory management # option(ENABLE_CHAI "Enable CHAI/Umpire memory management" Off) +option(ENABLE_CHAI_SINGLE_MEMORY "Enable single memory configuration in CHAI" Off) if(ENABLE_CHAI) # Find camp if (NOT TARGET camp) @@ -140,14 +141,18 @@ if(ENABLE_CHAI) endif () if (ENABLE_HIP) - # Set CHAI-related HIP variables for single memory address space. - # Use the THIN_GPU_ALLOCATE mode of CHAI on MI250X. - # This is to mirror the expected behavior of El Capitan. - # Requires env variables HSA_XNACK set to 1 and MPICH_GPU_SUPPORT_ENABLED set to 1 to work on the MI250X. - set (CHAI_ENABLE_UM OFF CACHE BOOL "") - set (CHAI_ENABLE_PINNED ON CACHE BOOL "") - set(CHAI_DISABLE_RM ON CACHE BOOL "") - set(CHAI_THIN_GPU_ALLOCATE ON CACHE BOOL "") + if(ENABLE_CHAI_SINGLE_MEMORY) + # Set CHAI-related HIP variables for single memory address space. + # Use the THIN_GPU_ALLOCATE mode of CHAI on MI250X. + # This is to mirror the expected behavior of El Capitan. + # Requires env variables HSA_XNACK set to 1 and MPICH_GPU_SUPPORT_ENABLED set to 1 to work on the MI250X. + set (CHAI_ENABLE_UM OFF CACHE BOOL "") + set (CHAI_ENABLE_PINNED ON CACHE BOOL "") + set(CHAI_DISABLE_RM ON CACHE BOOL "") + set(CHAI_THIN_GPU_ALLOCATE ON CACHE BOOL "") + + set(KRIPKE_USE_CHAI_SINGLE_MEMORY 1) + endif() message(STATUS "Kripke: Setting CAMP_HAVE_HIP") blt_add_target_definitions(TO camp @@ -355,6 +360,7 @@ configure_file(${PROJECT_SOURCE_DIR}/src/KripkeConfig.h.in blt_add_library( NAME kripke SOURCES "src/Kripke/Core/BaseVar.cpp" + "src/Kripke/Core/MemoryManager.cpp" "src/Kripke/Core/DataStore.cpp" "src/Kripke/Core/DomainVar.cpp" "src/Kripke/Generate.cpp" diff --git a/src/Kripke/Core/DataStore.cpp b/src/Kripke/Core/DataStore.cpp index 39d13f3a..b7e2c21f 100644 --- a/src/Kripke/Core/DataStore.cpp +++ b/src/Kripke/Core/DataStore.cpp @@ -19,21 +19,7 @@ using namespace Kripke; using namespace Kripke::Core; -DataStore::DataStore(int dev_pool_size){ -#ifdef KRIPKE_USE_CHAI - auto &rm = umpire::ResourceManager::getInstance(); - const char * allocator_name = "KRIPKE_DEVICE_POOL"; - size_t umpire_dev_pool_size = ((size_t) dev_pool_size) * 1024 * 1024 * 1024; - size_t umpire_dev_block_size = 512; - auto dev_pool_allocator = rm.makeAllocator(allocator_name, rm.getAllocator("DEVICE"), umpire_dev_pool_size, umpire_dev_block_size); - auto chai_resource_manager = chai::ArrayManager::getInstance(); - chai_resource_manager->setAllocator(chai::GPU, dev_pool_allocator); - // force allocation of GPU memory pool - auto tmp = new chai::ManagedArray(100, chai::GPU); - tmp->free(chai::GPU); - delete tmp; -#endif // KRIPKE_USE_CHAI -} +DataStore::DataStore(){} DataStore::~DataStore(){ diff --git a/src/Kripke/Core/DataStore.h b/src/Kripke/Core/DataStore.h index 199342f2..2c85885d 100644 --- a/src/Kripke/Core/DataStore.h +++ b/src/Kripke/Core/DataStore.h @@ -22,7 +22,7 @@ namespace Core { */ class DataStore { public: - DataStore(int dev_pool_size = 4); + DataStore(); ~DataStore(); DataStore(DataStore const &) = delete; DataStore &operator=(DataStore const &) = delete; diff --git a/src/Kripke/Core/Field.h b/src/Kripke/Core/Field.h index 9a3312b5..9103b40e 100644 --- a/src/Kripke/Core/Field.h +++ b/src/Kripke/Core/Field.h @@ -67,8 +67,12 @@ namespace Core { m_chunk_to_size[chunk_id] = sdom_size; #ifndef KRIPKE_USE_CHAI m_chunk_to_data[chunk_id] = new ElementType[sdom_size]; +#else +#ifdef KRIPKE_USE_CHAI_SINGLE_MEMORY + m_chunk_to_data[chunk_id].allocate(sdom_size, chai::GPU, #else m_chunk_to_data[chunk_id].allocate(sdom_size, chai::CPU, +#endif [=](const chai::PointerRecord* record, chai::Action action, chai::ExecutionSpace space){ /*printf("CHAI[%s, %d]: ", BaseVar::getName().c_str(), (int)chunk_id); switch(action){ diff --git a/src/Kripke/Core/MemoryManager.cpp b/src/Kripke/Core/MemoryManager.cpp new file mode 100644 index 00000000..9a1f5ab0 --- /dev/null +++ b/src/Kripke/Core/MemoryManager.cpp @@ -0,0 +1,54 @@ +// +// Copyright (c) 2014-25, Lawrence Livermore National Security, LLC +// and Kripke project contributors. See the Kripke/COPYRIGHT file for details. +// +// SPDX-License-Identifier: (BSD-3-Clause) +// + +#include +#include + +#ifdef KRIPKE_USE_CHAI +#define DEBUG +#include +#include +#include +#undef DEBUG +#endif + +using namespace Kripke; +using namespace Kripke::Core; + +MemoryManager::MemoryManager(int device_pool_size) : device_pool_size(device_pool_size) { +#ifdef KRIPKE_USE_CHAI + auto &rm = umpire::ResourceManager::getInstance(); + const char * allocator_name = "KRIPKE_DEVICE_POOL"; + size_t umpire_device_pool_size = ((size_t) device_pool_size) * 1024 * 1024 * 1024; + size_t umpire_dev_block_size = 512; + auto device_pool_allocator = rm.makeAllocator(allocator_name, rm.getAllocator("DEVICE"), umpire_device_pool_size, umpire_dev_block_size); + auto chai_resource_manager = chai::ArrayManager::getInstance(); + chai_resource_manager->setAllocator(chai::GPU, device_pool_allocator); + // force allocation of GPU memory pool + auto tmp = new chai::ManagedArray(100, chai::GPU); + tmp->free(chai::GPU); + delete tmp; +#endif // KRIPKE_USE_CHAI +} + +double MemoryManager::getDeviceMemoryPoolSize() { +#ifdef KRIPKE_USE_CHAI + return (double) device_pool_size; +#else + return 0.0; +#endif +} + +double MemoryManager::getDeviceMemoryHighWatermark() { +#ifdef KRIPKE_USE_CHAI + auto chai_resource_manager = chai::ArrayManager::getInstance(); + auto device_allocator = chai_resource_manager->getAllocator(chai::GPU); + return ((double) device_allocator.getHighWatermark()) / (1024 * 1024 * 1024); +#else + return 0.0; +#endif +} diff --git a/src/Kripke/Core/MemoryManager.h b/src/Kripke/Core/MemoryManager.h new file mode 100644 index 00000000..f7ee917a --- /dev/null +++ b/src/Kripke/Core/MemoryManager.h @@ -0,0 +1,28 @@ +// +// Copyright (c) 2014-25, Lawrence Livermore National Security, LLC +// and Kripke project contributors. See the Kripke/COPYRIGHT file for details. +// +// SPDX-License-Identifier: (BSD-3-Clause) +// + +#ifndef KRIPKE_CORE_MEMORYMANAGER_H__ +#define KRIPKE_CORE_MEMORYMANAGER_H__ + +#include + +namespace Kripke { +namespace Core { + +class MemoryManager { + protected: + int device_pool_size; + + public: + MemoryManager(int device_pool_size); + double getDeviceMemoryPoolSize(); + double getDeviceMemoryHighWatermark(); +}; + +} } // namespace + +#endif diff --git a/src/KripkeConfig.h.in b/src/KripkeConfig.h.in index f2c22638..7596f564 100644 --- a/src/KripkeConfig.h.in +++ b/src/KripkeConfig.h.in @@ -11,6 +11,7 @@ #cmakedefine KRIPKE_USE_OPENMP #cmakedefine KRIPKE_USE_CUDA #cmakedefine KRIPKE_USE_CHAI +#cmakedefine KRIPKE_USE_CHAI_SINGLE_MEMORY #cmakedefine KRIPKE_USE_HIP #cmakedefine KRIPKE_USE_CALIPER diff --git a/src/kripke.cpp b/src/kripke.cpp index 86e4a7cb..b5cbbeee 100644 --- a/src/kripke.cpp +++ b/src/kripke.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -500,7 +501,8 @@ int main(int argc, char **argv) { // Allocate problem - Kripke::Core::DataStore data_store(vars.dev_pool_size); + Kripke::Core::MemoryManager memory_manager(vars.dev_pool_size); + Kripke::Core::DataStore data_store; Kripke::generateProblem(data_store, vars); // Run the solver @@ -536,6 +538,22 @@ int main(int argc, char **argv) { printf(" Grind time : %e [(seconds/iteration)/unknowns]\n", grind_time); printf(" Sweep efficiency : %4.5lf [100.0 * SweepSubdomain time / SweepSolver time]\n", sweep_eff); printf(" Number of unknowns: %lu\n", (unsigned long) num_unknowns); + +#ifdef KRIPKE_USE_CHAI + double device_memory_pool_size = memory_manager.getDeviceMemoryPoolSize(); + double device_memory_high_watermark = memory_manager.getDeviceMemoryHighWatermark(); +#ifdef KRIPKE_USE_CALIPER + adiak::value("umpire_device_pool_size", device_memory_pool_size); + adiak::value("umpire_device_high_watermark", device_memory_high_watermark); +#endif + printf("\n"); + printf("Memory Usage\n"); + printf("============\n"); + printf("\n"); + printf(" Device pool size: %4.2lf GB\n", device_memory_pool_size); + printf(" Device high water mark: %4.2lf GB\n", device_memory_high_watermark); +#endif + } #ifdef KRIPKE_USE_CALIPER