repa-eval-4.0.0.1: Data/Repa/Eval/Generic/Seq/Chunked.hs
module Data.Repa.Eval.Generic.Seq.Chunked
( fillLinear
, fillBlock2)
where
import GHC.Exts
-------------------------------------------------------------------------------
-- | Fill something sequentially.
--
-- * The array is filled linearly from start to finish.
--
fillLinear
:: (Int# -> a -> IO ()) -- ^ Update function to write into result buffer.
-> (Int# -> a) -- ^ Function to get the value at a given index.
-> Int# -- ^ Number of elements to fill.
-> IO ()
fillLinear write getElem len
= fill 0#
where fill !ix
| 1# <- ix >=# len = return ()
| otherwise
= do write ix (getElem ix)
fill (ix +# 1#)
{-# INLINE [0] fillLinear #-}
-------------------------------------------------------------------------------
-- | 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.
--
fillBlock2
:: (Int# -> a -> IO ()) -- ^ Update function to write into result buffer.
-> (Int# -> Int# -> a) -- ^ Function to get the value at an (x, y) 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 ()
fillBlock2
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
| 1# <- y >=# y1 = return ()
| otherwise
= do fillLine1 x0 ix
fillBlock (y +# 1#) (ix +# imageWidth)
where {-# INLINE fillLine1 #-}
fillLine1 !x !ix'
| 1# <- x >=# x1 = return ()
| otherwise
= do write ix' (getElem x y)
fillLine1 (x +# 1#) (ix' +# 1#)
{-# INLINE [0] fillBlock2 #-}