{- Parallelitaet in funktionalen Programmiersprachen, Einfache Haskell-Beispielprogramme -} module Main where import Data.Time.Clock (diffUTCTime, getCurrentTime) import System.Environment (getArgs) import System.Random (StdGen, getStdGen, randoms) import Data.List (transpose) import Control.Parallel (par,pseq) import Control.DeepSeq import Control.Parallel.Strategies usage :: String usage = "1. Arg.: Versionen - 0 (binom), 1 (quicksort), 2 (qsort/parlist) \n" ++ "2. Arg.: Eingabegroesse" -- Hauptprogramm (Testumgebung) main :: IO () main = do args <- getArgs if null args then putStrLn usage else do let v = read (head args) let n = read (head (tail args)) putStrLn $ "Input Size: " ++ show n input <- randomInts n `fmap` getStdGen start <- getCurrentTime let result = runEval $ rdeepseq (test v n input) putStrLn ("Length of Result List: " ++ (show (length result))) end <- getCurrentTime putStrLn (show (end `diffUTCTime` start) ++ " elapsed." ) {- Beispielaufrufe: Binomialkoeffizienten: examplePar 0 30 +RTS -ls -N2 bzw. -N1 Quicksort: examplePar 1 100000 +RTS -ls -N2 bzw. -N1 -} test :: Int -> Int -> [Int] -> [Int] test v n input = case v of 0 -> [binom n (n `div` 2)] 1 -> qsort input 2 -> qsort2 input randomInts :: Int -> StdGen -> [Int] randomInts k g = let result = take k (randoms g) in length result `pseq` result -- Binomialkoeffizienten binom :: Int -> Int -> Int binom n k | k == 0 && n >= 0 = 1 | n < k && n >= 0 = 0 | k <= n && k >= 0 = runEval $ do b1 <- rpar (binom (n-1) k) b2 <- rseq (binom (n-1) (k-1)) return (b1 + b2) | otherwise = error "negative parameters" -- Quicksort qsort :: (Ord a, NFData a) => [a] -> [a] qsort [] = [] qsort (x:xs) = -- length smalls `par` length bigs `pseq` (smalls ++ x : bigs) `using` strat where smalls = qsort [y | y<-xs, y <=x] bigs = qsort [y | y<-xs, y > x] strat res = do (rpar `dot` rdeepseq) bigs; rdeepseq smalls; return res qsort2 :: (Ord a, NFData a) => [a] -> [a] qsort2 [] = [] qsort2 (x:xs) = -- length smalls `par` length bigs `pseq` combine ([smalls, bigs] `using` parList rdeepseq) where smalls = qsort [y | y<-xs, y <=x] bigs = qsort [y | y<-xs, y > x] combine (xs:ys:_) = xs ++ x:ys -- Determinantenberechnung det = undefined