module Data.Array.Accelerate.CUDA.AST (
module Data.Array.Accelerate.AST,
AccKernel(..), Free, Gamma(..), Idx_(..),
ExecAcc, ExecAfun, ExecOpenAcc(..),
ExecExp, ExecFun, ExecOpenExp, ExecOpenFun,
freevar, makeEnvMap,
) where
import Data.Array.Accelerate.AST
import Data.Array.Accelerate.Pretty
import Data.Array.Accelerate.Array.Sugar ( Array, Shape, Elt )
import qualified Data.Array.Accelerate.CUDA.FullList as FL
import qualified Foreign.CUDA.Driver as CUDA
import qualified Foreign.CUDA.Analysis as CUDA
import Text.PrettyPrint
import Data.Hashable
import Data.Monoid ( Monoid(..) )
import qualified Data.HashSet as Set
import qualified Data.HashMap.Strict as Map
data AccKernel a where
AccKernel :: !String
-> !CUDA.Fun
-> !CUDA.Module
-> !CUDA.Occupancy
-> !Int
-> !Int
-> !(Int -> Int)
-> AccKernel a
type Free aenv = Set.HashSet (Idx_ aenv)
freevar :: (Shape sh, Elt e) => Idx aenv (Array sh e) -> Free aenv
freevar = Set.singleton . Idx_
newtype Gamma aenv = Gamma ( Map.HashMap (Idx_ aenv) Int )
deriving ( Monoid )
makeEnvMap :: Free aenv -> Gamma aenv
makeEnvMap indices
= Gamma
. Map.fromList
. flip zip [0..]
$ Set.toList indices
data Idx_ aenv where
Idx_ :: (Shape sh, Elt e) => Idx aenv (Array sh e) -> Idx_ aenv
instance Eq (Idx_ aenv) where
Idx_ ix1 == Idx_ ix2 = idxToInt ix1 == idxToInt ix2
instance Hashable (Idx_ aenv) where
hashWithSalt salt (Idx_ ix)
= salt `hashWithSalt` idxToInt ix
data ExecOpenAcc aenv a where
ExecAcc :: !(FL.FullList () (AccKernel a))
-> !(Gamma aenv)
-> !(PreOpenAcc ExecOpenAcc aenv a)
-> ExecOpenAcc aenv a
EmbedAcc :: (Shape sh, Elt e)
=> !(PreExp ExecOpenAcc aenv sh)
-> ExecOpenAcc aenv (Array sh e)
type ExecAcc a = ExecOpenAcc () a
type ExecAfun a = PreAfun ExecOpenAcc a
type ExecOpenExp = PreOpenExp ExecOpenAcc
type ExecOpenFun = PreOpenFun ExecOpenAcc
type ExecExp = ExecOpenExp ()
type ExecFun = ExecOpenFun ()
instance Show (ExecOpenAcc aenv a) where
show = render . prettyExecAcc 0 noParens
instance Show (ExecAfun a) where
show = render . prettyExecAfun 0
prettyExecAfun :: Int -> ExecAfun a -> Doc
prettyExecAfun alvl pfun = prettyPreAfun prettyExecAcc alvl pfun
prettyExecAcc :: PrettyAcc ExecOpenAcc
prettyExecAcc alvl wrap exec =
case exec of
EmbedAcc sh ->
wrap $ hang (text "Embedded") 2
$ sep [ prettyPreExp prettyExecAcc 0 alvl parens sh ]
ExecAcc _ (Gamma fv) pacc ->
let base = prettyPreAcc prettyExecAcc alvl wrap pacc
ann = braces (freevars (Map.keys fv))
freevars = (text "fv=" <>) . brackets . hcat . punctuate comma
. map (\(Idx_ ix) -> char 'a' <> int (idxToInt ix))
in
case pacc of
Avar{} -> base
Alet{} -> base
Apply{} -> base
Acond{} -> base
Atuple{} -> base
Aprj{} -> base
_ -> ann <+> base