accelerate-0.4.0: Data/Array/Accelerate/Language.hs
{-# LANGUAGE FlexibleContexts, TypeFamilies, RankNTypes, ScopedTypeVariables #-}
{-# OPTIONS_GHC -fno-warn-missing-methods #-}
-- |Embedded array processing language: user-visible language
--
-- Copyright (c) 2009 Manuel M T Chakravarty, Gabriele Keller, Sean Lee
--
-- License: BSD3
--
--- Description ---------------------------------------------------------------
--
-- We use the dictionary view of overloaded operations (such as arithmetic and
-- bit manipulation) to reify such expressions. With non-overloaded
-- operations (such as, the logical connectives) and partially overloaded
-- operations (such as comparisons), we use the standard operator names with a
-- '*' attached. We keep the standard alphanumeric names as they can be
-- easily qualified.
module Data.Array.Accelerate.Language (
-- * Array and scalar expressions
Acc, Exp, -- re-exporting from 'Smart'
-- * Scalar introduction
constant, -- re-exporting from 'Smart'
-- * Array introduction
use, unit,
-- * Shape manipulation
reshape,
-- * Indexing
(!),
-- * Collective array operations
replicate, zip, map, zipWith, filter, scan, fold, permute, backpermute,
-- * Instances of Bounded, Enum, Eq, Ord, Bits, Num, Real, Floating,
-- Fractional, RealFrac, RealFloat
-- * Methods of H98 classes that we need to redefine as their signatures
-- change
(==*), (/=*), (<*), (<=*), (>*), (>=*), max, min,
-- * Standard functions that we need to redefine as their signatures change
(&&*), (||*), not
) where
-- avoid clashes with Prelude functions
import Prelude hiding (replicate, zip, map, zipWith, filter, max, min, not,
const)
import qualified Prelude
-- standard libraries
import Data.Bits
-- friends
import Data.Array.Accelerate.Type
import Data.Array.Accelerate.Array.Sugar hiding ((!))
import Data.Array.Accelerate.Smart
infixr 2 ||*
infixr 3 &&*
infix 4 ==*, /=*, <*, <=*, >*, >=*
infixl 9 !
-- |Collective operations
-- ----------------------
use :: (Ix dim, Elem e) => Array dim e -> Acc (Array dim e)
use = Use
unit :: Elem e => Exp e -> Acc (Scalar e)
unit = Unit
reshape :: (Ix dim, Ix dim', Elem e)
=> Exp dim
-> Acc (Array dim' e)
-> Acc (Array dim e)
reshape = Reshape
replicate :: forall slix e. (SliceIx slix, Elem e)
=> Exp slix
-> Acc (Array (Slice slix) e)
-> 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)
zip :: (Ix dim, Elem a, Elem b)
=> Acc (Array dim a)
-> Acc (Array dim b)
-> Acc (Array dim (a, b))
zip = zipWith (\x y -> x `Pair` y)
map :: (Ix dim, Elem a, Elem b)
=> (Exp a -> Exp b)
-> Acc (Array dim a)
-> Acc (Array dim b)
map = Map
zipWith :: (Ix dim, Elem a, Elem b, Elem c)
=> (Exp a -> Exp b -> Exp c)
-> Acc (Array dim a)
-> Acc (Array dim b)
-> 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
fold :: Elem a
=> (Exp a -> Exp a -> Exp a)
-> Exp a
-> Acc (Vector a)
-> Acc (Scalar a)
fold = Fold
permute :: (Ix dim, Ix dim', Elem a)
=> (Exp a -> Exp a -> Exp a)
-> Acc (Array dim' a)
-> (Exp dim -> Exp dim')
-> Acc (Array dim a)
-> Acc (Array dim' a)
permute = Permute
backpermute :: (Ix dim, Ix dim', Elem a)
=> Exp dim'
-> (Exp dim' -> Exp dim)
-> Acc (Array dim a)
-> Acc (Array dim' a)
backpermute = Backpermute
-- |Instances of all relevant H98 classes
-- --------------------------------------
instance (Elem t, IsBounded t) => Bounded (Exp t) where
minBound = mkMinBound
maxBound = mkMaxBound
instance (Elem t, IsScalar t) => Enum (Exp t)
-- succ = mkSucc
-- pred = mkPred
-- FIXME: ops
instance (Elem t, IsScalar t) => Prelude.Eq (Exp t)
-- FIXME: instance makes no sense with standard signatures
instance (Elem t, IsScalar t) => Prelude.Ord (Exp t)
-- FIXME: instance makes no sense with standard signatures
instance (Elem t, IsNum t, IsIntegral t) => Bits (Exp t) where
(.&.) = mkBAnd
(.|.) = mkBOr
xor = mkBXor
complement = mkBNot
-- FIXME: argh, the rest have fixed types in their signatures
instance (Elem t, IsNum t) => Num (Exp t) where
(+) = mkAdd
(-) = mkSub
(*) = mkMul
negate = mkNeg
abs = mkAbs
signum = mkSig
fromInteger = constant . fromInteger
instance (Elem t, IsNum t) => Real (Exp t)
-- FIXME: Why did we include this class? We won't need `toRational' until
-- we support rational numbers in AP computations.
instance (Elem t, IsIntegral t) => Integral (Exp t) where
quot = mkQuot
rem = mkRem
div = mkIDiv
mod = mkMod
-- quotRem =
-- divMod =
-- toInteger = -- makes no sense
instance (Elem t, IsFloating t) => Floating (Exp t) where
pi = mkPi
-- FIXME: add other ops
instance (Elem t, IsFloating t) => Fractional (Exp t) where
(/) = mkFDiv
recip = mkRecip
fromRational = exp . fromRational
-- FIXME: add other ops
instance (Elem t, IsFloating t) => RealFrac (Exp t)
-- FIXME: add ops
instance (Elem t, IsFloating t) => RealFloat (Exp t)
-- FIXME: add ops
-- |Methods from H98 classes, where we need other signatures
-- ---------------------------------------------------------
(==*) :: (Elem t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(==*) = mkEq
(/=*) :: (Elem t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(/=*) = mkNEq
-- compare :: a -> a -> Ordering -- we have no enumerations at the moment
-- compare = ...
(<*) :: (Elem t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(<*) = mkLt
(>=*) :: (Elem t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(>=*) = mkGtEq
(>*) :: (Elem t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(>*) = mkGt
(<=*) :: (Elem t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(<=*) = mkLtEq
max :: (Elem t, IsScalar t) => Exp t -> Exp t -> Exp t
max = mkMax
min :: (Elem t, IsScalar t) => Exp t -> Exp t -> Exp t
min = mkMin
-- |Non-overloaded standard functions, where we need other signatures
-- ------------------------------------------------------------------
(&&*) :: Exp Bool -> Exp Bool -> Exp Bool
(&&*) = mkLAnd
(||*) :: Exp Bool -> Exp Bool -> Exp Bool
(||*) = mkLOr
not :: Exp Bool -> Exp Bool
not = mkLNot