packages feed

remote-0.1: examples/pi/Pi6.hs

{-# LANGUAGE TemplateHaskell #-}
module Main where

import Remote
import PiCommon

worker :: Int -> Int -> ProcessId -> ProcessM ()
worker count offset master = 
   let (numin,numout) = countPairs offset count 
    in do send master (numin,numout)
          logS "PI" LoInformation ("Finished mapper from offset "++show offset)

$( remotable ['worker] )

initialProcess :: String -> ProcessM ()
initialProcess "WORKER" =
  receiveWait []

initialProcess "MASTER" = 
  do { peers <- getPeers
     ; mypid <- getSelfPid
     ; let { workers = findPeerByRole peers "WORKER"
     ;       interval = 1000000
     ;       numberedworkers = (zip [0,interval..] workers) }
     ; mapM_ (\ (offset,nid) -> spawn nid (worker__closure (interval-1) offset mypid)) numberedworkers
     ; (x,y) <- receiveLoop (0,0) (length workers)
     ; let est = estimatePi (fromIntegral x) (fromIntegral y)
        in say ("Done: " ++ longdiv (fst est) (snd est) 20) }
  where 
    estimatePi ni no | ni + no == 0 = (0,0)
                     | otherwise = (4 * ni , ni+no)
    receiveLoop a 0 = return a
    receiveLoop (numIn,numOut) n = 
      let 
        resultMatch = match (\ (x,y) -> return (x::Int,y::Int))
      in do { (newin,newout) <- receiveWait [resultMatch]
            ; let { x = numIn + newin
            ;       y = numOut + newout }
            ; receiveLoop (x,y) (n-1) }

initialProcess _ = error "Role must be WORKER or MASTER"

main = remoteInit (Just "config") [Main.__remoteCallMetaData] initialProcess