From ee8c95de1c8b3d80692f8e13d898bd87a80f592d Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Sun, 11 Oct 2026 14:25:56 +0200 Subject: [PATCH] CUDAMemHelpers test: the FFT indexer wait case trims the allocation pool after its pools The pools' indexers return their memory to the allocation pool when destroyed; without a trim the next GPU test in the same process (AdaptiveSpotFinderGPU_RunToRunReproducible) found the card taken and failed with out of memory. Co-Authored-By: Claude Opus 5.5 (1M context) --- tests/CUDAMemHelpersTest.cpp | 61 +++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/tests/CUDAMemHelpersTest.cpp b/tests/CUDAMemHelpersTest.cpp index 8c08d74f0..e095333a7 100644 --- a/tests/CUDAMemHelpersTest.cpp +++ b/tests/CUDAMemHelpersTest.cpp @@ -154,37 +154,42 @@ TEST_CASE("IndexerThreadPool_FFTIndexerWaitsForGPUWorkBeside", "[CUDAMemHelpers] } } }; - IndexerThreadPool probe(settings, IndexerConstruction::OnFirstUse, /*beside=*/true); - IndexerThreadPool pool(settings, IndexerConstruction::OnFirstUse); + // The pools' indexers go back to the allocation pool when they are destroyed; trim it after them, so + // the next test finds the card free. + { + IndexerThreadPool probe(settings, IndexerConstruction::OnFirstUse, /*beside=*/true); + IndexerThreadPool pool(settings, IndexerConstruction::OnFirstUse); - fill(); - { - GPUWorkBeside work; - CHECK(probe.Run(x, recip).error != nullptr); - } - { - std::optional image_pass(std::in_place); - std::thread ends([&] { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - held.reset(); - image_pass.reset(); - }); - GPUWorkBeside work; - CHECK(probe.Run(x, recip).error == nullptr); - ends.join(); - } + fill(); + { + GPUWorkBeside work; + CHECK(probe.Run(x, recip).error != nullptr); + } + { + std::optional image_pass(std::in_place); + std::thread ends([&] { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + held.reset(); + image_pass.reset(); + }); + GPUWorkBeside work; + CHECK(probe.Run(x, recip).error == nullptr); + ends.join(); + } - fill(); - { - std::optional work(std::in_place); - std::thread ends([&] { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - held.reset(); - work.reset(); - }); - CHECK(pool.Run(x, recip).error == nullptr); - ends.join(); + fill(); + { + std::optional work(std::in_place); + std::thread ends([&] { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + held.reset(); + work.reset(); + }); + CHECK(pool.Run(x, recip).error == nullptr); + ends.join(); + } } + cuda_trim_allocation_pool(); } #endif