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 #-}