diff --git a/generation/src/Add.hs b/generation/src/Add.hs index 522b343..c272fe3 100644 --- a/generation/src/Add.hs +++ b/generation/src/Add.hs @@ -16,11 +16,8 @@ import Language.Rust.Data.Ident import Language.Rust.Data.Position import Language.Rust.Quote import Language.Rust.Syntax -import System.Random(RandomGen) - import RustModule -numTestCases :: Int -numTestCases = 3000 +import System.Random(RandomGen) safeAddOps :: RustModule safeAddOps = RustModule { @@ -28,7 +25,7 @@ safeAddOps = RustModule { outputName = "safe_add", isUnsigned = True, generator = declareSafeAddOperators, - testCase = Just generateSafeTests + testCase = Just generateSafeTest } unsafeAddOps :: RustModule @@ -37,7 +34,7 @@ unsafeAddOps = RustModule { outputName = "unsafe_add", isUnsigned = True, generator = declareUnsafeAddOperators, - testCase = Just generateUnsafeTests + testCase = Just generateUnsafeTest } safeSignedAddOps :: RustModule @@ -46,7 +43,7 @@ safeSignedAddOps = RustModule { outputName = "safe_sadd", isUnsigned = False, generator = declareSafeSignedAddOperators, - testCase = Just generateSafeSignedTests + testCase = Just generateSafeSignedTest } unsafeSignedAddOps :: RustModule @@ -55,7 +52,7 @@ unsafeSignedAddOps = RustModule { outputName = "unsafe_sadd", isUnsigned = False, generator = declareUnsafeSignedAddOperators, - testCase = Just generateUnsafeSignedTests + testCase = Just generateUnsafeSignedTest } declareSafeAddOperators :: Word -> [Word] -> SourceFile Span @@ -374,48 +371,32 @@ generateSetters useLastCarry maxI resName i where target = mkIdent resName -generateSafeTests :: RandomGen g => Word -> g -> [Map String String] -generateSafeTests size g = go g numTestCases +generateSafeTest :: RandomGen g => Word -> g -> (Map String String, g) +generateSafeTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateNum g0 size - (y, g2) = generateNum g1 size - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("z", showX (x + y))] - in tcase : go g2 (i - 1) + (x, g1) = generateNum g0 size + (y, g2) = generateNum g1 size + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX (x + y))] -generateUnsafeTests :: RandomGen g => Word -> g -> [Map String String] -generateUnsafeTests size g = go g numTestCases +generateUnsafeTest :: RandomGen g => Word -> g -> (Map String String, g) +generateUnsafeTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateNum g0 size - (y, g2) = generateNum g1 size - z = (x + y) .&. ((2 ^ size) - 1) - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("z", showX z)] - in tcase : go g2 (i - 1) + (x, g1) = generateNum g0 size + (y, g2) = generateNum g1 size + z = (x + y) .&. ((2 ^ size) - 1) + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)] -generateSafeSignedTests :: RandomGen g => Word -> g -> [Map String String] -generateSafeSignedTests size g = go g numTestCases +generateSafeSignedTest :: RandomGen g => Word -> g -> (Map String String, g) +generateSafeSignedTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateSignedNum g0 size - (y, g2) = generateSignedNum g1 size - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("z", showX (x + y))] - in tcase : go g2 (i - 1) + (x, g1) = generateSignedNum g0 size + (y, g2) = generateSignedNum g1 size + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX (x + y))] -generateUnsafeSignedTests :: RandomGen g => Word -> g -> [Map String String] -generateUnsafeSignedTests size g = go g numTestCases +generateUnsafeSignedTest :: RandomGen g => Word -> g -> (Map String String, g) +generateUnsafeSignedTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateSignedNum g0 size - (y, g2) = generateSignedNum g1 size - z = (x + y) .&. ((2 ^ size) - 1) - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("z", showX z)] - in tcase : go g2 (i - 1) + (x, g1) = generateSignedNum g0 size + (y, g2) = generateSignedNum g1 size + z = (x + y) .&. ((2 ^ size) - 1) + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)] \ No newline at end of file diff --git a/generation/src/BinaryOps.hs b/generation/src/BinaryOps.hs index 044483f..5621779 100644 --- a/generation/src/BinaryOps.hs +++ b/generation/src/BinaryOps.hs @@ -16,16 +16,13 @@ import Language.Rust.Syntax import RustModule import System.Random(RandomGen) -numTestCases :: Int -numTestCases = 3000 - binaryOps :: RustModule binaryOps = RustModule { predicate = \ _ _ -> True, outputName = "binary", isUnsigned = True, generator = declareBinaryOperators, - testCase = Just generateTests + testCase = Just generateTest } declareBinaryOperators :: Word -> [Word] -> SourceFile Span @@ -240,16 +237,13 @@ generateAllTheVariants traitname func sname oper entries = [ [expr| $$(right).value[$$(i)] |] mempty) mempty -generateTests :: RandomGen g => Word -> g -> [Map String String] -generateTests size g = go g numTestCases +generateTest :: RandomGen g => Word -> g -> (Map String String, g) +generateTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateNum g0 size - (y, g2) = generateNum g1 size - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("a", showX (x .&. y)), - ("o", showX (x .|. y)), - ("e", showX (x `xor` y)), - ("n", showX ( ((2 ^ size) - 1) `xor` x ))] - in tcase : go g2 (i - 1) + (x, g1) = generateNum g0 size + (y, g2) = generateNum g1 size + tcase = Map.fromList [("x", showX x), ("y", showX y), + ("a", showX (x .&. y)), + ("o", showX (x .|. y)), + ("e", showX (x `xor` y)), + ("n", showX ( ((2 ^ size) - 1) `xor` x ))] \ No newline at end of file diff --git a/generation/src/Compare.hs b/generation/src/Compare.hs index 5c9a5a1..43e03e2 100644 --- a/generation/src/Compare.hs +++ b/generation/src/Compare.hs @@ -12,16 +12,13 @@ import Language.Rust.Syntax import RustModule import System.Random(RandomGen) -numTestCases :: Int -numTestCases = 3000 - comparisons :: RustModule comparisons = RustModule { predicate = \ _ _ -> True, outputName = "compare", isUnsigned = True, generator = declareComparators, - testCase = Just generateTests + testCase = Just generateTest } signedComparisons :: RustModule @@ -30,7 +27,7 @@ signedComparisons = RustModule { outputName = "scompare", isUnsigned = False, generator = declareSignedComparators, - testCase = Just generateSignedTests + testCase = Just generateSignedTest } declareComparators :: Word -> [Word] -> SourceFile Span @@ -249,34 +246,28 @@ buildCompareExp i numEntries where x = Lit [] (Int Dec (fromIntegral i) Unsuffixed mempty) mempty -generateTests :: RandomGen g => Word -> g -> [Map String String] -generateTests size g = go g numTestCases +generateTest :: RandomGen g => Word -> g -> (Map String String, g) +generateTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateNum g0 size - (y, g2) = generateNum g1 size - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("e", showB (x == y)), - ("n", showB (x /= y)), - ("g", showB (x > y)), - ("h", showB (x >= y)), - ("l", showB (x < y)), - ("k", showB (x <= y))] - in tcase : go g2 (i - 1) + (x, g1) = generateNum g0 size + (y, g2) = generateNum g1 size + tcase = Map.fromList [("x", showX x), ("y", showX y), + ("e", showB (x == y)), + ("n", showB (x /= y)), + ("g", showB (x > y)), + ("h", showB (x >= y)), + ("l", showB (x < y)), + ("k", showB (x <= y))] -generateSignedTests :: RandomGen g => Word -> g -> [Map String String] -generateSignedTests size g = go g numTestCases +generateSignedTest :: RandomGen g => Word -> g -> (Map String String, g) +generateSignedTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateSignedNum g0 size - (y, g2) = generateSignedNum g1 size - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("e", showB (x == y)), - ("n", showB (x /= y)), - ("g", showB (x > y)), - ("h", showB (x >= y)), - ("l", showB (x < y)), - ("k", showB (x <= y))] - in tcase : go g2 (i - 1) + (x, g1) = generateSignedNum g0 size + (y, g2) = generateSignedNum g1 size + tcase = Map.fromList [("x", showX x), ("y", showX y), + ("e", showB (x == y)), + ("n", showB (x /= y)), + ("g", showB (x > y)), + ("h", showB (x >= y)), + ("l", showB (x < y)), + ("k", showB (x <= y))] \ No newline at end of file diff --git a/generation/src/CryptoNum.hs b/generation/src/CryptoNum.hs index 40905bc..802ba62 100644 --- a/generation/src/CryptoNum.hs +++ b/generation/src/CryptoNum.hs @@ -16,16 +16,13 @@ import Language.Rust.Syntax import RustModule import System.Random(RandomGen) -numTestCases :: Int -numTestCases = 3000 - cryptoNum :: RustModule cryptoNum = RustModule { predicate = \ _ _ -> True, outputName = "cryptonum", isUnsigned = True, generator = declareCryptoNumInstance, - testCase = Just generateTests + testCase = Just generateTest } declareCryptoNumInstance :: Word -> [Word] -> SourceFile Span @@ -176,20 +173,16 @@ generateZeroTests i entries in [stmt| result &= self.value[$$(ilit)] == 0; |] : generateZeroTests (i + 1) entries -generateTests :: RandomGen g => Word -> g -> [Map String String] -generateTests size g = go g numTestCases +generateTest :: RandomGen g => Word -> g -> (Map String String, g) +generateTest size g0 = (tcase, g3) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateNum g0 size - (m, g2) = generateNum g1 size - (b, g3) = generateNum g2 16 - m' = m `mod` (fromIntegral size `div` 64) - r = x `mod` (2 ^ (64 * m')) - t = x `testBit` (fromIntegral b) - tcase = Map.fromList [("x", showX x), ("z", showB (x == 0)), - ("e", showB (even x)), ("o", showB (odd x)), - ("m", showX m'), ("r", showX r), - ("b", showX b), ("t", showB t)] - in tcase : go g3 (i - 1) - + (x, g1) = generateNum g0 size + (m, g2) = generateNum g1 size + (b, g3) = generateNum g2 16 + m' = m `mod` (fromIntegral size `div` 64) + r = x `mod` (2 ^ (64 * m')) + t = x `testBit` (fromIntegral b) + tcase = Map.fromList [("x", showX x), ("z", showB (x == 0)), + ("e", showB (even x)), ("o", showB (odd x)), + ("m", showX m'), ("r", showX r), + ("b", showX b), ("t", showB t)] diff --git a/generation/src/Division.hs b/generation/src/Division.hs index 31688e3..c92131e 100644 --- a/generation/src/Division.hs +++ b/generation/src/Division.hs @@ -13,16 +13,13 @@ import Language.Rust.Syntax import RustModule import System.Random(RandomGen) -numTestCases :: Int -numTestCases = 3000 - divisionOps :: RustModule divisionOps = RustModule { predicate = \ _ _ -> True, outputName = "divmod", isUnsigned = True, generator = declareDivision, - testCase = Just generateDivisionTests + testCase = Just generateDivisionTest } declareDivision :: Word -> [Word] -> SourceFile Span @@ -196,17 +193,15 @@ doCopy i = let liti = toLit i in [stmt| self.value[$$(liti)] = res.value[$$(liti)]; |] -generateDivisionTests :: RandomGen g => Word -> g -> [Map String String] -generateDivisionTests size g = go g numTestCases +generateDivisionTest :: RandomGen g => Word -> g -> (Map String String, g) +generateDivisionTest size g = go g where - go _ 0 = [] - go g0 i = + go g0 = let (x, g1) = generateNum g0 size (y, g2) = generateNum g1 size tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX (x `div` y)), ("r", showX (x `mod` y))] in if y == 0 - then go g2 i - else tcase : go g2 (i - 1) - + then go g2 + else (tcase, g2) \ No newline at end of file diff --git a/generation/src/ModInv.hs b/generation/src/ModInv.hs index b1f6ae5..be68bdd 100644 --- a/generation/src/ModInv.hs +++ b/generation/src/ModInv.hs @@ -17,16 +17,13 @@ import Language.Rust.Syntax import RustModule import System.Random(RandomGen) -numTestCases :: Int -numTestCases = 100 - generateModInvOps :: RustModule generateModInvOps = RustModule { predicate = \ me others -> (me + 64) `elem` others, outputName = "modinv", isUnsigned = True, generator = declareModInv, - testCase = Just generateModInvTests + testCase = Just generateModInvTest } declareModInv :: Word -> [Word] -> SourceFile Span @@ -221,11 +218,10 @@ declareModInv bitsize _ = } |] -generateModInvTests :: RandomGen g => Word -> g -> [Map String String] -generateModInvTests size g = go g numTestCases +generateModInvTest :: RandomGen g => Word -> g -> (Map String String, g) +generateModInvTest size g = go g where - go _ 0 = [] - go g0 i = + go g0 = let (x, g1) = generateNum g0 size (y, g2) = generateNum g1 size z = recipModInteger x y @@ -234,12 +230,12 @@ generateModInvTests size g = go g numTestCases ("z", showX z), ("a", showX a), ("b", showX b), ("v", showX v)] in if z == 0 - then go g2 i + then go g2 else assert (z < y) $ assert ((x * z) `mod` y == 1) $ assert (((a * x) + (b * y)) == v) $ assert (v == gcd x y) $ - tcase : go g2 (i - 1) + (tcase, g2) extendedGCD :: Integer -> Integer -> (Integer, Integer, Integer) extendedGCD x y = (a, b, g * (v finalState)) diff --git a/generation/src/ModOps.hs b/generation/src/ModOps.hs index df3f2e4..e50a23d 100644 --- a/generation/src/ModOps.hs +++ b/generation/src/ModOps.hs @@ -13,16 +13,13 @@ import Language.Rust.Syntax import RustModule import System.Random(RandomGen) -numTestCases :: Int -numTestCases = 1000 - modulusOps :: RustModule modulusOps = RustModule { predicate = \ me others -> (me * 2) `elem` others, outputName = "modops", isUnsigned = True, generator = declareModOps, - testCase = Just generateModulusTests + testCase = Just generateModulusTest } declareModOps :: Word -> [Word] -> SourceFile Span @@ -110,11 +107,10 @@ declareModOps bitsize _ = } |] -generateModulusTests :: RandomGen g => Word -> g -> [Map String String] -generateModulusTests size g = go g numTestCases +generateModulusTest :: RandomGen g => Word -> g -> (Map String String, g) +generateModulusTest size g = go g where - go _ 0 = [] - go g0 i = + go g0 = let (x, g1) = generateNum g0 size (y, g2) = generateNum g1 size (m, g3) = generateNum g2 size @@ -126,7 +122,7 @@ generateModulusTests size g = go g numTestCases ("e", showX (powModInteger x y m)) ] in if y < 2 - then go g3 i - else tcase : go g3 (i - 1) + then go g3 + else (tcase, g3) diff --git a/generation/src/Multiply.hs b/generation/src/Multiply.hs index 64d8867..854d800 100644 --- a/generation/src/Multiply.hs +++ b/generation/src/Multiply.hs @@ -19,16 +19,13 @@ import Language.Rust.Syntax import RustModule import System.Random(RandomGen) -numTestCases :: Int -numTestCases = 3000 - safeMultiplyOps :: RustModule safeMultiplyOps = RustModule { predicate = \ me others -> (me * 2) `elem` others, outputName = "safe_mul", isUnsigned = True, generator = declareSafeMulOperators, - testCase = Just generateSafeTests + testCase = Just generateSafeTest } unsafeMultiplyOps :: RustModule @@ -37,7 +34,7 @@ unsafeMultiplyOps = RustModule { outputName = "unsafe_mul", isUnsigned = True, generator = declareUnsafeMulOperators, - testCase = Just generateUnsafeTests + testCase = Just generateUnsafeTest } declareSafeMulOperators :: Word -> [Word] -> SourceFile Span @@ -289,31 +286,17 @@ inVars instr = -- ----------------------------------------------------------------------------- -generateSafeTests :: RandomGen g => Word -> g -> [Map String String] -generateSafeTests size g = go g numTestCases +generateSafeTest :: RandomGen g => Word -> g -> (Map String String, g) +generateSafeTest size g0 = (tcase, g2) where - go _ 0 = [ - Map.fromList [("x", "0"), ("y", "0"), ("z", "0")] - , (let x = (2 ^ size) - 1 - y = (2 ^ size) - 1 - z = x * y - in Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)]) - ] - go g0 i = - let (x, g1) = generateNum g0 size - (y, g2) = generateNum g1 size - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("z", showX (x * y))] - in tcase : go g2 (i - 1) + (x, g1) = generateNum g0 size + (y, g2) = generateNum g1 size + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX (x * y))] -generateUnsafeTests :: RandomGen g => Word -> g -> [Map String String] -generateUnsafeTests size g = go g numTestCases +generateUnsafeTest :: RandomGen g => Word -> g -> (Map String String, g) +generateUnsafeTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateNum g0 size - (y, g2) = generateNum g1 size - z = (x * y) .&. ((2 ^ size) - 1) - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("z", showX z)] - in tcase : go g2 (i - 1) + (x, g1) = generateNum g0 size + (y, g2) = generateNum g1 size + z = (x * y) .&. ((2 ^ size) - 1) + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)] diff --git a/generation/src/RustModule.hs b/generation/src/RustModule.hs index be5fecb..33b2895 100644 --- a/generation/src/RustModule.hs +++ b/generation/src/RustModule.hs @@ -8,7 +8,7 @@ module RustModule( ) where -import Control.Monad(forM_) +import Control.Monad(forM_, unless) import Data.Char(toUpper) import Data.List(isPrefixOf, partition) import Data.Map.Strict(Map) @@ -19,15 +19,29 @@ import Language.Rust.Data.Position(Span, spanOf) import Language.Rust.Pretty(writeSourceFile) import Language.Rust.Quote(item, sourceFile) import Language.Rust.Syntax(Item(..), SourceFile(..), Visibility(..)) +import System.CPUTime(getCPUTime) import System.IO(Handle,hPutStrLn) import System.Random(RandomGen(..)) +minimumTestCases :: Int +minimumTestCases = 10 + +maximumTestCases :: Int +maximumTestCases = 5000 + +targetTestGenerationTime :: Float +targetTestGenerationTime = 5.0 -- in seconds + +targetTestGenerationPicos :: Integer +targetTestGenerationPicos = + floor (targetTestGenerationTime * 1000000000000.0) + data RustModule = RustModule { predicate :: Word -> [Word] -> Bool, outputName :: String, isUnsigned :: Bool, generator :: Word -> [Word] -> SourceFile Span, - testCase :: forall g. RandomGen g => Maybe (Word -> g -> [Map String String]) + testCase :: forall g. RandomGen g => Maybe (Word -> g -> (Map String String, g)) } data Task = Task { @@ -96,96 +110,34 @@ generateTests :: RandomGen g => Maybe Task generateTests size rng m = fmap builder (testCase m) where - builder testGeneration = + builder testGenerator = let outFile = "testdata/" ++ outputName m ++ "/" ++ testFile (isUnsigned m) size - testGenAction hndl = writeTestCase hndl (testGeneration size (snd (split rng))) + testGenAction hndl = writeTestCases hndl (snd (split rng)) (testGenerator size) in Task outFile testGenAction --- basicTasks ++ moduleTasks --- where --- basicTasks = go rng files sizes --- moduleTasks = generateModules basicTasks --- -- --- go :: RandomGen g => g -> [RustModule] -> [Word] -> [Task] --- go _ [] _ = [] --- go g (_:rest) [] = go g rest sizes --- go g files'@(file:_) (size:rest) --- | not (predicate file size sizes) = go g files' rest --- | otherwise = --- let (myg, theirg) = split g --- tasks = go theirg files' rest --- (signedBit, prefix) | isUnsigned file = ("unsigned", "u") --- | otherwise = ("signed", "i") --- mainTask = Task { --- outputFile = "src" signedBit (prefix ++ show size) --- outputName file ++ ".rs", --- writer = \ hndl -> writeSourceFile hndl (generator file size sizes) --- } --- in case testCase file of --- Nothing -> --- mainTask : tasks --- Just caseGenerator -> --- let testTask = Task { --- outputFile = "testdata" outputName file testFile (isUnsigned file) size, --- writer = \ hndl -> writeTestCase hndl (caseGenerator size myg) --- } --- in testTask : mainTask : tasks --- ---generateModules :: [Task] -> [Task] ---generateModules tasks = Map.foldrWithKey maddModule [] fileMap ++ [signedTask, unsignedTask] --- where --- maddModule path mods acc --- | ("src/unsigned" `isPrefixOf` path) || ("src/signed" `isPrefixOf` path) = --- let (basePath, lowerName) = splitFileName (init path) --- upperName = map toUpper lowerName --- task = Task { --- outputFile = basePath lowerName ++ ".rs", --- writer = \ hndl -> --- do forM_ mods $ \ modl -> --- hPutStrLn hndl ("mod " ++ modl ++ ";") --- hPutStrLn hndl ("pub use base::" ++ upperName ++ ";") --- } --- in task : acc --- | otherwise = --- acc --- fileMap = foldr buildBaseMap Map.empty tasks --- buildBaseMap task acc = --- let (dir, fileext) = splitFileName (outputFile task) --- file = dropExtension fileext --- in Map.insertWith (++) dir [file] acc --- -- --- signedTask = moduleTask "signed" --- unsignedTask = moduleTask "unsigned" --- moduleTask kind = --- let mods = Map.foldrWithKey (topModule kind) [] fileMap --- pubuses = Map.foldrWithKey (pubUse kind) [] fileMap --- in Task { --- outputFile = "src" (kind ++ ".rs"), --- writer = \ hndl -> --- writeSourceFile hndl [sourceFile| --- $@{mods} --- $@{pubuses} --- |] --- } --- topModule kind path _ acc --- | ("src/" ++ kind) `isPrefixOf` path = --- let lowerName = takeFileName (init path) --- modl = mkIdent lowerName --- in [item| mod $$modl; |] : acc --- | otherwise = --- acc --- pubUse kind path _ acc --- | ("src/" ++ kind) `isPrefixOf` path = --- let lowerName = takeFileName (init path) --- tname = mkIdent (map toUpper lowerName) --- modl = mkIdent lowerName --- in [item| pub use $$modl::$$tname; |] : acc --- | otherwise = --- acc --- --- -writeTestCase :: Handle -> [Map String String] -> IO () -writeTestCase hndl tests = - forM_ tests $ \ test -> - forM_ (Map.toList test) $ \ (key, value) -> - hPutStrLn hndl (key ++ ": " ++ value) +writeTestCases :: RandomGen g => + Handle -> g -> + (g -> (Map String String, g)) -> + IO () +writeTestCases hndl rng nextTest = + do startTime <- getCPUTime + let stopTime = startTime + targetTestGenerationPicos + go 0 stopTime rng + where + go x endTime g + | x >= maximumTestCases = return () + | x < minimumTestCases = emit x endTime g + | otherwise = + do now <- getCPUTime + unless (now >= endTime) $ + emit x endTime g + -- + emit x endTime g = + do let (test, g') = nextTest g + writeTestCase hndl test + go (x + 1) endTime g' + +writeTestCase :: Handle -> Map String String -> IO () +writeTestCase hndl test = + forM_ (Map.toList test) $ \ (key, value) -> + hPutStrLn hndl (key ++ ": " ++ value) diff --git a/generation/src/Scale.hs b/generation/src/Scale.hs index 9c6441b..d11bc84 100644 --- a/generation/src/Scale.hs +++ b/generation/src/Scale.hs @@ -17,16 +17,13 @@ import Language.Rust.Syntax import RustModule import System.Random(RandomGen) -numTestCases :: Int -numTestCases = 3000 - safeScaleOps :: RustModule safeScaleOps = RustModule { predicate = \ me others -> (me + 64) `elem` others, outputName = "safe_scale", isUnsigned = True, generator = declareSafeScaleOperators, - testCase = Just generateSafeTests + testCase = Just generateSafeTest } unsafeScaleOps :: RustModule @@ -35,7 +32,7 @@ unsafeScaleOps = RustModule { outputName = "unsafe_scale", isUnsigned = True, generator = declareUnsafeScaleOperators, - testCase = Just generateUnsafeTests + testCase = Just generateUnsafeTest } declareSafeScaleOperators :: Word -> [Word] -> SourceFile Span @@ -256,26 +253,17 @@ generateScaletiplier full size input output = loaders ++ [bigy] ++ ripples ++ -- ----------------------------------------------------------------------------- -generateSafeTests :: RandomGen g => Word -> g -> [Map String String] -generateSafeTests size g = go g numTestCases +generateSafeTest :: RandomGen g => Word -> g -> (Map String String, g) +generateSafeTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateNum g0 size - (y, g2) = generateNum g1 64 - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("z", showX (x * y))] - in tcase : go g2 (i - 1) + (x, g1) = generateNum g0 size + (y, g2) = generateNum g1 64 + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX (x * y))] -generateUnsafeTests :: RandomGen g => Word -> g -> [Map String String] -generateUnsafeTests size g = go g numTestCases +generateUnsafeTest :: RandomGen g => Word -> g -> (Map String String, g) +generateUnsafeTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateNum g0 size - (y, g2) = generateNum g1 64 - z = (x * y) .&. ((2 ^ size) - 1) - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("z", showX z)] - in tcase : go g2 (i - 1) - + (x, g1) = generateNum g0 size + (y, g2) = generateNum g1 64 + z = (x * y) .&. ((2 ^ size) - 1) + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)] \ No newline at end of file diff --git a/generation/src/Shift.hs b/generation/src/Shift.hs index d8d9f52..cab7069 100644 --- a/generation/src/Shift.hs +++ b/generation/src/Shift.hs @@ -14,16 +14,13 @@ import Language.Rust.Syntax import RustModule import System.Random(RandomGen) -numTestCases :: Int -numTestCases = 3000 - shiftOps :: RustModule shiftOps = RustModule { predicate = \ _ _ -> True, outputName = "shift", isUnsigned = True, generator = declareShiftOperators, - testCase = Just generateTests + testCase = Just generateTest } signedShiftOps :: RustModule @@ -32,7 +29,7 @@ signedShiftOps = RustModule { outputName = "sshift", isUnsigned = False, generator = declareSignedShiftOperators, - testCase = Just generateSignedTests + testCase = Just generateSignedTest } declareShiftOperators :: Word -> [Word] -> SourceFile Span @@ -298,31 +295,24 @@ generateBaseImpls sname upper_shift lower_shift assign_shift lassign_shift right |] ] -generateTests :: RandomGen g => Word -> g -> [Map String String] -generateTests size g = go g numTestCases +generateTest :: RandomGen g => Word -> g -> (Map String String, g) +generateTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateNum g0 size - (y, g2) = generateNum g1 size - s = y `mod` fromIntegral size - l = modulate (x `shiftL` fromIntegral s) size - r = modulate (x `shiftR` fromIntegral s) size - tcase = Map.fromList [("x", showX x), ("s", showX s), - ("l", showX l), ("r", showX r)] - in tcase : go g2 (i - 1) + (x, g1) = generateNum g0 size + (y, g2) = generateNum g1 size + s = y `mod` fromIntegral size + l = modulate (x `shiftL` fromIntegral s) size + r = modulate (x `shiftR` fromIntegral s) size + tcase = Map.fromList [("x", showX x), ("s", showX s), + ("l", showX l), ("r", showX r)] - -generateSignedTests :: RandomGen g => Word -> g -> [Map String String] -generateSignedTests size g = go g numTestCases +generateSignedTest :: RandomGen g => Word -> g -> (Map String String, g) +generateSignedTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateSignedNum g0 size - (y, g2) = generateNum g1 size - s = y `mod` fromIntegral size - l = modulate (x `shiftL` fromIntegral s) size - r = modulate (x `shiftR` fromIntegral s) size - tcase = Map.fromList [("x", showX x), ("s", showX s), - ("l", showX l), ("r", showX r)] - in tcase : go g2 (i - 1) + (x, g1) = generateSignedNum g0 size + (y, g2) = generateNum g1 size + s = y `mod` fromIntegral size + l = modulate (x `shiftL` fromIntegral s) size + r = modulate (x `shiftR` fromIntegral s) size + tcase = Map.fromList [("x", showX x), ("s", showX s), + ("l", showX l), ("r", showX r)] \ No newline at end of file diff --git a/generation/src/Subtract.hs b/generation/src/Subtract.hs index 616ef29..f651f24 100644 --- a/generation/src/Subtract.hs +++ b/generation/src/Subtract.hs @@ -19,16 +19,13 @@ import Language.Rust.Syntax import RustModule import System.Random(RandomGen) -numTestCases :: Int -numTestCases = 3000 - safeSubtractOps :: RustModule safeSubtractOps = RustModule { predicate = \ me others -> (me + 64) `elem` others, outputName = "safe_sub", isUnsigned = True, generator = declareSafeSubtractOperators, - testCase = Just generateSafeTests + testCase = Just generateSafeTest } safeSignedSubtractOps :: RustModule @@ -37,7 +34,7 @@ safeSignedSubtractOps = RustModule { outputName = "safe_ssub", isUnsigned = False, generator = declareSafeSignedSubtractOperators, - testCase = Just generateSafeSignedTests + testCase = Just generateSafeSignedTest } unsafeSubtractOps :: RustModule @@ -46,7 +43,7 @@ unsafeSubtractOps = RustModule { outputName = "unsafe_sub", isUnsigned = True, generator = declareUnsafeSubtractOperators, - testCase = Just generateUnsafeTests + testCase = Just generateUnsafeTest } unsafeSignedSubtractOps :: RustModule @@ -55,7 +52,7 @@ unsafeSignedSubtractOps = RustModule { outputName = "unsafe_ssub", isUnsigned = False, generator = declareUnsafeSignedSubtractOperators, - testCase = Just generateUnsafeSignedTests + testCase = Just generateUnsafeSignedTest } declareSafeSubtractOperators :: Word -> [Word] -> SourceFile Span @@ -321,54 +318,36 @@ generateSetters useLastCarry maxI resName i where target = mkIdent resName -generateSafeTests :: RandomGen g => Word -> g -> [Map String String] -generateSafeTests size g = go g numTestCases +generateSafeTest :: RandomGen g => Word -> g -> (Map String String, g) +generateSafeTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateNum g0 size - (y, g2) = generateNum g1 size - r | x < y = (2 ^ (size + 64)) + (x - y) - | otherwise = x - y - tcase = Map.fromList [("x", showX x), - ("y", showX y), - ("z", showX r)] - in tcase : go g2 (i - 1) + (x, g1) = generateNum g0 size + (y, g2) = generateNum g1 size + r | x < y = (2 ^ (size + 64)) + (x - y) + | otherwise = x - y + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX r)] -generateSafeSignedTests :: RandomGen g => Word -> g -> [Map String String] -generateSafeSignedTests size g = go g numTestCases +generateSafeSignedTest :: RandomGen g => Word -> g -> (Map String String, g) +generateSafeSignedTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateSignedNum g0 size - (y, g2) = generateSignedNum g1 size - r | x < y = (2 ^ (size + 64)) + (x - y) - | otherwise = x - y - tcase = Map.fromList [("x", showX x), - ("y", showX y), - ("z", showX r)] - in tcase : go g2 (i - 1) + (x, g1) = generateSignedNum g0 size + (y, g2) = generateSignedNum g1 size + r | x < y = (2 ^ (size + 64)) + (x - y) + | otherwise = x - y + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX r)] -generateUnsafeTests :: RandomGen g => Word -> g -> [Map String String] -generateUnsafeTests size g = go g numTestCases +generateUnsafeTest :: RandomGen g => Word -> g -> (Map String String, g) +generateUnsafeTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateNum g0 size - (y, g2) = generateNum g1 size - z = (x - y) .&. ((2 ^ size) - 1) - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("z", showX z)] - in tcase : go g2 (i - 1) + (x, g1) = generateNum g0 size + (y, g2) = generateNum g1 size + z = (x - y) .&. ((2 ^ size) - 1) + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)] -generateUnsafeSignedTests :: RandomGen g => Word -> g -> [Map String String] -generateUnsafeSignedTests size g = go g numTestCases +generateUnsafeSignedTest :: RandomGen g => Word -> g -> (Map String String, g) +generateUnsafeSignedTest size g0 = (tcase, g2) where - go _ 0 = [] - go g0 i = - let (x, g1) = generateSignedNum g0 size - (y, g2) = generateSignedNum g1 size - z = (x - y) .&. ((2 ^ size) - 1) - tcase = Map.fromList [("x", showX x), ("y", showX y), - ("z", showX z)] - in tcase : go g2 (i - 1) + (x, g1) = generateSignedNum g0 size + (y, g2) = generateSignedNum g1 size + z = (x - y) .&. ((2 ^ size) - 1) + tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)] \ No newline at end of file