From ae0a749d08cf598b7d5978eb14a3b0a2717c62ba Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Tue, 5 Mar 2024 11:46:33 +0100 Subject: [PATCH] added insertion sort and regression test --- sort.hh | 119 +++++++--------------------------- tests/sort_regression_test.cc | 44 +++++++++++++ 2 files changed, 66 insertions(+), 97 deletions(-) create mode 100644 tests/sort_regression_test.cc diff --git a/sort.hh b/sort.hh index c36623d..1303658 100644 --- a/sort.hh +++ b/sort.hh @@ -6,107 +6,32 @@ Copyright 2024 Ahmet Inan #pragma once -#include - -template -static inline SIMD vorder(SIMD a) +template +static inline SIMD::uint_type, WIDTH> vorder(SIMD a) { - SIMD tmp; - for (int i = 0; i < WIDTH; ++i) - tmp.v[i] = i; - std::stable_sort(tmp.v, tmp.v+WIDTH, [a](int i, int j){ return a.v[i] < a.v[j]; }); - return tmp; + SIMD::uint_type, WIDTH> p; + p.v[0] = 0; + for (int i = 1, j; i < WIDTH; ++i) { + TYPE t = a.v[i]; + for (j = i; j > 0 && a.v[j-1] > t; --j) { + a.v[j] = a.v[j-1]; + p.v[j] = p.v[j-1]; + } + a.v[j] = t; + p.v[j] = i; + } + return p; } -template -static inline SIMD vorder(SIMD a) +template +static inline SIMD vsort(SIMD a) { - SIMD tmp; - for (int i = 0; i < WIDTH; ++i) - tmp.v[i] = i; - std::stable_sort(tmp.v, tmp.v+WIDTH, [a](int i, int j){ return a.v[i] < a.v[j]; }); - return tmp; -} - -template -static inline SIMD vorder(SIMD a) -{ - SIMD tmp; - for (int i = 0; i < WIDTH; ++i) - tmp.v[i] = i; - std::stable_sort(tmp.v, tmp.v+WIDTH, [a](int i, int j){ return a.v[i] < a.v[j]; }); - return tmp; -} - -template -static inline SIMD vorder(SIMD a) -{ - SIMD tmp; - for (int i = 0; i < WIDTH; ++i) - tmp.v[i] = i; - std::stable_sort(tmp.v, tmp.v+WIDTH, [a](int i, int j){ return a.v[i] < a.v[j]; }); - return tmp; -} - -template -static inline SIMD vorder(SIMD a) -{ - SIMD tmp; - for (int i = 0; i < WIDTH; ++i) - tmp.v[i] = i; - std::stable_sort(tmp.v, tmp.v+WIDTH, [a](int i, int j){ return a.v[i] < a.v[j]; }); - return tmp; -} - -template -static inline SIMD vorder(SIMD a) -{ - SIMD tmp; - for (int i = 0; i < WIDTH; ++i) - tmp.v[i] = i; - std::stable_sort(tmp.v, tmp.v+WIDTH, [a](int i, int j){ return a.v[i] < a.v[j]; }); - return tmp; -} - -template -static inline SIMD vsort(SIMD a) -{ - std::sort(a.v, a.v+WIDTH); - return a; -} - -template -static inline SIMD vsort(SIMD a) -{ - std::sort(a.v, a.v+WIDTH); - return a; -} - -template -static inline SIMD vsort(SIMD a) -{ - std::sort(a.v, a.v+WIDTH); - return a; -} - -template -static inline SIMD vsort(SIMD a) -{ - std::sort(a.v, a.v+WIDTH); - return a; -} - -template -static inline SIMD vsort(SIMD a) -{ - std::sort(a.v, a.v+WIDTH); - return a; -} - -template -static inline SIMD vsort(SIMD a) -{ - std::sort(a.v, a.v+WIDTH); + for (int i = 1, j; i < WIDTH; ++i) { + TYPE t = a.v[i]; + for (j = i; j > 0 && a.v[j-1] > t; --j) + a.v[j] = a.v[j-1]; + a.v[j] = t; + } return a; } diff --git a/tests/sort_regression_test.cc b/tests/sort_regression_test.cc new file mode 100644 index 0000000..1b18a2b --- /dev/null +++ b/tests/sort_regression_test.cc @@ -0,0 +1,44 @@ +/* +Regression Test for the SIMD wrappers sort + +Copyright 2024 Ahmet Inan +*/ + +#include +#include +#include +#include +#include +#include "simd.hh" +#include "sort.hh" + +int main() +{ + const int WIDTH = 32; + typedef int32_t TYPE; + typedef SIMD::uint_type UINT; + std::random_device rd; + typedef std::default_random_engine generator; + typedef std::uniform_int_distribution distribution; + auto rand = std::bind(distribution(0, WIDTH), generator(rd())); + for (int loop = 0; loop < 1000000; ++loop) { + SIMD a, b, c; + for (int i = 0; i < WIDTH; ++i) + a.v[i] = rand(); + b = vsort(a); + c = a; + std::sort(c.v, c.v+WIDTH); + for (int i = 0; i < WIDTH; ++i) + assert(b.v[i] == c.v[i]); + SIMD d, e; + d = vorder(a); + for (int i = 0; i < WIDTH; ++i) + e.v[i] = i; + std::stable_sort(e.v, e.v+WIDTH, [a](int i, int j){ return a.v[i] < a.v[j]; }); + for (int i = 0; i < WIDTH; ++i) + assert(d.v[i] == e.v[i]); + } + std::cerr << "Sort regression test passed!" << std::endl; + return 0; +} +