@@ -164,7 +164,98 @@ GPUTPCGMMerger::GPUTPCGMMerger()
164164#if !defined(GPUCA_GPUCODE) && (defined(GPUCA_MERGER_BY_MC_LABEL) || defined(GPUCA_CADEBUG_ENABLED) || GPUCA_MERGE_LOOPER_MC)
165165#include "GPUQAHelper.h"
166166
167- void GPUTPCGMMerger::CheckMergedTracks()
167+ template <class T>
168+ inline const auto* resolveMCLabels(const o2::dataformats::ConstMCTruthContainerView<o2::MCCompLabel>* a, const AliHLTTPCClusterMCLabel* b)
169+ {
170+ return a;
171+ }
172+ template <>
173+ inline const auto* resolveMCLabels<AliHLTTPCClusterMCLabel>(const o2::dataformats::ConstMCTruthContainerView<o2::MCCompLabel>* a, const AliHLTTPCClusterMCLabel* b)
174+ {
175+ return b;
176+ }
177+
178+ template <class T, class S>
179+ int64_t GPUTPCGMMerger::GetTrackLabelA(const S& trk) const
180+ {
181+ GPUTPCGMSectorTrack* sectorTrack = nullptr;
182+ int32_t nClusters = 0;
183+ if constexpr (std::is_same_v<S, GPUTPCGMBorderTrack&>) {
184+ sectorTrack = &mSectorTrackInfos[trk.TrackID()];
185+ nClusters = sectorTrack->OrigTrack()->NHits();
186+ } else {
187+ nClusters = trk.NClusters();
188+ }
189+ auto acc = GPUTPCTrkLbl<false, GPUTPCTrkLbl_ret>(resolveMCLabels<T>(GetConstantMem()->ioPtrs.clustersNative ? GetConstantMem()->ioPtrs.clustersNative->clustersMCTruth : nullptr, GetConstantMem()->ioPtrs.mcLabelsTPC), 0.5f);
190+ for (int32_t i = 0; i < nClusters; i++) {
191+ int32_t id;
192+ if constexpr (std::is_same_v<S, GPUTPCGMBorderTrack&>) {
193+ const GPUTPCTracker& tracker = GetConstantMem()->tpcTrackers[sectorTrack->Sector()];
194+ const GPUTPCHitId& ic = tracker.TrackHits()[sectorTrack->OrigTrack()->FirstHitID() + i];
195+ id = tracker.Data().ClusterDataIndex(tracker.Data().Row(ic.RowIndex()), ic.HitIndex()) + GetConstantMem()->ioPtrs.clustersNative->clusterOffset[sectorTrack->Sector()][0];
196+ } else {
197+ id = mClusters[trk.FirstClusterRef() + i].num;
198+ }
199+ acc.addLabel(id);
200+ }
201+ return acc.computeLabel().id;
202+ }
203+
204+ template <class S>
205+ int64_t GPUTPCGMMerger::GetTrackLabel(const S& trk) const
206+ {
207+ #ifdef GPUCA_TPC_GEOMETRY_O2
208+ if (GetConstantMem()->ioPtrs.clustersNative->clustersMCTruth) {
209+ return GetTrackLabelA<o2::dataformats::ConstMCTruthContainerView<o2::MCCompLabel>, S>(trk);
210+ } else
211+ #endif
212+ {
213+ return GetTrackLabelA<AliHLTTPCClusterMCLabel, S>(trk);
214+ }
215+ }
216+
217+ #endif
218+ // END DEBUG CODE
219+
220+ void GPUTPCGMMerger::CheckCollectedTracks()
221+ {
222+ uint32_t nErr = 0;
223+ for (uint32_t i = 0; i < mMemory->nMergedTracks; i++) {
224+ const GPUTPCGMMergedTrack& trk = mMergedTracks[i];
225+ if (trk.OK()) {
226+ if (trk.NClusters() == 0) {
227+ GPUError("FAILURE: Track marked ok but has 0 clusters");
228+ nErr++;
229+ }
230+ if (!trk.CCE() && !trk.MergedLooper()) {
231+ const GPUTPCGMMergedTrack* updTrk = &trk;
232+ while (updTrk->PrevSegment() >= 0) {
233+ auto next = &mMergedTracks[updTrk->PrevSegment()];
234+ if (!next->MergedLooper()) {
235+ GPUError("FAILURE: prev segment not marked as merged looper\n");
236+ nErr++;
237+ }
238+ if (next == &trk) {
239+ GPUError("FAILURE: segment cycle found\n");
240+ break;
241+ }
242+ updTrk = next;
243+ }
244+ if (updTrk->NClusters() == 0) {
245+ printf("FAILURE: segment leg has 0 clusters");
246+ }
247+ }
248+ }
249+ }
250+
251+ if (nErr == 0) {
252+ GPUInfo("Merged Tracks OK");
253+ } else {
254+ throw std::runtime_error("Error during track merging");
255+ }
256+ }
257+
258+ void GPUTPCGMMerger::CheckMergeGraph()
168259{
169260 uint32_t nErr = 0;
170261 std::vector<bool> trkUsed(SectorTrackInfoLocalTotal());
@@ -175,19 +266,19 @@ void GPUTPCGMMerger::CheckMergedTracks()
175266 for (int32_t itr = 0; itr < SectorTrackInfoLocalTotal(); itr++) {
176267 GPUTPCGMSectorTrack& track = mSectorTrackInfos[itr];
177268 if (track.PrevSegmentNeighbour() >= 0 && mSectorTrackInfos[track.PrevSegmentNeighbour()].NextSegmentNeighbour() != itr) {
178- GPUError("Invalid reciprocal segment link: %d PrevSegmentNeighbour %d NextSegmentNeighbour %d", itr, track.PrevSegmentNeighbour(), mSectorTrackInfos[track.PrevSegmentNeighbour()].NextSegmentNeighbour());
269+ GPUError("FAILURE: Invalid reciprocal segment link: %d PrevSegmentNeighbour %d NextSegmentNeighbour %d", itr, track.PrevSegmentNeighbour(), mSectorTrackInfos[track.PrevSegmentNeighbour()].NextSegmentNeighbour());
179270 nErr++;
180271 }
181272 if (track.NextSegmentNeighbour() >= 0 && mSectorTrackInfos[track.NextSegmentNeighbour()].PrevSegmentNeighbour() != itr) {
182- GPUError("Invalid reciprocal segment link: %d NextSegmentNeighbour %d PrevSegmentNeighbour %d", itr, track.NextSegmentNeighbour(), mSectorTrackInfos[track.NextSegmentNeighbour()].PrevSegmentNeighbour());
273+ GPUError("FAILURE: Invalid reciprocal segment link: %d NextSegmentNeighbour %d PrevSegmentNeighbour %d", itr, track.NextSegmentNeighbour(), mSectorTrackInfos[track.NextSegmentNeighbour()].PrevSegmentNeighbour());
183274 nErr++;
184275 }
185276 if (track.PrevNeighbour() >= 0 && mSectorTrackInfos[track.PrevNeighbour()].NextNeighbour() != itr) {
186- GPUError("Invalid reciprocal link: %d PrevNeighbour %d NextNeighbour %d", itr, track.PrevNeighbour(), mSectorTrackInfos[track.PrevNeighbour()].NextNeighbour());
277+ GPUError("FAILURE: Invalid reciprocal link: %d PrevNeighbour %d NextNeighbour %d", itr, track.PrevNeighbour(), mSectorTrackInfos[track.PrevNeighbour()].NextNeighbour());
187278 nErr++;
188279 }
189280 if (track.NextNeighbour() >= 0 && mSectorTrackInfos[track.NextNeighbour()].PrevNeighbour() != itr) {
190- GPUError("Invalid reciprocal link: %d NextNeighbour %d PrevNeighbour %d", itr, track.NextNeighbour(), mSectorTrackInfos[track.NextNeighbour()].PrevNeighbour());
281+ GPUError("FAILURE: Invalid reciprocal link: %d NextNeighbour %d PrevNeighbour %d", itr, track.NextNeighbour(), mSectorTrackInfos[track.NextNeighbour()].PrevNeighbour());
191282 nErr++;
192283 }
193284 if (track.PrevSegmentNeighbour() >= 0) {
@@ -202,19 +293,26 @@ void GPUTPCGMMerger::CheckMergedTracks()
202293 if (trkUsed[iTrk]) {
203294 GPUError("FAILURE: double use");
204295 nErr++;
296+ break;
205297 }
206298 trkUsed[iTrk] = true;
207299
208300 int32_t jtr = tr->NextSegmentNeighbour();
209301 if (jtr >= 0) {
210302 tr = &(mSectorTrackInfos[jtr]);
303+ if (tr->PrevNeighbour() >= 0) {
304+ GPUError("FAILURE: Non-base segment has previous leg");
305+ nErr++;
306+ }
211307 continue;
212308 }
213309 jtr = trbase->NextNeighbour();
214310 if (jtr >= 0) {
215311 trbase = &(mSectorTrackInfos[jtr]);
216312 tr = trbase;
217313 if (tr->PrevSegmentNeighbour() >= 0) {
314+ GPUError("FAILURE: Neibhbour leg has previous segment neightbout");
315+ nErr++;
218316 break;
219317 }
220318 continue;
@@ -230,62 +328,11 @@ void GPUTPCGMMerger::CheckMergedTracks()
230328 }
231329 if (nErr == 0) {
232330 GPUInfo("Merged Track Graph OK");
233- }
234- }
235-
236- template <class T>
237- inline const auto* resolveMCLabels(const o2::dataformats::ConstMCTruthContainerView<o2::MCCompLabel>* a, const AliHLTTPCClusterMCLabel* b)
238- {
239- return a;
240- }
241- template <>
242- inline const auto* resolveMCLabels<AliHLTTPCClusterMCLabel>(const o2::dataformats::ConstMCTruthContainerView<o2::MCCompLabel>* a, const AliHLTTPCClusterMCLabel* b)
243- {
244- return b;
245- }
246-
247- template <class T, class S>
248- int64_t GPUTPCGMMerger::GetTrackLabelA(const S& trk) const
249- {
250- GPUTPCGMSectorTrack* sectorTrack = nullptr;
251- int32_t nClusters = 0;
252- if constexpr (std::is_same_v<S, GPUTPCGMBorderTrack&>) {
253- sectorTrack = &mSectorTrackInfos[trk.TrackID()];
254- nClusters = sectorTrack->OrigTrack()->NHits();
255331 } else {
256- nClusters = trk.NClusters();
257- }
258- auto acc = GPUTPCTrkLbl<false, GPUTPCTrkLbl_ret>(resolveMCLabels<T>(GetConstantMem()->ioPtrs.clustersNative ? GetConstantMem()->ioPtrs.clustersNative->clustersMCTruth : nullptr, GetConstantMem()->ioPtrs.mcLabelsTPC), 0.5f);
259- for (int32_t i = 0; i < nClusters; i++) {
260- int32_t id;
261- if constexpr (std::is_same_v<S, GPUTPCGMBorderTrack&>) {
262- const GPUTPCTracker& tracker = GetConstantMem()->tpcTrackers[sectorTrack->Sector()];
263- const GPUTPCHitId& ic = tracker.TrackHits()[sectorTrack->OrigTrack()->FirstHitID() + i];
264- id = tracker.Data().ClusterDataIndex(tracker.Data().Row(ic.RowIndex()), ic.HitIndex()) + GetConstantMem()->ioPtrs.clustersNative->clusterOffset[sectorTrack->Sector()][0];
265- } else {
266- id = mClusters[trk.FirstClusterRef() + i].num;
267- }
268- acc.addLabel(id);
269- }
270- return acc.computeLabel().id;
271- }
272-
273- template <class S>
274- int64_t GPUTPCGMMerger::GetTrackLabel(const S& trk) const
275- {
276- #ifdef GPUCA_TPC_GEOMETRY_O2
277- if (GetConstantMem()->ioPtrs.clustersNative->clustersMCTruth) {
278- return GetTrackLabelA<o2::dataformats::ConstMCTruthContainerView<o2::MCCompLabel>, S>(trk);
279- } else
280- #endif
281- {
282- return GetTrackLabelA<AliHLTTPCClusterMCLabel, S>(trk);
332+ throw std::runtime_error("Invalid merge graph");
283333 }
284334}
285335
286- #endif
287- // END DEBUG CODE
288-
289336void GPUTPCGMMerger::PrintMergeGraph(const GPUTPCGMSectorTrack* trk, std::ostream& out) const
290337{
291338 const GPUTPCGMSectorTrack* orgTrack = trk;
@@ -1441,7 +1488,6 @@ struct GPUTPCGMMerger_CompareClusterIds {
14411488
14421489GPUd() void GPUTPCGMMerger::CollectMergedTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread)
14431490{
1444- // if (iThread == 0 && iBlock == 0) { CheckMergedTracks(); } return; // (if GPUCA_CADEBUG_ENABLED)
14451491 static constexpr int32_t kMaxParts = 16;
14461492 static constexpr int32_t kMaxClusters = GPUCA_MERGER_MAX_TRACK_CLUSTERS;
14471493
0 commit comments