-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Semi-explicit parallel programming library -- -- This package provides a library for semi-explicit parallel programming -- with Eden. Eden extends Haskell with a small set of syntactic -- constructs for explicit process specification and creation. While -- providing enough control to implement parallel algorithms efficiently, -- it frees the programmer from the tedious task of managing low-level -- details by introducing automatic communication (via head-strict lazy -- lists), synchronisation, and process handling. The Eden-modules depend -- on GHC. Using standard GHC, you will get a threaded simulation of -- Eden. Use the patched GHC-Eden compiler from -- http://www.mathematik.uni-marburg.de/~eden for a parallel -- build. See our homepage for more documentation and a tutorial. @package edenmodules @version 1.1.0.0 -- | Provides primitive functions for explicit distributed functional -- programming. This version: simulates primitives by Concurrent Haskell -- (can serve as specification of primitives semantics) -- -- Depends on GHC. -- -- Eden Group Marburg ( http://www.mathematik.uni-marburg.de/~eden ) module Control.Parallel.Eden.ParPrimConcHs noPe :: IO Int selfPe :: IO Int data ChanName' a fork :: IO () -> IO () createC :: IO (ChanName' a, a) connectToPort :: ChanName' a -> IO () sendData :: Mode -> a -> IO () data Mode Connect :: Mode Data :: Mode Stream :: Mode Instantiate :: Int -> Mode simInitPes :: Int -> IO () instance Show (ChanName' a) -- | Provides functions for semi-explicit distributed functional -- programming. Defines high-level coordination concepts via Prim.Op.s -- (which are wrapped inside ParPrimConc.hs). -- -- Notice: This module uses the concurrent simulation of the parallel -- primitives. -- -- Depends on GHC. -- -- Eden Group Marburg ( http://www.mathematik.uni-marburg.de/~eden ) module Control.Parallel.Eden.EdenConcHs -- | Process abstractions of type Process a b can be created -- with function process. Process abstractions define remote -- functions similar to lambda abstractions, which define local -- functions. data Process a b -- | Creates a process abstraction Process a b from a function -- a -> b. process :: (Trans a, Trans b) => (a -> b) -> Process a b data PA a runPA :: PA a -> a -- | Instantiates a process abstraction on a remote machine, sends the -- input of type a and returns the process output of type b. (#) :: (Trans a, Trans b) => Process a b -> a -> b -- | Instantiates a process defined by the given function a remote machine, -- sends the input of type a and returns the process output of type b. ($#) :: (Trans a, Trans b) => (a -> b) -> a -> b -- | Instantiates a list of process abstractions on remote machines with -- corresponding inputs of type a and returns the processes outputs, each -- of type b. The i-th process is supplied with the i-th input generating -- the i-th output. The number of processes (= length of output list) is -- defined by the shorter input list (thus one list may be infinite). spawn :: (Trans a, Trans b) => [Process a b] -> [a] -> [b] -- | Instantiates processes defined by the given list of functions on -- remote machines with corresponding inputs of type a and returns the -- processes outputs, each of type b. The i-th process is supplied with -- the i-th input generating the i-th output. The number of processes (= -- length of output list) is defined by the shorter input list (thus one -- list may be infinite). spawnF :: (Trans a, Trans b) => [a -> b] -> [a] -> [b] -- | Same as spawn , but with an additional [Int] -- argument that specifies where to instantiate the processes. spawnAt :: (Trans a, Trans b) => [Int] -> [Process a b] -> [a] -> [b] -- | Same as spawnF , but with an additional [Int] -- argument that specifies where to instantiate the processes. spawnFAt :: (Trans a, Trans b) => [Int] -> [a -> b] -> [a] -> [b] -- | Instantiates a process on a remote machine, sends the input of type a -- and returns the process output of type b in the parallel action monad, -- thus it can be combined to a larger parallel action. instantiate :: (Trans a, Trans b) => Process a b -> a -> PA b -- | Instantiates a process defined by the given function on a remote -- machine, sends the input of type a and returns the process output of -- type b in the parallel action monad, thus it can be combined to a -- larger parallel action. instantiateF :: (Trans a, Trans b) => (a -> b) -> a -> PA b -- | Instantiation with explicit placement (see instantiate). instantiateAt :: (Trans a, Trans b) => Int -> Process a b -> a -> PA b -- | Instantiation with explicit placement (see instantiate). instantiateFAt :: (Trans a, Trans b) => Int -> (a -> b) -> a -> PA b -- | Trans class: overloads communication for streams and tuples. You need -- to declare normal-form evaluation in an instance declaration of -- NFData. Use the default implementation for write and -- createComm for instances of Trans. class NFData a => Trans a where write x = rdeepseq x `pseq` sendData Data x createComm = do { (cx, x) <- createC; return (Comm (sendVia cx), x) } write :: Trans a => a -> IO () createComm :: Trans a => IO (ChanName a, a) -- | Number of (logical) machines in the system noPe :: Int -- | Local machine number (ranges from 1 to noPe) selfPe :: Int type RD a = ChanName (ChanName a) -- | Converts local data into corresponding remote data. release :: Trans a => a -> RD a -- | Converts local data into corresponding remote data. The result is in -- the parallel action monad and can be combined to a larger parallel -- action. releasePA :: Trans a => a -> PA (RD a) -- | This establishes a direct connection to the process which released the -- data in the first place. Notice that you have to fetch a remote value -- exactly once! fetch :: Trans a => RD a -> a -- | This establishes a direct connection to the process which released the -- data in the first place. The result is in the parallel action monad -- and can be combined to a larger parallel action. Notice that you have -- to fetch a remote value exactly once! fetchPA :: Trans a => RD a -> PA a -- | Transforms a list of local data into a corresponding remote data list. releaseAll :: Trans a => [a] -> [RD a] -- | Transforms a list of remote data into a corresponding local data list. -- map fetch would wait for each list element until fetching the -- next one. Function fetchAll blocks only on partial defined -- list structure, not on content. fetchAll :: Trans a => [RD a] -> [a] -- | Function liftRD is used to lift functions acting on normal -- data to function performing the same computation on Remote Data. liftRD :: (Trans a, Trans b) => (a -> b) -> RD a -> RD b -- | see liftRD liftRD2 :: (Trans a, Trans b, Trans c) => (a -> b -> c) -> RD a -> RD b -> RD c -- | see liftRD liftRD3 :: (Trans a, Trans b, Trans c, Trans d) => (a -> b -> c -> d) -> RD a -> RD b -> RD c -> RD d -- | see liftRD liftRD4 :: (Trans a, Trans b, Trans c, Trans d, Trans e) => (a -> b -> c -> d -> e) -> RD a -> RD b -> RD c -> RD d -> RD e -- | A channel name ChanName a is a handle for a reply channel. -- The channel can be created with the function new and you can connect -- to such a channel with the function parfill. type ChanName a = Comm a -- | A channel can be created with the function new (this is an unsafe side -- effect!). It takes a function, whose first parameter is the channel -- name ChanName a and whose second parameter is the value of -- type a that will be received lazily in the future. The -- ChanName and the value of type a can be used in the body of -- the parameter function to create the output of type b. The -- output of the parameter function will be forwarded to the output of -- new . -- -- Example: new (channame val -> (channame,val)) returns the -- tuple (channame, value) . new :: Trans a => (ChanName a -> a -> b) -> b -- | You can connect to a reply channel with function parfill -- (this is an unsafe side effect!). The first parameter is the name of -- the channel, the second parameter is the value to be send. The third -- parameter will be the functions result after the concurrent sending -- operation is initiated. The sending operation will be triggered as -- soon as the result of type b is demanded. Take care that the -- demand for the result of parfill does not depend on the sent -- value, as this will create a deadlock. parfill :: Trans a => ChanName a -> a -> b -> b -- | Non-deterministically merges a list of lists (usually input -- streams) into a single list. The order of the output list is -- determined by the availability of the inner lists constructors. -- (Function merge is defined using Concurrent Haskell's function -- nmergeIO) merge :: [[a]] -> [a] -- | same as merge mergeProc :: [[a]] -> [a] data Lift a Lift :: a -> Lift a deLift :: Lift a -> a createProcess :: (Trans a, Trans b) => Process a b -> a -> Lift b cpAt :: (Trans a, Trans b) => Int -> Process a b -> a -> Lift b -- | A class of types that can be fully evaluated. class NFData a rnf :: NFData a => a -> () -- | The type Strategy a is a -> (). Thus, a -- strategy is a function whose sole purpose it is to evaluate its -- argument (either in full or in part). type Strategy a = a -> () -- | Evaluate a value using the given strategy. using :: a -> Strategy a -> a -- | r0 performs *no* evaluation. r0 :: Strategy a -- | rseq evaluates its argument to weak head normal form. rseq :: Strategy a -- | rdeepseq fully evaluates its argument. Relies on class -- NFData from module Control.DeepSeq. rdeepseq :: NFData a => Strategy a -- | Evaluate each element of a list according to the given strategy. This -- function is a specialisation of seqFoldable to lists. seqList :: Strategy a -> Strategy [a] -- | Evaluate the elements of a foldable data structure according to the -- given strategy. seqFoldable :: Foldable t => Strategy a -> Strategy (t a) -- | Semantically identical to seq, but with a subtle operational -- difference: seq is strict in both its arguments, so the -- compiler may, for example, rearrange a `seq` b into -- b `seq` a `seq` b. This is normally no problem -- when using seq to express strictness, but it can be a problem -- when annotating code for parallelism, because we need more control -- over the order of evaluation; we may want to evaluate a -- before b, because we know that b has already been -- sparked in parallel with par. -- -- This is why we have pseq. In contrast to seq, -- pseq is only strict in its first argument (as far as the -- compiler is concerned), which restricts the transformations that the -- compiler can do, and ensures that the user can retain control of the -- evaluation order. pseq :: a -> b -> b instance (Trans a, Trans b, Trans c, Trans d, Trans e, Trans f, Trans g, Trans h, Trans i) => Trans (a, b, c, d, e, f, g, h, i) instance (Trans a, Trans b, Trans c, Trans d, Trans e, Trans f, Trans g, Trans h) => Trans (a, b, c, d, e, f, g, h) instance (Trans a, Trans b, Trans c, Trans d, Trans e, Trans f, Trans g) => Trans (a, b, c, d, e, f, g) instance (Trans a, Trans b, Trans c, Trans d, Trans e, Trans f) => Trans (a, b, c, d, e, f) instance (Trans a, Trans b, Trans c, Trans d, Trans e) => Trans (a, b, c, d, e) instance (Trans a, Trans b, Trans c, Trans d) => Trans (a, b, c, d) instance (Trans a, Trans b, Trans c) => Trans (a, b, c) instance (Trans a, Trans b) => Trans (a, b) instance (NFData a, Trans a) => Trans (Comm a) instance Trans a => Trans [a] instance Trans () instance Trans a => Trans (Maybe a) instance Trans Bool instance Trans Integer instance Trans Char instance Trans Double instance Trans Float instance Trans Int instance NFData (Comm a) instance Monad PA -- | The low-level parallel functional language: EDen Implementation -- language -- -- This module defines a thin layer of type-checking wrappers over the -- parallel primitives implemented in ParPrim.hs. -- -- Depends on the Eden Compiler. -- -- Eden Group Marburg module Control.Parallel.Eden.Edi fork :: IO () -> IO () spawnProcessAt :: Int -> IO () -> IO () spawnArgsProcessAt :: NFData a => Int -> (a -> IO ()) -> a -> IO () data ChanName' a createC :: IO (ChanName' a, a) createCs :: Int -> IO ([ChanName' a], [a]) sendWith :: Strategy a -> ChanName' a -> a -> IO () sendNF :: NFData a => ChanName' a -> a -> IO () sendStreamWith :: (a -> ()) -> ChanName' [a] -> [a] -> IO () sendNFStream :: NFData a => ChanName' [a] -> [a] -> IO () noPe :: IO Int selfPe :: IO Int -- | A class of types that can be fully evaluated. class NFData a rnf :: NFData a => a -> () -- | Evaluate a value using the given strategy. using :: a -> Strategy a -> a -- | r0 performs *no* evaluation. r0 :: Strategy a -- | rseq evaluates its argument to weak head normal form. rseq :: Strategy a -- | rdeepseq fully evaluates its argument. Relies on class -- NFData from module Control.DeepSeq. rdeepseq :: NFData a => Strategy a -- | Evaluate each element of a list according to the given strategy. This -- function is a specialisation of seqFoldable to lists. seqList :: Strategy a -> Strategy [a] -- | Evaluate the elements of a foldable data structure according to the -- given strategy. seqFoldable :: Foldable t => Strategy a -> Strategy (t a) instance NFData (ChanName' a) -- | Provides primitive functions for explicit distributed functional -- programming. Base module, importing PrimOps => exporting IO actions -- -- Depends on GHC. Using standard GHC, you will get a threaded simulation -- of the parallel primitives. Use the patched GHC-Eden compiler from -- http://www.mathematik.uni-marburg.de/~eden for a parallel build. -- -- Eden Group Marburg ( http://www.mathematik.uni-marburg.de/~eden ) module Control.Parallel.Eden.ParPrim -- | Provides functions for semi-explicit distributed functional -- programming. Defines high-level coordination concepts via Prim.Op.s -- (which are wrapped inside ParPrim.hs). -- -- Depends on GHC. Using standard GHC, you will get a threaded simulation -- of Eden. Use the patched GHC-Eden compiler from -- http://www.mathematik.uni-marburg.de/~eden for a parallel build. -- -- Eden Group Marburg ( http://www.mathematik.uni-marburg.de/~eden ) module Control.Parallel.Eden -- | Process abstractions of type Process a b can be created -- with function process. Process abstractions define remote -- functions similar to lambda abstractions, which define local -- functions. data Process a b -- | Creates a process abstraction Process a b from a function -- a -> b. process :: (Trans a, Trans b) => (a -> b) -> Process a b data PA a runPA :: PA a -> a -- | Instantiates a process abstraction on a remote machine, sends the -- input of type a and returns the process output of type b. (#) :: (Trans a, Trans b) => Process a b -> a -> b -- | Instantiates a process defined by the given function on a remote -- machine, sends the input of type a and returns the process output of -- type b. ($#) :: (Trans a, Trans b) => (a -> b) -> a -> b -- | Instantiates a list of process abstractions on remote machines with -- corresponding inputs of type a and returns the processes outputs, each -- of type b. The i-th process is supplied with the i-th input generating -- the i-th output. The number of processes (= length of output list) is -- defined by the shorter input list (thus one list may be infinite). spawn :: (Trans a, Trans b) => [Process a b] -> [a] -> [b] -- | Instantiates processes defined by the given list of functions on -- remote machines with corresponding inputs of type a and returns the -- processes outputs, each of type b. The i-th process is supplied with -- the i-th input generating the i-th output. The number of processes (= -- length of output list) is defined by the shorter input list (thus one -- list may be infinite). spawnF :: (Trans a, Trans b) => [a -> b] -> [a] -> [b] -- | Same as spawn , but with an additional [Int] -- argument that specifies where to instantiate the processes. spawnAt :: (Trans a, Trans b) => [Int] -> [Process a b] -> [a] -> [b] -- | Same as spawnF , but with an additional [Int] -- argument that specifies where to instantiate the processes. spawnFAt :: (Trans a, Trans b) => [Int] -> [a -> b] -> [a] -> [b] -- | Instantiates a process on a remote machine, sends the input of type a -- and returns the process output of type b in the parallel action monad, -- thus it can be combined to a larger parallel action. instantiate :: (Trans a, Trans b) => Process a b -> a -> PA b -- | Instantiates a process defined by the given function on a remote -- machine, sends the input of type a and returns the process output of -- type b in the parallel action monad, thus it can be combined to a -- larger parallel action. instantiateF :: (Trans a, Trans b) => (a -> b) -> a -> PA b -- | Instantiation with explicit placement (see instantiate). instantiateAt :: (Trans a, Trans b) => Int -> Process a b -> a -> PA b -- | Instantiation with explicit placement (see instantiate). instantiateFAt :: (Trans a, Trans b) => Int -> (a -> b) -> a -> PA b -- | Trans class: overloads communication for streams and tuples. You need -- to declare normal-form evaluation in an instance declaration of -- NFData. Use the default implementation for write and -- createComm for instances of Trans. class NFData a => Trans a where write x = rdeepseq x `pseq` sendData Data x createComm = do { (cx, x) <- createC; return (Comm (sendVia cx), x) } write :: Trans a => a -> IO () createComm :: Trans a => IO (ChanName a, a) -- | Number of (logical) machines in the system noPe :: Int -- | Local machine number (ranges from 1 to noPe) selfPe :: Int type RD a = ChanName (ChanName a) -- | Converts local data into corresponding remote data. release :: Trans a => a -> RD a -- | Converts local data into corresponding remote data. The result is in -- the parallel action monad and can be combined to a larger parallel -- action. releasePA :: Trans a => a -> PA (RD a) -- | This establishes a direct connection to the process which released the -- data in the first place. Notice that you have to fetch a remote value -- exactly once! fetch :: Trans a => RD a -> a -- | This establishes a direct connection to the process which released the -- data in the first place. The result is in the parallel action monad -- and can be combined to a larger parallel action. Notice that you have -- to fetch a remote value exactly once! fetchPA :: Trans a => RD a -> PA a -- | Transforms a list of local data into a corresponding remote data list. releaseAll :: Trans a => [a] -> [RD a] -- | Transforms a list of remote data into a corresponding local data list. -- map fetch would wait for each list element until fetching the -- next one. Function fetchAll blocks only on partial defined -- list structure, not on content. fetchAll :: Trans a => [RD a] -> [a] -- | Function liftRD is used to lift functions acting on normal -- data to function performing the same computation on Remote Data. liftRD :: (Trans a, Trans b) => (a -> b) -> RD a -> RD b -- | see liftRD liftRD2 :: (Trans a, Trans b, Trans c) => (a -> b -> c) -> RD a -> RD b -> RD c -- | see liftRD liftRD3 :: (Trans a, Trans b, Trans c, Trans d) => (a -> b -> c -> d) -> RD a -> RD b -> RD c -> RD d -- | see liftRD liftRD4 :: (Trans a, Trans b, Trans c, Trans d, Trans e) => (a -> b -> c -> d -> e) -> RD a -> RD b -> RD c -> RD d -> RD e -- | A channel name ChanName a is a handle for a reply channel. -- The channel can be created with the function new and you can connect -- to such a channel with the function parfill. type ChanName a = Comm a -- | A channel can be created with the function new (this is an unsafe side -- effect!). It takes a function, whose first parameter is the channel -- name ChanName a and whose second parameter is the value of -- type a that will be received lazily in the future. The -- ChanName and the value of type a can be used in the body of -- the parameter function to create the output of type b. The -- output of the parameter function will be forwarded to the output of -- new . -- -- Example: new (channame val -> (channame,val)) returns the -- tuple (channame, value) . new :: Trans a => (ChanName a -> a -> b) -> b -- | You can connect to a reply channel with function parfill -- (this is an unsafe side effect!). The first parameter is the name of -- the channel, the second parameter is the value to be send. The third -- parameter will be the functions result after the concurrent sending -- operation is initiated. The sending operation will be triggered as -- soon as the result of type b is demanded. Take care that the -- demand for the result of parfill does not depend on the sent -- value, as this will create a deadlock. parfill :: Trans a => ChanName a -> a -> b -> b -- | Non-deterministically merges a list of lists (usually input -- streams) into a single list. The order of the output list is -- determined by the availability of the inner lists constructors. -- (Function merge is defined using Concurrent Haskell's function -- nmergeIO) merge :: [[a]] -> [a] -- | same as merge mergeProc :: [[a]] -> [a] data Lift a Lift :: a -> Lift a deLift :: Lift a -> a createProcess :: (Trans a, Trans b) => Process a b -> a -> Lift b cpAt :: (Trans a, Trans b) => Int -> Process a b -> a -> Lift b -- | A class of types that can be fully evaluated. class NFData a rnf :: NFData a => a -> () -- | The type Strategy a is a -> (). Thus, a -- strategy is a function whose sole purpose it is to evaluate its -- argument (either in full or in part). type Strategy a = a -> () -- | Evaluate a value using the given strategy. using :: a -> Strategy a -> a -- | r0 performs *no* evaluation. r0 :: Strategy a -- | rseq evaluates its argument to weak head normal form. rseq :: Strategy a -- | rdeepseq fully evaluates its argument. Relies on class -- NFData from module Control.DeepSeq. rdeepseq :: NFData a => Strategy a -- | Evaluate each element of a list according to the given strategy. This -- function is a specialisation of seqFoldable to lists. seqList :: Strategy a -> Strategy [a] -- | Evaluate the elements of a foldable data structure according to the -- given strategy. seqFoldable :: Foldable t => Strategy a -> Strategy (t a) -- | Semantically identical to seq, but with a subtle operational -- difference: seq is strict in both its arguments, so the -- compiler may, for example, rearrange a `seq` b into -- b `seq` a `seq` b. This is normally no problem -- when using seq to express strictness, but it can be a problem -- when annotating code for parallelism, because we need more control -- over the order of evaluation; we may want to evaluate a -- before b, because we know that b has already been -- sparked in parallel with par. -- -- This is why we have pseq. In contrast to seq, -- pseq is only strict in its first argument (as far as the -- compiler is concerned), which restricts the transformations that the -- compiler can do, and ensures that the user can retain control of the -- evaluation order. pseq :: a -> b -> b instance (Trans a, Trans b, Trans c, Trans d, Trans e, Trans f, Trans g, Trans h, Trans i) => Trans (a, b, c, d, e, f, g, h, i) instance (Trans a, Trans b, Trans c, Trans d, Trans e, Trans f, Trans g, Trans h) => Trans (a, b, c, d, e, f, g, h) instance (Trans a, Trans b, Trans c, Trans d, Trans e, Trans f, Trans g) => Trans (a, b, c, d, e, f, g) instance (Trans a, Trans b, Trans c, Trans d, Trans e, Trans f) => Trans (a, b, c, d, e, f) instance (Trans a, Trans b, Trans c, Trans d, Trans e) => Trans (a, b, c, d, e) instance (Trans a, Trans b, Trans c, Trans d) => Trans (a, b, c, d) instance (Trans a, Trans b, Trans c) => Trans (a, b, c) instance (Trans a, Trans b) => Trans (a, b) instance (NFData a, Trans a) => Trans (Comm a) instance Trans a => Trans [a] instance Trans () instance Trans a => Trans (Maybe a) instance Trans Bool instance Trans Integer instance Trans Char instance Trans Double instance Trans Float instance Trans Int instance NFData (Comm a) instance Monad PA