packages feed

dph-base 0.5.1.1 → 0.6.0.1

raw patch · 13 files changed

+433/−660 lines, 13 filesdep +prettydep ~arraydep ~basedep ~vectorPVP ok

version bump matches the API change (PVP)

Dependencies added: pretty

Dependency ranges changed: array, base, vector

API changes (from Hackage documentation)

- Data.Array.Parallel.Base: class Read a
- Data.Array.Parallel.Base: readApp :: Read a => String -> ReadPrec a
- Data.Array.Parallel.Base: readList :: Read a => ReadS [a]
- Data.Array.Parallel.Base: readListPrec :: Read a => ReadPrec [a]
- Data.Array.Parallel.Base: readPrec :: Read a => ReadPrec a
- Data.Array.Parallel.Base: readsApp :: Read a => Int -> String -> ReadS a
- Data.Array.Parallel.Base: readsPrec :: Read a => Int -> ReadS a
- Data.Array.Parallel.Base: showsApp :: Show a => Int -> String -> a -> ShowS
- Data.Array.Parallel.Stream: appendSS :: Stream Int -> Stream a -> Stream Int -> Stream a -> Stream a
- Data.Array.Parallel.Stream: combine2ByTagS :: Stream Tag -> Stream a -> Stream a -> Stream a
- Data.Array.Parallel.Stream: combineSS :: Stream Bool -> Stream Int -> Stream a -> Stream Int -> Stream a -> Stream a
- Data.Array.Parallel.Stream: enumFromStepLenEachS :: Int -> Stream (Int, Int, Int) -> Stream Int
- Data.Array.Parallel.Stream: enumFromToEachS :: Int -> Stream (Int, Int) -> Stream Int
- Data.Array.Parallel.Stream: fold1SS :: (a -> a -> a) -> Stream Int -> Stream a -> Stream a
- Data.Array.Parallel.Stream: foldSS :: (a -> b -> a) -> a -> Stream Int -> Stream b -> Stream a
- Data.Array.Parallel.Stream: foldValuesR :: (a -> b -> a) -> a -> Int -> Stream b -> Stream a
- Data.Array.Parallel.Stream: indexedS :: Stream a -> Stream (Int, a)
- Data.Array.Parallel.Stream: indicesSS :: Int -> Int -> Stream Int -> Stream Int
- Data.Array.Parallel.Stream: interleaveS :: Stream a -> Stream a -> Stream a
- Data.Array.Parallel.Stream: replicateEachRS :: Int -> Stream a -> Stream a
- Data.Array.Parallel.Stream: replicateEachS :: Int -> Stream (Int, a) -> Stream a
+ Data.Array.Parallel.Array: append :: Array a e => a e -> a e -> a e
+ Data.Array.Parallel.Array: class Array a e
+ Data.Array.Parallel.Array: fromList :: Array a e => [e] -> a e
+ Data.Array.Parallel.Array: fromVector :: Array a e => Vector e -> a e
+ Data.Array.Parallel.Array: fromVectors1 :: Array a e => Vector e -> a e
+ Data.Array.Parallel.Array: fromVectors2 :: (Array a1 (a2 e), Array a2 e) => Vector (Vector e) -> a1 (a2 e)
+ Data.Array.Parallel.Array: fromVectors3 :: (Array a1 (a2 (a3 e)), Array a2 (a3 e), Array a3 e) => Vector (Vector (Vector e)) -> a1 (a2 (a3 e))
+ Data.Array.Parallel.Array: index :: Array a e => a e -> Int -> e
+ Data.Array.Parallel.Array: instance Array Vector e
+ Data.Array.Parallel.Array: instance Array [] e
+ Data.Array.Parallel.Array: length :: Array a e => a e -> Int
+ Data.Array.Parallel.Array: singleton :: Array a e => e -> a e
+ Data.Array.Parallel.Array: toList :: Array a e => a e -> [e]
+ Data.Array.Parallel.Array: toVector :: Array a e => a e -> Vector e
+ Data.Array.Parallel.Array: toVectors1 :: Array a e => a e -> Vector e
+ Data.Array.Parallel.Array: toVectors2 :: (Array a1 (a2 e), Array a2 e) => a1 (a2 e) -> Vector (Vector e)
+ Data.Array.Parallel.Array: toVectors3 :: (Array a1 (a2 (a3 e)), Array a2 (a3 e), Array a3 e) => a1 (a2 (a3 e)) -> Vector (Vector (Vector e))
+ Data.Array.Parallel.Array: valid :: Array a e => a e -> Bool
+ Data.Array.Parallel.Base: checkSlice :: String -> Int -> Int -> Int -> a -> a
+ Data.Array.Parallel.Base: debug :: Bool
+ Data.Array.Parallel.Base: debugCritical :: Bool
+ Data.Array.Parallel.Base: tracePrimEnabled :: Bool
+ Data.Array.Parallel.Base.Text: class Read a
+ Data.Array.Parallel.Base.Text: readApp :: Read a => String -> ReadPrec a
+ Data.Array.Parallel.Base.Text: readList :: Read a => ReadS [a]
+ Data.Array.Parallel.Base.Text: readListPrec :: Read a => ReadPrec [a]
+ Data.Array.Parallel.Base.Text: readPrec :: Read a => ReadPrec a
+ Data.Array.Parallel.Base.Text: readsApp :: Read a => Int -> String -> ReadS a
+ Data.Array.Parallel.Base.Text: readsPrec :: Read a => Int -> ReadS a
+ Data.Array.Parallel.Base.Text: showsApp :: Show a => Int -> String -> a -> ShowS
+ Data.Array.Parallel.Pretty: class PprPhysical a
+ Data.Array.Parallel.Pretty: class PprVirtual a
+ Data.Array.Parallel.Pretty: instance (PprPhysical a, PprPhysical b) => PprPhysical (a, b)
+ Data.Array.Parallel.Pretty: instance PprPhysical Bool
+ Data.Array.Parallel.Pretty: instance PprPhysical Double
+ Data.Array.Parallel.Pretty: instance PprPhysical Int
+ Data.Array.Parallel.Pretty: instance PprPhysical a => PprPhysical (Vector a)
+ Data.Array.Parallel.Pretty: instance PprVirtual Bool
+ Data.Array.Parallel.Pretty: instance PprVirtual Double
+ Data.Array.Parallel.Pretty: instance PprVirtual Int
+ Data.Array.Parallel.Pretty: pprp :: PprPhysical a => a -> Doc
+ Data.Array.Parallel.Pretty: pprv :: PprVirtual a => a -> Doc

Files

+ Data/Array/Parallel/Array.hs view
@@ -0,0 +1,121 @@++-- | Generic array class.+--   This is used as a compatability layer during testing and debugging.+module Data.Array.Parallel.Array +        ( Array(..)+        , fromList, toList+        , toVectors1,   toVectors2,   toVectors3+        , fromVectors1, fromVectors2, fromVectors3)+where   +import Control.Monad+import Data.Vector              (Vector)+import qualified Data.Vector    as V+import qualified Prelude        as P+import Prelude                  hiding (length)+++class Array a e where+ -- | Check whether an array has a valid internal representation.+ valid      :: a e -> Bool++ -- | Yield an array with just a single element.+ singleton  :: e   -> a e++ -- | Append two arrays.+ append     :: a e -> a e -> a e++ -- | Yield the length of an array.+ length     :: a e -> Int++ -- | Retrieve the element at the given index. + index      :: a e -> Int -> e++ -- | Convert an array to a vector.+ toVector   :: a e -> Vector e++ -- | Convert a vector to an array.+ fromVector :: Vector e -> a e+ ++instance Array [] e where+ valid          = const True+ singleton x    = [x]+ length         = P.length+ index          = (P.!!)+ append         = (P.++)+ toVector       = V.fromList+ fromVector     = V.toList+ ++instance Array Vector e where+ valid          = const True+ singleton      = V.singleton+ length         = V.length+ index          = (V.!)+ append         = (V.++)+ toVector       = id+ fromVector     = id+++-- | Convert a list to an array.+fromList :: Array a e => [e] -> a e+fromList = fromVector . V.fromList+++-- | Convert an array to a list.+toList   :: Array a e => a e -> [e]+toList   = V.toList . toVector+++-- | Convert the outer level of an array to vectors.+toVectors1 +        :: Array a e+        => a e -> Vector e++toVectors1 arr+        = toVector arr+        +        +-- | Convert the outer two levels of an array to vectors.+toVectors2 +        :: (Array a1 (a2 e), Array a2 e)+        => a1 (a2 e) -> Vector (Vector e)++toVectors2 = V.map toVector . toVector+        ++-- | Convert the outer three levels of an array to vectors.+toVectors3+        :: (Array a1 (a2 (a3 e)), Array a2 (a3 e), Array a3 e)+        => a1 (a2 (a3 e)) -> Vector (Vector (Vector e))++toVectors3 = V.map (V.map toVector) . V.map toVector . toVector +        ++-- | Convert some vectors to an array.+fromVectors1 +        :: Array a e+        => Vector e -> a e++fromVectors1 vec+        = fromVector vec+        ++-- | Convert some vectors to a nested array+fromVectors2 +        :: (Array a1 (a2 e), Array a2 e)+        => Vector (Vector e) -> a1 (a2 e)++fromVectors2+        = fromVector . V.map fromVector+++-- | Convert some vectors to a triply nested array+fromVectors3 +        :: (Array a1 (a2 (a3 e)), Array a2 (a3 e), Array a3 e)+        => Vector (Vector (Vector e)) -> a1 (a2 (a3 e))++fromVectors3+        = fromVector . V.map fromVector . V.map (V.map fromVector)++   
Data/Array/Parallel/Base.hs view
@@ -1,25 +1,18 @@--- | Basic functionality, imported by most modules.-module Data.Array.Parallel.Base (-  -- * Debugging infrastructure-  module Data.Array.Parallel.Base.Debug,--  -- * Data constructor tags-  module Data.Array.Parallel.Base.Util,+-- | Common config and debugging functions. Imported by most modules.+module Data.Array.Parallel.Base +        ( -- * Debugging infrastructure+          module Data.Array.Parallel.Base.Config+        , module Data.Array.Parallel.Base.Debug -  -- * Utils for defining Read\/Show instances.-  module Data.Array.Parallel.Base.Text,+          -- * Data constructor rags+        , module Data.Array.Parallel.Base.Tag -  -- * Tracing infrastructure-  module Data.Array.Parallel.Base.DTrace,-  module Data.Array.Parallel.Base.TracePrim,-  -  -- * ST monad re-exported from GHC-  ST(..), runST-) where+          -- * ST monad re-exported from GHC+        , ST(..)+        , runST)+where import Data.Array.Parallel.Base.Debug-import Data.Array.Parallel.Base.Util-import Data.Array.Parallel.Base.Text-import Data.Array.Parallel.Base.DTrace-import Data.Array.Parallel.Base.TracePrim+import Data.Array.Parallel.Base.Config+import Data.Array.Parallel.Base.Tag import GHC.ST (ST(..), runST) 
Data/Array/Parallel/Base/Config.hs view
@@ -1,11 +1,10 @@ -- | Top level hard-wired configuration flags. --   TODO: This should be generated by the make system-module Data.Array.Parallel.Base.Config (-    debug-  , debugCritical-  , tracePrimEnabled-) where-+module Data.Array.Parallel.Base.Config+        ( debugCritical+        , debug+        , tracePrimEnabled)+where  -- | Enable internal consistency checks for operations that could --   corrupt the heap.@@ -20,8 +19,8 @@ debug                   = False  --- | Print tracing information for each DPH primitive to console.---   The tracing hooks are in dph-prim-par/D/A/P/Unlifted.hs+-- | Print tracing information for each flat array primitive to console.+--   The tracing hooks are in `dph-prim-par:Data.Array.Parallel.Unlifted` tracePrimEnabled        :: Bool tracePrimEnabled        = False 
Data/Array/Parallel/Base/Debug.hs view
@@ -1,31 +1,48 @@ -- | Debugging infrastructure for the parallel arrays library.-module Data.Array.Parallel.Base.Debug (-    check-  , checkCritical-  , checkLen-  , checkEq-  , checkNotEmpty-  , uninitialised-) where+module Data.Array.Parallel.Base.Debug +        ( check+        , checkCritical+        , checkLen+        , checkSlice+        , checkEq+        , checkNotEmpty+        , uninitialised)+where import Data.Array.Parallel.Base.Config  (debug, debugCritical) -outOfBounds :: String -> Int -> Int -> a-outOfBounds loc n i = error $ loc ++ ": Out of bounds (size = "-                              ++ show n ++ "; index = " ++ show i ++ ")" +-- | Throw an index-out-of-bounds error.+errorOfBounds :: String -> Int -> Int -> a+errorOfBounds loc n i +        =  error $ loc ++ ": Out of bounds "+                ++ "(vector length = "  ++ show n +                ++ "; index = "         ++ show i ++ ")"+++-- | Throw a bad slice error.+errorBadSlice :: String -> Int -> Int -> Int -> a+errorBadSlice loc vecLen sliceStart sliceLen+        = error $ loc ++ ": Bad slice "+                ++ "(vecLen = "         ++ show vecLen+                ++ "; sliceStart = "    ++ show sliceStart+                ++ "; sliceLen = "     ++ show sliceLen ++ ")"++ -- | Bounds check, enabled when `debug` = `True`. --  --   The first integer is the length of the array, and the second---   is the index. The second must be greater or equal to '0' and less than the---   first integer. If the not then `error` with the `String`.+--   is the index. The second must be greater or equal to '0' and less than+--   the first integer. If the not then `error` with the `String`. -- check :: String -> Int -> Int -> a -> a-{-# INLINE check #-} check loc n i v -  | debug      = if (i >= 0 && i < n) then v else outOfBounds loc n i+  | debug      +  = if i >= 0 && i < n+        then v +        else errorOfBounds loc n i+   | otherwise  = v--- FIXME: Interestingly, ghc seems not to be able to optimise this if we test---	  for `not debug' (it doesn't inline the `not'...)+{-# INLINE check #-}   -- | Bounds check, enabled when `debugCritical` = `True`.@@ -33,14 +50,18 @@ --   This version is used to check operations that could corrupt the heap. --  --   The first integer is the length of the array, and the second---   is the index. The second must be greater or equal to '0' and less than the---   first integer. If the not then `error` with the `String`.+--   is the index. The second must be greater or equal to '0' and less than+--   the first integer. If the not then `error` with the `String`. -- checkCritical :: String -> Int -> Int -> a -> a-{-# INLINE checkCritical #-} checkCritical loc n i v -  | debugCritical = if (i >= 0 && i < n) then v else outOfBounds loc n i+  | debugCritical +  = if i >= 0 && i < n+        then v +        else errorOfBounds loc n i+   | otherwise     = v+{-# INLINE checkCritical #-}   -- | Length check, enabled when `debug` = `True`.@@ -49,42 +70,71 @@ --   than the first integer. If the not then `error` with the `String`. -- checkLen :: String -> Int -> Int -> a -> a-{-# INLINE checkLen #-} checkLen loc n i v -  | debug      = if (i >= 0 && i <= n) then v else outOfBounds loc n i+  | debug      +  = if i >= 0 && i <= n +        then v +        else errorOfBounds loc n i+   | otherwise  = v+{-# INLINE checkLen #-}  +-- | Slice check, enable when `debug` = `True`.+--+--   The vector must contain at least `sliceStart` + `sliceLen` elements.+-- +checkSlice :: String -> Int -> Int -> Int -> a -> a+checkSlice loc vecLen sliceStart sliceLen v+  | debug        +  = if   (  sliceStart >= 0             && sliceStart            <= vecLen+         && sliceStart + sliceLen >= 0  && sliceStart + sliceLen <= vecLen )+        then v+        else errorBadSlice loc vecLen sliceStart sliceLen++  | otherwise    = v+{-# INLINE checkSlice #-}++ -- | Equality check, enabled when `debug` = `True`. --    --   The two `a` values must be equal, else `error`. -----   The first `String` gives the location of the error, and the second some helpful message.+--   The first `String` gives the location of the error,+--   and the second some helpful message. -- checkEq :: (Eq a, Show a) => String -> String -> a -> a -> b -> b checkEq loc msg x y v-  | debug     = if x == y then v else err-  | otherwise = v-  where-    err = error $ loc ++ ": " ++ msg+  | debug     +  = if x == y +        then v +        else error $ loc ++ ": " ++ msg                   ++ " (first = " ++ show x                   ++ "; second = " ++ show y ++ ")" +  | otherwise = v+{-# INLINE checkEq #-} + -- | Given an array length, check it is not zero. checkNotEmpty :: String -> Int -> a -> a checkNotEmpty loc n v-  | debug     = if n /= 0 then v else err+  | debug     +  = if n /= 0 +        then v +        else error $ loc ++ ": Empty array"+   | otherwise = v-  where-    err = error $ loc ++ ": Empty array"+{-# INLINE checkNotEmpty #-}   -- | Throw an error saying something was not intitialised. --   ---   The `String` must contain a helpful message saying what module the error occured in, ---   and the possible reasons for it. If not then a puppy dies at compile time.+--   The `String` must contain a helpful message saying what module+--   the error occured in, and the possible reasons for it.+--   If not then a puppy dies at compile time. -- uninitialised :: String -> a-uninitialised loc = error $ loc ++ ": Touched an uninitialised value"+uninitialised loc +        = error $ loc ++ ": Touched an uninitialised value" 
+ Data/Array/Parallel/Base/Tag.hs view
@@ -0,0 +1,41 @@++-- | Data constructor tags.+module Data.Array.Parallel.Base.Tag +        ( Tag+        , tagToInt, intToTag+        , fromBool, toBool)+where+++-- | Given a value of an algebraic type, the tag tells us what+--   data constructor was used to create it.+type Tag = Int+++-- | Convert a `Tag` to an `Int`. This is identity at the value level.+tagToInt :: Tag -> Int+tagToInt = id+{-# INLINE tagToInt #-}+++-- | Convert an `Int` to a `Tag`. This is identity at the value level.+intToTag :: Int -> Tag+intToTag = id+{-# INLINE intToTag #-}+++-- | Get the `Tag` of a `Bool` value. `False` is 0, `True` is 1.+fromBool :: Bool -> Tag+fromBool False = 0+fromBool True  = 1+{-# INLINE fromBool #-}+++-- | Convert a `Tag` to a `Bool` value.+toBool :: Tag -> Bool+toBool n | n == 0    = False+         | otherwise = True+{-# INLINE toBool #-}+++
Data/Array/Parallel/Base/Text.hs view
@@ -1,20 +1,24 @@ -- | Utilities for defining Read\/Show instances.-module Data.Array.Parallel.Base.Text (-  showsApp, readApp, readsApp,-  Read(..)-) where+module Data.Array.Parallel.Base.Text +        ( showsApp+        , readApp+        , readsApp+        , Read(..))+where import Text.Read + showsApp :: Show a => Int -> String -> a -> ShowS-showsApp k fn arg = showParen (k>10) -                    (showString fn . showChar ' ' . showsPrec 11 arg)+showsApp k fn arg +        = showParen (k>10) +          (showString fn . showChar ' ' . showsPrec 11 arg)  readApp :: Read a => String -> ReadPrec a-readApp fn = parens (prec 10 $-  do-    Ident ide <- lexP-    if ide /= fn then pfail else step readPrec-  )+readApp fn + = parens $ prec 10 + $ do   Ident ide <- lexP+        if ide /= fn then pfail else step readPrec+  readsApp :: Read a => Int -> String -> ReadS a readsApp k fn = readPrec_to_S (readApp fn) k
Data/Array/Parallel/Base/TracePrim.hs view
@@ -1,5 +1,5 @@--- | When `tracePrimEnabled` in "Data.Array.Parallel.Config" is @True@, DPH programs will print---   out what array primitives they're using at runtime. See `tracePrim` for details.+-- | When `tracePrimEnabled`, DPH programs will print out what flat array+--   primitives they're using at runtime. See `tracePrim` for details. module Data.Array.Parallel.Base.TracePrim         ( tracePrim         , TracePrim(..))@@ -7,12 +7,13 @@ import Data.Array.Parallel.Base.Config import qualified Debug.Trace + -- | Print tracing information to console. -- --    This function is used to wrap the calls to DPH primitives defined --    in @dph-prim-par@:"Data.Array.Parallel.Unlifted" -----    Tracing is only enabled when `tracePrimEnabled` in "Data.Array.Parallel.Base.Config"  is `True`,+--    Tracing is only enabled when `tracePrimEnabled` is `True`. --    otherwise it's a no-op. --    tracePrim :: TracePrim -> a -> a@@ -21,10 +22,13 @@  | otherwise            = x   --- | Records information about the use of a primitive operator.+-- | Records information about the use of a flat array primitive. -- --    These are the operator names that the vectoriser introduces.---    The actual implementation of each operator varies depending on what DPH backend we're using.+--+--    The actual implementation of each operator varies depending on what+--    DPH primitive library is being used.+-- --    We only trace operators that are at least O(n) in complexity.  data TracePrim         = TraceReplicate   { traceCount      :: Int}
− Data/Array/Parallel/Base/Util.hs
@@ -1,37 +0,0 @@---- | Constructor tags.-module Data.Array.Parallel.Base.Util (-  Tag, fromBool, toBool, tagToInt, intToTag-) where-import Data.Word ( Word8 )----- | Given a value of an algebraic type, the tag tells us what---   data constructor was used to create it.-type Tag = Int----- | Get the `Tag` of a `Bool` value. `False` is 0, `True` is 1.-{-# INLINE fromBool #-}-fromBool :: Bool -> Tag-fromBool False = 0-fromBool True  = 1----- | Convert a `Tag` to a `Bool` value.-{-# INLINE toBool #-}-toBool :: Tag -> Bool-toBool n | n == 0    = False-         | otherwise = True----- | Convert a `Tag` to an `Int`. This is identity at the value level.-{-# INLINE tagToInt #-}-tagToInt :: Tag -> Int-tagToInt = id---- | Convert an `Int` to a `Tag`. This is identity at the value level.-{-# INLINE intToTag #-}-intToTag :: Int -> Tag-intToTag = id-
+ Data/Array/Parallel/Pretty.hs view
@@ -0,0 +1,57 @@++-- | Pretty printer classes+module Data.Array.Parallel.Pretty+        ( module Text.PrettyPrint+        , PprPhysical(..)+        , PprVirtual (..))+where+import Text.PrettyPrint+import qualified Data.Vector            as V+import Data.Vector                      (Vector)+++-- | Pretty print the physical structure of data.+class PprPhysical a where+ pprp :: a -> Doc++instance PprPhysical Bool where+ pprp = text . show++instance PprPhysical Int where+ pprp = text . show + +instance PprPhysical Double where+ pprp = text . show + + +-- | Pretty print virtual \/ logical structure of data.+class PprVirtual a where+ pprv :: a -> Doc++instance PprVirtual Bool where+ pprv = text . show++instance PprVirtual Int where+ pprv = text . show + +instance PprVirtual Double where+ pprv = text . show +++-- Instances ------------------------------------------------------------------ +instance (PprPhysical a, PprPhysical b)+        => PprPhysical (a, b) where+ pprp (x, y)+  = vcat+        [ text "Tuple2"+        , nest 4 $ pprp x+        , nest 4 $ pprp y]++instance PprPhysical a+        => PprPhysical (Vector a) where+ pprp vec+        = brackets +        $ hcat+        $ punctuate (text ", ") +        $ V.toList $ V.map pprp vec+
− Data/Array/Parallel/Stream.hs
@@ -1,525 +0,0 @@--- | Stream functions not implemented in @Data.Vector@-#include "fusion-phases.h"--module Data.Array.Parallel.Stream (--  -- * Flat stream operators-  indexedS, replicateEachS, replicateEachRS,-  interleaveS, combine2ByTagS,-  enumFromToEachS, enumFromStepLenEachS,-  -  -- * Segmented stream operators-  foldSS, fold1SS, combineSS, appendSS,-  foldValuesR,-  indicesSS-) where-import Data.Array.Parallel.Base ( Tag )-import qualified Data.Vector.Fusion.Stream as S-import Data.Vector.Fusion.Stream.Monadic ( Stream(..), Step(..) )-import Data.Vector.Fusion.Stream.Size    ( Size(..) )---- TODO: The use of INLINE pragmas in some of these function isn't consistent.---       for indexedS and combine2ByTagS, there is an INLINE_INNER on the 'next'---       function, but replicateEachS uses a plain INLINE and fold1SS uses---       a hard INLINE [0]. Can we make a rule that all top-level stream functions---       in this module have INLINE_STREAM, and all 'next' functions have---       INLINE_INNER? If not we should document the reasons for the special cases.--------- Note: [NEVER ENTERED]--- ~~~~~~~~~~~~~~~~~~~~~---  Cases marked NEVER ENTERED should be unreachable, assuming there are no ---  bugs elsewhere in the library. We used to throw an error when these---  branches were entered, but this was confusing the simplifier. It would be ---  better if we could put the errors back, but we'll need to check that ---  performance does not regress when we do so.------- | Tag each element of an stream with its index in that stream.------ @--- indexed [42,93,13]---  = [(0,42), (1,93), (2,13)]--- @-indexedS :: S.Stream a -> S.Stream (Int,a)-{-# INLINE_STREAM indexedS #-}-indexedS (Stream next s n) = Stream next' (0,s) n-  where-    {-# INLINE_INNER next' #-}-    next' (i,s) = do-                    r <- next s-                    case r of-                      Yield x s' -> return $ Yield (i,x) (i+1,s')-                      Skip    s' -> return $ Skip        (i,s')-                      Done       -> return Done----- | Given a stream of pairs containing a count an an element,---   replicate element the number of times given by the count.------   The first parameter sets the size hint of the resulting stream.--- --- @--- replicateEach 10 [(2,10), (5,20), (3,30)]---   = [10,10,20,20,20,20,20,30,30,30]--- @-replicateEachS :: Int -> S.Stream (Int,a) -> S.Stream a-{-# INLINE_STREAM replicateEachS #-}-replicateEachS n (Stream next s _) =-  Stream next' (0,Nothing,s) (Exact n)-  where-    {-# INLINE next' #-}-    next' (0, _, s) =-      do-        r <- next s-        case r of-          Done           -> return Done-          Skip s'        -> return $ Skip (0, Nothing, s')-          Yield (k,x) s' -> return $ Skip (k, Just x,s')-    next' (k,Nothing,s) = return Done   -- NEVER ENTERED (See Note)-    next' (k,Just x,s)  = return $ Yield x (k-1,Just x,s)----- | Repeat each element in the stream the given number of times.------ @--- replicateEach 2 [10,20,30]---  = [10,10,20,20,30,30]--- @----replicateEachRS :: Int -> S.Stream a -> S.Stream a-{-# INLINE_STREAM replicateEachRS #-}-replicateEachRS !n (Stream next s sz)-  = Stream next' (0,Nothing,s) (sz `multSize` n)-  where-    next' (0,_,s) =-      do-        r <- next s-        case r of-          Done       -> return Done-          Skip    s' -> return $ Skip (0,Nothing,s')-          Yield x s' -> return $ Skip (n,Just x,s')-    next' (i,Nothing,s) = return Done -- NEVER ENTERED (See Note)-    next' (i,Just x,s) = return $ Yield x (i-1,Just x,s)----- | Multiply a size hint by a scalar.-multSize :: Size -> Int -> Size-multSize (Exact n) k = Exact (n*k)-multSize (Max   n) k = Max   (n*k)-multSize Unknown   _ = Unknown----- | Interleave the elements of two streams. We alternate between the first---   and second streams, stopping when we can't find a matching element.------ @--- interleave [2,3,4] [10,20,30] = [2,10,3,20,4,30]--- interleave [2,3]   [10,20,30] = [2,10,3,20]--- interleave [2,3,4] [10,20]    = [2,10,3,20,4]--- @----interleaveS :: S.Stream a -> S.Stream a -> S.Stream a-{-# INLINE_STREAM interleaveS #-}-interleaveS (Stream next1 s1 n1) (Stream next2 s2 n2)-  = Stream next (False,s1,s2) (n1+n2)-  where-    {-# INLINE next #-}-    next (False,s1,s2) =-      do-        r <- next1 s1-        case r of-          Yield x s1' -> return $ Yield x (True ,s1',s2)-          Skip    s1' -> return $ Skip    (False,s1',s2)-          Done        -> return Done--    next (True,s1,s2) =-      do-        r <- next2 s2-        case r of-          Yield x s2' -> return $ Yield x (False,s1,s2')-          Skip    s2' -> return $ Skip    (True ,s1,s2')-          Done        -> return Done -- NEVER ENTERED (See Note)----- | Combine two streams, using a tag stream to tell us which of the data---   streams to take the next element from.------   If there are insufficient elements in the data strams for the provided---   tag stream then `error`.---  --- @--- combine2ByTag [0,1,1,0,0,1] [1,2,3] [4,5,6]---  = [1,4,5,2,3,6]--- @----combine2ByTagS :: S.Stream Tag -> S.Stream a -> S.Stream a -> S.Stream a-{-# INLINE_STREAM combine2ByTagS #-}-combine2ByTagS (Stream next_tag s m) (Stream next0 s0 _)-                                     (Stream next1 s1 _)-  = Stream next (Nothing,s,s0,s1) m-  where-    {-# INLINE_INNER next #-}-    next (Nothing,s,s0,s1)-      = do-          r <- next_tag s-          case r of-            Done       -> return Done-            Skip    s' -> return $ Skip (Nothing,s',s0,s1)-            Yield t s' -> return $ Skip (Just t, s',s0,s1)--    next (Just 0,s,s0,s1)-      = do-          r <- next0 s0-          case r of-            Done        -> error "combine2ByTagS: stream 1 too short"-            Skip    s0' -> return $ Skip    (Just 0, s,s0',s1)-            Yield x s0' -> return $ Yield x (Nothing,s,s0',s1)--    next (Just t,s,s0,s1)-      = do-          r <- next1 s1-          case r of-            Done        -> error "combine2ByTagS: stream 2 too short"-            Skip    s1' -> return $ Skip    (Just t, s,s0,s1')-            Yield x s1' -> return $ Yield x (Nothing,s,s0,s1')----- | Create a stream of integer ranges. The pairs in the input stream---   give the first and last value of each range.------   The first parameter gives the size hint for the resulting stream.--- --- @--- enumFromToEach 11 [(2,5), (10,16), (20,22)]---  = [2,3,4,5,10,11,12,13,14,15,16,20,21,22]--- @----enumFromToEachS :: Int -> S.Stream (Int,Int) -> S.Stream Int-{-# INLINE_STREAM enumFromToEachS #-}-enumFromToEachS n (Stream next s _) -  = Stream next' (Nothing,s) (Exact n)-  where-    {-# INLINE_INNER next' #-}-    next' (Nothing,s)-      = do-          r <- next s-          case r of-            Yield (k,m) s' -> return $ Skip (Just (k,m),s')-            Skip        s' -> return $ Skip (Nothing,   s')-            Done           -> return Done--    next' (Just (k,m),s)-      | k > m     = return $ Skip    (Nothing,     s)-      | otherwise = return $ Yield k (Just (k+1,m),s)----- | Create a stream of integer ranges. The triples in the input stream---   give the first value, increment, length of each range.------   The first parameter gives the size hint for the resulting stream.------ @--- enumFromStepLenEach [(1,1,5), (10,2,4), (20,3,5)]---  = [1,2,3,4,5,10,12,14,16,20,23,26,29,32]--- @---               -enumFromStepLenEachS :: Int -> S.Stream (Int,Int,Int) -> S.Stream Int -{-# INLINE_STREAM enumFromStepLenEachS #-}-enumFromStepLenEachS len (Stream next s _)-  = Stream next' (Nothing,s) (Exact len)-  where-    {-# INLINE_INNER next' #-}-    next' (Nothing,s) -      = do-          r <- next s-          case r of-            Yield (from,step,len) s' -> return $ Skip (Just (from,step,len),s')-            Skip                  s' -> return $ Skip (Nothing,s')-            Done                     -> return Done--    next' (Just (from,step,0),s) = return $ Skip (Nothing,s)-    next' (Just (from,step,n),s)-      = return $ Yield from (Just (from+step,step,n-1),s)----- | Segmented Stream fold. Take segments from the given stream and fold each---   using the supplied function and initial element. ------ @--- foldSS (+) 0 [2, 3, 2] [10, 20, 30, 40, 50, 60, 70]---  = [30,120,130]--- @----foldSS  :: (a -> b -> a)        -- ^ function to perform the fold-        -> a                    -- ^ initial element of each fold-        -> S.Stream Int         -- ^ stream of segment lengths-        -> S.Stream b           -- ^ stream of input data-        -> S.Stream a           -- ^ stream of fold results-        -{-# INLINE_STREAM foldSS #-}-foldSS f z (Stream nexts ss sz) (Stream nextv vs _) =-  Stream next (Nothing,z,ss,vs) sz-  where-    {-# INLINE next #-}-    next (Nothing,x,ss,vs) =-      do-        r <- nexts ss-        case r of-          Done        -> return Done-          Skip    ss' -> return $ Skip (Nothing,x, ss', vs)-          Yield n ss' -> return $ Skip (Just n, z, ss', vs)--    next (Just 0,x,ss,vs) =-      return $ Yield x (Nothing,z,ss,vs)-    next (Just n,x,ss,vs) =-      do-        r <- nextv vs-        case r of-          Done        -> return Done -- NEVER ENTERED (See Note)-          Skip    vs' -> return $ Skip (Just n,x,ss,vs')-          Yield y vs' -> let r = f x y-                         in r `seq` return (Skip (Just (n-1), r, ss, vs'))----- | Like `foldSS`, but use the first member of each chunk as the initial---   element for the fold.-fold1SS :: (a -> a -> a) -> S.Stream Int -> S.Stream a -> S.Stream a-{-# INLINE_STREAM fold1SS #-}-fold1SS f (Stream nexts ss sz) (Stream nextv vs _) =-  Stream next (Nothing,Nothing,ss,vs) sz-  where-    {-# INLINE [0] next #-}-    next (Nothing,Nothing,ss,vs) =-      do-        r <- nexts ss-        case r of-          Done        -> return Done-          Skip    ss' -> return $ Skip (Nothing,Nothing,ss',vs)-          Yield n ss' -> return $ Skip (Just n ,Nothing,ss',vs)--    next (Just !n,Nothing,ss,vs) =-      do-        r <- nextv vs-        case r of-          Done        -> return Done -- NEVER ENTERED (See Note)-          Skip    vs' -> return $ Skip (Just n,    Nothing,ss,vs')-          Yield x vs' -> return $ Skip (Just (n-1),Just x, ss,vs')--    next (Just 0,Just x,ss,vs) =-      return $ Yield x (Nothing,Nothing,ss,vs)--    next (Just n,Just x,ss,vs) =-      do-        r <- nextv vs-        case r of-          Done        -> return Done  -- NEVER ENTERED (See Note)-          Skip    vs' -> return $ Skip (Just n    ,Just x      ,ss,vs')-          Yield y vs' -> let r = f x y-                         in r `seq` return (Skip (Just (n-1),Just r,ss,vs'))----- | Segmented Stream combine. Like `combine2ByTagS`, except that the tags select---   entire segments of each data stream, instead of selecting one element at a time.------ @--- combineSS [True, True, False, True, False, False]---           [2,1,3] [10,20,30,40,50,60]---           [1,2,3] [11,22,33,44,55,66]---  = [10,20,30,11,40,50,60,22,33,44,55,66]--- @------   This says take two elements from the first stream, then another one element ---   from the first stream, then one element from the second stream, then three---   elements from the first stream...----combineSS -        :: S.Stream Bool        -- ^ tag values-        -> S.Stream Int         -- ^ segment lengths for first data stream-        -> S.Stream a           -- ^ first data stream-        -> S.Stream Int         -- ^ segment lengths for second data stream-        -> S.Stream a           -- ^ second data stream-        -> S.Stream a--{-# INLINE_STREAM combineSS #-}-combineSS (Stream nextf sf _) -          (Stream nexts1 ss1 _) (Stream nextv1 vs1 nv1)-          (Stream nexts2 ss2 _) (Stream nextv2 vs2 nv2)-  = Stream next (Nothing,True,sf,ss1,vs1,ss2,vs2)-                (nv1+nv2)-  where-    {-# INLINE next #-}-    next (Nothing,f,sf,ss1,vs1,ss2,vs2) =-      do-        r <- nextf sf-        case r of-          Done        -> return Done-          Skip sf'    -> return $ Skip (Nothing,f,sf',ss1,vs1,ss2,vs2) -          Yield c sf'-            | c ->-              do-                r <- nexts1 ss1-                case r of-                  Done         -> return Done-                  Skip ss1'    -> return $ Skip (Nothing,f,sf,ss1',vs1,ss2,vs2) -                  Yield n ss1' -> return $ Skip (Just n,c,sf',ss1',vs1,ss2,vs2) --            | otherwise ->-              do-                r <- nexts2 ss2-                case r of-                  Done         -> return Done-                  Skip ss2'    -> return $ Skip (Nothing,f,sf,ss1,vs1,ss2',vs2) -                  Yield n ss2' -> return $ Skip (Just n,c,sf',ss1,vs1,ss2',vs2)--    next (Just 0,_,sf,ss1,vs1,ss2,vs2) =-         return $ Skip (Nothing,True,sf,ss1,vs1,ss2,vs2)--    next (Just n,True,sf,ss1,vs1,ss2,vs2) =-      do-        r <- nextv1 vs1-        case r of-          Done         -> return Done-          Skip vs1'    -> return $ Skip (Just n,True,sf,ss1,vs1',ss2,vs2) -          Yield x vs1' -> return $ Yield x (Just (n-1),True,sf,ss1,vs1',ss2,vs2)--    next (Just n,False,sf,ss1,vs1,ss2,vs2) =-      do-        r <- nextv2 vs2-        case r of-          Done         -> return Done-          Skip vs2'    -> return $ Skip (Just n,False,sf,ss1,vs1,ss2,vs2') -          Yield x vs2' -> return $ Yield x (Just (n-1),False,sf,ss1,vs1,ss2,vs2')----- | Segmented Strem append. Append corresponding segments from each stream.------ @--- appendSS [2, 1, 3] [10, 20, 30, 40, 50, 60]---          [1, 3, 2] [11, 22, 33, 44, 55, 66]---  = [10,20,11,30,22,33,44,40,50,60,55,66]--- @----appendSS-        :: S.Stream Int         -- ^ segment lengths for first data stream-        -> S.Stream a           -- ^ first data stream-        -> S.Stream Int         -- ^ segment lengths for second data stream-        -> S.Stream a           -- ^ second data stream-        -> S.Stream a--{-# INLINE_STREAM appendSS #-}-appendSS (Stream nexts1 ss1 ns1) (Stream nextv1 sv1 nv1)-         (Stream nexts2 ss2 ns2) (Stream nextv2 sv2 nv2)-  = Stream next (True,Nothing,ss1,sv1,ss2,sv2) (nv1 + nv2)-  where-    {-# INLINE next #-}-    next (True,Nothing,ss1,sv1,ss2,sv2) =-      do-        r <- nexts1 ss1-        case r of-          Done         -> return $ Done-          Skip    ss1' -> return $ Skip (True,Nothing,ss1',sv1,ss2,sv2)-          Yield n ss1' -> return $ Skip (True,Just n ,ss1',sv1,ss2,sv2)--    next (True,Just 0,ss1,sv1,ss2,sv2)-      = return $ Skip (False,Nothing,ss1,sv1,ss2,sv2)--    next (True,Just n,ss1,sv1,ss2,sv2) =-      do-        r <- nextv1 sv1-        case r of-          Done         -> return Done  -- NEVER ENTERED (See Note)-          Skip    sv1' -> return $ Skip (True,Just n,ss1,sv1',ss2,sv2)-          Yield x sv1' -> return $ Yield x (True,Just (n-1),ss1,sv1',ss2,sv2)--    next (False,Nothing,ss1,sv1,ss2,sv2) =-      do-        r <- nexts2 ss2-        case r of-          Done         -> return Done  -- NEVER ENTERED (See Note)-          Skip    ss2' -> return $ Skip (False,Nothing,ss1,sv1,ss2',sv2)-          Yield n ss2' -> return $ Skip (False,Just n,ss1,sv1,ss2',sv2)--    next (False,Just 0,ss1,sv1,ss2,sv2)-      = return $ Skip (True,Nothing,ss1,sv1,ss2,sv2)--    next (False,Just n,ss1,sv1,ss2,sv2) =-      do-        r <- nextv2 sv2-        case r of-          Done         -> return Done  -- NEVER ENTERED (See Note)-          Skip    sv2' -> return $ Skip (False,Just n,ss1,sv1,ss2,sv2')-          Yield x sv2' -> return $ Yield x (False,Just (n-1),ss1,sv1,ss2,sv2')----- | Segmented Stream fold, with a fixed segment length.--- ---   Like `foldSS` but use a fixed length for each segment.----foldValuesR -        :: (a -> b -> a)        -- ^ function to perform the fold-        -> a                    -- ^ initial element for fold-        -> Int                  -- ^ length of each segment-        -> S.Stream b           -- ^ data stream-        -> S.Stream a--{-# INLINE_STREAM foldValuesR #-}-foldValuesR f z segSize (Stream nextv vs nv) =-  Stream next (segSize,z,vs) (nv `divSize` segSize)-  where-    {-# INLINE next #-}  -    next (0,x,vs) = return $ Yield x (segSize,z,vs)--    next (n,x,vs) =-      do-        r <- nextv vs-        case r of-          Done        -> return Done-          Skip    vs' -> return $ Skip (n,x,vs')-          Yield y vs' -> let r = f x y-                         in r `seq` return (Skip ((n-1),r,vs'))----- | Divide a size hint by a scalar.-divSize :: Size -> Int -> Size-divSize (Exact n) k = Exact (n `div` k)-divSize (Max   n) k = Max   (n `div` k)-divSize Unknown   _ = Unknown----- | Segmented Stream indices.--- --- @--- indicesSS 15 4 [3, 5, 7]---  = [4,5,6,0,1,2,3,4,0,1,2,3,4,5,6]--- @------ Note that we can set the starting value of the first segment independently--- via the second argument of indicesSS. We use this when distributing arrays--- across worker threads, as a thread's chunk may not start exactly at a --- segment boundary, so the index of a thread's first data element may not be--- zero.----indicesSS -        :: Int-        -> Int-        -> S.Stream Int-        -> S.Stream Int--{-# INLINE_STREAM indicesSS #-}-indicesSS n i (Stream next s _) =-  Stream next' (i,Nothing,s) (Exact n)-  where-    {-# INLINE next' #-}-    next' (i,Nothing,s) =-      do-        r <- next s-        case r of-          Done       -> return Done-          Skip    s' -> return $ Skip (i,Nothing,s')-          Yield k s' -> return $ Skip (i,Just k,s')--    next' (i,Just k,s)-      | k > 0     = return $ Yield i (i+1,Just (k-1),s)-      | otherwise = return $ Skip    (0  ,Nothing   ,s)-
LICENSE view
@@ -1,5 +1,4 @@-Copyright (c) 2001-2011, The DPH Team-All rights reserved.+Copyright (c) 2001-2012, The DPH Team  The DPH Team is:   Manuel M T Chakravarty
dph-base.cabal view
@@ -1,13 +1,15 @@ Name:           dph-base-Version:        0.5.1.1+Version:        0.6.0.1 License:        BSD3 License-File:   LICENSE Author:         The DPH Team Maintainer:     Ben Lippmeier <benl@cse.unsw.edu.au> Homepage:       http://www.haskell.org/haskellwiki/GHC/Data_Parallel_Haskell Category:       Data Structures-Synopsis:       Common utilities and config for Data Parallel Haskell+Synopsis:       Data Parallel Haskell common config and debugging functions.+Description:    Common configuration, debugging and utilities. + Cabal-Version:  >= 1.6 Build-Type:     Simple @@ -18,15 +20,16 @@ Library   Exposed-Modules:         Data.Array.Parallel.Base-        Data.Array.Parallel.Stream+        Data.Array.Parallel.Base.Text         Data.Array.Parallel.Base.DTrace         Data.Array.Parallel.Base.TracePrim+        Data.Array.Parallel.Pretty+        Data.Array.Parallel.Array    Other-Modules:         Data.Array.Parallel.Base.Config         Data.Array.Parallel.Base.Debug-        Data.Array.Parallel.Base.Util-        Data.Array.Parallel.Base.Text+        Data.Array.Parallel.Base.Tag    Include-Dirs:         include@@ -38,14 +41,19 @@    Extensions:           TypeFamilies, GADTs, RankNTypes,-         BangPatterns, MagicHash, UnboxedTuples, TypeOperators, CPP+         BangPatterns, MagicHash, UnboxedTuples, TypeOperators, CPP,+         MultiParamTypeClasses, FlexibleInstances -  GHC-Options: -Odph -funbox-strict-fields -fcpr-off +  GHC-Options:+        -Odph+        -funbox-strict-fields -fcpr-off     Build-Depends:  -        base     == 4.4.*,+        base     == 4.5.*,         ghc-prim == 0.2.*,-        array    == 0.3.*,+        array    == 0.4.*,         random   == 1.0.*,-        vector   == 0.7.*+        vector   == 0.9.*,+        pretty   == 1.1.*+           
include/fusion-phases.h view
@@ -1,16 +1,75 @@-#define INLINE_U       INLINE-#define INLINE_UP      INLINE-#define INLINE_STREAM  INLINE [1]-#define INLINE_DIST    INLINE [1]-#define INLINE_PA      INLINE-#define INLINE_BACKEND INLINE [2]-#define INLINE_INNER   INLINE [0]+-------------------------------------------------------------------------------+-- These are the main simplifier phases used in DPH.+--  The phase is numbered after the set of bindings that are inlined in that+--  phase. We start from the "outermost" combinators produced by the+--  vectoriser and work our way down to the Data.Vector streams.+-- -#define PHASE_PA+-- Inline bindings in user code, and closure functions.+-- This is dph-common-vseg:D.A.P.Lifted.Closure+#define PHASE_USER      [4]++-- Inline combinators that work on PArray and PData.+-- This is dph-common-vseg:D.A.P.PArray+#define PHASE_PA        [3]++-- Inline combinators from the unlifted backends+-- This is dph-prim-par:D.A.P.Unlifted.Parallel+--     and dph-prim-par:D.A.P.Unlifted.Sequential #define PHASE_BACKEND   [2]++-- Inline combinators for distributed arrays.+-- This is dph-prim-par:D.A.P.Unlifted.Distributed #define PHASE_DIST      [1]++-- Inline combinators for Data.Vector #define PHASE_STREAM    [1]++-- Inline stuff in inner loops. #define PHASE_INNER     [0] + #define UNTIL_PHASE_BACKEND [~2]+++-------------------------------------------------------------------------------+-- More fine-grained inliner pragmas that we use to annotate the actual+-- bindings. When debugging it's useful to control exactly what gets inlined.++-- Bindings in hand-crafted example code.+#define INLINE_USER    INLINE PHASE_USER++-- Closure combinators produced by the vectoriser.+-- dph-common-vseg:D.A.P.Lifted.Closure+#define INLINE_CLOSURE INLINE PHASE_USER++-- Stuff that works on PArrays+-- dph-common-vseg:D.A.P.Lifted.Combinators+-- dph-common-vseg:D.A.P.PArray+#define INLINE_PA      INLINE PHASE_USER++-- dph-common-vseg:D.A.P.PArray.PData+#define INLINE_PDATA   INLINE PHASE_PA++-- Generic stuff in the unlifted backend.+#define INLINE_BACKEND INLINE PHASE_BACKEND++-- Unlifted parallel array combinators.+-- dph-prim-par:D.A.P.Unlifted.Parallel+#define INLINE_UP      INLINE PHASE_BACKEND++-- Unlifted sequential array combinators.+-- dph-prim-seq:D.A.P.Unlifted.Sequential+#define INLINE_U       INLINE PHASE_BACKEND++-- dph-prim-par:D.A.P.Unlifted.Distributed+#define INLINE_DIST    INLINE PHASE_DIST++-- dph-prim-seq:D.A.P.Unlifted.Sequential.Vector+#define INLINE_STREAM  INLINE PHASE_STREAM+++#define INLINE_INNER   INLINE PHASE_INNER++