module Data.Array.Repa.Internals.EvalCursored
( fillCursoredBlock2P
, fillCursoredBlock2 )
where
import Data.Array.Repa.Index
import Data.Array.Repa.Internals.Elt
import Data.Array.Repa.Internals.Gang
import Data.Vector.Unboxed.Mutable as VM
import GHC.Base (remInt, quotInt)
import Prelude as P
fillCursoredBlock2P
:: Elt a
=> IOVector a
-> (DIM2 -> cursor)
-> (DIM2 -> cursor -> cursor)
-> (cursor -> a)
-> Int
-> Int
-> Int
-> Int
-> Int
-> IO ()
fillCursoredBlock2P
!vec
!makeCursorFCB !shiftCursorFCB !getElemFCB
!imageWidth !x0 !y0 !x1 !y1
= gangIO theGang fillBlock
where !threads = gangSize theGang
!blockWidth = x1 x0 + 1
!colChunkLen = blockWidth `quotInt` threads
!colChunkSlack = blockWidth `remInt` threads
colIx !ix
| ix < colChunkSlack = x0 + ix * (colChunkLen + 1)
| otherwise = x0 + ix * colChunkLen + colChunkSlack
fillBlock :: Int -> IO ()
fillBlock !ix
= let !x0' = colIx ix
!x1' = colIx (ix + 1) 1
!y0' = y0
!y1' = y1
in fillCursoredBlock2
vec
makeCursorFCB shiftCursorFCB getElemFCB
imageWidth x0' y0' x1' y1'
fillCursoredBlock2
:: Elt a
=> IOVector a
-> (DIM2 -> cursor)
-> (DIM2 -> cursor -> cursor)
-> (cursor -> a)
-> Int
-> Int
-> Int
-> Int
-> Int
-> IO ()
fillCursoredBlock2
!vec
!makeCursor !shiftCursor !getElem
!imageWidth !x0 !y0 !x1 !y1
= fillBlock y0
where
fillBlock !y
| y > y1 = return ()
| otherwise
= do fillLine4 x0
fillBlock (y + 1)
where
fillLine4 !x
| x + 4 > x1 = fillLine1 x
| otherwise
= do
let srcCur0 = makeCursor (Z :. y :. x)
let srcCur1 = shiftCursor (Z :. 0 :. 1) srcCur0
let srcCur2 = shiftCursor (Z :. 0 :. 1) srcCur1
let srcCur3 = shiftCursor (Z :. 0 :. 1) srcCur2
let val0 = getElem srcCur0
let val1 = getElem srcCur1
let val2 = getElem srcCur2
let val3 = getElem srcCur3
touch val0
touch val1
touch val2
touch val3
let !dstCur0 = x + y * imageWidth
VM.unsafeWrite vec (dstCur0) val0
VM.unsafeWrite vec (dstCur0 + 1) val1
VM.unsafeWrite vec (dstCur0 + 2) val2
VM.unsafeWrite vec (dstCur0 + 3) val3
fillLine4 (x + 4)
fillLine1 !x
| x > x1 = return ()
| otherwise
= do VM.unsafeWrite vec (x + y * imageWidth) (getElem $ makeCursor (Z :. y :. x))
fillLine1 (x + 1)