haskell-cnc-0.1.3: examples/embarrassingly_par.hs
{-
- Intel Concurrent Collections for Haskell
- Copyright (c) 2010, Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU Lesser General Public License,
- version 2.1, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
- more details.
-
- You should have received a copy of the GNU Lesser General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-}
-- Author: Ryan Newton
-- Embarassingly parallel.
-- If this doesn't get a speedup nothing will!
-- Note: This program is an example of a CnC Haskell program that
-- depends on "put" being strict. If it were not the real work would
-- be deferred until after the parallel computation is finished!
import GHC.Conc
import Debug.Trace
import Control.Monad
import System.Environment
import qualified Control.Monad.State.Strict as S
#include <haskell_cnc.h>
-- Compute sum_n(1/n)
work :: Int -> Int -> Double -> Double
work offset 0 n = n
work offset (!i) (!n) = work offset (i-1) (n + 1 / fromIntegral (i+offset))
runit total = runGraph graph `pseq` return ()
where
oneshare = total `quot` numCapabilities
mystep items jid =
do
#if CNC_VARIANT == 1
let tid = -99
#elif CNC_SCHEDULER == 8 || CNC_SCHEDULER == 5 || CNC_SCHEDULER == 6
tid <- S.lift$ myThreadId
#else
tid <- myThreadId
#endif
stepPutStr (show tid++" job "++show jid++": About to do big work ("++ show oneshare ++" iterations)...\n")
let res = work (oneshare * jid) oneshare 0.0
--tid2 <- S.lift$ myThreadId
stepPutStr (show tid++" job "++show jid++": done with work (result "++ show res ++"), putting item...\n")
put items jid res
graph =
do items <- newItemCol
tags <- newTagCol
cncPutStr$ "Running embarassingly parallel benchmark. CnC Variant: "++ show cncVariant ++"\n"
prescribe tags (mystep items)
initialize $
do stepPutStr$ "Begin initialize. Splitting work into "++show numCapabilities++" pieces\n"
forM_ [0 .. numCapabilities-1] (putt tags)
stepPutStr "Done initializing.\n"
finalize $
do stepPutStr "About to block on output:\n"
final <-
foldM (\ acc i ->
do stepPutStr$ " Retrieving output "++ show i ++": "
n <- get items i
stepPutStr$ show n ++ "\n"
return (acc + n))
0.0 [0 .. numCapabilities-1]
stepPutStr$ "Final Output: " ++ show final ++"\n"
main = do args <- getArgs
loop args
where
loop args =
case args of
[] -> runit $ 50*1000*1000
[n] -> runit $ round (10 ** read n)
-- [trials, n] -> doTrials (read trials) (loop [n])