diff --git a/image_analysis/indexing/IndexerThreadPool.cpp b/image_analysis/indexing/IndexerThreadPool.cpp index ea4150583..d849acb01 100644 --- a/image_analysis/indexing/IndexerThreadPool.cpp +++ b/image_analysis/indexing/IndexerThreadPool.cpp @@ -59,6 +59,7 @@ FFTPlanReuse::~FFTPlanReuse() = default; FFTIndexerReuse::FFTIndexerReuse() = default; FFTIndexerReuse::~FFTIndexerReuse() = default; void KeepFFTIndexers(const IndexingSettings &, int) {} +void ReleaseKeptFFTIndexers() {} #endif #ifdef JFJOCH_USE_CUDA @@ -152,6 +153,18 @@ static std::unique_ptr MakeFFTIndexerGPU(const IndexingSettings &settin return std::make_unique(settings); } +void ReleaseKeptFFTIndexers() { + std::map>> idle; + { + std::lock_guard lock(kept_fft_indexers().m); + idle.swap(kept_fft_indexers().idle); + } + for (auto &[key, list] : idle) { + ScopedGpuPin pin(std::get<0>(key)); + list.clear(); + } +} + void KeepFFTIndexers(const IndexingSettings &settings, int count) { if (get_gpu_count() == 0) return; diff --git a/image_analysis/indexing/IndexerThreadPool.h b/image_analysis/indexing/IndexerThreadPool.h index 023f6971d..1a61be816 100644 --- a/image_analysis/indexing/IndexerThreadPool.h +++ b/image_analysis/indexing/IndexerThreadPool.h @@ -74,6 +74,9 @@ public: // destroyed). Nothing without a GPU. void KeepFFTIndexers(const IndexingSettings &settings, int count); +// Destroys the kept FFT indexers that no pool is using: a settings change leaves them keyed on the old settings. +void ReleaseKeptFFTIndexers(); + class IndexerThread { struct TaskInput { const DiffractionExperiment &experiment; diff --git a/receiver/JFJochReceiverService.cpp b/receiver/JFJochReceiverService.cpp index d3f8f0fac..868369b08 100644 --- a/receiver/JFJochReceiverService.cpp +++ b/receiver/JFJochReceiverService.cpp @@ -389,6 +389,7 @@ JFJochReceiverService &JFJochReceiverService::Indexing(const IndexingSettings &i logger.Info("Resetting indexing thread pool"); indexer_thread_pool.reset(); + ReleaseKeptFFTIndexers(); if (input.GetAlgorithm() != IndexingAlgorithmEnum::None) { logger.Info("Creating indexing thread pool..."); diff --git a/tests/CUDAMemHelpersTest.cpp b/tests/CUDAMemHelpersTest.cpp index 6f5cf08fd..a01e008e9 100644 --- a/tests/CUDAMemHelpersTest.cpp +++ b/tests/CUDAMemHelpersTest.cpp @@ -443,6 +443,10 @@ TEST_CASE("IndexerThreadPool_FFTIndexerKeptAcrossPools", "[CUDAMemHelpers]") { CHECK(r.lattice.size() == fresh.lattice.size()); } CHECK(pooled() == kept); + + // A settings change in the broker: the kept indexers go while the reuse scope lives on + ReleaseKeptFFTIndexers(); + CHECK(pooled() <= before + (uint64_t(16) << 20)); } CHECK(pooled() <= before + (uint64_t(16) << 20)); for (int d = 0; d < get_gpu_count(); d++) {