packages feed

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 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