packages feed

repa 3.0.0.1 → 3.1.0.1

raw patch · 26 files changed

+604/−362 lines, 26 files

Files

Data/Array/Repa.hs view
@@ -29,11 +29,8 @@ --  contained within `D` and `C` arrays without needing to create manifest --  intermediate arrays.  -----  Converting between the parallel manifest representations (eg `U` and `B`)---  is either constant time or parallel copy, depending on the compatability---  of the physical representation. -----  /Writing fast code:/+--  /Advice for writing fast code:/ -- --  1. Repa does not support nested parallellism.  --     This means that you cannot `map` a parallel worker function across@@ -43,29 +40,59 @@ -- --  2. 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 a function like `computeS`, `computeP`, `computeUnboxedP`+--     You need to use `computeS`, `computeP`, `computeUnboxedP` --     and so on to actually evaluate the elements. --     ---  3. You should add @INLINE@ pragmas to all leaf-functions in your code, ---     expecially ones that compute numberic results. This ensures they are ---     specialised at the appropriate element types.+--  3. 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.+--     +--  4. 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. -----  4. Scheduling a parallel computation takes about 200us on an OSX machine. ---     You should sequential computation for small arrays in inner loops, ---     or a the bottom of a divide-and-conquer algorithm.+--  5. Scheduling a parallel computation takes about 200us on an OSX 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. --+--  6. 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.+--+--  7. Repa writes to the GHC eventlog at the start and end of  each parallel computation.+--     Use threadscope to see what your program is doing.+--+--  8. Follow the advice on program structure in the comment for `deepSeqArrays`+--+--  9. When you're sure your program works, switch to the unsafe versions+--     of functions like `traverse`. These don't do bounds checks.+--  module Data.Array.Repa         ( -- * Abstract array representation-          Array(..)-        , module Data.Array.Repa.Shape+          module Data.Array.Repa.Shape         , module Data.Array.Repa.Index+        , Array(..)         , Repr(..), (!), toList         , deepSeqArrays -        -- * Converting between array representations+        -- * Computation         , computeP, computeS         , copyP,    copyS-        , now          -- * Concrete array representations         -- ** Delayed representation@@ -84,13 +111,15 @@ 	-- ** Index space transformations 	, reshape 	, append, (++)+        , extract 	, transpose-	, extend-	, backpermute,         unsafeBackpermute+	, backpermute 	, backpermuteDft +        -- ** Slice transformations 	, module Data.Array.Repa.Slice 	, slice+        , extend  	-- from Data.Array.Repa.Operators.Mapping -------------------         -- ** Structure preserving operations@@ -101,10 +130,10 @@  	-- from Data.Array.Repa.Operators.Traversal ------------------ 	-- ** Generic traversal-	, traverse,            unsafeTraverse-	, traverse2,           unsafeTraverse2-	, traverse3,           unsafeTraverse3-	, traverse4,           unsafeTraverse4+	, traverse +	, traverse2+	, traverse3+	, traverse4 	 	-- from Data.Array.Repa.Operators.Interleave ----------------- 	-- ** Interleaving@@ -118,9 +147,11 @@ 	, foldAllP, foldAllS 	, sumP,     sumS 	, sumAllP,  sumAllS+        , equalsP,  equalsS 	 	-- from Data.Array.Repa.Operators.Selection -------------------	, select)+        -- ** Selection+	, selectP) where import Data.Array.Repa.Base import Data.Array.Repa.Shape
Data/Array/Repa/Base.hs view
@@ -12,10 +12,11 @@ data family Array r sh e  +-- Repr ----------------------------------------------------------------------- -- | Class of array representations that we can read elements from. -- class Repr r e where- -- | O(1). Take the extent of an array.+ -- | O(1). Take the extent (size) of an array.  extent       :: Shape sh => Array r sh e -> sh   -- | O(1). Shape polymorphic indexing.@@ -61,6 +62,32 @@ --   The implementation of this function has been hand-unwound to work for up to --   four arrays. Putting more in the list yields `error`. -- +--   For functions that are /not/ marked as INLINE, you should apply `deepSeqArrays`+--   to argument arrays before using them in a @compute@ or @copy@ expression.+--   For example:+--+-- @  processArrays +--     :: Monad m +--     => Array U DIM2 Int -> Array U DIM2 Int +--     -> m (Array U DIM2 Int)+--  processArrays arr1 arr2+--   = [arr1, arr2] \`deepSeqArrays\` +--     do arr3 <- computeP $ map f arr1+--        arr4 <- computeP $ zipWith g arr3 arr2+--        return arr4+--  @+--+--  Applying `deepSeqArrays` tells the GHC simplifier that it's ok to unbox +--  size fields and the pointers to the underlying array data at the start+--  of the function. Without this, they may be unboxed repeatedly when+--  computing elements in the result arrays, which will make your program slow.+--+--  If you INLINE @processArrays@ into the function that computes @arr1@ and @arr2@,+--  then you don't need to apply `deepSeqArrays`. This is because a pointer+--  to the underlying data will be passed directly to the consumers and never boxed.+--+--  If you're not sure, then just follow the example code above.+--    deepSeqArrays          :: (Shape sh, Repr r e)         => [Array r sh e] -> b -> b@@ -82,4 +109,6 @@          -> a1 `deepSeqArray` a2 `deepSeqArray` a3 `deepSeqArray` a4 `deepSeqArray` x          _ -> error "deepSeqArrays: only works for up to four arrays"++  
Data/Array/Repa/Eval.hs view
@@ -12,8 +12,8 @@         , fromList                  -- * Converting between representations-        , computeP, computeS-        , copyP,    copyS+        , computeS, computeP, suspendedComputeP+        , copyS,    copyP,    suspendedCopyP         , now                  -- * Chunked filling@@ -46,8 +46,8 @@  -- | Parallel computation of array elements. -----   * The `Fill` class is defined so that the source array must have a---     delayed representation (`D` or `C`)+--   * The source array must have a delayed representation like `D`, `C` or `P`, +--     and the result a manifest representation like `U` or `F`. -- --   * If you want to copy data between manifest representations then use --    `copyP` instead.@@ -55,30 +55,47 @@ --   * If you want to convert a manifest array back to a delayed representation --     then use `delay` instead. ---computeP :: Fill r1 r2 sh e-        => Array r1 sh e -> Array r2 sh e+computeP +        :: (Shape sh, Fill r1 r2 sh e, Repr r2 e, Monad m)+        => Array r1 sh e -> m (Array r2 sh e)+computeP arr = now $ suspendedComputeP arr {-# INLINE [4] computeP #-}-computeP arr1- = arr1 `deepSeqArray` -   unsafePerformIO- $ do   marr2    <- newMArr (size $ extent arr1) -        fillP arr1 marr2-        unsafeFreezeMArr (extent arr1) marr2   -- | Sequential computation of array elements. computeS          :: Fill r1 r2 sh e         => Array r1 sh e -> Array r2 sh e-{-# INLINE [4] computeS #-} computeS arr1  = arr1 `deepSeqArray`     unsafePerformIO  $ do   marr2    <- newMArr (size $ extent arr1)          fillS arr1 marr2         unsafeFreezeMArr (extent arr1) marr2+{-# INLINE [4] computeS #-}  +-- | 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 +        :: Fill r1 r2 sh e+        => Array r1 sh e -> Array r2 sh e+suspendedComputeP arr1+ = arr1 `deepSeqArray` +   unsafePerformIO+ $ do   marr2    <- newMArr (size $ extent arr1) +        fillP arr1 marr2+        unsafeFreezeMArr (extent arr1) marr2+{-# INLINE [4] suspendedComputeP #-}   -- | Parallel copying of arrays.@@ -87,44 +104,41 @@ --  --   * You can use it to copy manifest arrays between representations. -----   * You can also use it to compute elements, but doing this may not be as---     efficient. This is because delaying it the second time can hide---     information about the structure of the original computation.----copyP   :: (Repr r1 e, Fill D r2 sh e)-        => Array r1 sh e -> Array r2 sh e+copyP  :: (Shape sh, Fill D r2 sh e, Repr r1 e, Repr r2 e, Monad m)+        => Array r1 sh e -> m (Array r2 sh e)+copyP arr = now $ suspendedCopyP arr {-# INLINE [4] copyP #-}-copyP arr1 = computeP $ delay arr1   -- | Sequential copying of arrays. copyS   :: (Repr r1 e, Fill D r2 sh e)         => Array r1 sh e -> Array r2 sh e+copyS arr1  = computeS $ delay arr1 {-# INLINE [4] copyS #-}-copyS arr1 = computeS $ delay arr1  -        +-- | Suspended parallel copy of array elements.+suspendedCopyP   +        :: (Repr r1 e, Fill D r2 sh e)+        => Array r1 sh e -> Array r2 sh e+suspendedCopyP arr1  = suspendedComputeP $ delay arr1+{-# INLINE [4] suspendedCopyP #-} --- | Apply `deepSeqArray` to an array so the result is actually constructed---   at this point in a monadic computation. ------   * Haskell's laziness means that applications of `computeP` and `copyP` are---     automatically suspended.------   * Laziness can be problematic for data parallel programs, because we want---     each array to be constructed in parallel before moving onto the next one.---   ---   For example:++-- | Monadic version of `deepSeqArray`. +-- +--   Forces an suspended array computation to be completed at this point+--   in a monadic computation. -----   @ do  arr2 <- now $ computeP $ map f arr1---     arr3 <- now $ computeP $ zipWith arr2 arr1---     return arr3---   @+-- @ do  let arr2 = suspendedComputeP arr1+--     ...+--     arr3 <- now $ arr2+--     ...+-- @ -- now     :: (Shape sh, Repr r e, Monad m)         => Array r sh e -> m (Array r sh e)-{-# INLINE [4] now #-} now arr  = do   arr `deepSeqArray` return ()         return arr+{-# INLINE [4] now #-}
Data/Array/Repa/Eval/Chunked.hs view
@@ -4,7 +4,6 @@ module Data.Array.Repa.Eval.Chunked 	( fillChunkedP 	, fillChunkedS-        , fillChunkedS' 	, fillChunkedIOP) where import Data.Array.Repa.Eval.Gang@@ -29,21 +28,6 @@ 	 | otherwise 	 = do	write (I# ix) (getElem (I# ix)) 		fill (ix +# 1#)--fillChunkedS'-        :: Int-        -> (Int -> IO ())-        -> IO ()--fillChunkedS' !(I# len) eat- = fill 0#- where fill !ix-        | ix >=# len    = return ()-        | otherwise-        = do    eat (I# ix)-                fill (ix +# 1#)--   -- | Fill something in parallel.
Data/Array/Repa/Eval/Cursored.hs view
@@ -11,9 +11,8 @@ import Data.Array.Repa.Shape import Data.Array.Repa.Eval.Elt import Data.Array.Repa.Eval.Gang-import GHC.Base					(remInt, quotInt)-import Prelude					as P-import GHC.Exts+import GHC.Base+import Prelude                          as P  -- Non-cursored interface ----------------------------------------------------- -- | Fill a block in a rank-2 array in parallel.@@ -31,11 +30,11 @@         :: Elt a 	=> (Int -> a -> IO ())	-- ^ Update function to write into result buffer.         -> (DIM2 -> a)          -- ^ Function to evaluate the element at an index.-	-> Int			-- ^ Width of the whole array.-	-> Int			-- ^ x0 lower left corner of block to fill-	-> Int			-- ^ y0 -	-> Int			-- ^ x1 upper right corner of block to fill-	-> Int			-- ^ y1+	-> Int#			-- ^ Width of the whole array.+	-> Int#			-- ^ x0 lower left corner of block to fill+	-> Int#			-- ^ y0 +	-> Int#			-- ^ x1 upper right corner of block to fill+	-> Int#			-- ^ y1         -> IO ()  {-# INLINE [0] fillBlock2P #-}@@ -92,33 +91,33 @@ 	-> (DIM2   -> cursor)		-- ^ Make a cursor to a particular element. 	-> (DIM2   -> cursor -> cursor)	-- ^ Shift the cursor by an offset. 	-> (cursor -> a)		-- ^ Function to evaluate the element at an index.-	-> Int			-- ^ Width of the whole array.-	-> Int			-- ^ x0 lower left corner of block to fill-	-> Int			-- ^ y0-	-> Int			-- ^ x1 upper right corner of block to fill-	-> Int			-- ^ y1+	-> Int#			-- ^ Width of the whole array.+	-> Int#			-- ^ x0 lower left corner of block to fill+	-> Int#			-- ^ y0+	-> Int#			-- ^ x1 upper right corner of block to fill+	-> Int#			-- ^ y1 	-> IO ()  {-# INLINE [0] fillCursoredBlock2P #-} fillCursoredBlock2P 	!write 	!makeCursorFCB !shiftCursorFCB !getElemFCB-	!(I# imageWidth) !x0 !y0 !x1 !y1+	!imageWidth !x0 !y0 !x1 !y1  = 	gangIO theGang fillBlock- where	!threads	= gangSize theGang-	!blockWidth	= x1 - x0 + 1+ where	!(I# threads)  = gangSize theGang+	!blockWidth    = x1 -# x0 +# 1#  	-- All columns have at least this many pixels.-	!colChunkLen	= blockWidth `quotInt` threads+	!colChunkLen   = I# (blockWidth `quotInt#` threads)  	-- Extra pixels that we have to divide between some of the threads.-	!colChunkSlack	= blockWidth `remInt` threads+	!colChunkSlack = I# (blockWidth `remInt#` threads)  	-- Get the starting pixel of a column in the image. 	{-# INLINE colIx #-} 	colIx !ix-	 | ix < colChunkSlack	= x0 + ix * (colChunkLen + 1)-	 | otherwise		= x0 + ix * colChunkLen + colChunkSlack+	 | ix < colChunkSlack = (I# x0) +  ix * (colChunkLen  + 1)+	 | otherwise	      = (I# x0) + (ix * colChunkLen) + colChunkSlack  	-- Give one column to each thread 	{-# INLINE fillBlock #-}@@ -126,8 +125,8 @@ 	fillBlock !ix 	 = let	!(I# x0')	= colIx ix 		!(I# x1')	= colIx (ix + 1) - 1-		!(I# y0')	= y0-		!(I# y1')	= y1+		!y0'	  = y0+		!y1'	  = y1 	   in	fillCursoredBlock2S 			write 			makeCursorFCB shiftCursorFCB getElemFCB
Data/Array/Repa/Eval/Fill.hs view
@@ -26,6 +26,9 @@  -- | Freeze the mutable array into an immutable Repa array.  unsafeFreezeMArr :: sh  -> MArr r e -> IO (Array r sh e) + -- | Ensure the strucure of a mutable array is fully evaluated.+ deepSeqMArr      :: MArr r e -> a -> a+  -- | O(n). Construct a manifest array from a list. fromList
Data/Array/Repa/Eval/Selection.hs view
@@ -96,31 +96,36 @@ 	-- Fill the given chunk with elements selected from this range of indices. 	makeChunk :: IORef (IOVector a) -> Int -> Int -> IO () 	makeChunk !ref !ixSrc !ixSrcEnd-	 = do	vecDst	<- VM.new (len `div` threads)-		vecDst'	<- fillChunk ixSrc ixSrcEnd vecDst 0 (VM.length vecDst - 1)-		writeIORef ref vecDst'+         | ixSrc > ixSrcEnd+         = do  vecDst   <- VM.new 0+               writeIORef ref vecDst +         | otherwise+	 = do  vecDst	<- VM.new (len `div` threads)+               vecDst'	<- fillChunk ixSrc ixSrcEnd vecDst 0 (VM.length vecDst)+	       writeIORef ref vecDst' + 	-- The main filling loop. 	fillChunk :: Int -> Int -> IOVector a -> Int -> Int -> IO (IOVector a)-	fillChunk !ixSrc !ixSrcEnd !vecDst !ixDst !ixDstEnd+	fillChunk !ixSrc !ixSrcEnd !vecDst !ixDst !ixDstLen          -- If we've finished selecting elements, then slice the vector down          -- so it doesn't have any empty space at the end.-	 | ixSrc >= ixSrcEnd+	 | ixSrc > ixSrcEnd 	 = 	return	$ VM.slice 0 ixDst vecDst  	 -- If we've run out of space in the chunk then grow it some more.-	 | ixDst >= ixDstEnd-	 = do	let ixDstEnd'	= VM.length vecDst * 2 - 1-		vecDst' 	<- VM.grow vecDst (ixDstEnd + 1)-		fillChunk (ixSrc + 1) ixSrcEnd vecDst' (ixDst + 1) ixDstEnd'+	 | ixDst >= ixDstLen+	 = do	let ixDstLen'	= (VM.length vecDst + 1) * 2+		vecDst' 	<- VM.grow vecDst ixDstLen'+		fillChunk ixSrc ixSrcEnd vecDst' ixDst ixDstLen'  	 -- We've got a maching element, so add it to the chunk. 	 | fnMatch ixSrc 	 = do	VM.unsafeWrite vecDst ixDst (fnProduce ixSrc)-		fillChunk (ixSrc + 1) ixSrcEnd vecDst (ixDst + 1)  ixDstEnd+		fillChunk (ixSrc + 1) ixSrcEnd vecDst (ixDst + 1) ixDstLen  	 -- The element doesnt match, so keep going. 	 | otherwise-	 =	fillChunk (ixSrc + 1) ixSrcEnd vecDst ixDst ixDstEnd+	 =	fillChunk (ixSrc + 1) ixSrcEnd vecDst ixDst ixDstLen 
Data/Array/Repa/Index.hs view
@@ -8,12 +8,8 @@ 	, (:.)	(..)  	-- * Common dimensions.-	, DIM0-	, DIM1-	, DIM2-	, DIM3-	, DIM4-	, DIM5)+	, DIM0, DIM1, DIM2, DIM3, DIM4, DIM5+        ,       ix1,  ix2,  ix3,  ix4,  ix5) where import Data.Array.Repa.Shape import GHC.Base 		(quotInt, remInt)@@ -39,7 +35,33 @@ type DIM5	= DIM4 :. Int  --- Shape ------------------------------------------------------------------------------------------+-- | 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+ix1 x = Z :. x+{-# INLINE ix1 #-}++ix2 :: Int -> Int -> DIM2+ix2 y x = Z :. y :. x+{-# INLINE ix2 #-}++ix3 :: Int -> Int -> Int -> DIM3+ix3 z y x = Z :. z :. y :. x+{-# INLINE ix3 #-}++ix4 :: Int -> Int -> Int -> Int -> DIM4+ix4 a z y x = Z :. a :. z :. y :. x+{-# INLINE ix4 #-}++ix5 :: Int -> Int -> Int -> Int -> Int -> DIM5+ix5 b a z y x = Z :. b :. a :. z :. y :. x+{-# INLINE ix5 #-}+++-- Shape ---------------------------------------------------------------------- instance Shape Z where 	{-# INLINE [1] rank #-} 	rank _			= 0
Data/Array/Repa/Operators/IndexSpace.hs view
@@ -4,10 +4,11 @@ 	( reshape 	, append, (++) 	, transpose-	, extend-	, slice+        , extract 	, backpermute,         unsafeBackpermute-	, backpermuteDft,      unsafeBackpermuteDft)+	, backpermuteDft,      unsafeBackpermuteDft+        , extend,              unsafeExtend +        , slice,               unsafeSlice) where import Data.Array.Repa.Index import Data.Array.Repa.Slice@@ -29,7 +30,6 @@ 	-> Array r1 sh1 e 	-> Array D  sh2 e -{-# INLINE [3] reshape #-} reshape sh2 arr 	| not $ S.size sh2 == S.size (extent arr) 	= error @@ -38,6 +38,7 @@ reshape sh2 arr         = fromFunction sh2          $ unsafeIndex arr . fromIndex (extent arr) . toIndex sh2+{-# INLINE [2] reshape #-}    -- | Append two arrays.@@ -48,7 +49,6 @@ 	-> Array r2 (sh :. Int) e 	-> Array D  (sh :. Int) e -{-# INLINE [3] append #-} append arr1 arr2  = unsafeTraverse2 arr1 arr2 fnExtent fnElem  where@@ -60,9 +60,11 @@ 	fnElem f1 f2 (sh :. i)       		| i < n		= f1 (sh :. i)   		| otherwise	= f2 (sh :. (i - n))+{-# INLINE [2] append #-} -{-# INLINE (++) #-}+ (++) arr1 arr2 = append arr1 arr2+{-# INLINE (++) #-}   -- | Transpose the lowest two dimensions of an array.@@ -73,45 +75,22 @@ 	=> Array r (sh :. Int :. Int) e 	-> Array D (sh :. Int :. Int) e -{-# INLINE [3] transpose #-} transpose arr  = unsafeTraverse arr 	(\(sh :. m :. n) 	-> (sh :. n :.m)) 	(\f -> \(sh :. i :. j) 	-> f (sh :. j :. i))+{-# INLINE [2] transpose #-}  --- | Extend an array, according to a given slice specification.-extend-	:: ( Slice sl-	   , Shape (FullShape sl)-	   , Shape (SliceShape sl)-	   , Repr r e)-	=> sl-	-> Array r (SliceShape sl) e-	-> Array D (FullShape sl)  e--{-# INLINE [3] extend #-}-extend sl arr-	= unsafeBackpermute-		(fullOfSlice sl (extent arr))-		(sliceOfFull sl)-		arr---- | Take a slice from an array, according to a given specification.-slice	:: ( Slice sl-	   , Shape (FullShape sl)-	   , Shape (SliceShape sl)-	   , Repr r e)-	=> Array r (FullShape sl) e-	-> sl-	-> Array D (SliceShape sl) e--{-# INLINE [3] slice #-}-slice arr sl-	= unsafeBackpermute-		(sliceOfFull sl (extent arr))-		(fullOfSlice sl)-		arr+-- | Extract a sub-range of elements from an array.+extract :: (Shape sh, Repr r e)+        => sh                   -- ^ Starting index.+        -> sh                   -- ^ Size of result.+        -> Array r sh e +        -> Array D sh e+extract start sz arr+        = fromFunction sz (\ix -> arr `unsafeIndex` (addDim start ix))+{-# INLINE [2] extract #-}   -- | Backwards permutation of an array's elements.@@ -126,13 +105,13 @@ 	-> Array r  sh1 e 	-- ^ Source array. 	-> Array D  sh2 e -{-# INLINE [3] backpermute #-} backpermute newExtent perm arr 	= traverse arr (const newExtent) (. perm)+{-# INLINE [2] backpermute #-} -{-# INLINE [3] unsafeBackpermute #-} unsafeBackpermute newExtent perm arr         = unsafeTraverse arr (const newExtent) (. perm)+{-# INLINE [2] unsafeBackpermute #-}   -- | Default backwards permutation of an array's elements.@@ -148,19 +127,85 @@ 	-> Array r1 sh1 e	-- ^ Source array. 	-> Array D  sh2 e -{-# INLINE [3] backpermuteDft #-} backpermuteDft arrDft fnIndex arrSrc 	= fromFunction (extent arrDft) fnElem 	where	fnElem ix 		 = case fnIndex ix of 			Just ix'	-> arrSrc `index` ix' 			Nothing		-> arrDft `index` ix+{-# INLINE [2] backpermuteDft #-} -{-# INLINE [3] unsafeBackpermuteDft #-} unsafeBackpermuteDft arrDft fnIndex arrSrc         = fromFunction (extent arrDft) fnElem         where   fnElem ix                  = case fnIndex ix of                         Just ix'        -> arrSrc `unsafeIndex` ix'                         Nothing         -> arrDft `unsafeIndex` ix+{-# INLINE [2] unsafeBackpermuteDft #-} +++-- | 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, unsafeExtend+        :: ( Slice sl+           , Shape (FullShape sl)+           , Shape (SliceShape sl)+           , Repr r e)+        => sl+        -> Array r (SliceShape sl) e+        -> Array D (FullShape sl)  e++extend sl arr+        = backpermute+                (fullOfSlice sl (extent arr))+                (sliceOfFull sl)+                arr+{-# INLINE [2] extend #-}++unsafeExtend sl arr+        = unsafeBackpermute+                (fullOfSlice sl (extent arr))+                (sliceOfFull sl)+                arr+{-# INLINE [2] unsafeExtend #-}++++-- | 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, unsafeSlice+        :: ( Slice sl+           , Shape (FullShape sl)+           , Shape (SliceShape sl)+           , Repr r e)+        => Array r (FullShape sl) e+        -> sl+        -> Array D (SliceShape sl) e++slice arr sl+        = backpermute+                (sliceOfFull sl (extent arr))+                (fullOfSlice sl)+                arr+{-# INLINE [2] slice #-}+++unsafeSlice arr sl+        = unsafeBackpermute+                (sliceOfFull sl (extent arr))+                (fullOfSlice sl)+                arr+{-# INLINE [2] unsafeSlice #-}
Data/Array/Repa/Operators/Interleave.hs view
@@ -29,7 +29,7 @@ 	-> Array r2 (sh :. Int) a 	-> Array D  (sh :. Int) a -{-# INLINE [3] interleave2 #-}+{-# INLINE [2] interleave2 #-} interleave2 arr1 arr2  = arr1 `deepSeqArray` arr2 `deepSeqArray`    unsafeTraverse2 arr1 arr2 shapeFn elemFn@@ -58,7 +58,7 @@ 	-> Array r3 (sh :. Int) a 	-> Array D  (sh :. Int) a -{-# INLINE [3] interleave3 #-}+{-# INLINE [2] interleave3 #-} interleave3 arr1 arr2 arr3  = arr1 `deepSeqArray` arr2 `deepSeqArray` arr3 `deepSeqArray`    unsafeTraverse3 arr1 arr2 arr3 shapeFn elemFn@@ -90,7 +90,7 @@ 	-> Array r4 (sh :. Int) a 	-> Array D  (sh :. Int) a -{-# INLINE [3] interleave4 #-}+{-# INLINE [2] interleave4 #-} interleave4 arr1 arr2 arr3 arr4  = arr1 `deepSeqArray` arr2 `deepSeqArray` arr3 `deepSeqArray` arr4 `deepSeqArray`    unsafeTraverse4 arr1 arr2 arr3 arr4 shapeFn elemFn
Data/Array/Repa/Operators/Mapping.hs view
@@ -27,7 +27,7 @@ -- map     :: (Shape sh, Repr r a)         => (a -> b) -> Array r sh a -> Array D sh b-{-# INLINE [4] map #-}+{-# INLINE [3] map #-} map f arr  = case delay arr of         ADelayed sh g -> ADelayed sh (f . g)@@ -42,7 +42,7 @@         => (a -> b -> c)         -> Array r1 sh a -> Array r2 sh b         -> Array D sh c-{-# INLINE [3] zipWith #-}+{-# INLINE [2] zipWith #-} zipWith f arr1 arr2  = arr1 `deepSeqArray` arr2 `deepSeqArray`    let @@ -112,11 +112,11 @@  -- Cursored --------------------------- instance Combine C a C b where- {-# INLINE [4] cmap #-}+ {-# INLINE [3] cmap #-}  cmap f (ACursored sh makec shiftc loadc)         = ACursored sh makec shiftc (f . loadc) - {-# INLINE [3] czipWith #-}+ {-# INLINE [2] czipWith #-}  czipWith f arr1 (ACursored sh makec shiftc loadc)   = let {-# INLINE makec' #-}         makec' ix               = (ix, makec ix)@@ -149,11 +149,11 @@         , Combine r12 a r22 b)        => Combine (P r11 r12) a (P r21 r22) b where - {-# INLINE [4] cmap #-}+ {-# INLINE [3] cmap #-}  cmap f (APart sh range arr1 arr2)         = APart sh range (cmap f arr1) (cmap f arr2) - {-# INLINE [3] czipWith #-}+ {-# INLINE [2] czipWith #-}  czipWith f arr1 (APart sh range arr21 arr22)         = APart sh range (czipWith f arr1 arr21)                          (czipWith f arr1 arr22)
Data/Array/Repa/Operators/Reduction.hs view
@@ -1,15 +1,17 @@ {-# LANGUAGE BangPatterns, ExplicitForAll, TypeOperators, MagicHash #-}-+{-# OPTIONS -fno-warn-orphans #-} module Data.Array.Repa.Operators.Reduction 	( foldS,        foldP 	, foldAllS,     foldAllP 	, sumS,         sumP-	, sumAllS,      sumAllP)+	, sumAllS,      sumAllP+        , equalsS,      equalsP) where import Data.Array.Repa.Base import Data.Array.Repa.Index-import Data.Array.Repa.Eval.Elt+import Data.Array.Repa.Eval import Data.Array.Repa.Repr.Unboxed+import Data.Array.Repa.Operators.Mapping        as R import Data.Array.Repa.Shape		        as S import qualified Data.Vector.Unboxed	        as V import qualified Data.Vector.Unboxed.Mutable    as M@@ -18,24 +20,26 @@ import System.IO.Unsafe import GHC.Exts --- foldS ----------------------------------------------------------------------+-- fold ---------------------------------------------------------------------- -- | Sequential reduction of the innermost dimension of an arbitrary rank array. -- --   Combine this with `transpose` to fold any other dimension.-foldS 	:: (Shape sh, Elt a, Unbox a, Repr r a)-	=> (a -> a -> a)-	-> a-	-> Array r (sh :. Int) a-	-> Array U sh a-{-# INLINE [2] foldS #-}+foldS   :: (Shape sh, Elt a, Unbox a, Repr r a)+        => (a -> a -> a)+        -> a+        -> Array r (sh :. Int) a+        -> Array U sh a+ foldS f z arr- = let  sh@(sz :. n') = extent arr+ = arr `deepSeqArray`+   let  sh@(sz :. n') = extent arr         !(I# n)       = n'    in unsafePerformIO     $ do mvec   <- M.unsafeNew (S.size sz)          E.foldS mvec (\ix -> arr `unsafeIndex` fromIndex sh (I# ix)) f z n          !vec   <- V.unsafeFreeze mvec-         return $ fromUnboxed sz vec+         now $ fromUnboxed sz vec+{-# INLINE [1] foldS #-}   -- | Parallel reduction of the innermost dimension of an arbitray rank array.@@ -45,27 +49,32 @@ --   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.-foldP 	:: (Shape sh, Elt a, Unbox a, Repr r a)-	=> (a -> a -> a)-	-> a-	-> Array r (sh :. Int) a-	-> Array U sh a-{-# INLINE [2] foldP #-}+foldP   +        :: (Shape sh, Elt a, Unbox a, Repr r a, Monad m)+        => (a -> a -> a)+        -> a+        -> Array r (sh :. Int) a+        -> m (Array U sh a)+ foldP f z arr - = let  sh@(sz :. n) = extent arr+ = arr `deepSeqArray`+   let  sh@(sz :. n) = extent arr    in   case rank sh of            -- specialise rank-1 arrays, else one thread does all the work.            -- We can't match against the shape constructor,            -- otherwise type error: (sz ~ Z)            ---           1 -> let !vec = V.singleton $ foldAllP f z arr-                in  fromUnboxed sz vec+           1 -> do+                x       <- foldAllP f z arr+                now $ fromUnboxed sz $ V.singleton x -           _ -> unsafePerformIO +           _ -> now+              $ unsafePerformIO                $ do mvec   <- M.unsafeNew (S.size sz)                    E.foldP mvec (\ix -> arr `unsafeIndex` fromIndex sh ix) f z n                    !vec   <- V.unsafeFreeze mvec-                   return $ fromUnboxed sz vec+                   now $ fromUnboxed sz vec+{-# INLINE [1] foldP #-}   -- foldAll --------------------------------------------------------------------@@ -76,7 +85,7 @@ 	-> a 	-> Array r sh a 	-> a-{-# INLINE [2] foldAllS #-}+ foldAllS f z arr   = arr `deepSeqArray`    let  !ex     = extent arr@@ -84,6 +93,7 @@    in   E.foldAllS                  (\ix -> arr `unsafeIndex` fromIndex ex (I# ix))                 f z n +{-# INLINE [1] foldAllS #-}   -- | Parallel reduction of an array of arbitrary rank to a single scalar value.@@ -93,17 +103,21 @@ --   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.-foldAllP :: (Shape sh, Elt a, Unbox a, Repr r a)-	 => (a -> a -> a)-	 -> a-	 -> Array r sh a-	 -> a-{-# INLINE [2] foldAllP #-}+foldAllP +        :: (Shape sh, Elt a, Unbox a, Repr r a, Monad m)+	=> (a -> a -> a)+	-> a+	-> Array r sh a+	-> m a+ foldAllP f z arr - = let  sh = extent arr+ = arr `deepSeqArray`+   let  sh = extent arr         n  = size sh-   in   unsafePerformIO +   in   return+         $ unsafePerformIO           $ E.foldAllP (\ix -> arr `unsafeIndex` fromIndex sh ix) f z n+{-# INLINE [1] foldAllP #-}   -- sum ------------------------------------------------------------------------@@ -111,16 +125,16 @@ sumS	:: (Shape sh, Num a, Elt a, Unbox a, Repr r a) 	=> Array r (sh :. Int) a 	-> Array U sh a-{-# INLINE [4] sumS #-} sumS = foldS (+) 0+{-# INLINE [3] sumS #-}  --- | Sequential sum the innermost dimension of an array.-sumP	:: (Shape sh, Num a, Elt a, Unbox a, Repr r a)+-- | Parallel sum the innermost dimension of an array.+sumP	:: (Shape sh, Num a, Elt a, Unbox a, Repr r a, Monad m) 	=> Array r (sh :. Int) a-	-> Array U sh a-{-# INLINE [4] sumP #-}-sumP = foldP (+) 0+	-> m (Array U sh a)+sumP = foldP (+) 0 +{-# INLINE [3] sumP #-}   -- sumAll ---------------------------------------------------------------------@@ -128,14 +142,43 @@ sumAllS	:: (Shape sh, Elt a, Unbox a, Num a, Repr r a) 	=> Array r sh a 	-> a-{-# INLINE [4] sumAllS #-} sumAllS = foldAllS (+) 0+{-# INLINE [3] sumAllS #-}   -- | Parallel sum all the elements of an array.-sumAllP	:: (Shape sh, Elt a, Unbox a, Num a, Repr r a)+sumAllP	:: (Shape sh, Elt a, Unbox a, Num a, Repr r a, Monad m) 	=> Array r sh a-	-> a-{-# INLINE [4] sumAllP #-}+	-> m a sumAllP = foldAllP (+) 0+{-# INLINE [3] sumAllP #-}+++-- Equality ------------------------------------------------------------------+instance (Shape sh, Repr r e, Eq e) => Eq (Array r sh e) where+ (==) arr1 arr2+        =   extent arr1 == extent arr2+        && (foldAllS (&&) True (R.zipWith (==) arr1 arr2))+++-- | Check whether two arrays have the same shape and contain equal elements,+--   in parallel.+equalsP :: (Shape sh, Repr r1 e, Repr r2 e, Eq e, Monad m) +        => Array r1 sh e +        -> Array r2 sh e+        -> m Bool+equalsP arr1 arr2+ = do   same    <- foldAllP (&&) True (R.zipWith (==) arr1 arr2)+        return  $ (extent arr1 == extent arr2) && same+++-- | Check whether two arrays have the same shape and contain equal elements,+--   sequentially.+equalsS :: (Shape sh, Repr r1 e, Repr r2 e, Eq e) +        => Array r1 sh e +        -> Array r2 sh e+        -> Bool+equalsS arr1 arr2+        =   extent arr1 == extent arr2+        && (foldAllS (&&) True (R.zipWith (==) arr1 arr2)) 
Data/Array/Repa/Operators/Selection.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE BangPatterns #-} module Data.Array.Repa.Operators.Selection-	(select)+	(selectP) where import Data.Array.Repa.Index import Data.Array.Repa.Base@@ -19,15 +19,15 @@ -- --   * Use the integer as the index into the array you're filtering. ---select	:: Unbox a+selectP	:: (Unbox a, Monad m)         => (Int -> Bool)	-- ^ If the Int matches this predicate, 	-> (Int -> a)		-- ^  ... then pass it to this fn to produce a value 	-> Int			-- ^ Range between 0 and this maximum.-	-> Array U DIM1 a	-- ^ Array containing produced values.+	-> m (Array U DIM1 a)	-- ^ Array containing produced values. -{-# INLINE [2] select #-}-select match produce len- = unsafePerformIO+selectP match produce len+ = return+ $ unsafePerformIO  $ do   (sh, vec)	<- selectIO 	return $ sh `seq` vec `seq` 	         fromUnboxed sh vec@@ -41,3 +41,4 @@ 		let result	= V.concat vecs'  		return	(Z :. V.length result, result)+{-# INLINE [1] selectP #-}
Data/Array/Repa/Operators/Traversal.hs view
@@ -20,15 +20,15 @@ 	 				--   It is passed a lookup function to get elements of the source. 	-> Array D sh' b -{-# INLINE [4] traverse #-} traverse arr transExtent newElem  = arr `deepSeqArray`     fromFunction (transExtent (extent arr)) (newElem (index arr))+{-# INLINE [3] traverse #-} -{-# INLINE [4] unsafeTraverse #-} unsafeTraverse arr transExtent newElem  = arr `deepSeqArray`    fromFunction (transExtent (extent arr)) (newElem (unsafeIndex arr))+{-# INLINE [3] unsafeTraverse #-}   -- | Unstructured traversal over two arrays at once.@@ -45,17 +45,17 @@ 					--   source arrays.         -> Array D sh'' c -{-# INLINE [4] traverse2 #-} traverse2 arrA arrB transExtent newElem  = arrA `deepSeqArray` arrB `deepSeqArray`    fromFunction  (transExtent (extent arrA) (extent arrB))  	         (newElem     (index  arrA) (index  arrB))+{-# INLINE [3] traverse2 #-} -{-# INLINE [4] unsafeTraverse2 #-} unsafeTraverse2 arrA arrB transExtent newElem  = arrA `deepSeqArray` arrB `deepSeqArray`    fromFunction  (transExtent (extent arrA) (extent arrB))                  (newElem     (unsafeIndex arrA) (unsafeIndex arrB))+{-# INLINE [3] unsafeTraverse2 #-}   -- | Unstructured traversal over three arrays at once.@@ -74,17 +74,17 @@            ->  sh4 -> d )         -> Array D sh4 d -{-# INLINE [4] traverse3 #-} traverse3 arrA arrB arrC transExtent newElem  = arrA `deepSeqArray` arrB `deepSeqArray` arrC `deepSeqArray`    fromFunction (transExtent (extent arrA) (extent arrB) (extent arrC))  	        (newElem     (index arrA)  (index arrB)  (index  arrC))+{-# INLINE [3] traverse3 #-} -{-# INLINE [4] unsafeTraverse3 #-} unsafeTraverse3 arrA arrB arrC transExtent newElem  = arrA `deepSeqArray` arrB `deepSeqArray` arrC `deepSeqArray`    fromFunction	(transExtent (extent arrA) (extent arrB) (extent arrC)) 	        (newElem     (unsafeIndex arrA) (unsafeIndex arrB) (unsafeIndex arrC))+{-# INLINE [3] unsafeTraverse3 #-}   -- | Unstructured traversal over four arrays at once.@@ -104,17 +104,17 @@            ->  sh5 -> e )         -> Array D sh5 e -{-# INLINE [4] traverse4 #-} traverse4 arrA arrB arrC arrD transExtent newElem  = arrA `deepSeqArray` arrB `deepSeqArray` arrC `deepSeqArray` arrD `deepSeqArray`    fromFunction	(transExtent (extent arrA) (extent arrB) (extent arrC) (extent arrD)) 		(newElem     (index  arrA) (index  arrB) (index  arrC) (index  arrD))+{-# INLINE [3] traverse4 #-}  -{-# INLINE [4] unsafeTraverse4 #-} unsafeTraverse4 arrA arrB arrC arrD transExtent newElem  = arrA `deepSeqArray` arrB `deepSeqArray` arrC `deepSeqArray` arrD `deepSeqArray`    fromFunction (transExtent (extent arrA) (extent arrB) (extent arrC) (extent arrD)) 		(newElem     (unsafeIndex arrA) (unsafeIndex arrB) (unsafeIndex arrC) (unsafeIndex arrD))+{-# INLINE [3] unsafeTraverse4 #-}  
Data/Array/Repa/Repr/ByteString.hs view
@@ -24,21 +24,21 @@ -- Repr ----------------------------------------------------------------------- -- | Read elements from a `ByteString`. instance Repr B Word8 where- {-# INLINE linearIndex #-}  linearIndex (AByteString _ bs) ix         = bs `B.index` ix+ {-# INLINE linearIndex #-} - {-# INLINE unsafeLinearIndex #-}  unsafeLinearIndex (AByteString _ bs) ix         = bs `BU.unsafeIndex` ix+ {-# INLINE unsafeLinearIndex #-} - {-# INLINE extent #-}  extent (AByteString sh _)         = sh+ {-# INLINE extent #-} - {-# INLINE deepSeqArray #-}  deepSeqArray (AByteString sh bs) x    = sh `deepSeq` bs `seq` x+ {-# INLINE deepSeqArray #-}   -- Conversions ----------------------------------------------------------------@@ -46,12 +46,12 @@ fromByteString         :: Shape sh         => sh -> ByteString -> Array B sh Word8-{-# INLINE fromByteString #-} fromByteString sh bs         = AByteString sh bs+{-# INLINE fromByteString #-}   -- | O(1). Unpack a `ByteString` from an array. toByteString :: Array B sh Word8 -> ByteString-{-# INLINE toByteString #-} toByteString (AByteString _ bs) = bs+{-# INLINE toByteString #-}
Data/Array/Repa/Repr/Cursored.hs view
@@ -12,6 +12,7 @@ import Data.Array.Repa.Eval.Elt import Data.Array.Repa.Eval.Cursored import GHC.Exts+import Debug.Trace  -- | Cursored Arrays. --   These are produced by Repa's stencil functions, and help the fusion@@ -39,63 +40,72 @@ -- Repr ----------------------------------------------------------------------- -- | Compute elements of a cursored array. instance Repr C a where- {-# INLINE index #-}  index (ACursored _ makec _ loadc)         = loadc . makec+ {-# INLINE index #-} - {-# INLINE unsafeIndex #-}  unsafeIndex    = index+ {-# INLINE unsafeIndex #-}  - {-# INLINE linearIndex #-}  linearIndex (ACursored sh makec _ loadc)         = loadc . makec . fromIndex sh+ {-# INLINE linearIndex #-} - {-# INLINE extent #-}  extent (ACursored sh _ _ _)         = sh+ {-# INLINE extent #-}         - {-# INLINE deepSeqArray #-}  deepSeqArray (ACursored sh makec shiftc loadc) y   = sh `deepSeq` makec  `seq` shiftc `seq` loadc `seq` y+ {-# INLINE deepSeqArray #-}   -- Fill ----------------------------------------------------------------------- -- | Compute all elements in an rank-2 array.  instance (Fillable r2 e, Elt e) => Fill C r2 DIM2 e where- {-# INLINE fillP #-}- fillP (ACursored (Z :. h :. w) makec shiftc loadc) marr-  = fillCursoredBlock2P + fillP (ACursored (Z :. (I# h) :. (I# w)) makec shiftc loadc) marr+  = do  traceEventIO "Repa.fillP[Cursored]: start"+        fillCursoredBlock2P                  (unsafeWriteMArr marr)                  makec shiftc loadc-                w 0 0 (w - 1) (h - 1) -- {-# INLINE fillS #-}+                w 0# 0# (w -# 1#) (h -# 1#) +        traceEventIO "Repa.fillP[Cursored]: end"+ {-# INLINE fillP #-}+          fillS (ACursored (Z :. (I# h) :. (I# w)) makec shiftc loadc) marr-  = fillCursoredBlock2S +  = do  traceEventIO "Repa.fillS[Cursored]: start"+        fillCursoredBlock2S                  (unsafeWriteMArr marr)                  makec shiftc loadc                 w 0# 0# (w -# 1#) (h -# 1#) -+        traceEventIO "Repa.fillS[Cursored]: end"+ {-# INLINE fillS #-}+          -- | Compute a range of elements in a rank-2 array. instance (Fillable r2 e, Elt e) => FillRange C r2 DIM2 e where- {-# INLINE fillRangeP #-}- fillRangeP  (ACursored (Z :. _h :. w) makec shiftc loadc) marr-             (Z :. y0 :. x0) (Z :. y1 :. x1)-  = fillCursoredBlock2P + fillRangeP  (ACursored (Z :. _h :. (I# w)) makec shiftc loadc) marr+             (Z :. (I# y0) :. (I# x0)) (Z :. (I# y1) :. (I# x1))+  = do  traceEventIO "Repa.fillRangeP[Cursored]: start"+        fillCursoredBlock2P                  (unsafeWriteMArr marr)                  makec shiftc loadc                 w x0 y0 x1 y1-- {-# INLINE fillRangeS #-}+        traceEventIO "Repa.fillRangeP[Cursored]: end"+ {-# INLINE fillRangeP #-}+          fillRangeS  (ACursored (Z :. _h :. (I# w)) makec shiftc loadc) marr              (Z :. (I# y0) :. (I# x0))               (Z :. (I# y1) :. (I# x1))-  = fillCursoredBlock2S+  = do  traceEventIO "Repa.fillRangeS[Cursored]: start"+        fillCursoredBlock2S                 (unsafeWriteMArr marr)                  makec shiftc loadc                 w x0 y0 x1 y1- +        traceEventIO "Repa.fillRangeS[Cursored]: end"+ {-# INLINE fillRangeS #-}+        + -- Conversions ---------------------------------------------------------------- -- | Define a new cursored array. makeCursored @@ -105,5 +115,6 @@         -> (cursor -> e)                -- ^ Compute the element at the cursor.         -> Array C sh e -{-# INLINE makeCursored #-} makeCursored = ACursored+{-# INLINE makeCursored #-}+
Data/Array/Repa/Repr/Delayed.hs view
@@ -11,9 +11,13 @@ import Data.Array.Repa.Index import Data.Array.Repa.Shape import Data.Array.Repa.Base+import Debug.Trace import GHC.Exts  -- | 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 data instance Array D sh e         = ADelayed  @@ -24,66 +28,79 @@ -- Repr ----------------------------------------------------------------------- -- | Compute elements of a delayed array. instance Repr D a where- {-# INLINE index #-}  index       (ADelayed _  f) ix  = f ix+ {-# INLINE index #-} - {-# INLINE linearIndex #-}  linearIndex (ADelayed sh f) ix  = f (fromIndex sh ix)+ {-# INLINE linearIndex #-} - {-# INLINE extent #-}  extent (ADelayed sh _)         = sh+ {-# INLINE extent #-} - {-# INLINE deepSeqArray #-}  deepSeqArray (ADelayed sh f) y         = sh `deepSeq` f `seq` y+ {-# INLINE deepSeqArray #-}   -- Fill ----------------------------------------------------------------------- -- | Compute all elements in an array. instance (Fillable r2 e, Shape sh) => Fill D r2 sh e where- {-# INLINE [4] fillP #-}  fillP (ADelayed sh getElem) marr-  = fillChunkedP (size sh) (unsafeWriteMArr marr) (getElem . fromIndex sh) +  = marr `deepSeqMArr` +    do  traceEventIO "Repa.fillP[Delayed]: start"+        fillChunkedP (size sh) (unsafeWriteMArr marr) (getElem . fromIndex sh) +        traceEventIO "Repa.fillP[Delayed]: end"+ {-# INLINE [4] fillP #-} - {-# INLINE [4] fillS #-}  fillS (ADelayed sh getElem) marr-  = fillChunkedS (size sh) (unsafeWriteMArr marr) (getElem . fromIndex sh)+  = marr `deepSeqMArr` +    do  traceEventIO "Repa.fillS[Delayed]: start"+        fillChunkedS (size sh) (unsafeWriteMArr marr) (getElem . fromIndex sh)+        traceEventIO "Repa.fillS[Delayed]: end"+ {-# INLINE [4] fillS #-}   -- | Compute a range of elements in a rank-2 array. instance (Fillable r2 e, Elt e) => FillRange D r2 DIM2 e where+ fillRangeP  (ADelayed (Z :. _h :. (I# w)) getElem) marr+             (Z :. (I# y0) :. (I# x0)) (Z :. (I# y1) :. (I# x1))+  = marr `deepSeqMArr` +    do  traceEventIO "Repa.fillRangeP[Delayed]: start"+        fillBlock2P (unsafeWriteMArr marr) +                        getElem+                        w x0 y0 x1 y1+        traceEventIO "Repa.fillRangeP[Delayed]: end"  {-# INLINE [1] fillRangeP #-}- fillRangeP  (ADelayed (Z :. _h :. w) getElem) marr-             (Z :. y0 :. x0) (Z :. y1 :. x1)-  = fillBlock2P (unsafeWriteMArr marr) -                getElem-                w x0 y0 x1 y1 - {-# INLINE [1] fillRangeS #-}  fillRangeS  (ADelayed (Z :. _h :. (I# w)) getElem) marr              (Z :. (I# y0) :. (I# x0)) (Z :. (I# y1) :. (I# x1))-  = fillBlock2S (unsafeWriteMArr marr) +  = marr `deepSeqMArr`+    do  traceEventIO "Repa.fillRangeS[Delayed]: start"+        fillBlock2S (unsafeWriteMArr marr)                  getElem                 w x0 y0 x1 y1+        traceEventIO "Repa.fillRangeS[Delayed]: end"+ {-# INLINE [1] fillRangeS #-}   -- Conversions ---------------------------------------------------------------- -- | O(1). Wrap a function as a delayed array. fromFunction :: sh -> (sh -> a) -> Array D sh a-{-# INLINE fromFunction #-} fromFunction sh f          = ADelayed sh f +{-# INLINE fromFunction #-}  --- | O(1). Produce the extent of an array and a function to retrieve an arbitrary element.+-- | O(1). Produce the extent of an array, and a function to retrieve an+--   arbitrary element. toFunction          :: (Shape sh, Repr r1 a)         => Array r1 sh a -> (sh, sh -> a)-{-# INLINE toFunction #-} toFunction arr  = case delay arr of         ADelayed sh f -> (sh, f)+{-# INLINE toFunction #-}   -- | O(1). Delay an array.@@ -93,7 +110,7 @@ -- delay   :: (Shape sh, Repr r e)         => Array r sh e -> Array D sh e+delay arr = ADelayed (extent arr) (unsafeIndex arr) {-# INLINE delay #-}-delay arr = ADelayed (extent arr) (index arr)  
Data/Array/Repa/Repr/ForeignPtr.hs view
@@ -12,6 +12,7 @@ import Foreign.ForeignPtr import Foreign.Marshal.Alloc import System.IO.Unsafe+import qualified Foreign.ForeignPtr.Unsafe      as Unsafe  -- | Arrays represented as foreign buffers in the C heap. data F@@ -21,7 +22,6 @@ -- Repr ----------------------------------------------------------------------- -- | Read elements from a foreign buffer. instance Storable a => Repr F a where- {-# INLINE linearIndex #-}  linearIndex (AForeignPtr _ len fptr) ix   | ix < len           = unsafePerformIO @@ -30,21 +30,22 @@      | otherwise   = error "Repa: foreign array index out of bounds"-- {-# INLINE unsafeLinearIndex #-}+ {-# INLINE linearIndex #-}+   unsafeLinearIndex (AForeignPtr _ _ fptr) ix         = unsafePerformIO         $ withForeignPtr fptr          $ \ptr -> peekElemOff ptr ix+ {-# INLINE unsafeLinearIndex #-} - {-# INLINE extent #-}  extent (AForeignPtr sh _ _)         = sh+ {-# INLINE extent #-} - {-# INLINE deepSeqArray #-}  deepSeqArray (AForeignPtr sh len fptr) x    = sh `deepSeq` len `seq` fptr `seq` x-+ {-# INLINE deepSeqArray #-}+   -- Fill ----------------------------------------------------------------------- -- | Filling of foreign buffers.@@ -52,7 +53,6 @@  data MArr F e    = FPArr !Int !(ForeignPtr e) - {-# INLINE newMArr #-}  newMArr n   = do  let (proxy :: e) = undefined         ptr              <- mallocBytes (sizeOf proxy * n)@@ -60,32 +60,36 @@                  fptr             <- newForeignPtr finalizerFree ptr         return           $ FPArr n fptr+ {-# INLINE newMArr #-} - {-# INLINE unsafeWriteMArr #-}  unsafeWriteMArr (FPArr _ fptr) !ix !x-  = withForeignPtr fptr-  $ \ptr -> pokeElemOff ptr ix x+  = pokeElemOff (Unsafe.unsafeForeignPtrToPtr fptr) ix x+ {-# INLINE unsafeWriteMArr #-} - {-# INLINE unsafeFreezeMArr #-}  unsafeFreezeMArr !sh (FPArr len fptr)        =     return  $ AForeignPtr sh len fptr+ {-# INLINE unsafeFreezeMArr #-} + deepSeqMArr !(FPArr _ ptr) x+  = Unsafe.unsafeForeignPtrToPtr ptr `seq` x+ {-# INLINE deepSeqMArr #-} + -- Conversions ---------------------------------------------------------------- -- | O(1). Wrap a `ForeignPtr` as an array. fromForeignPtr         :: Shape sh         => sh -> ForeignPtr e -> Array F sh e-{-# INLINE fromForeignPtr #-} fromForeignPtr !sh !fptr         = AForeignPtr sh (size sh) fptr+{-# INLINE fromForeignPtr #-}   -- | O(1). Unpack a `ForeignPtr` from an array. toForeignPtr :: Array F sh e -> ForeignPtr e-{-# INLINE toForeignPtr #-} toForeignPtr (AForeignPtr _ _ fptr)         = fptr+{-# INLINE toForeignPtr #-}   -- | Compute an array sequentially and write the elements into a foreign@@ -94,9 +98,9 @@ computeIntoS         :: Fill r1 F sh e         => ForeignPtr e -> Array r1 sh e -> IO ()-{-# INLINE computeIntoS #-} computeIntoS !fptr !arr  = fillS arr (FPArr 0 fptr)+{-# INLINE computeIntoS #-}   -- | Compute an array in parallel and write the elements into a foreign@@ -105,7 +109,7 @@ computeIntoP         :: Fill r1 F sh e         => ForeignPtr e -> Array r1 sh e -> IO ()-{-# INLINE computeIntoP #-} computeIntoP !fptr !arr  = fillP arr (FPArr 0 fptr)+{-# INLINE computeIntoP #-} 
Data/Array/Repa/Repr/Partitioned.hs view
@@ -34,49 +34,49 @@                 (sh -> Bool)               -- predicate to check whether were in range  -- | Check whether an index is within the given range.-{-# INLINE inRange #-} inRange :: Range sh -> sh -> Bool inRange (Range _ _ p) ix         = p ix+{-# INLINE inRange #-}   -- Repr ----------------------------------------------------------------------- -- | Read elements from a partitioned array. instance (Repr r1 e, Repr r2 e) => Repr (P r1 r2) e where- {-# INLINE index #-}  index (APart _ range arr1 arr2) ix    | inRange range ix   = index arr1 ix    | otherwise          = index arr2 ix+ {-# INLINE index #-} - {-# INLINE linearIndex #-}  linearIndex arr@(APart sh _ _ _) ix         = index arr $ fromIndex sh ix+ {-# INLINE linearIndex #-} - {-# INLINE extent #-}  extent (APart sh _ _ _)          = sh+ {-# INLINE extent #-} - {-# INLINE deepSeqArray #-}  deepSeqArray (APart sh range arr1 arr2) y   = sh `deepSeq` range `deepSeqRange` arr1 `deepSeqArray` arr2 `deepSeqArray` y+ {-# INLINE deepSeqArray #-}  -{-# INLINE deepSeqRange #-} deepSeqRange :: Shape sh => Range sh -> b -> b deepSeqRange (Range low high f) y         = low `deepSeq` high `deepSeq` f `seq` y+{-# INLINE deepSeqRange #-}   -- Fill ----------------------------------------------------------------------- instance ( FillRange r1 r3 sh e, Fill r2 r3 sh e          , Fillable r3 e)         => Fill (P r1 r2) r3 sh e where- {-# INLINE fillP #-}  fillP (APart _ (Range ix10 ix11 _) arr1 arr2) marr   = do  fillRangeP arr1 marr ix10 ix11         fillP arr2 marr+ {-# INLINE fillP #-} - {-# INLINE fillS #-}  fillS (APart _ (Range ix10 ix11 _) arr1 arr2) marr   = do  fillRangeS arr1 marr ix10 ix11         fillS arr2 marr+ {-# INLINE fillS #-}
Data/Array/Repa/Repr/Unboxed.hs view
@@ -19,10 +19,11 @@  -- | Unboxed arrays are represented as unboxed vectors. -----   The implementation of `Data.Vector.Unboxed` 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.+--   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 data instance U.Unbox e => Array U sh e@@ -34,21 +35,21 @@ -- Repr ----------------------------------------------------------------------- -- | Read elements from an unboxed vector array. instance U.Unbox a => Repr U a where- {-# INLINE linearIndex #-}  linearIndex (AUnboxed _ vec) ix         = vec U.! ix+ {-# INLINE linearIndex #-} - {-# INLINE unsafeLinearIndex #-}  unsafeLinearIndex (AUnboxed _ vec) ix         = vec `U.unsafeIndex` ix+ {-# INLINE unsafeLinearIndex #-} - {-# INLINE extent #-}  extent (AUnboxed sh _)         = sh+ {-# INLINE extent #-} - {-# INLINE deepSeqArray #-}  deepSeqArray (AUnboxed sh vec) x    = sh `deepSeq` vec `seq` x+ {-# INLINE deepSeqArray #-}   -- Fill -----------------------------------------------------------------------@@ -57,20 +58,24 @@  data MArr U e    = UMArr (UM.IOVector e) - {-# INLINE newMArr #-}  newMArr n   = liftM UMArr (UM.new n)+ {-# INLINE newMArr #-} - {-# INLINE unsafeWriteMArr #-}  unsafeWriteMArr (UMArr v) ix   = UM.unsafeWrite v ix+ {-# INLINE unsafeWriteMArr #-} - {-# INLINE unsafeFreezeMArr #-}  unsafeFreezeMArr sh (UMArr mvec)        = do  vec     <- U.unsafeFreeze mvec         return  $  AUnboxed sh vec+ {-# INLINE unsafeFreezeMArr #-} + deepSeqMArr (UMArr vec) x+  = vec `seq` x+ {-# INLINE deepSeqMArr #-} + -- Conversions ---------------------------------------------------------------- -- | Sequential computation of array elements.. --@@ -79,8 +84,8 @@ computeUnboxedS         :: Fill r1 U sh e         => Array r1 sh e -> Array U sh e-{-# INLINE computeUnboxedS #-} computeUnboxedS = computeS+{-# INLINE computeUnboxedS #-}   -- | Parallel computation of array elements.@@ -88,10 +93,10 @@ --   * This is an alias for `computeP` with a more specific type. -- computeUnboxedP-        :: Fill r1 U sh e-        => Array r1 sh e -> Array U sh e-{-# INLINE computeUnboxedP #-}+        :: (Fill r1 U sh e, Monad m, U.Unbox e)+        => Array r1 sh e -> m (Array U sh e) computeUnboxedP = computeP+{-# INLINE computeUnboxedP #-}   -- | O(n). Convert a list to an unboxed vector array.@@ -101,37 +106,38 @@ fromListUnboxed         :: (Shape sh, U.Unbox a)         => sh -> [a] -> Array U sh a-{-# INLINE fromListUnboxed #-} fromListUnboxed = R.fromList+{-# INLINE fromListUnboxed #-}   -- | O(1). Wrap an unboxed vector as an array. fromUnboxed         :: (Shape sh, U.Unbox e)         => sh -> U.Vector e -> Array U sh e-{-# INLINE fromUnboxed #-} fromUnboxed sh vec         = AUnboxed sh vec+{-# INLINE fromUnboxed #-}   -- | O(1). Unpack an unboxed vector from an array. toUnboxed         :: U.Unbox e         => Array U sh e -> U.Vector e-{-# INLINE toUnboxed #-} toUnboxed (AUnboxed _ vec)         = vec+{-# INLINE toUnboxed #-} + -- Zip ------------------------------------------------------------------------ -- | O(1). Zip some unboxed arrays. --         The shapes must be identical else `error`. zip     :: (Shape sh, U.Unbox a, U.Unbox b)         => Array U sh a -> Array U sh b         -> Array U sh (a, b)-{-# INLINE zip #-} zip (AUnboxed sh1 vec1) (AUnboxed sh2 vec2)  | sh1 /= sh2   = error "Repa: zip array shapes not identical"  | otherwise    = AUnboxed sh1 (U.zip vec1 vec2)+{-# INLINE zip #-}   -- | O(1). Zip some unboxed arrays.@@ -139,11 +145,11 @@ zip3    :: (Shape sh, U.Unbox a, U.Unbox b, U.Unbox c)         => Array U sh a -> Array U sh b -> Array U sh c         -> Array U sh (a, b, c)-{-# INLINE zip3 #-} zip3 (AUnboxed sh1 vec1) (AUnboxed sh2 vec2) (AUnboxed sh3 vec3)  | sh1 /= sh2 || sh1 /= sh3  = error "Repa: zip array shapes not identical"  | otherwise    = AUnboxed sh1 (U.zip3 vec1 vec2 vec3)+{-# INLINE zip3 #-}   -- | O(1). Zip some unboxed arrays.@@ -151,11 +157,11 @@ zip4    :: (Shape sh, U.Unbox a, U.Unbox b, U.Unbox c, U.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)-{-# INLINE zip4 #-} zip4 (AUnboxed sh1 vec1) (AUnboxed sh2 vec2) (AUnboxed sh3 vec3) (AUnboxed sh4 vec4)  | sh1 /= sh2 || sh1 /= sh3 || sh1 /= sh4  = error "Repa: zip array shapes not identical"  | otherwise    = AUnboxed sh1 (U.zip4 vec1 vec2 vec3 vec4)+{-# INLINE zip4 #-}   -- | O(1). Zip some unboxed arrays.@@ -163,11 +169,11 @@ zip5    :: (Shape sh, U.Unbox a, U.Unbox b, U.Unbox c, U.Unbox d, U.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)-{-# INLINE zip5 #-} zip5 (AUnboxed sh1 vec1) (AUnboxed sh2 vec2) (AUnboxed sh3 vec3) (AUnboxed sh4 vec4) (AUnboxed sh5 vec5)  | sh1 /= sh2 || sh1 /= sh3 || sh1 /= sh4 || sh1 /= sh5  = error "Repa: zip array shapes not identical"  | otherwise    = AUnboxed sh1 (U.zip5 vec1 vec2 vec3 vec4 vec5)+{-# INLINE zip5 #-}   -- | O(1). Zip some unboxed arrays.@@ -175,11 +181,11 @@ zip6    :: (Shape sh, U.Unbox a, U.Unbox b, U.Unbox c, U.Unbox d, U.Unbox e, U.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)-{-# INLINE zip6 #-} zip6 (AUnboxed sh1 vec1) (AUnboxed sh2 vec2) (AUnboxed sh3 vec3) (AUnboxed sh4 vec4) (AUnboxed sh5 vec5) (AUnboxed sh6 vec6)  | sh1 /= sh2 || sh1 /= sh3 || sh1 /= sh4 || sh1 /= sh5 || sh1 /= sh6  = error "Repa: zip array shapes not identical"  | otherwise    = AUnboxed sh1 (U.zip6 vec1 vec2 vec3 vec4 vec5 vec6)+{-# INLINE zip6 #-}    -- Unzip ----------------------------------------------------------------------@@ -187,47 +193,47 @@ unzip   :: (U.Unbox a, U.Unbox b)         => Array U sh (a, b)         -> (Array U sh a, Array U sh b)-{-# INLINE unzip #-} unzip (AUnboxed sh vec)  = let  (as, bs)        = U.unzip vec    in   (AUnboxed sh as, AUnboxed sh bs)+{-# INLINE unzip #-}   -- | O(1). Unzip an unboxed array. unzip3   :: (U.Unbox a, U.Unbox b, U.Unbox c)         => Array U sh (a, b, c)         -> (Array U sh a, Array U sh b, Array U sh c)-{-# INLINE unzip3 #-} unzip3 (AUnboxed sh vec)  = let  (as, bs, cs) = U.unzip3 vec    in   (AUnboxed sh as, AUnboxed sh bs, AUnboxed sh cs)+{-# INLINE unzip3 #-}   -- | O(1). Unzip an unboxed array. unzip4   :: (U.Unbox a, U.Unbox b, U.Unbox c, U.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)-{-# INLINE unzip4 #-} unzip4 (AUnboxed sh vec)  = let  (as, bs, cs, ds) = U.unzip4 vec    in   (AUnboxed sh as, AUnboxed sh bs, AUnboxed sh cs, AUnboxed sh ds)+{-# INLINE unzip4 #-}   -- | O(1). Unzip an unboxed array. unzip5   :: (U.Unbox a, U.Unbox b, U.Unbox c, U.Unbox d, U.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)-{-# INLINE unzip5 #-} unzip5 (AUnboxed sh vec)  = let  (as, bs, cs, ds, es) = U.unzip5 vec    in   (AUnboxed sh as, AUnboxed sh bs, AUnboxed sh cs, AUnboxed sh ds, AUnboxed sh es)+{-# INLINE unzip5 #-}   -- | O(1). Unzip an unboxed array. unzip6  :: (U.Unbox a, U.Unbox b, U.Unbox c, U.Unbox d, U.Unbox e, U.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)-{-# INLINE unzip6 #-} unzip6 (AUnboxed sh vec)  = let  (as, bs, cs, ds, es, fs) = U.unzip6 vec    in   (AUnboxed sh as, AUnboxed sh bs, AUnboxed sh cs, AUnboxed sh ds, AUnboxed sh es, AUnboxed sh fs)+{-# INLINE unzip6 #-}
Data/Array/Repa/Repr/Undefined.hs view
@@ -19,19 +19,19 @@ -- | Undefined array elements. Inspecting them yields `error`. -- instance Repr X e where- {-# INLINE deepSeqArray #-}  deepSeqArray _ x         = x+ {-# INLINE deepSeqArray #-} - {-# INLINE extent #-}  extent (AUndefined sh)          = sh+ {-# INLINE extent #-} - {-# INLINE index #-}  index (AUndefined _) _        = error "Repa: array element is undefined."+ {-# INLINE index #-}         - {-# INLINE linearIndex #-}  linearIndex (AUndefined _) _  = error "Repa: array element is undefined."+ {-# INLINE linearIndex #-}    instance (Shape sh, Fillable r2 e, Num e) => Fill X r2 sh e where
Data/Array/Repa/Repr/Vector.hs view
@@ -28,21 +28,21 @@ -- Repr ----------------------------------------------------------------------- -- | Read elements from a boxed vector array. instance Repr V a where- {-# INLINE linearIndex #-}  linearIndex (AVector _ vec) ix         = vec V.! ix+ {-# INLINE linearIndex #-} - {-# INLINE unsafeLinearIndex #-}  unsafeLinearIndex (AVector _ vec) ix         = vec `V.unsafeIndex` ix+ {-# INLINE unsafeLinearIndex #-} - {-# INLINE extent #-}  extent (AVector sh _)         = sh+ {-# INLINE extent #-} - {-# INLINE deepSeqArray #-}  deepSeqArray (AVector sh vec) x    = sh `deepSeq` vec `seq` x+ {-# INLINE deepSeqArray #-}   -- Fill -----------------------------------------------------------------------@@ -51,19 +51,22 @@  data MArr V e    = MVec (VM.IOVector e) - {-# INLINE newMArr #-}  newMArr n   = liftM MVec (VM.new n)+ {-# INLINE newMArr #-} - {-# INLINE unsafeWriteMArr #-}  unsafeWriteMArr (MVec v) ix   = VM.unsafeWrite v ix+ {-# INLINE unsafeWriteMArr #-} - {-# INLINE unsafeFreezeMArr #-}  unsafeFreezeMArr sh (MVec mvec)        = do  vec     <- V.unsafeFreeze mvec         return  $  AVector sh vec+ {-# INLINE unsafeFreezeMArr #-} + deepSeqMArr !_vec x+  = x+ {-# INLINE deepSeqMArr #-}  -- Conversions ---------------------------------------------------------------- -- | Sequential computation of array elements.@@ -73,16 +76,16 @@ computeVectorS         :: Fill r1 V sh e         => Array r1 sh e -> Array V sh e-{-# INLINE computeVectorS #-} computeVectorS   = computeS+{-# INLINE computeVectorS #-}   -- | Parallel computation of array elements. computeVectorP-        :: Fill r1 V sh e-        => Array r1 sh e -> Array V sh e-{-# INLINE computeVectorP #-}+        :: (Fill r1 V sh e, Monad m)+        => Array r1 sh e -> m (Array V sh e) computeVectorP   = computeP+{-# INLINE computeVectorP #-}   -- | O(n). Convert a list to a boxed vector array.@@ -90,23 +93,23 @@ --   * This is an alias for `fromList` with a more specific type. -- fromListVector :: Shape sh => sh -> [a] -> Array V sh a-{-# INLINE fromListVector #-} fromListVector  = fromList+{-# INLINE fromListVector #-}   -- | O(1). Wrap a boxed vector as an array. fromVector         :: Shape sh         => sh -> V.Vector e -> Array V sh e-{-# INLINE fromVector #-} fromVector sh vec         = AVector sh vec+{-# INLINE fromVector #-}   -- | O(1). Unpack a boxed vector from an array. toVector :: Array V sh e -> V.Vector e-{-# INLINE toVector #-} toVector (AVector _ vec)         = vec+{-# INLINE toVector #-}  
Data/Array/Repa/Specialised/Dim2.hs view
@@ -8,6 +8,7 @@ 	, makeBordered2) where import Data.Array.Repa.Index+import Data.Array.Repa.Base import Data.Array.Repa.Repr.Partitioned import Data.Array.Repa.Repr.Undefined @@ -70,10 +71,9 @@ --   The two arrays must have the same extent. --   The border must be the same width on all sides. -----   TODO: Check arrays have same extent.--- makeBordered2-	:: DIM2			-- ^ Extent of array.+	:: (Repr r1 a, Repr r2 a)+        => DIM2			-- ^ Extent of array. 	-> Int			-- ^ Width of border. 	-> Array r1 DIM2 a	-- ^ Array for internal elements. 	-> Array r2 DIM2 a	-- ^ Array for border elements.@@ -81,21 +81,21 @@  {-# INLINE makeBordered2 #-} makeBordered2 sh@(_ :. aHeight :. aWidth) borderWidth arrInternal arrBorder- = let+ = checkDims `seq` +   let 	-- minimum and maximum indicies of values in the inner part of the image. 	!xMin		= borderWidth 	!yMin		= borderWidth 	!xMax		= aWidth  - borderWidth  - 1 	!yMax		= aHeight - borderWidth - 1 --	{-# INLINE inInternal #-} 	inInternal (Z :. y :. x) 		=  x >= xMin && x <= xMax 		&& y >= yMin && y <= yMax+        {-# INLINE inInternal #-} -	{-# INLINE inBorder #-} 	inBorder 	= not . inInternal+        {-# INLINE inBorder #-}     in	     --  internal region@@ -107,3 +107,11 @@     $   APart sh (Range (Z :. yMin     :. 0)        (Z :. yMax           :. xMin - 1)   inBorder)   arrBorder     $   APart sh (Range (Z :. yMin     :. xMax + 1) (Z :. yMax           :. aWidth - 1) inBorder)   arrBorder     $   AUndefined sh++ where+        checkDims+         = if (extent arrInternal) == (extent arrBorder)+                then ()+                else error "makeBordered2: internal and border arrays have different extents"+        {-# NOINLINE checkDims #-}+        --  NOINLINE because we don't want the branch in the core code.
Data/Array/Repa/Stencil/Dim2.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE MagicHash #-} --   This is specialised for stencils up to 7x7. --   Due to limitations in the GHC optimiser, using larger stencils doesn't --   work, and will yield `error` at runtime. We can probably increase the@@ -23,6 +24,7 @@ import Data.Array.Repa.Repr.Undefined import Data.Array.Repa.Stencil.Base import Data.Array.Repa.Stencil.Template+import GHC.Exts  -- | A index into the flat array. --   Should be abstract outside the stencil modules.@@ -167,34 +169,34 @@ 	   (StencilStatic sExtent zero loads) 	   arr cur -	| _ :. sHeight :. sWidth	<- sExtent-	, _ :. aHeight :. aWidth	<- extent arr+	| _ :. sHeight      :. sWidth	    <- sExtent+	, _ :. (I# aHeight) :. (I# aWidth)  <- extent arr 	, sHeight <= 7, sWidth <= 7 	= let 		-- Get data from the manifest array. 		{-# INLINE getData #-} 		getData :: DIM2 -> a-		getData (Z :. y :. x)+		getData (Z :. (I# y) :. (I# x)) 		 = wrapLoadX x y -		-- TODO: Inlining this into above makes SpecConstr choke-		wrapLoadX :: Int -> Int -> a+                {-# NOINLINE wrapLoadX #-}+		wrapLoadX :: Int# -> Int# -> a 		wrapLoadX !x !y-		 | x < 0	= wrapLoadY 0      	 y-		 | x >= aWidth	= wrapLoadY (aWidth - 1) y+		 | x <# 0#	= wrapLoadY 0#      	   y+		 | x >=# aWidth	= wrapLoadY (aWidth -# 1#) y 		 | otherwise    = wrapLoadY x y -		{-# INLINE wrapLoadY #-}-		wrapLoadY :: Int -> Int -> a+		{-# NOINLINE wrapLoadY #-}+		wrapLoadY :: Int# -> Int# -> a 		wrapLoadY !x !y-		 | y <  0	= loadXY x 0-		 | y >= aHeight = loadXY x (aHeight - 1)-		 | otherwise    = loadXY x y+		 | y <#  0#	 = loadXY x 0#+		 | y >=# aHeight = loadXY x (aHeight -# 1#)+		 | otherwise     = loadXY x y  		{-# INLINE loadXY #-}-		loadXY :: Int -> Int -> a+		loadXY :: Int# -> Int# -> a 		loadXY !x !y-		 = arr `unsafeIndex` (Z :. y :.  x)+		 = arr `unsafeIndex` (Z :. (I# y) :.  (I# x))  		-- Build a function to pass data from the array to our stencil. 		{-# INLINE oload #-}
+ Data/Array/Repa/Unsafe.hs view
@@ -0,0 +1,14 @@++-- | Functions without sanity or bounds checks.+module Data.Array.Repa.Unsafe+        ( unsafeBackpermute+        , unsafeBackpermuteDft+        , unsafeSlice+        , unsafeExtend+        , unsafeTraverse+        , unsafeTraverse2+        , unsafeTraverse3+        , unsafeTraverse4)+where+import Data.Array.Repa.Operators.IndexSpace+import Data.Array.Repa.Operators.Traversal
repa.cabal view
@@ -1,5 +1,5 @@ Name:                repa-Version:             3.0.0.1+Version:             3.1.0.1 License:             BSD3 License-file:        LICENSE Author:              The DPH Team@@ -72,6 +72,7 @@         Data.Array.Repa.Shape         Data.Array.Repa.Slice         Data.Array.Repa.Stencil+        Data.Array.Repa.Unsafe         Data.Array.Repa    Other-modules: