#include "L1Grid.h" #include "CbmL1Def.h" #include #include #include #include #include "omp.h" #include "L1Algo.h" using namespace std; /// Copy to memory block [@dest, @dest+@num] num number of times the value of i of type @T with size @typesize. /// uses binary expansion of copied volume for speed up template< typename T> inline void memset( T *dest, T i, size_t num ) { const size_t tsize = sizeof(T); unsigned int lastBin = 0; dest[0] = i; while ( lastBin+1 < num ) { unsigned int l = lastBin + 1; l = lastBin + l + 1 > num ? num - lastBin - 1 : l; memcpy( dest + lastBin + 1, dest, l*tsize ); lastBin += l; } } void L1Grid::UpdateIterGrid(int Nelements, L1StsHit* hits, vector * indicesBuf, THitI* indices, vector * indicesBuf2, vector * hits2, vector * pointsBuf, L1HitPoint* points, int &NHitsOnStation) { int SavedHits = 0 ; int Saved[fNThreads]; int Saved2[fNThreads]; int fin = fN; #pragma omp parallel for firstprivate(SavedHits, fin) for (int j=0; j0) for (int l=fFirstHitInBinArray[(fin-1)/fBinInGrid][(fin-1)%fBinInGrid]; l* indicesBuf) { int SavedHits=0; for (int j=0; j( yMax * fStepYInv - fYMinOverStep + 1.f ); fNz = static_cast( zMax * fStepZInv - fZMinOverStep + 1.f ); // unsigned int Nold = fN; fN = fNy * fNz; fBinInGrid = (((fN)/fNThreads)+1); // #pragma omp critical // cout<* pointsBuf, vector * hitsBuf, const L1StsHit* hits, vector * indices, vector * indicesBuf, char iS, L1Algo &Algo, THitI n, const vector< L1Strip > *vStsStrips, const vector< L1Strip > *vStsStripsB, const vector< fscal > *vStsZPos) { fOffsets.resize(fNThreads +1, 0); fNumberHitsInBin.resize(8000000, 0); fvec xv, yv, z; fvec u, v; fscal xs, ys; #pragma omp parallel for schedule(dynamic, 250) for( THitI x = 0; x < (fN+1); x+=fvecLen ) { reinterpret_cast(fNumberHitsInBin[x])=int_v(Vc::Zero); } #pragma omp parallel for schedule(dynamic, 250) firstprivate(xs, ys) for( THitI x = 0; x < nhits; x+=fvecLen ) { Algo.GetHitCoor((hits)[x], xs, ys, iS); for (int i=0; i* pointsBuf, vector * hitsBuf, const L1StsHit* hits, vector * indices, vector * indicesBuf, char iS, L1Algo &Algo, THitI n) { fOffsets.resize(fNThreads +1, 0); fNumberHitsInBin.resize(8000000, 0); fscal xs, ys; #pragma omp parallel for schedule(dynamic, 250) for( THitI x = 0; x < (fN+1); x++ ) { fNumberHitsInBin[x]=0; } #pragma omp parallel for schedule(dynamic, 250) firstprivate(xs, ys) for( THitI x = 0; x < nhits; x++ ) { Algo.GetHitCoor((hits)[x], xs, ys, iS); #pragma omp atomic fNumberHitsInBin[GetBinBounded(xs, ys)]++; } // fFirstHitInBin[0]=0; // // vector a(fN,0); //#pragma omp parallel // { //#pragma omp for // for(int ii=1; ii < fN; ii++) { // fFirstHitInBin[ii] = fNumberHitsInBin[ii-1]; // } // // recursiveSum(&fFirstHitInBin[0],&fFirstHitInBin[fN], fN); // // } // int NTreads = fNThreads/3; // // fOffsets[0]=0; // #pragma omp parallel for // for( int i = 1; i < NTreads; i++ ) // fOffsets[i]=i*fN/(NTreads); // fOffsets[NTreads]=fN; // // #pragma omp parallel for //schedule(static, 1)//firstprivate(first, last, mid) // for( THitI x = 0; x < NTreads; x++ ) // { // fFirstHitInBin[fOffsets[x]] = 0; // for( THitI iBin = fOffsets[x]+1; iBin < fOffsets[x+1]; iBin++ ) // fFirstHitInBin[iBin]=fFirstHitInBin[iBin-1]+ fNumberHitsInBin[iBin-1]; // } // // int Add[NTreads]; // // // Add[0]=0; // for (int p=1;p *vStsZPos, const vector< L1Strip > *vStsStrips, const vector< L1Strip > *vStsStripsB){ fscal xs, ys; #pragma omp parallel for schedule(dynamic, 250) firstprivate(xs, ys) for(THitI x = 0; x < nhits; x++ ) { // const THitI &index2 = x+n; // const THitI &bin = GetBinBounded((points)[x].Xs(), (points)[x].Ys()); // const THitI &index1 =fNumberHitsInBin[bin]; Algo.GetHitCoor((hits)[x], xs, ys, iS); const THitI &bin = GetBinBounded(xs, ys); if (fNumberHitsInBin[bin] == 1) { const THitI &index =fFirstHitInBinArray[bin/fBinInGrid][bin%fBinInGrid]; (indices)[index]=x+n; (*vStsHitsUnusedV).setHit(hits[x], index); (*vStsHitsUnusedV).z[index]=(*vStsZPos)[hits[x].iz]; (*vStsHitsUnusedV).u[index]=(*vStsStrips)[hits[x].f]; (*vStsHitsUnusedV).v[index]=(*vStsStripsB)[hits[x].b]; } else { omp_set_lock(&(lock[bin])); fNumberHitsInBin[bin]--; const THitI &index1 =fNumberHitsInBin[bin]+fFirstHitInBinArray[bin/fBinInGrid][bin%fBinInGrid]; (indices)[index1]=x+n; (*vStsHitsUnusedV).setHit(hits[x], index1); (*vStsHitsUnusedV).z[index1]=(*vStsZPos)[hits[x].iz]; (*vStsHitsUnusedV).u[index1]=(*vStsStrips)[hits[x].f]; (*vStsHitsUnusedV).v[index1]=(*vStsStripsB)[hits[x].b]; omp_unset_lock(&(lock[bin])); } } } void L1Grid::HitsSort(L1HitPoint* pointsBuf, L1StsHit* hitsBuf, const L1StsHit* hits, THitI* indices, THitI* indicesBuf, L1HitPoint* points, THitI n, THitI nhits, char iS, L1Algo &Algo, L1StsHitV* vStsHitsUnusedV, const vector< fscal > *vStsZPos, const vector< L1Strip > *vStsStrips, const vector< L1Strip > *vStsStripsB){ fscal xs, ys; #pragma omp parallel for schedule(dynamic, 250) firstprivate(xs, ys) for(THitI x = 0; x < nhits; x++ ) { // const THitI &index2 = x+n; // const THitI &bin = GetBinBounded((points)[x].Xs(), (points)[x].Ys()); // const THitI &index1 =fNumberHitsInBin[bin]; Algo.GetHitCoor((hits)[x], xs, ys, iS); const THitI &bin = GetBinBounded(xs, ys); if (fNumberHitsInBin[bin] == 1) { const THitI &index =fFirstHitInBinArray[bin/fBinInGrid][bin%fBinInGrid]; // (pointsBuf)[fFirstHitInBin[bin]]=points[x]; (hitsBuf)[index]=hits[x]; (indices)[index]=x+n; (*vStsHitsUnusedV).setHit(hits[x], index); (*vStsHitsUnusedV).z[index]=(*vStsZPos)[hits[x].iz]; (*vStsHitsUnusedV).u[index]=(*vStsStrips)[hits[x].f]; (*vStsHitsUnusedV).v[index]=(*vStsStripsB)[hits[x].b]; // a[fFirstHitInBinArray[bin/fBinInGrid][bin%fBinInGrid]]=x+n; } else { omp_set_lock(&(lock[bin])); fNumberHitsInBin[bin]--; const THitI &index1 =fNumberHitsInBin[bin]+fFirstHitInBinArray[bin/fBinInGrid][bin%fBinInGrid]; // cout<( yMax * fStepYInv - fYMinOverStep + 1.f ); fNz = static_cast( zMax * fStepZInv - fZMinOverStep + 1.f ); unsigned int Nold = fN; fN = fNy * fNz; // if (Nold < fN || Nold == 0) { // delete[] fFirstHitInBin; // fFirstHitInBin = new THitI[fN+1]; // one extra bin is needed by area to determine number of hits in the last bin // } } void L1Grid::FillPar( const L1HitPoint* points, THitI n) // call after sort, hits and number of hits are given as an input { fOffsets[0] = 0; // #pragma omp parallel for schedule(dynamic)//firstprivate(first, last, mid) for( THitI x = 1; x < fNThreads+1; x++ ) { THitI first = 0; THitI last = n; THitI mid = first + (last - first) / 2; if ((GetBinBounded(points[0].Xs(), points[0].Ys())*fBinInGrid) > x) { fOffsets[x] = 0; } else if (GetBinBounded(points[n].Xs(), points[n].Ys()/fBinInGrid) < x) { fOffsets[x] = n; } while (first < last) { if (x <= GetBinBounded(points[mid].Xs(), points[mid].Ys())/fBinInGrid) { last = mid; } else { first = mid + 1; } mid = first + (last - first) / 2; } fOffsets[x] = last; } unsigned int currBin; int lastBin = 0; #pragma omp parallel for firstprivate(lastBin, currBin) for( int j = 0; j < fNThreads; j++ ) { fFirstHitInBinArray[j][lastBin] = fOffsets[j]; for( THitI i = fOffsets[j]; i < fOffsets[j+1]; i++ ) { currBin = GetBinBounded(points[i].Xs(), points[i].Ys())%(fBinInGrid); // L1_assert( lastBin <= currBin ); memset( fFirstHitInBinArray[j] + lastBin + 1, i, currBin - lastBin ); lastBin = currBin; } memset( fFirstHitInBinArray[j] + lastBin + 1, fOffsets[j+1], fBinInGrid - lastBin ); } } void L1Grid::Fill( const L1HitPoint* points, THitI n ) // call after sort, hits and number of hits are given as an input { unsigned int lastBin = 0; // fFirstHitInBin[lastBin] = 0; for( THitI i = 0; i < n; i++ ) { const unsigned int currBin = GetBinBounded(points[i].Xs(), points[i].Ys()); L1_assert( lastBin <= currBin ); // memset( fFirstHitInBin + lastBin + 1, i, currBin - lastBin ); lastBin = currBin; } // memset( fFirstHitInBin + lastBin + 1, n, fN - lastBin ); }