repa 3.1.4.2 → 3.2.1.1
raw patch · 25 files changed
+617/−514 lines, 25 files
Files
- Data/Array/Repa.hs +19/−6
- Data/Array/Repa/Base.hs +15/−16
- Data/Array/Repa/Eval.hs +25/−17
- Data/Array/Repa/Eval/Fill.hs +0/−78
- Data/Array/Repa/Eval/Load.hs +36/−0
- Data/Array/Repa/Eval/Target.hs +49/−0
- Data/Array/Repa/Operators/IndexSpace.hs +16/−17
- Data/Array/Repa/Operators/Interleave.hs +8/−5
- Data/Array/Repa/Operators/Mapping.hs +81/−70
- Data/Array/Repa/Operators/Reduction.hs +15/−16
- Data/Array/Repa/Operators/Traversal.hs +8/−7
- Data/Array/Repa/Repr/ByteString.hs +11/−11
- Data/Array/Repa/Repr/Cursored.hs +38/−36
- Data/Array/Repa/Repr/Delayed.hs +42/−43
- Data/Array/Repa/Repr/ForeignPtr.hs +26/−26
- Data/Array/Repa/Repr/HintInterleave.hs +31/−29
- Data/Array/Repa/Repr/HintSmall.hs +35/−34
- Data/Array/Repa/Repr/Partitioned.hs +21/−18
- Data/Array/Repa/Repr/Unboxed.hs +29/−27
- Data/Array/Repa/Repr/Undefined.hs +16/−14
- Data/Array/Repa/Repr/Vector.hs +27/−27
- Data/Array/Repa/Specialised/Dim2.hs +1/−1
- Data/Array/Repa/Stencil/Base.hs +5/−2
- Data/Array/Repa/Stencil/Dim2.hs +60/−12
- repa.cabal +3/−2
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