accelerate 0.4.0 → 0.5.0.0
raw patch · 13 files changed
+266/−132 lines, 13 files
Files
- Data/Array/Accelerate.hs +8/−4
- Data/Array/Accelerate/AST.hs +49/−43
- Data/Array/Accelerate/Array/Representation.hs +11/−8
- Data/Array/Accelerate/Array/Sugar.hs +10/−8
- Data/Array/Accelerate/Interpreter.hs +14/−12
- Data/Array/Accelerate/Language.hs +67/−33
- Data/Array/Accelerate/Pretty.hs +6/−3
- Data/Array/Accelerate/Smart.hs +33/−17
- Data/Array/Accelerate/Type.hs +1/−1
- accelerate.cabal +2/−1
- examples/simple/Filter.hs +37/−0
- examples/simple/Main.hs +25/−0
- examples/simple/Makefile +3/−2
Data/Array/Accelerate.hs view
@@ -35,10 +35,10 @@ Elem, -- * Array shapes & indices- Ix(..), All(..), SliceIx(..), DIM0, DIM1, DIM2, DIM3, DIM4, DIM5,+ Ix(dim, size), All(..), SliceIx(..), DIM0, DIM1, DIM2, DIM3, DIM4, DIM5, -- * Array operations- shape, indexArray, fromIArray, toIArray, fromList, toList, Arrays,+ arrayShape, indexArray, fromIArray, toIArray, fromList, toList, Arrays, -- * Surface language module Data.Array.Accelerate.Language,@@ -47,10 +47,14 @@ -- friends import Data.Array.Accelerate.Type-import Data.Array.Accelerate.Array.Sugar hiding ((!))+import Data.Array.Accelerate.Array.Sugar hiding ((!), shape) import qualified Data.Array.Accelerate.Array.Sugar as Sugar import Data.Array.Accelerate.Language --- rename as (!) is already used by the EDSL for indexing+-- rename as '(!)' is already used by the EDSL for indexing indexArray :: Array dim e -> dim -> e indexArray = (Sugar.!)++-- rename as 'shape' is already used by the EDSL to query an array's shape+arrayShape :: Ix dim => Array dim e -> dim+arrayShape = Sugar.shape
Data/Array/Accelerate/AST.hs view
@@ -116,11 +116,19 @@ -- Local binding to represent sharing and demand explicitly; this is an -- eager(!) binding- Let :: OpenAcc aenv (Array dim e) -- ^bound expressions - -> OpenAcc (aenv, Array dim e) (Array dim' e') - -- ^the bound expr's scope+ Let :: OpenAcc aenv (Array dim e) -- bound expression+ -> OpenAcc (aenv, Array dim e) + (Array dim' e') -- the bound expr's scope -> OpenAcc aenv (Array dim' e') + -- Variant of 'Let' binding (and decomposing) a pair+ Let2 :: OpenAcc aenv (Array dim1 e1, + Array dim2 e2) -- bound expressions + -> OpenAcc ((aenv, Array dim1 e1), + Array dim2 e2)+ (Array dim' e') -- the bound expr's scope + -> OpenAcc aenv (Array dim' e')+ -- Variable bound by a 'Let', represented by a de Bruijn index Avar :: Idx aenv (Array dim e) -> OpenAcc aenv (Array dim e)@@ -135,26 +143,26 @@ -> OpenAcc aenv (Scalar e) -- Change the shape of an array without altering its contents- -- * precondition: size dim == size dim'+ -- > precondition: size dim == size dim' Reshape :: Ix dim- => Exp aenv dim -- ^new shape- -> OpenAcc aenv (Array dim' e) -- ^array to be reshaped+ => Exp aenv dim -- new shape+ -> OpenAcc aenv (Array dim' e) -- array to be reshaped -> OpenAcc aenv (Array dim e) -- Replicate an array across one or more dimensions as given by the first -- argument Replicate :: Ix dim- => SliceIndex slix sl co dim -- ^slice type specification- -> Exp aenv slix -- ^slice value specification- -> OpenAcc aenv (Array sl e) -- ^data to be replicated+ => SliceIndex slix sl co dim -- slice type specification+ -> Exp aenv slix -- slice value specification+ -> OpenAcc aenv (Array sl e) -- data to be replicated -> OpenAcc aenv (Array dim e) -- Index a subarray out of an array; i.e., the dimensions not indexed are -- returned whole Index :: Ix sl- => SliceIndex slix sl co dim -- ^slice type specification- -> OpenAcc aenv (Array dim e) -- ^array to be indexed- -> Exp aenv slix -- ^slice value specification+ => SliceIndex slix sl co dim -- slice type specification+ -> OpenAcc aenv (Array dim e) -- array to be indexed+ -> Exp aenv slix -- slice value specification -> OpenAcc aenv (Array sl e) -- Apply the given unary function to all elements of the given array@@ -173,17 +181,11 @@ -> OpenAcc aenv (Array dim e2) -> OpenAcc aenv (Array dim e3) - -- Remove all elements from a linear array that do not satisfy the given- -- predicate- Filter :: Fun aenv (e -> ElemRepr Bool) - -> OpenAcc aenv (Vector e)- -> OpenAcc aenv (Vector e)- -- Fold of an array with a given *associative* function and its neutral -- element- Fold :: Fun aenv (e -> e -> e) -- ^combination function- -> Exp aenv e -- ^default value- -> OpenAcc aenv (Array dim e) -- ^folded array+ Fold :: Fun aenv (e -> e -> e) -- combination function+ -> Exp aenv e -- default value+ -> OpenAcc aenv (Array dim e) -- folded array -> OpenAcc aenv (Scalar e) -- FIXME: generalise to Gabi's mapFold @@ -191,9 +193,9 @@ -- function and its neutral element; produces a rightmost fold value and a -- linear of the same shape (the fold value would be the rightmost element -- in a scan, as opposed to a prescan)- Scan :: Fun aenv (e -> e -> e) -- ^combination function- -> Exp aenv e -- ^default value- -> OpenAcc aenv (Vector e) -- ^linear array+ Scan :: Fun aenv (e -> e -> e) -- combination function+ -> Exp aenv e -- default value+ -> OpenAcc aenv (Vector e) -- linear array -> OpenAcc aenv (Vector e, Scalar e) -- FIXME: generalised multi-dimensional scan? And/or a generalised mapScan? @@ -206,20 +208,21 @@ -- some positions in the target array are never picked by the permutation -- functions). Moroever, we have a combination function (in case some -- positions on the target array are picked multiple times by the- -- permutation functions). The combination functions needs to be- -- *associative* and *commutative*. - Permute :: Fun aenv (e -> e -> e) -- ^combination function- -> OpenAcc aenv (Array dim' e) -- ^default values- -> Fun aenv (dim -> dim') -- ^permutation function- -> OpenAcc aenv (Array dim e) -- ^source array+ -- permutation functions). The combination function needs to be+ -- /associative/ and /commutative/ . We drop every element for which the+ -- permutation function yields -1 (i.e., a tuple of -1 values).+ Permute :: Fun aenv (e -> e -> e) -- combination function+ -> OpenAcc aenv (Array dim' e) -- default values+ -> Fun aenv (dim -> dim') -- permutation function+ -> OpenAcc aenv (Array dim e) -- source array -> OpenAcc aenv (Array dim' e) -- Generalised multi-dimensional backwards permutation; the permutation can -- be between arrays of varying shape; the permutation function must be total Backpermute :: Ix dim'- => Exp aenv dim' -- ^dimensions of the result- -> Fun aenv (dim' -> dim) -- ^permutation function- -> OpenAcc aenv (Array dim e) -- ^source array+ => Exp aenv dim' -- dimensions of the result+ -> Fun aenv (dim' -> dim) -- permutation function+ -> OpenAcc aenv (Array dim e) -- source array -> OpenAcc aenv (Array dim' e) -- |Closed array expression aka an array program@@ -246,17 +249,17 @@ -- data OpenExp env aenv t where - -- |Variable index, ranging only over tuples or scalars+ -- Variable index, ranging only over tuples or scalars Var :: ArrayElem t => Idx env t -> OpenExp env aenv t - -- |Constant values+ -- Constant values Const :: Elem t => t -- not converted to ElemRepr yet -> OpenExp env aenv (ElemRepr t) - -- |Tuples+ -- Tuples Pair :: (Elem s, Elem t) => s {- dummy to fix the type variable -} -> t {- dummy to fix the type variable -}@@ -274,30 +277,30 @@ -> OpenExp env aenv (ElemRepr (s, t)) -> OpenExp env aenv (ElemRepr t) - -- |Conditional expression (non-strict in 2nd and 3rd argument)+ -- Conditional expression (non-strict in 2nd and 3rd argument) Cond :: OpenExp env aenv (ElemRepr Bool) -> OpenExp env aenv t -> OpenExp env aenv t -> OpenExp env aenv t - -- |Primitive constants+ -- Primitive constants PrimConst :: Elem t => PrimConst t -> OpenExp env aenv (ElemRepr t) - -- |Primitive scalar operations+ -- Primitive scalar operations PrimApp :: (Elem a, Elem r) => PrimFun (a -> r) -> OpenExp env aenv (ElemRepr a) -> OpenExp env aenv (ElemRepr r) - -- |Project a single scalar from an array- -- * the array expression cannot contain any free scalar variables+ -- Project a single scalar from an array+ -- the array expression cannot contain any free scalar variables IndexScalar :: OpenAcc aenv (Array dim t) -> OpenExp env aenv dim -> OpenExp env aenv t - -- |Array shape- -- * the array expression cannot contain any free scalar variables+ -- Array shape+ -- the array expression cannot contain any free scalar variables Shape :: OpenAcc aenv (Array dim e) -> OpenExp env aenv dim @@ -372,6 +375,9 @@ -- ALSO: need to use overloading -- FIXME: conversions between various integer types+ -- should we have an overloaded functions like 'toInt'? + -- (or 'fromEnum' for enums?)+ PrimBoolToInt :: PrimFun (Bool -> Int) -- FIXME: what do we want to do about Enum? succ and pred are only -- moderatly useful without user-defined enumerations, but we want
Data/Array/Accelerate/Array/Representation.hs view
@@ -47,8 +47,8 @@ -- data Array dim e where Array :: (Ix dim, ArrayElem e) - => dim -- ^extent of dimensions = shape- -> ArrayData e -- ^data+ => dim -- extent of dimensions = shape+ -> ArrayData e -- data -> Array dim e -- |Shorthand for common shape representations@@ -71,17 +71,18 @@ -- |Class of index representations (which are nested pairs) ---class Ix ix where- dim :: ix -> Int -- ^number of dimensions (>= 0)- size :: ix -> Int -- ^for a *shape* yield the total number of +class Eq ix => Ix ix where+ dim :: ix -> Int -- number of dimensions (>= 0)+ size :: ix -> Int -- for a *shape* yield the total number of -- elements in that array- intersect :: ix -> ix -> ix -- ^yield the intersection of two shapes- index :: ix -> ix -> Int -- ^yield the index position in a linear, + intersect :: ix -> ix -> ix -- yield the intersection of two shapes+ ignore :: ix -- identifies ignored elements in 'permute'+ index :: ix -> ix -> Int -- yield the index position in a linear, -- row-major representation of the array -- (first argument is the shape) iter :: ix -> (ix -> a) -> (a -> a -> a) -> a -> a- -- ^iterate through the entire shape, applying+ -- iterate through the entire shape, applying -- the function; third argument combines results -- and fourth is returned in case of an empty -- iteration space; the index space is traversed@@ -96,6 +97,7 @@ dim () = 0 size () = 1 intersect () () = ()+ ignore = () index () () = 0 iter () f _ _ = f () @@ -106,6 +108,7 @@ dim (sh, _) = dim sh + 1 size (sh, sz) = size sh * sz (sh1, sz1) `intersect` (sh2, sz2) = (sh1 `intersect` sh2, sz1 `min` sz2)+ ignore = (ignore, -1) index (sh, sz) (ix, i) | i >= 0 && i < sz = index sh ix + size sh * i | otherwise
Data/Array/Accelerate/Array/Sugar.hs view
@@ -496,8 +496,8 @@ -- data Array dim e where Array :: (Ix dim, Elem e) - => dim -- ^extent of dimensions = shape- -> ArrayData (ElemRepr e) -- ^data, same layout as in+ => dim -- extent of dimensions = shape+ -> ArrayData (ElemRepr e) -- data, same layout as in -> Array dim e -- |Scalars@@ -557,12 +557,13 @@ -- |Indices as n-tuples -- class (Shape ix, Repr.Ix (ElemRepr ix)) => Ix ix where- dim :: ix -> Int -- ^number of dimensions (>= 0)- size :: ix -> Int -- ^for a *shape* yield the total number of - -- elements in that array- index :: ix -> ix -> Int -- ^corresponding index into a linear, row-major - -- representation of the array (first argument- -- is the shape)+ dim :: ix -> Int -- number of dimensions (>= 0)+ size :: ix -> Int -- for a *shape* yield the total number of + -- elements in that array+ ignore :: ix -- identifies ignored elements in 'permute'+ index :: ix -> ix -> Int -- corresponding index into a linear, row-major + -- representation of the array (first argument+ -- is the shape) rangeToShape :: (ix, ix) -> ix -- convert a minpoint-maxpoint index -- into a shape@@ -570,6 +571,7 @@ dim = Repr.dim . fromElem size = Repr.size . fromElem+ ignore = toElem Repr.ignore index sh ix = Repr.index (fromElem sh) (fromElem ix) rangeToShape (low, high)
Data/Array/Accelerate/Interpreter.hs view
@@ -21,6 +21,7 @@ ) where -- standard libraries+import Control.Monad import Data.Bits import Data.Char (chr, ord) @@ -72,6 +73,10 @@ = let !arr1 = force $ evalOpenAcc acc1 aenv in evalOpenAcc acc2 (aenv `Push` arr1) +evalOpenAcc (Let2 acc1 acc2) aenv + = let (!arr1, !arr2) = force $ evalOpenAcc acc1 aenv+ in evalOpenAcc acc2 (aenv `Push` arr1 `Push` arr2)+ evalOpenAcc (Avar idx) aenv = delay $ prj idx aenv evalOpenAcc (Use arr) _aenv = delay arr@@ -92,9 +97,6 @@ evalOpenAcc (ZipWith f acc1 acc2) aenv = zipWithOp (evalFun f aenv) (evalOpenAcc acc1 aenv) (evalOpenAcc acc2 aenv) -evalOpenAcc (Filter p acc) aenv- = filterOp (evalFun p aenv) (evalOpenAcc acc aenv)- evalOpenAcc (Fold f e acc) aenv = foldOp (evalFun f aenv) (evalExp e aenv) (evalOpenAcc acc aenv) @@ -193,12 +195,6 @@ zipWithOp f (DelayedArray sh1 rf1) (DelayedArray sh2 rf2) = DelayedArray (sh1 `intersect` sh2) (\ix -> f (rf1 ix) (rf2 ix)) -filterOp :: (e -> Sugar.ElemRepr Bool)- -> Delayed (Vector e)- -> Delayed (Vector e)-filterOp p (DelayedArray sh rf)- = error "Data.Array.Accelerate.Interpreter: filter: not yet implemented"- foldOp :: (e -> e -> e) -> e -> Delayed (Array dim e)@@ -247,9 +243,11 @@ -- the target dimension (where it gets combined with the current -- default) let update ix = do- let i = index dftsSh (p ix)- e <- readArrayData arr i- writeArrayData arr i (pf ix `f` e) + let target = p ix+ unless (target == ignore) $ do+ let i = index dftsSh target+ e <- readArrayData arr i+ writeArrayData arr i (pf ix `f` e) iter sh update (>>) (return ()) -- return the updated array@@ -370,6 +368,7 @@ evalPrim PrimRoundFloatInt = evalRoundFloatInt evalPrim PrimTruncFloatInt = evalTruncFloatInt evalPrim PrimIntFloat = evalIntFloat+evalPrim PrimBoolToInt = evalBoolToInt -- Pairing@@ -426,6 +425,9 @@ evalIntFloat :: Int -> Float evalIntFloat = fromIntegral++evalBoolToInt :: Bool -> Int+evalBoolToInt = fromEnum -- Extract methods from reified dictionaries
Data/Array/Accelerate/Language.hs view
@@ -30,12 +30,15 @@ -- * Shape manipulation reshape, - -- * Indexing- (!),- -- * Collective array operations- replicate, zip, map, zipWith, filter, scan, fold, permute, backpermute,+ slice, replicate, zip, map, zipWith, scan, fold, permute, backpermute, + -- * Conditional expressions+ (?),+ + -- * Array operations with a scalar result+ (!), shape,+ -- * Instances of Bounded, Enum, Eq, Ord, Bits, Num, Real, Floating, -- Fractional, RealFrac, RealFloat @@ -44,7 +47,13 @@ (==*), (/=*), (<*), (<=*), (>*), (>=*), max, min, -- * Standard functions that we need to redefine as their signatures change- (&&*), (||*), not+ (&&*), (||*), not,+ + -- * Conversions+ boolToInt,+ + -- * Constants+ ignore ) where @@ -58,18 +67,13 @@ -- friends import Data.Array.Accelerate.Type-import Data.Array.Accelerate.Array.Sugar hiding ((!))+import Data.Array.Accelerate.Array.Sugar hiding ((!), ignore, shape)+import qualified Data.Array.Accelerate.Array.Sugar as Sugar import Data.Array.Accelerate.Smart -infixr 2 ||*-infixr 3 &&*-infix 4 ==*, /=*, <*, <=*, >*, >=*-infixl 9 !----- |Collective operations--- ----------------------+-- Collective operations+-- --------------------- use :: (Ix dim, Elem e) => Array dim e -> Acc (Array dim e) use = Use@@ -89,11 +93,11 @@ -> Acc (Array (SliceDim slix) e) replicate = Replicate (undefined::slix) (undefined::e) -(!) :: forall slix e. (SliceIx slix, Elem e) - => Acc (Array (SliceDim slix) e) - -> Exp slix - -> Acc (Array (Slice slix) e)-(!) = Index (undefined::slix) (undefined::e) +slice :: forall slix e. (SliceIx slix, Elem e) + => Acc (Array (SliceDim slix) e) + -> Exp slix + -> Acc (Array (Slice slix) e)+slice = Index (undefined::slix) (undefined::e) zip :: (Ix dim, Elem a, Elem b) => Acc (Array dim a)@@ -114,18 +118,12 @@ -> Acc (Array dim c) zipWith = ZipWith -filter :: Elem a - => (Exp a -> Exp Bool) - -> Acc (Vector a) - -> Acc (Vector a)-filter = Filter- scan :: Elem a => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Vector a)- -> Acc (Vector a, Scalar a)-scan = Scan+ -> (Acc (Vector a), Acc (Scalar a))+scan f e arr = unpair (Scan f e arr) fold :: Elem a => (Exp a -> Exp a -> Exp a) @@ -150,9 +148,28 @@ backpermute = Backpermute --- |Instances of all relevant H98 classes--- --------------------------------------+-- Conditional expressions+-- ----------------------- +infix 0 ?+(?) :: Elem t => Exp Bool -> (Exp t, Exp t) -> Exp t+c ? (t, e) = Cond c t e+++-- Array operations with a scalar result+-- -------------------------------------++infixl 9 !+(!) :: (Ix dim, Elem e) => Acc (Array dim e) -> Exp dim -> Exp e+(!) = IndexScalar++shape :: Ix dim => Acc (Array dim e) -> Exp dim+shape = Shape+++-- Instances of all relevant H98 classes+-- -------------------------------------+ instance (Elem t, IsBounded t) => Bounded (Exp t) where minBound = mkMinBound maxBound = mkMaxBound@@ -214,9 +231,11 @@ -- FIXME: add ops --- |Methods from H98 classes, where we need other signatures--- ---------------------------------------------------------+-- Methods from H98 classes, where we need other signatures+-- -------------------------------------------------------- +infix 4 ==*, /=*, <*, <=*, >*, >=*+ (==*) :: (Elem t, IsScalar t) => Exp t -> Exp t -> Exp Bool (==*) = mkEq @@ -245,15 +264,30 @@ min = mkMin --- |Non-overloaded standard functions, where we need other signatures--- ------------------------------------------------------------------+-- Non-overloaded standard functions, where we need other signatures+-- ----------------------------------------------------------------- +infixr 3 &&* (&&*) :: Exp Bool -> Exp Bool -> Exp Bool (&&*) = mkLAnd +infixr 2 ||* (||*) :: Exp Bool -> Exp Bool -> Exp Bool (||*) = mkLOr not :: Exp Bool -> Exp Bool not = mkLNot ++-- Conversions+-- -----------++boolToInt :: Exp Bool -> Exp Int+boolToInt = mkBoolToInt+++-- Constants+-- ---------++ignore :: Ix dim => Exp dim+ignore = constant Sugar.ignore
Data/Array/Accelerate/Pretty.hs view
@@ -45,8 +45,12 @@ -- prettyAcc :: Int -> OpenAcc aenv a -> Doc prettyAcc lvl (Let acc1 acc2) - = text "let a" <> int lvl <+> text " = " <+> prettyAcc lvl acc1 <+>+ = text "let a" <> int lvl <+> char '=' <+> prettyAcc lvl acc1 <+> text " in " <+> prettyAcc (lvl + 1) acc2+prettyAcc lvl (Let2 acc1 acc2) + = text "let (a" <> int lvl <> text ", a" <> int (lvl + 1) <+> char '=' <+>+ prettyAcc lvl acc1 <+>+ text " in " <+> prettyAcc (lvl + 2) acc2 prettyAcc _ (Avar idx) = text $ "a" ++ show (idxToInt idx) prettyAcc _ (Use arr) = prettyArrOp "use" [prettyArray arr] prettyAcc lvl (Unit e) = prettyArrOp "unit" [prettyExp lvl parens e]@@ -62,8 +66,6 @@ = prettyArrOp "zipWith" [parens (prettyFun lvl f), prettyAccParens lvl acc1, prettyAccParens lvl acc2]-prettyAcc lvl (Filter p acc) - = prettyArrOp "filter" [parens (prettyFun lvl p), prettyAccParens lvl acc] prettyAcc lvl (Fold f e acc) = prettyArrOp "fold" [parens (prettyFun lvl f), prettyExp lvl parens e, prettyAccParens lvl acc]@@ -176,6 +178,7 @@ prettyPrim PrimRoundFloatInt = text "round" prettyPrim PrimTruncFloatInt = text "trunc" prettyPrim PrimIntFloat = text "intFloat"+prettyPrim PrimBoolToInt = text "boolToInt" {- -- Pretty print type
Data/Array/Accelerate/Smart.hs view
@@ -20,6 +20,9 @@ -- * HOAS -> de Bruijn conversion convertAcc, convertClosedExp,+ + -- * Smart constructors for unpairing+ unpair, -- * Smart constructors for literals constant,@@ -30,7 +33,7 @@ -- * Smart constructors for primitive functions mkAdd, mkSub, mkMul, mkNeg, mkAbs, mkSig, mkQuot, mkRem, mkIDiv, mkMod, mkBAnd, mkBOr, mkBXor, mkBNot, mkFDiv, mkRecip, mkLt, mkGt, mkLtEq, mkGtEq,- mkEq, mkNEq, mkMax, mkMin, mkLAnd, mkLOr, mkLNot,+ mkEq, mkNEq, mkMax, mkMin, mkLAnd, mkLOr, mkLNot, mkBoolToInt ) where @@ -40,10 +43,6 @@ -- friends import Data.Array.Accelerate.Type-{--import Data.Array.Accelerate.Array.Representation hiding (- Array(..), Scalar, Vector)--} import Data.Array.Accelerate.Array.Sugar import Data.Array.Accelerate.AST hiding (OpenAcc(..), Acc, OpenExp(..), Exp) import qualified Data.Array.Accelerate.AST as AST@@ -54,6 +53,11 @@ -- -------------------------- data Acc a where+ + FstArray :: Acc (Array dim1 e1, Array dim2 e2)+ -> Acc (Array dim1 e1)+ SndArray :: Acc (Array dim1 e1, Array dim2 e2)+ -> Acc (Array dim2 e2) Use :: Array dim e -> Acc (Array dim e) Unit :: Elem e@@ -84,10 +88,6 @@ -> Acc (Array dim e1) -> Acc (Array dim e2) -> Acc (Array dim e3)- Filter :: Elem e- => (Exp e -> Exp Bool) - -> Acc (Vector e)- -> Acc (Vector e) Fold :: Elem e => (Exp e -> Exp e -> Exp e) -> Exp e@@ -119,6 +119,10 @@ convertOpenAcc :: Layout aenv aenv -> Acc a -> AST.OpenAcc aenv (ArraysRepr a)+convertOpenAcc alyt (FstArray acc)+ = AST.Let2 (convertOpenAcc alyt acc) (AST.Avar (AST.SuccIdx AST.ZeroIdx))+convertOpenAcc alyt (SndArray acc)+ = AST.Let2 (convertOpenAcc alyt acc) (AST.Avar AST.ZeroIdx) convertOpenAcc _ (Use array) = AST.Use (fromArray array) convertOpenAcc alyt (Unit e) = AST.Unit (convertExp alyt e) convertOpenAcc alyt (Reshape e acc) @@ -134,8 +138,6 @@ = AST.ZipWith (convertFun2 alyt f) (convertOpenAcc alyt acc1) (convertOpenAcc alyt acc2)-convertOpenAcc alyt (Filter p acc) - = AST.Filter (convertFun1 alyt p) (convertOpenAcc alyt acc) convertOpenAcc alyt (Fold f e acc) = AST.Fold (convertFun2 alyt f) (convertExp alyt e) (convertOpenAcc alyt acc) convertOpenAcc alyt (Scan f e acc) @@ -309,14 +311,22 @@ -- |Smart constructors to construct HOAS AST expressions -- ----------------------------------------------------- --- |Smart constructor for literals--- -+-- Pushes the 'Acc' constructor through a pair+--+unpair :: (Ix dim1, Ix dim2, Elem e1, Elem e2)+ => Acc (Array dim1 e1, Array dim2 e2) + -> (Acc (Array dim1 e1), Acc (Array dim2 e2))+unpair acc = (FstArray acc, SndArray acc) ++-- Smart constructor for literals+-- + constant :: Elem t => t -> Exp t constant = Const --- |Smart constructor for constants--- -+-- Smart constructor for constants+-- mkMinBound :: (Elem t, IsBounded t) => Exp t mkMinBound = PrimConst (PrimMinBound boundedType)@@ -327,8 +337,8 @@ mkPi :: (Elem r, IsFloating r) => Exp r mkPi = PrimConst (PrimPi floatingType) --- |Smart constructors for primitive applications--- -+-- Smart constructors for primitive applications+-- -- Operators from Num @@ -426,3 +436,9 @@ -- FIXME: Character conversions -- FIXME: Numeric conversions++-- FIXME: Other conversions++mkBoolToInt :: Exp Bool -> Exp Int+mkBoolToInt b = PrimBoolToInt `PrimApp` b+
Data/Array/Accelerate/Type.hs view
@@ -97,7 +97,7 @@ -- |Non-numeric types supported in array computations. -- data NonNumType a where- TypeBool :: NonNumDict Bool -> NonNumType Bool -- ^marshaled to CInt+ TypeBool :: NonNumDict Bool -> NonNumType Bool -- marshaled to CInt TypeChar :: NonNumDict Char -> NonNumType Char TypeCChar :: NonNumDict CChar -> NonNumType CChar TypeCSChar :: NonNumDict CSChar -> NonNumType CSChar
accelerate.cabal view
@@ -1,5 +1,5 @@ Name: accelerate-Version: 0.4.0+Version: 0.5.0.0 Cabal-version: >= 1.6 Tested-with: GHC >= 6.10.1 @@ -38,6 +38,7 @@ Data.Array.Accelerate.Type Extra-source-files: INSTALL examples/simple/DotP.hs+ examples/simple/Filter.hs examples/simple/Main.hs examples/simple/Makefile examples/simple/SAXPY.hs
+ examples/simple/Filter.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE FlexibleContexts #-}++module Filter (filter, filter_ref) where++import Prelude hiding (replicate, zip, map, filter, max, min, not, zipWith)+import qualified Prelude++import Data.Array.Unboxed (UArray)+import Data.Array.IArray (IArray)+import qualified Data.Array.IArray as IArray++import Data.Array.Accelerate++filter :: Elem a + => (Exp a -> Exp Bool) + -> Acc (Vector a)+ -> Acc (Vector a)+filter p arr+ = let flags = map (boolToInt . p) arr+ (targetIdx, length) = scan (+) 0 flags+ arr' = backpermute (length!(constant ())) id arr+ in+ permute const arr' (\ix -> flags!ix ==* 0 ? (ignore, targetIdx!ix)) arr+ -- FIXME: This is abusing 'permute' in that the first two arguments are+ -- only justified because we know the permutation function will+ -- write to each location in the target exactly once.+ -- Instead, we should have a primitive that directly encodes the+ -- compaction pattern of the permutation function.++filter_ref :: IArray UArray e + => (e -> Bool)+ -> UArray Int e + -> UArray Int e+filter_ref p xs+ = let xs' = Prelude.filter p (IArray.elems xs)+ in+ IArray.listArray (0, length xs' - 1) xs'
examples/simple/Main.hs view
@@ -2,6 +2,8 @@ module Main where +import Prelude hiding (filter)+ import Control.Exception import Data.Array.Unboxed import Data.Array.IArray@@ -13,6 +15,7 @@ import Time import SAXPY import DotP+import Filter -- Auxilliary array functions@@ -211,6 +214,27 @@ {-# NOINLINE dotp_interp #-} dotp_interp arr1 arr2 () = Interp.run (dotp arr1 arr2) +test_filter :: Int -> IO ()+test_filter n+ = do+ putStrLn "== Filter"+ putStrLn $ "Generating data (n = " ++ show n ++ ")..."+ v_ref <- randomUVector n+ v <- convertUVector v_ref+ putStrLn "Running reference code..."+ ref_result <- timeUVector $ filter_ref' (< 0) v_ref+ putStrLn "Running Accelerate code..."+ result <- timeVector $ filter_interp (Acc.<* Acc.constant 0) (Acc.use v)+ putStrLn "Validating result..."+ validateFloats ref_result result+ where+ -- idiom with NOINLINE and extra parameter needed to prevent optimisations+ -- from sharing results over multiple runs+ {-# NOINLINE filter_ref' #-}+ filter_ref' p arr () = filter_ref p arr+ {-# NOINLINE filter_interp #-}+ filter_interp p arr () = Interp.run (filter p arr)+ main :: IO () main = do@@ -219,3 +243,4 @@ test_saxpy 100000 test_dotp 100000+ test_filter 2000
examples/simple/Makefile view
@@ -4,9 +4,10 @@ ghc $(HCFLAGS) -c Time.hs ghc $(HCFLAGS) -c SAXPY.hs ghc $(HCFLAGS) -c DotP.hs+ ghc $(HCFLAGS) -c Filter.hs ghc $(HCFLAGS) -c Main.hs- ghc $(HCFLAGS) -o test Main.o Time.o SAXPY.o DotP.o+ ghc $(HCFLAGS) -o test Main.o Time.o SAXPY.o DotP.o Filter.o clean:- rm -f *.o *.hi time+ rm -f *.o *.hi test