int kth_smallest_idx(elem_type a[], int n, int k) { register unsigned int i, j, l, m; register elem_type x; l = 0; m = n - 1; while (l < m) { x = a[k]; i = l; j = m; do { while (a[i] < x) i++; while (x < a[j]) j--; if (i <= j) { ELEM_SWAP(a[i], a[j]); i++; j--; } } while (i <= j); if (j < k) l = i; if (k < i) m = j; } return k; }
void fmat_rev(fmat_t *s) { uint_t i,j; for (i=0; i< s->height; i++) { for (j=0; j< FLOOR(s->length/2); j++) { ELEM_SWAP(s->data[i][j], s->data[i][s->length-1-j]); } } }
void fvec_shift (fvec_t * s) { uint_t j; for (j = 0; j < s->length / 2; j++) { ELEM_SWAP (s->data[j], s->data[j + s->length / 2]); } }
float median(float arr[], int n) { int low, high; int median; int middle, ll, hh; low = 0; high = n - 1; median = (low + high) / 2; for (;;) { if (high <= low) /* One element only */ return arr[median]; if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]); return arr[median]; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]); if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]); if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]); /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low + 1]); /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]); do hh--; while (arr[hh] > arr[low]); if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]); } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]); /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } }
void fvec_ishift (fvec_t * s) { uint_t half = s->length / 2, start = half, j; // if length is odd, middle element is moved to the beginning if (2 * half < s->length) start ++; #ifndef HAVE_ATLAS for (j = 0; j < half; j++) { ELEM_SWAP (s->data[j], s->data[j + start]); } #else aubio_cblas_swap(half, s->data, 1, s->data + start, 1); #endif if (start != half) { for (j = 0; j < half; j++) { ELEM_SWAP (s->data[half], s->data[j]); } } }
double kth_smallest_double (double x[], int N, int k) { register int i, j, l, m; register double tmp; l = 0; m = N - 1; while (l < m) { tmp = x[k]; i = l; j = m; do { while (x[i] < tmp) i++; while (tmp < x[j]) j--; if (i<=j) { ELEM_SWAP(x[i],x[j]); i++; j--; } } while (i <= j); if (j < k) l = i; if (k < i) m = j; } return x[k]; }
int kth_smallest(int a[], int n, int k) { register i,j,l,m ; register int x, t; l=0 ; m=n-1 ; while (l<m) { x=a[k] ; i=l ; j=m ; do { while (a[i]<x) i++ ; while (x<a[j]) j-- ; if (i<=j) { ELEM_SWAP(a[i],a[j]) ; i++ ; j-- ; } } while (i<=j) ; if (j<k) l=i ; if (k<i) m=j ; } return a[k] ; }
real kth_smallest(int n, real *x, int k) { register int i,j,l,m; register real xi; l=0 ; m=n-1 ; while (l<m) { xi=x[k] ; i=l ; j=m ; do { while (x[i]<xi) i++ ; while (xi<x[j]) j-- ; if (i<=j) { ELEM_SWAP(x[i],x[j]) ; i++ ; j-- ; } } while (i<=j) ; if (j<k) l=i ; if (k<i) m=j ; } return x[k] ; }
static elem_type kth_smallest(elem_type a[], int n, int k) { int i,j,l,m ; elem_type x ; l=0 ; m=n-1 ; while (l<m) { x=a[2*k+1] ; i=l ; j=m ; do { while (a[2*i+1]<x) i++ ; while (x<a[2*j+1]) j-- ; if (i<=j) { ELEM_SWAP(a[2*i+1],a[2*j+1]) ; i++ ; j-- ; } } while (i<=j) ; if (j<k) l=i ; if (k<i) m=j ; } return a[2*k+1] ; }
unsigned char median_uint8(unsigned char x[], int N) { register int low, median, high; register int middle, ll, hh; // set location values low = 0; high = N - 1; median = (low + high) / 2; for (;;) { // one element only if (high <= low) return x[median]; // two elements only if (high == low + 1) { if (x[low] > x[high]) { ELEM_SWAP(x[low], x[high]); } return x[median]; } // find median of low, middle and high items, swap into position low middle = (low + high) / 2; if (x[middle] > x[high]) { ELEM_SWAP(x[middle], x[high]); } if (x[low] > x[high]) { ELEM_SWAP(x[low], x[high]); } if (x[middle] > x[low]) { ELEM_SWAP(x[middle], x[low]); } // swap low item (now in position middle) into position (low + 1) ELEM_SWAP(x[middle], x[low + 1]); // nibble from each end towards middle, swapping items when stuck ll = low + 1; hh = high; for (;;) { do ll++; while (x[low] > x[ll]); do hh--; while (x[hh] > x[low]); if (hh < ll) { break; } ELEM_SWAP(x[ll], x[hh]); } // swap middle item (in position low) back into correct position ELEM_SWAP(x[low], x[hh]); // reset active partition if (hh <= median) { low = ll; } if (hh >= median) { high = hh - 1; } } }
void fvec_rev(fvec_t *s) { uint_t j; for (j=0; j< FLOOR((smpl_t)s->length/2); j++) { ELEM_SWAP(s->data[j], s->data[s->length-1-j]); } }
float PyMedian(float* a, int n) { /* Get the median of an array "a" with length "n" * using the Quickselect algorithm. Returns a float. * This Quickselect routine is based on the algorithm described in * "Numerical recipes in C", Second Edition, Cambridge University Press, * 1992, Section 8.5, ISBN 0-521-43108-5 * This code by Nicolas Devillard - 1998. Public domain. */ PyDoc_STRVAR(PyMedian__doc__, "PyMedian(a, n) -> float\n\n" "Get the median of array a of length n using the Quickselect " "algorithm."); /* Make a copy of the array so that we don't alter the input array */ float* arr = (float *) malloc(n * sizeof(float)); /* Indices of median, low, and high values we are considering */ int low = 0; int high = n - 1; int median = (low + high) / 2; /* Running indices for the quick select algorithm */ int middle, ll, hh; /* The median to return */ float med; /* running index i */ int i; /* Copy the input data into the array we work with */ for (i = 0; i < n; i++) { arr[i] = a[i]; } /* Start an infinite loop */ while (true) { /* Only One or two elements left */ if (high <= low + 1) { /* Check if we need to swap the two elements */ if ((high == low + 1) && (arr[low] > arr[high])) ELEM_SWAP(arr[low], arr[high]); med = arr[median]; free(arr); return med; } /* Find median of low, middle and high items; * swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]); if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]); if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]); /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low + 1]); /* Nibble from each end towards middle, * swap items when stuck */ ll = low + 1; hh = high; while (true) { do ll++; while (arr[low] > arr[ll]); do hh--; while (arr[hh] > arr[low]); if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]); } /* Swap middle item (in position low) back into * the correct position */ ELEM_SWAP(arr[low], arr[hh]); /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } }
/*Type of Cut Strategy is defined as: * (useAltCut, useVertical) = (true, true) => Alternating Cuts * (useAltCut, useVertical) = (true, false) => Horizontal Cuts* * (useAltCut, useVertical) = (false, true) => Vertical Cuts * */ void delaunay(Vertex **ppVertices, long numVertices, Edge **ppLe, Edge **ppRe, bool useAltCuts, bool useVertical) { NOT_NULL(ppVertices); if(numVertices == 2) { Edge *pA = Edge::makeEdge(); if(*ppVertices[0] > *ppVertices[1]) { ELEM_SWAP(ppVertices[0], ppVertices[1]); } pA->setOrg(ppVertices[0]); pA->setDest(ppVertices[1]); *ppLe = pA; *ppRe = pA->Sym(); } else if(numVertices == 3) { Edge *pA = Edge::makeEdge(), *pB = Edge::makeEdge(), *pC = 0; if(*ppVertices[0] > *ppVertices[1]) { ELEM_SWAP(ppVertices[0], ppVertices[1]); } if(*ppVertices[1] > *ppVertices[2]) { ELEM_SWAP(ppVertices[1], ppVertices[2]); } Edge::splice(pA->Sym(), pB); pA->setOrg(ppVertices[0]); pA->setDest(ppVertices[1]); pB->setOrg(ppVertices[1]); pB->setDest(ppVertices[2]); REAL ccw = orient2d(ppVertices[0]->Pos(), ppVertices[1]->Pos(), ppVertices[2]->Pos()); if(ccw > 0) { pC = Edge::connect(pB, pA); *ppLe = pA; *ppRe = pB->Sym(); } else if(ccw < 0) { pC = Edge::connect(pB, pA); *ppLe = pC->Sym(); *ppRe = pC; } else { *ppLe = pA; *ppRe = pB->Sym(); } } else { long middle = std::floor(numVertices/2); Edge *pLdo = 0, *pLdi = 0, *pRdi = 0, *pRdo = 0; //These vertices are used for merging a horizontal cut Vertex *pBotMax = 0, //highest vertex of bottom half *pTopMin = 0, //lowest vertex of top half *pMin = 0, //Lexicographically max vertex *pMax = 0; //Lexicographically min vertex //Find median partition by X or Y, depending on whether we're using a vertical cut std::nth_element(ppVertices, ppVertices+middle, ppVertices+numVertices, useVertical ? Vertex::lessX : Vertex::lessY); //Recursive calls delaunay(ppVertices, middle, &pLdo, &pLdi, useAltCuts, useAltCuts ? !useVertical : useVertical); delaunay(ppVertices+middle, numVertices - middle, &pRdi, &pRdo, useAltCuts, useAltCuts ? !useVertical : useVertical); //Modify ldi be highest in bottom half and rdi to be lowest in top half if(!useVertical) { pBotMax = ppVertices[0]; pTopMin = ppVertices[middle]; pMin = (*ppVertices[0] < *ppVertices[middle]) ? ppVertices[0] : ppVertices[middle]; pMax = (*ppVertices[0] > *ppVertices[middle]) ? ppVertices[0] : ppVertices[middle];; for(long i=1; i < middle; i++) { if(*ppVertices[i] < *pMin) { pMin = ppVertices[i]; } else if(*ppVertices[i] > *pMax) { pMax = ppVertices[i]; } if(ppVertices[i]->gtY(*pBotMax)) { pBotMax = ppVertices[i]; } } for(long i=middle+1; i < numVertices; i++) { if(*ppVertices[i] < *pMin) { pMin = ppVertices[i]; } else if(*ppVertices[i] > *pMax) { pMax = ppVertices[i]; } if(ppVertices[i]->ltY(*pTopMin)) { pTopMin = ppVertices[i]; } } pLdi = pBotMax->getCWHullEdge(); pRdi = pTopMin->getCCWHullEdge(); } //Compute the lower common tangent of two sets of vertices while (1) { if(pLdi->leftOf(pRdi->Org())) { pLdi = pLdi->Lnext(); } else if(pRdi->rightOf(pLdi->Org())) { pRdi = pRdi->Rprev(); } else { break; } } // Create a first cross edge pBasel from pRdi.origin to pLdi.origin Edge *pBasel = Edge::connect(pRdi->Sym(), pLdi); if(pLdi->Org() == pLdo->Org()) { pLdo = pBasel->Sym(); } if(pRdi->Org() == pRdo->Org()) { pRdo = pBasel; } //Merging two halves while(1) { //Locate the first Left point pLcand to be encou Edge *pLcand = pBasel->Sym()->Onext(); bool leftFinished = !pLcand->valid(pBasel); if(!leftFinished) { while(incircle(pBasel->Dest()->Pos(), pBasel->Org()->Pos(), pLcand->Dest()->Pos(), pLcand->Onext()->Dest()->Pos()) > 0) { Edge *pT = pLcand->Onext(); Edge::deleteEdge(pLcand); pLcand = pT; } } //Symmetrically locate the first R point to be hit Edge *pRcand = pBasel->Oprev(); bool rightFinished = !pRcand->valid(pBasel); if(!rightFinished) { while(incircle(pBasel->Dest()->Pos(), pBasel->Org()->Pos(), pRcand->Dest()->Pos(), pRcand->Oprev()->Dest()->Pos()) > 0) { Edge *pT = pRcand->Oprev(); Edge::deleteEdge(pRcand); pRcand = pT; } } //both are invalid, pBasel is upper common tangent if(leftFinished && rightFinished) { break; } //the next cross edge is to be connected to either pLcand.dest or pRcand.dest if(leftFinished || (!rightFinished && incircle(pLcand->Dest()->Pos(), pLcand->Org()->Pos(), pRcand->Org()->Pos(), pRcand->Dest()->Pos()) > 0)) { pBasel = Edge::connect(pRcand, pBasel->Sym()); } else { pBasel = Edge::connect(pBasel->Sym(), pLcand->Sym()); } } //Modify pLdo and pRdo if we merging a horizontal cut if(!useVertical) { pLdo = pMin->getCCWHullEdge(); pRdo = pMax->getCWHullEdge(); } *ppLe = pLdo; *ppRe = pRdo; } return; }
inline double Median(TYPE arr[], int n) { #define ELEM_SWAP(a,b) { register TYPE t=(a);(a)=(b);(b)=t; } int low = 0; int high = n-1; const int median = n / 2; for (;;) { if (high <= low) // One element only break; if (high == low + 1) // Two elements only { if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]); break; } // Find median of low, middle and high items; swap into position low const int middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]); if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]); if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]); // Swap low item (now in position middle) into position (low+1) ELEM_SWAP(arr[middle], arr[low+1]); // Nibble from each end towards middle, swapping items when stuck int ll = low + 1; int hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]); do hh--; while (arr[hh] > arr[low]); if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]); } // Swap middle item (in position low) back into correct position ELEM_SWAP(arr[low], arr[hh]); // Re-set active partition if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } #undef ELEM_SWAP double medianval; if (n%2) medianval = arr[median]; else { // otherwise we find the value to average with by maximising low partition TYPE max = arr[0]; for (int i = 1; i < median; i++) { if (arr[i] > max) max = arr[i]; } medianval = (double(arr[median])+max)/2; } return medianval; }
inline double MedianSelect(TYPE arr[], int n) { #define ELEM_SWAP(a,b) { register TYPE t=(a);(a)=(b);(b)=t; } int low = 0; int high = n-1; int m = n/2; for (;;) { if (high <= low) // One element only break; if (high == low + 1) // Two elements only { if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]); break; } // Find median of low, middle and high items; swap into position low const int middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]); if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]); if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]); // Swap low item (now in position middle) into position (low+1) ELEM_SWAP(arr[middle], arr[low+1]); // Nibble from each end towards middle, swapping items when stuck int ll = low + 1; int hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]); do hh--; while (arr[hh] > arr[low]); if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]); } // Swap middle item (in position low) back into correct position ELEM_SWAP(arr[low], arr[hh]); // Re-set active partition if (hh <= m) low = ll; if (hh >= m) high = hh - 1; } #undef ELEM_SWAP // BUG BUG -- this routine works fine if the result is arr[n/2], // but for even number of items this is incorrect. ASSERT(FALSE); return MedianOf(arr, n); }
void *calcPrefixSum(void* tid) { int left, i, j, right, depth = 0, cnt1, cnt2; int prev_lt, prev_end, pstart; int first, last, group, s, e, rem, barr_id; int k1, k2, med; int thread_id = *(int *)tid; int *from = input1, *to = input2, *tp; register int t; while(1) { #ifndef DEBUG printf("\nThread id: %d pstart: %d pend: %d start: %d end: %d first_thread:%d last_thread: %d\n", ps_msg[thread_id].thread_id, ps_msg[thread_id].pstart, ps_msg[thread_id].pend, ps_msg[thread_id].start, ps_msg[thread_id].end, ps_msg[thread_id].first_thread, ps_msg[thread_id].last_thread); #endif barr_id = ps_msg[thread_id].first_thread; if(barr_id == ps_msg[thread_id].last_thread) { #ifndef DEBUG printf("\n\nThread %d: RETURNED\n\n", thread_id); #endif qsort(from+ps_msg[thread_id].pstart, ps_msg[thread_id].pend-ps_msg[thread_id].pstart+1, sizeof(int), comp); if(depth % 2 != 0) memcpy((void*)(to+ps_msg[thread_id].pstart), (void*)(from+ps_msg[thread_id].pstart), (ps_msg[thread_id].pend-ps_msg[thread_id].pstart+1)*sizeof(int)); return NULL; } med = median(from+ps_msg[thread_id].start, ps_msg[thread_id].end-ps_msg[thread_id].start+1); medians[thread_id] = med; #ifndef DEBUG printf("Thread %d: %d\n", thread_id, medians[thread_id]); #endif pthread_barrier_wait(&cbarr[barr_id]); if(thread_id == barr_id) { med = median(medians+barr_id, ps_msg[thread_id].last_thread-barr_id+1); pivots[barr_id] = med; #ifndef DEBUG printf("Global pivot: %d\n", pivots[barr_id]); #endif } pthread_barrier_wait(&cbarr[barr_id]); /* local rearrangement in each chunk with in the partition * Dutch National Flag - 2 partitioning */ i = ps_msg[thread_id].start; #ifndef DEBUG printf("Start: Thread %d: barr_id: %d loop from %d to %d\n", thread_id, barr_id,ps_msg[thread_id].start,ps_msg[thread_id].end); #endif for(cnt1 = 0, j = ps_msg[thread_id].end; i <= j;) { if(from[i] >= pivots[barr_id]) { if(from[j] < pivots[barr_id]) ELEM_SWAP(from[i], from[j]); j--; } else { i++; cnt1++; } } sum1[thread_id] = cnt1; cnt2 = (ps_msg[thread_id].end - ps_msg[thread_id].start + 1) - cnt1; sum2[thread_id] = cnt2; #ifndef DEBUG printf("\nLocal Rearragement on thread: %d cnt1: %d cnt2: %d\n",thread_id, cnt1, cnt2); for(i = ps_msg[thread_id].start; i <= ps_msg[thread_id].end; i++){ printf("%d ",from[i]); } printf("\n"); printf(" Thread %d: waiting on %d \n", thread_id, barr_id); #endif pthread_barrier_wait(&cbarr[barr_id]); if(thread_id == barr_id) { #ifndef DEBUG printf("\nTotal Local Rearragement on %d cnt1: %d cnt2: %d: \n",thread_id, cnt1, cnt2); for(i = ps_msg[thread_id].pstart; i <= ps_msg[thread_id].pend; i++){ printf("%d ",from[i]); } printf("\n"); printf("Before Prefix Sum1: "); for(i = barr_id; i <= ps_msg[thread_id].last_thread; i++){ printf("%d ",sum1[i]); } printf("\n"); #endif for(k1 = 0, k2 = 0, i = barr_id; i <= ps_msg[thread_id].last_thread; i++) { k2 += sum1[i]; sum1[i] = k1; k1 = k2; } pivots_indices[barr_id] = ps_msg[barr_id].pstart + k2; #ifndef DEBUG printf("New pivot index is %d\n",pivots_indices[barr_id]); printf("Prefix Sum1: "); for(i = barr_id; i <= ps_msg[thread_id].last_thread; i++){ printf("%d ",sum1[i]); } printf("\n"); #endif } else if(thread_id == ps_msg[thread_id].last_thread) { #ifndef DEBUG printf("Before Prefix Sum2: "); for(i = barr_id; i <= ps_msg[thread_id].last_thread; i++){ printf("%d ",sum2[i]); } printf("\n"); #endif for(k1 = 0, k2 = 0,i = barr_id; i <= ps_msg[thread_id].last_thread; i++) { k2 += sum2[i]; sum2[i] = k1; k1 = k2; } #ifndef DEBUG printf("Prefix Sum2: "); for(i = barr_id; i <= ps_msg[thread_id].last_thread; i++){ printf("%d ",sum2[i]); } printf("\n"); #endif } pthread_barrier_wait(&cbarr[barr_id]); /* Copy elements to a new array */ i = ps_msg[thread_id].start; pstart = ps_msg[thread_id].pstart; if(cnt1 != 0) { #ifndef DEBUG printf("c1-Thread: %d copying to pstart:%d+%d from %d elements-%d to %d\n",thread_id, pstart, sum1[thread_id], i,cnt1, pstart+sum1[thread_id]); #endif memcpy((void*)(to+pstart+sum1[thread_id]), (void*)(from+i), cnt1*sizeof(int)); } if(cnt2 != 0) { #ifndef DEBUG printf("c2-Thread: %d copying to pstart:%d+%d from %d elements-%d to %d\n",thread_id, pstart+pivots_indices[barr_id], sum2[thread_id], i+cnt1, cnt2, pivots_indices[barr_id]+sum2[thread_id]); #endif memcpy((void*)(to+pivots_indices[barr_id]+sum2[thread_id]),(void*)(from+i+cnt1), cnt2*sizeof(int)); } pthread_barrier_wait(&cbarr[barr_id]); tp = from; from = to; to = tp; if(thread_id == barr_id) { prev_end = ps_msg[thread_id].pend; prev_lt = ps_msg[thread_id].last_thread; #ifndef DEBUG printf("Final: "); for(i = ps_msg[thread_id].pstart; i <= ps_msg[thread_id].pend; i++){ printf("%d ",from[i]); } printf("\n"); #endif med = ps_msg[thread_id].last_thread - barr_id + 1; k1 = pivots_indices[barr_id] - ps_msg[thread_id].start; k2 = prev_end - pivots_indices[barr_id] + 1; first = round(((double)k1/(k1+k2))*med); first = (first == 0)?1:first; last = med - first; group = k1/first; rem = k1%first; #ifndef DEBUG printf("\n---------Thread: %d First Paritioning: k:%d group:%d rem:%d first: %d last: %d------------\n", thread_id, k1, group1, rem1, first, last); printf("loop from: %d to %d\n", barr_id, barr_id+first); #endif cnt1 = barr_id + first; for(i = barr_id, s = 0, e = ps_msg[thread_id].start-1; i < cnt1; i++) { s = e + 1; e = s + group - 1; if(rem > 0) { rem--; e++; } ps_msg[i].pstart = ps_msg[thread_id].pstart; ps_msg[i].pend = pivots_indices[barr_id]-1; ps_msg[i].start = s; ps_msg[i].end = e; ps_msg[i].first_thread = barr_id; ps_msg[i].last_thread = cnt1-1; } #ifndef DEBUG printf("\n---------Thread: %d Second Paritioning: k:%d group:%d rem:%d first: %d last: %d------------\n", thread_id, k2, group2, rem2, first, last); printf("loop from: %d to %d\n", barr_id+first,barr_id+first+last); #endif cnt1 += last; group = k2/last; rem = k2%last; for(i = (barr_id+first), e = pivots_indices[barr_id]-1; i < cnt1; i++) { s = e + 1; e = s + group - 1; if(rem > 0) { rem--; e++; } ps_msg[i].pstart = pivots_indices[barr_id]; ps_msg[i].pend = prev_end; ps_msg[i].start = s; ps_msg[i].end = e; ps_msg[i].first_thread = barr_id+first; ps_msg[i].last_thread = cnt1-1; } #ifndef DEBUG for(i = 0; i < num_threads; i++) { printf("Thread id: %d pstart: %d pend: %d start: %d end: %d first_thread:%d last_thread: %d\n", ps_msg[i].thread_id, ps_msg[i].pstart, ps_msg[i].pend, ps_msg[i].start, ps_msg[i].end, ps_msg[i].first_thread, ps_msg[i].last_thread); } printf("cbarr: %d %d\n",barr_id, first); printf("cbarr: %d %d\n",barr_id+first, last); #endif pthread_barrier_destroy(&cbarr[barr_id]); pthread_barrier_init(&cbarr[barr_id], NULL, first); pthread_barrier_destroy(&cbarr[barr_id+first]); pthread_barrier_init(&cbarr[barr_id+first], NULL, last); for(i = barr_id+1; i <= prev_lt; i++) { pthread_barrier_wait(&obarr[i]); } //printf("Thread id: %d Master thread done !!\n", thread_id); } else { pthread_barrier_wait(&obarr[thread_id]); //printf("Thread %d done with a level\n",thread_id); } depth++; } }