RotationScaleMerge: enable GPU combine + scale-fulls by default

Steps 1-2 (GPU 3D-combine + resident scale-fulls) are validated bit-parity and
run-to-run deterministic against the CPU path across the rotation battery, and cut
the combine+scale-fulls region from ~0.46s to ~0.32s on lyso, so make them the
default when a GPU is present (consistent with phase-1 partial scaling already being
default-on). JFJOCH_RSM_CPU_COMBINE forces the CPU combine/scale-fulls for A/B or
debugging; JFJOCH_RSM_NO_GPU still disables the whole GPU path.

The only battery crystal whose reported metrics move is EP_cs_01-24 (CC1/2 2%,
unindexable noise) whose upstream integration is itself nondeterministic; its merged
intensities/CC/completeness are unchanged, only the ill-conditioned error-model b.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 08:35:23 +02:00
co-authored by Claude Opus 4.8
parent ced85bcd9d
commit 617184041f
2 changed files with 7 additions and 7 deletions
@@ -262,9 +262,9 @@ void RotationScaleMerge::Ingest() {
gpu_->SetRawRuns(static_cast<int>(rawrun_start.size()), static_cast<int>(perm.size()), perm.data(),
rawrun_start.data(), rawrun_count.data(),
rawrun_h.data(), rawrun_k.data(), rawrun_l.data());
gpu_combine_ = std::getenv("JFJOCH_RSM_GPU_COMBINE") != nullptr;
logger.Info("RotationScaleMerge: GPU partial-scaling active{}",
gpu_combine_ ? " (+ GPU combine)" : "");
gpu_combine_ = std::getenv("JFJOCH_RSM_CPU_COMBINE") == nullptr;
logger.Info("RotationScaleMerge: GPU partial-scaling{} active",
gpu_combine_ ? " + combine + scale-fulls" : "");
}
#endif
}
@@ -133,10 +133,10 @@ private:
// inactive when no GPU; the CPU loops are the fallback. Built in Ingest.
std::unique_ptr<RotationScaleMergeGPU> gpu_;
bool gpu_active_ = false;
// Phase-2 GPU combine (partials->fulls on the device). Opt-in for now (JFJOCH_RSM_GPU_COMBINE):
// it is validated bit-for-bit against the CPU combine and deterministic, but until the fulls stay
// resident for the scale-fulls + merge stages the fulls round-trip makes it no faster than the CPU
// path, so it is not on by default. See RotationScaleMergeGPU::Combine.
// Phase-2 GPU combine + scale-fulls (partials->fulls, scaled, kept resident on the device). On by
// default when a GPU is present - validated bit-parity + run-to-run deterministic vs the CPU path;
// set JFJOCH_RSM_CPU_COMBINE to fall back to the CPU combine/scale-fulls. See
// RotationScaleMergeGPU::Combine.
bool gpu_combine_ = false;
#endif