module ELynx.Tools.Concurrent
(
getNGen
, splitGen
, getChunks
, parMapChunk
) where
import Control.Monad
import Control.Parallel.Strategies
import qualified Data.Vector as V
import Data.Word
import System.Random.MWC
getNGen :: Int -> Maybe [Word32] -> IO [GenIO]
getNGen n ms = do
g <- maybe createSystemRandom (initialize . V.fromList) ms
splitGen n g
splitGen :: Int -> GenIO -> IO [GenIO]
splitGen n gen
| n <= 0 = return []
| otherwise =
fmap (gen:) . replicateM (n-1) $
initialize =<< (uniformVector gen 256 :: IO (V.Vector Word32))
getChunks :: Int -> Int -> [Int]
getChunks c n = ns
where n' = n `div` c
r = n `mod` c
ns = replicate r (n'+1) ++ replicate (c - r) n'
parMapChunk :: Int -> (a -> b) -> [a] -> [b]
parMapChunk n f as = map f as `using` parListChunk n rseq