diff --git a/examples/sort/Makefile b/examples/sort/Makefile new file mode 100644 index 00000000..2ead0854 --- /dev/null +++ b/examples/sort/Makefile @@ -0,0 +1,8 @@ + +EXAMPLE=sort +CPP_SRC=sort.cpp sort_serial.cpp +ISPC_SRC=sort.ispc +ISPC_TARGETS=sse2,sse4-x2,avx +#ISPC_FLAGS=-DDEBUG + +include ../common.mk diff --git a/examples/sort/sort.cpp b/examples/sort/sort.cpp new file mode 100644 index 00000000..083bafa6 --- /dev/null +++ b/examples/sort/sort.cpp @@ -0,0 +1,133 @@ +/* + Copyright (c) 2013, Durham University + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Durham University nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include "../timing.h" +#include "sort_ispc.h" + +using namespace ispc; + +extern void sort_serial (int n, unsigned int code[], int order[]); + +/* progress bar by Ross Hemsley; + * http://www.rosshemsley.co.uk/2011/02/creating-a-progress-bar-in-c-or-any-other-console-app/ */ +static inline void progressbar (unsigned int x, unsigned int n, unsigned int w = 50) +{ + if (n < 100) + { + x *= 100/n; + n = 100; + } + + if ((x != n) && (x % (n/100) != 0)) return; + + using namespace std; + + float ratio = x/(float)n; + int c = ratio * w; + + cout << setw(3) << (int)(ratio*100) << "% ["; + for (int x=0; x>32; + } +} + +export void sort_ispc (uniform int n, uniform unsigned int code[], uniform int order[], uniform int ntasks) +{ + uniform int num = ntasks < 1 ? num_cores () : ntasks; + uniform int span = n / num; + uniform int hsize = 256*programCount*num; + uniform int * uniform hist = uniform new int [hsize+1]; + uniform int64 * uniform pair = uniform new int64 [n]; + uniform int64 * uniform temp = uniform new int64 [n]; + uniform int pass, i; + +#if DEBUG + if (n < 100) + { + print ("input: "); + for (i = 0; i < n; i ++) print ("%, ", code[i]); + print ("\n"); + } +#endif + + launch[num] pack (span, n, code, pair); + sync; + + for (pass = 0; pass < 4; pass ++) + { + launch[num] histogram (span, n, pair, pass, hist+1); + sync; + + /* TODO: parallelize and vectorize prefix sum */ + for (hist[0] = 0, i = 1; i < hsize; i ++) hist[i] += hist[i-1]; + + launch[num] permutation (span, n, pair, pass, hist, temp); + sync; + + launch[num] copy (span, n, temp, pair); + sync; + } + + launch[num] unpack (span, n, pair, code, order); + sync; + +#if DEBUG + for (i = 0; i < n; i ++) + { + if (i > 0 && code[i-1] > code[i]) + print ("ERR at % => % > %; ", i, code[i-1], code[i]); + } + + if (n < 100) + { + print ("output: "); + for (i = 0; i < n; i ++) print ("%, ", code[i]); + print ("\n"); + print ("order: "); + for (i = 0; i < n; i ++) print ("%, ", order[i]); + print ("\n"); + } +#endif + + delete hist; + delete pair; + delete temp; +} diff --git a/examples/sort/sort_serial.cpp b/examples/sort/sort_serial.cpp new file mode 100644 index 00000000..46fffccd --- /dev/null +++ b/examples/sort/sort_serial.cpp @@ -0,0 +1,58 @@ +/* + Copyright (c) 2013, Durham University + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Durham University nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +typedef std::pair pair; + +struct cmp +{ + bool operator() (const pair& a, const pair& b) { return a.first < b.first; } +}; + +void sort_serial (int n, unsigned int code[], int order[]) +{ + std::vector pairs; + + pairs.reserve (n); + + for (int i = 0; i < n; i++) pairs.push_back (pair(code[i], i)); + + std::sort (pairs.begin(), pairs.end(), cmp()); + + int *o = order; + + for (std::vector::const_iterator p = pairs.begin(); p != pairs.end(); ++p, ++o) *o = p->second; +}