{-# LANGUAGE ScopedTypeVariables #-} module Main where import Config import QuickSort import Control.Monad import Data.Array.IO import Data.Label import Data.Maybe import System.Random import Text.Read (readMaybe) import Data.Array.Accelerate.Examples.Internal import qualified Data.Array.Accelerate as A main :: IO () main = do beginMonitoring (conf, opts, rest) <- parseArgs options defaults header footer let qsort = quicksort $ get optBackend opts case (get configRandomSize conf, rest) of (Nothing, [path]) -> do -- Read input from file file <- readFile path let input = map (fromMaybe (error "Parse error. Input file should contain integers separated by spaces") . readMaybe) $ words file let result = A.toList $ qsort $ A.fromList (A.Z A.:. length input) input putStrLn $ unwords $ map show result (Just size, _) -> do -- Do multiple runs using a random input -- For later runs, the program does not have to be recompiled replicateM_ 10 $ randomRun qsort size _ -> do putStrLn "Usage: accelerate-quicksort input.txt" putStrLn "Or: accelerate-quicksort --size 1000" randomRun :: (A.Vector Int -> A.Vector Int) -> Int -> IO () randomRun qsort size = do putStrLn $ "Sorting " ++ show size ++ " elements" input <- shuffle [1 .. size] let result = A.toList $ qsort $ A.fromList (A.Z A.:. length input) input putStrLn $ unwords (map show $ take 30 result) ++ (if size <= 30 then "" else " ...") putStrLn "" -- | /O(N)/ Randomly shuffle a list -- From https://wiki.haskell.org/Random_shuffle -- shuffle :: forall a. [a] -> IO [a] shuffle xs = do let n = length xs ar <- newListArray (1,n) xs :: IO (IOArray Int a) forM [1..n] $ \i -> do j <- randomRIO (i,n) vi <- readArray ar i vj <- readArray ar j writeArray ar j vi return vj