-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | High performance, regular, shape polymorphic parallel arrays. -- -- Repa provides high performance, regular, multi-dimensional, shape -- polymorphic parallel arrays. All numeric data is stored unboxed. -- Functions written with the Repa combinators are automatically parallel -- provided you supply +RTS -Nwhatever on the command line when running -- the program. @package repa @version 3.4.0.1 -- | Class of types that can be used as array shapes and indices. module Data.Array.Repa.Shape -- | Class of types that can be used as array shapes and indices. class Eq sh => Shape sh -- | Get the number of dimensions in a shape. rank :: Shape sh => sh -> Int -- | The shape of an array of size zero, with a particular dimensionality. zeroDim :: Shape sh => sh -- | The shape of an array with size one, with a particular dimensionality. unitDim :: Shape sh => sh -- | Compute the intersection of two shapes. intersectDim :: Shape sh => sh -> sh -> sh -- | Add the coordinates of two shapes componentwise addDim :: Shape sh => sh -> sh -> sh -- | Get the total number of elements in an array with this shape. size :: Shape sh => sh -> Int -- | Check whether this shape is small enough so that its flat indices an -- be represented as Int. If this returns False then your -- array is too big. Mostly used for writing QuickCheck tests. sizeIsValid :: Shape sh => sh -> Bool -- | Convert an index into its equivalent flat, linear, row-major version. toIndex :: Shape sh => sh -> sh -> Int -- | Inverse of toIndex. fromIndex :: Shape sh => sh -> Int -> sh -- | Check whether an index is within a given shape. inShapeRange :: Shape sh => sh -> sh -> sh -> Bool -- | Convert a shape into its list of dimensions. listOfShape :: Shape sh => sh -> [Int] -- | Convert a list of dimensions to a shape shapeOfList :: Shape sh => [Int] -> sh -- | Ensure that a shape is completely evaluated. deepSeq :: Shape sh => sh -> a -> a -- | Check whether an index is a part of a given shape. inShape :: Shape sh => sh -> sh -> Bool -- | Nicely format a shape as a string showShape :: Shape sh => sh -> String module Data.Array.Repa.Repr.HintSmall -- | Hints that evaluating this array is only a small amount of work. It -- will be evaluated sequentially in the main thread, instead of in -- parallel on the gang. This avoids the associated scheduling overhead. data S r1 -- | Wrap an array with a smallness hint. hintSmall :: Array r1 sh e -> Array (S r1) sh e instance GHC.Show.Show (Data.Array.Repa.Base.Array r1 sh e) => GHC.Show.Show (Data.Array.Repa.Base.Array (Data.Array.Repa.Repr.HintSmall.S r1) sh e) instance GHC.Read.Read (Data.Array.Repa.Base.Array r1 sh e) => GHC.Read.Read (Data.Array.Repa.Base.Array (Data.Array.Repa.Repr.HintSmall.S r1) sh e) instance Data.Array.Repa.Base.Source r1 a => Data.Array.Repa.Base.Source (Data.Array.Repa.Repr.HintSmall.S r1) a instance (Data.Array.Repa.Shape.Shape sh, Data.Array.Repa.Eval.Load.Load r1 sh e) => Data.Array.Repa.Eval.Load.Load (Data.Array.Repa.Repr.HintSmall.S r1) sh e instance (Data.Array.Repa.Shape.Shape sh, Data.Array.Repa.Eval.Load.LoadRange r1 sh e) => Data.Array.Repa.Eval.Load.LoadRange (Data.Array.Repa.Repr.HintSmall.S r1) sh e -- | Index types. module Data.Array.Repa.Index -- | An index of dimension zero data Z Z :: Z -- | Our index type, used for both shapes and indices. data (:.) tail head (:.) :: !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 -- | Helper for index construction. -- -- Use this instead of explicit constructors like (Z :. (x :: -- Int)). The this is sometimes needed to ensure that x is -- constrained to be in Int. ix1 :: Int -> DIM1 ix2 :: Int -> Int -> DIM2 ix3 :: Int -> Int -> Int -> DIM3 ix4 :: Int -> Int -> Int -> Int -> DIM4 ix5 :: Int -> Int -> Int -> Int -> Int -> DIM5 instance (GHC.Classes.Ord tail, GHC.Classes.Ord head) => GHC.Classes.Ord (tail Data.Array.Repa.Index.:. head) instance (GHC.Classes.Eq tail, GHC.Classes.Eq head) => GHC.Classes.Eq (tail Data.Array.Repa.Index.:. head) instance (GHC.Read.Read tail, GHC.Read.Read head) => GHC.Read.Read (tail Data.Array.Repa.Index.:. head) instance (GHC.Show.Show tail, GHC.Show.Show head) => GHC.Show.Show (tail Data.Array.Repa.Index.:. head) instance GHC.Classes.Ord Data.Array.Repa.Index.Z instance GHC.Classes.Eq Data.Array.Repa.Index.Z instance GHC.Read.Read Data.Array.Repa.Index.Z instance GHC.Show.Show Data.Array.Repa.Index.Z instance Data.Array.Repa.Shape.Shape Data.Array.Repa.Index.Z instance Data.Array.Repa.Shape.Shape sh => Data.Array.Repa.Shape.Shape (sh Data.Array.Repa.Index.:. GHC.Types.Int) -- | Index space transformation between arrays and slices. module Data.Array.Repa.Slice -- | Select all indices at a certain position. data All All :: All -- | Place holder for any possible shape. data Any sh Any :: Any sh -- | Map a type of the index in the full shape, to the type of the index in -- the slice. -- | Map the type of an index in the slice, to the type of the index in the -- full shape. -- | Class of index types that can map to slices. class Slice ss -- | Map an index of a full shape onto an index of some slice. sliceOfFull :: Slice ss => ss -> FullShape ss -> SliceShape ss -- | Map an index of a slice onto an index of the full shape. fullOfSlice :: Slice ss => ss -> SliceShape ss -> FullShape ss instance Data.Array.Repa.Slice.Slice Data.Array.Repa.Index.Z instance Data.Array.Repa.Slice.Slice (Data.Array.Repa.Slice.Any sh) instance Data.Array.Repa.Slice.Slice sl => Data.Array.Repa.Slice.Slice (sl Data.Array.Repa.Index.:. GHC.Types.Int) instance Data.Array.Repa.Slice.Slice sl => Data.Array.Repa.Slice.Slice (sl Data.Array.Repa.Index.:. Data.Array.Repa.Slice.All) -- | Gang Primitives. module Data.Array.Repa.Eval.Gang -- | This globally shared gang is auto-initialised at startup and shared by -- all Repa computations. -- -- In a data parallel setting, it does not help to have multiple gangs -- running at the same time. This is because a single data parallel -- computation should already be able to keep all threads busy. If we had -- multiple gangs running at the same time, then the system as a whole -- would run slower as the gangs would contend for cache and thrash the -- scheduler. -- -- If, due to laziness or otherwise, you try to start multiple parallel -- Repa computations at the same time, then you will get the following -- warning on stderr at runtime: -- --
--   Data.Array.Repa: Performing nested parallel computation sequentially.
--       You've probably called the compute or copy function while another
--       instance was already running. This can happen if the second version
--       was suspended due to lazy evaluation. Use deepSeqArray to ensure that
--       each array is fully evaluated before you compute the next one.
--   
theGang :: Gang -- | A Gang is a group of threads that execute arbitrary work -- requests. data Gang -- | Fork a Gang with the given number of threads (at least 1). forkGang :: Int -> IO Gang -- | O(1). Yield the number of threads in the Gang. gangSize :: Gang -> Int -- | Issue work requests for the Gang and wait until they complete. -- -- If the gang is already busy then print a warning to stderr and -- just run the actions sequentially in the requesting thread. gangIO :: Gang -> (Int -> IO ()) -> IO () -- | Same as gangIO but in the ST monad. gangST :: Gang -> (Int -> ST s ()) -> ST s () instance GHC.Show.Show Data.Array.Repa.Eval.Gang.Gang module Data.Array.Repa.Repr.Delayed -- | Delayed arrays are represented as functions from the index to element -- value. -- -- Every time you index into a delayed array the element at that position -- is recomputed. data D -- | O(1). Wrap a function as a delayed array. fromFunction :: sh -> (sh -> a) -> Array D sh a -- | O(1). Produce the extent of an array, and a function to retrieve an -- arbitrary element. toFunction :: (Shape sh, Source r1 a) => Array r1 sh a -> (sh, sh -> a) -- | O(1). Delay an array. This wraps the internal representation to be a -- function from indices to elements, so consumers don't need to worry -- about what the previous representation was. delay :: Shape sh => Source r e => Array r sh e -> Array D sh e instance Data.Array.Repa.Base.Source Data.Array.Repa.Repr.Delayed.D a instance Data.Array.Repa.Shape.Shape sh => Data.Array.Repa.Eval.Load.Load Data.Array.Repa.Repr.Delayed.D sh e instance Data.Array.Repa.Eval.Elt.Elt e => Data.Array.Repa.Eval.Load.LoadRange Data.Array.Repa.Repr.Delayed.D Data.Array.Repa.Index.DIM2 e module Data.Array.Repa.Operators.Traversal -- | Unstructured traversal. traverse :: (Source r a, Shape sh, Shape sh') => Array r sh a -> (sh -> sh') -> ((sh -> a) -> sh' -> b) -> Array D sh' b -- | Unstructured traversal. unsafeTraverse :: (Source r a, Shape sh, Shape sh') => Array r sh a -> (sh -> sh') -> ((sh -> a) -> sh' -> b) -> Array D sh' b -- | Unstructured traversal over two arrays at once. traverse2 :: (Source r1 a, Source r2 b, Shape sh, Shape sh', Shape sh'') => Array r1 sh a -> Array r2 sh' b -> (sh -> sh' -> sh'') -> ((sh -> a) -> (sh' -> b) -> (sh'' -> c)) -> Array D sh'' c -- | Unstructured traversal over two arrays at once. unsafeTraverse2 :: (Source r1 a, Source r2 b, Shape sh, Shape sh', Shape sh'') => Array r1 sh a -> Array r2 sh' b -> (sh -> sh' -> sh'') -> ((sh -> a) -> (sh' -> b) -> (sh'' -> c)) -> Array D sh'' c -- | Unstructured traversal over three arrays at once. traverse3 :: (Source r1 a, Source r2 b, Source r3 c, Shape sh1, Shape sh2, Shape sh3, Shape sh4) => Array r1 sh1 a -> Array r2 sh2 b -> Array r3 sh3 c -> (sh1 -> sh2 -> sh3 -> sh4) -> ((sh1 -> a) -> (sh2 -> b) -> (sh3 -> c) -> sh4 -> d) -> Array D sh4 d -- | Unstructured traversal over three arrays at once. unsafeTraverse3 :: (Source r1 a, Source r2 b, Source r3 c, Shape sh1, Shape sh2, Shape sh3, Shape sh4) => Array r1 sh1 a -> Array r2 sh2 b -> Array r3 sh3 c -> (sh1 -> sh2 -> sh3 -> sh4) -> ((sh1 -> a) -> (sh2 -> b) -> (sh3 -> c) -> sh4 -> d) -> Array D sh4 d -- | Unstructured traversal over four arrays at once. traverse4 :: (Source r1 a, Source r2 b, Source r3 c, Source r4 d, Shape sh1, Shape sh2, Shape sh3, Shape sh4, Shape sh5) => Array r1 sh1 a -> Array r2 sh2 b -> Array r3 sh3 c -> Array r4 sh4 d -> (sh1 -> sh2 -> sh3 -> sh4 -> sh5) -> ((sh1 -> a) -> (sh2 -> b) -> (sh3 -> c) -> (sh4 -> d) -> sh5 -> e) -> Array D sh5 e -- | Unstructured traversal over four arrays at once. unsafeTraverse4 :: (Source r1 a, Source r2 b, Source r3 c, Source r4 d, Shape sh1, Shape sh2, Shape sh3, Shape sh4, Shape sh5) => Array r1 sh1 a -> Array r2 sh2 b -> Array r3 sh3 c -> Array r4 sh4 d -> (sh1 -> sh2 -> sh3 -> sh4 -> sh5) -> ((sh1 -> a) -> (sh2 -> b) -> (sh3 -> c) -> (sh4 -> d) -> sh5 -> e) -> Array D sh5 e module Data.Array.Repa.Operators.IndexSpace -- | Impose a new shape on the elements of an array. The new extent must be -- the same size as the original, else error. reshape :: (Shape sh1, Shape sh2, Source r1 e) => sh2 -> Array r1 sh1 e -> Array D sh2 e -- | Append two arrays. append :: (Shape sh, Source r1 e, Source r2 e) => Array r1 (sh :. Int) e -> Array r2 (sh :. Int) e -> Array D (sh :. Int) e -- | Append two arrays. (++) :: (Shape sh, Source r1 e, Source r2 e) => Array r1 (sh :. Int) e -> Array r2 (sh :. Int) e -> Array D (sh :. Int) e -- | Transpose the lowest two dimensions of an array. Transposing an array -- twice yields the original. transpose :: (Shape sh, Source r e) => Array r ((sh :. Int) :. Int) e -> Array D ((sh :. Int) :. Int) e -- | Extract a sub-range of elements from an array. extract :: (Shape sh, Source r e) => sh -> sh -> Array r sh e -> Array D sh e -- | Backwards permutation of an array's elements. backpermute :: (Shape sh1, Shape sh2, Source r e) => sh2 -> (sh2 -> sh1) -> Array r sh1 e -> Array D sh2 e -- | Backwards permutation of an array's elements. unsafeBackpermute :: (Shape sh1, Shape sh2, Source r e) => sh2 -> (sh2 -> sh1) -> Array r sh1 e -> Array D sh2 e -- | Default backwards permutation of an array's elements. If the function -- returns Nothing then the value at that index is taken from the -- default array (arrDft) backpermuteDft :: (Shape sh1, Shape sh2, Source r1 e, Source r2 e) => Array r2 sh2 e -> (sh2 -> Maybe sh1) -> Array r1 sh1 e -> Array D sh2 e -- | Default backwards permutation of an array's elements. If the function -- returns Nothing then the value at that index is taken from the -- default array (arrDft) unsafeBackpermuteDft :: (Shape sh1, Shape sh2, Source r1 e, Source r2 e) => Array r2 sh2 e -> (sh2 -> Maybe sh1) -> Array r1 sh1 e -> Array D sh2 e -- | Extend an array, according to a given slice specification. -- -- For example, to replicate the rows of an array use the following: -- --
--   extend arr (Any :. (5::Int) :. All)
--   
extend :: (Slice sl, Shape (SliceShape sl), Shape (FullShape sl), Source r e) => sl -> Array r (SliceShape sl) e -> Array D (FullShape sl) e -- | Extend an array, according to a given slice specification. -- -- For example, to replicate the rows of an array use the following: -- --
--   extend arr (Any :. (5::Int) :. All)
--   
unsafeExtend :: (Slice sl, Shape (SliceShape sl), Shape (FullShape sl), Source r e) => sl -> Array r (SliceShape sl) e -> Array D (FullShape sl) e -- | Take a slice from an array, according to a given specification. -- -- For example, to take a row from a matrix use the following: -- --
--   slice arr (Any :. (5::Int) :. All)
--   
-- -- To take a column use: -- --
--   slice arr (Any :. (5::Int))
--   
slice :: (Slice sl, Shape (FullShape sl), Shape (SliceShape sl), Source r e) => Array r (FullShape sl) e -> sl -> Array D (SliceShape sl) e -- | Take a slice from an array, according to a given specification. -- -- For example, to take a row from a matrix use the following: -- --
--   slice arr (Any :. (5::Int) :. All)
--   
-- -- To take a column use: -- --
--   slice arr (Any :. (5::Int))
--   
unsafeSlice :: (Slice sl, Shape (FullShape sl), Shape (SliceShape sl), Source r e) => Array r (FullShape sl) e -> sl -> Array D (SliceShape sl) e -- | Functions without sanity or bounds checks. module Data.Array.Repa.Unsafe -- | Backwards permutation of an array's elements. unsafeBackpermute :: (Shape sh1, Shape sh2, Source r e) => sh2 -> (sh2 -> sh1) -> Array r sh1 e -> Array D sh2 e -- | Default backwards permutation of an array's elements. If the function -- returns Nothing then the value at that index is taken from the -- default array (arrDft) unsafeBackpermuteDft :: (Shape sh1, Shape sh2, Source r1 e, Source r2 e) => Array r2 sh2 e -> (sh2 -> Maybe sh1) -> Array r1 sh1 e -> Array D sh2 e -- | Take a slice from an array, according to a given specification. -- -- For example, to take a row from a matrix use the following: -- --
--   slice arr (Any :. (5::Int) :. All)
--   
-- -- To take a column use: -- --
--   slice arr (Any :. (5::Int))
--   
unsafeSlice :: (Slice sl, Shape (FullShape sl), Shape (SliceShape sl), Source r e) => Array r (FullShape sl) e -> sl -> Array D (SliceShape sl) e -- | Extend an array, according to a given slice specification. -- -- For example, to replicate the rows of an array use the following: -- --
--   extend arr (Any :. (5::Int) :. All)
--   
unsafeExtend :: (Slice sl, Shape (SliceShape sl), Shape (FullShape sl), Source r e) => sl -> Array r (SliceShape sl) e -> Array D (FullShape sl) e -- | Unstructured traversal. unsafeTraverse :: (Source r a, Shape sh, Shape sh') => Array r sh a -> (sh -> sh') -> ((sh -> a) -> sh' -> b) -> Array D sh' b -- | Unstructured traversal over two arrays at once. unsafeTraverse2 :: (Source r1 a, Source r2 b, Shape sh, Shape sh', Shape sh'') => Array r1 sh a -> Array r2 sh' b -> (sh -> sh' -> sh'') -> ((sh -> a) -> (sh' -> b) -> (sh'' -> c)) -> Array D sh'' c -- | Unstructured traversal over three arrays at once. unsafeTraverse3 :: (Source r1 a, Source r2 b, Source r3 c, Shape sh1, Shape sh2, Shape sh3, Shape sh4) => Array r1 sh1 a -> Array r2 sh2 b -> Array r3 sh3 c -> (sh1 -> sh2 -> sh3 -> sh4) -> ((sh1 -> a) -> (sh2 -> b) -> (sh3 -> c) -> sh4 -> d) -> Array D sh4 d -- | Unstructured traversal over four arrays at once. unsafeTraverse4 :: (Source r1 a, Source r2 b, Source r3 c, Source r4 d, Shape sh1, Shape sh2, Shape sh3, Shape sh4, Shape sh5) => Array r1 sh1 a -> Array r2 sh2 b -> Array r3 sh3 c -> Array r4 sh4 d -> (sh1 -> sh2 -> sh3 -> sh4 -> sh5) -> ((sh1 -> a) -> (sh2 -> b) -> (sh3 -> c) -> (sh4 -> d) -> sh5 -> e) -> Array D sh5 e module Data.Array.Repa.Operators.Interleave -- | Interleave the elements of two arrays. All the input arrays must have -- the same extent, else error. The lowest dimension of the result -- array is twice the size of the inputs. -- --
--   interleave2 a1 a2   b1 b2  =>  a1 b1 a2 b2
--               a3 a4   b3 b4      a3 b3 a4 b4
--   
interleave2 :: (Shape sh, Source r1 a, Source r2 a) => Array r1 (sh :. Int) a -> Array r2 (sh :. Int) a -> Array D (sh :. Int) a -- | Interleave the elements of three arrays. interleave3 :: (Shape sh, Source r1 a, Source r2 a, Source r3 a) => Array r1 (sh :. Int) a -> Array r2 (sh :. Int) a -> Array r3 (sh :. Int) a -> Array D (sh :. Int) a -- | Interleave the elements of four arrays. interleave4 :: (Shape sh, Source r1 a, Source r2 a, Source r3 a, Source r4 a) => Array r1 (sh :. Int) a -> Array r2 (sh :. Int) a -> Array r3 (sh :. Int) a -> Array r4 (sh :. Int) a -> Array D (sh :. Int) a module Data.Array.Repa.Repr.ByteString -- | Strict ByteStrings arrays are represented as ForeignPtr buffers of -- Word8 data B -- | O(1). Wrap a ByteString as an array. fromByteString :: Shape sh => sh -> ByteString -> Array B sh Word8 -- | O(1). Unpack a ByteString from an array. toByteString :: Array B sh Word8 -> ByteString instance GHC.Show.Show sh => GHC.Show.Show (Data.Array.Repa.Base.Array Data.Array.Repa.Repr.ByteString.B sh GHC.Word.Word8) instance GHC.Read.Read sh => GHC.Read.Read (Data.Array.Repa.Base.Array Data.Array.Repa.Repr.ByteString.B sh GHC.Word.Word8) instance Data.Array.Repa.Base.Source Data.Array.Repa.Repr.ByteString.B GHC.Word.Word8 module Data.Array.Repa.Repr.ForeignPtr -- | Arrays represented as foreign buffers in the C heap. data F -- | O(1). Wrap a ForeignPtr as an array. fromForeignPtr :: Shape sh => sh -> ForeignPtr e -> Array F sh e -- | O(1). Unpack a ForeignPtr from an array. toForeignPtr :: Array F sh e -> ForeignPtr e -- | Compute an array sequentially and write the elements into a foreign -- buffer without intermediate copying. If you want to copy a -- pre-existing manifest array to a foreign buffer then delay it -- first. computeIntoS :: (Load r1 sh e, Storable e) => ForeignPtr e -> Array r1 sh e -> IO () -- | Compute an array in parallel and write the elements into a foreign -- buffer without intermediate copying. If you want to copy a -- pre-existing manifest array to a foreign buffer then delay it -- first. computeIntoP :: (Load r1 sh e, Storable e) => ForeignPtr e -> Array r1 sh e -> IO () instance Foreign.Storable.Storable a => Data.Array.Repa.Base.Source Data.Array.Repa.Repr.ForeignPtr.F a instance Foreign.Storable.Storable e => Data.Array.Repa.Eval.Target.Target Data.Array.Repa.Repr.ForeignPtr.F e module Data.Array.Repa.Repr.HintInterleave -- | Hints that computing this array will be an unbalanced workload and -- evaluation should be interleaved between the processors. data I r1 -- | Wrap an array with a unbalanced-ness hint. hintInterleave :: Array r1 sh e -> Array (I r1) sh e instance GHC.Show.Show (Data.Array.Repa.Base.Array r1 sh e) => GHC.Show.Show (Data.Array.Repa.Base.Array (Data.Array.Repa.Repr.HintInterleave.I r1) sh e) instance GHC.Read.Read (Data.Array.Repa.Base.Array r1 sh e) => GHC.Read.Read (Data.Array.Repa.Base.Array (Data.Array.Repa.Repr.HintInterleave.I r1) sh e) instance Data.Array.Repa.Base.Source r1 a => Data.Array.Repa.Base.Source (Data.Array.Repa.Repr.HintInterleave.I r1) a instance (Data.Array.Repa.Shape.Shape sh, Data.Array.Repa.Eval.Load.Load Data.Array.Repa.Repr.Delayed.D sh e) => Data.Array.Repa.Eval.Load.Load (Data.Array.Repa.Repr.HintInterleave.I Data.Array.Repa.Repr.Delayed.D) sh e -- | Low level interface to parallel array filling operators. module Data.Array.Repa.Eval -- | Element types that can be used with the blockwise filling functions. -- -- This class is mainly used to define the touch method. This is -- used internally in the imeplementation of Repa to prevent let-binding -- from being floated inappropriately by the GHC simplifier. Doing a -- seq sometimes isn't enough, because the GHC simplifier can -- erase these, and still move around the bindings. class Elt a where touch = gtouch . from zero = to gzero one = to gone -- | Place a demand on a value at a particular point in an IO computation. touch :: Elt a => a -> IO () -- | Generic zero value, helpful for debugging. zero :: Elt a => a -- | Generic one value, helpful for debugging. one :: Elt a => a -- | Class of manifest array representations that can be constructed in -- parallel. class Target r e where data family MVec r e -- | Allocate a new mutable array of the given size. newMVec :: Target r e => Int -> IO (MVec r e) -- | Write an element into the mutable array. unsafeWriteMVec :: Target r e => MVec r e -> Int -> e -> IO () -- | Freeze the mutable array into an immutable Repa array. unsafeFreezeMVec :: Target r e => sh -> MVec r e -> IO (Array r sh e) -- | Ensure the strucure of a mutable array is fully evaluated. deepSeqMVec :: Target r e => MVec r e -> a -> a -- | Ensure the array is still live at this point. Needed when the mutable -- array is a ForeignPtr with a finalizer. touchMVec :: Target r e => MVec r e -> IO () -- | Compute all elements defined by an array and write them to a manifest -- target representation. -- -- Note that instances require that the source array to have a delayed -- representation such as D or C. If you want to use a -- pre-existing manifest array as the source then delay it -- first. class (Source r1 e, Shape sh) => Load r1 sh e -- | Fill an entire array sequentially. loadS :: (Load r1 sh e, Target r2 e) => Array r1 sh e -> MVec r2 e -> IO () -- | Fill an entire array in parallel. loadP :: (Load r1 sh e, Target r2 e) => Array r1 sh e -> MVec r2 e -> IO () -- | Compute a range of elements defined by an array and write them to a -- fillable representation. class (Source r1 e, Shape sh) => LoadRange r1 sh e -- | Fill a range of an array sequentially. loadRangeS :: (LoadRange r1 sh e, Target r2 e) => Array r1 sh e -> MVec r2 e -> sh -> sh -> IO () -- | Fill a range of an array in parallel. loadRangeP :: (LoadRange r1 sh e, Target r2 e) => Array r1 sh e -> MVec r2 e -> sh -> sh -> IO () -- | O(n). Construct a manifest array from a list. fromList :: (Shape sh, Target r e) => sh -> [e] -> Array r sh e -- | Sequential computation of array elements. computeS :: (Load r1 sh e, Target r2 e) => Array r1 sh e -> Array r2 sh e -- | Parallel computation of array elements. -- -- computeP :: (Load r1 sh e, Target r2 e, Source r2 e, Monad m) => Array r1 sh e -> m (Array r2 sh e) -- | Suspended parallel computation of array elements. -- -- This version creates a thunk that will evaluate the array on demand. -- If you force it when another parallel computation is already running -- then you will get a runtime warning and evaluation will be sequential. -- Use deepSeqArray and now to ensure that each array is -- evaluated before proceeding to the next one. -- -- If unsure then just use the monadic version computeP. This one -- ensures that each array is fully evaluated before continuing. suspendedComputeP :: (Load r1 sh e, Target r2 e) => Array r1 sh e -> Array r2 sh e -- | Sequential copying of arrays. copyS :: (Source r1 e, Load D sh e, Target r2 e) => Array r1 sh e -> Array r2 sh e -- | Parallel copying of arrays. -- -- copyP :: (Source r1 e, Source r2 e, Load D sh e, Target r2 e, Monad m) => Array r1 sh e -> m (Array r2 sh e) -- | Suspended parallel copy of array elements. suspendedCopyP :: (Source r1 e, Load D sh e, Target r2 e) => Array r1 sh e -> Array r2 sh e -- | Monadic version of deepSeqArray. -- -- Forces an suspended array computation to be completed at this point in -- a monadic computation. -- --
--   do  let arr2 = suspendedComputeP arr1
--       ...
--       arr3 <- now $ arr2
--       ...
--   
now :: (Shape sh, Source r e, Monad m) => Array r sh e -> m (Array r sh e) -- | Fill something sequentially. -- -- fillLinearS :: Int -> (Int -> a -> IO ()) -> (Int -> a) -> IO () -- | Fill something in parallel. -- -- fillChunkedP :: Int -> (Int -> a -> IO ()) -> (Int -> a) -> IO () -- | Fill something in parallel, using a separate IO action for each -- thread. -- -- fillChunkedIOP :: Int -> (Int -> a -> IO ()) -> (Int -> IO (Int -> IO a)) -> IO () -- | Fill something in parallel. -- -- fillInterleavedP :: Int -> (Int -> a -> IO ()) -> (Int -> a) -> IO () -- | Fill a block in a rank-2 array in parallel. -- -- fillBlock2P :: Elt a => (Int -> a -> IO ()) -> (DIM2 -> a) -> Int# -> Int# -> Int# -> Int# -> Int# -> IO () -- | Fill a block in a rank-2 array, sequentially. -- -- fillBlock2S :: (Int -> a -> IO ()) -> (DIM2 -> a) -> Int# -> Int# -> Int# -> Int# -> Int# -> IO () -- | Fill a block in a rank-2 array, sequentially. -- -- fillCursoredBlock2S :: Elt a => (Int -> a -> IO ()) -> (DIM2 -> cursor) -> (DIM2 -> cursor -> cursor) -> (cursor -> a) -> Int# -> Int# -> Int# -> Int# -> Int# -> IO () -- | Fill a block in a rank-2 array in parallel. -- -- fillCursoredBlock2P :: Elt a => (Int -> a -> IO ()) -> (DIM2 -> cursor) -> (DIM2 -> cursor -> cursor) -> (cursor -> a) -> Int# -> Int# -> Int# -> Int# -> Int# -> IO () -- | Select indices matching a predicate. -- -- selectChunkedS :: Shape sh => (sh -> a -> IO ()) -> (sh -> Bool) -> (sh -> a) -> sh -> IO Int -- | Select indices matching a predicate, in parallel. -- -- selectChunkedP :: Unbox a => (Int -> Bool) -> (Int -> a) -> Int -> IO [IOVector a] module Data.Array.Repa.Repr.Partitioned -- | Partitioned arrays. The last partition takes priority -- -- These are produced by Repa's support functions and allow arrays to be -- defined using a different element function for each partition. -- -- The basic idea is described in ``Efficient Parallel Stencil -- Convolution'', Ben Lippmeier and Gabriele Keller, Haskell 2011 -- -- though the underlying array representation has changed since this -- paper was published. data P r1 r2 data Range sh Range :: !sh -> !sh -> (sh -> Bool) -> Range sh -- | Check whether an index is within the given range. inRange :: Range sh -> sh -> Bool instance (Data.Array.Repa.Base.Source r1 e, Data.Array.Repa.Base.Source r2 e) => Data.Array.Repa.Base.Source (Data.Array.Repa.Repr.Partitioned.P r1 r2) e instance (Data.Array.Repa.Eval.Load.LoadRange r1 sh e, Data.Array.Repa.Eval.Load.Load r2 sh e) => Data.Array.Repa.Eval.Load.Load (Data.Array.Repa.Repr.Partitioned.P r1 r2) sh e module Data.Array.Repa.Repr.Unboxed -- | Unboxed arrays are represented as unboxed vectors. -- -- The implementation uses Data.Vector.Unboxed which is based on -- type families and picks an efficient, specialised representation for -- every element type. In particular, unboxed vectors of pairs are -- represented as pairs of unboxed vectors. This is the most efficient -- representation for numerical data. data U class (Vector Vector a, MVector MVector a) => Unbox a -- | Sequential computation of array elements.. -- -- computeUnboxedS :: (Shape sh, Load r1 sh e, Unbox e) => Array r1 sh e -> Array U sh e -- | Parallel computation of array elements. -- -- computeUnboxedP :: (Shape sh, Load r1 sh e, Monad m, Unbox e) => Array r1 sh e -> m (Array U sh e) -- | O(n). Convert a list to an unboxed vector array. -- -- fromListUnboxed :: (Shape sh, Unbox a) => sh -> [a] -> Array U sh a -- | O(1). Wrap an unboxed vector as an array. fromUnboxed :: (Shape sh, Unbox e) => sh -> Vector e -> Array U sh e -- | O(1). Unpack an unboxed vector from an array. toUnboxed :: Unbox e => Array U sh e -> Vector e -- | O(1). Zip some unboxed arrays. The shapes must be identical else -- error. zip :: (Shape sh, Unbox a, Unbox b) => Array U sh a -> Array U sh b -> Array U sh (a, b) -- | O(1). Zip some unboxed arrays. The shapes must be identical else -- error. zip3 :: (Shape sh, Unbox a, Unbox b, Unbox c) => Array U sh a -> Array U sh b -> Array U sh c -> Array U sh (a, b, c) -- | O(1). Zip some unboxed arrays. The shapes must be identical else -- error. zip4 :: (Shape sh, Unbox a, Unbox b, Unbox c, Unbox d) => Array U sh a -> Array U sh b -> Array U sh c -> Array U sh d -> Array U sh (a, b, c, d) -- | O(1). Zip some unboxed arrays. The shapes must be identical else -- error. zip5 :: (Shape sh, Unbox a, Unbox b, Unbox c, Unbox d, Unbox e) => Array U sh a -> Array U sh b -> Array U sh c -> Array U sh d -> Array U sh e -> Array U sh (a, b, c, d, e) -- | O(1). Zip some unboxed arrays. The shapes must be identical else -- error. zip6 :: (Shape sh, Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f) => Array U sh a -> Array U sh b -> Array U sh c -> Array U sh d -> Array U sh e -> Array U sh f -> Array U sh (a, b, c, d, e, f) -- | O(1). Unzip an unboxed array. unzip :: (Unbox a, Unbox b) => Array U sh (a, b) -> (Array U sh a, Array U sh b) -- | O(1). Unzip an unboxed array. unzip3 :: (Unbox a, Unbox b, Unbox c) => Array U sh (a, b, c) -> (Array U sh a, Array U sh b, Array U sh c) -- | O(1). Unzip an unboxed array. unzip4 :: (Unbox a, Unbox b, Unbox c, Unbox d) => Array U sh (a, b, c, d) -> (Array U sh a, Array U sh b, Array U sh c, Array U sh d) -- | O(1). Unzip an unboxed array. unzip5 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e) => Array U sh (a, b, c, d, e) -> (Array U sh a, Array U sh b, Array U sh c, Array U sh d, Array U sh e) -- | O(1). Unzip an unboxed array. unzip6 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f) => Array U sh (a, b, c, d, e, f) -> (Array U sh a, Array U sh b, Array U sh c, Array U sh d, Array U sh e, Array U sh f) instance (GHC.Show.Show sh, GHC.Show.Show e, Data.Vector.Unboxed.Base.Unbox e) => GHC.Show.Show (Data.Array.Repa.Base.Array Data.Array.Repa.Repr.Unboxed.U sh e) instance (GHC.Read.Read sh, GHC.Read.Read e, Data.Vector.Unboxed.Base.Unbox e) => GHC.Read.Read (Data.Array.Repa.Base.Array Data.Array.Repa.Repr.Unboxed.U sh e) instance Data.Vector.Unboxed.Base.Unbox a => Data.Array.Repa.Base.Source Data.Array.Repa.Repr.Unboxed.U a instance Data.Vector.Unboxed.Base.Unbox e => Data.Array.Repa.Eval.Target.Target Data.Array.Repa.Repr.Unboxed.U e module Data.Array.Repa.Operators.Selection -- | Produce an array by applying a predicate to a range of integers. If -- the predicate matches, then use the second function to generate the -- element. -- -- selectP :: (Unbox a, Monad m) => (Int -> Bool) -> (Int -> a) -> Int -> m (Array U DIM1 a) module Data.Array.Repa.Repr.Undefined -- | An array with undefined elements. -- -- data X instance GHC.Show.Show sh => GHC.Show.Show (Data.Array.Repa.Base.Array Data.Array.Repa.Repr.Undefined.X sh e) instance GHC.Read.Read sh => GHC.Read.Read (Data.Array.Repa.Base.Array Data.Array.Repa.Repr.Undefined.X sh e) instance Data.Array.Repa.Base.Source Data.Array.Repa.Repr.Undefined.X e instance (Data.Array.Repa.Shape.Shape sh, GHC.Num.Num e) => Data.Array.Repa.Eval.Load.Load Data.Array.Repa.Repr.Undefined.X sh e module Data.Array.Repa.Repr.Cursored -- | Cursored Arrays. These are produced by Repa's stencil functions, and -- help the fusion framework to share index compuations between array -- elements. -- -- The basic idea is described in ``Efficient Parallel Stencil -- Convolution'', Ben Lippmeier and Gabriele Keller, Haskell 2011 -- -- though the underlying array representation has changed since this -- paper was published. data C -- | Define a new cursored array. makeCursored :: sh -> (sh -> cursor) -> (sh -> cursor -> cursor) -> (cursor -> e) -> Array C sh e instance Data.Array.Repa.Base.Source Data.Array.Repa.Repr.Cursored.C a instance Data.Array.Repa.Eval.Elt.Elt e => Data.Array.Repa.Eval.Load.Load Data.Array.Repa.Repr.Cursored.C Data.Array.Repa.Index.DIM2 e instance Data.Array.Repa.Eval.Elt.Elt e => Data.Array.Repa.Eval.Load.LoadRange Data.Array.Repa.Repr.Cursored.C Data.Array.Repa.Index.DIM2 e module Data.Array.Repa.Operators.Mapping -- | Apply a worker function to each element of an array, yielding a new -- array with the same extent. map :: (Shape sh, Source r a) => (a -> b) -> Array r sh a -> Array D sh b -- | Combine two arrays, element-wise, with a binary operator. If the -- extent of the two array arguments differ, then the resulting array's -- extent is their intersection. zipWith :: (Shape sh, Source r1 a, Source r2 b) => (a -> b -> c) -> Array r1 sh a -> Array r2 sh b -> Array D sh c (+^) :: (Num c, Shape sh, Source r1 c, Source r2 c) => Array r1 sh c -> Array r2 sh c -> Array D sh c (-^) :: (Num c, Shape sh, Source r1 c, Source r2 c) => Array r1 sh c -> Array r2 sh c -> Array D sh c (*^) :: (Num c, Shape sh, Source r1 c, Source r2 c) => Array r1 sh c -> Array r2 sh c -> Array D sh c (/^) :: (Fractional c, Shape sh, Source r1 c, Source r2 c) => Array r1 sh c -> Array r2 sh c -> Array D sh c -- | Structured versions of map and zipWith that preserve -- the representation of cursored and partitioned arrays. -- -- For cursored (C) arrays, the cursoring of the source array is -- preserved. -- -- For partitioned (P) arrays, the worker function is fused with -- each array partition separately, instead of treating the whole array -- as a single bulk object. -- -- Preserving the cursored and/or paritioned representation of an array -- is will make follow-on computation more efficient than if the array -- was converted to a vanilla Delayed (D) array as with plain -- map and zipWith. -- -- If the source array is not cursored or partitioned then smap -- and szipWith are identical to the plain functions. class Structured r1 a b where type family TR r1 -- | Structured map. smap :: (Structured r1 a b, Shape sh) => (a -> b) -> Array r1 sh a -> Array (TR r1) sh b -- | Structured zipWith. If you have a cursored or partitioned -- source array then use that as the third argument (corresponding to -- r1 here) szipWith :: (Structured r1 a b, Shape sh, Source r c) => (c -> a -> b) -> Array r sh c -> Array r1 sh a -> Array (TR r1) sh b instance Data.Array.Repa.Operators.Mapping.Structured Data.Array.Repa.Repr.ByteString.B GHC.Word.Word8 b instance Data.Array.Repa.Operators.Mapping.Structured Data.Array.Repa.Repr.Cursored.C a b instance Data.Array.Repa.Operators.Mapping.Structured Data.Array.Repa.Repr.Delayed.D a b instance Foreign.Storable.Storable a => Data.Array.Repa.Operators.Mapping.Structured Data.Array.Repa.Repr.ForeignPtr.F a b instance (Data.Array.Repa.Operators.Mapping.Structured r1 a b, Data.Array.Repa.Operators.Mapping.Structured r2 a b) => Data.Array.Repa.Operators.Mapping.Structured (Data.Array.Repa.Repr.Partitioned.P r1 r2) a b instance Data.Array.Repa.Operators.Mapping.Structured r1 a b => Data.Array.Repa.Operators.Mapping.Structured (Data.Array.Repa.Repr.HintSmall.S r1) a b instance Data.Array.Repa.Operators.Mapping.Structured r1 a b => Data.Array.Repa.Operators.Mapping.Structured (Data.Array.Repa.Repr.HintInterleave.I r1) a b instance Data.Vector.Unboxed.Base.Unbox a => Data.Array.Repa.Operators.Mapping.Structured Data.Array.Repa.Repr.Unboxed.U a b instance Data.Array.Repa.Operators.Mapping.Structured Data.Array.Repa.Repr.Undefined.X a b -- | Functions specialised for arrays of dimension 2. module Data.Array.Repa.Specialised.Dim2 -- | Check if an index lies inside the given extent. As opposed to -- inRange from Data.Array.Repa.Index, this is a -- short-circuited test that checks that lowest dimension first. isInside2 :: DIM2 -> DIM2 -> Bool -- | Check if an index lies outside the given extent. As opposed to -- inRange from Data.Array.Repa.Index, this is a -- short-circuited test that checks the lowest dimension first. isOutside2 :: DIM2 -> DIM2 -> Bool -- | Given the extent of an array, clamp the components of an index so they -- lie within the given array. Outlying indices are clamped to the index -- of the nearest border element. clampToBorder2 :: DIM2 -> DIM2 -> DIM2 -- | Make a 2D partitioned array from two others, one to produce the -- elements in the internal region, and one to produce elements in the -- border region. The two arrays must have the same extent. The border -- must be the same width on all sides. makeBordered2 :: (Source r1 a, Source r2 a) => DIM2 -> Int -> Array r1 DIM2 a -> Array r2 DIM2 a -> Array (P r1 (P r2 (P r2 (P r2 (P r2 X))))) DIM2 a module Data.Array.Repa.Stencil.Dim2 -- | Wrapper for makeStencil that requires a DIM2 stencil. makeStencil2 :: Num a => Int -> Int -> (DIM2 -> Maybe a) -> Stencil DIM2 a -- | QuasiQuoter for producing a static stencil defintion. -- -- A definition like -- --
--   [stencil2|  0 1 0
--               1 0 1
--               0 1 0 |]
--   
--   
-- -- Is converted to: -- --
--   makeStencil2 (Z:.3:.3)
--      (\ix -> case ix of
--                Z :. -1 :.  0  -> Just 1
--                Z :.  0 :. -1  -> Just 1
--                Z :.  0 :.  1  -> Just 1
--                Z :.  1 :.  0  -> Just 1
--                _              -> Nothing)
--   
--   
stencil2 :: QuasiQuoter type PC5 = P C (P (S D) (P (S D) (P (S D) (P (S D) X)))) -- | Apply a stencil to every element of a 2D array. mapStencil2 :: Source r a => Boundary a -> Stencil DIM2 a -> Array r DIM2 a -> Array PC5 DIM2 a -- | Like mapStencil2 but with the parameters flipped. forStencil2 :: Source r a => Boundary a -> Array r DIM2 a -> Stencil DIM2 a -> Array PC5 DIM2 a module Data.Array.Repa.Operators.Reduction -- | Sequential reduction of the innermost dimension of an arbitrary rank -- array. -- -- Combine this with transpose to fold any other dimension. -- -- Elements are reduced in the order of their indices, from lowest to -- highest. Applications of the operator are associatied arbitrarily. -- --
--   >>> let c 0 x = x; c x 0 = x; c x y = y
--   
--   >>> let a = fromListUnboxed (Z :. 2 :. 2) [1,2,3,4] :: Array U (Z :. Int :. Int) Int
--   
--   >>> foldS c 0 a
--   AUnboxed (Z :. 2) (fromList [2,4])
--   
foldS :: (Shape sh, Source r a, Elt a, Unbox a) => (a -> a -> a) -> a -> Array r (sh :. Int) a -> Array U sh a -- | Parallel reduction of the innermost dimension of an arbitray rank -- array. -- -- The first argument needs to be an associative sequential operator. The -- starting element must be neutral with respect to the operator, for -- example 0 is neutral with respect to (+) as 0 + -- a = a. These restrictions are required to support parallel -- evaluation, as the starting element may be used multiple times -- depending on the number of threads. -- -- Elements are reduced in the order of their indices, from lowest to -- highest. Applications of the operator are associatied arbitrarily. -- --
--   >>> let c 0 x = x; c x 0 = x; c x y = y
--   
--   >>> let a = fromListUnboxed (Z :. 2 :. 2) [1,2,3,4] :: Array U (Z :. Int :. Int) Int
--   
--   >>> foldP c 0 a
--   AUnboxed (Z :. 2) (fromList [2,4])
--   
foldP :: (Shape sh, Source r a, Elt a, Unbox a, Monad m) => (a -> a -> a) -> a -> Array r (sh :. Int) a -> m (Array U sh a) -- | Sequential reduction of an array of arbitrary rank to a single scalar -- value. -- -- Elements are reduced in row-major order. Applications of the operator -- are associated arbitrarily. foldAllS :: (Shape sh, Source r a, Elt a, Unbox a) => (a -> a -> a) -> a -> Array r sh a -> a -- | Parallel reduction of an array of arbitrary rank to a single scalar -- value. -- -- The first argument needs to be an associative sequential operator. The -- starting element must be neutral with respect to the operator, for -- example 0 is neutral with respect to (+) as 0 + -- a = a. These restrictions are required to support parallel -- evaluation, as the starting element may be used multiple times -- depending on the number of threads. -- -- Elements are reduced in row-major order. Applications of the operator -- are associated arbitrarily. foldAllP :: (Shape sh, Source r a, Elt a, Unbox a, Monad m) => (a -> a -> a) -> a -> Array r sh a -> m a -- | Sequential sum the innermost dimension of an array. sumS :: (Shape sh, Source r a, Num a, Elt a, Unbox a) => Array r (sh :. Int) a -> Array U sh a -- | Parallel sum the innermost dimension of an array. sumP :: (Shape sh, Source r a, Num a, Elt a, Unbox a, Monad m) => Array r (sh :. Int) a -> m (Array U sh a) -- | Sequential sum of all the elements of an array. sumAllS :: (Shape sh, Source r a, Elt a, Unbox a, Num a) => Array r sh a -> a -- | Parallel sum all the elements of an array. sumAllP :: (Shape sh, Source r a, Elt a, Unbox a, Num a, Monad m) => Array r sh a -> m a -- | Check whether two arrays have the same shape and contain equal -- elements, sequentially. equalsS :: (Shape sh, Eq sh, Source r1 a, Source r2 a, Eq a) => Array r1 sh a -> Array r2 sh a -> Bool -- | Check whether two arrays have the same shape and contain equal -- elements, in parallel. equalsP :: (Shape sh, Eq sh, Source r1 a, Source r2 a, Eq a, Monad m) => Array r1 sh a -> Array r2 sh a -> m Bool instance (Data.Array.Repa.Shape.Shape sh, GHC.Classes.Eq sh, Data.Array.Repa.Base.Source r a, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Array.Repa.Base.Array r sh a) module Data.Array.Repa.Repr.Vector -- | Arrays represented as boxed vectors. -- -- This representation should only be used when your element type doesn't -- have an Unbox instsance. If it does, then use the Unboxed -- U representation will be faster. data V -- | Sequential computation of array elements. -- -- computeVectorS :: (Shape sh, Load r1 sh e) => Array r1 sh e -> Array V sh e -- | Parallel computation of array elements. computeVectorP :: (Shape sh, Load r1 sh e, Monad m) => Array r1 sh e -> m (Array V sh e) -- | O(n). Convert a list to a boxed vector array. -- -- fromListVector :: Shape sh => sh -> [a] -> Array V sh a -- | O(1). Wrap a boxed vector as an array. fromVector :: Shape sh => sh -> Vector e -> Array V sh e -- | O(1). Unpack a boxed vector from an array. toVector :: Array V sh e -> Vector e instance (GHC.Show.Show sh, GHC.Show.Show e) => GHC.Show.Show (Data.Array.Repa.Base.Array Data.Array.Repa.Repr.Vector.V sh e) instance (GHC.Read.Read sh, GHC.Read.Read e) => GHC.Read.Read (Data.Array.Repa.Base.Array Data.Array.Repa.Repr.Vector.V sh e) instance Data.Array.Repa.Base.Source Data.Array.Repa.Repr.Vector.V a instance Data.Array.Repa.Eval.Target.Target Data.Array.Repa.Repr.Vector.V e module Data.Array.Repa.Arbitrary -- | Generates a random unboxed array of a given shape arbitraryUShaped :: (Arbitrary a, Unbox a, Shape sh) => sh -> Gen (Array U sh a) -- | Property tested for unboxed random arrays with a given shape. forAllUShaped :: (Show a, Show sh, Testable prop, Arbitrary a, Unbox a, Shape sh) => sh -> (Array U sh a -> prop) -> Property -- | Property tested for pair of unboxed random arrays with a given shape. forAll2UShaped :: (Show a, Show sh, Testable prop, Arbitrary a, Unbox a, Shape sh) => sh -> ((Array U sh a, Array U sh a) -> prop) -> Property -- | Property tested for triple of unboxed random arrays with a given -- shape. forAll3UShaped :: (Show a, Show sh, Testable prop, Arbitrary a, Unbox a, Shape sh) => sh -> ((Array U sh a, Array U sh a, Array U sh a) -> prop) -> Property -- | Property tested for quadruple of unboxed random arrays with a given -- shape. forAll4UShaped :: (Show a, Show sh, Testable prop, Arbitrary a, Unbox a, Shape sh) => sh -> ((Array U sh a, Array U sh a, Array U sh a, Array U sh a) -> prop) -> Property -- | Property tested for 5-tuple of unboxed random arrays with a given -- shape. forAll5UShaped :: (Show a, Show sh, Testable prop, Arbitrary a, Unbox a, Shape sh) => sh -> ((Array U sh a, Array U sh a, Array U sh a, Array U sh a, Array U sh a) -> prop) -> Property -- | Generates a random boxed array of a given shape arbitraryVShaped :: (Arbitrary a, Shape sh) => sh -> Gen (Array V sh a) -- | Property tested for unboxed random arrays with a given shape. forAllVShaped :: (Show a, Show sh, Testable prop, Arbitrary a, Shape sh) => sh -> (Array V sh a -> prop) -> Property -- | Property tested for pair of unboxed random arrays with a given shape. forAll2VShaped :: (Show a, Show sh, Testable prop, Arbitrary a, Shape sh) => sh -> ((Array V sh a, Array V sh a) -> prop) -> Property -- | Property tested for triple of unboxed random arrays with a given -- shape. forAll3VShaped :: (Show a, Show sh, Testable prop, Arbitrary a, Shape sh) => sh -> ((Array V sh a, Array V sh a, Array V sh a) -> prop) -> Property -- | Property tested for quadruple of unboxed random arrays with a given -- shape. forAll4VShaped :: (Show a, Show sh, Testable prop, Arbitrary a, Shape sh) => sh -> ((Array V sh a, Array V sh a, Array V sh a, Array V sh a) -> prop) -> Property -- | Property tested for 5-tuple of unboxed random arrays with a given -- shape. forAll5VShaped :: (Show a, Show sh, Testable prop, Arbitrary a, Shape sh) => sh -> ((Array V sh a, Array V sh a, Array V sh a, Array V sh a, Array V sh a) -> prop) -> Property instance Test.QuickCheck.Arbitrary.Arbitrary Data.Array.Repa.Index.Z instance (Data.Array.Repa.Shape.Shape a, Test.QuickCheck.Arbitrary.Arbitrary a) => Test.QuickCheck.Arbitrary.Arbitrary (a Data.Array.Repa.Index.:. GHC.Types.Int) instance (Test.QuickCheck.Arbitrary.Arbitrary sh, Test.QuickCheck.Arbitrary.Arbitrary a, Data.Vector.Unboxed.Base.Unbox a, Data.Array.Repa.Shape.Shape sh) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Array.Repa.Base.Array Data.Array.Repa.Repr.Unboxed.U sh a) instance (Test.QuickCheck.Arbitrary.Arbitrary sh, Test.QuickCheck.Arbitrary.Arbitrary a, Data.Array.Repa.Shape.Shape sh) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Array.Repa.Base.Array Data.Array.Repa.Repr.Vector.V sh a) instance Test.QuickCheck.Arbitrary.CoArbitrary Data.Array.Repa.Index.Z instance (Data.Array.Repa.Shape.Shape a, Test.QuickCheck.Arbitrary.CoArbitrary a) => Test.QuickCheck.Arbitrary.CoArbitrary (a Data.Array.Repa.Index.:. GHC.Types.Int) instance (Test.QuickCheck.Arbitrary.CoArbitrary sh, Test.QuickCheck.Arbitrary.CoArbitrary a, Data.Array.Repa.Base.Source r a, Data.Array.Repa.Shape.Shape sh) => Test.QuickCheck.Arbitrary.CoArbitrary (Data.Array.Repa.Base.Array r sh a) -- | Repa arrays are wrappers around a linear structure that holds the -- element data. -- -- The representation tag determines what structure holds the data. -- -- Delayed Representations (functions that compute elements) -- -- -- -- Manifest Representations (real data) -- -- -- -- Meta Representations -- -- -- -- Array fusion is achieved via the delayed (D) and cursored -- (C) representations. At compile time, the GHC simplifier -- combines the functions contained within D and C arrays -- without needing to create manifest intermediate arrays. -- -- Advice for writing fast code: -- --
    --
  1. Repa does not support nested parallellism. This means that you -- cannot map a parallel worker function across an array and then -- call computeP to evaluate it, or pass a parallel worker to -- parallel reductions such as foldP. If you do then you will get -- a run-time warning and the code will run very slowly.
  2. --
  3. Arrays of type (Array D sh a) or (Array C sh a) -- are not real arrays. They are represented as functions that -- compute each element on demand. You need to use computeS, -- computeP, computeUnboxedP and so on to actually evaluate -- the elements.
  4. --
  5. Add INLINE pragmas to all leaf-functions in your code, -- expecially ones that compute numeric results. Non-inlined lazy -- function calls can cost upwards of 50 cycles each, while each numeric -- operator only costs one (or less). Inlining leaf functions also -- ensures they are specialised at the appropriate numeric types.
  6. --
  7. Add bang patterns to all function arguments, and all fields of -- your data types. In a high-performance Haskell program, the cost of -- lazy evaluation can easily dominate the run time if not handled -- correctly. You don't want to rely on the strictness analyser in -- numeric code because if it does not return a perfect result then the -- performance of your program will be awful. This is less of a problem -- for general Haskell code, and in a different context relying on -- strictness analysis is fine.
  8. --
  9. Scheduling an 8-thread parallel computation can take 50us on a -- Linux machine. You should switch to sequential evaluation functions -- like computeS and foldS for small arrays in inner loops, -- and at the bottom of a divide-and-conquer algorithm. Consider using a -- computeP that evaluates an array defined using computeS -- or foldS for each element.
  10. --
  11. Compile the modules that use Repa with the following flags: -- -Odph -rtsopts -threaded -fno-liberate-case -- -funfolding-use-threshold1000 -funfolding-keeness-factor1000 -- -fllvm -optlo-O3 You don't want the liberate-case transform -- because it tends to duplicate too much intermediate code, and is not -- needed if you use bang patterns as per point 4. The unfolding flags -- tell the inliner to not to fool around with heuristics, and just -- inline everything. If the binaries become too big then split the array -- part of your program into separate modules and only compile those with -- the unfolding flags.
  12. --
  13. Repa writes to the GHC eventlog at the start and end of each -- parallel computation. Use threadscope to see what your program is -- doing.
  14. --
  15. When you're sure your program works, switch to the unsafe versions -- of functions like traverse. These don't do bounds checks.
  16. --
-- -- Changes for Repa 3.2: -- --
    --
  1. Renamed some Repa 3.1 type classes to have more intuitive names: -- Repr -> Source, Fill -> Load, -- Fillable -> Target, Combine -> -- Structured.
  2. --
  3. Also renamed MArray -> MVec to emphasise its -- linear structure.
  4. --
  5. Made Array and MVec associated types of -- Source and Target respectively.
  6. --
  7. Added the S (Smallness) and I (Interleave) -- hints.
  8. --
module Data.Array.Repa -- | Class of array representations that we can read elements from. class Source r e where data family Array r sh e index arr ix = arr `linearIndex` toIndex (extent arr) ix unsafeIndex arr ix = arr `unsafeLinearIndex` toIndex (extent arr) ix unsafeLinearIndex = linearIndex -- | O(1). Take the extent (size) of an array. extent :: (Source r e, Shape sh) => Array r sh e -> sh -- | O(1). Shape polymorphic indexing. index :: (Source r e, Shape sh) => Array r sh e -> sh -> e -- | O(1). Shape polymorphic indexing. unsafeIndex :: (Source r e, Shape sh) => Array r sh e -> sh -> e -- | O(1). Linear indexing into underlying, row-major, array -- representation. linearIndex :: (Source r e, Shape sh) => Array r sh e -> Int -> e -- | O(1). Linear indexing into underlying, row-major, array -- representation. unsafeLinearIndex :: (Source r e, Shape sh) => Array r sh e -> Int -> e -- | Ensure an array's data structure is fully evaluated. deepSeqArray :: (Source r e, Shape sh) => Array r sh e -> b -> b -- | O(1). Alias for index (!) :: Shape sh => Source r e => Array r sh e -> sh -> e -- | O(n). Convert an array to a list. toList :: Shape sh => Source r e => Array r sh e -> [e] -- | Apply deepSeqArray to up to four arrays. deepSeqArrays :: Shape sh => Source r e => [Array r sh e] -> b -> b -- | Parallel computation of array elements. -- -- computeP :: (Load r1 sh e, Target r2 e, Source r2 e, Monad m) => Array r1 sh e -> m (Array r2 sh e) -- | Sequential computation of array elements. computeS :: (Load r1 sh e, Target r2 e) => Array r1 sh e -> Array r2 sh e -- | Parallel copying of arrays. -- -- copyP :: (Source r1 e, Source r2 e, Load D sh e, Target r2 e, Monad m) => Array r1 sh e -> m (Array r2 sh e) -- | Sequential copying of arrays. copyS :: (Source r1 e, Load D sh e, Target r2 e) => Array r1 sh e -> Array r2 sh e -- | Delayed arrays are represented as functions from the index to element -- value. -- -- Every time you index into a delayed array the element at that position -- is recomputed. data D -- | O(1). Wrap a function as a delayed array. fromFunction :: sh -> (sh -> a) -> Array D sh a -- | O(1). Produce the extent of an array, and a function to retrieve an -- arbitrary element. toFunction :: (Shape sh, Source r1 a) => Array r1 sh a -> (sh, sh -> a) -- | O(1). Delay an array. This wraps the internal representation to be a -- function from indices to elements, so consumers don't need to worry -- about what the previous representation was. delay :: Shape sh => Source r e => Array r sh e -> Array D sh e -- | Unboxed arrays are represented as unboxed vectors. -- -- The implementation uses Data.Vector.Unboxed which is based on -- type families and picks an efficient, specialised representation for -- every element type. In particular, unboxed vectors of pairs are -- represented as pairs of unboxed vectors. This is the most efficient -- representation for numerical data. data U -- | Parallel computation of array elements. -- -- computeUnboxedP :: (Shape sh, Load r1 sh e, Monad m, Unbox e) => Array r1 sh e -> m (Array U sh e) -- | Sequential computation of array elements.. -- -- computeUnboxedS :: (Shape sh, Load r1 sh e, Unbox e) => Array r1 sh e -> Array U sh e -- | O(n). Convert a list to an unboxed vector array. -- -- fromListUnboxed :: (Shape sh, Unbox a) => sh -> [a] -> Array U sh a -- | O(1). Wrap an unboxed vector as an array. fromUnboxed :: (Shape sh, Unbox e) => sh -> Vector e -> Array U sh e -- | O(1). Unpack an unboxed vector from an array. toUnboxed :: Unbox e => Array U sh e -> Vector e -- | Impose a new shape on the elements of an array. The new extent must be -- the same size as the original, else error. reshape :: (Shape sh1, Shape sh2, Source r1 e) => sh2 -> Array r1 sh1 e -> Array D sh2 e -- | Append two arrays. append :: (Shape sh, Source r1 e, Source r2 e) => Array r1 (sh :. Int) e -> Array r2 (sh :. Int) e -> Array D (sh :. Int) e -- | Append two arrays. (++) :: (Shape sh, Source r1 e, Source r2 e) => Array r1 (sh :. Int) e -> Array r2 (sh :. Int) e -> Array D (sh :. Int) e -- | Extract a sub-range of elements from an array. extract :: (Shape sh, Source r e) => sh -> sh -> Array r sh e -> Array D sh e -- | Transpose the lowest two dimensions of an array. Transposing an array -- twice yields the original. transpose :: (Shape sh, Source r e) => Array r ((sh :. Int) :. Int) e -> Array D ((sh :. Int) :. Int) e -- | Backwards permutation of an array's elements. backpermute :: (Shape sh1, Shape sh2, Source r e) => sh2 -> (sh2 -> sh1) -> Array r sh1 e -> Array D sh2 e -- | Default backwards permutation of an array's elements. If the function -- returns Nothing then the value at that index is taken from the -- default array (arrDft) backpermuteDft :: (Shape sh1, Shape sh2, Source r1 e, Source r2 e) => Array r2 sh2 e -> (sh2 -> Maybe sh1) -> Array r1 sh1 e -> Array D sh2 e -- | Take a slice from an array, according to a given specification. -- -- For example, to take a row from a matrix use the following: -- --
--   slice arr (Any :. (5::Int) :. All)
--   
-- -- To take a column use: -- --
--   slice arr (Any :. (5::Int))
--   
slice :: (Slice sl, Shape (FullShape sl), Shape (SliceShape sl), Source r e) => Array r (FullShape sl) e -> sl -> Array D (SliceShape sl) e -- | Extend an array, according to a given slice specification. -- -- For example, to replicate the rows of an array use the following: -- --
--   extend arr (Any :. (5::Int) :. All)
--   
extend :: (Slice sl, Shape (SliceShape sl), Shape (FullShape sl), Source r e) => sl -> Array r (SliceShape sl) e -> Array D (FullShape sl) e -- | Apply a worker function to each element of an array, yielding a new -- array with the same extent. map :: (Shape sh, Source r a) => (a -> b) -> Array r sh a -> Array D sh b -- | Combine two arrays, element-wise, with a binary operator. If the -- extent of the two array arguments differ, then the resulting array's -- extent is their intersection. zipWith :: (Shape sh, Source r1 a, Source r2 b) => (a -> b -> c) -> Array r1 sh a -> Array r2 sh b -> Array D sh c (+^) :: (Num c, Shape sh, Source r1 c, Source r2 c) => Array r1 sh c -> Array r2 sh c -> Array D sh c (-^) :: (Num c, Shape sh, Source r1 c, Source r2 c) => Array r1 sh c -> Array r2 sh c -> Array D sh c (*^) :: (Num c, Shape sh, Source r1 c, Source r2 c) => Array r1 sh c -> Array r2 sh c -> Array D sh c (/^) :: (Fractional c, Shape sh, Source r1 c, Source r2 c) => Array r1 sh c -> Array r2 sh c -> Array D sh c -- | Structured versions of map and zipWith that preserve -- the representation of cursored and partitioned arrays. -- -- For cursored (C) arrays, the cursoring of the source array is -- preserved. -- -- For partitioned (P) arrays, the worker function is fused with -- each array partition separately, instead of treating the whole array -- as a single bulk object. -- -- Preserving the cursored and/or paritioned representation of an array -- is will make follow-on computation more efficient than if the array -- was converted to a vanilla Delayed (D) array as with plain -- map and zipWith. -- -- If the source array is not cursored or partitioned then smap -- and szipWith are identical to the plain functions. class Structured r1 a b where type family TR r1 -- | Structured map. smap :: (Structured r1 a b, Shape sh) => (a -> b) -> Array r1 sh a -> Array (TR r1) sh b -- | Structured zipWith. If you have a cursored or partitioned -- source array then use that as the third argument (corresponding to -- r1 here) szipWith :: (Structured r1 a b, Shape sh, Source r c) => (c -> a -> b) -> Array r sh c -> Array r1 sh a -> Array (TR r1) sh b -- | Unstructured traversal. traverse :: (Source r a, Shape sh, Shape sh') => Array r sh a -> (sh -> sh') -> ((sh -> a) -> sh' -> b) -> Array D sh' b -- | Unstructured traversal over two arrays at once. traverse2 :: (Source r1 a, Source r2 b, Shape sh, Shape sh', Shape sh'') => Array r1 sh a -> Array r2 sh' b -> (sh -> sh' -> sh'') -> ((sh -> a) -> (sh' -> b) -> (sh'' -> c)) -> Array D sh'' c -- | Unstructured traversal over three arrays at once. traverse3 :: (Source r1 a, Source r2 b, Source r3 c, Shape sh1, Shape sh2, Shape sh3, Shape sh4) => Array r1 sh1 a -> Array r2 sh2 b -> Array r3 sh3 c -> (sh1 -> sh2 -> sh3 -> sh4) -> ((sh1 -> a) -> (sh2 -> b) -> (sh3 -> c) -> sh4 -> d) -> Array D sh4 d -- | Unstructured traversal over four arrays at once. traverse4 :: (Source r1 a, Source r2 b, Source r3 c, Source r4 d, Shape sh1, Shape sh2, Shape sh3, Shape sh4, Shape sh5) => Array r1 sh1 a -> Array r2 sh2 b -> Array r3 sh3 c -> Array r4 sh4 d -> (sh1 -> sh2 -> sh3 -> sh4 -> sh5) -> ((sh1 -> a) -> (sh2 -> b) -> (sh3 -> c) -> (sh4 -> d) -> sh5 -> e) -> Array D sh5 e -- | Interleave the elements of two arrays. All the input arrays must have -- the same extent, else error. The lowest dimension of the result -- array is twice the size of the inputs. -- --
--   interleave2 a1 a2   b1 b2  =>  a1 b1 a2 b2
--               a3 a4   b3 b4      a3 b3 a4 b4
--   
interleave2 :: (Shape sh, Source r1 a, Source r2 a) => Array r1 (sh :. Int) a -> Array r2 (sh :. Int) a -> Array D (sh :. Int) a -- | Interleave the elements of three arrays. interleave3 :: (Shape sh, Source r1 a, Source r2 a, Source r3 a) => Array r1 (sh :. Int) a -> Array r2 (sh :. Int) a -> Array r3 (sh :. Int) a -> Array D (sh :. Int) a -- | Interleave the elements of four arrays. interleave4 :: (Shape sh, Source r1 a, Source r2 a, Source r3 a, Source r4 a) => Array r1 (sh :. Int) a -> Array r2 (sh :. Int) a -> Array r3 (sh :. Int) a -> Array r4 (sh :. Int) a -> Array D (sh :. Int) a -- | Parallel reduction of the innermost dimension of an arbitray rank -- array. -- -- The first argument needs to be an associative sequential operator. The -- starting element must be neutral with respect to the operator, for -- example 0 is neutral with respect to (+) as 0 + -- a = a. These restrictions are required to support parallel -- evaluation, as the starting element may be used multiple times -- depending on the number of threads. -- -- Elements are reduced in the order of their indices, from lowest to -- highest. Applications of the operator are associatied arbitrarily. -- --
--   >>> let c 0 x = x; c x 0 = x; c x y = y
--   
--   >>> let a = fromListUnboxed (Z :. 2 :. 2) [1,2,3,4] :: Array U (Z :. Int :. Int) Int
--   
--   >>> foldP c 0 a
--   AUnboxed (Z :. 2) (fromList [2,4])
--   
foldP :: (Shape sh, Source r a, Elt a, Unbox a, Monad m) => (a -> a -> a) -> a -> Array r (sh :. Int) a -> m (Array U sh a) -- | Sequential reduction of the innermost dimension of an arbitrary rank -- array. -- -- Combine this with transpose to fold any other dimension. -- -- Elements are reduced in the order of their indices, from lowest to -- highest. Applications of the operator are associatied arbitrarily. -- --
--   >>> let c 0 x = x; c x 0 = x; c x y = y
--   
--   >>> let a = fromListUnboxed (Z :. 2 :. 2) [1,2,3,4] :: Array U (Z :. Int :. Int) Int
--   
--   >>> foldS c 0 a
--   AUnboxed (Z :. 2) (fromList [2,4])
--   
foldS :: (Shape sh, Source r a, Elt a, Unbox a) => (a -> a -> a) -> a -> Array r (sh :. Int) a -> Array U sh a -- | Parallel reduction of an array of arbitrary rank to a single scalar -- value. -- -- The first argument needs to be an associative sequential operator. The -- starting element must be neutral with respect to the operator, for -- example 0 is neutral with respect to (+) as 0 + -- a = a. These restrictions are required to support parallel -- evaluation, as the starting element may be used multiple times -- depending on the number of threads. -- -- Elements are reduced in row-major order. Applications of the operator -- are associated arbitrarily. foldAllP :: (Shape sh, Source r a, Elt a, Unbox a, Monad m) => (a -> a -> a) -> a -> Array r sh a -> m a -- | Sequential reduction of an array of arbitrary rank to a single scalar -- value. -- -- Elements are reduced in row-major order. Applications of the operator -- are associated arbitrarily. foldAllS :: (Shape sh, Source r a, Elt a, Unbox a) => (a -> a -> a) -> a -> Array r sh a -> a -- | Parallel sum the innermost dimension of an array. sumP :: (Shape sh, Source r a, Num a, Elt a, Unbox a, Monad m) => Array r (sh :. Int) a -> m (Array U sh a) -- | Sequential sum the innermost dimension of an array. sumS :: (Shape sh, Source r a, Num a, Elt a, Unbox a) => Array r (sh :. Int) a -> Array U sh a -- | Parallel sum all the elements of an array. sumAllP :: (Shape sh, Source r a, Elt a, Unbox a, Num a, Monad m) => Array r sh a -> m a -- | Sequential sum of all the elements of an array. sumAllS :: (Shape sh, Source r a, Elt a, Unbox a, Num a) => Array r sh a -> a -- | Check whether two arrays have the same shape and contain equal -- elements, in parallel. equalsP :: (Shape sh, Eq sh, Source r1 a, Source r2 a, Eq a, Monad m) => Array r1 sh a -> Array r2 sh a -> m Bool -- | Check whether two arrays have the same shape and contain equal -- elements, sequentially. equalsS :: (Shape sh, Eq sh, Source r1 a, Source r2 a, Eq a) => Array r1 sh a -> Array r2 sh a -> Bool -- | Produce an array by applying a predicate to a range of integers. If -- the predicate matches, then use the second function to generate the -- element. -- -- selectP :: (Unbox a, Monad m) => (Int -> Bool) -> (Int -> a) -> Int -> m (Array U DIM1 a) -- | Efficient computation of stencil based convolutions. module Data.Array.Repa.Stencil -- | Represents a convolution stencil that we can apply to array. Only -- statically known stencils are supported right now. data Stencil sh a -- | Static stencils are used when the coefficients are fixed, and known at -- compile time. StencilStatic :: !sh -> !a -> !(sh -> a -> a -> a) -> Stencil sh a [stencilExtent] :: Stencil sh a -> !sh [stencilZero] :: Stencil sh a -> !a [stencilAcc] :: Stencil sh a -> !(sh -> a -> a -> a) -- | How to handle the case when the stencil lies partly outside the array. data Boundary a -- | Use a fixed value for border regions. BoundFixed :: !a -> Boundary a -- | Treat points outside the array as having a constant value. BoundConst :: !a -> Boundary a -- | Clamp points outside to the same value as the edge pixel. BoundClamp :: Boundary a -- | Make a stencil from a function yielding coefficients at each index. makeStencil :: Num a => sh -> (sh -> Maybe a) -> Stencil sh a