42 for (int32_t
i = iStart + iBlock;
i < iEnd;
i += nBlocks) {
43 const int32_t
offset = merger.SectorTrackInfoFirst(
i);
45 const int32_t
n = merger.SectorTrackInfoLast(
i) - merger.SectorTrackInfoFirst(
i);
49 for (int32_t
j = 0;
j <
n;
j++) {
52 GPUCommonAlgorithm::sort(tmp, tmp +
n, [&merger,
offset](
const int32_t& aa,
const int32_t&
bb) {
53 const auto&
a = merger.SectorTrackInfos()[
offset + aa];
54 const auto&
b = merger.SectorTrackInfos()[
offset +
bb];
55 return (
a.X() !=
b.X()) ? (
a.X() <
b.X()) : (
a.Y() !=
b.Y()) ? (
a.Y() <
b.Y())
58 for (int32_t
j = 0;
j <
n;
j++) {
59 if (tmp[
j] >= 0 && tmp[
j] !=
j) {
60 auto getTrackIDIndex = [&merger](
const int32_t iSector,
const int32_t iTrack) {
61 const int32_t kEnd = merger.NMaxSingleSectorTracks();
62 for (int32_t k = 0; k < kEnd; k++) {
63 if (merger.TrackIDs()[iSector * merger.NMaxSingleSectorTracks() + k] == iTrack) {
67#ifndef GPUCA_GPUCODE_DEVICE
68 throw std::runtime_error(
"Internal error, track id missing");
73 auto firstItem = merger.SectorTrackInfos()[
offset + firstIdx];
74 int32_t firstTrackIDIndex = parameter ? 0 : getTrackIDIndex(
i,
offset + firstIdx);
75 int32_t currIdx = firstIdx;
76 int32_t sourceIdx = tmp[currIdx];
79 merger.SectorTrackInfos()[
offset + currIdx] = merger.SectorTrackInfos()[
offset + sourceIdx];
81 merger.TrackIDs()[
i * merger.NMaxSingleSectorTracks() + getTrackIDIndex(
i,
offset + sourceIdx)] =
offset + currIdx;
84 sourceIdx = tmp[currIdx];
85 }
while (sourceIdx != firstIdx);
87 merger.SectorTrackInfos()[
offset + currIdx] = firstItem;
89 merger.TrackIDs()[
i * merger.NMaxSingleSectorTracks() + firstTrackIDIndex] =
offset + currIdx;
99 if (iThread || iBlock) {
102 int32_t*
GPUrestrict() tmp = merger.TmpSortMemory();
103 const int32_t
n = merger.NOutputTracks();
104 for (int32_t
j = 0;
j <
n;
j++) {
107 GPUCommonAlgorithm::sortDeviceDynamic(tmp, tmp +
n, [&merger](
const int32_t& aa,
const int32_t&
bb) {
110 return (
a.GetAlpha() !=
b.GetAlpha()) ? (
a.GetAlpha() <
b.GetAlpha()) : (
a.GetParam().GetX() !=
b.GetParam().GetX()) ? (
a.GetParam().GetX() <
b.GetParam().GetX()) : (
a.GetParam().GetY() !=
b.GetParam().GetY()) ? (
a.GetParam().GetY() <
b.GetParam().GetY()) : (
a.GetParam().GetZ() <
b.GetParam().GetZ());
120 const int32_t
n = merger.NOutputTracks();
121 int32_t*
GPUrestrict() tmp = merger.TmpSortMemory();
124 for (int32_t
j = 0;
j <
n;
j++) {
127 }
else if (tmp[
j] >= 0) {
128 int32_t firstIdx =
j;
129 auto firstItem = merger.OutputTracks()[firstIdx];
130 int32_t currIdx = firstIdx;
131 int32_t sourceIdx = tmp[currIdx];
132 tmp2[sourceIdx] = currIdx;
135 merger.OutputTracks()[currIdx] = merger.OutputTracks()[sourceIdx];
137 sourceIdx = tmp[currIdx];
138 tmp2[sourceIdx] = currIdx;
139 }
while (sourceIdx != firstIdx);
141 merger.OutputTracks()[currIdx] = firstItem;
147 for (uint32_t k = iThread; k < merger.TmpCounter()[
i]; k += nThreads) {
148 merger.BorderTracks(
i)[k].SetTrackID(tmp2[merger.BorderTracks(
i)[k].TrackID()]);
159 auto* borderTracks = merger.BorderTracks(iBlock);
160 const uint32_t
n = merger.TmpCounter()[iBlock];
162 return (
a.TrackID() <
b.TrackID());