dph-prim-par: reorganising Distributed API to expose Gang primitives
authorBen Lippmeier <benl@ouroborus.net>
Mon, 23 Jul 2012 03:54:53 +0000 (13:54 +1000)
committerBen Lippmeier <benl@ouroborus.net>
Mon, 30 Jul 2012 03:48:35 +0000 (13:48 +1000)
23 files changed:
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed.hs
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Arrays.hs
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Basics.hs
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Combinators.hs
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Data/Maybe.hs [moved from dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types/Maybe.hs with 85% similarity]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Data/Prim.hs [moved from dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types/Prim.hs with 97% similarity]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Data/Tuple.hs [moved from dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types/Tuple.hs with 97% similarity]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Data/USSegd.hs [moved from dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types/USSegd.hs with 93% similarity]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Data/USegd.hs [moved from dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types/USegd.hs with 94% similarity]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Data/UVSegd.hs [moved from dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types/UVSegd.hs with 94% similarity]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Data/Unit.hs [moved from dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types/Unit.hs with 83% similarity]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Data/Vector.hs [moved from dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types/Vector.hs with 91% similarity]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Primitive.hs [new file with mode: 0644]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Primitive/DT.hs [moved from dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types/Base.hs with 94% similarity]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Primitive/DistST.hs [moved from dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/DistST.hs with 60% similarity]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Primitive/Gang.hs [moved from dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Gang.hs with 60% similarity]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Primitive/Operators.hs [new file with mode: 0644]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Scalars.hs
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/TheGang.hs [deleted file]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types.hs [deleted file]
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/USSegd.hs
dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/USegd.hs
dph-prim-par/dph-prim-par.cabal

index b595e81..31815b9 100644 (file)
@@ -56,12 +56,10 @@ module Data.Array.Parallel.Unlifted.Distributed
           -- * Debugging
         , fromD, toD, debugD)
 where
-import Data.Array.Parallel.Unlifted.Distributed.TheGang
 import Data.Array.Parallel.Unlifted.Distributed.Combinators
 import Data.Array.Parallel.Unlifted.Distributed.Scalars
 import Data.Array.Parallel.Unlifted.Distributed.Arrays
 import Data.Array.Parallel.Unlifted.Distributed.USegd
 import Data.Array.Parallel.Unlifted.Distributed.Basics
-import Data.Array.Parallel.Unlifted.Distributed.Types
-import Data.Array.Parallel.Unlifted.Distributed.Gang (Gang, forkGang, gangSize)
+import Data.Array.Parallel.Unlifted.Distributed.Primitive
 
index 9060e3c..49180b2 100644 (file)
@@ -24,9 +24,9 @@ module Data.Array.Parallel.Unlifted.Distributed.Arrays
         , carryD)
  where
 import Data.Array.Parallel.Base (ST, runST)
-import Data.Array.Parallel.Unlifted.Distributed.Gang
-import Data.Array.Parallel.Unlifted.Distributed.DistST
-import Data.Array.Parallel.Unlifted.Distributed.Types
+import Data.Array.Parallel.Unlifted.Distributed.Primitive
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.DistST
+import Data.Array.Parallel.Unlifted.Distributed.Data.Vector
 import Data.Array.Parallel.Unlifted.Distributed.Combinators
 import Data.Array.Parallel.Unlifted.Distributed.Scalars
 import Data.Array.Parallel.Unlifted.Sequential.Vector   (Vector, MVector, Unbox)
index 7b97aab..83b4416 100644 (file)
@@ -4,8 +4,7 @@
 module Data.Array.Parallel.Unlifted.Distributed.Basics 
         (eqD, neqD, toD, fromD)
 where
-import Data.Array.Parallel.Unlifted.Distributed.Gang 
-import Data.Array.Parallel.Unlifted.Distributed.Types
+import Data.Array.Parallel.Unlifted.Distributed.Primitive
 import Data.Array.Parallel.Unlifted.Distributed.Combinators 
 import Data.Array.Parallel.Unlifted.Distributed.Scalars
 import Control.Monad ( zipWithM_ )
index 2916442..4d7f448 100644 (file)
@@ -6,62 +6,24 @@
 -- | Standard combinators for distributed types.
 module Data.Array.Parallel.Unlifted.Distributed.Combinators 
         ( What (..)
-        , generateD, generateD_cheap
         , imapD, mapD
         , zipD, unzipD
         , fstD, sndD
         , zipWithD, izipWithD
         , foldD
         , scanD
-        , mapAccumLD
-
-           -- * Monadic combinators
-        , mapDST_, mapDST, zipWithDST_, zipWithDST)
+        , mapAccumLD)
 where
 import Data.Array.Parallel.Base ( ST, runST)
-import Data.Array.Parallel.Unlifted.Distributed.Gang
-import Data.Array.Parallel.Unlifted.Distributed.Types
-import Data.Array.Parallel.Unlifted.Distributed.DistST
+import Data.Array.Parallel.Unlifted.Distributed.Primitive
+import Data.Array.Parallel.Unlifted.Distributed.Data.Tuple
+import Data.Array.Parallel.Unlifted.Distributed.Data.Maybe      ()
 import Data.Array.Parallel.Unlifted.Distributed.What
 import Debug.Trace
 
 here s = "Data.Array.Parallel.Unlifted.Distributed.Combinators." ++ s
 
 
--- | Create a distributed value, given a function to create the instance
---   for each thread.
-generateD 
-        :: DT a 
-        => What         -- ^ What is the worker function doing.
-        -> Gang 
-        -> (Int -> a) 
-        -> Dist a
-generateD what g f 
-        = traceEvent (show $ CompGenerate False what) 
-        $ runDistST g (myIndex >>= return . f)
-{-# NOINLINE generateD #-}
-
-
--- | Create a distributed value, but do it sequentially.
---  
---   This function is used when we want to operate on a distributed value, but
---   there isn't much data involved. For example, if we want to distribute 
---   a single integer to each thread, then there's no need to fire up the 
---   gang for this.
---   
-generateD_cheap 
-        :: DT a 
-        => What          -- ^ What is the worker function doing.
-        -> Gang 
-        -> (Int -> a) 
-        -> Dist a
-
-generateD_cheap what g f 
-        = traceEvent (show $ CompGenerate True what) 
-        $ runDistST_seq g (myIndex >>= return . f)
-{-# NOINLINE generateD_cheap #-}
-
-
 -- Mapping --------------------------------------------------------------------
 --
 -- Fusing maps
@@ -112,20 +74,6 @@ imapD wFn gang f d
 --  formp, so once imapD is inlined no more fusion can take place.
 
 
--- | Map a function across all elements of a distributed value.
---   The worker function also gets the current thread index.
-imapD'  :: (DT a, DT b) 
-        => What -> Gang -> (Int -> a -> b) -> Dist a -> Dist b
-imapD' what gang f !d 
-  = traceEvent (show (CompMap $ what))
-  $ runDistST gang 
-        (do i <- myIndex
-            x <- myD d
-            return (f i x))
-{-# NOINLINE imapD' #-}
--- NOINLINE 
-
-
 {-# RULES
 
 "imapD/generateD" 
@@ -196,42 +144,6 @@ izipWithD what g f dx dy
   #-}
 
 
--- Folding --------------------------------------------------------------------
--- | Fold all the instances of a distributed value.
-foldD :: DT a => Gang -> (a -> a -> a) -> Dist a -> a
-foldD g f !d 
-  = checkGangD ("here foldD") g d 
-  $ fold 1 (indexD (here "foldD") d 0)
-  where
-    !n = gangSize g
-    --
-    fold i x | i == n    = x
-             | otherwise = fold (i+1) (f x $ indexD (here "foldD") d i)
-{-# NOINLINE foldD #-}
-
-
--- | Prefix sum of the instances of a distributed value.
-scanD :: forall a. DT a => Gang -> (a -> a -> a) -> a -> Dist a -> (Dist a, a)
-scanD g f z !d
-  = checkGangD (here "scanD") g d 
-  $ runST (do
-          md <- newMD g
-          s  <- scan md 0 z
-          d' <- unsafeFreezeMD md
-          return (d',s))
-  where
-    !n = gangSize g
-    
-    scan :: forall s. MDist a s -> Int -> a -> ST s a
-    scan md i !x
-        | i == n    = return x
-        | otherwise
-        = do    writeMD md i x
-                scan md (i+1) (f x $ indexD (here "scanD") d i)
-{-# NOINLINE scanD #-}
-
-
-
 -- MapAccumL ------------------------------------------------------------------
 -- | Combination of map and fold.
 mapAccumLD 
@@ -260,49 +172,3 @@ mapAccumLD g f acc !d
                       go md (i+1) acc''
 {-# INLINE_DIST mapAccumLD #-}
                                 
-
--- Versions that work on DistST -----------------------------------------------
--- NOTE: The following combinators must be strict in the Dists because if they
--- are not, the Dist might be evaluated (in parallel) when it is requested in
--- the current computation which, again, is parallel. This would break our
--- model andlead to a deadlock. Hence the bangs.
-
-mapDST_ :: DT a => Gang -> (a -> DistST s ()) -> Dist a -> ST s ()
-mapDST_ g p d 
- = mapDST_' g (\x -> x `deepSeqD` p x) d
-{-# INLINE mapDST_ #-}
-
-
-mapDST_' :: DT a => Gang -> (a -> DistST s ()) -> Dist a -> ST s ()
-mapDST_' g p !d 
- = checkGangD (here "mapDST_") g d 
- $ distST_ g (myD d >>= p)
-
-
-mapDST :: (DT a, DT b) => Gang -> (a -> DistST s b) -> Dist a -> ST s (Dist b)
-mapDST g p !d = mapDST' g (\x -> x `deepSeqD` p x) d
-{-# INLINE mapDST #-}
-
-
-mapDST' :: (DT a, DT b) => Gang -> (a -> DistST s b) -> Dist a -> ST s (Dist b)
-mapDST' g p !d 
- = checkGangD (here "mapDST_") g d 
- $ distST g (myD d >>= p)
-
-
-zipWithDST_ 
-        :: (DT a, DT b)
-        => Gang -> (a -> b -> DistST s ()) -> Dist a -> Dist b -> ST s ()
-zipWithDST_ g p !dx !dy 
- = mapDST_ g (uncurry p) (zipD dx dy)
-{-# INLINE zipWithDST_ #-}
-
-
-zipWithDST 
-        :: (DT a, DT b, DT c)
-        => Gang
-        -> (a -> b -> DistST s c) -> Dist a -> Dist b -> ST s (Dist c)
-zipWithDST g p !dx !dy 
- = mapDST g (uncurry p) (zipD dx dy)
-{-# INLINE zipWithDST #-}
-
@@ -1,9 +1,9 @@
 {-# OPTIONS -Wall -fno-warn-orphans -fno-warn-missing-signatures #-}
 
 -- | Distribution of Maybes.
-module Data.Array.Parallel.Unlifted.Distributed.Types.Maybe where
-import Data.Array.Parallel.Unlifted.Distributed.Types.Prim      ()
-import Data.Array.Parallel.Unlifted.Distributed.Types.Base
+module Data.Array.Parallel.Unlifted.Distributed.Data.Maybe where
+import Data.Array.Parallel.Unlifted.Distributed.Data.Prim      ()
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.DT
 import Control.Monad
 
 instance DT a => DT (Maybe a) where
@@ -1,13 +1,12 @@
 {-# OPTIONS -Wall -fno-warn-orphans -fno-warn-missing-signatures #-}
 
 -- | Distribution of values of primitive types.
-module Data.Array.Parallel.Unlifted.Distributed.Types.Prim 
+module Data.Array.Parallel.Unlifted.Distributed.Data.Prim 
         ( DPrim (..)
         , DT    (..)
         , Dist  (..))
 where
-import Data.Array.Parallel.Unlifted.Distributed.Types.Base
-import Data.Array.Parallel.Unlifted.Distributed.Gang
+import Data.Array.Parallel.Unlifted.Distributed.Primitive
 import Data.Array.Parallel.Unlifted.Sequential.Vector
 import Data.Array.Parallel.Base
 import Data.Array.Parallel.Pretty
@@ -3,14 +3,14 @@
 #include "fusion-phases.h"
 
 -- | Distribution of Tuples
-module Data.Array.Parallel.Unlifted.Distributed.Types.Tuple 
+module Data.Array.Parallel.Unlifted.Distributed.Data.Tuple 
         ( -- * Pairs
           zipD, unzipD, fstD, sndD
         
            -- * Triples
         , zip3D, unzip3D)
 where
-import Data.Array.Parallel.Unlifted.Distributed.Types.Base
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.DT
 import Data.Array.Parallel.Base
 import Data.Array.Parallel.Pretty
 import Control.Monad
@@ -3,7 +3,7 @@
 #include "fusion-phases.h"
 
 -- | Distribution of Segment Descriptors
-module Data.Array.Parallel.Unlifted.Distributed.Types.USSegd 
+module Data.Array.Parallel.Unlifted.Distributed.Data.USSegd 
         ( lengthD
         , takeLengthsD
         , takeIndicesD
@@ -12,15 +12,15 @@ module Data.Array.Parallel.Unlifted.Distributed.Types.USSegd
         , takeSourcesD
         , takeUSegdD)
 where
-import Data.Array.Parallel.Unlifted.Distributed.Types.Base
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.DT
 import Data.Array.Parallel.Unlifted.Sequential.USSegd                   (USSegd)
 import Data.Array.Parallel.Unlifted.Sequential.USegd                    (USegd)
 import Data.Array.Parallel.Unlifted.Sequential.Vector                   (Vector)
 import Data.Array.Parallel.Pretty
 import Control.Monad
 import Prelude                                                          as P
-import qualified Data.Array.Parallel.Unlifted.Distributed.Types.USegd   as DUSegd
-import qualified Data.Array.Parallel.Unlifted.Distributed.Types.Vector  as DV
+import qualified Data.Array.Parallel.Unlifted.Distributed.Data.USegd   as DUSegd
+import qualified Data.Array.Parallel.Unlifted.Distributed.Data.Vector  as DV
 import qualified Data.Array.Parallel.Unlifted.Sequential.USSegd         as USSegd
 
 
@@ -3,19 +3,19 @@
 #include "fusion-phases.h"
 
 -- | Distribution of Segment Descriptors
-module Data.Array.Parallel.Unlifted.Distributed.Types.USegd 
+module Data.Array.Parallel.Unlifted.Distributed.Data.USegd 
         ( mkDUSegd
         , lengthD
         , takeLengthsD
         , takeIndicesD
         , takeElementsD)
 where
-import Data.Array.Parallel.Unlifted.Distributed.Types.Base
+import Data.Array.Parallel.Unlifted.Distributed.Primitive
 import Data.Array.Parallel.Unlifted.Sequential.USegd                    (USegd)
 import Data.Array.Parallel.Unlifted.Sequential.Vector                   (Vector)
 import Data.Array.Parallel.Pretty
 import Control.Monad
-import qualified Data.Array.Parallel.Unlifted.Distributed.Types.Vector  as DV
+import qualified Data.Array.Parallel.Unlifted.Distributed.Data.Vector  as DV
 import qualified Data.Array.Parallel.Unlifted.Sequential.USegd          as USegd
 import Prelude                                                          as P
 
@@ -3,7 +3,7 @@
 #include "fusion-phases.h"
 
 -- | Distribution of Virtual Segment Descriptors
-module Data.Array.Parallel.Unlifted.Distributed.Types.UVSegd 
+module Data.Array.Parallel.Unlifted.Distributed.Data.UVSegd 
         ( lengthD
         , takeLengthsD
         , takeIndicesD
@@ -13,7 +13,7 @@ module Data.Array.Parallel.Unlifted.Distributed.Types.UVSegd
         , takeVSegidsD
         , takeUSSegdD)
 where
-import Data.Array.Parallel.Unlifted.Distributed.Types.Base
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.DT
 import Data.Array.Parallel.Unlifted.Sequential.UVSegd                   (UVSegd)
 import Data.Array.Parallel.Unlifted.Sequential.USSegd                   (USSegd)
 import Data.Array.Parallel.Unlifted.Sequential.Vector
@@ -21,7 +21,7 @@ import Data.Array.Parallel.Pretty
 import Control.Monad
 import Prelude                                                          as P
 import qualified Data.Array.Parallel.Unlifted.Sequential.UVSegd         as UVSegd
-import qualified Data.Array.Parallel.Unlifted.Distributed.Types.USSegd  as DUSegd
+import qualified Data.Array.Parallel.Unlifted.Distributed.Data.USSegd  as DUSegd
 
 
 instance DT UVSegd where
@@ -3,11 +3,10 @@
 #include "fusion-phases.h"
 
 -- | Distribution of unit values.
-module Data.Array.Parallel.Unlifted.Distributed.Types.Unit 
+module Data.Array.Parallel.Unlifted.Distributed.Data.Unit 
         (unitD)
 where
-import Data.Array.Parallel.Unlifted.Distributed.Types.Base
-import Data.Array.Parallel.Unlifted.Distributed.Gang
+import Data.Array.Parallel.Unlifted.Distributed.Primitive
 import Data.Array.Parallel.Base
 
 here :: String -> String
@@ -1,12 +1,12 @@
 {-# OPTIONS -Wall -fno-warn-orphans -fno-warn-missing-signatures #-}
 
 -- | Distribution of Vectors.
-module Data.Array.Parallel.Unlifted.Distributed.Types.Vector
+module Data.Array.Parallel.Unlifted.Distributed.Data.Vector
         (lengthD)
 where
 import qualified Data.Array.Parallel.Base               as B
-import Data.Array.Parallel.Unlifted.Distributed.Types.Prim
-import Data.Array.Parallel.Unlifted.Distributed.Gang
+import Data.Array.Parallel.Unlifted.Distributed.Data.Prim
+import Data.Array.Parallel.Unlifted.Distributed.Primitive
 import Data.Array.Parallel.Pretty
 import Data.Array.Parallel.Unlifted.Sequential.Vector   as V
 import qualified Data.Vector                            as BV
diff --git a/dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Primitive.hs b/dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Primitive.hs
new file mode 100644 (file)
index 0000000..8600a9d
--- /dev/null
@@ -0,0 +1,47 @@
+{-# OPTIONS -Wall -fno-warn-orphans -fno-warn-missing-signatures #-}
+{-# LANGUAGE CPP #-}
+#include "fusion-phases.h"
+
+-- | Standard combinators for distributed types.
+module Data.Array.Parallel.Unlifted.Distributed.Primitive
+        ( -- * The Gang
+          Gang
+        , gangSize
+        , seqGang
+        , forkGang
+        , theGang
+
+          -- * Distributed Types
+        , DT (..)
+        , newD
+        , debugD
+        , checkGangD
+
+          -- * Primitive Distributed Operators.
+        , generateD
+        , generateD_cheap
+        , imapD'
+        , foldD
+        , scanD)
+where
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.DT
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.Gang
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.Operators 
+import Control.Concurrent       (getNumCapabilities)
+import System.IO.Unsafe         (unsafePerformIO)
+
+
+-- | DPH programs use this single, shared gang of threads.
+--   The gang exists at top level, and is initialised at program start.
+-- 
+--   The vectoriser guarantees that the gang is only used by a single
+--   computation at a time. This is true because the program produced
+--   by the vector only uses flat parallelism, so parallel computations
+--   don't invoke further parallel computations. If the vectorised program
+--   tries to use nested parallelism then there is a bug in the vectoriser,
+--   and the code will run sequentially.
+--
+theGang :: Gang
+theGang = unsafePerformIO (getNumCapabilities >>= forkGang)
+{-# NOINLINE theGang #-}
+
@@ -1,5 +1,6 @@
+
 {-# OPTIONS -Wall -fno-warn-orphans -fno-warn-missing-signatures #-}
-module Data.Array.Parallel.Unlifted.Distributed.Types.Base 
+module Data.Array.Parallel.Unlifted.Distributed.Primitive.DT
         ( -- * Distributable Types
           DT(..)
         
@@ -11,9 +12,10 @@ module Data.Array.Parallel.Unlifted.Distributed.Types.Base
         , newD
         , debugD)
 where
-import Data.Array.Parallel.Unlifted.Distributed.Gang    (Gang, gangSize)
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.Gang
 import Data.Array.Parallel.Base
-import Data.List                                        (intercalate)
+import Data.List
+import Control.Monad.ST
 
 here :: String -> String
 here s = "Data.Array.Parallel.Unlifted.Distributed.Types.Base." ++ s
@@ -105,4 +107,3 @@ debugD d = "["
          ++ intercalate "," [measureD (indexD (here "debugD") d i) 
                             | i <- [0 .. sizeD d-1]]
          ++ "]"
-
@@ -1,3 +1,4 @@
+
 {-# OPTIONS -Wall -fno-warn-orphans -fno-warn-missing-signatures #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 -- | Distributed ST computations.
@@ -8,22 +9,32 @@
 --  thread.
 --
 -- /TODO:/ Add facilities for implementing parallel scans etc.
-module Data.Array.Parallel.Unlifted.Distributed.DistST 
+--
+--  TODO: 
+--
+module Data.Array.Parallel.Unlifted.Distributed.Primitive.DistST 
         ( DistST
+
+          -- * Primitives.
         , stToDistST
         , distST_, distST
         , runDistST, runDistST_seq
         , traceDistST
         , myIndex
         , myD
-        , readMyMD, writeMyMD)
+        , readMyMD, writeMyMD
+
+          -- * Monadic combinators
+        , mapDST_, mapDST, zipWithDST_, zipWithDST)
 where
 import Data.Array.Parallel.Base (ST, runST)
-import Data.Array.Parallel.Unlifted.Distributed.Gang
-import Data.Array.Parallel.Unlifted.Distributed.Types (DT(..), Dist, MDist)
-
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.DT
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.Gang
+import Data.Array.Parallel.Unlifted.Distributed.Data.Tuple
 import Control.Monad (liftM)
 
+here s = "Data.Array.Parallel.Unlifted.Distributed.DistST." ++ s
+
 
 -- | Data-parallel computations.
 --   When applied to a thread gang, the computation implicitly knows the index
@@ -41,6 +52,7 @@ instance Monad (DistST s) where
                                     unDistST (f x) i
 
 
+-- Primitives -----------------------------------------------------------------
 -- | Yields the index of the current thread within its gang.
 myIndex :: DistST s Int
 myIndex = DistST return
@@ -63,16 +75,16 @@ myD dt = liftM (indexD "myD" dt) myIndex
 -- | Yields the 'MDist' element owned by the current thread.
 readMyMD :: DT a => MDist a s -> DistST s a
 readMyMD mdt 
- = do  i <- myIndex
-       stToDistST $ readMD mdt i
+ = do   i <- myIndex
+        stToDistST $ readMD mdt i
 {-# NOINLINE readMyMD #-}
 
 
 -- | Writes the 'MDist' element owned by the current thread.
 writeMyMD :: DT a => MDist a s -> a -> DistST s ()
 writeMyMD mdt x 
- = do  i <- myIndex
-       stToDistST $ writeMD mdt i x
+ = do   i <- myIndex
+        stToDistST $ writeMD mdt i x
 {-# NOINLINE writeMyMD #-}
 
 
@@ -86,7 +98,7 @@ distST_ g = gangST g . unDistST
 -- | Execute a data-parallel computation, yielding the distributed result.
 distST :: DT a => Gang -> DistST s a -> ST s (Dist a)
 distST g p 
- = do  md <- newMD g
+ = do   md <- newMD g
         distST_ g $ writeMyMD md =<< p
         unsafeFreezeMD md
 {-# INLINE distST #-}
@@ -117,3 +129,50 @@ runDistST_seq g p = runST (
 traceDistST :: String -> DistST s ()
 traceDistST s = DistST $ \n -> traceGangST ("Worker " ++ show n ++ ": " ++ s)
 
+
+-- Combinators ----------------------------------------------------------------
+-- Versions that work on DistST -----------------------------------------------
+-- NOTE: The following combinators must be strict in the Dists because if they
+-- are not, the Dist might be evaluated (in parallel) when it is requested in
+-- the current computation which, again, is parallel. This would break our
+-- model andlead to a deadlock. Hence the bangs.
+
+mapDST_ :: DT a => Gang -> (a -> DistST s ()) -> Dist a -> ST s ()
+mapDST_ g p d 
+ = mapDST_' g (\x -> x `deepSeqD` p x) d
+{-# INLINE mapDST_ #-}
+
+
+mapDST_' :: DT a => Gang -> (a -> DistST s ()) -> Dist a -> ST s ()
+mapDST_' g p !d 
+ = checkGangD (here "mapDST_") g d 
+ $ distST_ g (myD d >>= p)
+
+
+mapDST :: (DT a, DT b) => Gang -> (a -> DistST s b) -> Dist a -> ST s (Dist b)
+mapDST g p !d = mapDST' g (\x -> x `deepSeqD` p x) d
+{-# INLINE mapDST #-}
+
+
+mapDST' :: (DT a, DT b) => Gang -> (a -> DistST s b) -> Dist a -> ST s (Dist b)
+mapDST' g p !d 
+ = checkGangD (here "mapDST_") g d 
+ $ distST g (myD d >>= p)
+
+
+zipWithDST_ 
+        :: (DT a, DT b)
+        => Gang -> (a -> b -> DistST s ()) -> Dist a -> Dist b -> ST s ()
+zipWithDST_ g p !dx !dy 
+ = mapDST_ g (uncurry p) (zipD dx dy)
+{-# INLINE zipWithDST_ #-}
+
+
+zipWithDST 
+        :: (DT a, DT b, DT c)
+        => Gang
+        -> (a -> b -> DistST s c) -> Dist a -> Dist b -> ST s (Dist c)
+zipWithDST g p !dx !dy 
+ = mapDST g (uncurry p) (zipD dx dy)
+{-# INLINE zipWithDST #-}
+
@@ -9,7 +9,7 @@
 #define TRACE_GANG 0
 
 -- | Gang primitives.
-module Data.Array.Parallel.Unlifted.Distributed.Gang 
+module Data.Array.Parallel.Unlifted.Distributed.Primitive.Gang
         ( Gang
         , seqGang
         , forkGang
@@ -29,24 +29,25 @@ import Debug.Trace              (traceEventIO)
 import System.Time ( ClockTime(..), getClockTime )
 #endif 
 
+
 -- Requests and operations on them --------------------------------------------
 -- | The 'Req' type encapsulates work requests for individual members of a gang. 
 data Req 
-       -- | Instruct the worker to run the given action then signal it's done
-       --   by writing to the MVar.
-       = ReqDo        (Int -> IO ()) (MVar ())
+        -- | Instruct the worker to run the given action then signal it's done
+        --   by writing to the MVar.
+        = ReqDo        (Int -> IO ()) (MVar ())
 
-       -- | Tell the worker that we're shutting the gang down.
+        -- | Tell the worker that we're shutting the gang down.
         --   The worker should signal that it's received the equest down by
-        --   writing to the MVar before returning to its caller (forkGang)     
-       | ReqShutdown  (MVar ())
+        --   writing to the MVar before returning to its caller (forkGang)      
+        | ReqShutdown  (MVar ())
 
 
 -- | Create a new request for the given action.
 newReq :: (Int -> IO ()) -> IO Req
 newReq p 
- = do  mv      <- newEmptyMVar
-       return  $ ReqDo p mv
+ = do   mv      <- newEmptyMVar
+        return  $ ReqDo p mv
 
 
 -- | Block until a thread request has been executed.
@@ -54,8 +55,8 @@ newReq p
 waitReq :: Req -> IO ()
 waitReq req
  = case req of
-       ReqDo     _ varDone     -> takeMVar varDone
-       ReqShutdown varDone     -> takeMVar varDone
+        ReqDo     _ varDone     -> takeMVar varDone
+        ReqShutdown varDone     -> takeMVar varDone
 
 
 -- Thread gangs and operations on them ----------------------------------------
@@ -68,7 +69,7 @@ data Gang
 
 instance Show Gang where
   showsPrec p (Gang n _ _) 
-       = showString "<<"
+        = showString "<<"
         . showsPrec p n
         . showString " threads>>"
 
@@ -82,24 +83,24 @@ seqGang (Gang n _ mv) = Gang n [] mv
 --   The threads blocks on the MVar waiting for a work request.
 gangWorker :: Int -> MVar Req -> IO ()
 gangWorker threadId varReq
- = do  traceGang $ "Worker " ++ show threadId ++ " waiting for request."
-       req     <- takeMVar varReq
-       
-       case req of
-        ReqDo action varDone
-         -> do traceGang $ "Worker " ++ show threadId ++ " begin"
-               start   <- getGangTime
-               action threadId
-               end     <- getGangTime
-               traceGang $ "Worker " ++ show threadId 
+ = do   traceGang $ "Worker " ++ show threadId ++ " waiting for request."
+        req     <- takeMVar varReq
+        
+        case req of
+         ReqDo action varDone
+          -> do traceGang $ "Worker " ++ show threadId ++ " begin"
+                start   <- getGangTime
+                action threadId
+                end     <- getGangTime
+                traceGang $ "Worker " ++ show threadId 
                           ++ " end (" ++ diffTime start end ++ ")"
-               
-               putMVar varDone ()
-               gangWorker threadId varReq
+                
+                putMVar varDone ()
+                gangWorker threadId varReq
 
-        ReqShutdown varDone
-         -> do traceGang $ "Worker " ++ show threadId ++ " shutting down."
-               putMVar varDone ()
+         ReqShutdown varDone
+          -> do traceGang $ "Worker " ++ show threadId ++ " shutting down."
+                putMVar varDone ()
 
 
 -- | Finaliser for worker threads.
@@ -119,32 +120,32 @@ gangWorker threadId varReq
 --
 finaliseWorker :: MVar Req -> IO ()
 finaliseWorker varReq
- = do  varDone <- newEmptyMVar
-       putMVar varReq (ReqShutdown varDone) 
-       takeMVar varDone
-       return ()
+ = do   varDone <- newEmptyMVar
+        putMVar varReq (ReqShutdown varDone) 
+        takeMVar varDone
+        return ()
 
 
 -- | Fork a 'Gang' with the given number of threads (at least 1).
 forkGang :: Int -> IO Gang
 forkGang n
  = assert (n > 0) 
- $ do  
-       -- Create the vars we'll use to issue work requests.
-       mvs     <- sequence . replicate n $ newEmptyMVar
-       
-       -- Add finalisers so we can shut the workers down cleanly if they
+ $ do   
+        -- Create the vars we'll use to issue work requests.
+        mvs     <- sequence . replicate n $ newEmptyMVar
+        
+        -- Add finalisers so we can shut the workers down cleanly if they
         -- become unreachable.
-       mapM_ (\var -> addMVarFinalizer var (finaliseWorker var)) mvs
+        mapM_ (\var -> addMVarFinalizer var (finaliseWorker var)) mvs
 
-       -- Create all the worker threads
-       zipWithM_ forkOn [0..] 
-               $ zipWith gangWorker [0 .. n-1] mvs
+        -- Create all the worker threads
+        zipWithM_ forkOn [0..] 
+                $ zipWith gangWorker [0 .. n-1] mvs
 
-       -- The gang is currently idle.
-       busy    <- newMVar False
-       
-       return $ Gang n mvs busy
+        -- The gang is currently idle.
+        busy    <- newMVar False
+        
+        return $ Gang n mvs busy
 
 
 -- | O(1). Yield the number of threads in the 'Gang'.
@@ -155,52 +156,52 @@ gangSize (Gang n _ _) = n
 -- | Issue work requests for the 'Gang' and wait until they have been executed.
 --   If the gang is already busy then just run the action in the requesting
 --   thread. 
-gangIO :: Gang
-       -> (Int -> IO ())
-       -> IO ()
+gangIO  :: Gang
+        -> (Int -> IO ())
+        -> IO ()
 
 gangIO (Gang n [] _)  p 
  = mapM_ p [0 .. n-1]
 
 #if SEQ_IF_GANG_BUSY
 gangIO (Gang n mvs busy) p 
- = do  traceGang   "gangIO: issuing work requests (SEQ_IF_GANG_BUSY)"
-       b <- swapMVar busy True
-
-       traceGang $ "gangIO: gang is currently " ++ (if b then "busy" else "idle")
-       if b
-        then mapM_ p [0 .. n-1]
-        else do
-               parIO n mvs p
-               _ <- swapMVar busy False
-               return ()
+ = do   traceGang   "gangIO: issuing work requests (SEQ_IF_GANG_BUSY)"
+        b <- swapMVar busy True
+
+        traceGang $ "gangIO: gang is currently " ++ (if b then "busy" else "idle")
+        if b
+         then mapM_ p [0 .. n-1]
+         else do
+                parIO n mvs p
+                _ <- swapMVar busy False
+                return ()
 #else
 gangIO (Gang n mvs busy) p = parIO n mvs p
 #endif
 
 
 -- | Issue some requests to the worker threads and wait for them to complete.
-parIO  :: Int                  -- ^ Number of threads in the gang.
-       -> [MVar Req]           -- ^ Request vars for worker threads.
-       -> (Int -> IO ())       -- ^ Action to run in all the workers, it's
+parIO   :: Int                  -- ^ Number of threads in the gang.
+        -> [MVar Req]           -- ^ Request vars for worker threads.
+        -> (Int -> IO ())       -- ^ Action to run in all the workers, it's
                                 --   given the ix of the particular worker
                                 ---  thread it's running on.
-       -> IO ()
+        -> IO ()
 
 parIO n mvs p 
- = do  traceGang "parIO: begin"
+ = do   traceGang "parIO: begin"
 
-       start   <- getGangTime
-       reqs    <- sequence . replicate n $ newReq p
+        start   <- getGangTime
+        reqs    <- sequence . replicate n $ newReq p
 
-       traceGang "parIO: issuing requests"
-       zipWithM_ putMVar mvs reqs
+        traceGang "parIO: issuing requests"
+        zipWithM_ putMVar mvs reqs
 
-       traceGang "parIO: waiting for requests to complete"
-       mapM_ waitReq reqs
-       end     <- getGangTime
+        traceGang "parIO: waiting for requests to complete"
+        mapM_ waitReq reqs
+        end     <- getGangTime
 
-       traceGang $ "parIO: end " ++ diffTime start end
+        traceGang $ "parIO: end " ++ diffTime start end
 
 
 -- | Same as 'gangIO' but in the 'ST' monad.
@@ -212,8 +213,8 @@ gangST g p = unsafeIOToST . gangIO g $ unsafeSTToIO . p
 #if TRACE_GANG
 getGangTime :: IO Integer
 getGangTime
- = do  TOD sec pico <- getClockTime
-       return (pico + sec * 1000000000000)
+ = do   TOD sec pico <- getClockTime
+        return (pico + sec * 1000000000000)
 
 diffTime :: Integer -> Integer -> String
 diffTime x y = show (y-x)
@@ -221,8 +222,8 @@ diffTime x y = show (y-x)
 -- | Emit a GHC event for debugging.
 traceGang :: String -> IO ()
 traceGang s
- = do  t <- getGangTime
-       traceEventIO $ show t ++ " @ " ++ s
+ = do   t <- getGangTime
+        traceEventIO $ show t ++ " @ " ++ s
 
 #else
 getGangTime :: IO ()
@@ -240,4 +241,3 @@ traceGang _ = return ()
 -- | Emit a GHC event for debugging, in the `ST` monad.
 traceGangST :: String -> ST s ()
 traceGangST s = unsafeIOToST (traceGang s)
-
diff --git a/dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Primitive/Operators.hs b/dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Primitive/Operators.hs
new file mode 100644 (file)
index 0000000..9dc629f
--- /dev/null
@@ -0,0 +1,112 @@
+
+-- Primitive Gang Operators are fundamental computations that run on the gang.
+--   At runtime we can record how long each one runs using GHC events.
+--   As Gang Operators are not inlined, fusion between them is done via GHC rewrite rules.
+
+-- TODO: rename these to generateG etc, to highlight the fusion level.
+{-# OPTIONS -Wall -fno-warn-orphans -fno-warn-missing-signatures #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE CPP #-}
+#include "fusion-phases.h"
+
+-- | Standard combinators for distributed types.
+module Data.Array.Parallel.Unlifted.Distributed.Primitive.Operators 
+        ( generateD
+        , generateD_cheap
+        , imapD'
+        , foldD
+        , scanD)
+where
+import Data.Array.Parallel.Base ( ST, runST)
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.DistST
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.DT
+import Data.Array.Parallel.Unlifted.Distributed.Primitive.Gang
+import Data.Array.Parallel.Unlifted.Distributed.What
+import Debug.Trace
+
+here s = "Data.Array.Parallel.Unlifted.Distributed.Combinators." ++ s
+
+
+-- | Create a distributed value, given a function to create the instance
+--   for each thread.
+generateD 
+        :: DT a 
+        => What         -- ^ What is the worker function doing.
+        -> Gang 
+        -> (Int -> a) 
+        -> Dist a
+
+generateD what g f 
+        = traceEvent (show $ CompGenerate False what) 
+        $ runDistST g (myIndex >>= return . f)
+{-# NOINLINE generateD #-}
+
+
+-- | Create a distributed value, but do it sequentially.
+--  
+--   This function is used when we want to operate on a distributed value, but
+--   there isn't much data involved. For example, if we want to distribute 
+--   a single integer to each thread, then there's no need to fire up the 
+--   gang for this.
+--   
+generateD_cheap 
+        :: DT a 
+        => What          -- ^ What is the worker function doing.
+        -> Gang 
+        -> (Int -> a) 
+        -> Dist a
+
+generateD_cheap what g f 
+        = traceEvent (show $ CompGenerate True what) 
+        $ runDistST_seq g (myIndex >>= return . f)
+{-# NOINLINE generateD_cheap #-}
+
+
+-- Mapping --------------------------------------------------------------------
+-- | Map a function across all elements of a distributed value.
+--   The worker function also gets the current thread index.
+imapD'  :: (DT a, DT b) 
+        => What -> Gang -> (Int -> a -> b) -> Dist a -> Dist b
+imapD' what gang f !d 
+  = traceEvent (show (CompMap $ what))
+  $ runDistST gang 
+        (do i <- myIndex
+            x <- myD d
+            return (f i x))
+{-# NOINLINE imapD' #-}
+
+
+-- Folding --------------------------------------------------------------------
+-- | Fold all the instances of a distributed value.
+foldD :: DT a => Gang -> (a -> a -> a) -> Dist a -> a
+foldD g f !d 
+  = checkGangD ("here foldD") g d 
+  $ fold 1 (indexD (here "foldD") d 0)
+  where
+    !n = gangSize g
+    --
+    fold i x | i == n    = x
+             | otherwise = fold (i+1) (f x $ indexD (here "foldD") d i)
+{-# NOINLINE foldD #-}
+
+
+-- | Prefix sum of the instances of a distributed value.
+scanD :: forall a. DT a => Gang -> (a -> a -> a) -> a -> Dist a -> (Dist a, a)
+scanD g f z !d
+  = checkGangD (here "scanD") g d 
+  $ runST (do
+          md <- newMD g
+          s  <- scan md 0 z
+          d' <- unsafeFreezeMD md
+          return (d',s))
+  where
+    !n = gangSize g
+    
+    scan :: forall s. MDist a s -> Int -> a -> ST s a
+    scan md i !x
+        | i == n    = return x
+        | otherwise
+        = do    writeMD md i x
+                scan md (i+1) (f x $ indexD (here "scanD") d i)
+{-# NOINLINE scanD #-}
+
index 6da257a..3baf5d9 100644 (file)
@@ -8,9 +8,10 @@ module Data.Array.Parallel.Unlifted.Distributed.Scalars
         , orD, andD
         , sumD)
 where
-import Data.Array.Parallel.Unlifted.Distributed.Gang
-import Data.Array.Parallel.Unlifted.Distributed.Types
+import Data.Array.Parallel.Unlifted.Distributed.Data.Unit
+import Data.Array.Parallel.Unlifted.Distributed.Data.Prim
 import Data.Array.Parallel.Unlifted.Distributed.Combinators
+import Data.Array.Parallel.Unlifted.Distributed.Primitive
 
 
 -- | Distribute a scalar.
diff --git a/dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/TheGang.hs b/dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/TheGang.hs
deleted file mode 100644 (file)
index e862b24..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-{-# OPTIONS -Wall -fno-warn-orphans -fno-warn-missing-signatures #-}
-module Data.Array.Parallel.Unlifted.Distributed.TheGang 
-        (theGang)
-where
-import Data.Array.Parallel.Unlifted.Distributed.Gang 
-import Control.Concurrent (getNumCapabilities)
-import System.IO.Unsafe (unsafePerformIO)
-
--- | DPH programs use this single, shared gang of threads.
---   The gang exists at top level, and is initialised at program start.
--- 
---   The vectoriser guarantees that the gang is only used by a single
---   computation at a time. This is true because the program produced
---   by the vector only uses flat parallelism, so parallel computations
---   don't invoke further parallel computations. If the vectorised program
---   tries to use nested parallelism then there is a bug in the vectoriser,
---   and the code will run sequentially.
---
-theGang :: Gang
-theGang = unsafePerformIO (getNumCapabilities >>= forkGang)
-{-# NOINLINE theGang #-}
-
diff --git a/dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types.hs b/dph-prim-par/Data/Array/Parallel/Unlifted/Distributed/Types.hs
deleted file mode 100644 (file)
index 2bf6a24..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-{-# OPTIONS -Wall -fno-warn-orphans -fno-warn-missing-signatures #-}
-{-# LANGUAGE CPP #-}
-#include "fusion-phases.h"
-
--- | Distributed types.
-module Data.Array.Parallel.Unlifted.Distributed.Types 
-        ( module Data.Array.Parallel.Unlifted.Distributed.Types.Vector
-        , module Data.Array.Parallel.Unlifted.Distributed.Types.Maybe
-        , module Data.Array.Parallel.Unlifted.Distributed.Types.Tuple
-        , module Data.Array.Parallel.Unlifted.Distributed.Types.Prim
-        , module Data.Array.Parallel.Unlifted.Distributed.Types.Unit
-        , module Data.Array.Parallel.Unlifted.Distributed.Types.Base)
-where
-import Data.Array.Parallel.Unlifted.Distributed.Types.Vector
-import Data.Array.Parallel.Unlifted.Distributed.Types.Maybe
-import Data.Array.Parallel.Unlifted.Distributed.Types.Tuple
-import Data.Array.Parallel.Unlifted.Distributed.Types.Prim
-import Data.Array.Parallel.Unlifted.Distributed.Types.Unit
-import Data.Array.Parallel.Unlifted.Distributed.Types.Base
-
-
index 3107436..00b8dbb 100644 (file)
@@ -8,14 +8,13 @@ module Data.Array.Parallel.Unlifted.Distributed.USSegd
 where
 import Data.Array.Parallel.Unlifted.Distributed.Arrays
 import Data.Array.Parallel.Unlifted.Distributed.Combinators
-import Data.Array.Parallel.Unlifted.Distributed.Types
-import Data.Array.Parallel.Unlifted.Distributed.Gang
+import Data.Array.Parallel.Unlifted.Distributed.Primitive
 import Data.Array.Parallel.Unlifted.Sequential.USSegd                   (USSegd)
 import Data.Array.Parallel.Unlifted.Sequential.Vector                   (Vector)
 import Data.Array.Parallel.Base
 import Data.Bits                                                        (shiftR)
 import Control.Monad                                                    (when)
-import Data.Array.Parallel.Unlifted.Distributed.Types.USSegd            ()
+import Data.Array.Parallel.Unlifted.Distributed.Data.USSegd            ()
 import qualified Data.Array.Parallel.Unlifted.Sequential.USegd          as USegd
 import qualified Data.Array.Parallel.Unlifted.Sequential.USSegd         as USSegd
 import qualified Data.Array.Parallel.Unlifted.Sequential.Vector         as Seq
index a0f73c2..8e45122 100644 (file)
@@ -12,14 +12,13 @@ module Data.Array.Parallel.Unlifted.Distributed.USegd
 where
 import Data.Array.Parallel.Unlifted.Distributed.Arrays
 import Data.Array.Parallel.Unlifted.Distributed.Combinators
-import Data.Array.Parallel.Unlifted.Distributed.Types
-import Data.Array.Parallel.Unlifted.Distributed.Gang
+import Data.Array.Parallel.Unlifted.Distributed.Primitive
 import Data.Array.Parallel.Unlifted.Sequential.USegd                    (USegd)
 import Data.Array.Parallel.Unlifted.Sequential.Vector                   (Vector, Unbox)
 import Data.Array.Parallel.Base
 import Data.Bits                                                        (shiftR)
 import Control.Monad                                                    (when)
-import qualified Data.Array.Parallel.Unlifted.Distributed.Types.USegd   as DUSegd
+import qualified Data.Array.Parallel.Unlifted.Distributed.Data.USegd   as DUSegd
 import qualified Data.Array.Parallel.Unlifted.Sequential.USegd          as USegd
 import qualified Data.Array.Parallel.Unlifted.Sequential.Vector         as Seq
 
index 7a79477..26d3bef 100644 (file)
@@ -15,32 +15,30 @@ Build-Type:     Simple
 
 Library
   Exposed-Modules:
-        Data.Array.Parallel.Unlifted.Distributed
-        Data.Array.Parallel.Unlifted.Distributed.Gang
-        Data.Array.Parallel.Unlifted.Distributed.TheGang
-        Data.Array.Parallel.Unlifted.Parallel
-        Data.Array.Parallel.Unlifted.Parallel.UPSegd
-        Data.Array.Parallel.Unlifted.Parallel.UPSSegd
-        Data.Array.Parallel.Unlifted.Parallel.UPVSegd
-        Data.Array.Parallel.Unlifted.Parallel.UPSel
-        Data.Array.Parallel.Unlifted
-        Data.Array.Parallel.Unlifted.Distributed.DistST
-        Data.Array.Parallel.Unlifted.Distributed.Types
+        Data.Array.Parallel.Unlifted.Distributed.Primitive.DT
+        Data.Array.Parallel.Unlifted.Distributed.Primitive.DistST
+        Data.Array.Parallel.Unlifted.Distributed.Primitive.Gang
+        Data.Array.Parallel.Unlifted.Distributed.Primitive.Operators
+        Data.Array.Parallel.Unlifted.Distributed.Primitive
+
+        Data.Array.Parallel.Unlifted.Distributed.Data.Maybe
+        Data.Array.Parallel.Unlifted.Distributed.Data.Prim
+        Data.Array.Parallel.Unlifted.Distributed.Data.Tuple
+        Data.Array.Parallel.Unlifted.Distributed.Data.Unit
+        Data.Array.Parallel.Unlifted.Distributed.Data.USegd
+        Data.Array.Parallel.Unlifted.Distributed.Data.USSegd
+        Data.Array.Parallel.Unlifted.Distributed.Data.UVSegd
+        Data.Array.Parallel.Unlifted.Distributed.Data.Vector
+
+        Data.Array.Parallel.Unlifted.Distributed.Arrays
+        Data.Array.Parallel.Unlifted.Distributed.Basics
         Data.Array.Parallel.Unlifted.Distributed.Combinators
         Data.Array.Parallel.Unlifted.Distributed.Scalars
-        Data.Array.Parallel.Unlifted.Distributed.Arrays
         Data.Array.Parallel.Unlifted.Distributed.USegd
         Data.Array.Parallel.Unlifted.Distributed.USSegd
-        Data.Array.Parallel.Unlifted.Distributed.Basics
-        Data.Array.Parallel.Unlifted.Distributed.Types.USegd
-        Data.Array.Parallel.Unlifted.Distributed.Types.USSegd
-        Data.Array.Parallel.Unlifted.Distributed.Types.UVSegd
-        Data.Array.Parallel.Unlifted.Distributed.Types.Vector
-        Data.Array.Parallel.Unlifted.Distributed.Types.Maybe
-        Data.Array.Parallel.Unlifted.Distributed.Types.Tuple
-        Data.Array.Parallel.Unlifted.Distributed.Types.Prim
-        Data.Array.Parallel.Unlifted.Distributed.Types.Unit
-        Data.Array.Parallel.Unlifted.Distributed.Types.Base
+        Data.Array.Parallel.Unlifted.Distributed.What
+        Data.Array.Parallel.Unlifted.Distributed
+
         Data.Array.Parallel.Unlifted.Parallel.Basics
         Data.Array.Parallel.Unlifted.Parallel.Combinators
         Data.Array.Parallel.Unlifted.Parallel.Enum
@@ -50,6 +48,13 @@ Library
         Data.Array.Parallel.Unlifted.Parallel.Subarrays
         Data.Array.Parallel.Unlifted.Parallel.Sums
         Data.Array.Parallel.Unlifted.Parallel.Text
+        Data.Array.Parallel.Unlifted.Parallel.UPSegd
+        Data.Array.Parallel.Unlifted.Parallel.UPSSegd
+        Data.Array.Parallel.Unlifted.Parallel.UPVSegd
+        Data.Array.Parallel.Unlifted.Parallel.UPSel
+        Data.Array.Parallel.Unlifted.Parallel
+
+        Data.Array.Parallel.Unlifted
 
   Exposed: False
 
@@ -60,7 +65,7 @@ Library
 
   GHC-Options:
         -Odph -funbox-strict-fields
-        -fcpr-off -Wall
+        -fcpr-off -Wall -eventlog
 
   Build-Depends:  
         base               == 4.6.*,