<commit_before>// $Id: AliHLTTPCGMMerger.cxx 30732 2009-01-22 23:02:02Z sgorbuno $
// **************************************************************************
// This file is property of and copyright by the ALICE HLT Project          *
// ALICE Experiment at CERN, All rights reserved.                           *
//                                                                          *
// Primary Authors: <NAME> <<EMAIL>> *
//                  <NAME> <<EMAIL>>                *
//                  for The ALICE HLT Project.                              *
//                                                                          *
// Permission to use, copy, modify and distribute this software and its     *
// documentation strictly for non-commercial purposes is hereby granted     *
// without fee, provided that the above copyright notice appears in all     *
// copies and that both the copyright notice and this permission notice     *
// appear in the supporting documentation. The authors make no claims       *
// about the suitability of this software for any purpose. It is            *
// provided "as is" without express or implied warranty.                    *
//                                                                          *
//***************************************************************************

#include <stdio.h>
#include "AliHLTTPCCASliceOutTrack.h"
#include "AliHLTTPCCATracker.h"
#include "AliHLTTPCCATrackParam.h"
#include "AliHLTTPCGMCluster.h"
#include "AliHLTTPCGMPolynomialField.h"
#include "AliHLTTPCGMPolynomialFieldCreator.h"

#include "AliHLTTPCGMMerger.h"

#include "AliHLTTPCCAMath.h"

#include "AliHLTTPCCATrackParam.h"
#include "AliHLTTPCCASliceOutput.h"
#include "AliHLTTPCGMMergedTrack.h"
#include "AliHLTTPCCAParam.h"
#include "AliHLTTPCCATrackLinearisation.h"

#include "AliHLTTPCGMTrackParam.h"
#include "AliHLTTPCGMTrackLinearisation.h"
#include "AliHLTTPCGMSliceTrack.h"
#include "AliHLTTPCGMBorderTrack.h"
#include <cmath>

#include <algorithm>

#include "AliHLTTPCCAGPUConfig.h"
#include "MemoryAssignmentHelpers.h"

#define DEBUG 0

AliHLTTPCGMMerger::AliHLTTPCGMMerger()
  :
  fField(),
  fSliceParam(),
  fNOutputTracks( 0 ),
  fNOutputTrackClusters( 0 ),
  fOutputTracks( 0 ),
  fSliceTrackInfos( 0 ),
  fMaxSliceTracks(0),
  fClusters(NULL),
  fBorderMemory(0),
  fBorderRangeMemory(0),
  fGPUTracker(NULL),
  fDebugLevel(0),
  fNClusters(0)
{
  //* constructor
  
  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
    fNextSliceInd[iSlice] = iSlice + 1;
    fPrevSliceInd[iSlice] = iSlice - 1;
  }
  int mid = fgkNSlices / 2 - 1 ;
  int last = fgkNSlices - 1 ;
  fNextSliceInd[ mid ] = 0;
  fPrevSliceInd[ 0 ] = mid;  fNextSliceInd[ last ] = fgkNSlices / 2;
  fPrevSliceInd[ fgkNSlices/2 ] = last;

  fField.Reset(); // set very wrong initial value in order to see if the field was not properly initialised    
  
  Clear();
}

AliHLTTPCGMMerger::AliHLTTPCGMMerger(const AliHLTTPCGMMerger&)
  :
  fField(),
  fSliceParam(),
  fNOutputTracks( 0 ),
  fNOutputTrackClusters( 0 ),
  fOutputTracks( 0 ),
  fSliceTrackInfos( 0 ),  
  fMaxSliceTracks(0),
  fClusters(NULL),
  fBorderMemory(0),
  fBorderRangeMemory(0),
  fGPUTracker(NULL),
  fDebugLevel(0),
  fNClusters(0)
{
  //* dummy
  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
    fNextSliceInd[iSlice] = 0;
    fPrevSliceInd[iSlice] = 0;
  }
  fField.Reset();

  Clear();
}

const AliHLTTPCGMMerger &AliHLTTPCGMMerger::operator=(const AliHLTTPCGMMerger&) const
{
  //* dummy
  return *this;
}

AliHLTTPCGMMerger::~AliHLTTPCGMMerger()
{
  //* destructor
  ClearMemory();
}

void AliHLTTPCGMMerger::SetSliceParam( const AliHLTTPCCAParam &v )
{
  fSliceParam = v;
  AliHLTTPCGMPolynomialFieldCreator::GetPolynomialField( v.BzkG(), fField );
}

void AliHLTTPCGMMerger::Clear()
{
  for ( int i = 0; i < fgkNSlices; ++i ) {
    fkSlices[i] = 0;
    fSliceNTrackInfos[ i ] = 0;
    fSliceTrackInfoStart[ i ] = 0;
  }
  ClearMemory();
}
 
void AliHLTTPCGMMerger::ClearMemory()
{
  if (fSliceTrackInfos) delete[] fSliceTrackInfos;  
  if (!(fGPUTracker && fGPUTracker->IsInitialized()))
  {
	  if (fOutputTracks) delete[] fOutputTracks;
	  if (fClusters) delete[] fClusters;
  }
  if (fBorderMemory) delete[] fBorderMemory;
  if (fBorderRangeMemory) delete[] fBorderRangeMemory;

  fNOutputTracks = 0;
  fOutputTracks = 0;
  fSliceTrackInfos = 0;
  fMaxSliceTracks = 0;
  fClusters = NULL;
  fBorderMemory = 0;  
  fBorderRangeMemory = 0;
}

void AliHLTTPCGMMerger::SetSliceData( int index, const AliHLTTPCCASliceOutput *sliceData )
{
  fkSlices[index] = sliceData;
}

bool AliHLTTPCGMMerger::Reconstruct()
{
  //* main merging routine

  //fSliceParam.LoadClusterErrors();
  
  int nIter = 1;
#ifdef HLTCA_STANDALONE
  HighResTimer timer;
  static double times[5] = {};
  static int nCount = 0;
#endif
  //cout<<"Merger..."<<endl;
  for( int iter=0; iter<nIter; iter++ ){
    if( !AllocateMemory() ) return 0;
#ifdef HLTCA_STANDALONE
	timer.ResetStart();
#endif
    UnpackSlices();
#ifdef HLTCA_STANDALONE
	times[0] += timer.GetCurrentElapsedTime(true);
#endif
   MergeWithingSlices();
#ifdef HLTCA_STANDALONE
    times[1] += timer.GetCurrentElapsedTime(true);
#endif
    MergeSlices();
#ifdef HLTCA_STANDALONE
    times[2] += timer.GetCurrentElapsedTime(true);
#endif
    CollectMergedTracks();
#ifdef HLTCA_STANDALONE
    times[3] += timer.GetCurrentElapsedTime(true);
#endif
    Refit();
#ifdef HLTCA_STANDALONE
    times[4] += timer.GetCurrentElapsedTime();
    nCount++;
	if (fDebugLevel > 0)
	{
		printf("Merge Time:\tUnpack Slices:\t%1.0f us\n", times[0] * 1000000 / nCount);
		printf("\t\tMerge Within:\t%1.0f us\n", times[1] * 1000000 / nCount);
		printf("\t\tMerge Slices:\t%1.0f us\n", times[2] * 1000000 / nCount);
		printf("\t\tCollect:\t%1.0f us\n", times[3] * 1000000 / nCount);
		printf("\t\tRefit:\t\t%1.0f us\n", times[4] * 1000000 / nCount);
	}
    if (!HLTCA_TIMING_SUM)
    {
        for (int i = 0;i < 5;i++) times[i] = 0.;
        nCount = 0;
    }
    timer.Stop();  
#endif
  }  
  //cout<<"\nMerger time = "<<timer.CpuTime()*1.e3/nIter<<" ms\n"<<endl;

  return 1;
}

bool AliHLTTPCGMMerger::AllocateMemory()
{
  //* memory allocation
  
  ClearMemory();

  int nTracks = 0;
  fNClusters = 0;
  fMaxSliceTracks  = 0;
  
  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
    if ( !fkSlices[iSlice] ) continue;
    nTracks += fkSlices[iSlice]->NTracks();
    fNClusters += fkSlices[iSlice]->NTrackClusters();
    if( fMaxSliceTracks < fkSlices[iSlice]->NTracks() ) fMaxSliceTracks = fkSlices[iSlice]->NTracks();
  }

  //cout<<"\nMerger: input "<<nTracks<<" tracks, "<<nClusters<<" clusters"<<endl;

  fSliceTrackInfos = new AliHLTTPCGMSliceTrack[nTracks];
  if (fGPUTracker && fGPUTracker->IsInitialized())
  {
	char* basemem = fGPUTracker->MergerHostMemory();
	AssignMemory(fClusters, basemem, fNClusters);
	AssignMemory(fOutputTracks, basemem, nTracks);
	if ((size_t) (basemem - fGPUTracker->MergerHostMemory()) > HLTCA_GPU_MERGER_MEMORY)
	{
		printf("Insufficient memory for track merger %lld > %lld\n", (long long int) (basemem - fGPUTracker->MergerHostMemory()), (long long int) HLTCA_GPU_MERGER_MEMORY);
		return(false);
	}
  }
  else
  {
	  fOutputTracks = new AliHLTTPCGMMergedTrack[nTracks];
	  fClusters = new AliHLTTPCGMMergedTrackHit[fNClusters];
  }
  fBorderMemory = new AliHLTTPCGMBorderTrack[fMaxSliceTracks*2];
  fBorderRangeMemory = new AliHLTTPCGMBorderTrack::Range[fMaxSliceTracks*2];
  
  return ( ( fOutputTracks!=NULL )
	   && ( fSliceTrackInfos!=NULL )
	   && ( fClusters!=NULL )
	   && ( fBorderMemory!=NULL )
	   && ( fBorderRangeMemory!=NULL )
	   );
}

void AliHLTTPCGMMerger::UnpackSlices()
{
  //* unpack the cluster information from the slice tracks and initialize track info array
  
  int nTracksCurrent = 0;

  const AliHLTTPCCASliceOutTrack* firstGlobalTracks[fgkNSlices];

  int maxSliceTracks = 0;
  for( int i=0; i<fgkNSlices; i++)
  {
      firstGlobalTracks[i] = 0;
      if (fkSlices[i]->NLocalTracks() > maxSliceTracks) maxSliceTracks = fkSlices[i]->NLocalTracks();
  }

  int* TrackIds = new int[maxSliceTracks * fgkNSlices];
  for (int i = 0;i < maxSliceTracks * fgkNSlices;i++) TrackIds[i] = -1;
<commit_msg>fix segfault when tracker does not find tracks in one sector<commit_after>// $Id: AliHLTTPCGMMerger.cxx 30732 2009-01-22 23:02:02Z sgorbuno $
// **************************************************************************
// This file is property of and copyright by the ALICE HLT Project          *
// ALICE Experiment at CERN, All rights reserved.                           *
//                                                                          *
// Primary Authors: <NAME> <<EMAIL>> *
//                  <NAME> <<EMAIL>>                *
//                  for The ALICE HLT Project.                              *
//                                                                          *
// Permission to use, copy, modify and distribute this software and its     *
// documentation strictly for non-commercial purposes is hereby granted     *
// without fee, provided that the above copyright notice appears in all     *
// copies and that both the copyright notice and this permission notice     *
// appear in the supporting documentation. The authors make no claims       *
// about the suitability of this software for any purpose. It is            *
// provided "as is" without express or implied warranty.                    *
//                                                                          *
//***************************************************************************

#include <stdio.h>
#include "AliHLTTPCCASliceOutTrack.h"
#include "AliHLTTPCCATracker.h"
#include "AliHLTTPCCATrackParam.h"
#include "AliHLTTPCGMCluster.h"
#include "AliHLTTPCGMPolynomialField.h"
#include "AliHLTTPCGMPolynomialFieldCreator.h"

#include "AliHLTTPCGMMerger.h"

#include "AliHLTTPCCAMath.h"

#include "AliHLTTPCCATrackParam.h"
#include "AliHLTTPCCASliceOutput.h"
#include "AliHLTTPCGMMergedTrack.h"
#include "AliHLTTPCCAParam.h"
#include "AliHLTTPCCATrackLinearisation.h"

#include "AliHLTTPCGMTrackParam.h"
#include "AliHLTTPCGMTrackLinearisation.h"
#include "AliHLTTPCGMSliceTrack.h"
#include "AliHLTTPCGMBorderTrack.h"
#include <cmath>

#include <algorithm>

#include "AliHLTTPCCAGPUConfig.h"
#include "MemoryAssignmentHelpers.h"

#define DEBUG 0

AliHLTTPCGMMerger::AliHLTTPCGMMerger()
  :
  fField(),
  fSliceParam(),
  fNOutputTracks( 0 ),
  fNOutputTrackClusters( 0 ),
  fOutputTracks( 0 ),
  fSliceTrackInfos( 0 ),
  fMaxSliceTracks(0),
  fClusters(NULL),
  fBorderMemory(0),
  fBorderRangeMemory(0),
  fGPUTracker(NULL),
  fDebugLevel(0),
  fNClusters(0)
{
  //* constructor
  
  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
    fNextSliceInd[iSlice] = iSlice + 1;
    fPrevSliceInd[iSlice] = iSlice - 1;
  }
  int mid = fgkNSlices / 2 - 1 ;
  int last = fgkNSlices - 1 ;
  fNextSliceInd[ mid ] = 0;
  fPrevSliceInd[ 0 ] = mid;  fNextSliceInd[ last ] = fgkNSlices / 2;
  fPrevSliceInd[ fgkNSlices/2 ] = last;

  fField.Reset(); // set very wrong initial value in order to see if the field was not properly initialised    
  
  Clear();
}

AliHLTTPCGMMerger::AliHLTTPCGMMerger(const AliHLTTPCGMMerger&)
  :
  fField(),
  fSliceParam(),
  fNOutputTracks( 0 ),
  fNOutputTrackClusters( 0 ),
  fOutputTracks( 0 ),
  fSliceTrackInfos( 0 ),  
  fMaxSliceTracks(0),
  fClusters(NULL),
  fBorderMemory(0),
  fBorderRangeMemory(0),
  fGPUTracker(NULL),
  fDebugLevel(0),
  fNClusters(0)
{
  //* dummy
  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
    fNextSliceInd[iSlice] = 0;
    fPrevSliceInd[iSlice] = 0;
  }
  fField.Reset();

  Clear();
}

const AliHLTTPCGMMerger &AliHLTTPCGMMerger::operator=(const AliHLTTPCGMMerger&) const
{
  //* dummy
  return *this;
}

AliHLTTPCGMMerger::~AliHLTTPCGMMerger()
{
  //* destructor
  ClearMemory();
}

void AliHLTTPCGMMerger::SetSliceParam( const AliHLTTPCCAParam &v )
{
  fSliceParam = v;
  AliHLTTPCGMPolynomialFieldCreator::GetPolynomialField( v.BzkG(), fField );
}

void AliHLTTPCGMMerger::Clear()
{
  for ( int i = 0; i < fgkNSlices; ++i ) {
    fkSlices[i] = 0;
    fSliceNTrackInfos[ i ] = 0;
    fSliceTrackInfoStart[ i ] = 0;
  }
  ClearMemory();
}
 
void AliHLTTPCGMMerger::ClearMemory()
{
  if (fSliceTrackInfos) delete[] fSliceTrackInfos;  
  if (!(fGPUTracker && fGPUTracker->IsInitialized()))
  {
	  if (fOutputTracks) delete[] fOutputTracks;
	  if (fClusters) delete[] fClusters;
  }
  if (fBorderMemory) delete[] fBorderMemory;
  if (fBorderRangeMemory) delete[] fBorderRangeMemory;

  fNOutputTracks = 0;
  fOutputTracks = 0;
  fSliceTrackInfos = 0;
  fMaxSliceTracks = 0;
  fClusters = NULL;
  fBorderMemory = 0;  
  fBorderRangeMemory = 0;
}

void AliHLTTPCGMMerger::SetSliceData( int index, const AliHLTTPCCASliceOutput *sliceData )
{
  fkSlices[index] = sliceData;
}

bool AliHLTTPCGMMerger::Reconstruct()
{
  //* main merging routine

  //fSliceParam.LoadClusterErrors();
  
  int nIter = 1;
#ifdef HLTCA_STANDALONE
  HighResTimer timer;
  static double times[5] = {};
  static int nCount = 0;
#endif
  //cout<<"Merger..."<<endl;
  for( int iter=0; iter<nIter; iter++ ){
    if( !AllocateMemory() ) return 0;
#ifdef HLTCA_STANDALONE
	timer.ResetStart();
#endif
    UnpackSlices();
#ifdef HLTCA_STANDALONE
	times[0] += timer.GetCurrentElapsedTime(true);
#endif
   MergeWithingSlices();
#ifdef HLTCA_STANDALONE
    times[1] += timer.GetCurrentElapsedTime(true);
#endif
    MergeSlices();
#ifdef HLTCA_STANDALONE
    times[2] += timer.GetCurrentElapsedTime(true);
#endif
    CollectMergedTracks();
#ifdef HLTCA_STANDALONE
    times[3] += timer.GetCurrentElapsedTime(true);
#endif
    Refit();
#ifdef HLTCA_STANDALONE
    times[4] += timer.GetCurrentElapsedTime();
    nCount++;
	if (fDebugLevel > 0)
	{
		printf("Merge Time:\tUnpack Slices:\t%1.0f us\n", times[0] * 1000000 / nCount);
		printf("\t\tMerge Within:\t%1.0f us\n", times[1] * 1000000 / nCount);
		printf("\t\tMerge Slices:\t%1.0f us\n", times[2] * 1000000 / nCount);
		printf("\t\tCollect:\t%1.0f us\n", times[3] * 1000000 / nCount);
		printf("\t\tRefit:\t\t%1.0f us\n", times[4] * 1000000 / nCount);
	}
    if (!HLTCA_TIMING_SUM)
    {
        for (int i = 0;i < 5;i++) times[i] = 0.;
        nCount = 0;
    }
    timer.Stop();  
#endif
  }  
  //cout<<"\nMerger time = "<<timer.CpuTime()*1.e3/nIter<<" ms\n"<<endl;

  return 1;
}

bool AliHLTTPCGMMerger::AllocateMemory()
{
  //* memory allocation
  
  ClearMemory();

  int nTracks = 0;
  fNClusters = 0;
  fMaxSliceTracks  = 0;
  
  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
    if ( !fkSlices[iSlice] ) continue;
    nTracks += fkSlices[iSlice]->NTracks();
    fNClusters += fkSlices[iSlice]->NTrackClusters();
    if( fMaxSliceTracks < fkSlices[iSlice]->NTracks() ) fMaxSliceTracks = fkSlices[iSlice]->NTracks();
  }

  //cout<<"\nMerger: input "<<nTracks<<" tracks, "<<nClusters<<" clusters"<<endl;

  fSliceTrackInfos = new AliHLTTPCGMSliceTrack[nTracks];
  if (fGPUTracker && fGPUTracker->IsInitialized())
  {
	char* basemem = fGPUTracker->MergerHostMemory();
	AssignMemory(fClusters, basemem, fNClusters);
	AssignMemory(fOutputTracks, basemem, nTracks);
	if ((size_t) (basemem - fGPUTracker->MergerHostMemory()) > HLTCA_GPU_MERGER_MEMORY)
	{
		printf("Insufficient memory for track merger %lld > %lld\n", (long long int) (basemem - fGPUTracker->MergerHostMemory()), (long long int) HLTCA_GPU_MERGER_MEMORY);
		return(false);
	}
  }
  else
  {
	  fOutputTracks = new AliHLTTPCGMMergedTrack[nTracks];
	  fClusters = new AliHLTTPCGMMergedTrackHit[fNClusters];
  }
  fBorderMemory = new AliHLTTPCGMBorderTrack[fMaxSliceTracks*2];
  fBorderRangeMemory = new AliHLTTPCGMBorderTrack::Range[fMaxSliceTracks*2];
  
  return ( ( fOutputTracks!=NULL )
	   && ( fSliceTrackInfos!=NULL )
	   && ( fClusters!=NULL )
	   && ( fBorderMemory!=NULL )
	   && ( fBorderRangeMemory!=NULL )
	   );
}

void AliHLTTPCGMMerger::UnpackSlices()
{
  //* unpack the cluster information from the slice tracks and initialize track info array
  
  int nTracksCurrent = 0;

  const AliHLTTPCCASliceOutTrack* firstGlobalTracks[fgkNSlices];

  int maxSliceTracks = 0;
  for( int i=0; i<fgkNSlices; i++)
  {
      firstGlobalTracks[i] = 0;
      if (fkSlices[i] && fkSlices[i]->NLocalTracks() > maxSliceTracks) maxSliceTracks = fkSlices[i]->NLocalTracks();
  }

  int* TrackIds = new int[maxSliceTracks * fgkNSlices];
  for (int i = 0;i < maxSliceTracks * fgkNSlices;i++) TrackIds[i] = -1;

{'fraction_non_alphanumeric': 0.1452081316553727, 'fraction_numerical': 0.01706195546950629, 'mean_word_length': 3.4757649607365284, 'pattern_counts': {'":': 0, '<': 87, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5313341', 'n_tokens_mistral': 6355, 'n_tokens_neox': 6012, 'n_words': 1219}