repa 3.2.1.1 → 3.2.2.1
raw patch · 10 files changed
+107/−35 lines, 10 filesdep ~QuickCheckdep ~basedep ~bytestring
Dependency ranges changed: QuickCheck, base, bytestring, ghc-prim, template-haskell
Files
- Data/Array/Repa/Eval.hs +1/−1
- Data/Array/Repa/Eval/Chunked.hs +72/−14
- Data/Array/Repa/Eval/Cursored.hs +2/−3
- Data/Array/Repa/Eval/Gang.hs +1/−1
- Data/Array/Repa/Operators/Mapping.hs +15/−0
- Data/Array/Repa/Repr/Delayed.hs +1/−1
- Data/Array/Repa/Stencil/Base.hs +2/−2
- Data/Array/Repa/Stencil/Dim2.hs +6/−6
- Data/Array/Repa/Stencil/Template.hs +1/−1
- repa.cabal +6/−6
Data/Array/Repa/Eval.hs view
@@ -17,7 +17,7 @@ , now -- * Chunked filling- , fillChunkedS+ , fillLinearS , fillChunkedP , fillChunkedIOP
Data/Array/Repa/Eval/Chunked.hs view
@@ -2,37 +2,87 @@ -- | Evaluate an array by breaking it up into linear chunks and filling -- each chunk in parallel. module Data.Array.Repa.Eval.Chunked- ( fillChunkedP- , fillChunkedS+ ( fillLinearS+ , fillBlock2S+ , fillChunkedP , fillChunkedIOP) where+import Data.Array.Repa.Index import Data.Array.Repa.Eval.Gang+ import GHC.Exts import Prelude as P +------------------------------------------------------------------------------- -- | Fill something sequentially. -- -- * The array is filled linearly from start to finish. -- -fillChunkedS+fillLinearS :: Int -- ^ Number of elements. -> (Int -> a -> IO ()) -- ^ Update function to write into result buffer. -> (Int -> a) -- ^ Fn to get the value at a given index. -> IO () -{-# INLINE [0] fillChunkedS #-}-fillChunkedS !(I# len) write getElem+fillLinearS !(I# len) write getElem = fill 0# where fill !ix | ix >=# len = return () | otherwise = do write (I# ix) (getElem (I# ix)) fill (ix +# 1#)+{-# INLINE [0] fillLinearS #-} +-------------------------------------------------------------------------------+-- | Fill a block in a rank-2 array, sequentially.+--+-- * Blockwise filling can be more cache-efficient than linear filling for+-- rank-2 arrays.+--+-- * The block is filled in row major order from top to bottom.+--+fillBlock2S+ :: (Int -> a -> IO ()) -- ^ Update function to write into result buffer.+ -> (DIM2 -> a) -- ^ Fn to get the value at the given index.+ -> Int# -- ^ Width of the whole array.+ -> Int# -- ^ x0 lower left corner of block to fill.+ -> Int# -- ^ y0+ -> Int# -- ^ w0 width of block to fill+ -> Int# -- ^ h0 height of block to fill+ -> IO ()++fillBlock2S+ write getElem+ !imageWidth !x0 !y0 !w0 h0++ = do fillBlock y0 ix0+ where !x1 = x0 +# w0+ !y1 = y0 +# h0+ !ix0 = x0 +# (y0 *# imageWidth)++ {-# INLINE fillBlock #-}+ fillBlock !y !ix+ | y >=# y1 = return ()+ | otherwise+ = do fillLine1 x0 ix+ fillBlock (y +# 1#) (ix +# imageWidth)++ where {-# INLINE fillLine1 #-}+ fillLine1 !x !ix'+ | x >=# x1 = return ()+ | otherwise+ = do write (I# ix') (getElem (Z :. (I# y) :. (I# x)))+ fillLine1 (x +# 1#) (ix' +# 1#)++{-# INLINE [0] fillBlock2S #-}+++------------------------------------------------------------------------------- -- | Fill something in parallel. -- --- * The array is split into linear chunks and each thread fills one chunk.+-- * The array is split into linear chunks,+-- and each thread linearly fills one chunk. -- fillChunkedP :: Int -- ^ Number of elements.@@ -40,7 +90,6 @@ -> (Int -> a) -- ^ Fn to get the value at a given index. -> IO () -{-# INLINE [0] fillChunkedP #-} fillChunkedP !(I# len) write getElem = gangIO theGang $ \(I# thread) -> @@ -68,18 +117,25 @@ | otherwise = do write (I# ix) (getElem (I# ix)) fill (ix +# 1#) end+{-# INLINE [0] fillChunkedP #-} +------------------------------------------------------------------------------- -- | Fill something in parallel, using a separate IO action for each thread.+--+-- * The array is split into linear chunks,+-- and each thread linearly fills one chunk.+-- fillChunkedIOP- :: Int -- ^ Number of elements.- -> (Int -> a -> IO ()) -- ^ Update fn to write into result buffer.- -> (Int -> IO (Int -> IO a)) -- ^ Create a fn to get the value at a given index.- -- The first `Int` is the thread number, so you can do some- -- per-thread initialisation.+ :: Int -- ^ Number of elements.+ -> (Int -> a -> IO ()) + -- ^ Update fn to write into result buffer.+ -> (Int -> IO (Int -> IO a)) + -- ^ Create a fn to get the value at a given index.+ -- The first `Int` is the thread number, so you can do some+ -- per-thread initialisation. -> IO () -{-# INLINE [0] fillChunkedIOP #-} fillChunkedIOP !(I# len) write mkGetElem = gangIO theGang $ \(I# thread) -> @@ -100,7 +156,6 @@ | thread <# chunkLeftover = thread *# (chunkLen +# 1#) | otherwise = thread *# chunkLen +# chunkLeftover - -- Given the threadId, starting and ending indices. -- Make a function to get each element for this chunk -- and call it for every index.@@ -120,3 +175,6 @@ = do x <- getElem (I# ix) write (I# ix) x go (ix +# 1#)+{-# INLINE [0] fillChunkedIOP #-}++
Data/Array/Repa/Eval/Cursored.hs view
@@ -3,7 +3,6 @@ -- each block in parallel. module Data.Array.Repa.Eval.Cursored ( fillBlock2P- , fillBlock2S , fillCursoredBlock2P , fillCursoredBlock2S ) where@@ -43,7 +42,7 @@ write id addDim getElem imageWidth x0 y0 w0 h0 -+{- -- | Fill a block in a rank-2 array sequentially. -- -- * Blockwise filling can be more cache-efficient than linear filling for@@ -69,7 +68,7 @@ = fillCursoredBlock2S write id addDim getElem imageWidth x0 y0 w0 h0-+-} -- Block filling ---------------------------------------------------------------------------------- -- | Fill a block in a rank-2 array in parallel.
Data/Array/Repa/Eval/Gang.hs view
@@ -100,7 +100,7 @@ -- Add finalisers so we can shut the workers down cleanly if they -- become unreachable. zipWithM_ (\varReq varDone - -> addMVarFinalizer varReq (finaliseWorker varReq varDone)) + -> mkWeakMVar varReq (finaliseWorker varReq varDone)) mvsRequest mvsDone
Data/Array/Repa/Operators/Mapping.hs view
@@ -16,6 +16,7 @@ import Data.Array.Repa.Repr.Delayed import Data.Array.Repa.Repr.ForeignPtr import Data.Array.Repa.Repr.HintSmall+import Data.Array.Repa.Repr.HintInterleave import Data.Array.Repa.Repr.Partitioned import Data.Array.Repa.Repr.Unboxed import Data.Array.Repa.Repr.Undefined@@ -176,6 +177,20 @@ szipWith f arr1 (ASmall arr2) = ASmall (szipWith f arr1 arr2)+ {-# INLINE [3] szipWith #-}+++-- Interleaved ------------------------+instance Structured r1 a b+ => Structured (I r1) a b where+ type TR (I r1) = I (TR r1)++ smap f (AInterleave arr1)+ = AInterleave (smap f arr1)+ {-# INLINE [3] smap #-}++ szipWith f arr1 (AInterleave arr2)+ = AInterleave (szipWith f arr1 arr2) {-# INLINE [3] szipWith #-}
Data/Array/Repa/Repr/Delayed.hs view
@@ -57,7 +57,7 @@ loadS (ADelayed sh getElem) mvec = mvec `deepSeqMVec` do traceEventIO "Repa.loadS[Delayed]: start"- fillChunkedS (size sh) (unsafeWriteMVec mvec) (getElem . fromIndex sh)+ fillLinearS (size sh) (unsafeWriteMVec mvec) (getElem . fromIndex sh) touchMVec mvec traceEventIO "Repa.loadS[Delayed]: end" {-# INLINE [4] loadS #-}
Data/Array/Repa/Stencil/Base.hs view
@@ -10,10 +10,10 @@ -- | How to handle the case when the stencil lies partly outside the array. data Boundary a -- | Use a fixed value for border regions.- = BoundFixed a+ = BoundFixed !a -- | Treat points outside the array as having a constant value.- | BoundConst a+ | BoundConst !a -- | Clamp points outside to the same value as the edge pixel. | BoundClamp
Data/Array/Repa/Stencil/Dim2.hs view
@@ -115,7 +115,6 @@ BoundFixed c -> c BoundConst c -> unsafeAppStencilCursor2_const addDim stencil c arr ix BoundClamp -> unsafeAppStencilCursor2_clamp addDim stencil arr ix- in -- internal region APart sh (Range (Z :. inY :. inX) (Z :. inH :. inW) inInternal) arrInternal@@ -191,11 +190,12 @@ {-# 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))+ | x <# 0# || x >=# aWidth+ || y <# 0# || 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 #-}
Data/Array/Repa/Stencil/Template.hs view
@@ -92,7 +92,7 @@ $ AppE (VarE (mkName "makeStencil2") `AppE` (LitE (IntegerL sizeX)) `AppE` (LitE (IntegerL sizeY)))- $ LetE [ PragmaD (InlineP (mkName "coeffs") (InlineSpec True False Nothing))+ $ LetE [ PragmaD (InlineP (mkName "coeffs") Inline FunLike (BeforePhase 0)) , ValD (VarP coeffs') (NormalB fnCoeffs) [] ] (VarE (mkName "coeffs"))
repa.cabal view
@@ -1,5 +1,5 @@ Name: repa-Version: 3.2.1.1+Version: 3.2.2.1 License: BSD3 License-file: LICENSE Author: The DPH Team@@ -23,12 +23,12 @@ Library Build-Depends: - base == 4.*,- ghc-prim == 0.2.*,+ base == 4.6.*,+ ghc-prim == 0.3.*, vector == 0.9.*,- bytestring == 0.9.*,- QuickCheck >= 2.3 && < 2.5,- template-haskell >= 2.5 && < 2.8+ bytestring == 0.10.*,+ template-haskell == 2.8.*,+ QuickCheck >= 2.3 && < 2.6 ghc-options: -Wall -fno-warn-missing-signatures