@@ -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