Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V2: Add an instance for the new SeedGen type class #98

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion System/Random/MWC.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# LANGUAGE BangPatterns, CPP, DeriveDataTypeable, FlexibleContexts,
{-# LANGUAGE BangPatterns, CPP, DataKinds, DeriveDataTypeable, FlexibleContexts,
FlexibleInstances, MultiParamTypeClasses, MagicHash, Rank2Types,
ScopedTypeVariables, TypeFamilies, UnboxedTuples, TypeOperators
#-}
Expand Down Expand Up @@ -177,6 +177,9 @@
import qualified Control.Exception as E
import System.Random.MWC.SeedSource
import qualified System.Random.Stateful as Random
#if MIN_VERSION_random(1,3,0)
import Data.List.NonEmpty (NonEmpty(..), toList)
#endif

-- | NOTE: Consider use of more principled type classes
-- 'Random.Uniform' and 'Random.UniformRange' instead.
Expand Down Expand Up @@ -443,7 +446,7 @@

-- | An immutable snapshot of the state of a 'Gen'.
newtype Seed = Seed (I.Vector Word32)
deriving (Eq, Show, Typeable)

Check warning on line 449 in System/Random/MWC.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.12.1 [1.2]

• Deriving ‘Typeable’ has no effect: all types now auto-derive Typeable

Check warning on line 449 in System/Random/MWC.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.12.1 [1.3]

• Deriving ‘Typeable’ has no effect: all types now auto-derive Typeable

Check warning on line 449 in System/Random/MWC.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 9.12.1 []

• Deriving ‘Typeable’ has no effect: all types now auto-derive Typeable

Check warning on line 449 in System/Random/MWC.hs

View workflow job for this annotation

GitHub Actions / macOS-latest / ghc 9.12.1 []

• Deriving ‘Typeable’ has no effect: all types now auto-derive Typeable

-- | Convert seed into vector.
fromSeed :: Seed -> I.Vector Word32
Expand Down Expand Up @@ -486,6 +489,28 @@
#endif
thawGen = restore

#if MIN_VERSION_random(1,3,0)
instance Random.SeedGen Seed where
type SeedSize Seed = 1032 -- == 4 * 258
fromSeed64 seed64 = toSeed $ I.fromListN 258
[ w32
| !w64 <- toList seed64
, !w32 <- [ fromIntegral (w64 `shiftR` 32)
, fromIntegral w64 ]
]
toSeed64 vSeed =
let w32sToW64 :: Word32 -> Word32 -> Word64
w32sToW64 w32u w32l =
(fromIntegral w32u `shiftL` 32) .|. fromIntegral w32l
v = fromSeed vSeed
evens = I.ifilter (\i _ -> even i) v
odds = I.ifilter (\i _ -> odd i) v
in case I.toList $ I.zipWith w32sToW64 evens odds of
[] ->
error $ "Impossible: Seed had an unexpected length of: " ++ show (I.length v)
x:xs -> x :| xs
#endif

-- | Convert vector to 'Seed'. It acts similarly to 'initialize' and
-- will accept any vector. If you want to pass seed immediately to
-- restore you better call initialize directly since following law holds:
Expand Down
13 changes: 11 additions & 2 deletions bench/Benchmark.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
module Main(main) where

import Control.Exception
Expand Down Expand Up @@ -48,8 +49,9 @@
opts <- parseOptions ingredients (bench "Fake" (nf id ()))
let iter = lookupOption opts
-- Set up RNG
mwc <- create
mtg <- M.newMTGen . Just =<< uniform mwc
mwc <- create
seed <- save mwc

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 8.0.2 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 8.2.2 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 8.2.2 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 8.10.7 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 8.10.7 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 8.6.5 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 8.6.5 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.0.2 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.0.2 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 8.4.4 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 8.4.4 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 8.8.4 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 8.8.4 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.6.6 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.6.6 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.4.8 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.4.8 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.2.8 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.2.8 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.8.4 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.8.4 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.10.1 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.10.1 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.12.1 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest / ghc 9.12.1 [1.2]

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 8.4.4 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 8.6.5 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 9.0.2 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 9.4.8 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 9.2.8 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 8.10.7 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 9.8.4 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 9.6.6 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 9.10.1 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / macOS-13 / ghc 8.4.4 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 9.12.1 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / macOS-13 / ghc 8.8.4 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / macOS-13 / ghc 8.10.7 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / macOS-13 / ghc 9.0.2 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / macOS-13 / ghc 8.6.5 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / macOS-latest / ghc 9.4.8 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / macOS-latest / ghc 9.8.4 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / macOS-latest / ghc 9.6.6 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / macOS-latest / ghc 9.12.1 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / macOS-latest / ghc 9.2.8 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / macOS-latest / ghc 9.10.1 []

Defined but not used: ‘seed’

Check warning on line 53 in bench/Benchmark.hs

View workflow job for this annotation

GitHub Actions / windows-latest / ghc 8.8.4 []

Defined but not used: ‘seed’
mtg <- M.newMTGen . Just =<< uniform mwc
defaultMainWithIngredients ingredients $ bgroup "All"
[ bgroup "mwc"
-- One letter group names are used so they will fit on the plot.
Expand Down Expand Up @@ -148,6 +150,13 @@
bench "Double" $ whnfIO $ loop iter (M.random mtg :: IO Double)
, bench "Int" $ whnfIO $ loop iter (M.random mtg :: IO Int)
]
#if MIN_VERSION_random(1,3,0)
, bgroup "seed"
[ bench "SeedGen.fromSeed" $ let rseed = R.toSeed seed :: R.Seed Seed
in whnf R.fromSeed rseed
, bench "SeedGen.toSeed" $ whnf R.toSeed seed
]
#endif
]

betaBinomial :: StatefulGen g m => Double -> Double -> Int -> g -> m Int
Expand Down
18 changes: 16 additions & 2 deletions tests/props.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE ViewPatterns #-}
import Control.Monad
import Data.Word
Expand All @@ -16,6 +17,9 @@ import Test.QuickCheck.Monadic
import System.Random.MWC
import System.Random.MWC.Distributions
import System.Random.Stateful (StatefulGen)
#if MIN_VERSION_random(1,3,0)
import qualified System.Random.Stateful as Random (SeedGen(..))
#endif

----------------------------------------------------------------
--
Expand Down Expand Up @@ -65,6 +69,9 @@ main = do
g0 <- createSystemRandom
defaultMainWithIngredients ingredients $ testGroup "mwc"
[ testProperty "save/restore" $ prop_SeedSaveRestore g0
#if MIN_VERSION_random(1,3,0)
, testProperty "SeedGen" $ prop_SeedGen g0
#endif
, testCase "user save/restore" $ saveRestoreUserSeed
, testCase "empty seed data" $ emptySeed
, testCase "output correct" $ do
Expand All @@ -76,8 +83,7 @@ main = do
]

updateGenState :: GenIO -> IO ()
updateGenState g = replicateM_ 256 (uniform g :: IO Word32)

updateGenState g = replicateM_ 250 (uniform g :: IO Word32)

prop_SeedSaveRestore :: GenIO -> Property
prop_SeedSaveRestore g = monadicIO $ do
Expand All @@ -86,6 +92,14 @@ prop_SeedSaveRestore g = monadicIO $ do
seed' <- run $ save =<< restore seed
return $ seed == seed'

#if MIN_VERSION_random(1,3,0)
prop_SeedGen :: GenIO -> Property
prop_SeedGen g = monadicIO $ do
run $ updateGenState g
seed <- run $ save g
return $ seed == (Random.fromSeed . Random.toSeed) seed
#endif

saveRestoreUserSeed :: IO ()
saveRestoreUserSeed = do
let seed = toSeed $ U.replicate 258 0
Expand Down
Loading