diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 842cc5285..26207ad75 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,6 +32,7 @@ variables: GIT_SUBMODULE_STRATEGY: recursive ALLOC_NAME: ${CI_PROJECT_NAME}_ci_${CI_PIPELINE_ID} BUILD_ROOT: ${CI_PROJECT_DIR} + PYTHON_ENVIRONMENT_PATH: ${CI_PROJECT_DIR}/.venv # Normally, stages are blocking in Gitlab. However, using the keyword "needs" we # can express dependencies between job that break the ordering of stages, in @@ -39,6 +40,7 @@ variables: # In practice q_*, l_* and b_* stages are independently run and start immediately. stages: + - environment - q_allocate_resources - q_build_and_test - q_release_resources @@ -46,6 +48,22 @@ stages: - b_build_and_test - multi_project +configure_python: + variables: + GIT_STRATEGY: none + tags: + - shell + - quartz + stage: environment + script: + - virtualenv -p /usr/tce/packages/python/python-3.8.2/bin/python ${PYTHON_ENVIRONMENT_PATH} + - . ${PYTHON_ENVIRONMENT_PATH}/bin/activate + - pip install lxml + cache: + key: venv + paths: + - ${PYTHON_ENVIRONMENT_PATH} + # This is the rules that drives the activation of "advanced" jobs. All advanced # jobs will share this through a template mechanism. .advanced_pipeline: diff --git a/.gitlab/quartz-templates.yml b/.gitlab/quartz-templates.yml index f5b6d2be2..58b6f98f3 100644 --- a/.gitlab/quartz-templates.yml +++ b/.gitlab/quartz-templates.yml @@ -30,7 +30,6 @@ allocate_resources (on quartz): stage: q_allocate_resources script: - salloc -N 1 -c 36 -p pdebug -t 20 --no-shell --job-name=${ALLOC_NAME} - needs: [] #### # In post-build phase, deallocate resources @@ -47,8 +46,13 @@ release_resources (on quartz): #### # Generic quartz build job, extending build script .build_and_test_on_quartz: - stage: q_build_and_test extends: [.build_toss_3_x86_64_ib_script, .on_quartz] + stage: q_build_and_test + cache: + key: venv + paths: + - ${PYTHON_ENVIRONMENT_PATH} + policy: pull .build_and_test_on_quartz_advanced: extends: [.build_and_test_on_quartz, .advanced_pipeline] diff --git a/CHANGELOG.md b/CHANGELOG.md index 164f65eb1..64cb98121 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,24 @@ Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to ### Fixed +## [v4.1.1] - 2020-10-05 + +### Added + +- Added primary pools test for allocation/deallocation overhead checking + +### Changed + +### Removed + +### Fixed + +- Fixed DynamicPoolMap deallocate to make coalesce check O(1) again. + +- Initialize m_default_allocator to HOST if not set explicitly. + +- Removed unreachable code that PGI compiler was giving compile warnings about. + ## [v4.1.0] - 2020-09-28 ### Added @@ -33,6 +51,8 @@ Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to - GitLab test script now converts CTest output to JUnit so that test results are visible in the native GitLab UI. +- Gitlab test scripts now caches python virtual environment. + ### Removed - Peer access is no longer automatically enabled for CUDA and HIP. @@ -54,6 +74,8 @@ Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to - Added cmake check to deterime if build subsystem capable of ASAN. +- CI script junit generation + ## [v4.0.1] - 2020-09-03 ### Fixed diff --git a/CMakeLists.txt b/CMakeLists.txt index 552e09338..b7feda158 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ cmake_policy(SET CMP0057 NEW) project(Umpire LANGUAGES CXX C - VERSION 4.1.0) + VERSION 4.1.1) set(UMPIRE_VERSION_RC "") diff --git a/Dockerfile b/Dockerfile index 668a01d72..13b4b141f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ COPY --chown=axom:axom . /home/axom/workspace WORKDIR /home/axom/workspace RUN mkdir build && cd build && cmake -DENABLE_DEVELOPER_DEFAULTS=On -DCMAKE_CXX_COMPILER=g++ .. RUN cd build && make -j 16 -RUN cd build && make test +RUN cd build && ctest -T test --output-on-failure FROM axom/compilers:gcc-6 AS gcc6 ENV GTEST_COLOR=1 @@ -12,7 +12,7 @@ COPY --chown=axom:axom . /home/axom/workspace WORKDIR /home/axom/workspace RUN mkdir build && cd build && cmake -DENABLE_DEVELOPER_DEFAULTS=On -DCMAKE_CXX_COMPILER=g++ .. RUN cd build && make -j 16 -RUN cd build && make test +RUN cd build && ctest -T test --output-on-failure FROM axom/compilers:gcc-7 AS gcc7 ENV GTEST_COLOR=1 @@ -20,7 +20,7 @@ COPY --chown=axom:axom . /home/axom/workspace WORKDIR /home/axom/workspace RUN mkdir build && cd build && cmake -DENABLE_DEVELOPER_DEFAULTS=On -DCMAKE_CXX_COMPILER=g++ .. RUN cd build && make -j 16 -RUN cd build && make test +RUN cd build && ctest -T test --output-on-failure FROM axom/compilers:gcc-8 AS gcc ENV GTEST_COLOR=1 @@ -28,7 +28,7 @@ COPY --chown=axom:axom . /home/axom/workspace WORKDIR /home/axom/workspace RUN mkdir build && cd build && cmake -DENABLE_C=On -DENABLE_COVERAGE=On -DCMAKE_BUILD_TYPE=Debug -DENABLE_DEVELOPER_DEFAULTS=On -DCMAKE_CXX_COMPILER=g++ .. RUN cd build && make -j 16 -RUN cd build && make test +RUN cd build && ctest -T test --output-on-failure FROM axom/compilers:clang-4 AS clang4 ENV GTEST_COLOR=1 @@ -36,7 +36,7 @@ COPY --chown=axom:axom . /home/axom/workspace WORKDIR /home/axom/workspace RUN mkdir build && cd build && cmake -DENABLE_DEVELOPER_DEFAULTS=On -DCMAKE_CXX_COMPILER=clang++ .. RUN cd build && make -j 16 -RUN cd build && make test +RUN cd build && ctest -T test --output-on-failure FROM axom/compilers:clang-5 AS clang5 ENV GTEST_COLOR=1 @@ -44,7 +44,7 @@ COPY --chown=axom:axom . /home/axom/workspace WORKDIR /home/axom/workspace RUN mkdir build && cd build && cmake -DENABLE_DEVELOPER_DEFAULTS=On -DCMAKE_CXX_COMPILER=clang++ .. RUN cd build && make -j 16 -RUN cd build && make test +RUN cd build && ctest -T test --output-on-failure FROM axom/compilers:clang-6 AS clang ENV GTEST_COLOR=1 @@ -52,7 +52,7 @@ COPY --chown=axom:axom . /home/axom/workspace WORKDIR /home/axom/workspace RUN mkdir build && cd build && cmake -DENABLE_DEVELOPER_DEFAULTS=On -DCMAKE_CXX_COMPILER=clang++ .. RUN cd build && make -j 16 -RUN cd build && make test +RUN cd build && ctest -T test --output-on-failure FROM axom/compilers:nvcc-10 AS nvcc ENV GTEST_COLOR=1 diff --git a/README.md b/README.md index 9a4dfcf8f..b7c79bb8c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Umpire Umpire v4.1.0 +# Umpire Umpire v4.1.1 [![Travis Build Status](https://travis-ci.com/LLNL/Umpire.svg?branch=develop)](https://travis-ci.com/LLNL/Umpire) [![Azure Pipelines Build Status](https://dev.azure.com/davidbeckingsale/Umpire/_apis/build/status/LLNL.Umpire?branchName=develop)](https://dev.azure.com/davidbeckingsale/Umpire/_build/latest?definitionId=1&branchName=develop) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index cb7e9b00d..cac7b108e 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,9 @@ +# v4.1.1 + +- Fixed DynamicPoolMap deallocate to make coalesce check O(1) again. + +- Initialize m_default_allocator to HOST if not set explicitly. + # v4.1.0 - QuickPool available via the C & Fortran APIs. diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index 0ea2ccfac..802377fc6 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -98,7 +98,7 @@ # The short X.Y version. version = u'4.1' # The full version, including alpha/beta/rc tags. -release = u'4.1.0' +release = u'4.1.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/sphinx/conf.py.in b/docs/sphinx/conf.py.in index 658c92b2d..cb15a839b 100644 --- a/docs/sphinx/conf.py.in +++ b/docs/sphinx/conf.py.in @@ -98,7 +98,7 @@ author = u'David Beckingsale' # The short X.Y version. version = u'4.1' # The full version, including alpha/beta/rc tags. -release = u'4.1.0' +release = u'4.1.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/scripts/gitlab/build_and_test.sh b/scripts/gitlab/build_and_test.sh index 91db2622a..f25e36c33 100755 --- a/scripts/gitlab/build_and_test.sh +++ b/scripts/gitlab/build_and_test.sh @@ -19,6 +19,9 @@ build_root=${BUILD_ROOT:-""} hostconfig=${HOST_CONFIG:-""} spec=${SPEC:-""} +sys_type=${SYS_TYPE:-""} +py_env_path=${PYTHON_ENVIRONMENT_PATH:-""} + # Dependencies if [[ "${option}" != "--build-only" && "${option}" != "--test-only" ]] then @@ -131,10 +134,16 @@ then cp Testing/*/Test.xml ${project_dir} # Convert CTest xml to JUnit (on toss3 only) - if [[ $SYS_TYPE == *toss3* ]]; then - ${project_dir}/scripts/gitlab/convert_to_junit.py \ - ${project_dir}/Test.xml \ - ${project_dir}/scripts/gitlab/junit.xslt > ${project_dir}/junit.xml + if [[ ${sys_type} == *toss_3* ]]; then + if [[ -n ${py_env_path} ]]; then + . ${py_env_path}/bin/activate + + python3 ${project_dir}/scripts/gitlab/convert_to_junit.py \ + ${project_dir}/Test.xml \ + ${project_dir}/scripts/gitlab/junit.xslt > ${project_dir}/junit.xml + else + echo "ERROR: needs python env with lxml, please set PYTHON_ENVIRONMENT_PATH" + fi fi if grep -q "Errors while running CTest" ./tests_output.txt diff --git a/scripts/make_release_tarball.sh b/scripts/make_release_tarball.sh index 37b11f390..5b43a4cba 100755 --- a/scripts/make_release_tarball.sh +++ b/scripts/make_release_tarball.sh @@ -7,7 +7,7 @@ ############################################################################## TAR_CMD=gtar -VERSION=4.1.0 +VERSION=4.1.1 git archive --prefix=umpire-${VERSION}/ -o umpire-${VERSION}.tar HEAD 2> /dev/null diff --git a/src/umpire/ResourceManager.cpp b/src/umpire/ResourceManager.cpp index 9a7f1cca0..f710d3f82 100644 --- a/src/umpire/ResourceManager.cpp +++ b/src/umpire/ResourceManager.cpp @@ -341,7 +341,6 @@ Allocator ResourceManager::makeResource(const std::string& name, MemoryResourceT if (name.find("::") == std::string::npos) { m_memory_resources[resource::string_to_resource(name)] = allocator.get(); } - m_default_allocator = allocator.get(); m_allocators_by_id[id] = allocator.get(); m_allocators.emplace_front(std::move(allocator)); @@ -414,8 +413,8 @@ Allocator ResourceManager::getDefaultAllocator() UMPIRE_LOG(Debug, ""); if (!m_default_allocator) { - return getAllocator("HOST"); - UMPIRE_ERROR("The default Allocator is not defined"); + UMPIRE_LOG(Debug, "Initializing m_default_allocator as HOST"); + m_default_allocator = getAllocator("HOST").getAllocationStrategy(); } return Allocator(m_default_allocator); @@ -623,7 +622,7 @@ void* ResourceManager::reallocate(void* current_ptr, std::size_t new_size) auto alloc_record = m_allocations.find(current_ptr); strategy = alloc_record->strategy; } else { - strategy = m_default_allocator; + strategy = getDefaultAllocator().getAllocationStrategy(); } void* new_ptr{reallocate_impl(current_ptr, new_size, Allocator(strategy))}; diff --git a/src/umpire/resource/MemoryResourceTypes.hpp b/src/umpire/resource/MemoryResourceTypes.hpp index e7ed1d1d7..e6ae024a2 100644 --- a/src/umpire/resource/MemoryResourceTypes.hpp +++ b/src/umpire/resource/MemoryResourceTypes.hpp @@ -40,9 +40,8 @@ inline std::string resource_to_string(MemoryResourceType type) return "DEVICE_CONST"; case File: return "FILE"; - default: + default: UMPIRE_ERROR("Unkown resource type: " << type); - return "UNKNOWN"; } } @@ -56,14 +55,13 @@ inline MemoryResourceType string_to_resource(const std::string& resource) else if (resource == "FILE") return MemoryResourceType::File; else { UMPIRE_ERROR("Unkown resource name: " << resource); - return MemoryResourceType::Unknown; } } inline int resource_to_device_id(const std::string& resource) { int device_id{0}; if (resource.find("::") != std::string::npos) { - device_id = std::stoi(resource.substr(resource.find("::") + 2)); + device_id = std::stoi(resource.substr(resource.find("::") + 2)); } return device_id; } diff --git a/src/umpire/strategy/DynamicPoolList.cpp b/src/umpire/strategy/DynamicPoolList.cpp index 70c146029..772e900ed 100644 --- a/src/umpire/strategy/DynamicPoolList.cpp +++ b/src/umpire/strategy/DynamicPoolList.cpp @@ -55,6 +55,13 @@ void DynamicPoolList::release() dpa.release(); } +std::size_t DynamicPoolList::getCurrentSize() const noexcept +{ + std::size_t CurrentSize = dpa.getCurrentSize(); + UMPIRE_LOG(Debug, "() returning " << CurrentSize); + return CurrentSize; +} + std::size_t DynamicPoolList::getActualSize() const noexcept { std::size_t ActualSize = dpa.getActualSize(); @@ -115,7 +122,7 @@ DynamicPoolList::CoalesceHeuristic DynamicPoolList::percent_releasable( [=](const DynamicPoolList& UMPIRE_UNUSED_ARG(pool)) { return false; }; } else if (percentage == 100) { return [=](const strategy::DynamicPoolList& pool) { - return (pool.getActualSize() == pool.getReleasableSize()); + return ( pool.getCurrentSize() == 0 ); }; } else { float f = (float)((float)percentage / (float)100.0); diff --git a/src/umpire/strategy/DynamicPoolList.hpp b/src/umpire/strategy/DynamicPoolList.hpp index 8c709d304..999fdbb4d 100644 --- a/src/umpire/strategy/DynamicPoolList.hpp +++ b/src/umpire/strategy/DynamicPoolList.hpp @@ -65,6 +65,7 @@ class DynamicPoolList : public AllocationStrategy { void release() override; std::size_t getActualSize() const noexcept override; + std::size_t getCurrentSize() const noexcept override; Platform getPlatform() noexcept override; diff --git a/src/umpire/strategy/DynamicPoolMap.cpp b/src/umpire/strategy/DynamicPoolMap.cpp index 2d0896745..6e764b47e 100644 --- a/src/umpire/strategy/DynamicPoolMap.cpp +++ b/src/umpire/strategy/DynamicPoolMap.cpp @@ -122,6 +122,8 @@ void* DynamicPoolMap::allocate(std::size_t bytes) alloc_bytes); } + m_current_bytes += bytes; + UMPIRE_UNPOISON_MEMORY_REGION(m_allocator, ptr, bytes); return ptr; } @@ -140,6 +142,8 @@ void DynamicPoolMap::deallocate(void* ptr) std::size_t whole_bytes; std::tie(bytes, is_head, whole_bytes) = *iter->second; + m_current_bytes -= bytes; + // Insert in free map insertFree(ptr, bytes, is_head, whole_bytes); @@ -177,6 +181,12 @@ std::size_t DynamicPoolMap::getActualSize() const noexcept return m_actual_bytes; } +std::size_t DynamicPoolMap::getCurrentSize() const noexcept +{ + UMPIRE_LOG(Debug, "() returning " << m_current_bytes); + return m_current_bytes; +} + std::size_t DynamicPoolMap::getFreeBlocks() const noexcept { return m_free_map.size(); @@ -473,7 +483,7 @@ DynamicPoolMap::CoalesceHeuristic DynamicPoolMap::percent_releasable( return [=](const DynamicPoolMap& UMPIRE_UNUSED_ARG(pool)) { return false; }; } else if (percentage == 100) { return [=](const strategy::DynamicPoolMap& pool) { - return (pool.getActualSize() == pool.getReleasableSize()); + return ( pool.getCurrentSize() == 0 ); }; } else { float f = (float)((float)percentage / (float)100.0); diff --git a/src/umpire/strategy/DynamicPoolMap.hpp b/src/umpire/strategy/DynamicPoolMap.hpp index c8f013c4d..04fd5780d 100644 --- a/src/umpire/strategy/DynamicPoolMap.hpp +++ b/src/umpire/strategy/DynamicPoolMap.hpp @@ -71,6 +71,7 @@ class DynamicPoolMap : public AllocationStrategy, void release() override; std::size_t getActualSize() const noexcept override; + std::size_t getCurrentSize() const noexcept override; Platform getPlatform() noexcept override; @@ -178,6 +179,7 @@ class DynamicPoolMap : public AllocationStrategy, const std::size_t m_next_minimum_pool_allocation_size; std::size_t m_actual_bytes{0}; + std::size_t m_current_bytes{0}; bool m_is_destructing{false}; }; diff --git a/src/umpire/strategy/DynamicSizePool.hpp b/src/umpire/strategy/DynamicSizePool.hpp index 885fb0d21..7193a6bb5 100644 --- a/src/umpire/strategy/DynamicSizePool.hpp +++ b/src/umpire/strategy/DynamicSizePool.hpp @@ -42,6 +42,8 @@ class DynamicSizePool : private umpire::strategy::mixins::AlignedAllocation { // Total size allocated (bytes) std::size_t m_actual_bytes; + std::size_t m_current_size{0}; + // Minimum size of initial allocation std::size_t m_first_minimum_pool_allocation_size; @@ -325,6 +327,7 @@ class DynamicSizePool : private umpire::strategy::mixins::AlignedAllocation { best->next = usedBlocks; usedBlocks = best; + m_current_size += rounded_bytes; UMPIRE_UNPOISON_MEMORY_REGION(m_allocator, usedBlocks->data, bytes); // Return the new pointer @@ -343,6 +346,7 @@ class DynamicSizePool : private umpire::strategy::mixins::AlignedAllocation { if (!curr) return; + m_current_size -= curr->size; UMPIRE_POISON_MEMORY_REGION(m_allocator, ptr, curr->size); UMPIRE_LOG(Debug, "Deallocating data held by " << curr); @@ -361,6 +365,11 @@ class DynamicSizePool : private umpire::strategy::mixins::AlignedAllocation { return m_actual_bytes; } + std::size_t getCurrentSize() const + { + return m_current_size; + } + std::size_t getBlocksInPool() const { std::size_t total_blocks{0}; diff --git a/tests/integration/CMakeLists.txt b/tests/integration/CMakeLists.txt index 2b67e41a8..621cf9fca 100644 --- a/tests/integration/CMakeLists.txt +++ b/tests/integration/CMakeLists.txt @@ -81,6 +81,20 @@ blt_add_test( NAME operation_tests COMMAND operation_tests) +blt_add_executable( + NAME reallocate_tests + SOURCES reallocate_tests.cpp + DEPENDS_ON ${integration_tests_depends}) + +target_include_directories( + reallocate_tests + PRIVATE + ${PROJECT_BINARY_DIR}/include) + +blt_add_test( + NAME reallocate_tests + COMMAND reallocate_tests) + blt_add_executable( NAME free_functions_integration_tests SOURCES free_functions_integration_tests.cpp diff --git a/tests/integration/primary_pool_tests.cpp b/tests/integration/primary_pool_tests.cpp index 2b29a138b..03577bf72 100644 --- a/tests/integration/primary_pool_tests.cpp +++ b/tests/integration/primary_pool_tests.cpp @@ -4,6 +4,11 @@ // // SPDX-License-Identifier: (MIT) ////////////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include #include #include #include @@ -52,8 +57,11 @@ using ResourceTypes = camp::list; using PoolTypes = - camp::list; + camp::list< + umpire::strategy::DynamicPoolList + , umpire::strategy::DynamicPoolMap + , umpire::strategy::QuickPool + >; using TestTypes = camp::cartesian_product; using PoolTestTypes = Test::Types; @@ -159,15 +167,18 @@ TYPED_TEST(PrimaryPoolTest, BlocksStatistic) this->m_min_pool_growth_size / 8);); } - if (std::is_same::value) { - dynamic_pool->coalesce(); - } ASSERT_EQ(dynamic_pool->getBlocksInPool(), 5); // 3 BLocks (1 Free, 2 allocated) for (int i{3}; i >= 2; --i) { ASSERT_NO_THROW(this->m_allocator->deallocate(allocs[i]);); } + + // + // The DynamicPoolMap does not recombine blocks dynamically, so we have + // to (carefully) coalesce them here to have our total block count match + // with the other pools. + // if (std::is_same::value) { dynamic_pool->coalesce(); } @@ -177,9 +188,6 @@ TYPED_TEST(PrimaryPoolTest, BlocksStatistic) for (int i{1}; i >= 0; --i) { ASSERT_NO_THROW(this->m_allocator->deallocate(allocs[i]);); } - if (std::is_same::value) { - dynamic_pool->coalesce(); - } ASSERT_EQ(dynamic_pool->getBlocksInPool(), 1); dynamic_pool->release(); @@ -563,3 +571,108 @@ TYPED_TEST(PrimaryPoolTest, heuristic_75_percent) ASSERT_NO_THROW({ alloc.deallocate(a[0]); }); // 100% releasable ASSERT_EQ(dynamic_pool->getBlocksInPool(), 1); // Collapse happened } + +template +class PrimaryPoolTimingsTest : public ::testing::Test { + public: + using Pool = typename camp::at>::type; + using ResourceType = typename camp::at>::type; + + void SetUp() override + { + m_resource_name = std::string(tag_to_string::value); + m_allocator = build_allocator("pool_", 100); + m_allocator_no_coalesce = build_allocator("no_coalesce_pool", 0); + } + + void TearDown() override + { + delete m_allocator; + delete m_allocator_no_coalesce; + } + + // + // Returns the test duration in milliseconds + // + void run_test(umpire::Allocator* alloc, int64_t& duration) + { + std::random_device rd; + std::mt19937 g{rd()}; + + auto start = std::chrono::steady_clock::now(); + + for (std::size_t i{0}; i < m_max_allocs; ++i) + ASSERT_NO_THROW( m_allocations[i] = alloc->allocate(1); ); + + std::shuffle( m_allocations.begin(), m_allocations.end(), g ); + + for (auto a : m_allocations ) + ASSERT_NO_THROW( alloc->deallocate(a); ); + + auto end = std::chrono::steady_clock::now(); + + duration = std::chrono::duration_cast(end - start).count(); + } + + umpire::Allocator* m_allocator; + umpire::Allocator* m_allocator_no_coalesce; + +private: + const std::size_t m_max_allocs{20000}; + std::vector m_allocations{m_max_allocs}; + std::string m_resource_name; + + template + umpire::Allocator* build_allocator(std::string name, int percentage) + { + static int unique_counter{0}; + const std::size_t initial_pool_size{512 * 1024 * 1024}; + const std::size_t min_pool_growth_size{1 * 1024 * 1024}; + const std::size_t alignment{16}; + const std::string pool_name{ name + + std::string{tag_to_string::value} + + std::string{"_"} + + std::string{m_resource_name} + std::string{"_"} + + std::to_string(unique_counter++)}; + + auto& rm = umpire::ResourceManager::getInstance(); + return new umpire::Allocator( + rm.makeAllocator( + pool_name + , rm.getAllocator(m_resource_name) + , initial_pool_size + , min_pool_growth_size + , alignment + , Pool::percent_releasable(percentage) + ) + ); + } +}; + +TYPED_TEST_SUITE(PrimaryPoolTimingsTest, PoolTestTypes, ); + +TYPED_TEST(PrimaryPoolTimingsTest, TestCoalesceHeuristicTiming) +{ + // + // Make sure that the time taken to run with the percent_releaseable(100) + // heuristic is close to the same as the time taken to run + // with the percent_releaseable(0) heuristic + // + int64_t ms_h_100{0}; + int64_t ms_h_0{0}; + + this->run_test(this->m_allocator, ms_h_100); + this->run_test(this->m_allocator_no_coalesce, ms_h_0); + + int64_t delta{ std::abs(ms_h_100 - ms_h_0) }; + + const int64_t max_delta{ std::max((ms_h_100/4), INT64_C(25)) }; + + if (delta >= max_delta) { + std::cerr << "Difference between heuristic durations exceed maximum of: " + << max_delta << std::endl + << "Heuristic(100) Duration: " << ms_h_100 + << ", Heuristic(0) Duration: " << ms_h_0 << std::endl; + } + ASSERT_LT(delta, max_delta); +} diff --git a/tests/integration/reallocate_tests.cpp b/tests/integration/reallocate_tests.cpp new file mode 100644 index 000000000..d12391a92 --- /dev/null +++ b/tests/integration/reallocate_tests.cpp @@ -0,0 +1,20 @@ +#include "umpire/ResourceManager.hpp" + +#include "gtest/gtest.h" + +// Needs to be in separate file so that resources are not initialized prior to +// reallocate call +TEST(Reallocate, Nullptr) +{ + auto& rm = umpire::ResourceManager::getInstance(); + constexpr std::size_t size = 1024; + + void* ptr{nullptr}; + EXPECT_NO_THROW({ + ptr = rm.reallocate(ptr, size); + }); + + ASSERT_NE(nullptr, ptr); + + rm.deallocate(ptr); +}