41 typedef unsigned long long int Uint64;
46 typedef long long int ll_t;
47 typedef unsigned long long int u_ll_t;
49 #define ALLOC(x,size) \ 50 { ll_t bytes = (ll_t)sizeof(*x) * (size); \ 51 bytes = (bytes < 1) ? 1 : bytes; \ 52 x = THEmalloc(bytes); \ 53 if (!x) { fprintf(stderr, \ 54 "malloc() of %s (%lld bytes) failed in file=%s, line=%d\n", \ 55 #x, bytes, __FILE__, __LINE__); RAISE(SIGABRT); } } 57 #define CALLOC(x,size) \ 58 { ll_t sz = (ll_t)(size); \ 59 sz = (sz < 1) ? 1 : sz; \ 60 x = THEcalloc(sz, sizeof(*x)); \ 61 if (!x) { ll_t bytes = (ll_t)sizeof(*x) * (sz); \ 63 "calloc() of %s (%lld bytes) failed in file=%s, line=%d\n", \ 64 #x, bytes, __FILE__, __LINE__); RAISE(SIGABRT); } } 66 #define FREE(x) if (x) { THEfree(x); x = NULL; } 69 #define AZZERT(cond) if (cond) ABOR1("Azzertion failed: "#cond) 76 #define SIGNBIT32 0x80000000u 77 #define MASKALL32 0xFFFFFFFFu 79 #define CVMGM32(a,b,c) ( ((c) & SIGNBIT32) ? (a) : (b) ) 85 #define SIGNBIT64 0x8000000000000000ull 86 #define MASKALL64 0xFFFFFFFFFFFFFFFFull 88 #define CVMGM64(a,b,c) ( ((c) & SIGNBIT64) ? (a) : (b) ) 94 #define MASKALL16 0xFFFF 96 #define NCOUNT (MASKALL16+1) 103 #define FOR(i,s,e) for (i = s; i < e; ++i) 105 #define SHIFTMASK(a,shift) ((int)(((a) >> shift) & mask)) 107 #define CntSort(T,NB,shift,idummy) \ 109 CSortSM##shift##NB(const T A[], const int n, int local_index[], \ 110 const T idummy, cs_shared_t *cs, const int irev) \ 112 const T mask = MASKALL16; \ 113 int i, tmp, nr, min = MASKALL16, max = min; \ 115 tmp = SHIFTMASK(A[i],shift); if (tmp < min) min = tmp; else if (tmp > max) max = tmp; \ 117 nr = max - min + 1; \ 118 AZZERT(nr <= 0 || nr > NCOUNT); \ 122 int *counts = cs->counts; \ 123 memset(counts, 0, nr * sizeof(*counts)); \ 125 FOR(i,0,n) { tmp = max - SHIFTMASK(A[i],shift); AZZERT(tmp < 0 || tmp >= NCOUNT); ++counts[ tmp ]; } \ 128 FOR(i,0,n) { tmp = SHIFTMASK(A[i],shift) - min; AZZERT(tmp < 0 || tmp >= NCOUNT); ++counts[ tmp ]; } \ 131 FOR(j,1,nr) counts[j] += counts[j-1]; \ 133 int *sorted = cs->sorted; \ 134 if (!sorted) { ALLOC(sorted, n); cs->sorted = sorted; } \ 136 for (i = n-1; i >= 0; --i) { \ 137 j = local_index[i]; \ 138 tmp = max - SHIFTMASK(A[j],shift); AZZERT(tmp < 0 || tmp >= NCOUNT); \ 139 icnt = --counts[ tmp ]; AZZERT(icnt < 0 || icnt >= n); \ 144 for (i = n-1; i >= 0; --i) { \ 145 j = local_index[i]; \ 146 tmp = SHIFTMASK(A[j],shift) - min; AZZERT(tmp < 0 || tmp >= NCOUNT); \ 147 icnt = --counts[ tmp ]; AZZERT(icnt < 0 || icnt >= n); \ 151 memcpy(local_index, sorted, n * sizeof(int)); \ 156 #define Helpers(T,NB) \ 158 signmask##NB(const T Data[], int n, int inc, const int *index, int index_adj) \ 163 if (index && index_adj == 0) { \ 167 T mask = CVMGM##NB(MASKALL##NB, SIGNBIT##NB, Data[j]); \ 168 A[i] = Data[j] ^ mask; \ 172 int j = index[i]*inc; \ 173 T mask = CVMGM##NB(MASKALL##NB, SIGNBIT##NB, Data[j]); \ 174 A[i] = Data[j] ^ mask; \ 181 int j = (index[i] - index_adj); \ 182 T mask = CVMGM##NB(MASKALL##NB, SIGNBIT##NB, Data[j]); \ 183 A[i] = Data[j] ^ mask; \ 187 int j = (index[i] - index_adj)*inc; \ 188 T mask = CVMGM##NB(MASKALL##NB, SIGNBIT##NB, Data[j]); \ 189 A[i] = Data[j] ^ mask; \ 195 T mask = CVMGM##NB(MASKALL##NB, SIGNBIT##NB, Data[i]); \ 196 A[i] = Data[i] ^ mask; \ 201 T mask = CVMGM##NB(MASKALL##NB, SIGNBIT##NB, Data[j]); \ 202 A[i] = Data[j] ^ mask; \ 209 justcopy##NB(const T Data[], int n, int inc, const int *index, int index_adj) \ 214 if (index && index_adj == 0) { \ 216 FOR(i,0,n) A[i] = Data[index[i]]; \ 218 FOR(i,0,n) A[i] = Data[index[i]*inc]; \ 223 FOR(i,0,n) A[i] = Data[(index[i]-index_adj)]; \ 225 FOR(i,0,n) A[i] = Data[(index[i]-index_adj)*inc]; \ 230 memcpy(A, Data, n * sizeof(T)); \ 232 FOR(i,0,n) A[i] = Data[i*inc]; \ 238 sorted##NB(T Data[], int n, int inc, const int local_index[], T work[]) \ 242 FOR(i,0,n) work[i] = Data[local_index[i]]; \ 243 memcpy(Data, work, n * sizeof(T)); \ 246 FOR(i,0,n) work[i] = Data[local_index[i]*inc]; \ 247 FOR(i,0,n) Data[i * inc] = work[i]; \ 255 int *local_index = NULL;
257 ALLOC(local_index, n);
258 FOR(i,0,n) local_index[
i] =
i;
268 int lc = local_index[
i];
269 AZZERT(lc < 0 || lc >= n);
270 tmpidx[
i] = index[lc];
272 memcpy(index, tmpidx, n *
sizeof(*index));
286 #define DoSort(T,copyfun,NB) { \ 288 int Npasses = Npasses##NB; \ 289 int *local_index = NULL; \ 291 T *dada = copyfun(&data[addr], n, inc, index, index ? index_adj : 0); \ 295 local_index = CreateIndex(n); \ 296 CSortSM0##NB(dada, n, local_index, shift, &cs, irev); \ 297 for (j=1; j<Npasses; j++) { \ 299 CSortSMshift##NB(dada, n, local_index, shift, &cs, irev); \ 302 Local2GlobalIndex(n, local_index, index, dada); \ 305 sorted##NB(&data[addr], n, inc, local_index, dada); \ 317 const int *Start_addr,
321 const int *Index_adj,
330 int addr = (*Start_addr) - 1;
332 int index_adj = *Index_adj;
335 if (n <= 0)
goto finish;
337 if (nidx < n) index = NULL;
341 DoSort(
Uint32,justcopy32,32);
344 DoSort(
Uint32,signmask32,32);
347 DoSort(Uint64,signmask64,64);
350 DoSort(
Uint32,signmask32,32);
353 DoSort(Uint64,signmask64,64);
356 DoSort(Uint64,justcopy64,64);
CntSort(CntSort(Uint32, CntSort(32, CntSort(0, idummy)
static const int Npasses32
static void Local2GlobalIndex(int n, const int local_index[], int index[], void *work)
unsigned long long int Uint64
void ec_countingsort_(const int *Mode, const int *N, const int *Inc, const int *Start_addr, void *Data, int *index, const int *Nindex, const int *Index_adj, const int *Reverse, int *retc)
integer(kind=kindofint) nidx
unsigned long long int u_ll_t
static int * CreateIndex(int n)
static const int Npasses64