randomgen (empty) → 0.1
raw patch · 4 files changed
+174/−0 lines, 4 filesdep +basedep +binarydep +bytestringsetup-changed
Dependencies added: base, binary, bytestring, mersenne-random-pure64
Files
- LICENSE +30/−0
- Main.hs +113/−0
- Setup.lhs +3/−0
- randomgen.cabal +28/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2008 Adam Wick++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.++3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.
+ Main.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE ForeignFunctionInterface #-}++import System.Random.Mersenne.Pure64+import Control.Concurrent+import Control.Monad+import Data.Binary.Put+import qualified Data.ByteString.Lazy as BS+import qualified Data.ByteString as S+import Data.Word+import Foreign.Marshal.Alloc+import Foreign.Ptr+import Foreign.Storable+import System.Environment+import GHC.Conc+import Foreign.C.Types+import Debug.Trace+import System.IO+++--+-- Parallel unfold and reduce.+--+-- -lcrypto+--++main :: IO ()+main = do+ args <- getArgs+ case args of+ [file, size] -> checkReasonableAndGo (Just (show numCapabilities)) file size+ [cpus, file, size] -> checkReasonableAndGo (Just cpus) file size+ _ -> dumpUsageAndQuit++dumpUsageAndQuit :: IO ()+dumpUsageAndQuit = mapM_ putStrLn+ ["USAGE: genblock [cpus] filename size"+ ,"where 'size' is given in gigabytes"+ ,"and cpus defaults to the value of +RTS -N"]++checkReasonableAndGo :: Maybe String -> String -> String -> IO ()+checkReasonableAndGo mcpus file size =+ case (maybe [(numCapabilities, "")] reads mcpus, reads size) of+ ([(cpus, "")], [(size', "")]) -> go cpus file size'+ _ -> dumpUsageAndQuit++go :: Int -> String -> Int -> IO ()+go cpus filename size_in_gb = do+ chan <- newChan+ forM_ [1..cpus] $ \n -> forkIO {-n-} $ do+ baseMT <- pureMT `fmap` getOpenSSLRand+ writeList2Chan chan $+ BS.toChunks $ runPut $ mersennePut baseMT++ ls <- getChanContents chan -- TODO need a LBS chan+ BS.writeFile filename . BS.take size . BS.fromChunks $ ls++ where+ size = fromIntegral size_in_gb * 1024 * 1024 * 1024+++-- unroll the loop+mersennePut :: PureMT -> Put+mersennePut mt = do++ let (k, mt1) = randomWord64 mt+ putWord64host k+ let (k, mt2) = randomWord64 mt1+ putWord64host k+ let (k, mt3) = randomWord64 mt2+ putWord64host k+ let (k, mt4) = randomWord64 mt3+ putWord64host k+ let (k, mt5) = randomWord64 mt4+ putWord64host k+ let (k, mt6) = randomWord64 mt5+ putWord64host k+ let (k, mt7) = randomWord64 mt6+ putWord64host k+ let (k, mt8) = randomWord64 mt7+ putWord64host k+ let (k, mt9) = randomWord64 mt8+ putWord64host k+ let (k, mt10) = randomWord64 mt9+ putWord64host k+ let (k, mt11) = randomWord64 mt10+ putWord64host k+ let (k, mt12) = randomWord64 mt11+ putWord64host k+ let (k, mt13) = randomWord64 mt12+ putWord64host k+ let (k, mt14) = randomWord64 mt13+ putWord64host k+ let (k, mt15) = randomWord64 mt14+ putWord64host k+ let (k, mt16) = randomWord64 mt15+ putWord64host k+ mersennePut mt16++------------------------------------------------------------------------++--+-- Get a decent random seed+--+getOpenSSLRand :: IO Word64+getOpenSSLRand = allocaBytes n $ \ ptr -> do+ fill_RAND_bytes ptr (fromIntegral n)+ peek $ castPtr ptr+ where+ n = sizeOf (undefined :: Word64)++foreign import ccall unsafe "openssl/rand.h RAND_bytes"+ fill_RAND_bytes :: Ptr Word8 -> CInt -> IO ()+
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ randomgen.cabal view
@@ -0,0 +1,28 @@+name: randomgen+version: 0.1+homepage: http://galois.com+synopsis: A fast, SMP parallel random data generator+description: A fast, SMP parallel random data generator+ .+ To generate 10G of high quality pseudorandom+ data, using 4 processors to fill the file:+ .+ $ randomgen "data" 10 +RTS -N4+ .+category: System+license: BSD3+license-file: LICENSE+author: Adam Wick+maintainer: awick@haskell.org+cabal-version: >= 1.2+build-type: Simple++executable randomgen+ main-is: Main.hs+ ghc-options: -O2 -threaded+ extensions: ForeignFunctionInterface+ build-depends: base,+ mersenne-random-pure64,+ bytestring,+ binary+ extra-libraries: crypto