From d7d002a56244eea6cf8aecc307e76e2520b3b511 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 19 Oct 2026 11:56:50 +0200 Subject: [PATCH] GPUCommonAlgorithm: partitionPoint Device code has no std::partition_point, and kernels write the binary search by hand (e.g. the last ROF at or before a cluster in ITS/tracking/GPU/cuda/TrackingKernels.cu). Add GPUCommonAlgorithm::partitionPoint(first, count, pred), std::partition_point over the indices [first, first + count), callable from host and device code; lower and upper bounds are its predicates key(i) < value and !(value < key(i)). Co-Authored-By: Claude Opus 5.5 Signed-off-by: Felix Schlepper --- GPU/Common/GPUCommonAlgorithm.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/GPU/Common/GPUCommonAlgorithm.h b/GPU/Common/GPUCommonAlgorithm.h index f9af751d847cf..9190cab4fb507 100644 --- a/GPU/Common/GPUCommonAlgorithm.h +++ b/GPU/Common/GPUCommonAlgorithm.h @@ -49,6 +49,8 @@ class GPUCommonAlgorithm #endif template GPUd() static void swap(T& a, T& b); + template + GPUhd() static I partitionPoint(I first, I count, const P& pred); private: template @@ -330,6 +332,24 @@ GPUdi() void GPUCommonAlgorithm::swap(T& a, T& b) } #endif +// std::partition_point over the indices [first, first + count): the first index for which pred is false, pred being true on a prefix. +// A lower bound of value in a sorted key(i) is pred(i) = key(i) < value, an upper bound pred(i) = !(value < key(i)). +template +GPUhdi() I GPUCommonAlgorithm::partitionPoint(I first, I count, const P& pred) +{ + while (count > 0) { + const I step = count / 2; + const I middle = first + step; + if (pred(middle)) { + first = middle + 1; + count -= step + 1; + } else { + count = step; + } + } + return first; +} + } // namespace o2::gpu // ----------------------------- WORK GROUP FUNCTIONS -----------------------------