Refinement: trial slots counted with their scale pool and both restraint sets; on the CPU no more than -N
GPU: a slot was packed onto a card by its engine's bytes alone. The per-slot estimate now adds the slot's ModelScaleGPUPool with the robust fit's buffers (ModelScaleGPUPool::DeviceBytes(n, 1, true)), and RefinementGPUEngine::DeviceBytes counts the two restraint sets SetRestraints() holds, not one. The 80%-of-card budget is unchanged, so where these do not fit fewer slots are packed instead of an allocation failing inside a running trial. CPU: OwnSlotDevices made a slot per wanted trial whatever the thread count, so -N 1 ran six trial threads with six models, topologies and engines in memory. The main slot and those beside it are now at most -N. Side by side equals sequential, so no result changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu (cherry picked from commit 3c04c01158266c267f8e5ffaaaa98d6d8fd2a747)
This commit is contained in:
1 parent
ac58921445
commit
257bf2fe2b
2 files changed
+13
-9
No files matched your search
@@ -1013,29 +1013,32 @@ std::unique_ptr<OwnSlot> MakeOwnSlot(const gemmi::Structure &before_topology, co
|
||||
}
|
||||
|
||||
// The devices of the slots beside the main one, `wanted` of them at most: the GPUs in turn from the main
|
||||
// engine's, each taking engines while they fit in its budget. -1 for each one on the CPU.
|
||||
// engine's, each taking engines while they fit in its budget. -1 for each one on the CPU, where the main one and
|
||||
// those beside it are no more than the threads.
|
||||
std::vector<int> OwnSlotDevices(const Context &main, int wanted, const RefinementSettings &settings) {
|
||||
#ifdef JFJOCH_USE_CUDA
|
||||
if (main.engine->OnGPU()) {
|
||||
const int n = get_gpu_count();
|
||||
// a slot's engine and its scale pool, the robust fit's buffers included
|
||||
const size_t slot_bytes = main.engine_bytes + ModelScaleGPUPool::DeviceBytes(main.refl.Size(), 1, true);
|
||||
std::vector<size_t> used(n, 0);
|
||||
used[main.device] = main.engine_bytes;
|
||||
used[main.device] = slot_bytes;
|
||||
std::vector<int> devices;
|
||||
for (int k = 1; k <= wanted; k++) {
|
||||
const int d = (main.device + k) % n;
|
||||
const size_t usable = get_gpu_total_memory(d) / 5 * 4;
|
||||
const size_t budget = usable > settings.gpu_resident_bytes ? usable - settings.gpu_resident_bytes : 0;
|
||||
if (used[d] + main.engine_bytes <= budget) {
|
||||
used[d] += main.engine_bytes;
|
||||
if (used[d] + slot_bytes <= budget) {
|
||||
used[d] += slot_bytes;
|
||||
devices.push_back(d);
|
||||
}
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
#else
|
||||
(void) settings;
|
||||
#endif
|
||||
return std::vector<int>(std::max(wanted, 0), -1);
|
||||
// on the CPU, no more trials at once than threads: each slot is a model, a topology and an engine of its own
|
||||
const int beside = std::min(wanted, static_cast<int>(settings.nthreads) - 1);
|
||||
return std::vector<int>(std::max(beside, 0), -1);
|
||||
}
|
||||
|
||||
// One weight trial: `cycles` macro-cycles from pos0 and b0, of the positions at X-ray weight w and, where adp_w is
|
||||
|
||||
Reference in new issue
Block a user