From 755e5781ef80b1e3791ef5f25aed8a902c135ae6 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 4 Mar 2026 12:19:45 -0800 Subject: [PATCH 1/9] Add destroyAllocator method Update C/FORTRAN interface --- cmake/SetupUmpireOptions.cmake | 1 + src/umpire/ResourceManager.cpp | 151 ++++++++++ src/umpire/ResourceManager.hpp | 38 +++ src/umpire/ResourceManager.inl | 1 + src/umpire/config.hpp.in | 1 + .../c_fortran/wrapResourceManager.cpp | 90 ++++++ .../interface/c_fortran/wrapResourceManager.h | 20 ++ src/umpire/interface/c_fortran/wrapfumpire.f | 133 +++++++++ src/umpire/interface/umpire_shroud.yaml | 18 ++ tests/integration/CMakeLists.txt | 14 + tests/integration/destroy_allocator_tests.cpp | 281 ++++++++++++++++++ 11 files changed, 748 insertions(+) create mode 100644 tests/integration/destroy_allocator_tests.cpp diff --git a/cmake/SetupUmpireOptions.cmake b/cmake/SetupUmpireOptions.cmake index 725afbae1..346d7578e 100644 --- a/cmake/SetupUmpireOptions.cmake +++ b/cmake/SetupUmpireOptions.cmake @@ -39,6 +39,7 @@ option(UMPIRE_ENABLE_SANITIZER_TESTS "Enable address sanitizer tests" Off) option(UMPIRE_ENABLE_DEVICE_ALLOCATOR "Enable Device Allocator" Off) option(UMPIRE_ENABLE_SQLITE_EXPERIMENTAL "Build with sqlite event integration (experimental)" Off) option(UMPIRE_DISABLE_ALLOCATIONMAP_DEBUG "Disable verbose output from AllocationMap during debug builds" Off) +option(UMPIRE_ENABLE_STRICT_DESTROY "Enable strict error checking in destroyAllocator (throw errors instead of warnings)" Off) set(UMPIRE_FMT_TARGET fmt::fmt-header-only CACHE STRING "Name of fmt target to use") if (UMPIRE_ENABLE_INACCESSIBILITY_TESTS) diff --git a/src/umpire/ResourceManager.cpp b/src/umpire/ResourceManager.cpp index 07f1cd5c6..05d69b2cf 100644 --- a/src/umpire/ResourceManager.cpp +++ b/src/umpire/ResourceManager.cpp @@ -326,6 +326,157 @@ void ResourceManager::removeAlias(const std::string& name, Allocator allocator) m_allocators_by_name.erase(a); } +bool ResourceManager::isCoreResource(strategy::AllocationStrategy* strategy) +{ + // Check if it's in the memory resources map (core resources) + for (const auto& entry : m_memory_resources) { + if (entry.second == strategy) { + return true; + } + } + + // Check special internal allocators + std::string name = strategy->getName(); + if (name == "__umpire_internal_null" || name == "__umpire_internal_0_byte_pool") { + return true; + } + + return false; +} + +void ResourceManager::destroyAllocator(const std::string& name, bool free_allocations) +{ + std::lock_guard lock(m_mutex); + + UMPIRE_LOG(Debug, "(name=\"" << name << "\", free_allocations=" << free_allocations << ")"); + + // Find strategy by name + auto it = m_allocators_by_name.find(name); + if (it == m_allocators_by_name.end()) { + UMPIRE_ERROR(runtime_error, fmt::format("Allocator \"{}\" not found", name)); + } + + strategy::AllocationStrategy* strategy = it->second; + int id = strategy->getId(); + + // Validate not core resource + if (isCoreResource(strategy)) { + UMPIRE_ERROR(runtime_error, + fmt::format("Cannot destroy core resource allocator \"{}\"", name)); + } + + // Check for active allocations + auto records = umpire::get_allocator_records(Allocator(strategy)); + if (!records.empty() && !free_allocations) { +#ifdef UMPIRE_ENABLE_STRICT_DESTROY + UMPIRE_ERROR(runtime_error, + fmt::format("Allocator \"{}\" has {} active allocations. " + "Use free_allocations=true or deallocate them first.", + name, records.size())); +#else + UMPIRE_LOG(Warning, "Allocator \"" << name << "\" has " << records.size() + << " active allocations. Destroying anyway (non-strict mode)."); +#endif + } + + // Check for child allocators (allocators using this as parent) + std::vector child_names; + for (const auto& alloc : m_allocators) { + if (alloc.get() != strategy && alloc->getParent() == strategy) { + child_names.push_back(alloc->getName()); + } + } + + if (!child_names.empty()) { + std::string children_str; + for (size_t i = 0; i < child_names.size(); ++i) { + if (i > 0) children_str += ", "; + children_str += child_names[i]; + } + +#ifdef UMPIRE_ENABLE_STRICT_DESTROY + UMPIRE_ERROR(runtime_error, + fmt::format("Allocator \"{}\" is a parent of other allocators: {}. " + "Destroy children first.", + name, children_str)); +#else + UMPIRE_LOG(Warning, "Allocator \"" << name << "\" is a parent of other allocators: " + << children_str << ". Destroying anyway (non-strict mode)."); +#endif + } + + // Free allocations if requested + if (free_allocations && !records.empty()) { + UMPIRE_LOG(Debug, "Freeing " << records.size() << " allocations"); + for (const auto& record : records) { + strategy->deallocate_internal(record.ptr, record.size); + } + } + + // Collect all names pointing to this strategy (handles aliases) + std::vector names_to_remove; + for (const auto& entry : m_allocators_by_name) { + if (entry.second == strategy) { + names_to_remove.push_back(entry.first); + } + } + + // Remove from all data structures + for (const auto& n : names_to_remove) { + m_allocators_by_name.erase(n); + } + + m_allocators_by_id.erase(id); + + // Remove from memory resources if present + for (auto it_mem = m_memory_resources.begin(); it_mem != m_memory_resources.end();) { + if (it_mem->second == strategy) { + it_mem = m_memory_resources.erase(it_mem); + } else { + ++it_mem; + } + } + + // Remove from shared allocator names if present + auto shared_it = std::find(m_shared_allocator_names.begin(), m_shared_allocator_names.end(), name); + if (shared_it != m_shared_allocator_names.end()) { + m_shared_allocator_names.erase(shared_it); + } + + // Remove from allocators list (destroys the unique_ptr) + for (auto it_alloc = m_allocators.begin(); it_alloc != m_allocators.end(); ++it_alloc) { + if (it_alloc->get() == strategy) { + m_allocators.erase(it_alloc); + break; + } + } + + // Record event for replay + umpire::event::record([&](auto& event) { + event.name("destroy_allocator") + .category(event::category::operation) + .arg("allocator_name", name) + .arg("allocator_id", id) + .arg("freed_allocations", free_allocations) + .tag("replay", "true"); + }); + + UMPIRE_LOG(Debug, "Allocator \"" << name << "\" destroyed successfully"); +} + +void ResourceManager::destroyAllocator(int id, bool free_allocations) +{ + UMPIRE_LOG(Debug, "(id=" << id << ", free_allocations=" << free_allocations << ")"); + + auto it = m_allocators_by_id.find(id); + if (it == m_allocators_by_id.end()) { + UMPIRE_ERROR(runtime_error, fmt::format("Allocator with id {} not found", id)); + } + + // Delegate to string version + destroyAllocator(it->second->getName(), free_allocations); +} + Allocator ResourceManager::getAllocator(void* ptr) { UMPIRE_LOG(Debug, "(ptr=" << ptr << ")"); diff --git a/src/umpire/ResourceManager.hpp b/src/umpire/ResourceManager.hpp index 4cd72813f..36d49e39a 100644 --- a/src/umpire/ResourceManager.hpp +++ b/src/umpire/ResourceManager.hpp @@ -161,6 +161,42 @@ class ResourceManager { */ void removeAlias(const std::string& name, Allocator allocator); + /*! + * \brief Destroy an allocator by name. + * + * Removes the allocator from the ResourceManager and frees associated + * resources. Core resource allocators (HOST, DEVICE, etc.) cannot be + * destroyed. + * + * If UMPIRE_ENABLE_STRICT_DESTROY is enabled at configure time: + * - Throws error if allocator has active allocations and free_allocations=false + * - Throws error if allocator is a parent of other allocators + * + * If UMPIRE_ENABLE_STRICT_DESTROY is disabled (default): + * - Logs warning but proceeds if allocator has active allocations + * - Logs warning but proceeds if allocator is a parent + * + * \param name Name of the allocator to destroy + * \param free_allocations If true, deallocates all active allocations + * before destroying. Defaults to false. + * + * \throw runtime_error if allocator is a core resource or not found + */ + void destroyAllocator(const std::string& name, bool free_allocations = false); + + /*! + * \brief Destroy an allocator by ID. + * + * See destroyAllocator(const std::string&, bool) for detailed behavior. + * + * \param id ID of the allocator to destroy + * \param free_allocations If true, deallocates all active allocations + * before destroying. Defaults to false. + * + * \throw runtime_error if allocator is a core resource or not found + */ + void destroyAllocator(int id, bool free_allocations = false); + /*! * \brief Get the Allocator used to allocate ptr. * @@ -328,6 +364,8 @@ class ResourceManager { strategy::AllocationStrategy* findAllocatorForId(int id); strategy::AllocationStrategy* getAllocationStrategy(const std::string& name); + bool isCoreResource(strategy::AllocationStrategy* strategy); + int getNextId() noexcept; std::string getAllocatorInformation() const noexcept; diff --git a/src/umpire/ResourceManager.inl b/src/umpire/ResourceManager.inl index ffec72fc2..2c96be943 100644 --- a/src/umpire/ResourceManager.inl +++ b/src/umpire/ResourceManager.inl @@ -11,6 +11,7 @@ #include "camp/list.hpp" #include "umpire/ResourceManager.hpp" +#include "umpire/event/event.hpp" #include "umpire/util/Macros.hpp" #include "umpire/util/error.hpp" #include "umpire/util/make_unique.hpp" diff --git a/src/umpire/config.hpp.in b/src/umpire/config.hpp.in index 6d16aec86..e98003d9d 100644 --- a/src/umpire/config.hpp.in +++ b/src/umpire/config.hpp.in @@ -36,6 +36,7 @@ #cmakedefine UMPIRE_ENABLE_DEVICE_ALLOCATOR #cmakedefine UMPIRE_ENABLE_SQLITE_EXPERIMENTAL #cmakedefine UMPIRE_DISABLE_ALLOCATIONMAP_DEBUG +#cmakedefine UMPIRE_ENABLE_STRICT_DESTROY #define UMPIRE_VERSION_MAJOR @Umpire_VERSION_MAJOR@ #define UMPIRE_VERSION_MINOR @Umpire_VERSION_MINOR@ diff --git a/src/umpire/interface/c_fortran/wrapResourceManager.cpp b/src/umpire/interface/c_fortran/wrapResourceManager.cpp index b0c39f875..5ca4a58ea 100644 --- a/src/umpire/interface/c_fortran/wrapResourceManager.cpp +++ b/src/umpire/interface/c_fortran/wrapResourceManager.cpp @@ -729,6 +729,96 @@ void umpire_resourcemanager_remove_alias_bufferify( // splicer end class.ResourceManager.method.remove_alias_bufferify } +/** + * \brief Destroy an allocator by name + * + */ +void umpire_resourcemanager_destroy_allocator( + umpire_resourcemanager * self, const char * name) +{ + umpire::ResourceManager *SH_this = + static_cast(self->addr); + // splicer begin class.ResourceManager.method.destroy_allocator + const std::string SHCXX_name(name); + SH_this->destroyAllocator(SHCXX_name); + // splicer end class.ResourceManager.method.destroy_allocator +} + +/** + * \brief Destroy an allocator by name + * + */ +void umpire_resourcemanager_destroy_allocator_bufferify( + umpire_resourcemanager * self, const char * name, int Lname) +{ + umpire::ResourceManager *SH_this = + static_cast(self->addr); + // splicer begin class.ResourceManager.method.destroy_allocator_bufferify + const std::string SHCXX_name(name, Lname); + SH_this->destroyAllocator(SHCXX_name); + // splicer end class.ResourceManager.method.destroy_allocator_bufferify +} + +/** + * \brief Destroy an allocator by name + * + */ +void umpire_resourcemanager_destroy_allocator_with_free( + umpire_resourcemanager * self, const char * name, + bool free_allocations) +{ + umpire::ResourceManager *SH_this = + static_cast(self->addr); + // splicer begin class.ResourceManager.method.destroy_allocator_with_free + const std::string SHCXX_name(name); + SH_this->destroyAllocator(SHCXX_name, free_allocations); + // splicer end class.ResourceManager.method.destroy_allocator_with_free +} + +/** + * \brief Destroy an allocator by name + * + */ +void umpire_resourcemanager_destroy_allocator_with_free_bufferify( + umpire_resourcemanager * self, const char * name, int Lname, + bool free_allocations) +{ + umpire::ResourceManager *SH_this = + static_cast(self->addr); + // splicer begin class.ResourceManager.method.destroy_allocator_with_free_bufferify + const std::string SHCXX_name(name, Lname); + SH_this->destroyAllocator(SHCXX_name, free_allocations); + // splicer end class.ResourceManager.method.destroy_allocator_with_free_bufferify +} + +/** + * \brief Destroy an allocator by ID + * + */ +void umpire_resourcemanager_destroy_allocator( + umpire_resourcemanager * self, int id) +{ + umpire::ResourceManager *SH_this = + static_cast(self->addr); + // splicer begin class.ResourceManager.method.destroy_allocator + SH_this->destroyAllocator(id); + // splicer end class.ResourceManager.method.destroy_allocator +} + +/** + * \brief Destroy an allocator by ID + * + */ +void umpire_resourcemanager_destroy_allocator_with_free( + umpire_resourcemanager * self, int id, bool free_allocations) +{ + umpire::ResourceManager *SH_this = + static_cast(self->addr); + // splicer begin class.ResourceManager.method.destroy_allocator_with_free + SH_this->destroyAllocator(id, free_allocations); + // splicer end class.ResourceManager.method.destroy_allocator_with_free +} + umpire_allocator * umpire_resourcemanager_get_allocator_for_ptr( umpire_resourcemanager * self, void * ptr, umpire_allocator * SHC_rv) diff --git a/src/umpire/interface/c_fortran/wrapResourceManager.h b/src/umpire/interface/c_fortran/wrapResourceManager.h index fd4ebe729..1faee27bc 100644 --- a/src/umpire/interface/c_fortran/wrapResourceManager.h +++ b/src/umpire/interface/c_fortran/wrapResourceManager.h @@ -200,6 +200,26 @@ void umpire_resourcemanager_remove_alias_bufferify( umpire_resourcemanager * self, const char * name, int Lname, umpire_allocator allocator); +void umpire_resourcemanager_destroy_allocator( + umpire_resourcemanager * self, const char * name); + +void umpire_resourcemanager_destroy_allocator_bufferify( + umpire_resourcemanager * self, const char * name, int Lname); + +void umpire_resourcemanager_destroy_allocator_with_free( + umpire_resourcemanager * self, const char * name, + bool free_allocations); + +void umpire_resourcemanager_destroy_allocator_with_free_bufferify( + umpire_resourcemanager * self, const char * name, int Lname, + bool free_allocations); + +void umpire_resourcemanager_destroy_allocator( + umpire_resourcemanager * self, int id); + +void umpire_resourcemanager_destroy_allocator_with_free( + umpire_resourcemanager * self, int id, bool free_allocations); + umpire_allocator * umpire_resourcemanager_get_allocator_for_ptr( umpire_resourcemanager * self, void * ptr, umpire_allocator * SHC_rv); diff --git a/src/umpire/interface/c_fortran/wrapfumpire.f b/src/umpire/interface/c_fortran/wrapfumpire.f index a09bd4ec6..084fdf0de 100644 --- a/src/umpire/interface/c_fortran/wrapfumpire.f +++ b/src/umpire/interface/c_fortran/wrapfumpire.f @@ -244,6 +244,10 @@ module umpire_mod procedure :: make_allocator_prefetcher => resourcemanager_make_allocator_prefetcher procedure :: add_alias => resourcemanager_add_alias procedure :: remove_alias => resourcemanager_remove_alias + procedure :: destroy_allocator => resourcemanager_destroy_allocator + procedure :: destroy_allocator_with_free => resourcemanager_destroy_allocator_with_free + procedure :: destroy_allocator => resourcemanager_destroy_allocator + procedure :: destroy_allocator_with_free => resourcemanager_destroy_allocator_with_free procedure :: get_allocator_for_ptr => resourcemanager_get_allocator_for_ptr procedure :: is_allocator_name => resourcemanager_is_allocator_name procedure :: is_allocator_id => resourcemanager_is_allocator_id @@ -261,6 +265,9 @@ module umpire_mod procedure :: deregister_allocation => resourcemanager_deregister_allocation procedure :: associated => resourcemanager_associated generic :: copy => copy_all, copy_with_size + generic :: destroy_allocator => destroy_allocator, & + destroy_allocator_with_free, destroy_allocator, & + destroy_allocator_with_free generic :: get_allocator => get_allocator_by_name, & get_allocator_by_id, get_allocator_for_ptr generic :: is_allocator => is_allocator_name, is_allocator_id @@ -954,6 +961,69 @@ subroutine c_resourcemanager_remove_alias_bufferify(self, name, & type(umpire_SHROUD_allocator_capsule), intent(IN), value :: allocator end subroutine c_resourcemanager_remove_alias_bufferify + subroutine c_resourcemanager_destroy_allocator(self, name) & + bind(C, name="umpire_resourcemanager_destroy_allocator") + use iso_c_binding, only : C_CHAR + import :: umpire_SHROUD_resourcemanager_capsule + implicit none + type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self + character(kind=C_CHAR), intent(IN) :: name(*) + end subroutine c_resourcemanager_destroy_allocator + + subroutine c_resourcemanager_destroy_allocator_bufferify(self, & + name, Lname) & + bind(C, name="umpire_resourcemanager_destroy_allocator_bufferify") + use iso_c_binding, only : C_CHAR, C_INT + import :: umpire_SHROUD_resourcemanager_capsule + implicit none + type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self + character(kind=C_CHAR), intent(IN) :: name(*) + integer(C_INT), value, intent(IN) :: Lname + end subroutine c_resourcemanager_destroy_allocator_bufferify + + subroutine c_resourcemanager_destroy_allocator_with_free(self, & + name, free_allocations) & + bind(C, name="umpire_resourcemanager_destroy_allocator_with_free") + use iso_c_binding, only : C_BOOL, C_CHAR + import :: umpire_SHROUD_resourcemanager_capsule + implicit none + type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self + character(kind=C_CHAR), intent(IN) :: name(*) + logical(C_BOOL), value, intent(IN) :: free_allocations + end subroutine c_resourcemanager_destroy_allocator_with_free + + subroutine c_resourcemanager_destroy_allocator_with_free_bufferify( & + self, name, Lname, free_allocations) & + bind(C, name="umpire_resourcemanager_destroy_allocator_with_free_bufferify") + use iso_c_binding, only : C_BOOL, C_CHAR, C_INT + import :: umpire_SHROUD_resourcemanager_capsule + implicit none + type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self + character(kind=C_CHAR), intent(IN) :: name(*) + integer(C_INT), value, intent(IN) :: Lname + logical(C_BOOL), value, intent(IN) :: free_allocations + end subroutine c_resourcemanager_destroy_allocator_with_free_bufferify + + subroutine c_resourcemanager_destroy_allocator(self, id) & + bind(C, name="umpire_resourcemanager_destroy_allocator") + use iso_c_binding, only : C_INT + import :: umpire_SHROUD_resourcemanager_capsule + implicit none + type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self + integer(C_INT), value, intent(IN) :: id + end subroutine c_resourcemanager_destroy_allocator + + subroutine c_resourcemanager_destroy_allocator_with_free(self, & + id, free_allocations) & + bind(C, name="umpire_resourcemanager_destroy_allocator_with_free") + use iso_c_binding, only : C_BOOL, C_INT + import :: umpire_SHROUD_resourcemanager_capsule + implicit none + type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self + integer(C_INT), value, intent(IN) :: id + logical(C_BOOL), value, intent(IN) :: free_allocations + end subroutine c_resourcemanager_destroy_allocator_with_free + function c_resourcemanager_get_allocator_for_ptr(self, ptr, & SHT_crv) & result(SHT_rv) & @@ -3115,6 +3185,69 @@ subroutine resourcemanager_remove_alias(obj, name, allocator) ! splicer end class.ResourceManager.method.remove_alias end subroutine resourcemanager_remove_alias + !> + !! \brief Destroy an allocator by name + !! + !< + subroutine resourcemanager_destroy_allocator(obj, name) + use iso_c_binding, only : C_INT + class(UmpireResourceManager) :: obj + character(len=*), intent(IN) :: name + ! splicer begin class.ResourceManager.method.destroy_allocator + call c_resourcemanager_destroy_allocator_bufferify(obj%cxxmem, & + name, len_trim(name, kind=C_INT)) + ! splicer end class.ResourceManager.method.destroy_allocator + end subroutine resourcemanager_destroy_allocator + + !> + !! \brief Destroy an allocator by name + !! + !< + subroutine resourcemanager_destroy_allocator_with_free(obj, name, & + free_allocations) + use iso_c_binding, only : C_BOOL, C_INT + class(UmpireResourceManager) :: obj + character(len=*), intent(IN) :: name + logical, value, intent(IN) :: free_allocations + ! splicer begin class.ResourceManager.method.destroy_allocator_with_free + logical(C_BOOL) SH_free_allocations + SH_free_allocations = free_allocations ! coerce to C_BOOL + call c_resourcemanager_destroy_allocator_with_free_bufferify(obj%cxxmem, & + name, len_trim(name, kind=C_INT), SH_free_allocations) + ! splicer end class.ResourceManager.method.destroy_allocator_with_free + end subroutine resourcemanager_destroy_allocator_with_free + + !> + !! \brief Destroy an allocator by ID + !! + !< + subroutine resourcemanager_destroy_allocator(obj, id) + use iso_c_binding, only : C_INT + class(UmpireResourceManager) :: obj + integer(C_INT), value, intent(IN) :: id + ! splicer begin class.ResourceManager.method.destroy_allocator + call c_resourcemanager_destroy_allocator(obj%cxxmem, id) + ! splicer end class.ResourceManager.method.destroy_allocator + end subroutine resourcemanager_destroy_allocator + + !> + !! \brief Destroy an allocator by ID + !! + !< + subroutine resourcemanager_destroy_allocator_with_free(obj, id, & + free_allocations) + use iso_c_binding, only : C_BOOL, C_INT + class(UmpireResourceManager) :: obj + integer(C_INT), value, intent(IN) :: id + logical, value, intent(IN) :: free_allocations + ! splicer begin class.ResourceManager.method.destroy_allocator_with_free + logical(C_BOOL) SH_free_allocations + SH_free_allocations = free_allocations ! coerce to C_BOOL + call c_resourcemanager_destroy_allocator_with_free(obj%cxxmem, & + id, SH_free_allocations) + ! splicer end class.ResourceManager.method.destroy_allocator_with_free + end subroutine resourcemanager_destroy_allocator_with_free + function resourcemanager_get_allocator_for_ptr(obj, ptr) & result(SHT_rv) use iso_c_binding, only : C_PTR diff --git a/src/umpire/interface/umpire_shroud.yaml b/src/umpire/interface/umpire_shroud.yaml index 77bc05bab..e8e6563a2 100644 --- a/src/umpire/interface/umpire_shroud.yaml +++ b/src/umpire/interface/umpire_shroud.yaml @@ -264,6 +264,24 @@ declarations: - decl: void addAlias(const std::string& name, Allocator allocator) - decl: void removeAlias(const std::string& name, Allocator allocator) + - decl: void destroyAllocator(const std::string& name, bool free_allocations=false) + doxygen: + brief: Destroy an allocator by name + format: + function_suffix: _by_name + default_arg_suffix: + - "" + - _with_free + + - decl: void destroyAllocator(int id, bool free_allocations=false) + doxygen: + brief: Destroy an allocator by ID + format: + function_suffix: _by_id + default_arg_suffix: + - "" + - _with_free + - decl: Allocator getAllocator(void* ptr) format: function_suffix: _for_ptr diff --git a/tests/integration/CMakeLists.txt b/tests/integration/CMakeLists.txt index 9c83a846f..ffd9ed3ba 100644 --- a/tests/integration/CMakeLists.txt +++ b/tests/integration/CMakeLists.txt @@ -243,6 +243,20 @@ blt_add_test( NAME introspection_tests COMMAND introspection_tests) +blt_add_executable( + NAME destroy_allocator_tests + SOURCES destroy_allocator_tests.cpp + DEPENDS_ON ${integration_tests_depends}) + +target_include_directories( + destroy_allocator_tests + PRIVATE + ${PROJECT_BINARY_DIR}/include) + +blt_add_test( + NAME destroy_allocator_tests + COMMAND destroy_allocator_tests) + if (UMPIRE_ENABLE_IPC_SHARED_MEMORY AND UMPIRE_ENABLE_MPI) blt_add_executable( NAME get_communicator_tests diff --git a/tests/integration/destroy_allocator_tests.cpp b/tests/integration/destroy_allocator_tests.cpp new file mode 100644 index 000000000..fdcee7a96 --- /dev/null +++ b/tests/integration/destroy_allocator_tests.cpp @@ -0,0 +1,281 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2016-26, Lawrence Livermore National Security, LLC and Umpire +// project contributors. See the COPYRIGHT file for details. +// +// SPDX-License-Identifier: (MIT) +////////////////////////////////////////////////////////////////////////////// +#include "gtest/gtest.h" +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" +#include "umpire/Umpire.hpp" +#include "umpire/config.hpp" +#include "umpire/strategy/QuickPool.hpp" + +TEST(DestroyAllocatorTest, DestroyBasicQuickPool) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Create a QuickPool + auto pool = rm.makeAllocator("test_pool_basic", rm.getAllocator("HOST")); + + // Allocate and deallocate to verify it works + void* ptr = pool.allocate(100); + ASSERT_NE(nullptr, ptr); + pool.deallocate(ptr); + + // Verify allocator exists + ASSERT_TRUE(rm.isAllocator("test_pool_basic")); + + // Destroy the allocator + ASSERT_NO_THROW(rm.destroyAllocator("test_pool_basic")); + + // Verify allocator no longer exists + ASSERT_FALSE(rm.isAllocator("test_pool_basic")); + + // Verify getting the allocator throws an error + ASSERT_THROW(rm.getAllocator("test_pool_basic"), umpire::runtime_error); +} + +TEST(DestroyAllocatorTest, DestroyAllocatorById) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Create a QuickPool + auto pool = rm.makeAllocator("test_pool_by_id", rm.getAllocator("HOST")); + int id = pool.getId(); + + // Verify allocator exists + ASSERT_TRUE(rm.isAllocator(id)); + + // Destroy the allocator by ID + ASSERT_NO_THROW(rm.destroyAllocator(id)); + + // Verify allocator no longer exists + ASSERT_FALSE(rm.isAllocator(id)); + ASSERT_FALSE(rm.isAllocator("test_pool_by_id")); +} + +TEST(DestroyAllocatorTest, ErrorOnCoreResourceDestruction) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Attempt to destroy HOST allocator - should throw error + ASSERT_THROW(rm.destroyAllocator("HOST"), umpire::runtime_error); + + // Verify HOST still exists + ASSERT_TRUE(rm.isAllocator("HOST")); + +#ifdef UMPIRE_ENABLE_DEVICE + // Attempt to destroy DEVICE allocator - should throw error + ASSERT_THROW(rm.destroyAllocator("DEVICE"), umpire::runtime_error); + + // Verify DEVICE still exists + ASSERT_TRUE(rm.isAllocator("DEVICE")); +#endif +} + +TEST(DestroyAllocatorTest, ErrorOnInternalAllocators) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Attempt to destroy internal null allocator - should throw error + ASSERT_THROW(rm.destroyAllocator("__umpire_internal_null"), umpire::runtime_error); + + // Attempt to destroy internal 0-byte pool - should throw error + ASSERT_THROW(rm.destroyAllocator("__umpire_internal_0_byte_pool"), umpire::runtime_error); +} + +#ifdef UMPIRE_ENABLE_STRICT_DESTROY +TEST(DestroyAllocatorTest, ActiveAllocationsStrictMode) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Create a QuickPool + auto pool = rm.makeAllocator("test_pool_strict", rm.getAllocator("HOST")); + + // Allocate memory + void* ptr = pool.allocate(100); + ASSERT_NE(nullptr, ptr); + + // Try to destroy with active allocations - should throw error in strict mode + ASSERT_THROW(rm.destroyAllocator("test_pool_strict", false), umpire::runtime_error); + + // Clean up + pool.deallocate(ptr); + rm.destroyAllocator("test_pool_strict"); +} +#else +TEST(DestroyAllocatorTest, ActiveAllocationsNonStrictMode) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Create a QuickPool + auto pool = rm.makeAllocator("test_pool_nonstrict", rm.getAllocator("HOST")); + + // Allocate memory + void* ptr = pool.allocate(100); + ASSERT_NE(nullptr, ptr); + + // Destroy with active allocations - should succeed with warning in non-strict mode + ASSERT_NO_THROW(rm.destroyAllocator("test_pool_nonstrict", false)); + + // Verify allocator is destroyed + ASSERT_FALSE(rm.isAllocator("test_pool_nonstrict")); +} +#endif + +TEST(DestroyAllocatorTest, FreeAllocationsOnDestroy) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Create a QuickPool + auto pool = rm.makeAllocator("test_pool_free", rm.getAllocator("HOST")); + + // Allocate multiple chunks of memory + void* ptr1 = pool.allocate(100); + void* ptr2 = pool.allocate(200); + void* ptr3 = pool.allocate(300); + ASSERT_NE(nullptr, ptr1); + ASSERT_NE(nullptr, ptr2); + ASSERT_NE(nullptr, ptr3); + + // Destroy with free_allocations=true - should succeed and free all allocations + ASSERT_NO_THROW(rm.destroyAllocator("test_pool_free", true)); + + // Verify allocator is destroyed + ASSERT_FALSE(rm.isAllocator("test_pool_free")); +} + +TEST(DestroyAllocatorTest, DestroyAllocatorWithAliases) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Create a QuickPool + auto pool = rm.makeAllocator("test_pool_alias", rm.getAllocator("HOST")); + + // Add aliases + rm.addAlias("alias1", pool); + rm.addAlias("alias2", pool); + + // Verify aliases exist + ASSERT_TRUE(rm.isAllocator("test_pool_alias")); + ASSERT_TRUE(rm.isAllocator("alias1")); + ASSERT_TRUE(rm.isAllocator("alias2")); + + // Destroy by original name + ASSERT_NO_THROW(rm.destroyAllocator("test_pool_alias")); + + // Verify all aliases are removed + ASSERT_FALSE(rm.isAllocator("test_pool_alias")); + ASSERT_FALSE(rm.isAllocator("alias1")); + ASSERT_FALSE(rm.isAllocator("alias2")); +} + +#ifdef UMPIRE_ENABLE_STRICT_DESTROY +TEST(DestroyAllocatorTest, ParentChildWarningStrictMode) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Create parent allocator + auto parent = rm.makeAllocator("test_parent_strict", rm.getAllocator("HOST")); + + // Create child allocator using parent + auto child = rm.makeAllocator("test_child_strict", parent); + + // Try to destroy parent - should throw error in strict mode + ASSERT_THROW(rm.destroyAllocator("test_parent_strict"), umpire::runtime_error); + + // Clean up in correct order + rm.destroyAllocator("test_child_strict"); + rm.destroyAllocator("test_parent_strict"); +} +#else +TEST(DestroyAllocatorTest, ParentChildWarningNonStrictMode) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Create parent allocator + auto parent = rm.makeAllocator("test_parent_nonstrict", rm.getAllocator("HOST")); + + // Create child allocator using parent + rm.makeAllocator("test_child_nonstrict", parent); + + // Destroy parent - should succeed with warning in non-strict mode + ASSERT_NO_THROW(rm.destroyAllocator("test_parent_nonstrict")); + + // Clean up child + rm.destroyAllocator("test_child_nonstrict"); +} +#endif + +#if defined(UMPIRE_ENABLE_IPC_SHARED_MEMORY) || defined(UMPIRE_ENABLE_MPI3_SHARED_MEMORY) +TEST(DestroyAllocatorTest, DestroySharedAllocator) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Create a SHARED allocator + auto shared_alloc = rm.makeResource("SHARED"); + std::string shared_name = shared_alloc.getName(); + + // Verify it's in the shared allocator names list + auto shared_names = rm.getSharedAllocatorNames(); + ASSERT_TRUE(std::find(shared_names.begin(), shared_names.end(), shared_name) != shared_names.end()); + + // Destroy the shared allocator + ASSERT_NO_THROW(rm.destroyAllocator(shared_name)); + + // Verify it's removed from shared allocator names + shared_names = rm.getSharedAllocatorNames(); + ASSERT_TRUE(std::find(shared_names.begin(), shared_names.end(), shared_name) == shared_names.end()); +} +#endif + +TEST(DestroyAllocatorTest, AllocatorNotFound) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Attempt to destroy non-existent allocator - should throw error + ASSERT_THROW(rm.destroyAllocator("non_existent_allocator"), umpire::runtime_error); + ASSERT_THROW(rm.destroyAllocator(99999), umpire::runtime_error); +} + +TEST(DestroyAllocatorTest, RepeatedDestroy) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Create a QuickPool + rm.makeAllocator("test_pool_repeated", rm.getAllocator("HOST")); + + // Destroy once - should succeed + ASSERT_NO_THROW(rm.destroyAllocator("test_pool_repeated")); + + // Attempt to destroy again - should throw "not found" error + ASSERT_THROW(rm.destroyAllocator("test_pool_repeated"), umpire::runtime_error); +} + +TEST(DestroyAllocatorTest, DestroyAndRecreate) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + // Create a QuickPool + auto pool1 = rm.makeAllocator("test_pool_recreate", rm.getAllocator("HOST")); + int id1 = pool1.getId(); + + // Destroy it + ASSERT_NO_THROW(rm.destroyAllocator("test_pool_recreate")); + + // Create a new allocator with the same name + auto pool2 = rm.makeAllocator("test_pool_recreate", rm.getAllocator("HOST")); + int id2 = pool2.getId(); + + // Should have different IDs + ASSERT_NE(id1, id2); + + // Verify new allocator works + void* ptr = pool2.allocate(100); + ASSERT_NE(nullptr, ptr); + pool2.deallocate(ptr); + + // Clean up + rm.destroyAllocator("test_pool_recreate"); +} From 3b99bb172871731405d226bf474c1da00f9ce8db Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 4 Mar 2026 16:35:37 -0800 Subject: [PATCH 2/9] Configure with runtime var --- cmake/SetupUmpireOptions.cmake | 1 - src/umpire/ResourceManager.cpp | 81 ++++++++++--------- src/umpire/ResourceManager.hpp | 23 +++++- src/umpire/config.hpp.in | 1 - tests/integration/destroy_allocator_tests.cpp | 43 +++++----- 5 files changed, 86 insertions(+), 63 deletions(-) diff --git a/cmake/SetupUmpireOptions.cmake b/cmake/SetupUmpireOptions.cmake index 346d7578e..725afbae1 100644 --- a/cmake/SetupUmpireOptions.cmake +++ b/cmake/SetupUmpireOptions.cmake @@ -39,7 +39,6 @@ option(UMPIRE_ENABLE_SANITIZER_TESTS "Enable address sanitizer tests" Off) option(UMPIRE_ENABLE_DEVICE_ALLOCATOR "Enable Device Allocator" Off) option(UMPIRE_ENABLE_SQLITE_EXPERIMENTAL "Build with sqlite event integration (experimental)" Off) option(UMPIRE_DISABLE_ALLOCATIONMAP_DEBUG "Disable verbose output from AllocationMap during debug builds" Off) -option(UMPIRE_ENABLE_STRICT_DESTROY "Enable strict error checking in destroyAllocator (throw errors instead of warnings)" Off) set(UMPIRE_FMT_TARGET fmt::fmt-header-only CACHE STRING "Name of fmt target to use") if (UMPIRE_ENABLE_INACCESSIBILITY_TESTS) diff --git a/src/umpire/ResourceManager.cpp b/src/umpire/ResourceManager.cpp index 05d69b2cf..0650cead9 100644 --- a/src/umpire/ResourceManager.cpp +++ b/src/umpire/ResourceManager.cpp @@ -326,9 +326,9 @@ void ResourceManager::removeAlias(const std::string& name, Allocator allocator) m_allocators_by_name.erase(a); } -bool ResourceManager::isCoreResource(strategy::AllocationStrategy* strategy) +bool ResourceManager::isBuiltinAllocator(strategy::AllocationStrategy* strategy) { - // Check if it's in the memory resources map (core resources) + // Check if it's in the memory resources map (builtin resources) for (const auto& entry : m_memory_resources) { if (entry.second == strategy) { return true; @@ -359,50 +359,53 @@ void ResourceManager::destroyAllocator(const std::string& name, bool free_alloca strategy::AllocationStrategy* strategy = it->second; int id = strategy->getId(); - // Validate not core resource - if (isCoreResource(strategy)) { + // Validate not builtin allocator + if (isBuiltinAllocator(strategy)) { UMPIRE_ERROR(runtime_error, - fmt::format("Cannot destroy core resource allocator \"{}\"", name)); + fmt::format("Cannot destroy builtin allocator \"{}\"", name)); } // Check for active allocations - auto records = umpire::get_allocator_records(Allocator(strategy)); - if (!records.empty() && !free_allocations) { -#ifdef UMPIRE_ENABLE_STRICT_DESTROY - UMPIRE_ERROR(runtime_error, - fmt::format("Allocator \"{}\" has {} active allocations. " - "Use free_allocations=true or deallocate them first.", - name, records.size())); -#else - UMPIRE_LOG(Warning, "Allocator \"" << name << "\" has " << records.size() - << " active allocations. Destroying anyway (non-strict mode)."); -#endif + if (isStrictDestructionMode()) { + auto records = umpire::get_allocator_records(Allocator(strategy)); + if (!records.empty() && !free_allocations) { + UMPIRE_ERROR(runtime_error, + fmt::format("Allocator \"{}\" has {} active allocations. " + "Use free_allocations=true or deallocate them first.", + name, records.size())); + } + } else if (!free_allocations) { + UMPIRE_LOG(Warning, "Allocator \"" << name << "\" may have active allocations. " + << "Destroying anyway (non-strict mode)."); } + // Get records for potential cleanup + auto records = umpire::get_allocator_records(Allocator(strategy)); + // Check for child allocators (allocators using this as parent) - std::vector child_names; - for (const auto& alloc : m_allocators) { - if (alloc.get() != strategy && alloc->getParent() == strategy) { - child_names.push_back(alloc->getName()); + if (isStrictDestructionMode()) { + std::vector child_names; + for (const auto& alloc : m_allocators) { + if (alloc.get() != strategy && alloc->getParent() == strategy) { + child_names.push_back(alloc->getName()); + } } - } - if (!child_names.empty()) { - std::string children_str; - for (size_t i = 0; i < child_names.size(); ++i) { - if (i > 0) children_str += ", "; - children_str += child_names[i]; - } + if (!child_names.empty()) { + std::string children_str; + for (size_t i = 0; i < child_names.size(); ++i) { + if (i > 0) children_str += ", "; + children_str += child_names[i]; + } -#ifdef UMPIRE_ENABLE_STRICT_DESTROY - UMPIRE_ERROR(runtime_error, - fmt::format("Allocator \"{}\" is a parent of other allocators: {}. " - "Destroy children first.", - name, children_str)); -#else - UMPIRE_LOG(Warning, "Allocator \"" << name << "\" is a parent of other allocators: " - << children_str << ". Destroying anyway (non-strict mode)."); -#endif + UMPIRE_ERROR(runtime_error, + fmt::format("Allocator \"{}\" is a parent of other allocators: {}. " + "Destroy children first.", + name, children_str)); + } + } else { + UMPIRE_LOG(Warning, "Allocator \"" << name << "\" may be a parent of other allocators. " + << "Destroying anyway (non-strict mode)."); } // Free allocations if requested @@ -1109,6 +1112,12 @@ std::shared_ptr ResourceManager::getOperation(const std::st return op_registry.find(operation_name, src_allocator.getAllocationStrategy(), dst_allocator.getAllocationStrategy()); } +bool ResourceManager::isStrictDestructionMode() const noexcept +{ + static const char* env_value = std::getenv("UMPIRE_STRICT_DESTRUCTION"); + return (env_value != nullptr); +} + int ResourceManager::getNumDevices() const { int device_count{0}; diff --git a/src/umpire/ResourceManager.hpp b/src/umpire/ResourceManager.hpp index 36d49e39a..345f686b5 100644 --- a/src/umpire/ResourceManager.hpp +++ b/src/umpire/ResourceManager.hpp @@ -168,14 +168,20 @@ class ResourceManager { * resources. Core resource allocators (HOST, DEVICE, etc.) cannot be * destroyed. * - * If UMPIRE_ENABLE_STRICT_DESTROY is enabled at configure time: + * Behavior is controlled by the UMPIRE_STRICT_DESTRUCTION environment variable: + * + * If UMPIRE_STRICT_DESTRUCTION is set (to any value): * - Throws error if allocator has active allocations and free_allocations=false * - Throws error if allocator is a parent of other allocators * - * If UMPIRE_ENABLE_STRICT_DESTROY is disabled (default): + * If UMPIRE_STRICT_DESTRUCTION is not set (default): * - Logs warning but proceeds if allocator has active allocations * - Logs warning but proceeds if allocator is a parent * + * Example: + * export UMPIRE_STRICT_DESTRUCTION=1 // Enable strict mode + * unset UMPIRE_STRICT_DESTRUCTION // Disable strict mode (default) + * * \param name Name of the allocator to destroy * \param free_allocations If true, deallocates all active allocations * before destroying. Defaults to false. @@ -364,7 +370,18 @@ class ResourceManager { strategy::AllocationStrategy* findAllocatorForId(int id); strategy::AllocationStrategy* getAllocationStrategy(const std::string& name); - bool isCoreResource(strategy::AllocationStrategy* strategy); + bool isBuiltinAllocator(strategy::AllocationStrategy* strategy); + + /*! + * \brief Check if strict destruction mode is enabled via environment variable. + * + * Checks the UMPIRE_STRICT_DESTRUCTION environment variable. If set to any + * value, strict mode is enabled (errors thrown). If unset, non-strict mode + * is used (warnings logged). The check is cached on first call. + * + * \return true if UMPIRE_STRICT_DESTRUCTION is set, false otherwise + */ + bool isStrictDestructionMode() const noexcept; int getNextId() noexcept; diff --git a/src/umpire/config.hpp.in b/src/umpire/config.hpp.in index e98003d9d..6d16aec86 100644 --- a/src/umpire/config.hpp.in +++ b/src/umpire/config.hpp.in @@ -36,7 +36,6 @@ #cmakedefine UMPIRE_ENABLE_DEVICE_ALLOCATOR #cmakedefine UMPIRE_ENABLE_SQLITE_EXPERIMENTAL #cmakedefine UMPIRE_DISABLE_ALLOCATIONMAP_DEBUG -#cmakedefine UMPIRE_ENABLE_STRICT_DESTROY #define UMPIRE_VERSION_MAJOR @Umpire_VERSION_MAJOR@ #define UMPIRE_VERSION_MINOR @Umpire_VERSION_MINOR@ diff --git a/tests/integration/destroy_allocator_tests.cpp b/tests/integration/destroy_allocator_tests.cpp index fdcee7a96..4c9837c5e 100644 --- a/tests/integration/destroy_allocator_tests.cpp +++ b/tests/integration/destroy_allocator_tests.cpp @@ -10,6 +10,7 @@ #include "umpire/Umpire.hpp" #include "umpire/config.hpp" #include "umpire/strategy/QuickPool.hpp" +#include // for setenv/unsetenv TEST(DestroyAllocatorTest, DestroyBasicQuickPool) { @@ -85,15 +86,13 @@ TEST(DestroyAllocatorTest, ErrorOnInternalAllocators) ASSERT_THROW(rm.destroyAllocator("__umpire_internal_0_byte_pool"), umpire::runtime_error); } -#ifdef UMPIRE_ENABLE_STRICT_DESTROY TEST(DestroyAllocatorTest, ActiveAllocationsStrictMode) { - auto& rm = umpire::ResourceManager::getInstance(); + // Set strict mode + setenv("UMPIRE_STRICT_DESTRUCTION", "1", 1); - // Create a QuickPool + auto& rm = umpire::ResourceManager::getInstance(); auto pool = rm.makeAllocator("test_pool_strict", rm.getAllocator("HOST")); - - // Allocate memory void* ptr = pool.allocate(100); ASSERT_NE(nullptr, ptr); @@ -103,16 +102,18 @@ TEST(DestroyAllocatorTest, ActiveAllocationsStrictMode) // Clean up pool.deallocate(ptr); rm.destroyAllocator("test_pool_strict"); + + // Unset for other tests + unsetenv("UMPIRE_STRICT_DESTRUCTION"); } -#else + TEST(DestroyAllocatorTest, ActiveAllocationsNonStrictMode) { - auto& rm = umpire::ResourceManager::getInstance(); + // Ensure strict mode is off + unsetenv("UMPIRE_STRICT_DESTRUCTION"); - // Create a QuickPool + auto& rm = umpire::ResourceManager::getInstance(); auto pool = rm.makeAllocator("test_pool_nonstrict", rm.getAllocator("HOST")); - - // Allocate memory void* ptr = pool.allocate(100); ASSERT_NE(nullptr, ptr); @@ -122,7 +123,6 @@ TEST(DestroyAllocatorTest, ActiveAllocationsNonStrictMode) // Verify allocator is destroyed ASSERT_FALSE(rm.isAllocator("test_pool_nonstrict")); } -#endif TEST(DestroyAllocatorTest, FreeAllocationsOnDestroy) { @@ -171,15 +171,13 @@ TEST(DestroyAllocatorTest, DestroyAllocatorWithAliases) ASSERT_FALSE(rm.isAllocator("alias2")); } -#ifdef UMPIRE_ENABLE_STRICT_DESTROY TEST(DestroyAllocatorTest, ParentChildWarningStrictMode) { - auto& rm = umpire::ResourceManager::getInstance(); + // Set strict mode + setenv("UMPIRE_STRICT_DESTRUCTION", "1", 1); - // Create parent allocator + auto& rm = umpire::ResourceManager::getInstance(); auto parent = rm.makeAllocator("test_parent_strict", rm.getAllocator("HOST")); - - // Create child allocator using parent auto child = rm.makeAllocator("test_child_strict", parent); // Try to destroy parent - should throw error in strict mode @@ -188,16 +186,18 @@ TEST(DestroyAllocatorTest, ParentChildWarningStrictMode) // Clean up in correct order rm.destroyAllocator("test_child_strict"); rm.destroyAllocator("test_parent_strict"); + + // Unset for other tests + unsetenv("UMPIRE_STRICT_DESTRUCTION"); } -#else + TEST(DestroyAllocatorTest, ParentChildWarningNonStrictMode) { - auto& rm = umpire::ResourceManager::getInstance(); + // Ensure strict mode is off + unsetenv("UMPIRE_STRICT_DESTRUCTION"); - // Create parent allocator + auto& rm = umpire::ResourceManager::getInstance(); auto parent = rm.makeAllocator("test_parent_nonstrict", rm.getAllocator("HOST")); - - // Create child allocator using parent rm.makeAllocator("test_child_nonstrict", parent); // Destroy parent - should succeed with warning in non-strict mode @@ -206,7 +206,6 @@ TEST(DestroyAllocatorTest, ParentChildWarningNonStrictMode) // Clean up child rm.destroyAllocator("test_child_nonstrict"); } -#endif #if defined(UMPIRE_ENABLE_IPC_SHARED_MEMORY) || defined(UMPIRE_ENABLE_MPI3_SHARED_MEMORY) TEST(DestroyAllocatorTest, DestroySharedAllocator) From edee8b1539800677a48c71d08c3627d4b4543155 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 4 Mar 2026 16:48:12 -0800 Subject: [PATCH 3/9] Test fix --- src/umpire/ResourceManager.cpp | 19 +------- tests/integration/CMakeLists.txt | 17 +++++++ .../destroy_allocator_strict_mode_tests.cpp | 45 +++++++++++++++++ tests/integration/destroy_allocator_tests.cpp | 48 ------------------- 4 files changed, 64 insertions(+), 65 deletions(-) create mode 100644 tests/integration/destroy_allocator_strict_mode_tests.cpp diff --git a/src/umpire/ResourceManager.cpp b/src/umpire/ResourceManager.cpp index 0650cead9..1829e3aa7 100644 --- a/src/umpire/ResourceManager.cpp +++ b/src/umpire/ResourceManager.cpp @@ -328,14 +328,12 @@ void ResourceManager::removeAlias(const std::string& name, Allocator allocator) bool ResourceManager::isBuiltinAllocator(strategy::AllocationStrategy* strategy) { - // Check if it's in the memory resources map (builtin resources) for (const auto& entry : m_memory_resources) { if (entry.second == strategy) { return true; } } - // Check special internal allocators std::string name = strategy->getName(); if (name == "__umpire_internal_null" || name == "__umpire_internal_0_byte_pool") { return true; @@ -350,7 +348,6 @@ void ResourceManager::destroyAllocator(const std::string& name, bool free_alloca UMPIRE_LOG(Debug, "(name=\"" << name << "\", free_allocations=" << free_allocations << ")"); - // Find strategy by name auto it = m_allocators_by_name.find(name); if (it == m_allocators_by_name.end()) { UMPIRE_ERROR(runtime_error, fmt::format("Allocator \"{}\" not found", name)); @@ -359,13 +356,11 @@ void ResourceManager::destroyAllocator(const std::string& name, bool free_alloca strategy::AllocationStrategy* strategy = it->second; int id = strategy->getId(); - // Validate not builtin allocator if (isBuiltinAllocator(strategy)) { UMPIRE_ERROR(runtime_error, fmt::format("Cannot destroy builtin allocator \"{}\"", name)); } - // Check for active allocations if (isStrictDestructionMode()) { auto records = umpire::get_allocator_records(Allocator(strategy)); if (!records.empty() && !free_allocations) { @@ -379,10 +374,7 @@ void ResourceManager::destroyAllocator(const std::string& name, bool free_alloca << "Destroying anyway (non-strict mode)."); } - // Get records for potential cleanup - auto records = umpire::get_allocator_records(Allocator(strategy)); - // Check for child allocators (allocators using this as parent) if (isStrictDestructionMode()) { std::vector child_names; for (const auto& alloc : m_allocators) { @@ -408,15 +400,14 @@ void ResourceManager::destroyAllocator(const std::string& name, bool free_alloca << "Destroying anyway (non-strict mode)."); } - // Free allocations if requested - if (free_allocations && !records.empty()) { + if (free_allocations) { + auto records = umpire::get_allocator_records(Allocator(strategy)); UMPIRE_LOG(Debug, "Freeing " << records.size() << " allocations"); for (const auto& record : records) { strategy->deallocate_internal(record.ptr, record.size); } } - // Collect all names pointing to this strategy (handles aliases) std::vector names_to_remove; for (const auto& entry : m_allocators_by_name) { if (entry.second == strategy) { @@ -424,14 +415,12 @@ void ResourceManager::destroyAllocator(const std::string& name, bool free_alloca } } - // Remove from all data structures for (const auto& n : names_to_remove) { m_allocators_by_name.erase(n); } m_allocators_by_id.erase(id); - // Remove from memory resources if present for (auto it_mem = m_memory_resources.begin(); it_mem != m_memory_resources.end();) { if (it_mem->second == strategy) { it_mem = m_memory_resources.erase(it_mem); @@ -440,13 +429,11 @@ void ResourceManager::destroyAllocator(const std::string& name, bool free_alloca } } - // Remove from shared allocator names if present auto shared_it = std::find(m_shared_allocator_names.begin(), m_shared_allocator_names.end(), name); if (shared_it != m_shared_allocator_names.end()) { m_shared_allocator_names.erase(shared_it); } - // Remove from allocators list (destroys the unique_ptr) for (auto it_alloc = m_allocators.begin(); it_alloc != m_allocators.end(); ++it_alloc) { if (it_alloc->get() == strategy) { m_allocators.erase(it_alloc); @@ -454,7 +441,6 @@ void ResourceManager::destroyAllocator(const std::string& name, bool free_alloca } } - // Record event for replay umpire::event::record([&](auto& event) { event.name("destroy_allocator") .category(event::category::operation) @@ -476,7 +462,6 @@ void ResourceManager::destroyAllocator(int id, bool free_allocations) UMPIRE_ERROR(runtime_error, fmt::format("Allocator with id {} not found", id)); } - // Delegate to string version destroyAllocator(it->second->getName(), free_allocations); } diff --git a/tests/integration/CMakeLists.txt b/tests/integration/CMakeLists.txt index ffd9ed3ba..4937e25bc 100644 --- a/tests/integration/CMakeLists.txt +++ b/tests/integration/CMakeLists.txt @@ -257,6 +257,23 @@ blt_add_test( NAME destroy_allocator_tests COMMAND destroy_allocator_tests) +blt_add_executable( + NAME destroy_allocator_strict_mode_tests + SOURCES destroy_allocator_strict_mode_tests.cpp + DEPENDS_ON ${integration_tests_depends}) + +target_include_directories( + destroy_allocator_strict_mode_tests + PRIVATE + ${PROJECT_BINARY_DIR}/include) + +blt_add_test( + NAME destroy_allocator_strict_mode_tests + COMMAND destroy_allocator_strict_mode_tests) + +set_property(TEST destroy_allocator_strict_mode_tests + PROPERTY ENVIRONMENT "UMPIRE_STRICT_DESTRUCTION=1") + if (UMPIRE_ENABLE_IPC_SHARED_MEMORY AND UMPIRE_ENABLE_MPI) blt_add_executable( NAME get_communicator_tests diff --git a/tests/integration/destroy_allocator_strict_mode_tests.cpp b/tests/integration/destroy_allocator_strict_mode_tests.cpp new file mode 100644 index 000000000..5a5454630 --- /dev/null +++ b/tests/integration/destroy_allocator_strict_mode_tests.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2016-26, Lawrence Livermore National Security, LLC and Umpire +// project contributors. See the COPYRIGHT file for details. +// +// SPDX-License-Identifier: (MIT) +////////////////////////////////////////////////////////////////////////////// +#include "gtest/gtest.h" +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" +#include "umpire/Umpire.hpp" +#include "umpire/config.hpp" +#include "umpire/strategy/QuickPool.hpp" + +// These tests require UMPIRE_STRICT_DESTRUCTION=1 to be set in the environment +// before the process starts, since the mode is determined by a static variable. +// The CMakeLists.txt sets this environment variable when running this test suite. + +TEST(DestroyAllocatorStrictModeTest, ActiveAllocations) +{ + auto& rm = umpire::ResourceManager::getInstance(); + auto pool = rm.makeAllocator("test_pool_strict", rm.getAllocator("HOST")); + void* ptr = pool.allocate(100); + ASSERT_NE(nullptr, ptr); + + // Try to destroy with active allocations - should throw error in strict mode + ASSERT_THROW(rm.destroyAllocator("test_pool_strict", false), umpire::runtime_error); + + // Clean up + pool.deallocate(ptr); + rm.destroyAllocator("test_pool_strict"); +} + +TEST(DestroyAllocatorStrictModeTest, ParentChildWarning) +{ + auto& rm = umpire::ResourceManager::getInstance(); + auto parent = rm.makeAllocator("test_parent_strict", rm.getAllocator("HOST")); + auto child = rm.makeAllocator("test_child_strict", parent); + + // Try to destroy parent - should throw error in strict mode + ASSERT_THROW(rm.destroyAllocator("test_parent_strict"), umpire::runtime_error); + + // Clean up in correct order + rm.destroyAllocator("test_child_strict"); + rm.destroyAllocator("test_parent_strict"); +} diff --git a/tests/integration/destroy_allocator_tests.cpp b/tests/integration/destroy_allocator_tests.cpp index 4c9837c5e..7c1eeb4bc 100644 --- a/tests/integration/destroy_allocator_tests.cpp +++ b/tests/integration/destroy_allocator_tests.cpp @@ -10,7 +10,6 @@ #include "umpire/Umpire.hpp" #include "umpire/config.hpp" #include "umpire/strategy/QuickPool.hpp" -#include // for setenv/unsetenv TEST(DestroyAllocatorTest, DestroyBasicQuickPool) { @@ -86,32 +85,8 @@ TEST(DestroyAllocatorTest, ErrorOnInternalAllocators) ASSERT_THROW(rm.destroyAllocator("__umpire_internal_0_byte_pool"), umpire::runtime_error); } -TEST(DestroyAllocatorTest, ActiveAllocationsStrictMode) -{ - // Set strict mode - setenv("UMPIRE_STRICT_DESTRUCTION", "1", 1); - - auto& rm = umpire::ResourceManager::getInstance(); - auto pool = rm.makeAllocator("test_pool_strict", rm.getAllocator("HOST")); - void* ptr = pool.allocate(100); - ASSERT_NE(nullptr, ptr); - - // Try to destroy with active allocations - should throw error in strict mode - ASSERT_THROW(rm.destroyAllocator("test_pool_strict", false), umpire::runtime_error); - - // Clean up - pool.deallocate(ptr); - rm.destroyAllocator("test_pool_strict"); - - // Unset for other tests - unsetenv("UMPIRE_STRICT_DESTRUCTION"); -} - TEST(DestroyAllocatorTest, ActiveAllocationsNonStrictMode) { - // Ensure strict mode is off - unsetenv("UMPIRE_STRICT_DESTRUCTION"); - auto& rm = umpire::ResourceManager::getInstance(); auto pool = rm.makeAllocator("test_pool_nonstrict", rm.getAllocator("HOST")); void* ptr = pool.allocate(100); @@ -171,31 +146,8 @@ TEST(DestroyAllocatorTest, DestroyAllocatorWithAliases) ASSERT_FALSE(rm.isAllocator("alias2")); } -TEST(DestroyAllocatorTest, ParentChildWarningStrictMode) -{ - // Set strict mode - setenv("UMPIRE_STRICT_DESTRUCTION", "1", 1); - - auto& rm = umpire::ResourceManager::getInstance(); - auto parent = rm.makeAllocator("test_parent_strict", rm.getAllocator("HOST")); - auto child = rm.makeAllocator("test_child_strict", parent); - - // Try to destroy parent - should throw error in strict mode - ASSERT_THROW(rm.destroyAllocator("test_parent_strict"), umpire::runtime_error); - - // Clean up in correct order - rm.destroyAllocator("test_child_strict"); - rm.destroyAllocator("test_parent_strict"); - - // Unset for other tests - unsetenv("UMPIRE_STRICT_DESTRUCTION"); -} - TEST(DestroyAllocatorTest, ParentChildWarningNonStrictMode) { - // Ensure strict mode is off - unsetenv("UMPIRE_STRICT_DESTRUCTION"); - auto& rm = umpire::ResourceManager::getInstance(); auto parent = rm.makeAllocator("test_parent_nonstrict", rm.getAllocator("HOST")); rm.makeAllocator("test_child_nonstrict", parent); From 1a093420c1e6be43a1f1ebbd0b16ae9f42f70a93 Mon Sep 17 00:00:00 2001 From: Kristi Belcher Date: Wed, 11 Mar 2026 14:58:09 -0700 Subject: [PATCH 4/9] codex attempted fixes to c interface --- .../interface/c_fortran/wrapResourceManager.cpp | 4 ++-- .../interface/c_fortran/wrapResourceManager.h | 4 ++-- src/umpire/interface/c_fortran/wrapfumpire.f | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/umpire/interface/c_fortran/wrapResourceManager.cpp b/src/umpire/interface/c_fortran/wrapResourceManager.cpp index 5ca4a58ea..d3dd6d364 100644 --- a/src/umpire/interface/c_fortran/wrapResourceManager.cpp +++ b/src/umpire/interface/c_fortran/wrapResourceManager.cpp @@ -795,7 +795,7 @@ void umpire_resourcemanager_destroy_allocator_with_free_bufferify( * \brief Destroy an allocator by ID * */ -void umpire_resourcemanager_destroy_allocator( +void umpire_resourcemanager_destroy_allocator_by_id( umpire_resourcemanager * self, int id) { umpire::ResourceManager *SH_this = @@ -809,7 +809,7 @@ void umpire_resourcemanager_destroy_allocator( * \brief Destroy an allocator by ID * */ -void umpire_resourcemanager_destroy_allocator_with_free( +void umpire_resourcemanager_destroy_allocator_by_id_with_free( umpire_resourcemanager * self, int id, bool free_allocations) { umpire::ResourceManager *SH_this = diff --git a/src/umpire/interface/c_fortran/wrapResourceManager.h b/src/umpire/interface/c_fortran/wrapResourceManager.h index 1faee27bc..6cf57fc35 100644 --- a/src/umpire/interface/c_fortran/wrapResourceManager.h +++ b/src/umpire/interface/c_fortran/wrapResourceManager.h @@ -214,10 +214,10 @@ void umpire_resourcemanager_destroy_allocator_with_free_bufferify( umpire_resourcemanager * self, const char * name, int Lname, bool free_allocations); -void umpire_resourcemanager_destroy_allocator( +void umpire_resourcemanager_destroy_allocator_by_id( umpire_resourcemanager * self, int id); -void umpire_resourcemanager_destroy_allocator_with_free( +void umpire_resourcemanager_destroy_allocator_by_id_with_free( umpire_resourcemanager * self, int id, bool free_allocations); umpire_allocator * umpire_resourcemanager_get_allocator_for_ptr( diff --git a/src/umpire/interface/c_fortran/wrapfumpire.f b/src/umpire/interface/c_fortran/wrapfumpire.f index 084fdf0de..4e7147c07 100644 --- a/src/umpire/interface/c_fortran/wrapfumpire.f +++ b/src/umpire/interface/c_fortran/wrapfumpire.f @@ -1004,25 +1004,25 @@ subroutine c_resourcemanager_destroy_allocator_with_free_bufferify( & logical(C_BOOL), value, intent(IN) :: free_allocations end subroutine c_resourcemanager_destroy_allocator_with_free_bufferify - subroutine c_resourcemanager_destroy_allocator(self, id) & - bind(C, name="umpire_resourcemanager_destroy_allocator") + subroutine c_resourcemanager_destroy_allocator_by_id(self, id) & + bind(C, name="umpire_resourcemanager_destroy_allocator_by_id") use iso_c_binding, only : C_INT import :: umpire_SHROUD_resourcemanager_capsule implicit none type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self integer(C_INT), value, intent(IN) :: id - end subroutine c_resourcemanager_destroy_allocator + end subroutine c_resourcemanager_destroy_allocator_by_id - subroutine c_resourcemanager_destroy_allocator_with_free(self, & + subroutine c_resourcemanager_destroy_allocator_by_id_with_free(self, & id, free_allocations) & - bind(C, name="umpire_resourcemanager_destroy_allocator_with_free") + bind(C, name="umpire_resourcemanager_destroy_allocator_by_id_with_free") use iso_c_binding, only : C_BOOL, C_INT import :: umpire_SHROUD_resourcemanager_capsule implicit none type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self integer(C_INT), value, intent(IN) :: id logical(C_BOOL), value, intent(IN) :: free_allocations - end subroutine c_resourcemanager_destroy_allocator_with_free + end subroutine c_resourcemanager_destroy_allocator_by_id_with_free function c_resourcemanager_get_allocator_for_ptr(self, ptr, & SHT_crv) & @@ -3226,7 +3226,7 @@ subroutine resourcemanager_destroy_allocator(obj, id) class(UmpireResourceManager) :: obj integer(C_INT), value, intent(IN) :: id ! splicer begin class.ResourceManager.method.destroy_allocator - call c_resourcemanager_destroy_allocator(obj%cxxmem, id) + call c_resourcemanager_destroy_allocator_by_id(obj%cxxmem, id) ! splicer end class.ResourceManager.method.destroy_allocator end subroutine resourcemanager_destroy_allocator @@ -3243,7 +3243,7 @@ subroutine resourcemanager_destroy_allocator_with_free(obj, id, & ! splicer begin class.ResourceManager.method.destroy_allocator_with_free logical(C_BOOL) SH_free_allocations SH_free_allocations = free_allocations ! coerce to C_BOOL - call c_resourcemanager_destroy_allocator_with_free(obj%cxxmem, & + call c_resourcemanager_destroy_allocator_by_id_with_free(obj%cxxmem, & id, SH_free_allocations) ! splicer end class.ResourceManager.method.destroy_allocator_with_free end subroutine resourcemanager_destroy_allocator_with_free From 823c73eb71e1cc461fcf08894fc02e33c5767042 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 11 Mar 2026 22:05:01 +0000 Subject: [PATCH 5/9] Update C/FORTRAN interface --- .../interface/c_fortran/wrapResourceManager.cpp | 4 ++-- .../interface/c_fortran/wrapResourceManager.h | 4 ++-- src/umpire/interface/c_fortran/wrapfumpire.f | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/umpire/interface/c_fortran/wrapResourceManager.cpp b/src/umpire/interface/c_fortran/wrapResourceManager.cpp index d3dd6d364..5ca4a58ea 100644 --- a/src/umpire/interface/c_fortran/wrapResourceManager.cpp +++ b/src/umpire/interface/c_fortran/wrapResourceManager.cpp @@ -795,7 +795,7 @@ void umpire_resourcemanager_destroy_allocator_with_free_bufferify( * \brief Destroy an allocator by ID * */ -void umpire_resourcemanager_destroy_allocator_by_id( +void umpire_resourcemanager_destroy_allocator( umpire_resourcemanager * self, int id) { umpire::ResourceManager *SH_this = @@ -809,7 +809,7 @@ void umpire_resourcemanager_destroy_allocator_by_id( * \brief Destroy an allocator by ID * */ -void umpire_resourcemanager_destroy_allocator_by_id_with_free( +void umpire_resourcemanager_destroy_allocator_with_free( umpire_resourcemanager * self, int id, bool free_allocations) { umpire::ResourceManager *SH_this = diff --git a/src/umpire/interface/c_fortran/wrapResourceManager.h b/src/umpire/interface/c_fortran/wrapResourceManager.h index 6cf57fc35..1faee27bc 100644 --- a/src/umpire/interface/c_fortran/wrapResourceManager.h +++ b/src/umpire/interface/c_fortran/wrapResourceManager.h @@ -214,10 +214,10 @@ void umpire_resourcemanager_destroy_allocator_with_free_bufferify( umpire_resourcemanager * self, const char * name, int Lname, bool free_allocations); -void umpire_resourcemanager_destroy_allocator_by_id( +void umpire_resourcemanager_destroy_allocator( umpire_resourcemanager * self, int id); -void umpire_resourcemanager_destroy_allocator_by_id_with_free( +void umpire_resourcemanager_destroy_allocator_with_free( umpire_resourcemanager * self, int id, bool free_allocations); umpire_allocator * umpire_resourcemanager_get_allocator_for_ptr( diff --git a/src/umpire/interface/c_fortran/wrapfumpire.f b/src/umpire/interface/c_fortran/wrapfumpire.f index 4e7147c07..084fdf0de 100644 --- a/src/umpire/interface/c_fortran/wrapfumpire.f +++ b/src/umpire/interface/c_fortran/wrapfumpire.f @@ -1004,25 +1004,25 @@ subroutine c_resourcemanager_destroy_allocator_with_free_bufferify( & logical(C_BOOL), value, intent(IN) :: free_allocations end subroutine c_resourcemanager_destroy_allocator_with_free_bufferify - subroutine c_resourcemanager_destroy_allocator_by_id(self, id) & - bind(C, name="umpire_resourcemanager_destroy_allocator_by_id") + subroutine c_resourcemanager_destroy_allocator(self, id) & + bind(C, name="umpire_resourcemanager_destroy_allocator") use iso_c_binding, only : C_INT import :: umpire_SHROUD_resourcemanager_capsule implicit none type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self integer(C_INT), value, intent(IN) :: id - end subroutine c_resourcemanager_destroy_allocator_by_id + end subroutine c_resourcemanager_destroy_allocator - subroutine c_resourcemanager_destroy_allocator_by_id_with_free(self, & + subroutine c_resourcemanager_destroy_allocator_with_free(self, & id, free_allocations) & - bind(C, name="umpire_resourcemanager_destroy_allocator_by_id_with_free") + bind(C, name="umpire_resourcemanager_destroy_allocator_with_free") use iso_c_binding, only : C_BOOL, C_INT import :: umpire_SHROUD_resourcemanager_capsule implicit none type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self integer(C_INT), value, intent(IN) :: id logical(C_BOOL), value, intent(IN) :: free_allocations - end subroutine c_resourcemanager_destroy_allocator_by_id_with_free + end subroutine c_resourcemanager_destroy_allocator_with_free function c_resourcemanager_get_allocator_for_ptr(self, ptr, & SHT_crv) & @@ -3226,7 +3226,7 @@ subroutine resourcemanager_destroy_allocator(obj, id) class(UmpireResourceManager) :: obj integer(C_INT), value, intent(IN) :: id ! splicer begin class.ResourceManager.method.destroy_allocator - call c_resourcemanager_destroy_allocator_by_id(obj%cxxmem, id) + call c_resourcemanager_destroy_allocator(obj%cxxmem, id) ! splicer end class.ResourceManager.method.destroy_allocator end subroutine resourcemanager_destroy_allocator @@ -3243,7 +3243,7 @@ subroutine resourcemanager_destroy_allocator_with_free(obj, id, & ! splicer begin class.ResourceManager.method.destroy_allocator_with_free logical(C_BOOL) SH_free_allocations SH_free_allocations = free_allocations ! coerce to C_BOOL - call c_resourcemanager_destroy_allocator_by_id_with_free(obj%cxxmem, & + call c_resourcemanager_destroy_allocator_with_free(obj%cxxmem, & id, SH_free_allocations) ! splicer end class.ResourceManager.method.destroy_allocator_with_free end subroutine resourcemanager_destroy_allocator_with_free From ce5126332139c08d891fbc08a48f31b23b32c8a1 Mon Sep 17 00:00:00 2001 From: Kristi Belcher Date: Wed, 11 Mar 2026 15:18:12 -0700 Subject: [PATCH 6/9] Revert "codex attempted fixes to c interface" This reverts commit 1a093420c1e6be43a1f1ebbd0b16ae9f42f70a93. --- .../interface/c_fortran/wrapResourceManager.cpp | 4 ++-- .../interface/c_fortran/wrapResourceManager.h | 4 ++-- src/umpire/interface/c_fortran/wrapfumpire.f | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/umpire/interface/c_fortran/wrapResourceManager.cpp b/src/umpire/interface/c_fortran/wrapResourceManager.cpp index d3dd6d364..5ca4a58ea 100644 --- a/src/umpire/interface/c_fortran/wrapResourceManager.cpp +++ b/src/umpire/interface/c_fortran/wrapResourceManager.cpp @@ -795,7 +795,7 @@ void umpire_resourcemanager_destroy_allocator_with_free_bufferify( * \brief Destroy an allocator by ID * */ -void umpire_resourcemanager_destroy_allocator_by_id( +void umpire_resourcemanager_destroy_allocator( umpire_resourcemanager * self, int id) { umpire::ResourceManager *SH_this = @@ -809,7 +809,7 @@ void umpire_resourcemanager_destroy_allocator_by_id( * \brief Destroy an allocator by ID * */ -void umpire_resourcemanager_destroy_allocator_by_id_with_free( +void umpire_resourcemanager_destroy_allocator_with_free( umpire_resourcemanager * self, int id, bool free_allocations) { umpire::ResourceManager *SH_this = diff --git a/src/umpire/interface/c_fortran/wrapResourceManager.h b/src/umpire/interface/c_fortran/wrapResourceManager.h index 6cf57fc35..1faee27bc 100644 --- a/src/umpire/interface/c_fortran/wrapResourceManager.h +++ b/src/umpire/interface/c_fortran/wrapResourceManager.h @@ -214,10 +214,10 @@ void umpire_resourcemanager_destroy_allocator_with_free_bufferify( umpire_resourcemanager * self, const char * name, int Lname, bool free_allocations); -void umpire_resourcemanager_destroy_allocator_by_id( +void umpire_resourcemanager_destroy_allocator( umpire_resourcemanager * self, int id); -void umpire_resourcemanager_destroy_allocator_by_id_with_free( +void umpire_resourcemanager_destroy_allocator_with_free( umpire_resourcemanager * self, int id, bool free_allocations); umpire_allocator * umpire_resourcemanager_get_allocator_for_ptr( diff --git a/src/umpire/interface/c_fortran/wrapfumpire.f b/src/umpire/interface/c_fortran/wrapfumpire.f index 4e7147c07..084fdf0de 100644 --- a/src/umpire/interface/c_fortran/wrapfumpire.f +++ b/src/umpire/interface/c_fortran/wrapfumpire.f @@ -1004,25 +1004,25 @@ subroutine c_resourcemanager_destroy_allocator_with_free_bufferify( & logical(C_BOOL), value, intent(IN) :: free_allocations end subroutine c_resourcemanager_destroy_allocator_with_free_bufferify - subroutine c_resourcemanager_destroy_allocator_by_id(self, id) & - bind(C, name="umpire_resourcemanager_destroy_allocator_by_id") + subroutine c_resourcemanager_destroy_allocator(self, id) & + bind(C, name="umpire_resourcemanager_destroy_allocator") use iso_c_binding, only : C_INT import :: umpire_SHROUD_resourcemanager_capsule implicit none type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self integer(C_INT), value, intent(IN) :: id - end subroutine c_resourcemanager_destroy_allocator_by_id + end subroutine c_resourcemanager_destroy_allocator - subroutine c_resourcemanager_destroy_allocator_by_id_with_free(self, & + subroutine c_resourcemanager_destroy_allocator_with_free(self, & id, free_allocations) & - bind(C, name="umpire_resourcemanager_destroy_allocator_by_id_with_free") + bind(C, name="umpire_resourcemanager_destroy_allocator_with_free") use iso_c_binding, only : C_BOOL, C_INT import :: umpire_SHROUD_resourcemanager_capsule implicit none type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self integer(C_INT), value, intent(IN) :: id logical(C_BOOL), value, intent(IN) :: free_allocations - end subroutine c_resourcemanager_destroy_allocator_by_id_with_free + end subroutine c_resourcemanager_destroy_allocator_with_free function c_resourcemanager_get_allocator_for_ptr(self, ptr, & SHT_crv) & @@ -3226,7 +3226,7 @@ subroutine resourcemanager_destroy_allocator(obj, id) class(UmpireResourceManager) :: obj integer(C_INT), value, intent(IN) :: id ! splicer begin class.ResourceManager.method.destroy_allocator - call c_resourcemanager_destroy_allocator_by_id(obj%cxxmem, id) + call c_resourcemanager_destroy_allocator(obj%cxxmem, id) ! splicer end class.ResourceManager.method.destroy_allocator end subroutine resourcemanager_destroy_allocator @@ -3243,7 +3243,7 @@ subroutine resourcemanager_destroy_allocator_with_free(obj, id, & ! splicer begin class.ResourceManager.method.destroy_allocator_with_free logical(C_BOOL) SH_free_allocations SH_free_allocations = free_allocations ! coerce to C_BOOL - call c_resourcemanager_destroy_allocator_by_id_with_free(obj%cxxmem, & + call c_resourcemanager_destroy_allocator_with_free(obj%cxxmem, & id, SH_free_allocations) ! splicer end class.ResourceManager.method.destroy_allocator_with_free end subroutine resourcemanager_destroy_allocator_with_free From b0d94a98cb14ccca52a1bd1b62b82afbbe3546a6 Mon Sep 17 00:00:00 2001 From: Kristi Belcher Date: Wed, 11 Mar 2026 15:38:17 -0700 Subject: [PATCH 7/9] attempting to fix c-fortran interfact issue --- .../interface/c_fortran/wrapResourceManager.cpp | 12 ++++++------ src/umpire/interface/c_fortran/wrapResourceManager.h | 12 ++++++------ src/umpire/interface/c_fortran/wrapfumpire.f | 12 ++++++------ src/umpire/interface/umpire_shroud.yaml | 12 ++++-------- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/umpire/interface/c_fortran/wrapResourceManager.cpp b/src/umpire/interface/c_fortran/wrapResourceManager.cpp index 5ca4a58ea..88d0e4397 100644 --- a/src/umpire/interface/c_fortran/wrapResourceManager.cpp +++ b/src/umpire/interface/c_fortran/wrapResourceManager.cpp @@ -733,7 +733,7 @@ void umpire_resourcemanager_remove_alias_bufferify( * \brief Destroy an allocator by name * */ -void umpire_resourcemanager_destroy_allocator( +void umpire_resourcemanager_destroy_allocator_by_name( umpire_resourcemanager * self, const char * name) { umpire::ResourceManager *SH_this = @@ -748,7 +748,7 @@ void umpire_resourcemanager_destroy_allocator( * \brief Destroy an allocator by name * */ -void umpire_resourcemanager_destroy_allocator_bufferify( +void umpire_resourcemanager_destroy_allocator_by_name_bufferify( umpire_resourcemanager * self, const char * name, int Lname) { umpire::ResourceManager *SH_this = @@ -763,7 +763,7 @@ void umpire_resourcemanager_destroy_allocator_bufferify( * \brief Destroy an allocator by name * */ -void umpire_resourcemanager_destroy_allocator_with_free( +void umpire_resourcemanager_destroy_allocator_by_name_with_free( umpire_resourcemanager * self, const char * name, bool free_allocations) { @@ -779,7 +779,7 @@ void umpire_resourcemanager_destroy_allocator_with_free( * \brief Destroy an allocator by name * */ -void umpire_resourcemanager_destroy_allocator_with_free_bufferify( +void umpire_resourcemanager_destroy_allocator_by_name_with_free_bufferify( umpire_resourcemanager * self, const char * name, int Lname, bool free_allocations) { @@ -795,7 +795,7 @@ void umpire_resourcemanager_destroy_allocator_with_free_bufferify( * \brief Destroy an allocator by ID * */ -void umpire_resourcemanager_destroy_allocator( +void umpire_resourcemanager_destroy_allocator_by_id( umpire_resourcemanager * self, int id) { umpire::ResourceManager *SH_this = @@ -809,7 +809,7 @@ void umpire_resourcemanager_destroy_allocator( * \brief Destroy an allocator by ID * */ -void umpire_resourcemanager_destroy_allocator_with_free( +void umpire_resourcemanager_destroy_allocator_by_id_with_free( umpire_resourcemanager * self, int id, bool free_allocations) { umpire::ResourceManager *SH_this = diff --git a/src/umpire/interface/c_fortran/wrapResourceManager.h b/src/umpire/interface/c_fortran/wrapResourceManager.h index 1faee27bc..8b2584ac5 100644 --- a/src/umpire/interface/c_fortran/wrapResourceManager.h +++ b/src/umpire/interface/c_fortran/wrapResourceManager.h @@ -200,24 +200,24 @@ void umpire_resourcemanager_remove_alias_bufferify( umpire_resourcemanager * self, const char * name, int Lname, umpire_allocator allocator); -void umpire_resourcemanager_destroy_allocator( +void umpire_resourcemanager_destroy_allocator_by_name( umpire_resourcemanager * self, const char * name); -void umpire_resourcemanager_destroy_allocator_bufferify( +void umpire_resourcemanager_destroy_allocator_by_name_bufferify( umpire_resourcemanager * self, const char * name, int Lname); -void umpire_resourcemanager_destroy_allocator_with_free( +void umpire_resourcemanager_destroy_allocator_by_name_with_free( umpire_resourcemanager * self, const char * name, bool free_allocations); -void umpire_resourcemanager_destroy_allocator_with_free_bufferify( +void umpire_resourcemanager_destroy_allocator_by_name_with_free_bufferify( umpire_resourcemanager * self, const char * name, int Lname, bool free_allocations); -void umpire_resourcemanager_destroy_allocator( +void umpire_resourcemanager_destroy_allocator_by_id( umpire_resourcemanager * self, int id); -void umpire_resourcemanager_destroy_allocator_with_free( +void umpire_resourcemanager_destroy_allocator_by_id_with_free( umpire_resourcemanager * self, int id, bool free_allocations); umpire_allocator * umpire_resourcemanager_get_allocator_for_ptr( diff --git a/src/umpire/interface/c_fortran/wrapfumpire.f b/src/umpire/interface/c_fortran/wrapfumpire.f index 084fdf0de..cba5d6bc9 100644 --- a/src/umpire/interface/c_fortran/wrapfumpire.f +++ b/src/umpire/interface/c_fortran/wrapfumpire.f @@ -962,7 +962,7 @@ subroutine c_resourcemanager_remove_alias_bufferify(self, name, & end subroutine c_resourcemanager_remove_alias_bufferify subroutine c_resourcemanager_destroy_allocator(self, name) & - bind(C, name="umpire_resourcemanager_destroy_allocator") + bind(C, name="umpire_resourcemanager_destroy_allocator_by_name") use iso_c_binding, only : C_CHAR import :: umpire_SHROUD_resourcemanager_capsule implicit none @@ -972,7 +972,7 @@ end subroutine c_resourcemanager_destroy_allocator subroutine c_resourcemanager_destroy_allocator_bufferify(self, & name, Lname) & - bind(C, name="umpire_resourcemanager_destroy_allocator_bufferify") + bind(C, name="umpire_resourcemanager_destroy_allocator_by_name_bufferify") use iso_c_binding, only : C_CHAR, C_INT import :: umpire_SHROUD_resourcemanager_capsule implicit none @@ -983,7 +983,7 @@ end subroutine c_resourcemanager_destroy_allocator_bufferify subroutine c_resourcemanager_destroy_allocator_with_free(self, & name, free_allocations) & - bind(C, name="umpire_resourcemanager_destroy_allocator_with_free") + bind(C, name="umpire_resourcemanager_destroy_allocator_by_name_with_free") use iso_c_binding, only : C_BOOL, C_CHAR import :: umpire_SHROUD_resourcemanager_capsule implicit none @@ -994,7 +994,7 @@ end subroutine c_resourcemanager_destroy_allocator_with_free subroutine c_resourcemanager_destroy_allocator_with_free_bufferify( & self, name, Lname, free_allocations) & - bind(C, name="umpire_resourcemanager_destroy_allocator_with_free_bufferify") + bind(C, name="umpire_resourcemanager_destroy_allocator_by_name_with_free_bufferify") use iso_c_binding, only : C_BOOL, C_CHAR, C_INT import :: umpire_SHROUD_resourcemanager_capsule implicit none @@ -1005,7 +1005,7 @@ subroutine c_resourcemanager_destroy_allocator_with_free_bufferify( & end subroutine c_resourcemanager_destroy_allocator_with_free_bufferify subroutine c_resourcemanager_destroy_allocator(self, id) & - bind(C, name="umpire_resourcemanager_destroy_allocator") + bind(C, name="umpire_resourcemanager_destroy_allocator_by_id") use iso_c_binding, only : C_INT import :: umpire_SHROUD_resourcemanager_capsule implicit none @@ -1015,7 +1015,7 @@ end subroutine c_resourcemanager_destroy_allocator subroutine c_resourcemanager_destroy_allocator_with_free(self, & id, free_allocations) & - bind(C, name="umpire_resourcemanager_destroy_allocator_with_free") + bind(C, name="umpire_resourcemanager_destroy_allocator_by_id_with_free") use iso_c_binding, only : C_BOOL, C_INT import :: umpire_SHROUD_resourcemanager_capsule implicit none diff --git a/src/umpire/interface/umpire_shroud.yaml b/src/umpire/interface/umpire_shroud.yaml index e8e6563a2..602141467 100644 --- a/src/umpire/interface/umpire_shroud.yaml +++ b/src/umpire/interface/umpire_shroud.yaml @@ -267,20 +267,16 @@ declarations: - decl: void destroyAllocator(const std::string& name, bool free_allocations=false) doxygen: brief: Destroy an allocator by name - format: - function_suffix: _by_name default_arg_suffix: - - "" - - _with_free + - _by_name + - _by_name_with_free - decl: void destroyAllocator(int id, bool free_allocations=false) doxygen: brief: Destroy an allocator by ID - format: - function_suffix: _by_id default_arg_suffix: - - "" - - _with_free + - _by_id + - _by_id_with_free - decl: Allocator getAllocator(void* ptr) format: From e347526fb7048a7c31eab62d1270e68ba71c9437 Mon Sep 17 00:00:00 2001 From: Kristi Belcher Date: Wed, 11 Mar 2026 15:49:07 -0700 Subject: [PATCH 8/9] using unused var --- tests/integration/destroy_allocator_strict_mode_tests.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/integration/destroy_allocator_strict_mode_tests.cpp b/tests/integration/destroy_allocator_strict_mode_tests.cpp index 5a5454630..76ac98ec1 100644 --- a/tests/integration/destroy_allocator_strict_mode_tests.cpp +++ b/tests/integration/destroy_allocator_strict_mode_tests.cpp @@ -36,6 +36,8 @@ TEST(DestroyAllocatorStrictModeTest, ParentChildWarning) auto parent = rm.makeAllocator("test_parent_strict", rm.getAllocator("HOST")); auto child = rm.makeAllocator("test_child_strict", parent); + UMPIRE_USE_VAR(child); + // Try to destroy parent - should throw error in strict mode ASSERT_THROW(rm.destroyAllocator("test_parent_strict"), umpire::runtime_error); From cee4100f6985a18852b17490655ace99d3563d92 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 11 Mar 2026 22:51:03 +0000 Subject: [PATCH 9/9] Update C/FORTRAN interface --- .../c_fortran/wrapResourceManager.cpp | 24 ++--- src/umpire/interface/c_fortran/wrapfumpire.f | 89 ++++++++++--------- 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/src/umpire/interface/c_fortran/wrapResourceManager.cpp b/src/umpire/interface/c_fortran/wrapResourceManager.cpp index 88d0e4397..9b8f1254d 100644 --- a/src/umpire/interface/c_fortran/wrapResourceManager.cpp +++ b/src/umpire/interface/c_fortran/wrapResourceManager.cpp @@ -738,10 +738,10 @@ void umpire_resourcemanager_destroy_allocator_by_name( { umpire::ResourceManager *SH_this = static_cast(self->addr); - // splicer begin class.ResourceManager.method.destroy_allocator + // splicer begin class.ResourceManager.method.destroy_allocator_by_name const std::string SHCXX_name(name); SH_this->destroyAllocator(SHCXX_name); - // splicer end class.ResourceManager.method.destroy_allocator + // splicer end class.ResourceManager.method.destroy_allocator_by_name } /** @@ -753,10 +753,10 @@ void umpire_resourcemanager_destroy_allocator_by_name_bufferify( { umpire::ResourceManager *SH_this = static_cast(self->addr); - // splicer begin class.ResourceManager.method.destroy_allocator_bufferify + // splicer begin class.ResourceManager.method.destroy_allocator_by_name_bufferify const std::string SHCXX_name(name, Lname); SH_this->destroyAllocator(SHCXX_name); - // splicer end class.ResourceManager.method.destroy_allocator_bufferify + // splicer end class.ResourceManager.method.destroy_allocator_by_name_bufferify } /** @@ -769,10 +769,10 @@ void umpire_resourcemanager_destroy_allocator_by_name_with_free( { umpire::ResourceManager *SH_this = static_cast(self->addr); - // splicer begin class.ResourceManager.method.destroy_allocator_with_free + // splicer begin class.ResourceManager.method.destroy_allocator_by_name_with_free const std::string SHCXX_name(name); SH_this->destroyAllocator(SHCXX_name, free_allocations); - // splicer end class.ResourceManager.method.destroy_allocator_with_free + // splicer end class.ResourceManager.method.destroy_allocator_by_name_with_free } /** @@ -785,10 +785,10 @@ void umpire_resourcemanager_destroy_allocator_by_name_with_free_bufferify( { umpire::ResourceManager *SH_this = static_cast(self->addr); - // splicer begin class.ResourceManager.method.destroy_allocator_with_free_bufferify + // splicer begin class.ResourceManager.method.destroy_allocator_by_name_with_free_bufferify const std::string SHCXX_name(name, Lname); SH_this->destroyAllocator(SHCXX_name, free_allocations); - // splicer end class.ResourceManager.method.destroy_allocator_with_free_bufferify + // splicer end class.ResourceManager.method.destroy_allocator_by_name_with_free_bufferify } /** @@ -800,9 +800,9 @@ void umpire_resourcemanager_destroy_allocator_by_id( { umpire::ResourceManager *SH_this = static_cast(self->addr); - // splicer begin class.ResourceManager.method.destroy_allocator + // splicer begin class.ResourceManager.method.destroy_allocator_by_id SH_this->destroyAllocator(id); - // splicer end class.ResourceManager.method.destroy_allocator + // splicer end class.ResourceManager.method.destroy_allocator_by_id } /** @@ -814,9 +814,9 @@ void umpire_resourcemanager_destroy_allocator_by_id_with_free( { umpire::ResourceManager *SH_this = static_cast(self->addr); - // splicer begin class.ResourceManager.method.destroy_allocator_with_free + // splicer begin class.ResourceManager.method.destroy_allocator_by_id_with_free SH_this->destroyAllocator(id, free_allocations); - // splicer end class.ResourceManager.method.destroy_allocator_with_free + // splicer end class.ResourceManager.method.destroy_allocator_by_id_with_free } umpire_allocator * umpire_resourcemanager_get_allocator_for_ptr( diff --git a/src/umpire/interface/c_fortran/wrapfumpire.f b/src/umpire/interface/c_fortran/wrapfumpire.f index cba5d6bc9..1646a604f 100644 --- a/src/umpire/interface/c_fortran/wrapfumpire.f +++ b/src/umpire/interface/c_fortran/wrapfumpire.f @@ -244,10 +244,10 @@ module umpire_mod procedure :: make_allocator_prefetcher => resourcemanager_make_allocator_prefetcher procedure :: add_alias => resourcemanager_add_alias procedure :: remove_alias => resourcemanager_remove_alias - procedure :: destroy_allocator => resourcemanager_destroy_allocator - procedure :: destroy_allocator_with_free => resourcemanager_destroy_allocator_with_free - procedure :: destroy_allocator => resourcemanager_destroy_allocator - procedure :: destroy_allocator_with_free => resourcemanager_destroy_allocator_with_free + procedure :: destroy_allocator_by_name => resourcemanager_destroy_allocator_by_name + procedure :: destroy_allocator_by_name_with_free => resourcemanager_destroy_allocator_by_name_with_free + procedure :: destroy_allocator_by_id => resourcemanager_destroy_allocator_by_id + procedure :: destroy_allocator_by_id_with_free => resourcemanager_destroy_allocator_by_id_with_free procedure :: get_allocator_for_ptr => resourcemanager_get_allocator_for_ptr procedure :: is_allocator_name => resourcemanager_is_allocator_name procedure :: is_allocator_id => resourcemanager_is_allocator_id @@ -265,9 +265,9 @@ module umpire_mod procedure :: deregister_allocation => resourcemanager_deregister_allocation procedure :: associated => resourcemanager_associated generic :: copy => copy_all, copy_with_size - generic :: destroy_allocator => destroy_allocator, & - destroy_allocator_with_free, destroy_allocator, & - destroy_allocator_with_free + generic :: destroy_allocator => destroy_allocator_by_name, & + destroy_allocator_by_name_with_free, destroy_allocator_by_id & + , destroy_allocator_by_id_with_free generic :: get_allocator => get_allocator_by_name, & get_allocator_by_id, get_allocator_for_ptr generic :: is_allocator => is_allocator_name, is_allocator_id @@ -961,17 +961,18 @@ subroutine c_resourcemanager_remove_alias_bufferify(self, name, & type(umpire_SHROUD_allocator_capsule), intent(IN), value :: allocator end subroutine c_resourcemanager_remove_alias_bufferify - subroutine c_resourcemanager_destroy_allocator(self, name) & + subroutine c_resourcemanager_destroy_allocator_by_name(self, & + name) & bind(C, name="umpire_resourcemanager_destroy_allocator_by_name") use iso_c_binding, only : C_CHAR import :: umpire_SHROUD_resourcemanager_capsule implicit none type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self character(kind=C_CHAR), intent(IN) :: name(*) - end subroutine c_resourcemanager_destroy_allocator + end subroutine c_resourcemanager_destroy_allocator_by_name - subroutine c_resourcemanager_destroy_allocator_bufferify(self, & - name, Lname) & + subroutine c_resourcemanager_destroy_allocator_by_name_bufferify( & + self, name, Lname) & bind(C, name="umpire_resourcemanager_destroy_allocator_by_name_bufferify") use iso_c_binding, only : C_CHAR, C_INT import :: umpire_SHROUD_resourcemanager_capsule @@ -979,10 +980,10 @@ subroutine c_resourcemanager_destroy_allocator_bufferify(self, & type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self character(kind=C_CHAR), intent(IN) :: name(*) integer(C_INT), value, intent(IN) :: Lname - end subroutine c_resourcemanager_destroy_allocator_bufferify + end subroutine c_resourcemanager_destroy_allocator_by_name_bufferify - subroutine c_resourcemanager_destroy_allocator_with_free(self, & - name, free_allocations) & + subroutine c_resourcemanager_destroy_allocator_by_name_with_free( & + self, name, free_allocations) & bind(C, name="umpire_resourcemanager_destroy_allocator_by_name_with_free") use iso_c_binding, only : C_BOOL, C_CHAR import :: umpire_SHROUD_resourcemanager_capsule @@ -990,9 +991,9 @@ subroutine c_resourcemanager_destroy_allocator_with_free(self, & type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self character(kind=C_CHAR), intent(IN) :: name(*) logical(C_BOOL), value, intent(IN) :: free_allocations - end subroutine c_resourcemanager_destroy_allocator_with_free + end subroutine c_resourcemanager_destroy_allocator_by_name_with_free - subroutine c_resourcemanager_destroy_allocator_with_free_bufferify( & + subroutine c_resourcemanager_destroy_allocator_by_name_with_free_bufferify( & self, name, Lname, free_allocations) & bind(C, name="umpire_resourcemanager_destroy_allocator_by_name_with_free_bufferify") use iso_c_binding, only : C_BOOL, C_CHAR, C_INT @@ -1002,19 +1003,19 @@ subroutine c_resourcemanager_destroy_allocator_with_free_bufferify( & character(kind=C_CHAR), intent(IN) :: name(*) integer(C_INT), value, intent(IN) :: Lname logical(C_BOOL), value, intent(IN) :: free_allocations - end subroutine c_resourcemanager_destroy_allocator_with_free_bufferify + end subroutine c_resourcemanager_destroy_allocator_by_name_with_free_bufferify - subroutine c_resourcemanager_destroy_allocator(self, id) & + subroutine c_resourcemanager_destroy_allocator_by_id(self, id) & bind(C, name="umpire_resourcemanager_destroy_allocator_by_id") use iso_c_binding, only : C_INT import :: umpire_SHROUD_resourcemanager_capsule implicit none type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self integer(C_INT), value, intent(IN) :: id - end subroutine c_resourcemanager_destroy_allocator + end subroutine c_resourcemanager_destroy_allocator_by_id - subroutine c_resourcemanager_destroy_allocator_with_free(self, & - id, free_allocations) & + subroutine c_resourcemanager_destroy_allocator_by_id_with_free( & + self, id, free_allocations) & bind(C, name="umpire_resourcemanager_destroy_allocator_by_id_with_free") use iso_c_binding, only : C_BOOL, C_INT import :: umpire_SHROUD_resourcemanager_capsule @@ -1022,7 +1023,7 @@ subroutine c_resourcemanager_destroy_allocator_with_free(self, & type(umpire_SHROUD_resourcemanager_capsule), intent(IN) :: self integer(C_INT), value, intent(IN) :: id logical(C_BOOL), value, intent(IN) :: free_allocations - end subroutine c_resourcemanager_destroy_allocator_with_free + end subroutine c_resourcemanager_destroy_allocator_by_id_with_free function c_resourcemanager_get_allocator_for_ptr(self, ptr, & SHT_crv) & @@ -3189,64 +3190,64 @@ end subroutine resourcemanager_remove_alias !! \brief Destroy an allocator by name !! !< - subroutine resourcemanager_destroy_allocator(obj, name) + subroutine resourcemanager_destroy_allocator_by_name(obj, name) use iso_c_binding, only : C_INT class(UmpireResourceManager) :: obj character(len=*), intent(IN) :: name - ! splicer begin class.ResourceManager.method.destroy_allocator - call c_resourcemanager_destroy_allocator_bufferify(obj%cxxmem, & + ! splicer begin class.ResourceManager.method.destroy_allocator_by_name + call c_resourcemanager_destroy_allocator_by_name_bufferify(obj%cxxmem, & name, len_trim(name, kind=C_INT)) - ! splicer end class.ResourceManager.method.destroy_allocator - end subroutine resourcemanager_destroy_allocator + ! splicer end class.ResourceManager.method.destroy_allocator_by_name + end subroutine resourcemanager_destroy_allocator_by_name !> !! \brief Destroy an allocator by name !! !< - subroutine resourcemanager_destroy_allocator_with_free(obj, name, & - free_allocations) + subroutine resourcemanager_destroy_allocator_by_name_with_free(obj, & + name, free_allocations) use iso_c_binding, only : C_BOOL, C_INT class(UmpireResourceManager) :: obj character(len=*), intent(IN) :: name logical, value, intent(IN) :: free_allocations - ! splicer begin class.ResourceManager.method.destroy_allocator_with_free + ! splicer begin class.ResourceManager.method.destroy_allocator_by_name_with_free logical(C_BOOL) SH_free_allocations SH_free_allocations = free_allocations ! coerce to C_BOOL - call c_resourcemanager_destroy_allocator_with_free_bufferify(obj%cxxmem, & + call c_resourcemanager_destroy_allocator_by_name_with_free_bufferify(obj%cxxmem, & name, len_trim(name, kind=C_INT), SH_free_allocations) - ! splicer end class.ResourceManager.method.destroy_allocator_with_free - end subroutine resourcemanager_destroy_allocator_with_free + ! splicer end class.ResourceManager.method.destroy_allocator_by_name_with_free + end subroutine resourcemanager_destroy_allocator_by_name_with_free !> !! \brief Destroy an allocator by ID !! !< - subroutine resourcemanager_destroy_allocator(obj, id) + subroutine resourcemanager_destroy_allocator_by_id(obj, id) use iso_c_binding, only : C_INT class(UmpireResourceManager) :: obj integer(C_INT), value, intent(IN) :: id - ! splicer begin class.ResourceManager.method.destroy_allocator - call c_resourcemanager_destroy_allocator(obj%cxxmem, id) - ! splicer end class.ResourceManager.method.destroy_allocator - end subroutine resourcemanager_destroy_allocator + ! splicer begin class.ResourceManager.method.destroy_allocator_by_id + call c_resourcemanager_destroy_allocator_by_id(obj%cxxmem, id) + ! splicer end class.ResourceManager.method.destroy_allocator_by_id + end subroutine resourcemanager_destroy_allocator_by_id !> !! \brief Destroy an allocator by ID !! !< - subroutine resourcemanager_destroy_allocator_with_free(obj, id, & - free_allocations) + subroutine resourcemanager_destroy_allocator_by_id_with_free(obj, & + id, free_allocations) use iso_c_binding, only : C_BOOL, C_INT class(UmpireResourceManager) :: obj integer(C_INT), value, intent(IN) :: id logical, value, intent(IN) :: free_allocations - ! splicer begin class.ResourceManager.method.destroy_allocator_with_free + ! splicer begin class.ResourceManager.method.destroy_allocator_by_id_with_free logical(C_BOOL) SH_free_allocations SH_free_allocations = free_allocations ! coerce to C_BOOL - call c_resourcemanager_destroy_allocator_with_free(obj%cxxmem, & + call c_resourcemanager_destroy_allocator_by_id_with_free(obj%cxxmem, & id, SH_free_allocations) - ! splicer end class.ResourceManager.method.destroy_allocator_with_free - end subroutine resourcemanager_destroy_allocator_with_free + ! splicer end class.ResourceManager.method.destroy_allocator_by_id_with_free + end subroutine resourcemanager_destroy_allocator_by_id_with_free function resourcemanager_get_allocator_for_ptr(obj, ptr) & result(SHT_rv)