packages feed

abstract-par (empty) → 0.3

raw patch · 5 files changed

+296/−0 lines, 5 filesdep +basedep +deepseqsetup-changed

Dependencies added: base, deepseq

Files

+ Control/Monad/Par/Class.hs view
@@ -0,0 +1,173 @@+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, CPP,+     FlexibleInstances, UndecidableInstances+  #-}+-- UndecidableInstances++{-|++    This module establishes a class hierarchy that captures the+    interface(s) for valid Par monads.  In particular, the functionality+    is split into layers: e.g. Futures vs. full IVars vs. Chans (Streams).  +    +    Not all Par monad schedulers must provide all functionality.++    For more documentation of the programming model, see  ++      * The "Control.Monad.Par" module in the @monad-par@ package.+      * The wiki/tutorial (<http://www.haskell.org/haskellwiki/Par_Monad:_A_Parallelism_Tutorial>)+      * The original paper (<http://www.cs.indiana.edu/~rrnewton/papers/haskell2011_monad-par.pdf>)+      * Tutorial slides (<http://community.haskell.org/~simonmar/slides/CUFP.pdf>)+      * Other slides: <http://www.cs.ox.ac.uk/ralf.hinze/WG2.8/28/slides/simon.pdf>, +                      <http://www.cs.indiana.edu/~rrnewton/talks/2011_HaskellSymposium_ParMonad.pdf>++ -}+--  ++module Control.Monad.Par.Class +  (  +  -- * Futures+    ParFuture(..)+  -- * IVars+  , ParIVar(..)+  +    -- RRN: Not releasing this interface until there is a nice implementation of it:+    --  Channels (Streams)+    --  , ParChan(..)++  , NFData()+  )+where++import Control.DeepSeq++--------------------------------------------------------------------------------++-- | @ParFuture@ captures the class of Par monads which support+--   futures.  This level of functionality subsumes @par@/@pseq@ and is+--   similar to the "Control.Parallel.Strategies.Eval" monad.+-- +--   A minimal implementation consists of `spawn_` and `get`.+--   However, for monads that are also a member of `ParIVar` it is+--   typical to simply define `spawn` in terms of `fork`, `new`, and `put`.+class Monad m => ParFuture future m | m -> future where+  -- | Create a potentially-parallel computation, and return a /future/+  -- (or /promise/) that can be used to query the result of the forked+  -- computataion.  +  --+  -- >  spawn p = do+  -- >    r <- new+  -- >    fork (p >>= put r)+  -- >    return r+  --+  spawn  :: NFData a => m a -> m (future a)+  +  -- | Like 'spawn', but the result is only head-strict, not fully-strict.+  spawn_ :: m a -> m (future a)+  get    :: future a -> m a++  -- | Spawn a pure (rather than monadic) computation.  Fully-strict.+  -- +  -- >  spawnP = spawn . return+  spawnP :: NFData a =>   a -> m (future a)+  +  -- Default implementations:+  spawn  p = spawn_ (do x <- p; deepseq x (return x))+  spawnP a = spawn (return a)+++--------------------------------------------------------------------------------++-- | @ParIVar@ builds on futures by adding full /anyone-writes, anyone-reads/ IVars.+--   These are more expressive but may not be supported by all distributed schedulers.+-- +-- A minimal implementation consists of `fork`, `put_`, and `new`.+class ParFuture ivar m  => ParIVar ivar m | m -> ivar where+  -- | Forks a computation to happen in parallel.  The forked+  -- computation may exchange values with other computations using+  -- @IVar@s.+  fork :: m () -> m ()+  +  -- | creates a new @IVar@+  new  :: m (ivar a)+  +  -- | put a value into a @IVar@.  Multiple 'put's to the same @IVar@+  -- are not allowed, and result in a runtime error.+  --+  -- 'put' fully evaluates its argument, which therefore must be an+  -- instance of 'NFData'.  The idea is that this forces the work to+  -- happen when we expect it, rather than being passed to the consumer+  -- of the @IVar@ and performed later, which often results in less+  -- parallelism than expected.+  --+  -- Sometimes partial strictness is more appropriate: see 'put_'.+  --+  put  :: NFData a => ivar a -> a -> m ()+  put v a = deepseq a (put_ v a)+  +  -- | like 'put', but only head-strict rather than fully-strict.  +  put_ :: ivar a -> a -> m ()++  -- Extra API routines that have default implementations:+  +  -- | creates a new @IVar@ that contains a value+  newFull :: NFData a => a -> m (ivar a)+  newFull a = deepseq a (newFull_ a)+  +  -- | creates a new @IVar@ that contains a value (head-strict only)+  newFull_ ::  a -> m (ivar a)+  newFull_ a = do v <- new+                  -- This is usually inefficient! +		  put_ v a+		  return v++--------------------------------------------------------------------------------  ++-- class ParYieldable ?? +  -- TODO: I think we should add yield officially:++  -- Allows other parallel computations to progress.  (should not be+  -- necessary in most cases).+  --  yield  :: m ()+++--------------------------------------------------------------------------------++-- | @ParChan@ provides communication via streams of values between+--   computations in a Par monad.  Channels in this case are split+--   into separate send and receive ports.+--+--   The critical thing to know about @Chan@s in @Par@ monads is that+--   while the @recv@ method destructively advances the position of+--   the consumer's \"cursor\" in the stream, this is only observable+--   in the /local/ @Par@ thread.  That is, at @fork@ points it is+--   necessary to give the child computation a separate set of stream+--   cursors so that it observes the same sequences as the parent.+class Monad m => ParChan snd rcv m | m -> snd, m -> rcv where+   -- | Create a new communication channel, with separate send and receive ports.+   newChan :: m (snd a, rcv a)+   -- | Receive a message on a channel in a synchronous, blocking manner.+   recv    :: rcv a -> m a+   -- | Send a message on a channel.  This may or may not block.+   send    :: snd a -> a -> m ()+++----------------------------------------------------------------------------------------------------++-- t1 :: P.Par Int+-- If the ParIVar => ParFuture instance exists the following is sufficient:+t1 :: (ParFuture v m) => m Int+t1 = do +  x <- spawn (return 3)+  get x++t2 :: (ParIVar v m) => m Int+t2 = do +  x <- new+  put x "hi"+  return 3+++-- TODO: SPECIALIZE generic routines for the default par monad (and possibly ParRNG)?++--  SPECIALISE parMap  :: (NFData b) => (a -> b)     -> [a] -> Par [b] +-- SPECIALISE parMapM :: (NFData b) => (a -> Par b) -> [a] -> Par [b] 
+ Control/Monad/Par/Unsafe.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}+-- TODO: ADD Unsafe++-- | Unsafe operations.  NOT part of "Safe Haskell".+-- +-- These are "unsafe" (in the normal, Haskell sense) when used with a+-- "runPar" of type `Par a -> a`.  If used with a `runParIO` that+-- stays in the IO monad, then they are simply dangerous.+-- +-- For the purposes of Safe Haskell, any module that imports this+-- module becomes untrustworthy.++module Control.Monad.Par.Unsafe +  (+   ParUnsafe(..)+  ) +where++-- import Control.Monad.Par.Class++-- | The class of Par monads that provide unsafe functionality.+class ParUnsafe iv p | p -> iv where +  -- | Peek at the current contents of an 'IVar' in a nonblocking way.+  unsafePeek   :: iv a -> p (Maybe a)++  -- | Attempt to put a value into an 'IVar'.  If successful, return the+  --   value put.  If something is already there, return it instead.+  unsafeTryPut :: iv a -> a -> p a++  -- | Lift an 'IO' operation into the Par monad.+  unsafeParIO  :: IO a -> p a++-- Aside:+-- If the need ever arises we could also consider unsafeMultiplePut that+-- would be able to change the current value of an IVar.  It could+-- cause big problems in the distributed case, however.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Simon Marlow 2011++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Simon Marlow nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+import Distribution.Simple+main = defaultMain
+ abstract-par.cabal view
@@ -0,0 +1,54 @@+Name:                abstract-par+Version:             0.3+Synopsis:            Type classes generalizing the functionality of the 'monad-par' library.+++-- Version history:++--  0.3      : Factored out of monad-par package.+++Description:         The 'Par' monad(s) offer an alternative +                     parallel programming API to that provided by the +                     @parallel@ package.++                     A 'Par' monad allows the simple description of+                     parallel computations, and can be used to add+                     parallelism to pure Haskell code.  The basic API+                     is straightforward: a @Par@ monad supports forking+                     and simple communication in terms of 'IVar's.++                     This module is an interface module only. It+                     provides a number of type clasess, but not an+                     implementation.  The type classes separate different +                     levels of @Par@ functionality.  See the +                     "Control.Monad.Par.Class" module for more details.++                     The 'monad-par' library is one example of a+                     concrete library providing this interface.+++Homepage:            https://github.com/simonmar/monad-par+License:             BSD3+License-file:        LICENSE+Author:              Ryan Newton+Maintainer:          Ryan Newton <rrnewton@gmail.com>+Copyright:           (c) Ryan Newton 2011-2012+Stability:           Experimental+Category:            Control,Parallelism,Monads+Build-type:          Simple+Cabal-version:       >=1.8++extra-source-files:+++Library+  Exposed-modules: +                 -- A class generalizing different levels of monad-par functionality:+                   Control.Monad.Par.Class++                 -- A class providing unsafe functionality:+                 , Control.Monad.Par.Unsafe++  Build-depends: base >= 4 && < 5+               , deepseq >= 1.2