Permalink
Browse files

Start on new dph-common-global package that includes global arrays.

  • Loading branch information...
1 parent b00e19d commit 2328495d53a8cd14d310a54e4d5e0753abbf4c73 @benl23x5 benl23x5 committed Jun 30, 2011
@@ -0,0 +1,107 @@
+{-# LANGUAGE
+ TypeOperators, ScopedTypeVariables, ExistentialQuantification,
+ TypeFamilies, Rank2Types, MultiParamTypeClasses,
+ StandaloneDeriving #-}
+
+module Data.Array.Parallel.Lifted.Closure where
+import Data.Array.Parallel.PArray
+
+-- Closures -------------------------------------------------------------------
+infixr 0 :->
+data (a :-> b)
+ = forall env. PM env
+ => Clo (env -> a -> b)
+ (forall m1 m2
+ . (PJ m1 env, PJ m2 a)
+ => Int -> PData m1 env -> PData m2 a -> PData Sized b)
+ env
+
+-- | Closure application.
+($:) :: (a :-> b) -> a -> b
+($:) (Clo fv fl env) x = fv env x
+
+
+-- | Construct an arity-1 closure.
+closure1
+ :: (a -> b)
+ -> (forall m2. PJ m2 a => Int -> PData m2 a -> PData Sized b)
+ -> (a :-> b)
+closure1 fv fl
+ = Clo (\_env -> fv)
+ (\n _env -> fl n)
+ ()
+
+
+-- | Construct an arity-2 closure.
+closure2
+ :: forall a b c. PM a
+ => (a -> b -> c)
+ -> (forall m1 m2
+ . (PJ m1 a, PJ m2 b)
+ => Int -> PData m1 a -> PData m2 b -> PData Sized c)
+ -> (a :-> b :-> c)
+
+closure2 fv fl
+ = let fv_1 :: forall env. env -> a -> (b :-> c)
+ fv_1 _ xa = Clo fv fl xa
+
+ fl_1 :: forall env m1 m2
+ . (PJ m1 env, PJ m2 a)
+ => Int -> PData m1 env -> PData m2 a -> PData Sized (b :-> c)
+
+ fl_1 n _ xs = AClo fv fl (restrictPJ n xs)
+
+ in Clo fv_1 fl_1 ()
+
+
+-- Array Closures -------------------------------------------------------------
+data instance PData m (a :-> b)
+ = forall env. (PJ m env, PM env)
+ => AClo (env -> a -> b)
+ (forall m1 m2
+ . (PJ m1 env, PJ m2 a)
+ => Int -> PData m1 env -> PData m2 a -> PData Sized b)
+ (PData m env)
+
+instance PR (a :-> b) where
+ emptyPR
+ = AClo (\_ _ -> error "empty array closure")
+ (\_ _ -> error "empty array closure")
+ (emptyPR :: PData Sized ())
+
+ appPR = error "appPR[:->] not defined"
+ fromListPR = error "fromListPR[:->] not defined"
+
+
+instance PJ Global (a :-> b) where
+ restrictPJ n (AClo fv fl env)
+ = AClo fv fl (restrictPJ n env)
+
+ indexPJ (AClo fv fl env) ix
+ = Clo fv fl (indexPJ env ix)
+
+
+instance PJ Sized (a :-> b) where
+ restrictPJ n (AClo fv fl env)
+ = AClo fv fl (restrictPJ n env)
+
+ indexPJ (AClo fv fl env) ix
+ = Clo fv fl (indexPJ env ix)
+
+
+instance PE (a :-> b) where
+ repeatPE (Clo fv fl env)
+ = AClo fv fl (repeatPE env)
+
+
+instance PM (a :-> b)
+
+
+-- | Lifted closure application.
+liftedApply
+ :: PJ m2 a
+ => Int -> PData m1 (a :-> b) -> PData m2 a -> PData Sized b
+
+liftedApply n (AClo _ fl envs) as
+ = fl n envs as
+
@@ -0,0 +1,88 @@
+{-# LANGUAGE
+ TypeFamilies, MultiParamTypeClasses,
+ FlexibleInstances, FlexibleContexts,
+ RankNTypes, ExistentialQuantification,
+ StandaloneDeriving, TypeOperators #-}
+
+module Data.Array.Parallel.Lifted.Combinators where
+import Data.Array.Parallel.Lifted.Closure
+import Data.Array.Parallel.PArray
+
+import qualified Data.Vector.Unboxed as V
+import Data.Vector.Unboxed (Vector)
+
+-- fromList -------------------------------------------------------------------
+fromListPA
+ :: PM a
+ => [a] -> PArray a
+fromListPA xs
+ = PArray (length xs) (fromListPR xs)
+
+-- length ---------------------------------------------------------------------
+lengthPA :: PArray a :-> Int
+lengthPA = closure1 lengthPA_v lengthPA_l
+
+-----
+lengthPA_v :: PArray a -> Int
+lengthPA_v (PArray n _) = n
+
+-----
+lengthPA_l :: PJ m (PArray a)
+ => Int -> PData m (PArray a) -> PData Sized Int
+
+lengthPA_l c da
+ = let PNestedS segd _ = restrictPJ c da
+ in undefined -- TODO
+
+
+-- map ------------------------------------------------------------------------
+mapPA :: (PM a, PM b)
+ => (a :-> b) :-> PArray a :-> PArray b
+mapPA = closure2 mapPA_v mapPA_l
+
+-----
+mapPA_v :: (PM a, PM b)
+ => (a :-> b) -> PArray a -> PArray b
+
+mapPA_v (Clo fv fl env) (PArray n as)
+ = PArray n (fl n (repeatPE env) as)
+
+-----
+mapPA_l :: (PJ m1 (a :-> b), PJ m2 (PArray a))
+ => Int -> PData m1 (a :-> b)
+ -> PData m2 (PArray a) -> PData Sized (PArray b)
+
+mapPA_l n clo arr2
+ = let PNestedS segd2 d2 = restrictPJ n arr2
+ in undefined -- TODO
+
+
+-- index ----------------------------------------------------------------------
+indexPA :: PM a => PArray a :-> Int :-> a
+indexPA = closure2 indexPA_v indexPA_l
+
+indexPA_v :: PM a => PArray a -> Int -> a
+indexPA_v (PArray _ d1) ix
+ = indexPJ d1 ix
+
+indexPA_l :: (PJ m1 (PArray a), PJ m2 Int)
+ => Int -> PData m1 (PArray a) -> PData m2 Int -> PData Sized a
+
+indexPA_l n src ixs
+ = case indexlPJ n src (restrictPJ n ixs) of
+ PArray _ d -> d
+
+
+-- plus -----------------------------------------------------------------------
+plusPA :: Int :-> Int :-> Int
+plusPA = closure2 plusPA_v plusPA_l
+
+plusPA_v :: Int -> Int -> Int
+plusPA_v = (+)
+
+plusPA_l :: (PJ m1 Int, PJ m2 Int)
+ => Int -> PData m1 Int -> PData m2 Int -> PData Sized Int
+plusPA_l n d1 d2
+ = let PIntS vec1 = restrictPJ n d1
+ PIntS vec2 = restrictPJ n d2
+ in PIntS (V.zipWith (+) vec1 vec2)
@@ -0,0 +1,8 @@
+
+module Data.Array.Parallel.PArray
+ ( module Data.Array.Parallel.PArray.PData
+ , module Data.Array.Parallel.PArray.PDataInstances)
+where
+import Data.Array.Parallel.PArray.PData
+import Data.Array.Parallel.PArray.PDataInstances
+
@@ -0,0 +1,105 @@
+{-# LANGUAGE
+ TypeFamilies, MultiParamTypeClasses,
+ FlexibleContexts,
+ StandaloneDeriving, UndecidableInstances #-}
+ -- Undeciable instances only for Show instance
+
+module Data.Array.Parallel.PArray.PData where
+import qualified Data.Vector.Unboxed as V
+import Data.Vector.Unboxed (Vector)
+
+-- PArray ---------------------------------------------------------------------
+-- | A parallel array.
+-- PArrays always contain a finite (sized) number of elements, which means
+-- they have a length.
+data PArray a
+ = PArray Int (PData Sized a)
+
+deriving instance (Show (PData Sized a), Show a)
+ => Show (PArray a)
+
+
+-- PData ----------------------------------------------------------------------
+-- | Parallel array data.
+-- As opposed to finite PArrays, a PData can represent a finite or infinite
+-- number of array elements, depending on the mode. The infinite case simply
+-- means that all array indices map to some element value.
+--
+data family PData mode a
+
+-- | An array with a finite size.
+data Sized
+
+-- | An infinite (globalised) array, with the same value for every element.
+-- These are constructed by repeating a single value.
+-- Not all array operations are possible on global arrays, in particular
+-- we cannot take their length, or append global arrays to others.
+data Global
+
+
+-- PS Dictionary (Sized) ------------------------------------------------------
+-- | Contains operations on sized arrays.
+-- For methods that consume source arrays, all elements from the source
+-- may be demanded, and the total work linear in the length of the
+-- source and result arrays.
+--
+class PS a where
+ -- | Produce an empty array with size zero.
+ emptyPS :: PData Sized a
+
+ -- | Append two sized arrays.
+ appPS :: PData Sized a -> PData Sized a -> PData Sized a
+
+ -- | Convert a sized array to a list.
+ fromListPS :: [a] -> PData Sized a
+
+
+-- PJ Dictionary (Projection) -------------------------------------------------
+-- | Contains projection operators.
+-- Projection operators may consume source arrays without demanding all
+-- the elements. These operators are indexed on the mode of the source
+-- arrays, and may have different implementations depending on whether
+-- the source is Sized or Global.
+--
+-- This class has a PS superclass because the instances may also use
+-- operators on sized arrays.
+--
+class PS a => PJ m a where
+ -- | Restrict an array to be a particular size.
+ -- For pre-Sized arrays, instances should simply check that the source
+ -- has the required length, and `error` if it does not. For global arrays,
+ -- we take a finite slice starting from the beginning. If the global array
+ -- is physically represented by a single element, then it's ok to
+ -- physically copy that element to produce the required array length.
+ restrictPJ :: Int -> PData m a -> PData Sized a
+
+ -- | Lookup a single element from the source array.
+ indexPJ :: PData m a -> Int -> a
+
+ -- | Lifted replicate, look up each indexed element from the corresponding
+ -- array. This method only has an instance for the nested case, where
+ -- a = PArray b.
+ indexlPJ :: Int -> PData m a -> PData Sized Int -> a
+
+
+-- PE Dictionary (Expansion) --------------------------------------------------
+-- | Contains expansion operators.
+-- Expansion operators construct infinite arrays from finite data.
+class PE a where
+ -- | Produce a globally defined array with the provided element at every index.
+ -- Physically, this is performed just by storing the provided element once,
+ -- and returning it for every latter indexing operation.
+ repeatPE :: a -> PData Global a
+
+
+-- PR Dictionary (Representation) ---------------------------------------------
+-- | Convenience class to bundle together all the primitive operators
+-- that work on our representation of parallel arrays.
+class (PJ Sized a, PJ Global a, PE a) => PR a
+
+
+-- Derived polymorphic operators ----------------------------------------------
+replicatePR :: PR a => Int -> a -> PData Sized a
+replicatePR n x = restrictPJ n (repeatPE x)
+
+
Oops, something went wrong.

0 comments on commit 2328495

Please sign in to comment.