Skip to content

Commit 3b9aa4e

Browse files
committed
GPUTracking: replace the merger's goto with helper lambdas
MSL supports neither goto nor labels. The label sat at the end of the loop body, so each jump was a continue for the outer loop that could not be written as one because it was issued from an inner loop. Two lambdas take over the chain walks that did the jumping: one advances a track along its segment chain and reports whether the target was met on the way, the other reports whether the target sits on either neighbour chain. Each jump then becomes a plain continue at the top level of the loop body. A null target lets the first one also cover the four walks that never tested for one, leaving the file three lines shorter than it is with the goto. Checked against the goto version by transcribing both loop bodies into a harness and comparing the skip decision and the resulting segment and neighbour links of every track over 400000 random link graphs, 71% of which took a skip path and 100000 of which reached the merging stage: no differences.
1 parent 257d60e commit 3b9aa4e

1 file changed

Lines changed: 37 additions & 40 deletions

File tree

‎GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx‎

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,31 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSectors(GPUResolveSharedMemory& smem, in
11591159
int32_t start, end;
11601160
setBlockRange(SectorTrackInfoLocalTotal(), nBlocks, iBlock, start, end);
11611161

1162+
// Walk a segment chain to its end, dir 0 towards the head and 1 towards the
1163+
// tail, reporting whether target was met on the way.
1164+
auto walkSegmentChain = [tracks = mSectorTrackInfos](GPUTPCGMSectorTrack*& track, const GPUTPCGMSectorTrack* target, int32_t dir) {
1165+
while (track->SegmentNeighbour(dir) >= 0) {
1166+
track = &tracks[track->SegmentNeighbour(dir)];
1167+
if (track == target) {
1168+
return true;
1169+
}
1170+
}
1171+
return false;
1172+
};
1173+
// Report whether target sits on either neighbour chain starting at from.
1174+
auto neighbourChainReaches = [tracks = mSectorTrackInfos](const GPUTPCGMSectorTrack* from, const GPUTPCGMSectorTrack* target) {
1175+
for (int32_t k = 0; k < 2; k++) {
1176+
const GPUTPCGMSectorTrack* tmp = from;
1177+
while (tmp->Neighbour(k) >= 0) {
1178+
tmp = &tracks[tmp->Neighbour(k)];
1179+
if (tmp == target) {
1180+
return true;
1181+
}
1182+
}
1183+
}
1184+
return false;
1185+
};
1186+
11621187
for (int32_t baseIdx = 0; baseIdx < SectorTrackInfoLocalTotal(); baseIdx += nThreads) {
11631188
int32_t itr = baseIdx + iThread;
11641189
bool inRange = itr < SectorTrackInfoLocalTotal();
@@ -1202,52 +1227,29 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSectors(GPUResolveSharedMemory& smem, in
12021227
// PrintMergeGraph(track1, std::cout);
12031228
// PrintMergeGraph(track2, std::cout);
12041229

1205-
while (track2->PrevSegmentNeighbour() >= 0) {
1206-
track2 = &mSectorTrackInfos[track2->PrevSegmentNeighbour()];
1207-
}
1230+
walkSegmentChain(track2, nullptr, 0);
12081231
if (sameSegment) {
12091232
if (track1 == track2) {
12101233
continue;
12111234
}
1212-
while (track1->PrevSegmentNeighbour() >= 0) {
1213-
track1 = &mSectorTrackInfos[track1->PrevSegmentNeighbour()];
1214-
if (track1 == track2) {
1215-
goto NextTrack;
1216-
}
1235+
if (walkSegmentChain(track1, track2, 0)) {
1236+
continue;
12171237
}
12181238
GPUCommonAlgorithm::swap(track1, track1Base);
1219-
for (int32_t k = 0; k < 2; k++) {
1220-
GPUTPCGMSectorTrack* tmp = track1Base;
1221-
while (tmp->Neighbour(k) >= 0) {
1222-
tmp = &mSectorTrackInfos[tmp->Neighbour(k)];
1223-
if (tmp == track2) {
1224-
goto NextTrack;
1225-
}
1226-
}
1239+
if (neighbourChainReaches(track1Base, track2)) {
1240+
continue;
12271241
}
1228-
1229-
while (track1->NextSegmentNeighbour() >= 0) {
1230-
track1 = &mSectorTrackInfos[track1->NextSegmentNeighbour()];
1231-
if (track1 == track2) {
1232-
goto NextTrack;
1233-
}
1242+
if (walkSegmentChain(track1, track2, 1)) {
1243+
continue;
12341244
}
12351245
} else {
1236-
while (track1->PrevSegmentNeighbour() >= 0) {
1237-
track1 = &mSectorTrackInfos[track1->PrevSegmentNeighbour()];
1238-
}
1246+
walkSegmentChain(track1, nullptr, 0);
12391247

12401248
if (track1 == track2) {
12411249
continue;
12421250
}
1243-
for (int32_t k = 0; k < 2; k++) {
1244-
GPUTPCGMSectorTrack* tmp = track1;
1245-
while (tmp->Neighbour(k) >= 0) {
1246-
tmp = &mSectorTrackInfos[tmp->Neighbour(k)];
1247-
if (tmp == track2) {
1248-
goto NextTrack;
1249-
}
1250-
}
1251+
if (neighbourChainReaches(track1, track2)) {
1252+
continue;
12511253
}
12521254

12531255
float z1min, z1max, z2min, z2max;
@@ -1284,9 +1286,7 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSectors(GPUResolveSharedMemory& smem, in
12841286

12851287
track2Base = track2;
12861288
if (!sameSegment) {
1287-
while (track1->NextSegmentNeighbour() >= 0) {
1288-
track1 = &mSectorTrackInfos[track1->NextSegmentNeighbour()];
1289-
}
1289+
walkSegmentChain(track1, nullptr, 1);
12901290
}
12911291
track1->SetNextSegmentNeighbour(track2 - mSectorTrackInfos);
12921292
track2->SetPrevSegmentNeighbour(track1 - mSectorTrackInfos);
@@ -1302,9 +1302,7 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSectors(GPUResolveSharedMemory& smem, in
13021302
track2->SetNeighbor(-1, k);
13031303
track2new->SetNeighbor(-1, k ^ 1);
13041304
track1 = track1new;
1305-
while (track1->NextSegmentNeighbour() >= 0) {
1306-
track1 = &mSectorTrackInfos[track1->NextSegmentNeighbour()];
1307-
}
1305+
walkSegmentChain(track1, nullptr, 1);
13081306
track1->SetNextSegmentNeighbour(track2new - mSectorTrackInfos);
13091307
track2new->SetPrevSegmentNeighbour(track1 - mSectorTrackInfos);
13101308
track1 = track1new;
@@ -1319,7 +1317,6 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSectors(GPUResolveSharedMemory& smem, in
13191317
}
13201318
// GPUInfo("Result");
13211319
// PrintMergeGraph(track1, std::cout);
1322-
NextTrack:;
13231320
}
13241321
}
13251322
}

0 commit comments

Comments
 (0)