rugnux: joint sweeps release the members' fulls, and the joint input holds no spare capacity
The members' fulls were "released" with `= {}`, an assignment from an empty initializer list that
keeps the vectors' memory (about 0.6 GB per sweep of a ~600 A cell, ~11 GB for 20 sweeps, held
through the joint merge); they are now assigned empty vectors. The joint merge's input grew each
frame's reflections one by one, up to twice their size in spare capacity; each frame is now reserved
at its count first. Nothing the merge reads changes.
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
59ab1935e4
commit
30770ddb1d
2 files changed
+19
-5
No files matched your search
@@ -574,11 +574,24 @@ JointMergeInput BuildJointMergeInput(const std::vector<JointMemberSweep> &sweeps
|
||||
out.outcomes.resize(first + sweep.n_frames);
|
||||
for (int64_t f = 0; f < sweep.n_frames; ++f)
|
||||
out.outcomes[first + f].latt = lattice;
|
||||
const auto usable = [](const ScaledFull &full) {
|
||||
return std::isfinite(full.I) && std::isfinite(full.var_bkg) && full.var_per_I > 0.0f && full.d > 0.0f;
|
||||
};
|
||||
const auto frame_of = [&](const ScaledFull &full) {
|
||||
return std::clamp<int64_t>(std::llround(full.image_number), 0, sweep.n_frames - 1);
|
||||
};
|
||||
// Each frame's reflections reserved at their count first: grown one by one, a large cell's
|
||||
// sweeps held up to twice their size in spare capacity.
|
||||
std::vector<size_t> count(sweep.n_frames, 0);
|
||||
for (const ScaledFull &full : sweep.fulls)
|
||||
if (usable(full))
|
||||
count[frame_of(full)]++;
|
||||
for (int64_t f = 0; f < sweep.n_frames; ++f)
|
||||
out.outcomes[first + f].reflections.reserve(count[f]);
|
||||
for (const ScaledFull &full : sweep.fulls) {
|
||||
if (!std::isfinite(full.I) || !std::isfinite(full.var_bkg) || !(full.var_per_I > 0.0f)
|
||||
|| !(full.d > 0.0f))
|
||||
if (!usable(full))
|
||||
continue;
|
||||
const auto frame = std::clamp<int64_t>(std::llround(full.image_number), 0, sweep.n_frames - 1);
|
||||
const auto frame = frame_of(full);
|
||||
const gemmi::Op::Miller hkl = rel.cob.apply_to_hkl({{full.h, full.k, full.l}});
|
||||
// A full as the merge takes a pre-combined observation, so that the combine rebuilds the variance
|
||||
// its own sweep's merge gave it: a count c of intensity I/c at correction c = var_per_I is a
|
||||
|
||||
@@ -4262,9 +4262,10 @@ int RugnuxCli::RunJointSweeps(const RugnuxSweepPlan &plan) {
|
||||
JointMergeInput input = BuildJointMergeInput(members, relation);
|
||||
// The joint merge works on its own copy of the fulls (input.outcomes): the members' go, so that a large
|
||||
// cell's sweeps are not held twice.
|
||||
// (Assigned an empty vector, not {}: that is an assignment from an empty list, which keeps the memory.)
|
||||
for (JointMemberSweep &m : members) {
|
||||
m.fulls = {};
|
||||
m.merged = {};
|
||||
m.fulls = std::vector<ScaledFull>();
|
||||
m.merged = std::vector<MergedReflection>();
|
||||
}
|
||||
if (input.segments.size() < 2)
|
||||
logger.Warning("Only {} sweep goes into the joint merge", input.segments.size());
|
||||
|
||||
Reference in new issue
Block a user