module Data.Array.Repa.Internals.EvalChunked
( fillChunkedS
, fillChunkedP)
where
import Data.Array.Repa.Internals.Elt
import Data.Array.Repa.Internals.Gang
import Data.Vector.Unboxed as V
import Data.Vector.Unboxed.Mutable as VM
import GHC.Base (remInt, quotInt)
import Prelude as P
fillChunkedS
:: Elt a
=> IOVector a
-> (Int -> a)
-> IO ()
fillChunkedS !vec !getElem
= fill 0
where !len = VM.length vec
fill !ix
| ix >= len = return ()
| otherwise
= do VM.unsafeWrite vec ix (getElem ix)
fill (ix + 1)
fillChunkedP
:: Unbox a
=> IOVector a
-> (Int -> a)
-> IO ()
fillChunkedP !vec !getElem
= gangIO theGang
$ \thread -> fill (splitIx thread) (splitIx (thread + 1))
where
!threads = gangSize theGang
!len = VM.length vec
!chunkLen = len `quotInt` threads
!chunkLeftover = len `remInt` threads
splitIx thread
| thread < chunkLeftover = thread * (chunkLen + 1)
| otherwise = thread * chunkLen + chunkLeftover
fill !ix !end
| ix >= end = return ()
| otherwise
= do VM.unsafeWrite vec ix (getElem ix)
fill (ix + 1) end