From 96e9fb4440400c1eb24ccde35f22f1d4d2fc04b0 Mon Sep 17 00:00:00 2001 From: Richard Thier Date: Fri, 30 Jun 2023 16:39:33 +0200 Subject: [PATCH] add thiersort for testing - all kinds of crashes for now --- thiersort.h | 18 ++++++++++++------ ypsu.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/thiersort.h b/thiersort.h index 9c3960b..797de2f 100644 --- a/thiersort.h +++ b/thiersort.h @@ -377,7 +377,7 @@ static inline void thiersort8_floatkey( * * @param arr The input array. * @param askey The sequence that generates input. Gives the ith elem as key. - * @param elemlen The size of a single elem, + * @param elemsize The size of a single elem, * @param length The length of input sequence. Number of elements. * @param malloc The function to use for allocating the key-index array. * @returns Created array of keys+indices for that key to sort. @@ -385,7 +385,7 @@ static inline void thiersort8_floatkey( static inline struct tselem *thiersort_prepare_array( void *arr, union tskey (askey)(void *elem), - TSU32 elemlen, + TSU32 elemsize, TSU32 length, void* (*malloc)(size_t size)) { /* Allocate */ @@ -393,7 +393,7 @@ static inline struct tselem *thiersort_prepare_array( /* Fill */ TSU32 j = 0; - for(size_t i = 0; i < (length * elemlen); i += elemlen, ++j) { + for(size_t i = 0; i < (length * elemsize); i += elemsize, ++j) { out[j].key = askey((void *)((TSU8 *)arr + i)); out[j].i = j; } @@ -410,8 +410,8 @@ static inline struct tselem *thiersort_prepare_array( * @param sortres A thiersort result on previously prepared arr. * @param arr The original array which was prepared for sort and was sorted. * @param length The number of element (both in sortres and arr) - * @param elemlen Size of a single element - * @param tmp An array of elemlen bytes to store values for swap! + * @param elemsize Size of a single element + * @param tmp An array of elemsize bytes to store values for swap! * @param free The operation used for freeing the sort res array. */ static inline void thiersort_apply( @@ -517,6 +517,8 @@ static inline TSU8 ts_radixi( /* Need float sign trickery */ return ts_floatsigntrick((TSU8)k.u); } + + assert(false); // should never happen } /** Simple inplace quicksort for tselems */ @@ -531,6 +533,8 @@ static inline void ts_quicksort_inplace( const TSU32 bi, void *reent_data), void *reent_data) { + // Must do this early exit! + if(from == to) return; TSU32 len = (to - from); TSU32 mid = from + len / 2; @@ -597,6 +601,8 @@ static inline void ts_quicksort_fromto( const TSU32 bi, void *reent_data), void *reent_data) { + // Must do this early exit! + if(from == to) return; TSU32 len = (to - from); TSU32 mid = from + len / 2; @@ -677,7 +683,7 @@ static inline void thiersort8_internal( /* Move elements according to their buckets O(n) */ /* Right-to-left ensures keeping internal order */ - for(TSU32 i = length; i > 0; ++i) { + for(TSU32 i = length; i > 0; --i) { TSU8 radi = ts_radixi(arr[i - 1].key, isint, isunsigned, isfloat); TSU32 offset = --radics[radi]; arr2[offset] = arr[i - 1]; diff --git a/ypsu.cpp b/ypsu.cpp index 019cdcf..34aa84d 100644 --- a/ypsu.cpp +++ b/ypsu.cpp @@ -319,6 +319,7 @@ void vsort(uint32_t *a, int n) { } } } + void pagedsort(uint32_t *a, int n) { enum { pagesize = 1024 }; int pagecount = (n + pagesize - 1) / pagesize + 512; @@ -393,6 +394,46 @@ void pagedsort(uint32_t *a, int n) { free(pd); } +void thiersort_uintkey8(uint32_t *arr, int n) { + // Prepare: O(n) + tselem *tarr = thiersort_prepare_array( + arr, + // union tskey (askey)(void *elem), + [] (void *elem) { + tskey k; + k.u = *((uint32_t *)elem); + return k; + }, + 4, // elemsize, + n, // length, + malloc); + + for(uint32_t i = 0; i < n; ++i) { + printf("In: %d\n", tarr[i].key.u); + } + + // Sort: O(n*loglogn on amortized on random input): + thiersort8_uintkey( + tarr, + n, + malloc, + free); + + for(uint32_t i = 0; i < n; ++i) { + printf("Out: %d\n", tarr[i].key.u); + } + + // Apply: O(n) + uint32_t tmp[1]; // needed for elem swaps + thiersort_apply( + tarr, + arr, + n, + 4, // elemsize + tmp, + free); +} + // to measure / profile a single variant void measure_single(int n) { for (auto inputtype : inputtypes) { @@ -416,9 +457,11 @@ void measure_single(int n) { } int main(void) { - int n = 100000000; + //int n = 100000000; //int n = 10000000; - //int n = 100; + int n = 65; + + printf("Sorting %d elements:\n\n", n); // Uncomment this for profiling and alg! //measure_single(n); @@ -468,10 +511,12 @@ int main(void) { w = v;*/ measure(inputtype, "gptbuck", [&] { gpt_bucket_sort(&w[0], w.size()); }); assert(w == expected); - measure(inputtype, "magbuck", [&] { magyar_bucket_sort(&w[0], w.size()); }); - assert(w == expected); + //measure(inputtype, "magbuck", [&] { magyar_bucket_sort(&w[0], w.size()); }); + //assert(w == expected); measure(inputtype, "magbuck2", [&] { magyar_bucket_sort2(&w[0], w.size()); }); assert(w == expected); + measure(inputtype, "thiersort_uintkey8", [&] { thiersort_uintkey8(&w[0], w.size()); }); + assert(w == expected); /* w = v; measure(inputtype, "frewr", [&] { frewr(&w[0], w.size()); });