accelerate 0.13.0.1 → 0.13.0.2
raw patch · 7 files changed
+160/−121 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- Data/Array/Accelerate.hs +18/−9
- Data/Array/Accelerate/AST.hs +8/−4
- Data/Array/Accelerate/Interpreter.hs +18/−11
- Data/Array/Accelerate/Trafo.hs +21/−26
- Data/Array/Accelerate/Trafo/Sharing.hs +93/−69
- Data/Array/Accelerate/Trafo/Substitution.hs +1/−1
- accelerate.cabal +1/−1
Data/Array/Accelerate.hs view
@@ -9,28 +9,37 @@ -- Portability : non-portable (GHC extensions) -- -- This module defines an embedded language of array computations for--- high-performance computing. Computations on multi-dimensional, regular+-- high-performance computing. Computations on multi-dimensional, regular -- arrays are expressed in the form of parameterised collective operations--- (such as maps, reductions, and permutations). These computations are online+-- (such as maps, reductions, and permutations). These computations are online -- compiled and executed on a range of architectures. ----- /Abstract interface/+-- [/Abstract interface:/] -- -- The types representing array computations are only exported abstractly — -- i.e., client code can generate array computations and submit them for--- for execution, but it cannot inspect these computations. This is to allow--- for more flexibility for future extensions of this library.+-- execution, but it cannot inspect these computations. This is to allow for+-- more flexibility for future extensions of this library. ----- /Code execution/+-- [/Code execution:/] ----- Access to the various backends is via a 'run' function in--- backend-specific toplevel modules. Currently, we have the following:+-- Access to the various backends is via a 'run' function in backend-specific+-- top level modules. Currently, we have the following: -- -- * "Data.Array.Accelerate.Interpreter": simple interpreter in Haskell as a -- reference implementation defining the semantics of the Accelerate language -- -- * "Data.Array.Accelerate.CUDA": an implementation supporting parallel--- execution on CUDA-capable NVIDIA GPUs+-- execution on CUDA-capable NVIDIA GPUs+--+-- [/Examples and documentation:/]+--+-- * A (draft) tutorial is available on the GitHub wiki:+-- <https://github.com/AccelerateHS/accelerate/wiki>+--+-- * The @accelerate-examples@ package demonstrates a range of computational+-- kernels and several complete applications:+-- <http://hackage.haskell.org/package/accelerate-examples> -- module Data.Array.Accelerate (
Data/Array/Accelerate/AST.hs view
@@ -226,11 +226,15 @@ -> acc aenv arrs -> PreOpenAcc acc aenv a - -- Array-function application (to keep things simple for the moment, the function must be closed)+ -- Array-function application.+ --+ -- The array function is not closed at the core level because we need access+ -- to free variables introduced by 'run1' style evaluators. See Issue#95.+ -- Apply :: (Arrays arrs1, Arrays arrs2)- => PreAfun acc (arrs1 -> arrs2)- -> acc aenv arrs1- -> PreOpenAcc acc aenv arrs2+ => PreOpenAfun acc aenv (arrs1 -> arrs2)+ -> acc aenv arrs1+ -> PreOpenAcc acc aenv arrs2 -- Apply a backend-specific foreign function to an array, with a pure -- Accelerate version for use with other backends. The functions must be
Data/Array/Accelerate/Interpreter.hs view
@@ -75,15 +75,17 @@ -- | Prepare and run an embedded array program of one argument -- run1 :: (Arrays a, Arrays b) => (Sugar.Acc a -> Sugar.Acc b) -> a -> b-run1 afun = \a -> exec acc a- where- acc = Sharing.convertAccFun1 True True True afun+run1 = run' - exec :: Afun (a -> b) -> a -> b- exec (Alam (Abody f)) a = force $ evalOpenAcc f (Empty `Push` a)- exec _ _ = error "Hey type checker! We can not get here!" +-- | Prepare an n-ary embedded array program for execution, returning an n-ary+-- closure to do so.+--+run' :: Sharing.Afunction f => f -> Sharing.AfunctionR f+run' afun = let acc = Sharing.convertAfun True True True afun+ in evalOpenAfun acc Empty + -- | Stream a lazily read list of input arrays through the given program, -- collecting results as we go --@@ -95,6 +97,13 @@ -- Array expression evaluation -- --------------------------- +-- Evaluate an open array function+--+evalOpenAfun :: OpenAfun aenv f -> Val aenv -> f+evalOpenAfun (Alam f) aenv = \a -> evalOpenAfun f (aenv `Push` a)+evalOpenAfun (Abody b) aenv = force $ evalOpenAcc b aenv++ -- Evaluate an open array expression -- evalOpenAcc :: OpenAcc aenv a -> Val aenv -> Delayed a@@ -114,11 +123,9 @@ let tup' = force $ evalOpenAcc tup aenv :: arrs in delay $ evalPrj ix (fromTuple tup') -evalPreOpenAcc (Apply (Alam (Abody funAcc)) acc) aenv- = let !arr = force $ evalOpenAcc acc aenv- in evalOpenAcc funAcc (Empty `Push` arr)-evalPreOpenAcc (Apply _afun _acc) _aenv- = error "GHC's pattern match checker is too dumb to figure that this case is impossible"+evalPreOpenAcc (Apply f acc) aenv =+ let !arr = force $ evalOpenAcc acc aenv+ in delay $ evalOpenAfun f aenv arr evalPreOpenAcc (Acond cond acc1 acc2) aenv = if (evalExp cond aenv) then evalOpenAcc acc1 aenv else evalOpenAcc acc2 aenv
Data/Array/Accelerate/Trafo.hs view
@@ -1,5 +1,7 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} {-# OPTIONS_HADDOCK hide #-} -- |@@ -17,8 +19,8 @@ -- * HOAS -> de Bruijn conversion Phase(..), phases, - convertAcc, convertAccWith,- convertAccFun1, convertAccFun1With,+ convertAcc, convertAccWith,+ convertAfun, convertAfunWith, -- * Fusion module Data.Array.Accelerate.Trafo.Fusion,@@ -33,10 +35,11 @@ import Data.Array.Accelerate.Smart import Data.Array.Accelerate.Debug-import Data.Array.Accelerate.Pretty ( ) -- show instances+import Data.Array.Accelerate.Pretty ( ) -- show instances import Data.Array.Accelerate.Array.Sugar ( Arrays, Elt ) import Data.Array.Accelerate.Trafo.Base-import Data.Array.Accelerate.Trafo.Fusion hiding ( convertAcc, convertAfun )+import Data.Array.Accelerate.Trafo.Fusion hiding ( convertAcc, convertAfun ) -- to export types+import Data.Array.Accelerate.Trafo.Sharing ( Function, FunctionR, Afunction, AfunctionR ) import Data.Array.Accelerate.Trafo.Substitution import qualified Data.Array.Accelerate.AST as AST import qualified Data.Array.Accelerate.Trafo.Fusion as Fusion@@ -105,14 +108,14 @@ -- | Convert a unary function over array computations, incorporating sharing -- observation and array fusion ---convertAccFun1 :: (Arrays a, Arrays b) => (Acc a -> Acc b) -> DelayedAfun (a -> b)-convertAccFun1 = convertAccFun1With phases+convertAfun :: Afunction f => f -> DelayedAfun (AfunctionR f)+convertAfun = convertAfunWith phases -convertAccFun1With :: (Arrays a, Arrays b) => Phase -> (Acc a -> Acc b) -> DelayedAfun (a -> b)-convertAccFun1With ok acc+convertAfunWith :: Afunction f => Phase -> f -> DelayedAfun (AfunctionR f)+convertAfunWith ok acc = Fusion.convertAfun -- `when` enableAccFusion $ Rewrite.convertSegmentsAfun `when` convertOffsetOfSegment- $ Sharing.convertAccFun1 (recoverAccSharing ok) (recoverExpSharing ok) (floatOutAccFromExp ok) acc+ $ Sharing.convertAfun (recoverAccSharing ok) (recoverExpSharing ok) (floatOutAccFromExp ok) acc where when f phase | phase ok = f@@ -131,15 +134,10 @@ -- | Convert closed scalar functions, incorporating sharing observation and -- optimisation. ---convertFun1 :: (Elt a, Elt b) => (Exp a -> Exp b) -> AST.Fun () (a -> b)-convertFun1- = Rewrite.simplify- . Sharing.convertFun1 (recoverExpSharing phases)--convertFun2 :: (Elt a, Elt b, Elt c) => (Exp a -> Exp b -> Exp c) -> AST.Fun () (a -> b -> c)-convertFun2+convertFun :: Function f => f -> AST.Fun () (FunctionR f)+convertFun = Rewrite.simplify- . Sharing.convertFun2 (recoverExpSharing phases)+ . Sharing.convertFun (recoverExpSharing phases) -- Pretty printing@@ -148,17 +146,14 @@ instance Arrays arrs => Show (Acc arrs) where show = withSimplStats . show . convertAcc -instance (Arrays a, Arrays b) => Show (Acc a -> Acc b) where- show = withSimplStats . show . convertAccFun1+instance Afunction (Acc a -> f) => Show (Acc a -> f) where+ show = withSimplStats . show . convertAfun instance Elt e => Show (Exp e) where show = withSimplStats . show . convertExp -instance (Elt a, Elt b) => Show (Exp a -> Exp b) where- show = withSimplStats . show . convertFun1--instance (Elt a, Elt b, Elt c) => Show (Exp a -> Exp b -> Exp c) where- show = withSimplStats . show . convertFun2+instance Function (Exp a -> f) => Show (Exp a -> f) where+ show = withSimplStats . show . convertFun -- Debugging
Data/Array/Accelerate/Trafo/Sharing.hs view
@@ -1,7 +1,9 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE PatternGuards #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE PatternGuards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-} {-# OPTIONS_GHC -fno-warn-orphans #-} {-# OPTIONS_GHC -fno-warn-name-shadowing #-} {-# OPTIONS_HADDOCK hide #-}@@ -22,8 +24,8 @@ module Data.Array.Accelerate.Trafo.Sharing ( -- * HOAS -> de Bruijn conversion- convertAcc, convertAccFun1,- convertExp, convertFun1, convertFun2,+ convertAcc, convertAfun, Afunction, AfunctionR,+ convertExp, convertFun, Function, FunctionR ) where @@ -106,6 +108,9 @@ incLayout EmptyLayout = EmptyLayout incLayout (PushLayout lyt ix) = PushLayout (incLayout lyt) (SuccIdx ix) +sizeLayout :: Layout env env' -> Int+sizeLayout EmptyLayout = 0+sizeLayout (PushLayout lyt _) = 1 + sizeLayout lyt -- Conversion from HOAS to de Bruijn computation AST@@ -129,27 +134,46 @@ in convertOpenAcc config 0 [] EmptyLayout acc --- | Convert a unary function over array computations++-- | Convert a closed function over array computations, while incorporating+-- sharing information. ---convertAccFun1- :: forall a b. (Arrays a, Arrays b)- => Bool -- ^ recover sharing of array computations ?- -> Bool -- ^ recover sharing of scalar expressions ?- -> Bool -- ^ always float array computations out of expressions?- -> (Acc a -> Acc b)- -> AST.Afun (a -> b)-convertAccFun1 shareAcc shareExp floatAcc f- = let config = Config shareAcc shareExp (shareAcc && floatAcc)+convertAfun :: Afunction f => Bool -> Bool -> Bool -> f -> AST.Afun (AfunctionR f)+convertAfun shareAcc shareExp floatAcc =+ let config = Config shareAcc shareExp (shareAcc && floatAcc)+ in aconvert config EmptyLayout - lvl = 0- a = Atag lvl- alyt = EmptyLayout- `PushLayout`- (ZeroIdx :: Idx ((), a) a)- openF = convertOpenAcc config (lvl + 1) [lvl] alyt (f (Acc a))- in- Alam (Abody openF) +-- Convert a HOAS fragment into de Bruijn form, binding variables into the typed+-- environment layout one binder at a time.+--+-- NOTE: Because we convert one binder at a time left-to-right, the bound+-- variables ('vars') will have de Bruijn index _zero_ as the outermost+-- binding, and thus go to the end of the list.+--+class Afunction f where+ type AfunctionR f+ aconvert :: Config -> Layout aenv aenv -> f -> AST.OpenAfun aenv (AfunctionR f)++instance (Arrays a, Afunction r) => Afunction (Acc a -> r) where+ type AfunctionR (Acc a -> r) = a -> AfunctionR r+ --+ aconvert config alyt f+ = let a = Acc $ Atag (sizeLayout alyt)+ alyt' = incLayout alyt `PushLayout` ZeroIdx+ in+ Alam $ aconvert config alyt' (f a)++instance Arrays b => Afunction (Acc b) where+ type AfunctionR (Acc b) = b+ --+ aconvert config alyt body+ = let lvl = sizeLayout alyt+ vars = [lvl-1, lvl-2 .. 0]+ in+ Abody $ convertOpenAcc config lvl vars alyt body++ -- | Convert an open array expression to de Bruijn form while also incorporating sharing -- information. --@@ -219,11 +243,9 @@ -> AST.Avar (prjIdx ("de Bruijn conversion tag " ++ show i) i alyt) Pipe afun1 afun2 acc- -> let a = recoverAccSharing config- e = recoverExpSharing config- f = floatOutAcc config- boundAcc = convertAccFun1 a e f afun1 `AST.Apply` convertSharingAcc config alyt aenv acc- bodyAcc = convertAccFun1 a e f afun2 `AST.Apply` AST.OpenAcc (AST.Avar AST.ZeroIdx)+ -> let alyt' = incLayout alyt `PushLayout` ZeroIdx+ boundAcc = aconvert config alyt afun1 `AST.Apply` convertSharingAcc config alyt aenv acc+ bodyAcc = aconvert config alyt' afun2 `AST.Apply` AST.OpenAcc (AST.Avar AST.ZeroIdx) in AST.Alet (AST.OpenAcc boundAcc) (AST.OpenAcc bodyAcc) @@ -232,7 +254,7 @@ e = recoverExpSharing config f = floatOutAcc config in- AST.Aforeign ff (convertAccFun1 a e f afun) (cvtA acc)+ AST.Aforeign ff (convertAfun a e f afun) (cvtA acc) Acond b acc1 acc2 -> AST.Acond (cvtE b) (cvtA acc1) (cvtA acc2) Atuple arrs -> AST.Atuple (convertSharingAtuple config alyt aenv arrs)@@ -311,6 +333,46 @@ +-- Scalar functions+-- ----------------++-- | Convert a closed scalar function to de Bruijn form while incorporating+-- sharing information.+--+-- The current design requires all free variables to be bound at the outermost+-- level --- we have no general apply term, and so lambdas are always outermost.+-- In higher-order abstract syntax, this represents an n-ary, polyvariadic+-- function.+--+convertFun :: Function f => Bool => f -> AST.Fun () (FunctionR f)+convertFun shareExp =+ let config = Config False shareExp False+ in convert config EmptyLayout+++class Function f where+ type FunctionR f+ convert :: Config -> Layout env env -> f -> AST.OpenFun env () (FunctionR f)++instance (Elt a, Function r) => Function (Exp a -> r) where+ type FunctionR (Exp a -> r) = a -> FunctionR r+ --+ convert config lyt f+ = let x = Exp $ Tag (sizeLayout lyt)+ lyt' = incLayout lyt `PushLayout` ZeroIdx+ in+ Lam $ convert config lyt' (f x)++instance Elt b => Function (Exp b) where+ type FunctionR (Exp b) = b+ --+ convert config lyt body+ = let lvl = sizeLayout lyt+ vars = [lvl-1, lvl-2 .. 0]+ in+ Body $ convertOpenExp config lvl vars lyt body++ -- Scalar expressions -- ------------------ @@ -327,44 +389,6 @@ in convertOpenExp config 0 [] EmptyLayout exp --- | Convert a closed scalar function of one parameter to de Bruijn form while--- incorporating sharing information----convertFun1- :: (Elt a, Elt b)- => Bool- -> (Exp a -> Exp b)- -> AST.Fun () (a -> b)-convertFun1 shareExp f- = let config = Config False shareExp False-- lvl = 0- x = Exp (Tag lvl)- lyt = EmptyLayout `PushLayout` ZeroIdx- body = convertOpenExp config (lvl+1) [lvl] lyt (f x)- in- Lam (Body body)---- | Convert a closed scalar function of two parameters to de Bruijn form while--- incorporating sharing information----convertFun2- :: (Elt a, Elt b, Elt c)- => Bool- -> (Exp a -> Exp b -> Exp c)- -> AST.Fun () (a -> b -> c)-convertFun2 shareExp f- = let config = Config False shareExp False-- lvl = 0- x = Exp (Tag (lvl+1))- y = Exp (Tag lvl)- lyt = EmptyLayout `PushLayout` SuccIdx ZeroIdx- `PushLayout` ZeroIdx- body = convertOpenExp config (lvl+2) [lvl, lvl+1] lyt (f x y)- in- Lam (Lam (Body body))- convertOpenExp :: Elt e => Config@@ -432,7 +456,7 @@ LinearIndex a i -> AST.LinearIndex (cvtA a) (cvt i) Shape a -> AST.Shape (cvtA a) ShapeSize e -> AST.ShapeSize (cvt e)- Foreign ff f e -> AST.Foreign ff (convertFun1 (recoverExpSharing config) f) (cvt e)+ Foreign ff f e -> AST.Foreign ff (convertFun (recoverExpSharing config) f) (cvt e) cvtA :: Arrays a => SharingAcc a -> AST.OpenAcc aenv a cvtA = convertSharingAcc config alyt aenv
Data/Array/Accelerate/Trafo/Substitution.hs view
@@ -305,7 +305,7 @@ Avar ix -> accOut (v ix) Atuple tup -> Atuple (rebuildATA rebuild v tup) Aprj tup a -> Aprj tup (rebuild v a)- Apply f a -> Apply f (rebuild v a)+ Apply f a -> Apply (rebuildAfun rebuild v f) (rebuild v a) Aforeign ff afun as -> Aforeign ff afun (rebuild v as) Acond p t e -> Acond (rebuildEA rebuild v p) (rebuild v t) (rebuild v e) Use a -> Use a
accelerate.cabal view
@@ -1,5 +1,5 @@ Name: accelerate-Version: 0.13.0.1+Version: 0.13.0.2 Cabal-version: >= 1.6 Tested-with: GHC >= 7.4.2 Build-type: Custom