Copyright | [2008..2017] Manuel M T Chakravarty Gabriele Keller [2009..2017] Trevor L. McDonell [2013..2017] Robert Clifton-Everest [2014..2014] Frederik M. Madsen |
---|---|

License | BSD3 |

Maintainer | Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> |

Stability | experimental |

Portability | non-portable (GHC extensions) |

Safe Haskell | None |

Language | Haskell2010 |

`Data.Array.Accelerate`

defines an embedded language of array computations
for high-performance computing in Haskell. 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 compiled and can be executed on a range of architectures.

*Abstract interface:*

The types representing array computations are only exported abstractly; client code can generate array computations and submit them for execution, but it cannot inspect these computations. This is to allow for more flexibility for future extensions of this library.

*Stratified language:*

Accelerate distinguishes the types of collective operations `Acc`

from the
type of scalar operations `Exp`

to achieve a stratified language. Collective
operations comprise many scalar computations that are executed in parallel,
but scalar computations *can not* contain collective operations. This
separation excludes *nested, irregular* data-parallelism statically; instead,
Accelerate is limited to *flat data-parallelism* involving only regular,
multi-dimensional arrays.

*Optimisations:*

Accelerate uses a number of scalar and array optimisations, including
*array fusion*, in order to improve the performance of programs. Fusing
a program entails combining successive traversals (loops) over an array into
a single traversal, which reduces memory traffic and eliminates intermediate
arrays.

*Code execution:*

Several backends are available which can be used to evaluate accelerate programs:

- Data.Array.Accelerate.Interpreter: simple interpreter in Haskell as a reference implementation defining the semantics of the Accelerate language
- accelerate-llvm-native: implementation supporting parallel execution on multicore CPUs (e.g. x86).
- accelerate-llvm-ptx: implementation supporting parallel execution on CUDA-capable NVIDIA GPUs.

*Examples:*

- A short tutorial-style example for generating a Mandelbrot set: http://www.acceleratehs.org/examples/mandelbrot.html
The accelerate-examples package demonstrates a range of computational kernels and several complete applications:

- Implementation of the canny edge detector
- Interactive Mandelbrot set generator
- N-body simulation of gravitational attraction between large bodies
- Implementation of the PageRank algorithm
- A simple, real-time, interactive ray tracer.
- A particle based simulation of stable fluid flows
- A cellular automaton simulation
- A "password recovery" tool, for dictionary attacks on MD5 hashes.

lulesh-accelerate is an implementation of the Livermore Unstructured Lagrangian Explicit Shock Hydrodynamics (LULESH) application. LULESH is representative of typical hydrodynamics codes, although simplified and hard-coded to solve the Sedov blast problem on an unstructured hexahedron mesh.

- For more information on LULESH: https://codesign.llnl.gov/lulesh.php.

*Starting a new project:*

Accelerate and its associated packages are available on both Hackage and Stackage. A project template is available to help create a new projects using the stack build tool. To create a new project using the template:

stack new PROJECT_NAME https://github.com/AccelerateHS/accelerate/raw/stable/accelerate.hsfiles

*Additional components:*

- accelerate-io: Fast conversion between Accelerate arrays and other formats (e.g. Repa, Vector).
- accelerate-fft: Fast Fourier transform, with FFI bindings to optimised implementations.
- accelerate-blas: BLAS and LAPACK operations, with FFI bindings to optimised implementations.
- accelerate-bignum: Fixed-width large integer arithmetic.
- colour-accelerate: Colour representations in Accelerate (RGB, sRGB, HSV, and HSL).
- gloss-accelerate: Generate gloss pictures from Accelerate.
- gloss-raster-accelerate: Parallel rendering of raster images and animations.
- lens-accelerate: Lens operators for Accelerate types.
- linear-accelerate: Linear vector space types for Accelerate.
- mwc-random-accelerate: Generate Accelerate arrays filled with high-quality pseudorandom numbers.

*Contact:*

Mailing list for both use and development discussion:

- Bug reports: https://github.com/AccelerateHS/accelerate/issues
Maintainers:

- Trevor L. McDonell: mailto:tmcdonell@cse.unsw.edu.au
- Manuel M T Chakravarty: mailto:chak@cse.unsw.edu.au

*Tip:*

Accelerate tends to stress GHC's garbage collector, so it helps to increase the default GC allocation sizes. This can be done when running an executable by specifying RTS options on the command line, for example:

./foo +RTS -A64M -n2M -RTS

You can make these settings the default by adding the following `ghc-options`

to your `.cabal`

file or similar:

ghc-options: -with-rtsopts=-n2M -with-rtsopts=-A64M

To specify RTS options you will also need to compile your program with `-rtsopts`

.

## Synopsis

- data Acc a
- data Array sh e
- class (Typeable a, Typeable (ArrRepr a)) => Arrays a
- type Scalar = Array DIM0
- type Vector = Array DIM1
- type Matrix = Array DIM2
- type Segments = Vector
- class (Show a, Typeable a, Typeable (EltRepr a), ArrayElt (EltRepr a)) => Elt a
- data Z = Z
- data tail :. head = tail :. head
- type DIM0 = Z
- type DIM1 = DIM0 :. Int
- type DIM2 = DIM1 :. Int
- type DIM3 = DIM2 :. Int
- type DIM4 = DIM3 :. Int
- type DIM5 = DIM4 :. Int
- type DIM6 = DIM5 :. Int
- type DIM7 = DIM6 :. Int
- type DIM8 = DIM7 :. Int
- type DIM9 = DIM8 :. Int
- class (Elt sh, Elt (Any sh), Shape (EltRepr sh), FullShape sh ~ sh, CoSliceShape sh ~ sh, SliceShape sh ~ Z) => Shape sh
- class (Elt sl, Shape (SliceShape sl), Shape (CoSliceShape sl), Shape (FullShape sl)) => Slice sl where
- type SliceShape sl :: *
- type CoSliceShape sl :: *
- type FullShape sl :: *

- data All = All
- data Any sh = Any
- (!) :: (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh -> Exp e
- (!!) :: (Shape sh, Elt e) => Acc (Array sh e) -> Exp Int -> Exp e
- the :: Elt e => Acc (Scalar e) -> Exp e
- null :: (Shape sh, Elt e) => Acc (Array sh e) -> Exp Bool
- length :: Elt e => Acc (Vector e) -> Exp Int
- shape :: (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh
- size :: (Shape sh, Elt e) => Acc (Array sh e) -> Exp Int
- shapeSize :: Shape sh => Exp sh -> Exp Int
- use :: Arrays arrays => arrays -> Acc arrays
- unit :: Elt e => Exp e -> Acc (Scalar e)
- generate :: (Shape sh, Elt a) => Exp sh -> (Exp sh -> Exp a) -> Acc (Array sh a)
- fill :: (Shape sh, Elt e) => Exp sh -> Exp e -> Acc (Array sh e)
- enumFromN :: (Shape sh, Num e, FromIntegral Int e) => Exp sh -> Exp e -> Acc (Array sh e)
- enumFromStepN :: (Shape sh, Num e, FromIntegral Int e) => Exp sh -> Exp e -> Exp e -> Acc (Array sh e)
- (++) :: forall sh e. (Slice sh, Shape sh, Elt e) => Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e)
- concatOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Acc (Array sh e) -> Acc (Array sh e) -> Acc (Array sh e)
- (?|) :: Arrays a => Exp Bool -> (Acc a, Acc a) -> Acc a
- acond :: Arrays a => Exp Bool -> Acc a -> Acc a -> Acc a
- awhile :: Arrays a => (Acc a -> Acc (Scalar Bool)) -> (Acc a -> Acc a) -> Acc a -> Acc a
- class IfThenElse t where
- type EltT t a :: Constraint

- (>->) :: (Arrays a, Arrays b, Arrays c) => (Acc a -> Acc b) -> (Acc b -> Acc c) -> Acc a -> Acc c
- compute :: Arrays a => Acc a -> Acc a
- indexed :: (Shape sh, Elt a) => Acc (Array sh a) -> Acc (Array sh (sh, a))
- map :: (Shape sh, Elt a, Elt b) => (Exp a -> Exp b) -> Acc (Array sh a) -> Acc (Array sh b)
- imap :: (Shape sh, Elt a, Elt b) => (Exp sh -> Exp a -> Exp b) -> Acc (Array sh a) -> Acc (Array sh b)
- zipWith :: (Shape sh, Elt a, Elt b, Elt c) => (Exp a -> Exp b -> Exp c) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c)
- zipWith3 :: (Shape sh, Elt a, Elt b, Elt c, Elt d) => (Exp a -> Exp b -> Exp c -> Exp d) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d)
- zipWith4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e)
- zipWith5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f)
- zipWith6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g)
- zipWith7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h)
- zipWith8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh i)
- zipWith9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i -> Exp j) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh i) -> Acc (Array sh j)
- izipWith :: (Shape sh, Elt a, Elt b, Elt c) => (Exp sh -> Exp a -> Exp b -> Exp c) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c)
- izipWith3 :: (Shape sh, Elt a, Elt b, Elt c, Elt d) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d)
- izipWith4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e)
- izipWith5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f)
- izipWith6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g)
- izipWith7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h)
- izipWith8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh i)
- izipWith9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i -> Exp j) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh i) -> Acc (Array sh j)
- zip :: (Shape sh, Elt a, Elt b) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh (a, b))
- zip3 :: (Shape sh, Elt a, Elt b, Elt c) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh (a, b, c))
- zip4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh (a, b, c, d))
- zip5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh (a, b, c, d, e))
- zip6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh (a, b, c, d, e, f))
- zip7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh (a, b, c, d, e, f, g))
- zip8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh (a, b, c, d, e, f, g, h))
- zip9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh i) -> Acc (Array sh (a, b, c, d, e, f, g, h, i))
- unzip :: (Shape sh, Elt a, Elt b) => Acc (Array sh (a, b)) -> (Acc (Array sh a), Acc (Array sh b))
- unzip3 :: (Shape sh, Elt a, Elt b, Elt c) => Acc (Array sh (a, b, c)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c))
- unzip4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d) => Acc (Array sh (a, b, c, d)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d))
- unzip5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e) => Acc (Array sh (a, b, c, d, e)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d), Acc (Array sh e))
- unzip6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f) => Acc (Array sh (a, b, c, d, e, f)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d), Acc (Array sh e), Acc (Array sh f))
- unzip7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g) => Acc (Array sh (a, b, c, d, e, f, g)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d), Acc (Array sh e), Acc (Array sh f), Acc (Array sh g))
- unzip8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h) => Acc (Array sh (a, b, c, d, e, f, g, h)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d), Acc (Array sh e), Acc (Array sh f), Acc (Array sh g), Acc (Array sh h))
- unzip9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i) => Acc (Array sh (a, b, c, d, e, f, g, h, i)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d), Acc (Array sh e), Acc (Array sh f), Acc (Array sh g), Acc (Array sh h), Acc (Array sh i))
- reshape :: (Shape sh, Shape sh', Elt e) => Exp sh -> Acc (Array sh' e) -> Acc (Array sh e)
- flatten :: forall sh e. (Shape sh, Elt e) => Acc (Array sh e) -> Acc (Vector e)
- replicate :: (Slice slix, Elt e) => Exp slix -> Acc (Array (SliceShape slix) e) -> Acc (Array (FullShape slix) e)
- slice :: (Slice slix, Elt e) => Acc (Array (FullShape slix) e) -> Exp slix -> Acc (Array (SliceShape slix) e)
- init :: forall sh e. (Slice sh, Shape sh, Elt e) => Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e)
- tail :: forall sh e. (Slice sh, Shape sh, Elt e) => Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e)
- take :: forall sh e. (Slice sh, Shape sh, Elt e) => Exp Int -> Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e)
- drop :: forall sh e. (Slice sh, Shape sh, Elt e) => Exp Int -> Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e)
- slit :: forall sh e. (Slice sh, Shape sh, Elt e) => Exp Int -> Exp Int -> Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e)
- initOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Acc (Array sh e) -> Acc (Array sh e)
- tailOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Acc (Array sh e) -> Acc (Array sh e)
- takeOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Exp Int -> Acc (Array sh e) -> Acc (Array sh e)
- dropOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Exp Int -> Acc (Array sh e) -> Acc (Array sh e)
- slitOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Exp Int -> Exp Int -> Acc (Array sh e) -> Acc (Array sh e)
- permute :: (Shape sh, Shape sh', Elt a) => (Exp a -> Exp a -> Exp a) -> Acc (Array sh' a) -> (Exp sh -> Exp sh') -> Acc (Array sh a) -> Acc (Array sh' a)
- ignore :: Shape sh => Exp sh
- scatter :: Elt e => Acc (Vector Int) -> Acc (Vector e) -> Acc (Vector e) -> Acc (Vector e)
- backpermute :: (Shape sh, Shape sh', Elt a) => Exp sh' -> (Exp sh' -> Exp sh) -> Acc (Array sh a) -> Acc (Array sh' a)
- gather :: (Shape sh, Elt e) => Acc (Array sh Int) -> Acc (Vector e) -> Acc (Array sh e)
- reverse :: Elt e => Acc (Vector e) -> Acc (Vector e)
- transpose :: Elt e => Acc (Array DIM2 e) -> Acc (Array DIM2 e)
- reverseOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Acc (Array sh e) -> Acc (Array sh e)
- transposeOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Lens' (Exp sh) (Exp Int) -> Acc (Array sh e) -> Acc (Array sh e)
- filter :: forall sh e. (Shape sh, Slice sh, Elt e) => (Exp e -> Exp Bool) -> Acc (Array (sh :. Int) e) -> Acc (Vector e, Array sh Int)
- fold :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array sh a)
- fold1 :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Acc (Array (sh :. Int) a) -> Acc (Array sh a)
- foldAll :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array sh a) -> Acc (Scalar a)
- fold1All :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Acc (Array sh a) -> Acc (Scalar a)
- foldSeg :: (Shape sh, Elt a, Elt i, IsIntegral i) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Segments i) -> Acc (Array (sh :. Int) a)
- fold1Seg :: (Shape sh, Elt a, Elt i, IsIntegral i) => (Exp a -> Exp a -> Exp a) -> Acc (Array (sh :. Int) a) -> Acc (Segments i) -> Acc (Array (sh :. Int) a)
- all :: (Shape sh, Elt e) => (Exp e -> Exp Bool) -> Acc (Array (sh :. Int) e) -> Acc (Array sh Bool)
- any :: (Shape sh, Elt e) => (Exp e -> Exp Bool) -> Acc (Array (sh :. Int) e) -> Acc (Array sh Bool)
- and :: Shape sh => Acc (Array (sh :. Int) Bool) -> Acc (Array sh Bool)
- or :: Shape sh => Acc (Array (sh :. Int) Bool) -> Acc (Array sh Bool)
- sum :: (Shape sh, Num e) => Acc (Array (sh :. Int) e) -> Acc (Array sh e)
- product :: (Shape sh, Num e) => Acc (Array (sh :. Int) e) -> Acc (Array sh e)
- minimum :: (Shape sh, Ord e) => Acc (Array (sh :. Int) e) -> Acc (Array sh e)
- maximum :: (Shape sh, Ord e) => Acc (Array (sh :. Int) e) -> Acc (Array sh e)
- scanl :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a)
- scanl1 :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a)
- scanl' :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a, Array sh a)
- scanr :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a)
- scanr1 :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a)
- scanr' :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a, Array sh a)
- prescanl :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a)
- postscanl :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a)
- prescanr :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a)
- postscanr :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a)
- scanlSeg :: forall sh e i. (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e)
- scanl1Seg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e)
- scanl'Seg :: forall sh e i. (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e, Array (sh :. Int) e)
- prescanlSeg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e)
- postscanlSeg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e)
- scanrSeg :: forall sh e i. (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e)
- scanr1Seg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e)
- scanr'Seg :: forall sh e i. (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e, Array (sh :. Int) e)
- prescanrSeg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e)
- postscanrSeg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e)
- stencil :: (Stencil sh a stencil, Elt b) => (stencil -> Exp b) -> Boundary (Array sh a) -> Acc (Array sh a) -> Acc (Array sh b)
- stencil2 :: (Stencil sh a stencil1, Stencil sh b stencil2, Elt c) => (stencil1 -> stencil2 -> Exp c) -> Boundary (Array sh a) -> Acc (Array sh a) -> Boundary (Array sh b) -> Acc (Array sh b) -> Acc (Array sh c)
- class (Elt (StencilRepr sh stencil), Stencil sh a (StencilRepr sh stencil)) => Stencil sh a stencil
- data Boundary t
- clamp :: Boundary (Array sh e)
- mirror :: Boundary (Array sh e)
- wrap :: Boundary (Array sh e)
- function :: (Shape sh, Elt e) => (Exp sh -> Exp e) -> Boundary (Array sh e)
- type Stencil3 a = (Exp a, Exp a, Exp a)
- type Stencil5 a = (Exp a, Exp a, Exp a, Exp a, Exp a)
- type Stencil7 a = (Exp a, Exp a, Exp a, Exp a, Exp a, Exp a, Exp a)
- type Stencil9 a = (Exp a, Exp a, Exp a, Exp a, Exp a, Exp a, Exp a, Exp a, Exp a)
- type Stencil3x3 a = (Stencil3 a, Stencil3 a, Stencil3 a)
- type Stencil5x3 a = (Stencil5 a, Stencil5 a, Stencil5 a)
- type Stencil3x5 a = (Stencil3 a, Stencil3 a, Stencil3 a, Stencil3 a, Stencil3 a)
- type Stencil5x5 a = (Stencil5 a, Stencil5 a, Stencil5 a, Stencil5 a, Stencil5 a)
- type Stencil3x3x3 a = (Stencil3x3 a, Stencil3x3 a, Stencil3x3 a)
- type Stencil5x3x3 a = (Stencil5x3 a, Stencil5x3 a, Stencil5x3 a)
- type Stencil3x5x3 a = (Stencil3x5 a, Stencil3x5 a, Stencil3x5 a)
- type Stencil3x3x5 a = (Stencil3x3 a, Stencil3x3 a, Stencil3x3 a, Stencil3x3 a, Stencil3x3 a)
- type Stencil5x5x3 a = (Stencil5x5 a, Stencil5x5 a, Stencil5x5 a)
- type Stencil5x3x5 a = (Stencil5x3 a, Stencil5x3 a, Stencil5x3 a, Stencil5x3 a, Stencil5x3 a)
- type Stencil3x5x5 a = (Stencil3x5 a, Stencil3x5 a, Stencil3x5 a, Stencil3x5 a, Stencil3x5 a)
- type Stencil5x5x5 a = (Stencil5x5 a, Stencil5x5 a, Stencil5x5 a, Stencil5x5 a, Stencil5x5 a)
- data Exp t
- class Elt a => Eq a where
- class Eq a => Ord a where
- data Ordering
- type Enum a = Enum (Exp a)
- succ :: Enum a => a -> a
- pred :: Enum a => a -> a
- type Bounded a = (Elt a, Bounded (Exp a))
- minBound :: Bounded a => a
- maxBound :: Bounded a => a
- type Num a = (Elt a, Num (Exp a))
- (+) :: Num a => a -> a -> a
- (-) :: Num a => a -> a -> a
- (*) :: Num a => a -> a -> a
- negate :: Num a => a -> a
- abs :: Num a => a -> a
- signum :: Num a => a -> a
- fromInteger :: Num a => Integer -> Exp a
- type Integral a = (Enum a, Real a, Integral (Exp a))
- quot :: Integral a => a -> a -> a
- rem :: Integral a => a -> a -> a
- div :: Integral a => a -> a -> a
- mod :: Integral a => a -> a -> a
- quotRem :: Integral a => a -> a -> (a, a)
- divMod :: Integral a => a -> a -> (a, a)
- type Fractional a = (Num a, Fractional (Exp a))
- (/) :: Fractional a => a -> a -> a
- recip :: Fractional a => a -> a
- fromRational :: Fractional a => Rational -> Exp a
- type Floating a = (Fractional a, Floating (Exp a))
- pi :: Floating a => a
- sin :: Floating a => a -> a
- cos :: Floating a => a -> a
- tan :: Floating a => a -> a
- asin :: Floating a => a -> a
- acos :: Floating a => a -> a
- atan :: Floating a => a -> a
- sinh :: Floating a => a -> a
- cosh :: Floating a => a -> a
- tanh :: Floating a => a -> a
- asinh :: Floating a => a -> a
- acosh :: Floating a => a -> a
- atanh :: Floating a => a -> a
- exp :: Floating a => a -> a
- sqrt :: Floating a => a -> a
- log :: Floating a => a -> a
- (**) :: Floating a => a -> a -> a
- logBase :: Floating a => a -> a -> a
- class (Real a, Fractional a) => RealFrac a where
- div' :: (RealFrac a, Elt b, IsIntegral b) => Exp a -> Exp a -> Exp b
- mod' :: (Floating a, RealFrac a, ToFloating Int a) => Exp a -> Exp a -> Exp a
- divMod' :: (Floating a, RealFrac a, Num b, IsIntegral b, ToFloating b a) => Exp a -> Exp a -> (Exp b, Exp a)
- class (RealFrac a, Floating a) => RealFloat a where
- class FromIntegral a b where
- class ToFloating a b where
- class Lift c e where
- type Plain e

- class Lift c e => Unlift c e where
- lift1 :: (Unlift Exp a, Lift Exp b) => (a -> b) -> Exp (Plain a) -> Exp (Plain b)
- lift2 :: (Unlift Exp a, Unlift Exp b, Lift Exp c) => (a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
- lift3 :: (Unlift Exp a, Unlift Exp b, Unlift Exp c, Lift Exp d) => (a -> b -> c -> d) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c) -> Exp (Plain d)
- ilift1 :: (Exp Int -> Exp Int) -> Exp DIM1 -> Exp DIM1
- ilift2 :: (Exp Int -> Exp Int -> Exp Int) -> Exp DIM1 -> Exp DIM1 -> Exp DIM1
- ilift3 :: (Exp Int -> Exp Int -> Exp Int -> Exp Int) -> Exp DIM1 -> Exp DIM1 -> Exp DIM1 -> Exp DIM1
- constant :: Elt t => t -> Exp t
- fst :: forall a b. (Elt a, Elt b) => Exp (a, b) -> Exp a
- afst :: forall a b. (Arrays a, Arrays b) => Acc (a, b) -> Acc a
- snd :: forall a b. (Elt a, Elt b) => Exp (a, b) -> Exp b
- asnd :: forall a b. (Arrays a, Arrays b) => Acc (a, b) -> Acc b
- curry :: Lift f (f a, f b) => (f (Plain (f a), Plain (f b)) -> f c) -> f a -> f b -> f c
- uncurry :: Unlift f (f a, f b) => (f a -> f b -> f c) -> f (Plain (f a), Plain (f b)) -> f c
- (?) :: Elt t => Exp Bool -> (Exp t, Exp t) -> Exp t
- caseof :: (Elt a, Elt b) => Exp a -> [(Exp a -> Exp Bool, Exp b)] -> Exp b -> Exp b
- cond :: Elt t => Exp Bool -> Exp t -> Exp t -> Exp t
- while :: Elt e => (Exp e -> Exp Bool) -> (Exp e -> Exp e) -> Exp e -> Exp e
- iterate :: forall a. Elt a => Exp Int -> (Exp a -> Exp a) -> Exp a -> Exp a
- sfoldl :: forall sh a b. (Shape sh, Slice sh, Elt a, Elt b) => (Exp a -> Exp b -> Exp a) -> Exp a -> Exp sh -> Acc (Array (sh :. Int) b) -> Exp a
- (&&) :: Exp Bool -> Exp Bool -> Exp Bool
- (||) :: Exp Bool -> Exp Bool -> Exp Bool
- not :: Exp Bool -> Exp Bool
- subtract :: Num a => Exp a -> Exp a -> Exp a
- even :: Integral a => Exp a -> Exp Bool
- odd :: Integral a => Exp a -> Exp Bool
- gcd :: Integral a => Exp a -> Exp a -> Exp a
- lcm :: Integral a => Exp a -> Exp a -> Exp a
- (^) :: forall a b. (Num a, Integral b) => Exp a -> Exp b -> Exp a
- (^^) :: (Fractional a, Integral b) => Exp a -> Exp b -> Exp a
- index0 :: Exp Z
- index1 :: Elt i => Exp i -> Exp (Z :. i)
- unindex1 :: Elt i => Exp (Z :. i) -> Exp i
- index2 :: (Elt i, Slice (Z :. i)) => Exp i -> Exp i -> Exp ((Z :. i) :. i)
- unindex2 :: forall i. (Elt i, Slice (Z :. i)) => Exp ((Z :. i) :. i) -> Exp (i, i)
- index3 :: (Elt i, Slice (Z :. i), Slice ((Z :. i) :. i)) => Exp i -> Exp i -> Exp i -> Exp (((Z :. i) :. i) :. i)
- unindex3 :: forall i. (Elt i, Slice (Z :. i), Slice ((Z :. i) :. i)) => Exp (((Z :. i) :. i) :. i) -> Exp (i, i, i)
- indexHead :: (Slice sh, Elt a) => Exp (sh :. a) -> Exp a
- indexTail :: (Slice sh, Elt a) => Exp (sh :. a) -> Exp sh
- toIndex :: Shape sh => Exp sh -> Exp sh -> Exp Int
- fromIndex :: Shape sh => Exp sh -> Exp Int -> Exp sh
- intersect :: Shape sh => Exp sh -> Exp sh -> Exp sh
- ord :: Exp Char -> Exp Int
- chr :: Exp Int -> Exp Char
- boolToInt :: Exp Bool -> Exp Int
- bitcast :: (Elt a, Elt b, IsScalar (EltRepr a), IsScalar (EltRepr b), BitSizeEq (EltRepr a) (EltRepr b)) => Exp a -> Exp b
- foreignAcc :: (Arrays as, Arrays bs, Foreign asm) => asm (as -> bs) -> (Acc as -> Acc bs) -> Acc as -> Acc bs
- foreignExp :: (Elt x, Elt y, Foreign asm) => asm (x -> y) -> (Exp x -> Exp y) -> Exp x -> Exp y
- arrayRank :: Shape sh => sh -> Int
- arrayShape :: Shape sh => Array sh e -> sh
- arraySize :: Shape sh => sh -> Int
- arrayReshape :: (Shape sh, Shape sh', Elt e) => sh -> Array sh' e -> Array sh e
- indexArray :: Array sh e -> sh -> e
- linearIndexArray :: Array sh e -> Int -> e
- fromFunction :: (Shape sh, Elt e) => sh -> (sh -> e) -> Array sh e
- fromFunctionM :: (Shape sh, Elt e) => sh -> (sh -> IO e) -> IO (Array sh e)
- fromList :: (Shape sh, Elt e) => sh -> [e] -> Array sh e
- toList :: forall sh e. Array sh e -> [e]
- (.) :: (b -> c) -> (a -> b) -> a -> c
- ($) :: (a -> b) -> a -> b
- error :: HasCallStack => [Char] -> a
- undefined :: HasCallStack => a
- const :: a -> b -> a
- data Int
- data Int8
- data Int16
- data Int32
- data Int64
- data Word
- data Word8
- data Word16
- data Word32
- data Word64
- newtype Half = Half {}
- data Float
- data Double
- data Bool
- data Char
- data CFloat
- data CDouble
- data CShort
- data CUShort
- data CInt
- data CUInt
- data CLong
- data CULong
- data CLLong
- data CULLong
- data CChar
- data CSChar
- data CUChar
- class Typeable a => IsScalar a
- class (Num a, IsSingle a) => IsNum a
- class IsBounded a
- class (IsSingle a, IsNum a, IsBounded a) => IsIntegral a
- class (Floating a, IsSingle a, IsNum a) => IsFloating a
- class IsNonNum a

# The *Accelerate* Array Language

## Embedded array computations

Accelerate is an *embedded language* that distinguishes between vanilla
arrays (e.g. in Haskell memory on the CPU) and embedded arrays (e.g. in
device memory on a GPU), as well as the computations on both of these. Since
Accelerate is an embedded language, programs written in Accelerate are not
compiled by the Haskell compiler (GHC). Rather, each Accelerate backend is
a *runtime compiler* which generates and executes parallel SIMD code of the
target language at application *runtime*.

The type constructor `Acc`

represents embedded collective array operations.
A term of type `Acc a`

is an Accelerate program which, once executed, will
produce a value of type `a`

(an `Array`

or a tuple of `Arrays`

). Collective
operations of type `Acc a`

comprise many *scalar expressions*, wrapped in
type constructor `Exp`

, which will be executed in parallel. Although
collective operations comprise many scalar operations executed in parallel,
scalar operations *cannot* initiate new collective operations: this
stratification between scalar operations in `Exp`

and array operations in
`Acc`

helps statically exclude *nested data parallelism*, which is difficult
to execute efficiently on constrained hardware such as GPUs.

*A simple example*

As a simple example, to compute a vector dot product we can write:

dotp :: Num a => Vector a -> Vector a -> Acc (Scalar a) dotp xs ys = let xs' = use xs ys' = use ys in fold (+) 0 ( zipWith (*) xs' ys' )

The function `dotp`

consumes two one-dimensional arrays (`Vector`

s) of
values, and produces a single (`Scalar`

) result as output. As the return type
is wrapped in the type `Acc`

, we see that it is an embedded Accelerate
computation - it will be evaluated in the *object* language of dynamically
generated parallel code, rather than the *meta* language of vanilla Haskell.

As the arguments to `dotp`

are plain Haskell arrays, to make these available
to Accelerate computations they must be embedded with the
`use`

function.

An Accelerate backend is used to evaluate the embedded computation and return
the result back to vanilla Haskell. Calling the `run`

function of a backend
will generate code for the target architecture, compile, and execute it. For
example, the following backends are available:

- accelerate-llvm-native: for execution on multicore CPUs
- accelerate-llvm-ptx: for execution on NVIDIA CUDA-capable GPUs

See also `Exp`

, which encapsulates embedded *scalar* computations.

*Avoiding nested parallelism*

As mentioned above, embedded scalar computations of type `Exp`

can not
initiate further collective operations.

Suppose we wanted to extend our above `dotp`

function to matrix-vector
multiplication. First, let's rewrite our `dotp`

function to take `Acc`

arrays
as input (which is typically what we want):

dotp :: Num a => Acc (Vector a) -> Acc (Vector a) -> Acc (Scalar a) dotp xs ys = fold (+) 0 ( zipWith (*) xs ys )

We might then be inclined to lift our dot-product program to the following
(incorrect) matrix-vector product, by applying `dotp`

to each row of the
input matrix:

mvm_ndp :: Num a => Acc (Matrix a) -> Acc (Vector a) -> Acc (Vector a) mvm_ndp mat vec = let Z :. rows :. cols = unlift (shape mat) :: Z :. Exp Int :. Exp Int in generate (index1 rows) (\row -> the $ dotp vec (slice mat (lift (row :. All))))

Here, we use `generate`

to create a one-dimensional
vector by applying at each index a function to `slice`

out the corresponding `row`

of the matrix to pass to the `dotp`

function.
However, since both `generate`

and
`slice`

are data-parallel operations, and moreover that
`slice`

*depends on* the argument `row`

given to it by
the `generate`

function, this definition requires
nested data-parallelism, and is thus not permitted. The clue that this
definition is invalid is that in order to create a program which will be
accepted by the type checker, we must use the function
`the`

to retrieve the result of the `dotp`

operation,
effectively concealing that `dotp`

is a collective array computation in order
to match the type expected by `generate`

, which is that
of scalar expressions. Additionally, since we have fooled the type-checker,
this problem will only be discovered at program runtime.

In order to avoid this problem, we can make use of the fact that operations
in Accelerate are *rank polymorphic*. The `fold`

operation reduces along the innermost dimension of an array of arbitrary
rank, reducing the rank (dimensionality) of the array by one. Thus, we can
`replicate`

the input vector to as many `rows`

there
are in the input matrix, and perform the dot-product of the vector with every
row simultaneously:

mvm :: A.Num a => Acc (Matrix a) -> Acc (Vector a) -> Acc (Vector a) mvm mat vec = let Z :. rows :. cols = unlift (shape mat) :: Z :. Exp Int :. Exp Int vec' = A.replicate (lift (Z :. rows :. All)) vec in A.fold (+) 0 ( A.zipWith (*) mat vec' )

Note that the intermediate, replicated array `vec'`

is never actually created
in memory; it will be fused directly into the operation which consumes it. We
discuss fusion next.

*Fusion*

Array computations of type `Acc`

will be subject to *array fusion*;
Accelerate will combine individual `Acc`

computations into a single
computation, which reduces the number of traversals over the input data and
thus improves performance. As such, it is often useful to have some intuition
on when fusion should occur.

The main idea is to first partition array operations into two categories:

- Element-wise operations, such as
`map`

,`generate`

, and`backpermute`

. Each element of these operations can be computed independently of all others. - Collective operations such as
`fold`

,`scanl`

, and`stencil`

. To compute each output element of these operations requires reading multiple elements from the input array(s).

Element-wise operations fuse together whenever the consumer operation uses a single element of the input array. Element-wise operations can both fuse their inputs into themselves, as well be fused into later operations. Both these examples should fuse into a single loop:

If the consumer operation uses more than one element of the input array
(typically, via `generate`

indexing an array multiple
times), then the input array will be completely evaluated first; no fusion
occurs in this case, because fusing the first operation into the second
implies duplicating work.

On the other hand, collective operations can fuse their input arrays into themselves, but on output always evaluate to an array; collective operations will not be fused into a later step. For example:

Here the element-wise sequence (`use`

+ `generate`

+ `zipWith`

) will
fuse into a single operation, which then fuses into the collective
`fold`

operation. At this point in the program the
`fold`

must now be evaluated. In the final step the
`map`

reads in the array produced by
`fold`

. As there is no fusion between the
`fold`

and `map`

steps, this
program consists of two "loops"; one for the `use`

+ `generate`

+ `zipWith`

+ `fold`

step, and one for the final
`map`

step.

You can see how many operations will be executed in the fused program by
`Show`

-ing the `Acc`

program, or by using the debugging option `-ddump-dot`

to save the program as a graphviz DOT file.

As a special note, the operations `unzip`

and
`reshape`

, when applied to a real array, are executed
in constant time, so in this situation these operations will not be fused.

*Tips*

- Since
`Acc`

represents embedded computations that will only be executed when evaluated by a backend, we can programatically generate these computations using the meta language Haskell; for example, unrolling loops or embedding input values into the generated code. - It is usually best to keep all intermediate computations in
`Acc`

, and only`run`

the computation at the very end to produce the final result. This enables optimisations between intermediate results (e.g. array fusion) and, if the target architecture has a separate memory space, as is the case of GPUs, to prevent excessive data transfers.

## Instances

### Arrays

Dense, regular, multi-dimensional arrays.

The `Array`

is the core computational unit of Accelerate; all programs in
Accelerate take zero or more arrays as input and produce one or more arrays
as output. The `Array`

type has two type parameters:

*sh*: is the shape of the array, tracking the dimensionality and extent of each dimension of the array; for example,`DIM1`

for one-dimensional`Vector`

s,`DIM2`

for two-dimensional matrices, and so on.*e*: represents the type of each element of the array; for example,`Int`

,`Float`

, et cetera.

Array data is store unboxed in an unzipped struct-of-array representation.
Elements are laid out in row-major order (the right-most index of a `Shape`

is the fastest varying). The allowable array element types are members of the
`Elt`

class, which roughly consists of:

- Signed and unsigned integers (8, 16, 32, and 64-bits wide).
- Floating point numbers (single and double precision)
`Char`

`Bool`

- ()
- Shapes formed from
`Z`

and (`:.`

) - Nested tuples of all of these, currently up to 15-elements wide.

Note that `Array`

itself is not an allowable element type---there are no
nested arrays in Accelerate, regular arrays only!

If device and host memory are separate, arrays will be transferred to the
device when necessary (possibly asynchronously and in parallel with other
tasks) and cached on the device if sufficient memory is available. Arrays are
made available to embedded language computations via
`use`

.

Section "Getting data in" lists functions for getting data into and out of
the `Array`

type.

## Instances

(Shape sh, Elt e) => Lift Acc (Array sh e) Source # | |

Elt e => IsList (Vector e) Source # | |

Show (Vector e) Source # | |

Show (Scalar e) Source # | |

(Eq sh, Eq e) => Eq (Array sh e) Source # | |

Show (Array sh e) Source # | |

Show (Array DIM2 e) Source # | |

NFData (Array sh e) Source # | |

(Shape sh, Elt e) => Arrays (Array sh e) Source # | |

type Item (Vector e) Source # | |

type Plain (Array sh e) Source # | |

class (Typeable a, Typeable (ArrRepr a)) => Arrays a Source #

`Arrays`

consists of nested tuples of individual `Array`

s, currently up to
15-elements wide. Accelerate computations can thereby return multiple
results.

arrays, flavour, toArr, fromArr

## Instances

Arrays () Source # | |

(Arrays a, Arrays b) => Arrays (a, b) Source # | |

(Shape sh, Elt e) => Arrays (Array sh e) Source # | |

(Arrays a, Arrays b, Arrays c) => Arrays (a, b, c) Source # | |

(Arrays a, Arrays b, Arrays c, Arrays d) => Arrays (a, b, c, d) Source # | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e) => Arrays (a, b, c, d, e) Source # | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f) => Arrays (a, b, c, d, e, f) Source # | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g) => Arrays (a, b, c, d, e, f, g) Source # | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h) => Arrays (a, b, c, d, e, f, g, h) Source # | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i) => Arrays (a, b, c, d, e, f, g, h, i) Source # | |

arrays :: (a, b, c, d, e, f, g, h, i) -> ArraysR (ArrRepr (a, b, c, d, e, f, g, h, i)) flavour :: (a, b, c, d, e, f, g, h, i) -> ArraysFlavour (a, b, c, d, e, f, g, h, i) toArr :: ArrRepr (a, b, c, d, e, f, g, h, i) -> (a, b, c, d, e, f, g, h, i) fromArr :: (a, b, c, d, e, f, g, h, i) -> ArrRepr (a, b, c, d, e, f, g, h, i) | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j) => Arrays (a, b, c, d, e, f, g, h, i, j) Source # | |

arrays :: (a, b, c, d, e, f, g, h, i, j) -> ArraysR (ArrRepr (a, b, c, d, e, f, g, h, i, j)) flavour :: (a, b, c, d, e, f, g, h, i, j) -> ArraysFlavour (a, b, c, d, e, f, g, h, i, j) toArr :: ArrRepr (a, b, c, d, e, f, g, h, i, j) -> (a, b, c, d, e, f, g, h, i, j) fromArr :: (a, b, c, d, e, f, g, h, i, j) -> ArrRepr (a, b, c, d, e, f, g, h, i, j) | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k) => Arrays (a, b, c, d, e, f, g, h, i, j, k) Source # | |

arrays :: (a, b, c, d, e, f, g, h, i, j, k) -> ArraysR (ArrRepr (a, b, c, d, e, f, g, h, i, j, k)) flavour :: (a, b, c, d, e, f, g, h, i, j, k) -> ArraysFlavour (a, b, c, d, e, f, g, h, i, j, k) toArr :: ArrRepr (a, b, c, d, e, f, g, h, i, j, k) -> (a, b, c, d, e, f, g, h, i, j, k) fromArr :: (a, b, c, d, e, f, g, h, i, j, k) -> ArrRepr (a, b, c, d, e, f, g, h, i, j, k) | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l) => Arrays (a, b, c, d, e, f, g, h, i, j, k, l) Source # | |

arrays :: (a, b, c, d, e, f, g, h, i, j, k, l) -> ArraysR (ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l)) flavour :: (a, b, c, d, e, f, g, h, i, j, k, l) -> ArraysFlavour (a, b, c, d, e, f, g, h, i, j, k, l) toArr :: ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l) -> (a, b, c, d, e, f, g, h, i, j, k, l) fromArr :: (a, b, c, d, e, f, g, h, i, j, k, l) -> ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l) | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m) => Arrays (a, b, c, d, e, f, g, h, i, j, k, l, m) Source # | |

arrays :: (a, b, c, d, e, f, g, h, i, j, k, l, m) -> ArraysR (ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m)) flavour :: (a, b, c, d, e, f, g, h, i, j, k, l, m) -> ArraysFlavour (a, b, c, d, e, f, g, h, i, j, k, l, m) toArr :: ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m) -> (a, b, c, d, e, f, g, h, i, j, k, l, m) fromArr :: (a, b, c, d, e, f, g, h, i, j, k, l, m) -> ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m) | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n) => Arrays (a, b, c, d, e, f, g, h, i, j, k, l, m, n) Source # | |

arrays :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> ArraysR (ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n)) flavour :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> ArraysFlavour (a, b, c, d, e, f, g, h, i, j, k, l, m, n) toArr :: ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n) fromArr :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n) | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n, Arrays o) => Arrays (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) Source # | |

arrays :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> ArraysR (ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)) flavour :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> ArraysFlavour (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) toArr :: ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) fromArr :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) | |

(Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n, Arrays o, Arrays p) => Arrays (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) Source # | |

arrays :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) -> ArraysR (ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)) flavour :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) -> ArraysFlavour (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) toArr :: ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) fromArr :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) -> ArrRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) |

type Segments = Vector Source #

Segment descriptor (vector of segment lengths).

To represent nested one-dimensional arrays, we use a flat array of data
values in conjunction with a *segment descriptor*, which stores the lengths
of the subarrays.

### Array elements

class (Show a, Typeable a, Typeable (EltRepr a), ArrayElt (EltRepr a)) => Elt a Source #

The `Elt`

class characterises the allowable array element types, and hence
the types which can appear in scalar Accelerate expressions.

Accelerate arrays consist of simple atomic types as well as nested tuples thereof, stored efficiently in memory as consecutive unpacked elements without pointers. It roughly consists of:

- Signed and unsigned integers (8, 16, 32, and 64-bits wide)
- Floating point numbers (half, single, and double precision)
`Char`

`Bool`

- ()
- Shapes formed from
`Z`

and (`:.`

) - Nested tuples of all of these, currently up to 15-elements wide

Adding new instances for `Elt`

consists of explaining to Accelerate how to
map between your data type and a (tuple of) primitive values. For examples
see:

eltType, fromElt, toElt

## Instances

Elt Bool Source # | |

Elt Char Source # | |

Elt Double Source # | |

Elt Float Source # | |

Elt Int Source # | |

Elt Int8 Source # | |

Elt Int16 Source # | |

Elt Int32 Source # | |

Elt Int64 Source # | |

Elt Ordering Source # | |

Elt Word Source # | |

Elt Word8 Source # | |

Elt Word16 Source # | |

Elt Word32 Source # | |

Elt Word64 Source # | |

Elt () Source # | |

Elt CChar Source # | |

Elt CSChar Source # | |

Elt CUChar Source # | |

Elt CShort Source # | |

Elt CUShort Source # | |

Elt CInt Source # | |

Elt CUInt Source # | |

Elt CLong Source # | |

Elt CULong Source # | |

Elt CLLong Source # | |

Elt CULLong Source # | |

Elt CFloat Source # | |

Elt CDouble Source # | |

Elt Half Source # | |

Elt All Source # | |

Elt Z Source # | |

Elt a => Elt (Maybe a) Source # | |

Elt (Complex Double) Source # | |

Elt (Complex Float) Source # | |

Elt (Complex CFloat) Source # | |

Elt (Complex CDouble) Source # | |

Elt (Complex Half) Source # | |

Elt a => Elt (Min a) Source # | |

Elt a => Elt (Max a) Source # | |

Elt a => Elt (Sum a) Source # | |

Elt a => Elt (Product a) Source # | |

Shape sh => Elt (Any (sh :. Int)) Source # | |

Elt (Any Z) Source # | |

(Elt a, Elt b) => Elt (Either a b) Source # | |

(Elt a, Elt b) => Elt (a, b) Source # | |

(Elt t, Elt h) => Elt (t :. h) Source # | |

(Elt a, Elt b, Elt c) => Elt (a, b, c) Source # | |

(Elt a, Elt b, Elt c, Elt d) => Elt (a, b, c, d) Source # | |

(Elt a, Elt b, Elt c, Elt d, Elt e) => Elt (a, b, c, d, e) Source # | |

(Elt a, Elt b, Elt c, Elt d, Elt e, Elt f) => Elt (a, b, c, d, e, f) Source # | |

(Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g) => Elt (a, b, c, d, e, f, g) Source # | |

(Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h) => Elt (a, b, c, d, e, f, g, h) Source # | |

(Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i) => Elt (a, b, c, d, e, f, g, h, i) Source # | |

(Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j) => Elt (a, b, c, d, e, f, g, h, i, j) Source # | |

(Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k) => Elt (a, b, c, d, e, f, g, h, i, j, k) Source # | |

(Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l) => Elt (a, b, c, d, e, f, g, h, i, j, k, l) Source # | |

(Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m) => Elt (a, b, c, d, e, f, g, h, i, j, k, l, m) Source # | |

eltType :: (a, b, c, d, e, f, g, h, i, j, k, l, m) -> TupleType (EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m)) fromElt :: (a, b, c, d, e, f, g, h, i, j, k, l, m) -> EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m) toElt :: EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m) -> (a, b, c, d, e, f, g, h, i, j, k, l, m) | |

(Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m, Elt n) => Elt (a, b, c, d, e, f, g, h, i, j, k, l, m, n) Source # | |

eltType :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> TupleType (EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n)) fromElt :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n) toElt :: EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n) | |

(Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m, Elt n, Elt o) => Elt (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) Source # | |

eltType :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> TupleType (EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)) fromElt :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) toElt :: EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) | |

(Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m, Elt n, Elt o, Elt p) => Elt (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) Source # | |

eltType :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) -> TupleType (EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)) fromElt :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) -> EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) toElt :: EltRepr (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) |

### Array shapes & indices

Operations in Accelerate take the form of collective operations over arrays
of the type

. Much like the
repa library, arrays in Accelerate
are parameterised by a type `Array`

sh e*sh* which determines the dimensionality of the
array and the type of each index, as well as the type of each element of the
array *e*.

Shape types, and multidimensional array indices, are built like lists
(technically; a heterogeneous snoc-list) using `Z`

and (`:.`

):

data Z = Z data tail :. head = tail :. head

Here, the constructor `Z`

corresponds to a shape with zero dimension (or
a `Scalar`

array, with one element) and is used to mark the end of the list.
The constructor (`:.`

) adds additional dimensions to the shape on the
*right*. For example:

Z :. Int

is the type of the shape of a one-dimensional array (`Vector`

) indexed by an
`Int`

, while:

Z :. Int :. Int

is the type of the shape of a two-dimensional array (a matrix) indexed by an
`Int`

in each dimension.

This style is used to construct both the *type* and *value* of the shape. For
example, to define the shape of a vector of ten elements:

sh :: Z :. Int sh = Z :. 10

Note that the right-most index is the *innermost* dimension. This is the
fastest-varying index, and corresponds to the elements of the array which are
adjacent in memory.

Rank-0 index

## Instances

data tail :. head infixl 3 Source #

Increase an index rank by one dimension. The `:.`

operator is
used to construct both values and types.

tail :. head infixl 3 |

## Instances

Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e) Source # | |

Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e) Source # | |

Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e) Source # | |

Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e) Source # | |

(Elt e, Slice (Plain ix), Unlift Exp ix) => Unlift Exp (ix :. Exp e) Source # | |

(Elt e, Slice ix) => Unlift Exp (Exp ix :. Exp e) Source # | |

(Elt e, Slice (Plain ix), Lift Exp ix) => Lift Exp (ix :. Exp e) Source # | |

(Slice (Plain ix), Lift Exp ix) => Lift Exp (ix :. All) Source # | |

(Slice (Plain ix), Lift Exp ix) => Lift Exp (ix :. Int) Source # | |

Elt e => IsList (Vector e) Source # | |

Show (Vector e) Source # | |

Shape sh => Elt (Any (sh :. Int)) Source # | |

(Eq tail, Eq head) => Eq (tail :. head) Source # | |

Show (Array DIM2 e) Source # | |

(Show sh, Show sz) => Show (sh :. sz) Source # | |

Slice sl => Slice (sl :. Int) Source # | |

Slice sl => Slice (sl :. All) Source # | |

Shape sh => Shape (sh :. Int) Source # | |

intersect :: (sh :. Int) -> (sh :. Int) -> sh :. Int union :: (sh :. Int) -> (sh :. Int) -> sh :. Int toIndex :: (sh :. Int) -> (sh :. Int) -> Int fromIndex :: (sh :. Int) -> Int -> sh :. Int iter :: (sh :. Int) -> ((sh :. Int) -> a) -> (a -> a -> a) -> a -> a iter1 :: (sh :. Int) -> ((sh :. Int) -> a) -> (a -> a -> a) -> a rangeToShape :: (sh :. Int, sh :. Int) -> sh :. Int shapeToRange :: (sh :. Int) -> (sh :. Int, sh :. Int) shapeToList :: (sh :. Int) -> [Int] listToShape :: [Int] -> sh :. Int sliceAnyIndex :: (sh :. Int) -> SliceIndex (EltRepr (Any (sh :. Int))) (EltRepr (sh :. Int)) () (EltRepr (sh :. Int)) sliceNoneIndex :: (sh :. Int) -> SliceIndex (EltRepr (sh :. Int)) () (EltRepr (sh :. Int)) (EltRepr (sh :. Int)) | |

(Elt t, Elt h) => Elt (t :. h) Source # | |

(Stencil (sh :. Int) a row2, Stencil (sh :. Int) a row1, Stencil (sh :. Int) a row0) => Stencil ((sh :. Int) :. Int) a (row2, row1, row0) Source # | |

(Stencil (sh :. Int) a row1, Stencil (sh :. Int) a row2, Stencil (sh :. Int) a row3, Stencil (sh :. Int) a row4, Stencil (sh :. Int) a row5) => Stencil ((sh :. Int) :. Int) a (row1, row2, row3, row4, row5) Source # | |

(Stencil (sh :. Int) a row1, Stencil (sh :. Int) a row2, Stencil (sh :. Int) a row3, Stencil (sh :. Int) a row4, Stencil (sh :. Int) a row5, Stencil (sh :. Int) a row6, Stencil (sh :. Int) a row7) => Stencil ((sh :. Int) :. Int) a (row1, row2, row3, row4, row5, row6, row7) Source # | |

(Stencil (sh :. Int) a row1, Stencil (sh :. Int) a row2, Stencil (sh :. Int) a row3, Stencil (sh :. Int) a row4, Stencil (sh :. Int) a row5, Stencil (sh :. Int) a row6, Stencil (sh :. Int) a row7, Stencil (sh :. Int) a row8, Stencil (sh :. Int) a row9) => Stencil ((sh :. Int) :. Int) a (row1, row2, row3, row4, row5, row6, row7, row8, row9) Source # | |

type Item (Vector e) Source # | |

type SliceShape (sl :. Int) Source # | |

type SliceShape (sl :. All) Source # | |

type CoSliceShape (sl :. Int) Source # | |

type CoSliceShape (sl :. All) Source # | |

type FullShape (sl :. Int) Source # | |

type FullShape (sl :. All) Source # | |

type Plain (ix :. Exp e) Source # | |

type Plain (ix :. All) Source # | |

type Plain (ix :. Int) Source # | |

class (Elt sh, Elt (Any sh), Shape (EltRepr sh), FullShape sh ~ sh, CoSliceShape sh ~ sh, SliceShape sh ~ Z) => Shape sh Source #

Shapes and indices of multi-dimensional arrays

sliceAnyIndex, sliceNoneIndex

## Instances

Shape Z Source # | |

iter :: Z -> (Z -> a) -> (a -> a -> a) -> a -> a iter1 :: Z -> (Z -> a) -> (a -> a -> a) -> a rangeToShape :: (Z, Z) -> Z shapeToRange :: Z -> (Z, Z) shapeToList :: Z -> [Int] listToShape :: [Int] -> Z sliceAnyIndex :: Z -> SliceIndex (EltRepr (Any Z)) (EltRepr Z) () (EltRepr Z) sliceNoneIndex :: Z -> SliceIndex (EltRepr Z) () (EltRepr Z) (EltRepr Z) | |

Shape sh => Shape (sh :. Int) Source # | |

intersect :: (sh :. Int) -> (sh :. Int) -> sh :. Int union :: (sh :. Int) -> (sh :. Int) -> sh :. Int toIndex :: (sh :. Int) -> (sh :. Int) -> Int fromIndex :: (sh :. Int) -> Int -> sh :. Int iter :: (sh :. Int) -> ((sh :. Int) -> a) -> (a -> a -> a) -> a -> a iter1 :: (sh :. Int) -> ((sh :. Int) -> a) -> (a -> a -> a) -> a rangeToShape :: (sh :. Int, sh :. Int) -> sh :. Int shapeToRange :: (sh :. Int) -> (sh :. Int, sh :. Int) shapeToList :: (sh :. Int) -> [Int] listToShape :: [Int] -> sh :. Int sliceAnyIndex :: (sh :. Int) -> SliceIndex (EltRepr (Any (sh :. Int))) (EltRepr (sh :. Int)) () (EltRepr (sh :. Int)) sliceNoneIndex :: (sh :. Int) -> SliceIndex (EltRepr (sh :. Int)) () (EltRepr (sh :. Int)) (EltRepr (sh :. Int)) |

class (Elt sl, Shape (SliceShape sl), Shape (CoSliceShape sl), Shape (FullShape sl)) => Slice sl where Source #

Slices, aka generalised indices, as *n*-tuples and mappings of slice
indices to slices, co-slices, and slice dimensions

sliceIndex :: sl -> SliceIndex (EltRepr sl) (EltRepr (SliceShape sl)) (EltRepr (CoSliceShape sl)) (EltRepr (FullShape sl)) Source #

## Instances

Slice Z Source # | |

Shape sh => Slice (Any sh) Source # | |

Slice sl => Slice (sl :. Int) Source # | |

Slice sl => Slice (sl :. All) Source # | |

Marker for entire dimensions in `slice`

and
`replicate`

descriptors.

Occurrences of `All`

indicate the dimensions into which the array's existing
extent will be placed unchanged.

## Instances

Eq All Source # | |

Show All Source # | |

Elt All Source # | |

(Slice (Plain ix), Lift Exp ix) => Lift Exp (ix :. All) Source # | |

Slice sl => Slice (sl :. All) Source # | |

type SliceShape (sl :. All) Source # | |

type CoSliceShape (sl :. All) Source # | |

type FullShape (sl :. All) Source # | |

type Plain (ix :. All) Source # | |

Marker for arbitrary dimensions in `slice`

and `replicate`

descriptors.

`Any`

can be used in the leftmost position of a slice instead of `Z`

,
indicating that any dimensionality is admissible in that position.

## Instances

Shape sh => Lift Exp (Any sh) Source # | |

Eq (Any sh) Source # | |

Show (Any sh) Source # | |

Shape sh => Slice (Any sh) Source # | |

Shape sh => Elt (Any (sh :. Int)) Source # | |

Elt (Any Z) Source # | |

type SliceShape (Any sh) Source # | |

type CoSliceShape (Any sh) Source # | |

type FullShape (Any sh) Source # | |

type Plain (Any sh) Source # | |

## Array access

### Element indexing

(!) :: (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh -> Exp e infixl 9 Source #

Multidimensional array indexing. Extract the value from an array at the specified zero-based index.

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

Matrix (Z :. 5 :. 10) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]`mat`

`>>>`

12`runExp $ use mat ! constant (Z:.1:.2)`

(!!) :: (Shape sh, Elt e) => Acc (Array sh e) -> Exp Int -> Exp e infixl 9 Source #

Extract the value from an array at the specified linear index. Multidimensional arrays in Accelerate are stored in row-major order with zero-based indexing.

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

Matrix (Z :. 5 :. 10) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]`mat`

`>>>`

12`runExp $ use mat !! 12`

the :: Elt e => Acc (Scalar e) -> Exp e Source #

Extract the element of a singleton array.

the xs == xs ! Z

### Shape information

shape :: (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh Source #

Extract the shape (extent) of an array.

size :: (Shape sh, Elt e) => Acc (Array sh e) -> Exp Int Source #

The number of elements in the array

shapeSize :: Shape sh => Exp sh -> Exp Int Source #

The number of elements that would be held by an array of the given shape.

## Construction

### Introduction

use :: Arrays arrays => arrays -> Acc arrays Source #

Make an array from vanilla Haskell available for processing within embedded Accelerate computations.

Depending upon which backend is used to eventually execute array
computations, `use`

may entail data transfer (e.g. to a GPU).

`use`

is overloaded so that it can accept tuples of `Arrays`

:

`>>>`

`let vec = fromList (Z:.10) [0..] :: Vector Int`

`>>>`

Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]`vec`

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

Matrix (Z :. 5 :. 10) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]`mat`

`>>>`

`let vec' = use vec :: Acc (Vector Int)`

`>>>`

`let mat' = use mat :: Acc (Matrix Int)`

`>>>`

`let tup = use (vec, mat) :: Acc (Vector Int, Matrix Int)`

unit :: Elt e => Exp e -> Acc (Scalar e) Source #

Construct a singleton (one element) array from a scalar value (or tuple of scalar values).

### Initialisation

generate :: (Shape sh, Elt a) => Exp sh -> (Exp sh -> Exp a) -> Acc (Array sh a) Source #

Construct a new array by applying a function to each index.

For example, the following will generate a one-dimensional array
(`Vector`

) of three floating point numbers:

`>>>`

Vector (Z :. 3) [1.2,1.2,1.2]`run $ generate (index1 3) (\_ -> 1.2) :: Vector Float`

Or equivalently:

`>>>`

Vector (Z :. 3) [1.2,1.2,1.2]`run $ fill (constant (Z :. 3)) 1.2 :: Vector Float`

The following will create a vector with the elements `[1..10]`

:

`>>>`

Vector (Z :. 10) [1,2,3,4,5,6,7,8,9,10]`run $ generate (index1 10) (\ix -> unindex1 ix + 1) :: Vector Int`

*NOTE:*

Using `generate`

, it is possible to introduce nested data parallelism, which
will cause the program to fail.

If the index given by the scalar function is then used to dispatch further
parallel work, whose result is returned into `Exp`

terms by array indexing
operations such as (`!`

) or `the`

, the program
will fail with the error:
`./Data/Array/Accelerate/Trafo/Sharing.hs:447 (convertSharingExp): inconsistent valuation @ shared 'Exp' tree ...`

.

fill :: (Shape sh, Elt e) => Exp sh -> Exp e -> Acc (Array sh e) Source #

Create an array where all elements are the same value.

`>>>`

Vector (Z :. 10) [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]`run $ fill (constant (Z:.10)) 0 :: Vector Float`

### Enumeration

enumFromN :: (Shape sh, Num e, FromIntegral Int e) => Exp sh -> Exp e -> Acc (Array sh e) Source #

Create an array of the given shape containing the values `x`

, `x+1`

, etc.
(in row-major order).

`>>>`

Matrix (Z :. 5 :. 10) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]`run $ enumFromN (constant (Z:.5:.10)) 0 :: Matrix Int`

:: (Shape sh, Num e, FromIntegral Int e) | |

=> Exp sh | |

-> Exp e | x: start |

-> Exp e | y: step |

-> Acc (Array sh e) |

Create an array of the given shape containing the values `x`

, `x+y`

,
`x+y+y`

etc. (in row-major order).

`>>>`

Matrix (Z :. 5 :. 10) [ 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0, 10.5, 11.0, 11.5, 12.0, 12.5, 13.0, 13.5, 14.0, 14.5, 15.0, 15.5, 16.0, 16.5, 17.0, 17.5, 18.0, 18.5, 19.0, 19.5, 20.0, 20.5, 21.0, 21.5, 22.0, 22.5, 23.0, 23.5, 24.0, 24.5]`run $ enumFromStepN (constant (Z:.5:.10)) 0 0.5 :: Matrix Float`

### Concatenation

(++) :: forall sh e. (Slice sh, Shape sh, Elt e) => Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e) infixr 5 Source #

Concatenate innermost component of two arrays. The extent of the lower dimensional component is the intersection of the two arrays.

`>>>`

`let m1 = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

Matrix (Z :. 5 :. 10) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]`m1`

`>>>`

`let m2 = fromList (Z:.10:.3) [0..] :: Matrix Int`

`>>>`

Matrix (Z :. 10 :. 3) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]`m2`

`>>>`

Matrix (Z :. 5 :. 13) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 3, 4, 5, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 6, 7, 8, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 9, 10, 11, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 12, 13, 14]`run $ use m1 ++ use m2`

concatOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Acc (Array sh e) -> Acc (Array sh e) -> Acc (Array sh e) Source #

Generalised version of '(++)' where the argument `Lens'`

specifies which
dimension to concatenate along.

Appropriate lenses are available from lens-accelerate.

`>>>`

`let m1 = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

Matrix (Z :. 5 :. 10) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]`m1`

`>>>`

`let m2 = fromList (Z:.10:.5) [0..] :: Matrix Int`

`>>>`

Matrix (Z :. 10 :. 5) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]`m2`

`>>>`

Matrix (Z :. 5 :. 15) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 10, 11, 12, 13, 14, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 15, 16, 17, 18, 19, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 20, 21, 22, 23, 24]`run $ concatOn _1 (use m1) (use m2)`

`>>>`

Matrix (Z :. 15 :. 5) [ 0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31, 32, 33, 34, 40, 41, 42, 43, 44, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]`run $ concatOn _2 (use m1) (use m2)`

## Composition

### Flow control

An array-level if-then-else construct.

Enabling the `RebindableSyntax`

extension will allow you to use the standard
if-then-else syntax instead.

class IfThenElse t where Source #

For use with `-XRebindableSyntax`

, this class provides `ifThenElse`

lifted
to both scalar and array types.

type EltT t a :: Constraint Source #

### Controlling execution

(>->) :: (Arrays a, Arrays b, Arrays c) => (Acc a -> Acc b) -> (Acc b -> Acc c) -> Acc a -> Acc c infixl 1 Source #

Pipelining of two array computations. The first argument will be fully evaluated before being passed to the second computation. This can be used to prevent the argument being fused into the function, for example.

Denotationally, we have

(acc1 >-> acc2) arrs = let tmp = acc1 arrs in tmp `seq` acc2 tmp

For an example use of this operation see the `compute`

function.

compute :: Arrays a => Acc a -> Acc a Source #

Force an array expression to be evaluated, preventing it from fusing with
other operations. Forcing operations to be computed to memory, rather than
being fused into their consuming function, can sometimes improve performance.
For example, computing a matrix `transpose`

could provide better memory
locality for the subsequent operation. Preventing fusion to split large
operations into several simpler steps could also help by reducing register
pressure.

Preventing fusion also means that the individual operations are available to be executed concurrently with other kernels. In particular, consider using this if you have a series of operations that are compute bound rather than memory bound.

Here is the synthetic example:

loop :: Exp Int -> Exp Int loop ticks = let clockRate = 900000 -- kHz in while (\i -> i < clockRate * ticks) (+1) 0 test :: Acc (Vector Int) test = zip3 (compute $ map loop (use $ fromList (Z:.1) [10])) (compute $ map loop (use $ fromList (Z:.1) [10])) (compute $ map loop (use $ fromList (Z:.1) [10]))

Without the use of `compute`

, the operations are fused together and the three
long-running loops are executed sequentially in a single kernel. Instead, the
individual operations can now be executed concurrently, potentially reducing
overall runtime.

## Element-wise operations

### Indexing

indexed :: (Shape sh, Elt a) => Acc (Array sh a) -> Acc (Array sh (sh, a)) Source #

Pair each element with its index

`>>>`

`let xs = fromList (Z:.5) [0..] :: Vector Float`

`>>>`

Vector (Z :. 5) [(Z :. 0,0.0),(Z :. 1,1.0),(Z :. 2,2.0),(Z :. 3,3.0),(Z :. 4,4.0)]`run $ indexed (use xs)`

`>>>`

`let mat = fromList (Z:.3:.4) [0..] :: Matrix Float`

`>>>`

Matrix (Z :. 3 :. 4) [ (Z :. 0 :. 0,0.0), (Z :. 0 :. 1,1.0), (Z :. 0 :. 2,2.0), (Z :. 0 :. 3,3.0), (Z :. 1 :. 0,4.0), (Z :. 1 :. 1,5.0), (Z :. 1 :. 2,6.0), (Z :. 1 :. 3,7.0), (Z :. 2 :. 0,8.0), (Z :. 2 :. 1,9.0), (Z :. 2 :. 2,10.0), (Z :. 2 :. 3,11.0)]`run $ indexed (use mat)`

### Mapping

map :: (Shape sh, Elt a, Elt b) => (Exp a -> Exp b) -> Acc (Array sh a) -> Acc (Array sh b) Source #

Apply the given function element-wise to an array. Denotationally we have:

map f [x1, x2, ... xn] = [f x1, f x2, ... f xn]

`>>>`

`let xs = fromList (Z:.10) [0..] :: Vector Int`

`>>>`

Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]`xs`

`>>>`

Vector (Z :. 10) [1,2,3,4,5,6,7,8,9,10]`run $ map (+1) (use xs)`

imap :: (Shape sh, Elt a, Elt b) => (Exp sh -> Exp a -> Exp b) -> Acc (Array sh a) -> Acc (Array sh b) Source #

Apply a function to every element of an array and its index

### Zipping

zipWith :: (Shape sh, Elt a, Elt b, Elt c) => (Exp a -> Exp b -> Exp c) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) Source #

Apply the given binary function element-wise to the two arrays. The extent of the resulting array is the intersection of the extents of the two source arrays.

`>>>`

`let xs = fromList (Z:.3:.5) [0..] :: Matrix Int`

`>>>`

Matrix (Z :. 3 :. 5) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]`xs`

`>>>`

`let ys = fromList (Z:.5:.10) [1..] :: Matrix Int`

`>>>`

Matrix (Z :. 5 :. 10) [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]`ys`

`>>>`

Matrix (Z :. 3 :. 5) [ 1, 3, 5, 7, 9, 16, 18, 20, 22, 24, 31, 33, 35, 37, 39]`run $ zipWith (+) (use xs) (use ys)`

zipWith3 :: (Shape sh, Elt a, Elt b, Elt c, Elt d) => (Exp a -> Exp b -> Exp c -> Exp d) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) Source #

Zip three arrays with the given function, analogous to `zipWith`

.

zipWith4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) Source #

Zip four arrays with the given function, analogous to `zipWith`

.

zipWith5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) Source #

Zip five arrays with the given function, analogous to `zipWith`

.

zipWith6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) Source #

Zip six arrays with the given function, analogous to `zipWith`

.

zipWith7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) Source #

Zip seven arrays with the given function, analogous to `zipWith`

.

zipWith8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh i) Source #

Zip eight arrays with the given function, analogous to `zipWith`

.

zipWith9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j) => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i -> Exp j) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh i) -> Acc (Array sh j) Source #

Zip nine arrays with the given function, analogous to `zipWith`

.

izipWith :: (Shape sh, Elt a, Elt b, Elt c) => (Exp sh -> Exp a -> Exp b -> Exp c) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) Source #

Zip two arrays with a function that also takes the element index

izipWith3 :: (Shape sh, Elt a, Elt b, Elt c, Elt d) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) Source #

Zip three arrays with a function that also takes the element index,
analogous to `izipWith`

.

izipWith4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) Source #

Zip four arrays with the given function that also takes the element index,
analogous to `zipWith`

.

izipWith5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) Source #

Zip five arrays with the given function that also takes the element index,
analogous to `zipWith`

.

izipWith6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) Source #

Zip six arrays with the given function that also takes the element index,
analogous to `zipWith`

.

izipWith7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) Source #

Zip seven arrays with the given function that also takes the element
index, analogous to `zipWith`

.

izipWith8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh i) Source #

Zip eight arrays with the given function that also takes the element
index, analogous to `zipWith`

.

izipWith9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j) => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i -> Exp j) -> Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh i) -> Acc (Array sh j) Source #

Zip nine arrays with the given function that also takes the element index,
analogous to `zipWith`

.

zip :: (Shape sh, Elt a, Elt b) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh (a, b)) Source #

Combine the elements of two arrays pairwise. The shape of the result is the intersection of the two argument shapes.

`>>>`

`let m1 = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`let m2 = fromList (Z:.10:.5) [0..] :: Matrix Float`

`>>>`

Matrix (Z :. 5 :. 5) [ (0,0.0), (1,1.0), (2,2.0), (3,3.0), (4,4.0), (10,5.0), (11,6.0), (12,7.0), (13,8.0), (14,9.0), (20,10.0), (21,11.0), (22,12.0), (23,13.0), (24,14.0), (30,15.0), (31,16.0), (32,17.0), (33,18.0), (34,19.0), (40,20.0), (41,21.0), (42,22.0), (43,23.0), (44,24.0)]`run $ zip (use m1) (use m2)`

zip3 :: (Shape sh, Elt a, Elt b, Elt c) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh (a, b, c)) Source #

Take three arrays and return an array of triples, analogous to zip.

zip4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh (a, b, c, d)) Source #

Take four arrays and return an array of quadruples, analogous to zip.

zip5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh (a, b, c, d, e)) Source #

Take five arrays and return an array of five-tuples, analogous to zip.

zip6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh (a, b, c, d, e, f)) Source #

Take six arrays and return an array of six-tuples, analogous to zip.

zip7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh (a, b, c, d, e, f, g)) Source #

Take seven arrays and return an array of seven-tuples, analogous to zip.

zip8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh (a, b, c, d, e, f, g, h)) Source #

Take seven arrays and return an array of seven-tuples, analogous to zip.

zip9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i) => Acc (Array sh a) -> Acc (Array sh b) -> Acc (Array sh c) -> Acc (Array sh d) -> Acc (Array sh e) -> Acc (Array sh f) -> Acc (Array sh g) -> Acc (Array sh h) -> Acc (Array sh i) -> Acc (Array sh (a, b, c, d, e, f, g, h, i)) Source #

Take seven arrays and return an array of seven-tuples, analogous to zip.

### Unzipping

unzip :: (Shape sh, Elt a, Elt b) => Acc (Array sh (a, b)) -> (Acc (Array sh a), Acc (Array sh b)) Source #

unzip3 :: (Shape sh, Elt a, Elt b, Elt c) => Acc (Array sh (a, b, c)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c)) Source #

Take an array of triples and return three arrays, analogous to `unzip`

.

unzip4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d) => Acc (Array sh (a, b, c, d)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d)) Source #

Take an array of quadruples and return four arrays, analogous to `unzip`

.

unzip5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e) => Acc (Array sh (a, b, c, d, e)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d), Acc (Array sh e)) Source #

Take an array of 5-tuples and return five arrays, analogous to `unzip`

.

unzip6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f) => Acc (Array sh (a, b, c, d, e, f)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d), Acc (Array sh e), Acc (Array sh f)) Source #

Take an array of 6-tuples and return six arrays, analogous to `unzip`

.

unzip7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g) => Acc (Array sh (a, b, c, d, e, f, g)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d), Acc (Array sh e), Acc (Array sh f), Acc (Array sh g)) Source #

Take an array of 7-tuples and return seven arrays, analogous to `unzip`

.

unzip8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h) => Acc (Array sh (a, b, c, d, e, f, g, h)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d), Acc (Array sh e), Acc (Array sh f), Acc (Array sh g), Acc (Array sh h)) Source #

Take an array of 8-tuples and return eight arrays, analogous to `unzip`

.

unzip9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i) => Acc (Array sh (a, b, c, d, e, f, g, h, i)) -> (Acc (Array sh a), Acc (Array sh b), Acc (Array sh c), Acc (Array sh d), Acc (Array sh e), Acc (Array sh f), Acc (Array sh g), Acc (Array sh h), Acc (Array sh i)) Source #

Take an array of 8-tuples and return eight arrays, analogous to `unzip`

.

## Modifying Arrays

### Shape manipulation

reshape :: (Shape sh, Shape sh', Elt e) => Exp sh -> Acc (Array sh' e) -> Acc (Array sh e) Source #

Change the shape of an array without altering its contents. The `size`

of
the source and result arrays must be identical.

precondition: shapeSize sh == shapeSize sh'

If the argument array is manifest in memory, `reshape`

is a no-op. If the
argument is to be fused into a subsequent operation, `reshape`

corresponds to
an index transformation in the fused code.

flatten :: forall sh e. (Shape sh, Elt e) => Acc (Array sh e) -> Acc (Vector e) Source #

Flatten the given array of arbitrary dimension into a one-dimensional
vector. As with `reshape`

, this operation performs no work.

### Replication

replicate :: (Slice slix, Elt e) => Exp slix -> Acc (Array (SliceShape slix) e) -> Acc (Array (FullShape slix) e) Source #

Replicate an array across one or more dimensions as specified by the
*generalised* array index provided as the first argument.

For example, given the following vector:

`>>>`

`let vec = fromList (Z:.10) [0..] :: Vector Int`

`>>>`

Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]`vec`

...we can replicate these elements to form a two-dimensional array either by replicating those elements as new rows:

`>>>`

Matrix (Z :. 4 :. 10) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`run $ replicate (constant (Z :. (4::Int) :. All)) (use vec)`

...or as columns:

`>>>`

Matrix (Z :. 10 :. 4) [ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9]`run $ replicate (lift (Z :. All :. (4::Int))) (use vec)`

Replication along more than one dimension is also possible. Here we replicate twice across the first dimension and three times across the third dimension:

`>>>`

Array (Z :. 2 :. 10 :. 3) [0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9]`run $ replicate (constant (Z :. (2::Int) :. All :. (3::Int))) (use vec)`

The marker `Any`

can be used in the slice specification to match against some
arbitrary dimension. For example, here `Any`

matches against whatever shape
type variable `sh`

takes.

`>>>`

let rep0 :: (Shape sh, Elt e) => Exp Int -> Acc (Array sh e) -> Acc (Array (sh :. Int) e) rep0 n a = replicate (lift (Any :. n)) a :}`:{`

`>>>`

`let x = unit 42 :: Acc (Scalar Int)`

`>>>`

Vector (Z :. 10) [42,42,42,42,42,42,42,42,42,42]`run $ rep0 10 x`

`>>>`

Matrix (Z :. 10 :. 5) [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9]`run $ rep0 5 (use vec)`

Of course, `Any`

and `All`

can be used together.

`>>>`

let rep1 :: (Shape sh, Elt e) => Exp Int -> Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int :. Int) e) rep1 n a = replicate (lift (Any :. n :. All)) a :}`:{`

`>>>`

Matrix (Z :. 5 :. 10) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`run $ rep1 5 (use vec)`

### Extracting sub-arrays

slice :: (Slice slix, Elt e) => Acc (Array (FullShape slix) e) -> Exp slix -> Acc (Array (SliceShape slix) e) Source #

Index an array with a *generalised* array index, supplied as the second
argument. The result is a new array (possibly a singleton) containing the
selected dimensions (`All`

s) in their entirety.

`slice`

is the opposite of `replicate`

, and can be used to *cut out* entire
dimensions. For example, for the two dimensional array `mat`

:

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

...will can select a specific row to yield a one dimensional result by fixing
the row index (2) while allowing the column index to vary (via `All`

):

`>>>`

Vector (Z :. 10) [20,21,22,23,24,25,26,27,28,29]`run $ slice (use mat) (constant (Z :. (2::Int) :. All))`

A fully specified index (with no `All`

s) returns a single element (zero
dimensional array).

`>>>`

Scalar Z [42]`run $ slice (use mat) (constant (Z :. 4 :. 2 :: DIM2))`

The marker `Any`

can be used in the slice specification to match against some
arbitrary (lower) dimension. Here `Any`

matches whatever shape type variable
`sh`

takes:

`>>>`

let sl0 :: (Shape sh, Elt e) => Acc (Array (sh:.Int) e) -> Exp Int -> Acc (Array sh e) sl0 a n = slice a (lift (Any :. n)) :}`:{`

`>>>`

`let vec = fromList (Z:.10) [0..] :: Vector Int`

`>>>`

Scalar Z [4]`run $ sl0 (use vec) 4`

`>>>`

Vector (Z :. 5) [4,14,24,34,44]`run $ sl0 (use mat) 4`

Of course, `Any`

and `All`

can be used together.

`>>>`

let sl1 :: (Shape sh, Elt e) => Acc (Array (sh:.Int:.Int) e) -> Exp Int -> Acc (Array (sh:.Int) e) sl1 a n = slice a (lift (Any :. n :. All)) :}`:{`

`>>>`

Vector (Z :. 10) [40,41,42,43,44,45,46,47,48,49]`run $ sl1 (use mat) 4`

`>>>`

`let cube = fromList (Z:.3:.4:.5) [0..] :: Array DIM3 Int`

`>>>`

Array (Z :. 3 :. 4 :. 5) [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59]`cube`

`>>>`

Matrix (Z :. 3 :. 5) [ 10, 11, 12, 13, 14, 30, 31, 32, 33, 34, 50, 51, 52, 53, 54]`run $ sl1 (use cube) 2`

init :: forall sh e. (Slice sh, Shape sh, Elt e) => Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e) Source #

Yield all but the elements in the last index of the innermost dimension.

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Matrix (Z :. 5 :. 9) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48]`run $ init (use mat)`

tail :: forall sh e. (Slice sh, Shape sh, Elt e) => Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e) Source #

Yield all but the first element along the innermost dimension of an array. The innermost dimension must not be empty.

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Matrix (Z :. 5 :. 9) [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 31, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49]`run $ tail (use mat)`

take :: forall sh e. (Slice sh, Shape sh, Elt e) => Exp Int -> Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e) Source #

Yield the first `n`

elements in the innermost dimension of the array (plus
all lower dimensional elements).

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Matrix (Z :. 5 :. 5) [ 0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31, 32, 33, 34, 40, 41, 42, 43, 44]`run $ take 5 (use mat)`

drop :: forall sh e. (Slice sh, Shape sh, Elt e) => Exp Int -> Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int) e) Source #

Yield all but the first `n`

elements along the innermost dimension of the
array (plus all lower dimensional elements).

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Matrix (Z :. 5 :. 3) [ 7, 8, 9, 17, 18, 19, 27, 28, 29, 37, 38, 39, 47, 48, 49]`run $ drop 7 (use mat)`

:: (Slice sh, Shape sh, Elt e) | |

=> Exp Int | starting index |

-> Exp Int | length |

-> Acc (Array (sh :. Int) e) | |

-> Acc (Array (sh :. Int) e) |

Yield a slit (slice) of the innermost indices of an array. Denotationally, we have:

slit i n = take n . drop i

initOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Acc (Array sh e) -> Acc (Array sh e) Source #

Generalised version of `init`

where the argument `Lens'`

specifies which
dimension to operate over.

Appropriate lenses are available from lens-accelerate.

*Since: 1.2.0.0*

tailOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Acc (Array sh e) -> Acc (Array sh e) Source #

Generalised version of `tail`

where the argument `Lens'`

specifies which
dimension to operate over.

Appropriate lenses are available from lens-accelerate.

*Since: 1.2.0.0*

takeOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Exp Int -> Acc (Array sh e) -> Acc (Array sh e) Source #

Generalised version of `take`

where the argument `Lens'`

specifies which
dimension to operate over.

Appropriate lenses are available from lens-accelerate.

*Since: 1.2.0.0*

dropOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Exp Int -> Acc (Array sh e) -> Acc (Array sh e) Source #

Generalised version of `drop`

where the argument `Lens'`

specifies which
dimension to operate over.

Appropriate lenses are available from lens-accelerate.

*Since: 1.2.0.0*

:: (Shape sh, Elt e) | |

=> Lens' (Exp sh) (Exp Int) | |

-> Exp Int | starting index |

-> Exp Int | length |

-> Acc (Array sh e) | |

-> Acc (Array sh e) |

Generalised version of `drop`

where the argument `Lens'`

specifies which
dimension to operate over.

Appropriate lenses are available from lens-accelerate.

*Since: 1.2.0.0*

### Permutations

#### Forward permutation (scatter)

:: (Shape sh, Shape sh', Elt a) | |

=> (Exp a -> Exp a -> Exp a) | combination function |

-> Acc (Array sh' a) | array of default values |

-> (Exp sh -> Exp sh') | index permutation function |

-> Acc (Array sh a) | array of source values to be permuted |

-> Acc (Array sh' a) |

Generalised forward permutation operation (array scatter).

Forward permutation specified by a function mapping indices from the source array to indices in the result array. The result array is initialised with the given defaults and any further values that are permuted into the result array are added to the current value using the given combination function.

The combination function must be *associative* and *commutative*. Elements
that are mapped to the magic index `ignore`

by the permutation function are
dropped.

The combination function is given the new value being permuted as its first argument, and the current value of the array as its second.

For example, we can use `permute`

to compute the occurrence count (histogram)
for an array of values in the range `[0,10)`

:

`>>>`

let histogram :: Acc (Vector Int) -> Acc (Vector Int) histogram xs = let zeros = fill (constant (Z:.10)) 0 ones = fill (shape xs) 1 in permute (+) zeros (\ix -> index1 (xs!ix)) ones :}`:{`

`>>>`

`let xs = fromList (Z :. 20) [0,0,1,2,1,1,2,4,8,3,4,9,8,3,2,5,5,3,1,2] :: Vector Int`

`>>>`

Vector (Z :. 10) [2,4,4,3,2,2,0,0,2,1]`run $ histogram (use xs)`

As a second example, note that the dimensionality of the source and
destination arrays can differ. In this way, we can use `permute`

to create an
identity matrix by overwriting elements along the diagonal:

`>>>`

let identity :: Num a => Exp Int -> Acc (Matrix a) identity n = let zeros = fill (index2 n n) 0 ones = fill (index1 n) 1 in permute const zeros (\(unindex1 -> i) -> index2 i i) ones :}`:{`

`>>>`

Matrix (Z :. 5 :. 5) [ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]`run $ identity 5 :: Matrix Int`

*Note:*

Regarding array fusion:

- The
`permute`

operation will always be evaluated; it can not be fused into a later step. - Since the index permutation function might not cover all positions in the output array (the function is not surjective), the array of default values must be evaluated. However, other operations may fuse into this.
- The array of source values can fuse into the permutation operation.
- If the array of default values is only used once, it will be updated in-place.

Regarding the defaults array:

If you are sure that the default values are not necessary---they are not used
by the combination function and every element will be overwritten---a default
array created by `fill`

ing with the value
`undef`

will give you a new uninitialised array.

ignore :: Shape sh => Exp sh Source #

Magic index identifying elements that are ignored in a forward permutation.

:: Elt e | |

=> Acc (Vector Int) | destination indices to scatter into |

-> Acc (Vector e) | default values |

-> Acc (Vector e) | source values |

-> Acc (Vector e) |

Overwrite elements of the destination by scattering the values of the source array according to the given index mapping.

Note that if the destination index appears more than once in the mapping the result is undefined.

`>>>`

`let to = fromList (Z :. 6) [1,3,7,2,5,8] :: Vector Int`

`>>>`

`let input = fromList (Z :. 7) [1,9,6,4,4,2,5] :: Vector Int`

`>>>`

Vector (Z :. 10) [0,1,4,9,0,4,0,6,2,0]`run $ scatter (use to) (fill (constant (Z:.10)) 0) (use input)`

#### Backward permutation (gather)

:: (Shape sh, Shape sh', Elt a) | |

=> Exp sh' | shape of the result array |

-> (Exp sh' -> Exp sh) | index permutation function |

-> Acc (Array sh a) | source array |

-> Acc (Array sh' a) |

Generalised backward permutation operation (array gather).

Backward permutation specified by a function mapping indices in the destination array to indices in the source array. Elements of the output array are thus generated by reading from the corresponding index in the source array.

For example, backpermute can be used to
`transpose`

a matrix; at every index `Z:.y:.x`

in the result array, we get the value at that index by reading from the
source array at index `Z:.x:.y`

:

`>>>`

let swap :: Exp DIM2 -> Exp DIM2 swap = lift1 f where f :: Z :. Exp Int :. Exp Int -> Z :. Exp Int :. Exp Int f (Z:.y:.x) = Z :. x :. y :}`:{`

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

`let mat' = use mat`

`>>>`

Matrix (Z :. 10 :. 5) [ 0, 10, 20, 30, 40, 1, 11, 21, 31, 41, 2, 12, 22, 32, 42, 3, 13, 23, 33, 43, 4, 14, 24, 34, 44, 5, 15, 25, 35, 45, 6, 16, 26, 36, 46, 7, 17, 27, 37, 47, 8, 18, 28, 38, 48, 9, 19, 29, 39, 49]`run $ backpermute (swap (shape mat')) swap mat'`

:: (Shape sh, Elt e) | |

=> Acc (Array sh Int) | index of source at each index to gather |

-> Acc (Vector e) | source values |

-> Acc (Array sh e) |

Gather elements from a source array by reading values at the given indices.

`>>>`

`let input = fromList (Z:.9) [1,9,6,4,4,2,0,1,2] :: Vector Int`

`>>>`

`let from = fromList (Z:.6) [1,3,7,2,5,3] :: Vector Int`

`>>>`

Vector (Z :. 6) [9,4,1,6,2,4]`run $ gather (use from) (use input)`

#### Specialised permutations

transpose :: Elt e => Acc (Array DIM2 e) -> Acc (Array DIM2 e) Source #

Transpose the rows and columns of a matrix.

reverseOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Acc (Array sh e) -> Acc (Array sh e) Source #

Generalised version of `reverse`

where the argument `Lens'`

specifies which
dimension to reverse.

Appropriate lenses are available from lens-accelerate.

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Matrix (Z :. 5 :. 10) [ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40]`run $ reverseOn _1 (use mat)`

`>>>`

Matrix (Z :. 5 :. 10) [ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`run $ reverseOn _2 (use mat)`

*Since: 1.2.0.0*

transposeOn :: (Shape sh, Elt e) => Lens' (Exp sh) (Exp Int) -> Lens' (Exp sh) (Exp Int) -> Acc (Array sh e) -> Acc (Array sh e) Source #

Generalised version of `transpose`

where the argument `Lens'`

s specify
which two dimensions to transpose.

Appropriate lenses are available from lens-accelerate.

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Matrix (Z :. 10 :. 5) [ 0, 10, 20, 30, 40, 1, 11, 21, 31, 41, 2, 12, 22, 32, 42, 3, 13, 23, 33, 43, 4, 14, 24, 34, 44, 5, 15, 25, 35, 45, 6, 16, 26, 36, 46, 7, 17, 27, 37, 47, 8, 18, 28, 38, 48, 9, 19, 29, 39, 49]`run $ transposeOn _1 _2 (use mat)`

`>>>`

`let box = fromList (Z:.2:.3:.5) [0..] :: Array DIM3 Int`

`>>>`

Array (Z :. 2 :. 3 :. 5) [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29]`box`

`>>>`

Array (Z :. 2 :. 5 :. 3) [0,5,10,1,6,11,2,7,12,3,8,13,4,9,14,15,20,25,16,21,26,17,22,27,18,23,28,19,24,29]`run $ transposeOn _1 _2 (use box)`

`>>>`

Array (Z :. 3 :. 2 :. 5) [0,1,2,3,4,15,16,17,18,19,5,6,7,8,9,20,21,22,23,24,10,11,12,13,14,25,26,27,28,29]`run $ transposeOn _2 _3 (use box)`

`>>>`

Array (Z :. 5 :. 3 :. 2) [0,15,5,20,10,25,1,16,6,21,11,26,2,17,7,22,12,27,3,18,8,23,13,28,4,19,9,24,14,29]`run $ transposeOn _1 _3 (use box)`

*Since: 1.2.0.0*

### Filtering

filter :: forall sh e. (Shape sh, Slice sh, Elt e) => (Exp e -> Exp Bool) -> Acc (Array (sh :. Int) e) -> Acc (Vector e, Array sh Int) Source #

Drop elements that do not satisfy the predicate. Returns the elements which pass the predicate, together with a segment descriptor indicating how many elements along each outer dimension were valid.

`>>>`

`let vec = fromList (Z :. 10) [1..10] :: Vector Int`

`>>>`

Vector (Z :. 10) [1,2,3,4,5,6,7,8,9,10]`vec`

`>>>`

(Vector (Z :. 5) [2,4,6,8,10],Scalar Z [5])`run $ filter even (use vec)`

`>>>`

`let mat = fromList (Z :. 4 :. 10) [1,2,3,4,5,6,7,8,9,10,1,1,1,1,1,2,2,2,2,2,2,4,6,8,10,12,14,16,18,20,1,3,5,7,9,11,13,15,17,19] :: Matrix Int`

`>>>`

Matrix (Z :. 4 :. 10) [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]`mat`

`>>>`

(Vector (Z :. 20) [1,3,5,7,9,1,1,1,1,1,1,3,5,7,9,11,13,15,17,19],Vector (Z :. 4) [5,5,0,10])`run $ filter odd (use mat)`

## Folding

fold :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array sh a) Source #

Reduction of the innermost dimension of an array of arbitrary rank.

The shape of the result obeys the property:

shape (fold f z xs) == indexTail (shape xs)

The first argument needs to be an *associative* function to enable an
efficient parallel implementation. The initial element does not need to be an
identity element of the combination function.

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Vector (Z :. 5) [87,187,287,387,487]`run $ fold (+) 42 (use mat)`

Reductions with non-commutative operators are supported. For example, the following computes the maximum segment sum problem along each innermost dimension of the array.

https://en.wikipedia.org/wiki/Maximum_subarray_problem

`>>>`

let maximumSegmentSum :: forall sh e. (Shape sh, Num e, Ord e) => Acc (Array (sh :. Int) e) -> Acc (Array sh e) maximumSegmentSum = map (\v -> let (x,_,_,_) = unlift v :: (Exp e, Exp e, Exp e, Exp e) in x) . fold1 f . map g where f :: (Num a, Ord a) => Exp (a,a,a,a) -> Exp (a,a,a,a) -> Exp (a,a,a,a) f x y = let (mssx, misx, mcsx, tsx) = unlift x (mssy, misy, mcsy, tsy) = unlift y in lift ( mssx `max` (mssy `max` (mcsx+misy)) , misx `max` (tsx+misy) , mcsy `max` (mcsx+tsy) , tsx+tsy ) -- g :: (Num a, Ord a) => Exp a -> Exp (a,a,a,a) g x = let y = max x 0 in lift (y,y,y,x) :}`:{`

`>>>`

`let vec = fromList (Z:.10) [-2,1,-3,4,-1,2,1,-5,4,0] :: Vector Int`

`>>>`

Scalar Z [6]`run $ maximumSegmentSum (use vec)`

See also `Fold`

, which can be a useful way to
compute multiple results from a single reduction.

fold1 :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Acc (Array (sh :. Int) a) -> Acc (Array sh a) Source #

Variant of `fold`

that requires the innermost dimension of the array to be
non-empty and doesn't need an default value.

The shape of the result obeys the property:

shape (fold f z xs) == indexTail (shape xs)

The first argument needs to be an *associative* function to enable an
efficient parallel implementation, but does not need to be commutative.

foldAll :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array sh a) -> Acc (Scalar a) Source #

Reduction of an array of arbitrary rank to a single scalar value. The first
argument needs to be an *associative* function to enable efficient parallel
implementation. The initial element does not need to be an identity element.

`>>>`

`let vec = fromList (Z:.10) [0..] :: Vector Float`

`>>>`

Scalar Z [87.0]`run $ foldAll (+) 42 (use vec)`

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Float`

`>>>`

Scalar Z [1225.0]`run $ foldAll (+) 0 (use mat)`

fold1All :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Acc (Array sh a) -> Acc (Scalar a) Source #

Variant of `foldAll`

that requires the reduced array to be non-empty and
does not need a default value. The first argument must be an *associative*
function.

### Segmented reductions

foldSeg :: (Shape sh, Elt a, Elt i, IsIntegral i) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Segments i) -> Acc (Array (sh :. Int) a) Source #

Segmented reduction along the innermost dimension of an array. The segment descriptor specifies the lengths of the logical sub-arrays, each of which is reduced independently. The innermost dimension must contain at least as many elements as required by the segment descriptor (sum thereof).

`>>>`

`let seg = fromList (Z:.4) [1,4,0,3] :: Segments Int`

`>>>`

Vector (Z :. 4) [1,4,0,3]`seg`

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Matrix (Z :. 5 :. 4) [ 0, 10, 0, 18, 10, 50, 0, 48, 20, 90, 0, 78, 30, 130, 0, 108, 40, 170, 0, 138]`run $ foldSeg (+) 0 (use mat) (use seg)`

fold1Seg :: (Shape sh, Elt a, Elt i, IsIntegral i) => (Exp a -> Exp a -> Exp a) -> Acc (Array (sh :. Int) a) -> Acc (Segments i) -> Acc (Array (sh :. Int) a) Source #

Variant of `foldSeg`

that requires *all* segments of the reduced array to
be non-empty and doesn't need a default value. The segment descriptor
specifies the length of each of the logical sub-arrays.

### Specialised reductions

all :: (Shape sh, Elt e) => (Exp e -> Exp Bool) -> Acc (Array (sh :. Int) e) -> Acc (Array sh Bool) Source #

Check if all elements along the innermost dimension satisfy a predicate.

`>>>`

`let mat = fromList (Z :. 4 :. 10) [1,2,3,4,5,6,7,8,9,10,1,1,1,1,1,2,2,2,2,2,2,4,6,8,10,12,14,16,18,20,1,3,5,7,9,11,13,15,17,19] :: Matrix Int`

`>>>`

Matrix (Z :. 4 :. 10) [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]`mat`

`>>>`

Vector (Z :. 4) [False,False,True,False]`run $ all even (use mat)`

any :: (Shape sh, Elt e) => (Exp e -> Exp Bool) -> Acc (Array (sh :. Int) e) -> Acc (Array sh Bool) Source #

Check if any element along the innermost dimension satisfies the predicate.

`>>>`

`let mat = fromList (Z :. 4 :. 10) [1,2,3,4,5,6,7,8,9,10,1,1,1,1,1,2,2,2,2,2,2,4,6,8,10,12,14,16,18,20,1,3,5,7,9,11,13,15,17,19] :: Matrix Int`

`>>>`

Matrix (Z :. 4 :. 10) [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]`mat`

`>>>`

Vector (Z :. 4) [True,True,True,False]`run $ any even (use mat)`

and :: Shape sh => Acc (Array (sh :. Int) Bool) -> Acc (Array sh Bool) Source #

Check if all elements along the innermost dimension are `True`

.

or :: Shape sh => Acc (Array (sh :. Int) Bool) -> Acc (Array sh Bool) Source #

Check if any element along the innermost dimension is `True`

.

sum :: (Shape sh, Num e) => Acc (Array (sh :. Int) e) -> Acc (Array sh e) Source #

Compute the sum of elements along the innermost dimension of the array. To
find the sum of the entire array, `flatten`

it first.

`>>>`

`let mat = fromList (Z:.2:.5) [0..] :: Matrix Int`

`>>>`

Vector (Z :. 2) [10,35]`run $ sum (use mat)`

product :: (Shape sh, Num e) => Acc (Array (sh :. Int) e) -> Acc (Array sh e) Source #

Compute the product of the elements along the innermost dimension of the
array. To find the product of the entire array, `flatten`

it first.

`>>>`

`let mat = fromList (Z:.2:.5) [0..] :: Matrix Int`

`>>>`

Vector (Z :. 2) [0,15120]`run $ product (use mat)`

minimum :: (Shape sh, Ord e) => Acc (Array (sh :. Int) e) -> Acc (Array sh e) Source #

Yield the minimum element along the innermost dimension of the array. To
find find the minimum element of the entire array, `flatten`

it first.

The array must not be empty. See also `fold1`

.

`>>>`

`let mat = fromList (Z :. 3 :. 4) [1,4,3,8, 0,2,8,4, 7,9,8,8] :: Matrix Int`

`>>>`

Matrix (Z :. 3 :. 4) [ 1, 4, 3, 8, 0, 2, 8, 4, 7, 9, 8, 8]`mat`

`>>>`

Vector (Z :. 3) [1,0,7]`run $ minimum (use mat)`

maximum :: (Shape sh, Ord e) => Acc (Array (sh :. Int) e) -> Acc (Array sh e) Source #

Yield the maximum element along the innermost dimension of the array. To
find the maximum element of the entire array, `flatten`

it first.

The array must not be empty. See also `fold1`

.

`>>>`

`let mat = fromList (Z :. 3 :. 4) [1,4,3,8, 0,2,8,4, 7,9,8,8] :: Matrix Int`

`>>>`

Matrix (Z :. 3 :. 4) [ 1, 4, 3, 8, 0, 2, 8, 4, 7, 9, 8, 8]`mat`

`>>>`

Vector (Z :. 3) [8,8,9]`run $ maximum (use mat)`

## Scans (prefix sums)

scanl :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a) Source #

Data.List style left-to-right scan along the innermost dimension of an
arbitrary rank array. The first argument needs to be an *associative*
function to enable efficient parallel implementation. The initial value
(second argument) may be arbitrary.

`>>>`

`let vec = fromList (Z :. 10) [0..] :: Vector Int`

`>>>`

Vector (Z :. 11) [10,10,11,13,16,20,25,31,38,46,55]`run $ scanl (+) 10 (use vec)`

`>>>`

`let mat = fromList (Z :. 4 :. 10) [0..] :: Matrix Int`

`>>>`

Matrix (Z :. 4 :. 11) [ 0, 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 0, 10, 21, 33, 46, 60, 75, 91, 108, 126, 145, 0, 20, 41, 63, 86, 110, 135, 161, 188, 216, 245, 0, 30, 61, 93, 126, 160, 195, 231, 268, 306, 345]`run $ scanl (+) 0 (use mat)`

scanl1 :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a) Source #

Data.List style left-to-right scan along the innermost dimension without an
initial value (aka inclusive scan). The innermost dimension of the array must
not be empty. The first argument must be an *associative* function.

`>>>`

`let mat = fromList (Z:.4:.10) [0..] :: Matrix Int`

`>>>`

Matrix (Z :. 4 :. 10) [ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 10, 21, 33, 46, 60, 75, 91, 108, 126, 145, 20, 41, 63, 86, 110, 135, 161, 188, 216, 245, 30, 61, 93, 126, 160, 195, 231, 268, 306, 345]`run $ scanl1 (+) (use mat)`

scanl' :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a, Array sh a) Source #

Variant of `scanl`

, where the last element (final reduction result) along
each dimension is returned separately. Denotationally we have:

scanl' f e arr = (init res, unit (res!len)) where len = shape arr res = scanl f e arr

`>>>`

`let vec = fromList (Z:.10) [0..] :: Vector Int`

`>>>`

`let (res,sum) = run $ scanl' (+) 0 (use vec)`

`>>>`

Vector (Z :. 10) [0,0,1,3,6,10,15,21,28,36]`res`

`>>>`

Scalar Z [45]`sum`

`>>>`

`let mat = fromList (Z:.4:.10) [0..] :: Matrix Int`

`>>>`

`let (res,sums) = run $ scanl' (+) 0 (use mat)`

`>>>`

Matrix (Z :. 4 :. 10) [ 0, 0, 1, 3, 6, 10, 15, 21, 28, 36, 0, 10, 21, 33, 46, 60, 75, 91, 108, 126, 0, 20, 41, 63, 86, 110, 135, 161, 188, 216, 0, 30, 61, 93, 126, 160, 195, 231, 268, 306]`res`

`>>>`

Vector (Z :. 4) [45,145,245,345]`sums`

scanr :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a) Source #

Right-to-left variant of `scanl`

.

scanr1 :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a) Source #

Right-to-left variant of `scanl1`

.

scanr' :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a, Array sh a) Source #

Right-to-left variant of `scanl'`

.

prescanl :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a) Source #

Left-to-right pre-scan (aka exclusive scan). As for `scan`

, the first
argument must be an *associative* function. Denotationally, we have:

prescanl f e = afst . scanl' f e

`>>>`

`let vec = fromList (Z:.10) [1..10] :: Vector Int`

`>>>`

Vector (Z :. 10) [0,1,3,6,10,15,21,28,36,45]`run $ prescanl (+) 0 (use vec)`

postscanl :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a) Source #

Left-to-right post-scan, a variant of `scanl1`

with an initial value. As
with `scanl1`

, the array must not be empty. Denotationally, we have:

postscanl f e = map (e `f`) . scanl1 f

`>>>`

`let vec = fromList (Z:.10) [1..10] :: Vector Int`

`>>>`

Vector (Z :. 10) [43,45,48,52,57,63,70,78,87,97]`run $ postscanl (+) 42 (use vec)`

prescanr :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a) Source #

Right-to-left pre-scan (aka exclusive scan). As for `scan`

, the first
argument must be an *associative* function. Denotationally, we have:

prescanr f e = afst . scanr' f e

postscanr :: (Shape sh, Elt a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh :. Int) a) -> Acc (Array (sh :. Int) a) Source #

Right-to-left postscan, a variant of `scanr1`

with an initial value.
Denotationally, we have:

postscanr f e = map (e `f`) . scanr1 f

### Segmented scans

scanlSeg :: forall sh e i. (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e) Source #

Segmented version of `scanl`

along the innermost dimension of an array. The
innermost dimension must have at least as many elements as the sum of the
segment descriptor.

`>>>`

`let seg = fromList (Z:.4) [1,4,0,3] :: Segments Int`

`>>>`

Vector (Z :. 4) [1,4,0,3]`seg`

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Matrix (Z :. 5 :. 12) [ 0, 0, 0, 1, 3, 6, 10, 0, 0, 5, 11, 18, 0, 10, 0, 11, 23, 36, 50, 0, 0, 15, 31, 48, 0, 20, 0, 21, 43, 66, 90, 0, 0, 25, 51, 78, 0, 30, 0, 31, 63, 96, 130, 0, 0, 35, 71, 108, 0, 40, 0, 41, 83, 126, 170, 0, 0, 45, 91, 138]`run $ scanlSeg (+) 0 (use mat) (use seg)`

scanl1Seg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e) Source #

Segmented version of `scanl1`

along the innermost dimension.

As with `scanl1`

, the total number of elements considered, in this case given
by the `sum`

of segment descriptor, must not be zero. The input vector must
contain at least this many elements.

Zero length segments are allowed, and the behaviour is as if those entries were not present in the segment descriptor; that is:

scanl1Seg f xs [n,0,0] == scanl1Seg f xs [n] where n /= 0

`>>>`

`let seg = fromList (Z:.4) [1,4,0,3] :: Segments Int`

`>>>`

Vector (Z :. 4) [1,4,0,3]`seg`

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Matrix (Z :. 5 :. 8) [ 0, 1, 3, 6, 10, 5, 11, 18, 10, 11, 23, 36, 50, 15, 31, 48, 20, 21, 43, 66, 90, 25, 51, 78, 30, 31, 63, 96, 130, 35, 71, 108, 40, 41, 83, 126, 170, 45, 91, 138]`run $ scanl1Seg (+) (use mat) (use seg)`

scanl'Seg :: forall sh e i. (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e, Array (sh :. Int) e) Source #

Segmented version of `scanl'`

along the innermost dimension of an array. The
innermost dimension must have at least as many elements as the sum of the
segment descriptor.

The first element of the resulting tuple is a vector of scanned values. The second element is a vector of segment scan totals and has the same size as the segment vector.

`>>>`

`let seg = fromList (Z:.4) [1,4,0,3] :: Segments Int`

`>>>`

Vector (Z :. 4) [1,4,0,3]`seg`

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

`let (res,sums) = run $ scanl'Seg (+) 0 (use mat) (use seg)`

`>>>`

Matrix (Z :. 5 :. 8) [ 0, 0, 1, 3, 6, 0, 5, 11, 0, 0, 11, 23, 36, 0, 15, 31, 0, 0, 21, 43, 66, 0, 25, 51, 0, 0, 31, 63, 96, 0, 35, 71, 0, 0, 41, 83, 126, 0, 45, 91]`res`

`>>>`

Matrix (Z :. 5 :. 4) [ 0, 10, 0, 18, 10, 50, 0, 48, 20, 90, 0, 78, 30, 130, 0, 108, 40, 170, 0, 138]`sums`

prescanlSeg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e) Source #

Segmented version of `prescanl`

.

postscanlSeg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e) Source #

Segmented version of `postscanl`

.

scanrSeg :: forall sh e i. (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e) Source #

Segmented version of `scanr`

along the innermost dimension of an array. The
innermost dimension must have at least as many elements as the sum of the
segment descriptor.

`>>>`

`let seg = fromList (Z:.4) [1,4,0,3] :: Segments Int`

`>>>`

Vector (Z :. 4) [1,4,0,3]`seg`

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Matrix (Z :. 5 :. 12) [ 2, 0, 18, 15, 11, 6, 0, 0, 24, 17, 9, 0, 12, 0, 58, 45, 31, 16, 0, 0, 54, 37, 19, 0, 22, 0, 98, 75, 51, 26, 0, 0, 84, 57, 29, 0, 32, 0, 138, 105, 71, 36, 0, 0, 114, 77, 39, 0, 42, 0, 178, 135, 91, 46, 0, 0, 144, 97, 49, 0]`run $ scanrSeg (+) 0 (use mat) (use seg)`

scanr1Seg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e) Source #

Segmented version of `scanr1`

.

`>>>`

`let seg = fromList (Z:.4) [1,4,0,3] :: Segments Int`

`>>>`

Vector (Z :. 4) [1,4,0,3]`seg`

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

Matrix (Z :. 5 :. 8) [ 0, 10, 9, 7, 4, 18, 13, 7, 10, 50, 39, 27, 14, 48, 33, 17, 20, 90, 69, 47, 24, 78, 53, 27, 30, 130, 99, 67, 34, 108, 73, 37, 40, 170, 129, 87, 44, 138, 93, 47]`run $ scanr1Seg (+) (use mat) (use seg)`

scanr'Seg :: forall sh e i. (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e, Array (sh :. Int) e) Source #

Segmented version of `scanr'`

.

`>>>`

`let seg = fromList (Z:.4) [1,4,0,3] :: Segments Int`

`>>>`

Vector (Z :. 4) [1,4,0,3]`seg`

`>>>`

`let mat = fromList (Z:.5:.10) [0..] :: Matrix Int`

`>>>`

`mat`

`>>>`

`let (res,sums) = run $ scanr'Seg (+) 0 (use mat) (use seg)`

`>>>`

Matrix (Z :. 5 :. 8) [ 0, 15, 11, 6, 0, 17, 9, 0, 0, 45, 31, 16, 0, 37, 19, 0, 0, 75, 51, 26, 0, 57, 29, 0, 0, 105, 71, 36, 0, 77, 39, 0, 0, 135, 91, 46, 0, 97, 49, 0]`res`

`>>>`

Matrix (Z :. 5 :. 4) [ 2, 18, 0, 24, 12, 58, 0, 54, 22, 98, 0, 84, 32, 138, 0, 114, 42, 178, 0, 144]`sums`

prescanrSeg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e) Source #

Segmented version of `prescanr`

.

postscanrSeg :: (Shape sh, Slice sh, Elt e, Integral i, Bits i, FromIntegral i Int) => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Array (sh :. Int) e) -> Acc (Segments i) -> Acc (Array (sh :. Int) e) Source #

Segmented version of `postscanr`

.

## Stencils

:: (Stencil sh a stencil, Elt b) | |

=> (stencil -> Exp b) | stencil function |

-> Boundary (Array sh a) | boundary condition |

-> Acc (Array sh a) | source array |

-> Acc (Array sh b) | destination array |

Map a stencil over an array. In contrast to `map`

, the domain of a stencil
function is an entire *neighbourhood* of each array element. Neighbourhoods
are sub-arrays centred around a focal point. They are not necessarily
rectangular, but they are symmetric and have an extent of at least three
along each axis. Due to the symmetry requirement the extent is necessarily
odd. The focal point is the array position that is determined by the stencil.

For those array positions where the neighbourhood extends past the boundaries of the source array, a boundary condition determines the contents of the out-of-bounds neighbourhood positions.

Stencil neighbourhoods are specified via nested tuples, where the nesting depth is equal to the dimensionality of the array. For example, a 3x1 stencil for a one-dimensional array:

s31 :: Stencil3 a -> Exp a s31 (l,c,r) = ...

...where `c`

is the focal point of the stencil, and `l`

and `r`

represent the
elements to the left and right of the focal point, respectively. Similarly,
a 3x3 stencil for a two-dimensional array:

s33 :: Stencil3x3 a -> Exp a s33 ((_,t,_) ,(l,c,r) ,(_,b,_)) = ...

...where `c`

is again the focal point and `t`

, `b`

, `l`

and `r`

are the
elements to the top, bottom, left, and right of the focal point, respectively
(the diagonal elements have been elided).

For example, the following computes a 5x5 Gaussian blur as a separable 2-pass operation.

type Stencil5x1 a = (Stencil3 a, Stencil5 a, Stencil3 a) type Stencil1x5 a = (Stencil3 a, Stencil3 a, Stencil3 a, Stencil3 a, Stencil3 a) convolve5x1 :: Num a => [Exp a] -> Stencil5x1 a -> Exp a convolve5x1 kernel (_, (a,b,c,d,e), _) = Prelude.sum $ Prelude.zipWith (*) kernel [a,b,c,d,e] convolve1x5 :: Num a => [Exp a] -> Stencil1x5 a -> Exp a convolve1x5 kernel ((_,a,_), (_,b,_), (_,c,_), (_,d,_), (_,e,_)) = Prelude.sum $ Prelude.zipWith (*) kernel [a,b,c,d,e] gaussian = [0.06136,0.24477,0.38774,0.24477,0.06136] blur :: Num a => Acc (Matrix a) -> Acc (Matrix a) blur = stencil (convolve5x1 gaussian) clamp . stencil (convolve1x5 gaussian) clamp

:: (Stencil sh a stencil1, Stencil sh b stencil2, Elt c) | |

=> (stencil1 -> stencil2 -> Exp c) | binary stencil function |

-> Boundary (Array sh a) | boundary condition #1 |

-> Acc (Array sh a) | source array #1 |

-> Boundary (Array sh b) | boundary condition #2 |

-> Acc (Array sh b) | source array #2 |

-> Acc (Array sh c) | destination array |

Map a binary stencil of an array. The extent of the resulting array is the
intersection of the extents of the two source arrays. This is the stencil
equivalent of `zipWith`

.

### Stencil specification

class (Elt (StencilRepr sh stencil), Stencil sh a (StencilRepr sh stencil)) => Stencil sh a stencil Source #

stencilPrj

## Instances

Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e) Source # | |

Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e) Source # | |

Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e) Source # | |

Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e) Source # | |

(Stencil (sh :. Int) a row2, Stencil (sh :. Int) a row1, Stencil (sh :. Int) a row0) => Stencil ((sh :. Int) :. Int) a (row2, row1, row0) Source # | |

(Stencil (sh :. Int) a row1, Stencil (sh :. Int) a row2, Stencil (sh :. Int) a row3, Stencil (sh :. Int) a row4, Stencil (sh :. Int) a row5) => Stencil ((sh :. Int) :. Int) a (row1, row2, row3, row4, row5) Source # | |

(Stencil (sh :. Int) a row1, Stencil (sh :. Int) a row2, Stencil (sh :. Int) a row3, Stencil (sh :. Int) a row4, Stencil (sh :. Int) a row5, Stencil (sh :. Int) a row6, Stencil (sh :. Int) a row7) => Stencil ((sh :. Int) :. Int) a (row1, row2, row3, row4, row5, row6, row7) Source # | |

(Stencil (sh :. Int) a row1, Stencil (sh :. Int) a row2, Stencil (sh :. Int) a row3, Stencil (sh :. Int) a row4, Stencil (sh :. Int) a row5, Stencil (sh :. Int) a row6, Stencil (sh :. Int) a row7, Stencil (sh :. Int) a row8, Stencil (sh :. Int) a row9) => Stencil ((sh :. Int) :. Int) a (row1, row2, row3, row4, row5, row6, row7, row8, row9) Source # | |

clamp :: Boundary (Array sh e) Source #

Boundary condition where elements of the stencil which would be out-of-bounds are instead clamped to the edges of the array.

In the following 3x3 stencil, the out-of-bounds element `b`

will instead
return the value at position `c`

:

+------------+ |a | b|cd | |e | +------------+

mirror :: Boundary (Array sh e) Source #

Stencil boundary condition where coordinates beyond the array extent are instead mirrored

In the following 5x3 stencil, the out-of-bounds element `c`

will instead
return the value at position `d`

, and similarly the element at `b`

will
return the value at `e`

:

+------------+ |a | bc|def | |g | +------------+