Model validation: budget counts only what is really held; fewer extra engines

On an 8.55 GB card (WDDM) the validation planned 6.81 GB of a 6.84 GB budget, but the card already
held more than the 20% headroom allowed, and the driver paged GPU memory to system RAM: every
rigid-body fit ran ~5x slower. Measured on 4nwv on a 16 GB card, at the start of model validation
the device held 1.1 GB beyond a fresh context, and on 6oel 2.7 GB:
  - the stream-ordered allocation pool's free-but-reserved memory, left by the image passes and the
    scaling's pooled buffers (1.07 GB on 4nwv, 2.1 GB on 6oel); the validation's engines are allocated
    outside the pool and cannot reuse it;
  - the image pass's FFT indexers (IndexerThreadPool), alive for the whole run (0.8 GB on 4nwv,
    0.5 GB on 6oel), although nothing indexes after the merge.
Both are now released: the validation trims the pool (cuda_trim_allocation_pool) before it plans,
and rugnux drops the indexer pool once the leftover-lattice census, its last user, has ended, before
the model is validated or searched for. What is left beside the validation is 0.06 GB over a fresh
context on both sets (streams, idle cuFFT plans).

Extra engines are now added only within half of the budget. They change no number and bought little
where measured (4nwv, 16 GB card: 13.6 s with one rigid-body engine, 13.1 s with two, 12.6 s with
five), so the card keeps headroom instead. On 16 GB 4nwv now plans 2 rigid-body and 2 scale-fit
engines, 6.56 GB (measured peak 7.3 GB with the context); on an 8.55 GB card one of each, 4.42 GB.

Reflection files, maps and models byte-identical to rc175 HEAD on 4nwv, 8tyy, 6oel and 3inp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 09:56:15 +02:00
co-authored by Claude Opus 5.5
parent 0d25d765cf
commit 3373106ae1
5 changed files with 31 additions and 8 deletions
+8 -3
View File
@@ -145,10 +145,15 @@ TEST_CASE("ModelValidation_GPUPlanOnCardSizes", "[ModelValidation]") {
last_rb = plan.rigid_body_engines;
last_scale = plan.scale_fit_engines;
}
// 8 GB, a 6.40 GB budget: 1.40 + 0.89 + 2 x 1.88 + 1 x 0.25 = 6.31 GB.
// 8 GB, a 6.40 GB budget: one engine of each, 4.42 GB, already over half of it, so no more engines.
const ModelValidationGPUPlan small = PlanModelValidationGPU(LargeCellNeed(8 * GB));
CHECK(small.rigid_body_engines == 2);
CHECK(small.rigid_body_engines == 1);
CHECK(small.scale_fit_engines == 1);
CHECK(small.bytes == size_t(4424500000));
// 16 GB, half of the 12.8 GB budget: a second rigid-body engine, 6.31 GB, and no second scale fit.
const ModelValidationGPUPlan mid = PlanModelValidationGPU(LargeCellNeed(16 * GB));
CHECK(mid.rigid_body_engines == 2);
CHECK(mid.scale_fit_engines == 1);
CHECK(!small.may_run_beside);
// 128 GB: every engine wanted, and room for a second validation of the same size.
const ModelValidationGPUPlan large = PlanModelValidationGPU(LargeCellNeed(128 * GB));
@@ -198,7 +203,7 @@ TEST_CASE("ModelValidation_GPUPlanBesideChangesOnlyEngines", "[ModelValidation]"
CHECK(full.structure_factors);
CHECK(full.rigid_body_engines == 0);
CHECK(!full.null_structure_factors);
CHECK(full.scale_fit_engines == 3);
CHECK(full.scale_fit_engines == 1);
}
TEST_CASE("ModelValidation_ReadsPdbAndMmcif", "[ModelValidation]") {