JFJochReceiverService::Indexing: kept FFT indexers of the old settings are released
Since0df766328the broker keeps an FFTIndexerReuse for its whole life, so the broker's own indexing pool (Lite and FPGA receivers) hands its GPU FFT indexers back to the reuse cache instead of freeing them. The cache is keyed on the FFT settings and never shrank: every change of the indexing settings through the API parked another 0.6-0.9 GB per worker on the card, until a pool build ran out of GPU memory. (Before0df766328the same happened from the first live rotation run on.) The service now releases the kept indexers when it rebuilds the pool; rugnux live keeps new ones at its next run. (ported from rc184-28f47fb756) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK
This commit is contained in:
1 parent
7e84ad094b
commit
69ce5f3edd
4 files changed
+21
No files matched your search
@@ -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<Indexer> MakeFFTIndexerGPU(const IndexingSettings &settin
|
||||
return std::make_unique<FFTIndexerGPU>(settings);
|
||||
}
|
||||
|
||||
void ReleaseKeptFFTIndexers() {
|
||||
std::map<FFTIndexerKey, std::vector<std::unique_ptr<Indexer>>> 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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...");
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
Reference in new issue
Block a user