module Data.Repa.Eval.Generic.Par.Chunked
( fillChunked
, fillChunkedIO)
where
import Data.Repa.Eval.Gang
import GHC.Exts
fillChunked
:: Gang
-> (Int# -> a -> IO ())
-> (Int# -> a)
-> Int#
-> IO ()
fillChunked :: forall a.
Gang -> (Int# -> a -> IO ()) -> (Int# -> a) -> Int# -> IO ()
fillChunked Gang
gang Int# -> a -> IO ()
write Int# -> a
getElem Int#
len
= Gang -> (Int# -> IO ()) -> IO ()
gangIO Gang
gang
((Int# -> IO ()) -> IO ()) -> (Int# -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int#
thread ->
let !start :: Int#
start = Int# -> Int#
splitIx Int#
thread
!end :: Int#
end = Int# -> Int#
splitIx (Int#
thread Int# -> Int# -> Int#
+# Int#
1#)
in Int# -> Int# -> IO ()
fill Int#
start Int#
end
where
!threads :: Int#
threads = Gang -> Int#
gangSize Gang
gang
!chunkLen :: Int#
chunkLen = Int#
len Int# -> Int# -> Int#
`quotInt#` Int#
threads
!chunkLeftover :: Int#
chunkLeftover = Int#
len Int# -> Int# -> Int#
`remInt#` Int#
threads
splitIx :: Int# -> Int#
splitIx Int#
thread
| Int#
1# <- Int#
thread Int# -> Int# -> Int#
<# Int#
chunkLeftover = Int#
thread Int# -> Int# -> Int#
*# (Int#
chunkLen Int# -> Int# -> Int#
+# Int#
1#)
| Bool
otherwise = Int#
thread Int# -> Int# -> Int#
*# Int#
chunkLen Int# -> Int# -> Int#
+# Int#
chunkLeftover
{-# INLINE splitIx #-}
fill :: Int# -> Int# -> IO ()
fill !Int#
ix !Int#
end
| Int#
1# <- Int#
ix Int# -> Int# -> Int#
>=# Int#
end = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise
= do Int# -> a -> IO ()
write Int#
ix (Int# -> a
getElem Int#
ix)
Int# -> Int# -> IO ()
fill (Int#
ix Int# -> Int# -> Int#
+# Int#
1#) Int#
end
{-# INLINE fill #-}
{-# INLINE [0] fillChunked #-}
fillChunkedIO
:: Gang
-> (Int# -> a -> IO ())
-> (Int# -> IO (Int# -> IO a))
-> Int#
-> IO ()
fillChunkedIO :: forall a.
Gang
-> (Int# -> a -> IO ())
-> (Int# -> IO (Int# -> IO a))
-> Int#
-> IO ()
fillChunkedIO Gang
gang Int# -> a -> IO ()
write Int# -> IO (Int# -> IO a)
mkGetElem Int#
len
= Gang -> (Int# -> IO ()) -> IO ()
gangIO Gang
gang
((Int# -> IO ()) -> IO ()) -> (Int# -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int#
thread ->
let !start :: Int#
start = Int# -> Int#
splitIx Int#
thread
!end :: Int#
end = Int# -> Int#
splitIx (Int#
thread Int# -> Int# -> Int#
+# Int#
1#)
in Int# -> Int# -> Int# -> IO ()
fillChunk Int#
thread Int#
start Int#
end
where
!threads :: Int#
threads = Gang -> Int#
gangSize Gang
gang
!chunkLen :: Int#
chunkLen = Int#
len Int# -> Int# -> Int#
`quotInt#` Int#
threads
!chunkLeftover :: Int#
chunkLeftover = Int#
len Int# -> Int# -> Int#
`remInt#` Int#
threads
splitIx :: Int# -> Int#
splitIx Int#
thread
| Int#
1# <- Int#
thread Int# -> Int# -> Int#
<# Int#
chunkLeftover = Int#
thread Int# -> Int# -> Int#
*# (Int#
chunkLen Int# -> Int# -> Int#
+# Int#
1#)
| Bool
otherwise = Int#
thread Int# -> Int# -> Int#
*# Int#
chunkLen Int# -> Int# -> Int#
+# Int#
chunkLeftover
{-# INLINE splitIx #-}
fillChunk :: Int# -> Int# -> Int# -> IO ()
fillChunk !Int#
thread !Int#
ixStart !Int#
ixEnd
= do Int# -> IO a
getElem <- Int# -> IO (Int# -> IO a)
mkGetElem Int#
thread
(Int# -> IO a) -> Int# -> Int# -> IO ()
fill Int# -> IO a
getElem Int#
ixStart Int#
ixEnd
{-# INLINE fillChunk #-}
fill :: (Int# -> IO a) -> Int# -> Int# -> IO ()
fill !Int# -> IO a
getElem !Int#
ix0 !Int#
end
= Int# -> IO ()
go Int#
ix0
where go :: Int# -> IO ()
go !Int#
ix
| Int#
1# <- Int#
ix Int# -> Int# -> Int#
>=# Int#
end = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise
= do a
x <- Int# -> IO a
getElem Int#
ix
Int# -> a -> IO ()
write Int#
ix a
x
Int# -> IO ()
go (Int#
ix Int# -> Int# -> Int#
+# Int#
1#)
{-# INLINE fill #-}
{-# INLINE [0] fillChunkedIO #-}