uvector-0.1: examples/qsort/QSortPar.hs
{-# GHC_OPTIONS -fglasgow-exts #-}
{-# OPTIONS -fno-spec-constr-count #-}
--
-- TODO:
-- permute operations, which are fairly important for this algorithm, are currently
-- all sequential
module QSortPar (qsortPar)
where
import Data.Array.Parallel.Unlifted.Distributed
import Data.Array.Parallel.Unlifted.Parallel
import Data.Array.Parallel.Unlifted
import Debug.Trace
-- I'm lazy here and use the lifted qsort instead of writing a flat version
qsortPar :: UArr Double -> UArr Double
{-# NOINLINE qsortPar #-}
qsortPar = concatSU . qsortLifted . singletonSU
-- Remove the trivially sorted segments
qsortLifted:: SUArr Double -> SUArr Double
qsortLifted xssArr =
splitApplySUP flags qsortLifted' id xssArr
where
flags = mapUP ((> 1)) $ lengthsSU xssArr
-- Actual sorting
qsortLifted' xssarr =
if (xssLen == 0)
then xssarr
else (takeCU xssLen sorted) ^+:+^ equal ^+:+^ (dropCU xssLen sorted)
where
xssLen = lengthSU xssarr
xsLens = lengthsSU xssarr
pivots = xssarr !:^ mapUP (flip div 2) xsLens
pivotss = replicateSUP xsLens pivots
xarrLens = zipSU xssarr pivotss
sorted = qsortLifted (smaller +:+^ greater)
smaller = fstSU $ filterSUP (uncurryS (<)) xarrLens
greater = fstSU $ filterSUP (uncurryS (>)) xarrLens
equal = fstSU $ filterSUP (uncurryS (==)) xarrLens
splitApplySUP:: (UA e, UA e', Show e, Show e') =>
UArr Bool -> (SUArr e -> SUArr e') -> (SUArr e -> SUArr e') -> SUArr e -> SUArr e'
{-# INLINE splitApplySUP #-}
splitApplySUP flags f1 f2 xssArr =
if (lengthSU xssArr == 0)
then segmentArrU emptyU emptyU
else combineCU flags res1 res2
where
res1 = f1 $ packCUP flags xssArr
res2 = f2 $ packCUP (mapUP not flags) xssArr