Skip to content

Accelerate Quick Reference

Accelerate is the Haskell EDSL used in all course practicals for data-parallel GPU programming.

Core Types

-- Scalar expression (runs on GPU)
Exp a

-- Parallel array (runs on GPU)
Acc (Array sh a)

-- Shape types (dimensionality)
Z                    -- 0-dimensional (scalar)
Z :. Int             -- 1-dimensional (DIM1 = Vector)
Z :. Int :. Int      -- 2-dimensional (DIM2 = Matrix)

-- Type aliases
type Scalar a = Array DIM0 a     -- single value
type Vector a = Array DIM1 a     -- 1D array
type Matrix a = Array DIM2 a     -- 2D array

Lifting Values

-- Lift a Haskell value into an Exp
constant :: Elt a => a -> Exp a

-- Create an Acc array from a Haskell list
use :: Array sh a -> Acc (Array sh a)

-- Extract result from GPU back to Haskell
run :: Acc a -> a

Key Combinators

-- Element-wise
map      :: (Exp a -> Exp b) -> Acc (Array sh a) -> Acc (Array sh b)
zipWith  :: (Exp a -> Exp b -> Exp c) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c)
imap     :: (Exp sh -> Exp a -> Exp b) -> Acc (Array sh a) -> Acc (Array sh b)

-- Reductions
fold     :: (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array sh a)
fold1    :: (Exp a -> Exp a -> Exp a) -> Acc (Array (sh :. Int) a) -> Acc (Array sh a)

-- Scans
scanl    :: (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Vector a) -> Acc (Vector a)
scanr    :: (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Vector a) -> Acc (Vector a)
scanl'   :: (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Vector a) -> (Acc (Vector a), Acc (Scalar a))

-- Index manipulation
backpermute :: Exp sh' -> (Exp sh' -> Exp sh) -> Acc (Array sh a) -> Acc (Array sh' a)
permute     :: (Exp a -> Exp a -> Exp a) -> Acc (Array sh' a) -> (Exp sh -> Exp sh') -> Acc (Array sh a) -> Acc (Array sh' a)

-- Stencil
stencil  :: (Stencil sh a -> Exp b) -> Boundary (Array sh a) -> Acc (Array sh a) -> Acc (Array sh b)

-- Shape / indexing
shape    :: Acc (Array sh a) -> Exp sh
index1   :: Exp Int -> Exp DIM1
unindex1 :: Exp DIM1 -> Exp Int
index2   :: Exp Int -> Exp Int -> Exp DIM2
unindex2 :: Exp DIM2 -> (Exp Int, Exp Int)

-- Array construction
generate :: Exp sh -> (Exp sh -> Exp a) -> Acc (Array sh a)
fill     :: Exp sh -> Exp a -> Acc (Array sh a)
enumFromN :: Exp sh -> Exp a -> Acc (Array sh a)

Stencil Patterns

-- 1D stencil (3-element neighborhood)
type Stencil3 a = (Exp a, Exp a, Exp a)  -- (left, center, right)

-- 2D stencil (3x3 neighborhood)
type Stencil3x3 a = (Stencil3 a, Stencil3 a, Stencil3 a)

-- Boundary conditions
Clamp    -- replicate edge values
Mirror   -- reflect at boundary
Wrap     -- wrap around (periodic)
Constant :: a -> Boundary a  -- use a fixed value

Common Patterns

-- Sum all elements
total :: Acc (Vector Int) -> Acc (Scalar Int)
total = fold (+) 0

-- Prefix sum
prefixSum :: Acc (Vector Int) -> Acc (Vector Int)
prefixSum = scanl (+) 0

-- Reverse a vector
rev :: Acc (Vector a) -> Acc (Vector a)
rev xs = backpermute (shape xs) (\ix -> index1 (n - 1 - unindex1 ix)) xs
  where n = unindex1 (shape xs)

-- Count elements matching predicate
countWhere :: (Exp a -> Exp Bool) -> Acc (Vector a) -> Acc (Scalar Int)
countWhere p = fold (+) 0 . map (\x -> p x ? (1, 0))

-- Conditional expression
(?) :: Exp Bool -> (Exp a, Exp a) -> Exp a

Exp vs Acc

Level Type Represents Operations
Scalar Exp a Single GPU value +, *, ==, ? (conditional)
Array Acc (Array sh a) Bulk data on GPU map, fold, scan, permute

You cannot index into an Acc array with a plain Haskell index — use generate, backpermute, or stencils to express element access patterns.

The Exp/Acc Boundary

-- WRONG: can't use Haskell if/then/else on Exp
bad x = if x > 0 then x else 0

-- RIGHT: use Accelerate's conditional
good x = x > 0 ? (x, 0)

-- WRONG: can't pattern match on Exp tuples
bad (a, b) = a + b

-- RIGHT: use fst/snd from Accelerate (or unlift)
good pair = fst pair + snd pair