Refinement: the weight trials' own slots made while the placement runs
Bitwise. MakeOwnSlot copies the model as it was before the topology and reads only what the placement does not change (cell, reflections, the engine's kind, the B ceiling), so the slots are now built on their threads right after the start score, beside the rigid-body and group-B placement, and joined where they were built before (also where the placement throws). The "slots" stage goes from 0.23 s to 0 on 9yl4; the placement is not slowed (0.59 -> 0.60 s). Refined CIF md5 unchanged on 5reo, 5f6m, 9yl4, 7d98, 5f6m MD start (GPU) and 6o2h (CPU); side by side = one at a time. Wall: 5reo 1.46-1.53 -> 1.54, 5f6m 2.26 -> 2.21, 9yl4 7.03 -> 6.83, 7d98 3.65 -> 3.56, 5f6m MD start 4.20 -> 4.15 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu (cherry picked from commit 0752a921a4293d4213894e3242c4ef36d8ce2a05)
This commit is contained in:
1 parent
1f8b5b1986
commit
f34d2f4cca
1 file changed
+31
-21
@@ -1272,6 +1272,35 @@ RefinementResult RefineModel(const gemmi::Structure &placed, const std::vector<M
|
||||
return result;
|
||||
}
|
||||
|
||||
// The trials run side by side, as many at a time as the longest set of them has and the cards take engines:
|
||||
// on the main model and engine, and on copies with engines of their own; each with a share of the threads. The
|
||||
// copies are made while the placement runs: they start from the model as it was before the topology was made
|
||||
// and take nothing from the main context that the placement changes.
|
||||
int wanted = static_cast<int>(std::max({settings.weight_ladder.size() * settings.adp_ladder.size(),
|
||||
settings.final_ladder.size(), size_t{3}}));
|
||||
if (settings.max_trials_at_once > 0)
|
||||
wanted = std::min(wanted, static_cast<int>(settings.max_trials_at_once));
|
||||
const std::vector<int> devices = settings.restrained ? OwnSlotDevices(ctx, wanted - 1, settings) : std::vector<int>();
|
||||
const size_t slot_threads = std::max<size_t>(1, settings.nthreads / (devices.size() + 1));
|
||||
std::vector<std::unique_ptr<OwnSlot>> own(devices.size());
|
||||
std::vector<std::thread> slot_builders;
|
||||
// joined before the slots are taken, or here where the placement throws
|
||||
struct JoinAll {
|
||||
std::vector<std::thread> &threads;
|
||||
~JoinAll() {
|
||||
for (std::thread &t : threads)
|
||||
if (t.joinable())
|
||||
t.join();
|
||||
}
|
||||
} join_slot_builders{slot_builders};
|
||||
for (size_t k = 0; k < devices.size(); k++)
|
||||
slot_builders.emplace_back([&, k]() {
|
||||
#ifdef JFJOCH_USE_CUDA
|
||||
const ScopedGpuPin pin(devices[k] >= 0 ? devices[k] : get_gpu());
|
||||
#endif
|
||||
own[k] = MakeOwnSlot(before_topology, ctx, devices[k], slot_threads, settings);
|
||||
});
|
||||
|
||||
RefinePlacement(ctx, settings.group_b, result);
|
||||
if (restrained)
|
||||
PlaceRiders(ctx, topo);
|
||||
@@ -1317,28 +1346,9 @@ RefinementResult RefineModel(const gemmi::Structure &placed, const std::vector<M
|
||||
const std::vector<gemmi::Position> pos0 = ctx.Positions();
|
||||
const std::vector<double> b0 = ctx.B();
|
||||
|
||||
// The trials run side by side, as many at a time as the longest set of them has and the cards take engines:
|
||||
// on the main model and engine, and on copies with engines of their own; each with a share of the threads.
|
||||
std::optional<RefinementStage> slot_stage("slots");
|
||||
int wanted = static_cast<int>(std::max({settings.weight_ladder.size() * settings.adp_ladder.size(),
|
||||
settings.final_ladder.size(), size_t{3}}));
|
||||
if (settings.max_trials_at_once > 0)
|
||||
wanted = std::min(wanted, static_cast<int>(settings.max_trials_at_once));
|
||||
const std::vector<int> devices = OwnSlotDevices(ctx, wanted - 1, settings);
|
||||
const size_t slot_threads = std::max<size_t>(1, settings.nthreads / (devices.size() + 1));
|
||||
std::vector<std::unique_ptr<OwnSlot>> own(devices.size());
|
||||
{
|
||||
std::vector<std::thread> threads;
|
||||
for (size_t k = 0; k < devices.size(); k++)
|
||||
threads.emplace_back([&, k]() {
|
||||
#ifdef JFJOCH_USE_CUDA
|
||||
const ScopedGpuPin pin(devices[k] >= 0 ? devices[k] : get_gpu());
|
||||
#endif
|
||||
own[k] = MakeOwnSlot(before_topology, ctx, devices[k], slot_threads, settings);
|
||||
});
|
||||
for (std::thread &t : threads)
|
||||
t.join();
|
||||
}
|
||||
for (std::thread &t : slot_builders)
|
||||
t.join();
|
||||
const size_t main_threads = ctx.nthreads;
|
||||
ctx.nthreads = slot_threads;
|
||||
std::vector<TrialSlot> trial_slots{{&ctx, &topo}};
|
||||
|
||||
Reference in new issue
Block a user