From 8ae53b7fdf9e30ec4e5ba9e70e524aacaf65cf26 Mon Sep 17 00:00:00 2001 From: jungfrau Date: Sun, 23 Aug 2026 08:23:57 -0400 Subject: [PATCH] Say what actually makes the post-refine bucket sort reproducible The bucketing commit justified itself with "the partials order became total in an earlier commit", which is true of the scale/merge ingest and not of this sort: part_less ends at the image number, so two partials of one reflection on one image tie, exactly as they did before. Nothing is wrong with the result. The counting-sort prefix lays each bucket out chunk by chunk, and a chunk is a contiguous span of the gathered order, so every bucket arrives at std::sort in global gather order no matter how many threads scattered it - the order is reproducible run to run and identical across -N. Giving Partial a rank field to make the comparator total would settle those ties by index instead, at eight more bytes on an array that reaches tens of millions of elements, and would change nothing anyone can observe. So state the invariant where the comparator is, rather than leaving the next reader to trust a claim that does not hold for this half. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_011n8riB6X59oRjkrSHzNPAU --- image_analysis/geom_refinement/PostRefine.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/image_analysis/geom_refinement/PostRefine.cpp b/image_analysis/geom_refinement/PostRefine.cpp index 681bca17..7e952786 100644 --- a/image_analysis/geom_refinement/PostRefine.cpp +++ b/image_analysis/geom_refinement/PostRefine.cpp @@ -149,6 +149,12 @@ PostRefineResult PostRefineRotationGeometry(const std::vector