/crawl2/examples/mapfold/MapFold.hs

http://github.com/fortytools/holumbus · Haskell · 98 lines · 49 code · 17 blank · 32 comment · 0 complexity · b39525d58266272e7724baaadd36f66f MD5 · raw file

  1. -- ------------------------------------------------------------
  2. {- |
  3. Module : MapFold
  4. Copyright : Copyright (C) 2009 Uwe Schmidt
  5. License : MIT
  6. Maintainer : Uwe Schmidt (uwe@fh-wedel.de)
  7. Stability : experimental
  8. Portability: none portable
  9. Test program for Control.Concurrent.MapFold module
  10. -}
  11. -- ------------------------------------------------------------
  12. module MapFold
  13. where
  14. import Control.Concurrent
  15. import Control.Concurrent.MapFold
  16. import System.IO
  17. import System.IO.Unsafe
  18. import System.Random
  19. -- ------------------------------------------------------------
  20. main :: IO ()
  21. main = do
  22. mapM_ (runEx [1..10]) [1,2,5,10,20]
  23. runEx :: [Int] -> Int -> IO ()
  24. runEx xs n = do
  25. putStrLn $ "example run with " ++ show n ++ " processors and input " ++ show xs
  26. res <- run n xs
  27. putStrLn $ "result is " ++ res
  28. -- ------------------------------------------------------------
  29. --
  30. -- test case: take a list of numbers, in the map phase convert them into strings
  31. -- and in the fold phase build the expression for summing up the numbers.
  32. -- The trace output shows the sequence of the map and fold operations performed.
  33. -- The test runs show different results for different runs.
  34. --
  35. -- So in general the binary op
  36. -- applied during the fold phase must be associative and symmetric to deliver useful
  37. -- results (to make the result determinated).
  38. run :: Int -> [Int] -> IO String
  39. run processors = mapFold processors mapF foldF
  40. where
  41. mapF x = do
  42. logg $ "mapF: inp = " ++ show x
  43. randomDelay
  44. res <- return $ show x
  45. logg $ "mapF: res = " ++ show res
  46. return res
  47. foldF x y = do
  48. logg $ "foldF: inp = " ++ show (x,y)
  49. randomDelay
  50. res <- return $ "(" ++ x ++ "+" ++ y ++ ")"
  51. logg $ "foldF: res = " ++ show res
  52. return res
  53. -- ------------------------------------------------------------
  54. --
  55. -- simulate some compilcated computation
  56. -- by delaying the process a fraction of a second
  57. randomDelay :: IO ()
  58. randomDelay = mysec >>= threadDelay
  59. where
  60. mysec :: IO Int
  61. mysec = do
  62. r <- randomIO
  63. return $ (r :: Int) `mod` 1000000
  64. -- ------------------------------------------------------------
  65. --
  66. -- just for syncing log messages
  67. stdErrSem :: QSem
  68. stdErrSem = unsafePerformIO $ newQSem 1
  69. waitStderr, signalStderr :: IO ()
  70. waitStderr = waitQSem stdErrSem
  71. signalStderr = signalQSem stdErrSem
  72. logg :: String -> IO ()
  73. logg msg = do
  74. waitStderr
  75. tid <- myThreadId
  76. hPutStrLn stderr $ show tid ++ ": " ++ msg
  77. hFlush stderr
  78. signalStderr
  79. -- ------------------------------------------------------------