packages feed

repa 3.1.4.2 → 3.2.1.1

raw patch · 25 files changed

+617/−514 lines, 25 files

Files

Data/Array/Repa.hs view
@@ -1,6 +1,8 @@ {-# OPTIONS -fno-warn-unused-imports #-} -- | Repa arrays are wrappers around a linear structure that holds the element---   data. The representation tag determines what structure holds the data.+--   data. +-- +--  The representation tag determines what structure holds the data. -- --   Delayed Representations (functions that compute elements) --@@ -65,7 +67,7 @@ --     This is less of a problem for general Haskell code, and in a different --     context relying on strictness analysis is fine. -----  5. Scheduling a parallel computation takes about 200us on an OSX machine. +--  5. 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@@ -87,13 +89,24 @@ -- --  8. When you're sure your program works, switch to the unsafe versions --     of functions like `traverse`. These don't do bounds checks.--- +--+-- /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. Also renamed `MArray` -> `MVec` to emphasise its linear structure.+--+--  3. Made `Array` and `MVec` associated types of `Source` and `Target` respectively.+--+--  4. Added the `S` (Smallness) and `I` (Interleave) hints.+-- module Data.Array.Repa         ( -- * Abstract array representation           module Data.Array.Repa.Shape         , module Data.Array.Repa.Index-        , Array(..)-        , Repr(..), (!), toList+        , Array (..)+        , Source(..), (!), toList         , deepSeqArrays          -- * Computation@@ -132,7 +145,7 @@ 	, map 	, zipWith 	, (+^), (-^), (*^), (/^)-        , Combine(..)+        , Structured(..)  	-- from Data.Array.Repa.Operators.Traversal ------------------ 	-- ** Generic traversal
Data/Array/Repa/Base.hs view
@@ -1,26 +1,24 @@  module Data.Array.Repa.Base-        ( Array-        , Repr (..), (!), toList+        ( Source (..), (!), toList         , deepSeqArrays) where import Data.Array.Repa.Shape --- | Arrays with a representation tag, shape, and element type.---   Use one of the type tags like `D`, `U` and so on for @r@, ---   one of `DIM1`, `DIM2` ... for @sh@.-data family Array r sh e ---- Repr -----------------------------------------------------------------------+-- Source ----------------------------------------------------------------------- -- | Class of array representations that we can read elements from.----class Repr r e where+class Source r e where+ -- Arrays with a representation tag, shape, and element type.+ --   Use one of the type tags like `D`, `U` and so on for @r@, + --   one of `DIM1`, `DIM2` ... for @sh@.+ data Array r sh e+  -- | O(1). Take the extent (size) of an array.- extent       :: Shape sh => Array r sh e -> sh+ extent :: Shape sh => Array r sh e -> sh   -- | O(1). Shape polymorphic indexing.- index, unsafeIndex+ index, unsafeIndex          :: Shape sh => Array r sh e -> sh -> e   {-# INLINE index #-}@@ -37,16 +35,17 @@  unsafeLinearIndex      = linearIndex   -- | Ensure an array's data structure is fully evaluated.- deepSeqArray :: Shape sh => Array r sh e -> b -> b+ deepSeqArray +        :: Shape sh =>Array r sh e -> b -> b   -- | O(1). Alias for `index`-(!) :: (Repr r e, Shape sh) => Array r sh e -> sh -> e+(!) :: Shape sh => Source r e => Array r sh e -> sh -> e (!) = index   -- | O(n). Convert an array to a list.-toList  :: (Shape sh, Repr r e)+toList  :: Shape sh => Source r e         => Array r sh e -> [e] {-# INLINE toList #-} toList arr @@ -91,7 +90,7 @@ --  If you're not sure, then just follow the example code above. --    deepSeqArrays -        :: (Shape sh, Repr r e)+        :: Shape sh => Source r e         => [Array r sh e] -> b -> b {-# INLINE deepSeqArrays #-} deepSeqArrays arrs x
Data/Array/Repa/Eval.hs view
@@ -6,9 +6,9 @@           Elt       (..)          -- * Parallel array filling-        , Fillable  (..)-        , Fill      (..)-        , FillRange (..)+        , Target    (..)+        , Load      (..)+        , LoadRange (..)         , fromList                  -- * Converting between representations@@ -37,7 +37,8 @@         , selectChunkedP) where import Data.Array.Repa.Eval.Elt-import Data.Array.Repa.Eval.Fill+import Data.Array.Repa.Eval.Target+import Data.Array.Repa.Eval.Load import Data.Array.Repa.Eval.Chunked import Data.Array.Repa.Eval.Interleaved import Data.Array.Repa.Eval.Cursored@@ -60,7 +61,8 @@ --     then use `delay` instead. -- computeP -        :: (Shape sh, Fill r1 r2 sh e, Repr r2 e, Monad m)+        :: ( Load r1 sh e+           , Target r2 e, Source r2 e, Monad m)         => Array r1 sh e -> m (Array r2 sh e) computeP arr = now $ suspendedComputeP arr {-# INLINE [4] computeP #-}@@ -68,14 +70,14 @@  -- | Sequential computation of array elements. computeS -        :: Fill r1 r2 sh e+        :: (Load r1 sh e, Target r2 e)         => Array r1 sh e -> Array r2 sh e computeS arr1  = arr1 `deepSeqArray`     unsafePerformIO- $ do   marr2    <- newMArr (size $ extent arr1) -        fillS arr1 marr2-        unsafeFreezeMArr (extent arr1) marr2+ $ do   mvec2   <- newMVec (size $ extent arr1) +        loadS arr1 mvec2+        unsafeFreezeMVec (extent arr1) mvec2 {-# INLINE [4] computeS #-}  @@ -91,14 +93,14 @@ --   that each array is fully evaluated before continuing. -- suspendedComputeP -        :: Fill r1 r2 sh e+        :: (Load r1 sh e, Target r2 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+ $ do   mvec2    <- newMVec (size $ extent arr1) +        loadP arr1 mvec2+        unsafeFreezeMVec (extent arr1) mvec2 {-# INLINE [4] suspendedComputeP #-}  @@ -108,14 +110,17 @@ --  --   * You can use it to copy manifest arrays between representations. ---copyP  :: (Shape sh, Fill D r2 sh e, Repr r1 e, Repr r2 e, Monad m)+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) copyP arr = now $ suspendedCopyP arr {-# INLINE [4] copyP #-}   -- | Sequential copying of arrays.-copyS   :: (Repr r1 e, Fill D r2 sh e)+copyS   :: ( Source r1 e+           , Load D sh e, Target r2 e)         => Array r1 sh e -> Array r2 sh e copyS arr1  = computeS $ delay arr1 {-# INLINE [4] copyS #-}@@ -123,7 +128,8 @@  -- | Suspended parallel copy of array elements. suspendedCopyP   -        :: (Repr r1 e, Fill D r2 sh e)+        :: ( Source r1 e+           , Load D sh e, Target r2 e)         => Array r1 sh e -> Array r2 sh e suspendedCopyP arr1  = suspendedComputeP $ delay arr1 {-# INLINE [4] suspendedCopyP #-}@@ -140,9 +146,11 @@ --     ... -- @ ---now     :: (Shape sh, Repr r e, Monad m)+now     :: (Shape sh, Source r e, Monad m)         => Array r sh e -> m (Array r sh e) now arr  = do   arr `deepSeqArray` return ()         return arr {-# INLINE [4] now #-}++
− Data/Array/Repa/Eval/Fill.hs
@@ -1,78 +0,0 @@--module Data.Array.Repa.Eval.Fill-        ( Fillable  (..), fromList-        , Fill      (..)-        , FillRange (..))-where-import Data.Array.Repa.Base-import Data.Array.Repa.Shape-import Control.Monad-import System.IO.Unsafe---- Fillable ---------------------------------------------------------------------- | Class of manifest array representations that can be filled in parallel ---   and then frozen into immutable Repa arrays.-class Fillable r e where-- -- | Mutable version of the representation.- data MArr r e-- -- | Allocate a new mutable array of the given size.- newMArr          :: Int -> IO (MArr r e)-- -- | Write an element into the mutable array.- unsafeWriteMArr  :: MArr r e -> Int -> e -> IO ()-- -- | 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-- -- | Ensure the array is still live at this point.- --   Needed when the mutable array is a ForeignPtr with a finalizer.- touchMArr        :: MArr r e -> IO ()----- | O(n). Construct a manifest array from a list.-fromList-        :: (Shape sh, Fillable r e)-        => sh -> [e] -> Array r sh e-fromList sh xx- = unsafePerformIO- $ do   let len = length xx-        if len /= size sh-         then error "Data.Array.Repa.Eval.Fill.fromList: provide array shape does not match list length"-         else do-                marr    <- newMArr len-                zipWithM_ (unsafeWriteMArr marr) [0..] xx-                unsafeFreezeMArr sh marr----- Fill -------------------------------------------------------------------------- | Compute all elements defined by an array and write them to a fillable---   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 (Shape sh, Repr r1 e, Fillable r2 e) => Fill r1 r2 sh e where- -- | Fill an entire array sequentially.- fillS          :: Array r1 sh e -> MArr r2 e -> IO ()-- -- | Fill an entire array in parallel.- fillP          :: Array r1 sh e -> MArr r2 e -> IO ()----- FillRange --------------------------------------------------------------------- | Compute a range of elements defined by an array and write them to a fillable---   representation.-class (Shape sh, Repr r1 e, Fillable r2 e) => FillRange r1 r2 sh e where- -- | Fill a range of an array sequentially.- fillRangeS     :: Array r1 sh e -> MArr r2 e -> sh -> sh -> IO ()-- -- | Fill a range of an array in parallel.- fillRangeP     :: Array r1 sh e -> MArr r2 e -> sh -> sh -> IO ()---                        
+ Data/Array/Repa/Eval/Load.hs view
@@ -0,0 +1,36 @@++module Data.Array.Repa.Eval.Load+        ( Load      (..)+        , LoadRange (..))+where+import Data.Array.Repa.Eval.Target+import Data.Array.Repa.Shape+import Data.Array.Repa.Base++-- Load -----------------------------------------------------------------------+-- | 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 where+ -- | Fill an entire array sequentially.+ loadS          :: Target r2 e => Array r1 sh e -> MVec r2 e -> IO ()++ -- | Fill an entire array in parallel.+ loadP          :: Target r2 e => Array r1 sh e -> MVec r2 e -> IO ()+++-- FillRange ------------------------------------------------------------------+-- | 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 where+ -- | Fill a range of an array sequentially.+ loadRangeS     :: Target r2 e => Array r1 sh e -> MVec r2 e -> sh -> sh -> IO ()++ -- | Fill a range of an array in parallel.+ loadRangeP     :: Target r2 e => Array r1 sh e -> MVec r2 e -> sh -> sh -> IO ()+++                        
+ Data/Array/Repa/Eval/Target.hs view
@@ -0,0 +1,49 @@++module Data.Array.Repa.Eval.Target+        ( Target    (..)+        , fromList)+where+import Data.Array.Repa.Base+import Data.Array.Repa.Shape+import Control.Monad+import System.IO.Unsafe+++-- Target ---------------------------------------------------------------------+-- | Class of manifest array representations that can be constructed in parallel.+class Target r e where++ -- | Mutable version of the representation.+ data MVec r e++ -- | Allocate a new mutable array of the given size.+ newMVec          :: Int -> IO (MVec r e)++ -- | Write an element into the mutable array.+ unsafeWriteMVec  :: MVec r e -> Int -> e -> IO ()++ -- | Freeze the mutable array into an immutable Repa array.+ unsafeFreezeMVec :: sh  -> MVec r e -> IO (Array r sh e)++ -- | Ensure the strucure of a mutable array is fully evaluated.+ deepSeqMVec      :: 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        :: MVec r e -> IO ()+++-- | O(n). Construct a manifest array from a list.+fromList :: (Shape sh, Target r e)+         => sh -> [e] -> Array r sh e+fromList sh xx+ = unsafePerformIO+ $ do   let len = length xx+        if len /= size sh+         then error "Data.Array.Repa.Eval.Fill.fromList: provide array shape does not match list length"+         else do+                mvec    <- newMVec len+                zipWithM_ (unsafeWriteMVec mvec) [0..] xx+                unsafeFreezeMVec sh mvec++
Data/Array/Repa/Operators/IndexSpace.hs view
@@ -24,8 +24,8 @@ -- Index space transformations ------------------------------------------------ -- | 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 sh2, Shape sh1-           , Repr r1 e)+reshape	:: ( Shape sh1, Shape sh2+           , Source r1 e) 	=> sh2 	-> Array r1 sh1 e 	-> Array D  sh2 e@@ -44,7 +44,7 @@ -- | Append two arrays. append, (++) 	:: ( Shape sh-	   , Repr r1 e, Repr r2 e)+           , Source r1 e, Source r2 e) 	=> Array r1 (sh :. Int) e 	-> Array r2 (sh :. Int) e 	-> Array D  (sh :. Int) e@@ -70,10 +70,9 @@ -- | Transpose the lowest two dimensions of an array. --	Transposing an array twice yields the original. transpose-	:: ( Shape sh-	   , Repr r e)-	=> Array r (sh :. Int :. Int) e-	-> Array D (sh :. Int :. Int) e+	:: (Shape sh, Source r e)+	=> Array  r (sh :. Int :. Int) e+	-> Array  D (sh :. Int :. Int) e  transpose arr  = unsafeTraverse arr@@ -83,7 +82,7 @@   -- | Extract a sub-range of elements from an array.-extract :: (Shape sh, Repr r e)+extract :: (Shape sh, Source r e)         => sh                   -- ^ Starting index.         -> sh                   -- ^ Size of result.         -> Array r sh e @@ -97,8 +96,8 @@ --	The result array has the same extent as the original. backpermute, unsafeBackpermute 	:: forall r sh1 sh2 e-	.  ( Shape sh1, Shape sh2-	   , Repr r e)+        .  ( Shape sh1, Shape sh2+	   , Source r e) 	=> sh2 			-- ^ Extent of result array. 	-> (sh2 -> sh1) 	-- ^ Function mapping each index in the result array 				--	to an index of the source array.@@ -118,10 +117,10 @@ --	If the function returns `Nothing` then the value at that index is taken --	from the default array (@arrDft@) backpermuteDft, unsafeBackpermuteDft-	:: forall r0 r1 sh1 sh2 e-	.  ( Shape sh1, Shape sh2-	   , Repr  r0 e, Repr r1 e)-	=> Array r0 sh2 e	-- ^ Default values (@arrDft@)+	:: forall r1 r2 sh1 sh2 e+        .  ( Shape sh1,   Shape sh2+           , Source r1 e, Source r2 e)+	=> Array r2 sh2 e	-- ^ Default values (@arrDft@) 	-> (sh2 -> Maybe sh1) 	-- ^ Function mapping each index in the result array 				--	to an index in the source array. 	-> Array r1 sh1 e	-- ^ Source array.@@ -153,9 +152,9 @@ -- extend, unsafeExtend         :: ( Slice sl-           , Shape (FullShape sl)            , Shape (SliceShape sl)-           , Repr r e)+           , Shape (FullShape sl)+           , Source r e)         => sl         -> Array r (SliceShape sl) e         -> Array D (FullShape sl)  e@@ -190,7 +189,7 @@         :: ( Slice sl            , Shape (FullShape sl)            , Shape (SliceShape sl)-           , Repr r e)+           , Source r e)         => Array r (FullShape sl) e         -> sl         -> Array D (SliceShape sl) e
Data/Array/Repa/Operators/Interleave.hs view
@@ -5,13 +5,14 @@ 	, interleave3 	, interleave4) where+import Data.Array.Repa.Shape import Data.Array.Repa.Index import Data.Array.Repa.Base import Data.Array.Repa.Repr.Delayed import Data.Array.Repa.Operators.Traversal-import Data.Array.Repa.Shape		as S import Prelude				hiding ((++)) + -- Interleave ----------------------------------------------------------------- -- | Interleave the elements of two arrays. --   All the input arrays must have the same extent, else `error`.@@ -23,8 +24,8 @@ -- @ -- interleave2-	:: (Shape sh-	   , Repr r1 a, Repr r2 a)+	:: ( Shape sh+           , Source r1 a, Source r2 a) 	=> Array r1 (sh :. Int) a 	-> Array r2 (sh :. Int) a 	-> Array D  (sh :. Int) a@@ -51,7 +52,7 @@ -- | Interleave the elements of three arrays. interleave3 	:: ( Shape sh-	   , Repr r1 a, Repr r2 a, Repr r3 a)+           , Source r1 a, Source r2 a, Source r3 a) 	=> Array r1 (sh :. Int) a 	-> Array r2 (sh :. Int) a 	-> Array r3 (sh :. Int) a@@ -81,7 +82,7 @@ -- | Interleave the elements of four arrays. interleave4 	:: ( Shape sh-	   , Repr r1 a, Repr r2 a, Repr r3 a, Repr r4 a)+           , 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@@ -109,3 +110,5 @@ 		2	-> get3 (sh :. ix `div` 4) 		3	-> get4 (sh :. ix `div` 4) 		_	-> error "Data.Array.Repa.interleave4: this never happens :-P"++
Data/Array/Repa/Operators/Mapping.hs view
@@ -6,8 +6,8 @@         , zipWith         , (+^), (-^), (*^), (/^) -          -- * Combining maps-        , Combine(..))+          -- * Structured maps+        , Structured(..)) where import Data.Array.Repa.Shape import Data.Array.Repa.Base@@ -26,7 +26,7 @@ -- | Apply a worker function to each element of an array,  --   yielding a new array with the same extent. ---map     :: (Shape sh, Repr r a)+map     :: (Shape sh, Source r a)         => (a -> b) -> Array r sh a -> Array D sh b map f arr  = case delay arr of@@ -39,36 +39,35 @@ --	If the extent of the two array arguments differ, --	then the resulting array's extent is their intersection. ---zipWith :: (Shape sh, Repr r1 a, Repr r2 b)+zipWith :: (Shape sh, Source r1 a, Source r2 b)         => (a -> b -> c)         -> Array r1 sh a -> Array r2 sh b         -> Array D sh c zipWith f arr1 arr2- = let  {-# INLINE get #-}-        get ix  = f (arr1 `unsafeIndex` ix) (arr2 `unsafeIndex` ix)-+ = let  get ix  = f (arr1 `unsafeIndex` ix) (arr2 `unsafeIndex` ix)+        {-# INLINE get #-}+            in   fromFunction                  (intersectDim (extent arr1) (extent arr2))                  get {-# INLINE [2] zipWith #-}  -{-# INLINE (+^) #-} (+^)	= zipWith (+)+{-# INLINE (+^) #-} -{-# INLINE (-^) #-} (-^)	= zipWith (-)+{-# INLINE (-^) #-} -{-# INLINE (*^) #-} (*^)	= zipWith (*)+{-# INLINE (*^) #-} -{-# INLINE (/^) #-} (/^)	= zipWith (/)-+{-# INLINE (/^) #-}  --- Combine ----------------------------------------------------------------------- | Combining versions of @map@ and @zipWith@ that preserve the representation+-- Structured -------------------------------------------------------------------+-- | 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.@@ -81,103 +80,115 @@ --   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 `cmap` and ---   `czipWith` are identical to the plain functions.+--   If the source array is not cursored or partitioned then `smap` and +--   `szipWith` are identical to the plain functions. ---class Combine r1 a r2 b | r1 -> r2 where+class Structured r1 a b where+ -- | The target result representation.+ type TR r1 - -- | Combining @map@.- cmap   :: Shape sh + -- | Structured @map@.+ smap   :: Shape sh          => (a -> b) -        -> Array r1 sh a -        -> Array r2 sh b+        -> Array r1     sh a +        -> Array (TR r1) sh b - -- | Combining @zipWith@.+ -- | Structured @zipWith@.  --   If you have a cursored or partitioned source array then use that as  --   the third argument (corresponding to @r1@ here)- czipWith-        :: (Shape sh, Repr r c)+ szipWith+        :: (Shape sh, Source r c)         => (c -> a -> b)-        -> Array r  sh c-        -> Array r1 sh a-        -> Array r2 sh b+        -> Array r      sh c+        -> Array r1     sh a+        -> Array (TR r1) sh b   -- ByteString --------------------------instance Combine B Word8 D b where- cmap           = map- czipWith       = zipWith+instance Structured B Word8 b where+ type TR B = D+ smap           = map+ szipWith       = zipWith   -- Cursored ----------------------------instance Combine C a C b where- {-# INLINE [3] cmap #-}- cmap f (ACursored sh makec shiftc loadc)-        = ACursored sh makec shiftc (f . loadc)+instance Structured C a b where+ type TR C = C - {-# INLINE [2] czipWith #-}- czipWith f arr1 (ACursored sh makec shiftc loadc)-  = let {-# INLINE makec' #-}-        makec' ix               = (ix, makec ix)+ smap f (ACursored sh makec shiftc loadc)+        = ACursored sh makec shiftc (f . loadc)+ {-# INLINE [3] smap #-} -        {-# INLINE shiftc' #-}+ szipWith f arr1 (ACursored sh makec shiftc loadc)+  = let makec' ix               = (ix, makec ix)+        {-# INLINE makec' #-}+                 shiftc' off (ix, cur)   = (addDim off ix, shiftc off cur)+        {-# INLINE shiftc' #-} -        {-# INLINE load' #-}         load' (ix, cur)         = f (arr1 `unsafeIndex` ix) (loadc cur)+        {-# INLINE load' #-}      in  ACursored                  (intersectDim (extent arr1) sh)                 makec' shiftc' load'+ {-# INLINE [2] szipWith #-}   -- Delayed -----------------------------instance Combine D a D b where- cmap           = map- czipWith       = zipWith+instance Structured D a b where+ type TR D = D+ smap           = map+ szipWith       = zipWith   -- ForeignPtr --------------------------instance Storable a => Combine F a D b where- cmap           = map- czipWith       = zipWith+instance Storable a => Structured F a b where+ type TR F = D+ smap           = map+ szipWith       = zipWith   -- Partitioned -------------------------instance (Combine r11 a r21 b-        , Combine r12 a r22 b)-       => Combine (P r11 r12) a (P r21 r22) b where+instance (Structured r1 a b+        , Structured r2 a b)+       => Structured (P r1 r2) a b where+ type TR (P r1 r2) = P (TR r1) (TR r2) - cmap f (APart sh range arr1 arr2)-        = APart sh range (cmap f arr1) (cmap f arr2)- {-# INLINE [3] cmap #-}+ smap f (APart sh range arr1 arr2)+        = APart sh range (smap f arr1) (smap f arr2)+ {-# INLINE [3] smap #-} - czipWith f arr1 (APart sh range arr21 arr22)-        = APart sh range (czipWith f arr1 arr21)-                         (czipWith f arr1 arr22)- {-# INLINE [2] czipWith #-}+ szipWith f arr1 (APart sh range arr21 arr22)+        = APart sh range (szipWith f arr1 arr21)+                         (szipWith f arr1 arr22)+ {-# INLINE [2] szipWith #-}   -- Small -------------------------------instance   Combine r1 a r2 b-        => Combine (S r1) a (S r2) b where- cmap f (ASmall arr1)-        = ASmall (cmap f arr1)- {-# INLINE [3] cmap #-}+instance   Structured r1 a b+        => Structured (S r1) a b where+ type TR (S r1) = S (TR r1) - czipWith f arr1 (ASmall arr2)-        = ASmall (czipWith f arr1 arr2)- {-# INLINE [3] czipWith #-}+ smap f (ASmall arr1)+        = ASmall (smap f arr1)+ {-# INLINE [3] smap #-} + szipWith f arr1 (ASmall arr2)+        = ASmall (szipWith f arr1 arr2)+ {-# INLINE [3] szipWith #-} + -- Unboxed -----------------------------instance Unbox a => Combine U a D b where- cmap           = map- czipWith       = zipWith+instance Unbox a => Structured U a b where+ type TR U = D+ smap           = map+ szipWith       = zipWith   -- Undefined ---------------------------instance Combine X a X b where- cmap     _   (AUndefined sh) = AUndefined sh- czipWith _ _ (AUndefined sh) = AUndefined sh+instance Structured X a b where+ type TR X = X+ smap     _   (AUndefined sh) = AUndefined sh+ szipWith _ _ (AUndefined sh) = AUndefined sh 
Data/Array/Repa/Operators/Reduction.hs view
@@ -24,7 +24,7 @@ -- | 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)+foldS   :: (Shape sh, Source r a, Elt a, Unbox a)         => (a -> a -> a)         -> a         -> Array r (sh :. Int) a@@ -49,8 +49,7 @@ --   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, Monad m)+foldP   :: (Shape sh, Source r a, Elt a, Unbox a, Monad m)         => (a -> a -> a)         -> a         -> Array r (sh :. Int) a@@ -80,7 +79,7 @@ -- foldAll -------------------------------------------------------------------- -- | Sequential reduction of an array of arbitrary rank to a single scalar value. ---foldAllS :: (Shape sh, Elt a, Unbox a, Repr r a)+foldAllS :: (Shape sh, Source r a, Elt a, Unbox a) 	=> (a -> a -> a) 	-> a 	-> Array r sh a@@ -104,7 +103,7 @@ --   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, Monad m)+        :: (Shape sh, Source r a, Elt a, Unbox a, Monad m) 	=> (a -> a -> a) 	-> a 	-> Array r sh a@@ -122,7 +121,7 @@  -- sum ------------------------------------------------------------------------ -- | Sequential sum the innermost dimension of an array.-sumS	:: (Shape sh, Num a, Elt a, Unbox a, Repr r a)+sumS	:: (Shape sh, Source r a, Num a, Elt a, Unbox a) 	=> Array r (sh :. Int) a 	-> Array U sh a sumS = foldS (+) 0@@ -130,7 +129,7 @@   -- | Parallel sum the innermost dimension of an array.-sumP	:: (Shape sh, Num a, Elt a, Unbox a, Repr r a, Monad m)+sumP	:: (Shape sh, Source r a, Num a, Elt a, Unbox a, Monad m) 	=> Array r (sh :. Int) a 	-> m (Array U sh a) sumP = foldP (+) 0 @@ -139,7 +138,7 @@  -- sumAll --------------------------------------------------------------------- -- | Sequential sum of all the elements of an array.-sumAllS	:: (Shape sh, Elt a, Unbox a, Num a, Repr r a)+sumAllS	:: (Shape sh, Source r a, Elt a, Unbox a, Num a) 	=> Array r sh a 	-> a sumAllS = foldAllS (+) 0@@ -147,7 +146,7 @@   -- | Parallel sum all the elements of an array.-sumAllP	:: (Shape sh, Elt a, Unbox a, Num a, Repr r a, Monad m)+sumAllP	:: (Shape sh, Source r a, Elt a, Unbox a, Num a, Monad m) 	=> Array r sh a 	-> m a sumAllP = foldAllP (+) 0@@ -155,7 +154,7 @@   -- Equality -------------------------------------------------------------------instance (Shape sh, Repr r e, Eq e) => Eq (Array r sh e) where+instance (Shape sh, Eq sh, Source r a, Eq a) => Eq (Array r sh a) where  (==) arr1 arr2         =   extent arr1 == extent arr2         && (foldAllS (&&) True (R.zipWith (==) arr1 arr2))@@ -163,9 +162,9 @@  -- | 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+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 equalsP arr1 arr2  = do   same    <- foldAllP (&&) True (R.zipWith (==) arr1 arr2)@@ -174,9 +173,9 @@  -- | 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+equalsS :: (Shape sh, Eq sh, Source r1 a, Source r2 a, Eq a) +        => Array r1 sh a +        -> Array r2 sh a         -> Bool equalsS arr1 arr2         =   extent arr1 == extent arr2
Data/Array/Repa/Operators/Traversal.hs view
@@ -13,7 +13,8 @@ -- | Unstructured traversal. traverse, unsafeTraverse 	:: forall r sh sh' a b-	.  (Shape sh, Shape sh', Repr r a)+	.  ( Source r a+           , Shape sh, Shape sh') 	=> Array r sh a		        -- ^ Source array. 	-> (sh  -> sh')			-- ^ Function to produce the extent of the result. 	-> ((sh -> a) -> sh' -> b)	-- ^ Function to produce elements of the result.@@ -32,8 +33,8 @@ -- | Unstructured traversal over two arrays at once. traverse2, unsafeTraverse2 	:: forall r1 r2 sh sh' sh'' a b c-	.  ( Shape sh,  Shape sh', Shape sh''-	   , Repr r1 a, Repr r2 b)+	.  ( Source r1 a, Source r2 b+           , Shape sh, Shape sh', Shape sh'')         => Array r1 sh  a 		-- ^ First source array. 	-> Array r2 sh' b		-- ^ Second source array.         -> (sh -> sh' -> sh'')		-- ^ Function to produce the extent of the result.@@ -59,8 +60,8 @@ 	:: forall r1  r2  r3 	          sh1 sh2 sh3 sh4 	          a   b   c   d-	.  ( Shape sh1, Shape sh2, Shape sh3, Shape sh4-	   , Repr r1 a, Repr r2 b, Repr r3 c)+	.  ( 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@@ -86,8 +87,8 @@ 	:: forall r1  r2  r3  r4 	          sh1 sh2 sh3 sh4 sh5 	          a   b   c   d   e-	.  ( Shape sh1, Shape sh2, Shape sh3, Shape sh4, Shape sh5-	   , Repr r1 a, Repr r2 b, Repr r3 c, Repr r4 d)+	.  ( 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
Data/Array/Repa/Repr/ByteString.hs view
@@ -14,19 +14,12 @@  -- | Strict ByteStrings arrays are represented as ForeignPtr buffers of Word8 data B-data instance Array B sh Word8-        = AByteString !sh !ByteString         -deriving instance Show sh-        => Show (Array B sh Word8)--deriving instance Read sh-        => Read (Array B sh Word8)----- Repr ----------------------------------------------------------------------- -- | Read elements from a `ByteString`.-instance Repr B Word8 where+instance Source B Word8 where+ data Array B sh Word8+        = AByteString !sh !ByteString+  linearIndex (AByteString _ bs) ix         = bs `B.index` ix  {-# INLINE linearIndex #-}@@ -42,6 +35,13 @@  deepSeqArray (AByteString sh bs) x    = sh `deepSeq` bs `seq` x  {-# INLINE deepSeqArray #-}+++deriving instance Show sh+        => Show (Array B sh Word8)++deriving instance Read sh+        => Read (Array B sh Word8)   -- Conversions ----------------------------------------------------------------
Data/Array/Repa/Repr/Cursored.hs view
@@ -8,9 +8,10 @@ import Data.Array.Repa.Index import Data.Array.Repa.Repr.Delayed import Data.Array.Repa.Repr.Undefined-import Data.Array.Repa.Eval.Fill+import Data.Array.Repa.Eval.Load import Data.Array.Repa.Eval.Elt import Data.Array.Repa.Eval.Cursored+import Data.Array.Repa.Eval.Target import GHC.Exts import Debug.Trace @@ -23,23 +24,24 @@ --   array representation has changed since this paper was published. data C -data instance Array C sh e++-- | Compute elements of a cursored array.+instance Source C a where++ data Array C sh a         = forall cursor. ACursored         { cursoredExtent :: !sh                             -- | Make a cursor to a particular element.-	, makeCursor     :: sh -> cursor+        , makeCursor     :: sh -> cursor -	  -- | Shift the cursor by an offset, to get to another element.-	, shiftCursor    :: sh -> cursor -> cursor+          -- | Shift the cursor by an offset, to get to another element.+        , shiftCursor    :: sh -> cursor -> cursor -	  -- | Load\/compute the element at the given cursor.-	, loadCursor	 :: cursor -> e }+          -- | Load\/compute the element at the given cursor.+        , loadCursor     :: cursor -> a }  --- Repr -------------------------------------------------------------------------- | Compute elements of a cursored array.-instance Repr C a where  index (ACursored _ makec _ loadc)         = loadc . makec  {-# INLINE index #-}@@ -62,52 +64,52 @@  -- Fill ----------------------------------------------------------------------- -- | Compute all elements in an rank-2 array. -instance (Fillable r2 e, Elt e) => Fill C r2 DIM2 e where- fillP (ACursored (Z :. (I# h) :. (I# w)) makec shiftc loadc) marr-  = do  traceEventIO "Repa.fillP[Cursored]: start"+instance Elt e => Load C DIM2 e where+ loadP (ACursored (Z :. (I# h) :. (I# w)) makec shiftc loadc) marr+  = do  traceEventIO "Repa.loadP[Cursored]: start"         fillCursoredBlock2P -                (unsafeWriteMArr marr) +                (unsafeWriteMVec marr)                  makec shiftc loadc                 w 0# 0# w h-        touchMArr marr-        traceEventIO "Repa.fillP[Cursored]: end"- {-# INLINE fillP #-}+        touchMVec marr+        traceEventIO "Repa.loadP[Cursored]: end"+ {-# INLINE loadP #-}         - fillS (ACursored (Z :. (I# h) :. (I# w)) makec shiftc loadc) marr-  = do  traceEventIO "Repa.fillS[Cursored]: start"+ loadS (ACursored (Z :. (I# h) :. (I# w)) makec shiftc loadc) marr+  = do  traceEventIO "Repa.loadS[Cursored]: start"         fillCursoredBlock2S -                (unsafeWriteMArr marr) +                (unsafeWriteMVec marr)                  makec shiftc loadc                 w 0# 0# w h-        touchMArr marr-        traceEventIO "Repa.fillS[Cursored]: end"- {-# INLINE fillS #-}+        touchMVec marr+        traceEventIO "Repa.loadS[Cursored]: end"+ {-# INLINE loadS #-}           -- | Compute a range of elements in a rank-2 array.-instance (Fillable r2 e, Elt e) => FillRange C r2 DIM2 e where- fillRangeP  (ACursored (Z :. _h :. (I# w)) makec shiftc loadc) marr+instance Elt e => LoadRange C DIM2 e where+ loadRangeP  (ACursored (Z :. _h :. (I# w)) makec shiftc loadc) marr              (Z :. (I# y0) :. (I# x0)) (Z :. (I# h0) :. (I# w0))-  = do  traceEventIO "Repa.fillRangeP[Cursored]: start"+  = do  traceEventIO "Repa.loadRangeP[Cursored]: start"         fillCursoredBlock2P -                (unsafeWriteMArr marr) +                (unsafeWriteMVec marr)                  makec shiftc loadc                 w x0 y0 w0 h0-        touchMArr marr-        traceEventIO "Repa.fillRangeP[Cursored]: end"- {-# INLINE fillRangeP #-}+        touchMVec marr+        traceEventIO "Repa.loadRangeP[Cursored]: end"+ {-# INLINE loadRangeP #-}         - fillRangeS  (ACursored (Z :. _h :. (I# w)) makec shiftc loadc) marr+ loadRangeS  (ACursored (Z :. _h :. (I# w)) makec shiftc loadc) marr              (Z :. (I# y0) :. (I# x0))               (Z :. (I# h0) :. (I# w0))-  = do  traceEventIO "Repa.fillRangeS[Cursored]: start"+  = do  traceEventIO "Repa.loadRangeS[Cursored]: start"         fillCursoredBlock2S-                (unsafeWriteMArr marr) +                (unsafeWriteMVec marr)                  makec shiftc loadc                 w x0 y0 w0 h0-        touchMArr marr-        traceEventIO "Repa.fillRangeS[Cursored]: end"- {-# INLINE fillRangeS #-}+        touchMVec marr+        traceEventIO "Repa.loadRangeS[Cursored]: end"+ {-# INLINE loadRangeS #-}           -- Conversions ----------------------------------------------------------------
Data/Array/Repa/Repr/Delayed.hs view
@@ -4,10 +4,11 @@         , fromFunction, toFunction         , delay) where-import Data.Array.Repa.Eval.Elt-import Data.Array.Repa.Eval.Cursored+import Data.Array.Repa.Eval.Load+import Data.Array.Repa.Eval.Target import Data.Array.Repa.Eval.Chunked-import Data.Array.Repa.Eval.Fill+import Data.Array.Repa.Eval.Cursored+import Data.Array.Repa.Eval.Elt import Data.Array.Repa.Index import Data.Array.Repa.Shape import Data.Array.Repa.Base@@ -19,15 +20,14 @@ --   Every time you index into a delayed array the element at that position  --   is recomputed. data D-data instance Array D sh e++-- | Compute elements of a delayed array.+instance Source D a where+ data Array D sh a         = ADelayed                   !sh -                (sh -> e) -+                (sh -> a)  --- Repr -------------------------------------------------------------------------- | Compute elements of a delayed array.-instance Repr D a where  index       (ADelayed _  f) ix  = f ix  {-# INLINE index #-} @@ -43,50 +43,49 @@  {-# INLINE deepSeqArray #-}  --- Fill -----------------------------------------------------------------------+-- Load ----------------------------------------------------------------------- -- | Compute all elements in an array.-instance (Fillable r2 e, Shape sh) => Fill D r2 sh e where- fillP (ADelayed sh getElem) marr-  = marr `deepSeqMArr` -    do  traceEventIO "Repa.fillP[Delayed]: start"-        fillChunkedP (size sh) (unsafeWriteMArr marr) (getElem . fromIndex sh) -        touchMArr marr-        traceEventIO "Repa.fillP[Delayed]: end"- {-# INLINE [4] fillP #-}-- fillS (ADelayed sh getElem) marr-  = marr `deepSeqMArr` -    do  traceEventIO "Repa.fillS[Delayed]: start"-        fillChunkedS (size sh) (unsafeWriteMArr marr) (getElem . fromIndex sh)-        touchMArr marr-        traceEventIO "Repa.fillS[Delayed]: end"+instance Shape sh => Load D sh e where+ loadP (ADelayed sh getElem) mvec+  = mvec `deepSeqMVec` +    do  traceEventIO "Repa.loadP[Delayed]: start"+        fillChunkedP (size sh) (unsafeWriteMVec mvec) (getElem . fromIndex sh) +        touchMVec mvec+        traceEventIO "Repa.loadP[Delayed]: end"+ {-# INLINE [4] loadP #-} - {-# INLINE [4] fillS #-}+ loadS (ADelayed sh getElem) mvec+  = mvec `deepSeqMVec` +    do  traceEventIO "Repa.loadS[Delayed]: start"+        fillChunkedS (size sh) (unsafeWriteMVec mvec) (getElem . fromIndex sh)+        touchMVec mvec+        traceEventIO "Repa.loadS[Delayed]: end"+ {-# INLINE [4] loadS #-}   -- | 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+instance Elt e => LoadRange D DIM2 e where+ loadRangeP  (ADelayed (Z :. _h :. (I# w)) getElem) mvec              (Z :. (I# y0) :. (I# x0)) (Z :. (I# h0) :. (I# w0))-  = marr `deepSeqMArr` -    do  traceEventIO "Repa.fillRangeP[Delayed]: start"-        fillBlock2P (unsafeWriteMArr marr) +  = mvec `deepSeqMVec` +    do  traceEventIO "Repa.loadRangeP[Delayed]: start"+        fillBlock2P (unsafeWriteMVec mvec)                          getElem                         w x0 y0 w0 h0-        touchMArr marr-        traceEventIO "Repa.fillRangeP[Delayed]: end"- {-# INLINE [1] fillRangeP #-}+        touchMVec mvec+        traceEventIO "Repa.loadRangeP[Delayed]: end"+ {-# INLINE [1] loadRangeP #-} - fillRangeS  (ADelayed (Z :. _h :. (I# w)) getElem) marr+ loadRangeS  (ADelayed (Z :. _h :. (I# w)) getElem) mvec              (Z :. (I# y0) :. (I# x0)) (Z :. (I# h0) :. (I# w0))-  = marr `deepSeqMArr`-    do  traceEventIO "Repa.fillRangeS[Delayed]: start"-        fillBlock2S (unsafeWriteMArr marr) +  = mvec `deepSeqMVec`+    do  traceEventIO "Repa.loadRangeS[Delayed]: start"+        fillBlock2S (unsafeWriteMVec mvec)                  getElem                 w x0 y0 w0 h0-        touchMArr marr-        traceEventIO "Repa.fillRangeS[Delayed]: end"- {-# INLINE [1] fillRangeS #-}+        touchMVec mvec+        traceEventIO "Repa.loadRangeS[Delayed]: end"+ {-# INLINE [1] loadRangeS #-}   -- Conversions ----------------------------------------------------------------@@ -100,7 +99,7 @@ -- | O(1). Produce the extent of an array, and a function to retrieve an --   arbitrary element. toFunction -        :: (Shape sh, Repr r1 a)+        :: (Shape sh, Source r1 a)         => Array r1 sh a -> (sh, sh -> a) toFunction arr  = case delay arr of@@ -113,7 +112,7 @@ --   indices to elements, so consumers don't need to worry about --   what the previous representation was. ---delay   :: (Shape sh, Repr r e)+delay   :: Shape sh => Source r e         => Array r sh e -> Array D sh e delay arr = ADelayed (extent arr) (unsafeIndex arr) {-# INLINE delay #-}
Data/Array/Repa/Repr/ForeignPtr.hs view
@@ -6,7 +6,8 @@ where import Data.Array.Repa.Shape import Data.Array.Repa.Base-import Data.Array.Repa.Eval.Fill+import Data.Array.Repa.Eval.Load+import Data.Array.Repa.Eval.Target import Data.Array.Repa.Repr.Delayed import Foreign.Storable import Foreign.ForeignPtr@@ -16,13 +17,12 @@  -- | Arrays represented as foreign buffers in the C heap. data F-data instance Array F sh e-        = AForeignPtr !sh !Int !(ForeignPtr e) ---- Repr ----------------------------------------------------------------------- -- | Read elements from a foreign buffer.-instance Storable a => Repr F a where+instance Storable a => Source F a where+ data Array F sh a+        = AForeignPtr !sh !Int !(ForeignPtr a)+  linearIndex (AForeignPtr _ len fptr) ix   | ix < len           = unsafePerformIO @@ -48,38 +48,38 @@  {-# INLINE deepSeqArray #-}   --- Fill -------------------------------------------------------------------------- | Filling of foreign buffers.-instance Storable e => Fillable F e where- data MArr F e -  = FPArr !Int !(ForeignPtr e)+-- Load -----------------------------------------------------------------------+-- | Filling foreign buffers.+instance Storable e => Target F e where+ data MVec F e +  = FPVec !Int !(ForeignPtr e) - newMArr n+ newMVec n   = do  let (proxy :: e) = undefined         ptr              <- mallocBytes (sizeOf proxy * n)         _                <- peek ptr  `asTypeOf` return proxy                  fptr             <- newForeignPtr finalizerFree ptr-        return           $ FPArr n fptr- {-# INLINE newMArr #-}+        return           $ FPVec n fptr+ {-# INLINE newMVec #-}   -- CAREFUL: Unwrapping the foreignPtr like this means we need to be careful  -- to touch it after the last use, otherwise the finaliser might run too early.- unsafeWriteMArr (FPArr _ fptr) !ix !x+ unsafeWriteMVec (FPVec _ fptr) !ix !x   = pokeElemOff (Unsafe.unsafeForeignPtrToPtr fptr) ix x- {-# INLINE unsafeWriteMArr #-}+ {-# INLINE unsafeWriteMVec #-} - unsafeFreezeMArr !sh (FPArr len fptr)     + unsafeFreezeMVec !sh (FPVec len fptr)   =     return  $ AForeignPtr sh len fptr- {-# INLINE unsafeFreezeMArr #-}+ {-# INLINE unsafeFreezeMVec #-} - deepSeqMArr !(FPArr _ fptr) x+ deepSeqMVec !(FPVec _ fptr) x   = Unsafe.unsafeForeignPtrToPtr fptr `seq` x- {-# INLINE deepSeqMArr #-}+ {-# INLINE deepSeqMVec #-} - touchMArr (FPArr _ fptr)+ touchMVec (FPVec _ fptr)   = touchForeignPtr fptr- {-# INLINE touchMArr #-}+ {-# INLINE touchMVec #-}   -- Conversions ----------------------------------------------------------------@@ -103,10 +103,10 @@ --   buffer without intermediate copying. If you want to copy a --   pre-existing manifest array to a foreign buffer then `delay` it first. computeIntoS-        :: Fill r1 F sh e+        :: (Load r1 sh e, Storable e)         => ForeignPtr e -> Array r1 sh e -> IO () computeIntoS !fptr !arr- = fillS arr (FPArr 0 fptr)+ = loadS arr (FPVec 0 fptr) {-# INLINE computeIntoS #-}  @@ -114,9 +114,9 @@ --   buffer without intermediate copying. If you want to copy a --   pre-existing manifest array to a foreign buffer then `delay` it first. computeIntoP-        :: Fill r1 F sh e+        :: (Load r1 sh e, Storable e)         => ForeignPtr e -> Array r1 sh e -> IO () computeIntoP !fptr !arr- = fillP arr (FPArr 0 fptr)+ = loadP arr (FPVec 0 fptr) {-# INLINE computeIntoP #-} 
Data/Array/Repa/Repr/HintInterleave.hs view
@@ -2,7 +2,8 @@ module Data.Array.Repa.Repr.HintInterleave         (I, Array (..), hintInterleave) where-import Data.Array.Repa.Eval.Fill+import Data.Array.Repa.Eval.Load+import Data.Array.Repa.Eval.Target import Data.Array.Repa.Eval.Interleaved import Data.Array.Repa.Repr.Delayed import Data.Array.Repa.Shape@@ -14,22 +15,10 @@ --   and evaluation should be interleaved between the processors. data I r1 -data instance Array (I r1) sh e-        = AInterleave !(Array r1 sh e)--deriving instance Show (Array r1 sh e) -        => Show (Array (I r1) sh e)--deriving instance Read (Array r1 sh e) -        => Read (Array (I r1) sh e)----- | Wrap an array with a unbalanced-ness hint.-hintInterleave :: Array r1 sh e -> Array (I r1) sh e-hintInterleave = AInterleave-+instance Source r1 a => Source (I r1) a where+ data Array (I r1) sh a+        = AInterleave !(Array r1 sh a) -instance Repr r1 a => Repr (I r1) a where  extent (AInterleave arr)          = extent arr  {-# INLINE extent #-}@@ -55,20 +44,33 @@  {-# INLINE deepSeqArray #-}  --- Fill ------------------------------------------------------------------------instance ( Shape sh, Fill D r2 sh e) -        => Fill (I D) r2 sh e where- fillP (AInterleave (ADelayed sh getElem)) marr-  = marr `deepSeqMArr`-    do  traceEventIO "Repa.fillP[Interleaved]: start"-        fillInterleavedP (size sh) (unsafeWriteMArr marr) (getElem . fromIndex sh) -        touchMArr marr-        traceEventIO "Repa.fillP[Interleaved]: end"- {-# INLINE [4] fillP #-}+deriving instance Show (Array r1 sh e) +        => Show (Array (I r1) sh e) +deriving instance Read (Array r1 sh e) +        => Read (Array (I r1) sh e)+++-- | Wrap an array with a unbalanced-ness hint.+hintInterleave :: Array r1 sh e -> Array (I r1) sh e+hintInterleave = AInterleave+++-- Load -----------------------------------------------------------------------+instance (Shape sh, Load D sh e) +        => Load (I D) sh e where+ loadP (AInterleave (ADelayed sh getElem)) marr+  = marr `deepSeqMVec`+    do  traceEventIO "Repa.loadP[Interleaved]: start"+        fillInterleavedP (size sh) (unsafeWriteMVec marr) (getElem . fromIndex sh) +        touchMVec marr+        traceEventIO "Repa.loadP[Interleaved]: end"+ {-# INLINE [4] loadP #-}+  -- The fact that the workload is unbalanced doesn't affect us when the  -- program is run sequentially, so just use the filling method of the inner  -- representation- fillS (AInterleave arr) marr-  = fillS arr marr- {-# INLINE fillS #-}+ loadS (AInterleave arr) marr+  = loadS arr marr+ {-# INLINE loadS #-}+
Data/Array/Repa/Repr/HintSmall.hs view
@@ -2,31 +2,20 @@ module Data.Array.Repa.Repr.HintSmall         (S, Array (..), hintSmall) where+import Data.Array.Repa.Eval.Load import Data.Array.Repa.Base-import Data.Array.Repa.Eval.Fill import Data.Array.Repa.Shape + -- | 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 -data instance Array (S r1) sh e-        = ASmall !(Array r1 sh e)--deriving instance Show (Array r1 sh e) -        => Show (Array (S r1) sh e)--deriving instance Read (Array r1 sh e) -        => Read (Array (S r1) sh e)----- | Wrap an array with a smallness hint.-hintSmall :: Array r1 sh e -> Array (S r1) sh e-hintSmall = ASmall-+instance Source r1 a => Source (S r1) a where+ data Array (S r1) sh a+        = ASmall !(Array r1 sh a) -instance Repr r1 a => Repr (S r1) a where  extent (ASmall arr)          = extent arr  {-# INLINE extent #-}@@ -52,25 +41,37 @@  {-# INLINE deepSeqArray #-}  --- Fill ------------------------------------------------------------------------instance ( Shape sh, Fill r1 r2 sh e) -        => Fill (S r1) r2 sh e where- fillP (ASmall arr) marr-  = fillS arr marr- {-# INLINE fillP #-}+-- | Wrap an array with a smallness hint.+hintSmall :: Array r1 sh e -> Array (S r1) sh e+hintSmall = ASmall - fillS (ASmall arr) marr-  = fillS arr marr- {-# INLINE fillS #-} +deriving instance Show (Array r1 sh e) +        => Show (Array (S r1) sh e) --- FillRange -------------------------------------------------------------------instance ( Shape sh, FillRange r1 r2 sh e)-        => FillRange (S r1) r2 sh e where- fillRangeP (ASmall arr) marr ix1 ix2-  = fillRangeS arr marr ix1 ix2- {-# INLINE fillRangeP #-}+deriving instance Read (Array r1 sh e) +        => Read (Array (S r1) sh e) - fillRangeS (ASmall arr) marr ix1 ix2-  = fillRangeS arr marr ix1 ix2- {-# INLINE fillRangeS #-}++-- Load ----------------------------------------------------------------------+instance ( Shape sh, Load r1 sh e) +        => Load (S r1) sh e where+ loadP (ASmall arr) marr+  = loadS arr marr+ {-# INLINE loadP #-}++ loadS (ASmall arr) marr+  = loadS arr marr+ {-# INLINE loadS #-}+++-- LoadRange ------------------------------------------------------------------+instance ( Shape sh, LoadRange r1 sh e)+        => LoadRange (S r1) sh e where+ loadRangeP (ASmall arr) marr ix1 ix2+  = loadRangeS arr marr ix1 ix2+ {-# INLINE loadRangeP #-}++ loadRangeS (ASmall arr) marr ix1 ix2+  = loadRangeS arr marr ix1 ix2+ {-# INLINE loadRangeS #-}
Data/Array/Repa/Repr/Partitioned.hs view
@@ -23,11 +23,6 @@ -- data P r1 r2 -data instance Array (P r1 r2) sh e-        = APart !sh                          -- size of the whole array-                !(Range sh) !(Array r1 sh e) -- if in range use this array-                !(Array r2 sh e)             -- otherwise use this array- data Range sh         = Range !sh !sh                      -- indices defining the range                 (sh -> Bool)                 -- predicate to check whether were in range@@ -41,7 +36,13 @@  -- Repr ----------------------------------------------------------------------- -- | Read elements from a partitioned array.-instance (Repr r1 e, Repr r2 e) => Repr (P r1 r2) e where+instance (Source r1 e, Source r2 e) => Source (P r1 r2) e where+ data Array (P r1 r2) sh e+        = APart !sh                          -- size of the whole array+                !(Range sh) !(Array r1 sh e) -- if in range use this array+                !(Array r2 sh e)             -- otherwise use this array++  index (APart _ range arr1 arr2) ix    | inRange range ix   = index arr1 ix    | otherwise          = index arr2 ix@@ -66,16 +67,18 @@ {-# 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- fillP (APart _ (Range ix sz _) arr1 arr2) marr-  = do  fillRangeP arr1 marr ix sz-        fillP arr2 marr- {-# INLINE fillP #-}+-- Load -----------------------------------------------------------------------+instance (LoadRange r1 sh e, Load r2 sh e)+        => Load (P r1 r2) sh e where+ loadP (APart _ (Range ix sz _) arr1 arr2) marr+  = do  loadRangeP arr1 marr ix sz+        loadP arr2 marr+ {-# INLINE loadP #-} - fillS (APart _ (Range ix sz _) arr1 arr2) marr-  = do  fillRangeS arr1 marr ix sz-        fillS arr2 marr- {-# INLINE fillS #-}+ loadS (APart _ (Range ix sz _) arr1 arr2) marr+  = do  loadRangeS arr1 marr ix sz+        loadS arr2 marr+ {-# INLINE loadS #-}+++
Data/Array/Repa/Repr/Unboxed.hs view
@@ -26,19 +26,12 @@ --   This is the most efficient representation for numerical data. -- data U-data instance U.Unbox e => Array U sh e-        = AUnboxed !sh !(U.Vector e)-        -deriving instance (Show sh, Show e, U.Unbox e)-        => Show (Array U sh e) -deriving instance (Read sh, Read e, U.Unbox e)-        => Read (Array U sh e)----- Repr ----------------------------------------------------------------------- -- | Read elements from an unboxed vector array.-instance U.Unbox a => Repr U a where+instance U.Unbox a => Source U a where+ data Array U sh a+        = AUnboxed !sh !(U.Vector a)+  linearIndex (AUnboxed _ vec) ix         = vec U.! ix  {-# INLINE linearIndex #-}@@ -56,32 +49,39 @@  {-# INLINE deepSeqArray #-}  +deriving instance (Show sh, Show e, U.Unbox e)+        => Show (Array U sh e)++deriving instance (Read sh, Read e, U.Unbox e)+        => Read (Array U sh e)++ -- Fill ----------------------------------------------------------------------- -- | Filling of unboxed vector arrays.-instance U.Unbox e => Fillable U e where- data MArr U e -  = UMArr (UM.IOVector e)+instance U.Unbox e => Target U e where+ data MVec U e +  = UMVec (UM.IOVector e) - newMArr n-  = liftM UMArr (UM.new n)- {-# INLINE newMArr #-}+ newMVec n+  = liftM UMVec (UM.new n)+ {-# INLINE newMVec #-} - unsafeWriteMArr (UMArr v) ix+ unsafeWriteMVec (UMVec v) ix   = UM.unsafeWrite v ix- {-# INLINE unsafeWriteMArr #-}+ {-# INLINE unsafeWriteMVec #-} - unsafeFreezeMArr sh (UMArr mvec)     + unsafeFreezeMVec sh (UMVec mvec)        = do  vec     <- U.unsafeFreeze mvec         return  $  AUnboxed sh vec- {-# INLINE unsafeFreezeMArr #-}+ {-# INLINE unsafeFreezeMVec #-} - deepSeqMArr (UMArr vec) x+ deepSeqMVec (UMVec vec) x   = vec `seq` x- {-# INLINE deepSeqMArr #-}+ {-# INLINE deepSeqMVec #-} - touchMArr _ + touchMVec _    = return ()- {-# INLINE touchMArr #-}+ {-# INLINE touchMVec #-}   -- Conversions ----------------------------------------------------------------@@ -90,7 +90,8 @@ --   * This is an alias for `computeS` with a more specific type. -- computeUnboxedS-        :: Fill r1 U sh e+        :: ( Shape sh+           , Load r1 sh e, U.Unbox e)         => Array r1 sh e -> Array U sh e computeUnboxedS = computeS {-# INLINE computeUnboxedS #-}@@ -101,7 +102,8 @@ --   * This is an alias for `computeP` with a more specific type. -- computeUnboxedP-        :: (Fill r1 U sh e, Monad m, U.Unbox e)+        :: ( Shape sh+           , Load r1 sh e, Monad m, U.Unbox e)         => Array r1 sh e -> m (Array U sh e) computeUnboxedP = computeP {-# INLINE computeUnboxedP #-}
Data/Array/Repa/Repr/Undefined.hs view
@@ -4,7 +4,7 @@ where import Data.Array.Repa.Base import Data.Array.Repa.Shape-import Data.Array.Repa.Eval.Fill+import Data.Array.Repa.Eval   -- | An array with undefined elements.@@ -12,19 +12,14 @@ --   * This is normally used as the last representation in a partitioned array,  --     as the previous partitions are expected to provide full coverage. data X-data instance Array X sh e-        = AUndefined !sh -deriving instance Show sh -        => Show (Array X sh e) -deriving instance Read sh -        => Read (Array X sh e)-- -- | Undefined array elements. Inspecting them yields `error`. ---instance Repr X e where+instance Source X e where+ data Array X sh e+        = AUndefined !sh+  deepSeqArray _ x         = x  {-# INLINE deepSeqArray #-}@@ -40,10 +35,17 @@  linearIndex (AUndefined _) ix         = error $ "Repa: array element at " ++ show ix ++ " is undefined."  {-# INLINE linearIndex #-}-  -instance (Shape sh, Fillable r2 e, Num e) => Fill X r2 sh e where- fillS _ _ = return ()- fillP _ _ = return ()++deriving instance Show sh +        => Show (Array X sh e)++deriving instance Read sh +        => Read (Array X sh e)+++instance (Shape sh, Num e) => Load X sh e where+ loadS _ _ = return ()+ loadP _ _ = return ()  
Data/Array/Repa/Repr/Vector.hs view
@@ -19,19 +19,12 @@ --   have an `Unbox` instsance. If it does, then use the Unboxed `U` --   representation will be faster. data V-data instance Array V sh e-        = AVector !sh !(V.Vector e)         -deriving instance (Show sh, Show e)-        => Show (Array V sh e)--deriving instance (Read sh, Read e)-        => Read (Array V sh e)----- Repr ----------------------------------------------------------------------- -- | Read elements from a boxed vector array.-instance Repr V a where+instance Source V a where+ data Array V sh a+        = AVector !sh !(V.Vector a)+  linearIndex (AVector _ vec) ix         = vec V.! ix  {-# INLINE linearIndex #-}@@ -49,32 +42,39 @@  {-# INLINE deepSeqArray #-}  +deriving instance (Show sh, Show e)+        => Show (Array V sh e)++deriving instance (Read sh, Read e)+        => Read (Array V sh e)++ -- Fill ----------------------------------------------------------------------- -- | Filling of boxed vector arrays.-instance Fillable V e where- data MArr V e -  = MVec (VM.IOVector e)+instance Target V e where+ data MVec V e +  = MVector (VM.IOVector e) - newMArr n-  = liftM MVec (VM.new n)- {-# INLINE newMArr #-}+ newMVec n+  = liftM MVector (VM.new n)+ {-# INLINE newMVec #-} - unsafeWriteMArr (MVec v) ix+ unsafeWriteMVec (MVector v) ix   = VM.unsafeWrite v ix- {-# INLINE unsafeWriteMArr #-}+ {-# INLINE unsafeWriteMVec #-} - unsafeFreezeMArr sh (MVec mvec)     + unsafeFreezeMVec sh (MVector mvec)        = do  vec     <- V.unsafeFreeze mvec         return  $  AVector sh vec- {-# INLINE unsafeFreezeMArr #-}+ {-# INLINE unsafeFreezeMVec #-} - deepSeqMArr !_vec x+ deepSeqMVec !_vec x   = x- {-# INLINE deepSeqMArr #-}+ {-# INLINE deepSeqMVec #-} - touchMArr _ + touchMVec _    = return ()- {-# INLINE touchMArr #-}+ {-# INLINE touchMVec #-}   -- Conversions ----------------------------------------------------------------@@ -83,7 +83,7 @@ --   * This is an alias for `compute` with a more specific type. -- computeVectorS-        :: Fill r1 V sh e+        :: (Shape sh, Load r1 sh e)         => Array r1 sh e -> Array V sh e computeVectorS   = computeS {-# INLINE computeVectorS #-}@@ -91,7 +91,7 @@  -- | Parallel computation of array elements. computeVectorP-        :: (Fill r1 V sh e, Monad m)+        :: (Shape sh, Load r1 sh e, Monad m)         => Array r1 sh e -> m (Array V sh e) computeVectorP   = computeP {-# INLINE computeVectorP #-}
Data/Array/Repa/Specialised/Dim2.hs view
@@ -73,7 +73,7 @@ --   The border must be the same width on all sides. -- makeBordered2-	:: (Repr r1 a, Repr r2 a)+	:: (Source r1 a, Source r2 a)         => DIM2			-- ^ Extent of array. 	-> Int			-- ^ Width of border. 	-> Array r1 DIM2 a	-- ^ Array for internal elements.
Data/Array/Repa/Stencil/Base.hs view
@@ -9,8 +9,11 @@  -- | How to handle the case when the stencil lies partly outside the array. data Boundary a-	-- | Treat points outside as having a constant value.-	= BoundConst a+        -- | Use a fixed value for border regions.+        = BoundFixed a++	-- | Treat points outside the array as having a constant value.+	| BoundConst a  	-- | Clamp points outside to the same value as the edge pixel. 	| BoundClamp
Data/Array/Repa/Stencil/Dim2.hs view
@@ -11,11 +11,10 @@ --   fits in the 7x7 tile. -- module Data.Array.Repa.Stencil.Dim2-	( -	-- * Stencil creation+	( -- * Stencil creation 	  makeStencil2, stencil2 -	-- * Stencil operators+	  -- * Stencil operators 	, PC5, mapStencil2, forStencil2) where import Data.Array.Repa.Base@@ -42,10 +41,10 @@ -- Wrappers ------------------------------------------------------------------- -- | Like `mapStencil2` but with the parameters flipped. forStencil2-        :: Repr r a+        :: Source r a         => Boundary a-	-> Array r DIM2 a-	-> Stencil DIM2 a+	-> Array  r DIM2 a+	-> Stencil  DIM2 a 	-> Array PC5 DIM2 a  {-# INLINE forStencil2 #-}@@ -56,7 +55,7 @@ ------------------------------------------------------------------------------- -- | Apply a stencil to every element of a 2D array. mapStencil2-        :: Repr r a+        :: Source r a         => Boundary a		-- ^ How to handle the boundary of the array. 	-> Stencil DIM2 a	-- ^ Stencil to apply. 	-> Array r DIM2 a		-- ^ Array to apply stencil to.@@ -113,9 +112,9 @@         {-# INLINE getBorder' #-}         getBorder' ix          = case boundary of-                BoundConst c    -> c-                BoundClamp      -> unsafeAppStencilCursor2_clamp addDim stencil-                                        arr ix+                BoundFixed c    -> c+                BoundConst c    -> unsafeAppStencilCursor2_const addDim stencil c arr ix+                BoundClamp      -> unsafeAppStencilCursor2_clamp addDim stencil arr ix     in     --  internal region@@ -130,7 +129,7 @@   unsafeAppStencilCursor2-	:: Repr r a+	:: Source r a 	=> (DIM2 -> Cursor -> Cursor) 	-> Stencil DIM2 a 	-> Array r DIM2 a@@ -163,10 +162,59 @@                 , " It must fit within a 7x7 tile to be compiled statically." ]  +-- | Like above, but treat elements outside the array has having a constant value.+unsafeAppStencilCursor2_const+        :: forall r a+        .  Source r a+        => (DIM2 -> DIM2 -> DIM2)+        -> Stencil DIM2 a+        -> a+        -> Array r DIM2 a+        -> DIM2+        -> a++{-# INLINE unsafeAppStencilCursor2_const #-}+unsafeAppStencilCursor2_const shift+           (StencilStatic sExtent zero loads)+           fixed arr cur++        | _ :. 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 :. (I# y) :. (I# x))+                 = getData' x y++                {-# NOINLINE getData' #-}+                getData' :: Int# -> Int# -> a+                getData' !x !y+                 | x <# 0#       = fixed+                 | x >=# aWidth  = fixed+                 | y <# 0#       = fixed+                 | y >=# aHeight = fixed+                 | otherwise     = arr `unsafeIndex` (Z :. (I# y) :.  (I# x))++                -- Build a function to pass data from the array to our stencil.+                {-# INLINE oload #-}+                oload oy ox+                 = let  !cur' = shift (Z :. oy :. ox) cur+                   in   loads (Z :. oy :. ox) (getData cur')++           in   template7x7 oload zero++        | otherwise+        = error $ unlines +                [ "mapStencil2: Your stencil is too big for this method."+                , " It must fit within a 7x7 tile to be compiled statically." ]++ -- | Like above, but clamp out of bounds array values to the closest real value. unsafeAppStencilCursor2_clamp 	:: forall r a-	.  Repr r a+	.  Source r a 	=> (DIM2 -> DIM2 -> DIM2) 	-> Stencil DIM2 a 	-> Array r DIM2 a
repa.cabal view
@@ -1,5 +1,5 @@ Name:                repa-Version:             3.1.4.2+Version:             3.2.1.1 License:             BSD3 License-file:        LICENSE Author:              The DPH Team@@ -82,7 +82,8 @@         Data.Array.Repa.Eval.Cursored         Data.Array.Repa.Eval.Interleaved         Data.Array.Repa.Eval.Elt-        Data.Array.Repa.Eval.Fill+        Data.Array.Repa.Eval.Target+        Data.Array.Repa.Eval.Load         Data.Array.Repa.Eval.Reduction         Data.Array.Repa.Eval.Selection         Data.Array.Repa.Stencil.Base