docs: say what the CPU prediction path actually does

BraggPrediction.h claimed the buffer "GROWS to whatever a frame actually
predicts, so a large cell is never truncated here". Only the two GPU Calc
overrides call GrowCapacity; both CPU predictors stop at max_reflections.
The cap is applied inside the h/k/l walk and before the resolution test,
so what survives is the low-|h| block, not the reflections nearest the
Ewald sphere - a cell large enough to overflow 20000 gives different
merged reflections with and without a GPU. Documented rather than
silently claimed otherwise.

Also removed a paragraph describing a once-per-predictor overflow warning
that no longer exists, and fixed the rugnux_cli.cpp path in HDF5.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-31 15:02:57 +02:00
co-authored by Claude Opus 5
parent 66e705c0fe
commit b5b7cf2cf9
2 changed files with 11 additions and 9 deletions
+1 -1
View File
@@ -93,7 +93,7 @@ bitshuffle + Zstd; signed integer image datasets use `INTx_MIN` as the HDF5 fill
### Reprocessing output: `<prefix>_process.h5`
The offline reprocessing tool [`rugnux`](TOOLS.md) (`tools/rugnux_cli.cpp`) re-runs the
The offline reprocessing tool [`rugnux`](TOOLS.md) (`rugnux/rugnux_cli.cpp`) re-runs the
full analysis pipeline (spot finding, indexing, refinement, integration, scaling) on an existing
dataset and writes its results to a master file named **`<prefix>_process.h5`**. This file uses the
**integrated** format, but instead of copying the images its `/entry/data/data` is a *virtual
@@ -33,17 +33,18 @@ struct BraggPredictionSettings {
class BraggPrediction {
protected:
// Not const: the buffer grows to fit a frame that predicts more than it currently holds.
// Not const: on the GPU path the buffer grows to fit a frame that predicts more than it holds.
int max_reflections;
std::vector<Reflection> reflections;
// A frame that predicts more than the buffer holds keeps an ARBITRARY subset of them: the GPU
// kernels claim slots with an atomicAdd, so which ones survive depends on block scheduling and
// changes from run to run. Say so, once per predictor, rather than let it pass silently - it is
// not a small effect (measured: a 3% run-to-run spread in the number of merged reflections, and
// every frame of that dataset overflowed).
// Make room for `count` reflections. Overridden where device buffers have to follow. Called only
// when a frame predicted more than the current capacity, so a run pays for it a handful of times.
//
// NOTE: only the GPU Calc overrides call this. BraggPrediction::Calc and BraggPredictionRot::Calc
// stop filling at max_reflections instead, silently - and because that cap is applied inside the
// h/k/l walk, before the resolution test, what survives is the low-|h| block rather than the
// reflections nearest the Ewald sphere. A cell large enough to overflow 20000 therefore yields
// different merged reflections on a CPU-only build than on a GPU one.
virtual void GrowCapacity(int count);
// Deterministically cap Calc's output at kPredictionOutput: if more were predicted, keep the ones
@@ -54,8 +55,9 @@ public:
// The prediction buffer holds up to kPredictionCapacity reflections so a strong lattice does not
// overflow it. Calc returns at most kPredictionOutput, the number that flows downstream and is serialized - kept low so the
// per-image reflection list stays within the frame transport headroom.
// Starting size only: the buffer GROWS to whatever a frame actually predicts (GrowCapacity), so a
// large cell is never truncated here. It used to be a hard cap, and overflowing it was both lossy
// Starting size. On the GPU path the buffer grows to whatever a frame actually predicts
// (GrowCapacity), so a large cell is not truncated there; the CPU path still caps at this value,
// see the note on GrowCapacity. It used to be a hard cap on both, and overflowing it was lossy
// and NON-DETERMINISTIC - the GPU kernels claim slots with an atomicAdd, so which reflections
// survived depended on block scheduling and changed between runs of the same command.
static constexpr int kPredictionCapacity = 20000;