Repository navigation
Conversation
Move the comparators of the TPC merger's sorts, and MergeLooperParam they sort, from GPUTPCGMMerger.cxx and GPUTPCGMO2Output.cxx into GPUTPCGMMergerSortComp.h, unchanged. The CUDA and HIP backends see them because they compile the kernel sources into one unit; a backend that runs these sorts in host code needs them from a header.
Needs review. On a 30-collision Pb-Pb time frame, 7 of 4,416,506 clusters differed between the CPU and the Metal backend, each by one step of a packed width, sigmaTime or sigmaPad. Those widths were all within one float ulp below a quantisation step: sigma * 32 was 11.4999994, 14.4999992, 29.4999996 or 31.4999988, where the packing rounds at n + 0.5, so any difference in the last bit decides between n and n + 1. The CPU build compiles this with -ffast-math. Its arm64 code for finalize() computes 1 / Q once, the means as products with it, the variance as one fused multiply-add, fma(SS, 1 / Q, -mean * mean), and an IEEE sqrt. Metal's fast-math division and sqrt are not correctly rounded. Do the same operations on Metal explicitly, with precise::divide, fma and precise::sqrt: the pbpb clusters then match the CPU bit for bit, with no measurable cost; the rest of the Metal code keeps fast math. This matches the CPU build that the compiler produces on arm64 with clang. An x86 build, or another compiler, may choose a different sequence under -ffast-math. Writing the sequence explicitly for all backends would make the widths independent of those choices, but can change the CPU results on some platforms.
The sorts of the merged tracks by quality and by q/pT, of the looper candidates and of the O2 output tracks, which CUDA and HIP run with thrust, ran on a single GPU thread otherwise: about 730 ms per event on a 30-collision Pb-Pb time frame, at up to 140 times the CPU's time. The GPU memory is shared with the host, so sort there once the stream is drained, with the std::sort of the CPU backend, which also orders the elements that compare equal as on the CPU. The number of elements is read from the device copy of the counters, as the host copy of the O2 output count is still being transferred when the sort is launched.
The border-range sorts of the track merging between sectors, 360 per time frame, took 312 ms per event on a 30-collision Pb-Pb time frame on a single GPU thread. On the host they take about 6 ms, plus 52 ms of waiting for the streams.
Collaborator
|
Could you check if this rebases onto #15318? If this will cause merge conflicts, I'd wait with this until the new tracking version is deployed. |
Member
Author
|
I can wait. It's only a speedup. The part I care more is #16065 which makes results equal between CPU and GPU (on Apple devices). |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The border-range sorts of the track merging between sectors, 360 per
time frame, took 312 ms per event on a 30-collision Pb-Pb time frame on
a single GPU thread. On the host they take about 6 ms, plus 52 ms of
waiting for the streams.