Switch to a more dynamic, time-based test generation scheme.

This commit is contained in:
2020-03-01 16:56:17 -08:00
parent 71451617f9
commit 9c76d7e0b4
12 changed files with 212 additions and 374 deletions

View File

@@ -16,11 +16,8 @@ import Language.Rust.Data.Ident
import Language.Rust.Data.Position import Language.Rust.Data.Position
import Language.Rust.Quote import Language.Rust.Quote
import Language.Rust.Syntax import Language.Rust.Syntax
import System.Random(RandomGen)
import RustModule import RustModule
numTestCases :: Int import System.Random(RandomGen)
numTestCases = 3000
safeAddOps :: RustModule safeAddOps :: RustModule
safeAddOps = RustModule { safeAddOps = RustModule {
@@ -28,7 +25,7 @@ safeAddOps = RustModule {
outputName = "safe_add", outputName = "safe_add",
isUnsigned = True, isUnsigned = True,
generator = declareSafeAddOperators, generator = declareSafeAddOperators,
testCase = Just generateSafeTests testCase = Just generateSafeTest
} }
unsafeAddOps :: RustModule unsafeAddOps :: RustModule
@@ -37,7 +34,7 @@ unsafeAddOps = RustModule {
outputName = "unsafe_add", outputName = "unsafe_add",
isUnsigned = True, isUnsigned = True,
generator = declareUnsafeAddOperators, generator = declareUnsafeAddOperators,
testCase = Just generateUnsafeTests testCase = Just generateUnsafeTest
} }
safeSignedAddOps :: RustModule safeSignedAddOps :: RustModule
@@ -46,7 +43,7 @@ safeSignedAddOps = RustModule {
outputName = "safe_sadd", outputName = "safe_sadd",
isUnsigned = False, isUnsigned = False,
generator = declareSafeSignedAddOperators, generator = declareSafeSignedAddOperators,
testCase = Just generateSafeSignedTests testCase = Just generateSafeSignedTest
} }
unsafeSignedAddOps :: RustModule unsafeSignedAddOps :: RustModule
@@ -55,7 +52,7 @@ unsafeSignedAddOps = RustModule {
outputName = "unsafe_sadd", outputName = "unsafe_sadd",
isUnsigned = False, isUnsigned = False,
generator = declareUnsafeSignedAddOperators, generator = declareUnsafeSignedAddOperators,
testCase = Just generateUnsafeSignedTests testCase = Just generateUnsafeSignedTest
} }
declareSafeAddOperators :: Word -> [Word] -> SourceFile Span declareSafeAddOperators :: Word -> [Word] -> SourceFile Span
@@ -374,48 +371,32 @@ generateSetters useLastCarry maxI resName i
where where
target = mkIdent resName target = mkIdent resName
generateSafeTests :: RandomGen g => Word -> g -> [Map String String] generateSafeTest :: RandomGen g => Word -> g -> (Map String String, g)
generateSafeTests size g = go g numTestCases generateSafeTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateNum g0 size
go g0 i = (y, g2) = generateNum g1 size
let (x, g1) = generateNum g0 size tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX (x + y))]
(y, g2) = generateNum g1 size
tcase = Map.fromList [("x", showX x), ("y", showX y),
("z", showX (x + y))]
in tcase : go g2 (i - 1)
generateUnsafeTests :: RandomGen g => Word -> g -> [Map String String] generateUnsafeTest :: RandomGen g => Word -> g -> (Map String String, g)
generateUnsafeTests size g = go g numTestCases generateUnsafeTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateNum g0 size
go g0 i = (y, g2) = generateNum g1 size
let (x, g1) = generateNum g0 size z = (x + y) .&. ((2 ^ size) - 1)
(y, g2) = generateNum g1 size tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)]
z = (x + y) .&. ((2 ^ size) - 1)
tcase = Map.fromList [("x", showX x), ("y", showX y),
("z", showX z)]
in tcase : go g2 (i - 1)
generateSafeSignedTests :: RandomGen g => Word -> g -> [Map String String] generateSafeSignedTest :: RandomGen g => Word -> g -> (Map String String, g)
generateSafeSignedTests size g = go g numTestCases generateSafeSignedTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateSignedNum g0 size
go g0 i = (y, g2) = generateSignedNum g1 size
let (x, g1) = generateSignedNum g0 size tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX (x + y))]
(y, g2) = generateSignedNum g1 size
tcase = Map.fromList [("x", showX x), ("y", showX y),
("z", showX (x + y))]
in tcase : go g2 (i - 1)
generateUnsafeSignedTests :: RandomGen g => Word -> g -> [Map String String] generateUnsafeSignedTest :: RandomGen g => Word -> g -> (Map String String, g)
generateUnsafeSignedTests size g = go g numTestCases generateUnsafeSignedTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateSignedNum g0 size
go g0 i = (y, g2) = generateSignedNum g1 size
let (x, g1) = generateSignedNum g0 size z = (x + y) .&. ((2 ^ size) - 1)
(y, g2) = generateSignedNum g1 size tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)]
z = (x + y) .&. ((2 ^ size) - 1)
tcase = Map.fromList [("x", showX x), ("y", showX y),
("z", showX z)]
in tcase : go g2 (i - 1)

View File

@@ -16,16 +16,13 @@ import Language.Rust.Syntax
import RustModule import RustModule
import System.Random(RandomGen) import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
binaryOps :: RustModule binaryOps :: RustModule
binaryOps = RustModule { binaryOps = RustModule {
predicate = \ _ _ -> True, predicate = \ _ _ -> True,
outputName = "binary", outputName = "binary",
isUnsigned = True, isUnsigned = True,
generator = declareBinaryOperators, generator = declareBinaryOperators,
testCase = Just generateTests testCase = Just generateTest
} }
declareBinaryOperators :: Word -> [Word] -> SourceFile Span declareBinaryOperators :: Word -> [Word] -> SourceFile Span
@@ -240,16 +237,13 @@ generateAllTheVariants traitname func sname oper entries = [
[expr| $$(right).value[$$(i)] |] [expr| $$(right).value[$$(i)] |]
mempty) mempty mempty) mempty
generateTests :: RandomGen g => Word -> g -> [Map String String] generateTest :: RandomGen g => Word -> g -> (Map String String, g)
generateTests size g = go g numTestCases generateTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateNum g0 size
go g0 i = (y, g2) = generateNum g1 size
let (x, g1) = generateNum g0 size tcase = Map.fromList [("x", showX x), ("y", showX y),
(y, g2) = generateNum g1 size ("a", showX (x .&. y)),
tcase = Map.fromList [("x", showX x), ("y", showX y), ("o", showX (x .|. y)),
("a", showX (x .&. y)), ("e", showX (x `xor` y)),
("o", showX (x .|. y)), ("n", showX ( ((2 ^ size) - 1) `xor` x ))]
("e", showX (x `xor` y)),
("n", showX ( ((2 ^ size) - 1) `xor` x ))]
in tcase : go g2 (i - 1)

View File

@@ -12,16 +12,13 @@ import Language.Rust.Syntax
import RustModule import RustModule
import System.Random(RandomGen) import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
comparisons :: RustModule comparisons :: RustModule
comparisons = RustModule { comparisons = RustModule {
predicate = \ _ _ -> True, predicate = \ _ _ -> True,
outputName = "compare", outputName = "compare",
isUnsigned = True, isUnsigned = True,
generator = declareComparators, generator = declareComparators,
testCase = Just generateTests testCase = Just generateTest
} }
signedComparisons :: RustModule signedComparisons :: RustModule
@@ -30,7 +27,7 @@ signedComparisons = RustModule {
outputName = "scompare", outputName = "scompare",
isUnsigned = False, isUnsigned = False,
generator = declareSignedComparators, generator = declareSignedComparators,
testCase = Just generateSignedTests testCase = Just generateSignedTest
} }
declareComparators :: Word -> [Word] -> SourceFile Span declareComparators :: Word -> [Word] -> SourceFile Span
@@ -249,34 +246,28 @@ buildCompareExp i numEntries
where where
x = Lit [] (Int Dec (fromIntegral i) Unsuffixed mempty) mempty x = Lit [] (Int Dec (fromIntegral i) Unsuffixed mempty) mempty
generateTests :: RandomGen g => Word -> g -> [Map String String] generateTest :: RandomGen g => Word -> g -> (Map String String, g)
generateTests size g = go g numTestCases generateTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateNum g0 size
go g0 i = (y, g2) = generateNum g1 size
let (x, g1) = generateNum g0 size tcase = Map.fromList [("x", showX x), ("y", showX y),
(y, g2) = generateNum g1 size ("e", showB (x == y)),
tcase = Map.fromList [("x", showX x), ("y", showX y), ("n", showB (x /= y)),
("e", showB (x == y)), ("g", showB (x > y)),
("n", showB (x /= y)), ("h", showB (x >= y)),
("g", showB (x > y)), ("l", showB (x < y)),
("h", showB (x >= y)), ("k", showB (x <= y))]
("l", showB (x < y)),
("k", showB (x <= y))]
in tcase : go g2 (i - 1)
generateSignedTests :: RandomGen g => Word -> g -> [Map String String] generateSignedTest :: RandomGen g => Word -> g -> (Map String String, g)
generateSignedTests size g = go g numTestCases generateSignedTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateSignedNum g0 size
go g0 i = (y, g2) = generateSignedNum g1 size
let (x, g1) = generateSignedNum g0 size tcase = Map.fromList [("x", showX x), ("y", showX y),
(y, g2) = generateSignedNum g1 size ("e", showB (x == y)),
tcase = Map.fromList [("x", showX x), ("y", showX y), ("n", showB (x /= y)),
("e", showB (x == y)), ("g", showB (x > y)),
("n", showB (x /= y)), ("h", showB (x >= y)),
("g", showB (x > y)), ("l", showB (x < y)),
("h", showB (x >= y)), ("k", showB (x <= y))]
("l", showB (x < y)),
("k", showB (x <= y))]
in tcase : go g2 (i - 1)

View File

@@ -16,16 +16,13 @@ import Language.Rust.Syntax
import RustModule import RustModule
import System.Random(RandomGen) import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
cryptoNum :: RustModule cryptoNum :: RustModule
cryptoNum = RustModule { cryptoNum = RustModule {
predicate = \ _ _ -> True, predicate = \ _ _ -> True,
outputName = "cryptonum", outputName = "cryptonum",
isUnsigned = True, isUnsigned = True,
generator = declareCryptoNumInstance, generator = declareCryptoNumInstance,
testCase = Just generateTests testCase = Just generateTest
} }
declareCryptoNumInstance :: Word -> [Word] -> SourceFile Span declareCryptoNumInstance :: Word -> [Word] -> SourceFile Span
@@ -176,20 +173,16 @@ generateZeroTests i entries
in [stmt| result &= self.value[$$(ilit)] == 0; |] : in [stmt| result &= self.value[$$(ilit)] == 0; |] :
generateZeroTests (i + 1) entries generateZeroTests (i + 1) entries
generateTests :: RandomGen g => Word -> g -> [Map String String] generateTest :: RandomGen g => Word -> g -> (Map String String, g)
generateTests size g = go g numTestCases generateTest size g0 = (tcase, g3)
where where
go _ 0 = [] (x, g1) = generateNum g0 size
go g0 i = (m, g2) = generateNum g1 size
let (x, g1) = generateNum g0 size (b, g3) = generateNum g2 16
(m, g2) = generateNum g1 size m' = m `mod` (fromIntegral size `div` 64)
(b, g3) = generateNum g2 16 r = x `mod` (2 ^ (64 * m'))
m' = m `mod` (fromIntegral size `div` 64) t = x `testBit` (fromIntegral b)
r = x `mod` (2 ^ (64 * m')) tcase = Map.fromList [("x", showX x), ("z", showB (x == 0)),
t = x `testBit` (fromIntegral b) ("e", showB (even x)), ("o", showB (odd x)),
tcase = Map.fromList [("x", showX x), ("z", showB (x == 0)), ("m", showX m'), ("r", showX r),
("e", showB (even x)), ("o", showB (odd x)), ("b", showX b), ("t", showB t)]
("m", showX m'), ("r", showX r),
("b", showX b), ("t", showB t)]
in tcase : go g3 (i - 1)

View File

@@ -13,16 +13,13 @@ import Language.Rust.Syntax
import RustModule import RustModule
import System.Random(RandomGen) import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
divisionOps :: RustModule divisionOps :: RustModule
divisionOps = RustModule { divisionOps = RustModule {
predicate = \ _ _ -> True, predicate = \ _ _ -> True,
outputName = "divmod", outputName = "divmod",
isUnsigned = True, isUnsigned = True,
generator = declareDivision, generator = declareDivision,
testCase = Just generateDivisionTests testCase = Just generateDivisionTest
} }
declareDivision :: Word -> [Word] -> SourceFile Span declareDivision :: Word -> [Word] -> SourceFile Span
@@ -196,17 +193,15 @@ doCopy i =
let liti = toLit i let liti = toLit i
in [stmt| self.value[$$(liti)] = res.value[$$(liti)]; |] in [stmt| self.value[$$(liti)] = res.value[$$(liti)]; |]
generateDivisionTests :: RandomGen g => Word -> g -> [Map String String] generateDivisionTest :: RandomGen g => Word -> g -> (Map String String, g)
generateDivisionTests size g = go g numTestCases generateDivisionTest size g = go g
where where
go _ 0 = [] go g0 =
go g0 i =
let (x, g1) = generateNum g0 size let (x, g1) = generateNum g0 size
(y, g2) = generateNum g1 size (y, g2) = generateNum g1 size
tcase = Map.fromList [("x", showX x), ("y", showX y), tcase = Map.fromList [("x", showX x), ("y", showX y),
("z", showX (x `div` y)), ("z", showX (x `div` y)),
("r", showX (x `mod` y))] ("r", showX (x `mod` y))]
in if y == 0 in if y == 0
then go g2 i then go g2
else tcase : go g2 (i - 1) else (tcase, g2)

View File

@@ -17,16 +17,13 @@ import Language.Rust.Syntax
import RustModule import RustModule
import System.Random(RandomGen) import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 100
generateModInvOps :: RustModule generateModInvOps :: RustModule
generateModInvOps = RustModule { generateModInvOps = RustModule {
predicate = \ me others -> (me + 64) `elem` others, predicate = \ me others -> (me + 64) `elem` others,
outputName = "modinv", outputName = "modinv",
isUnsigned = True, isUnsigned = True,
generator = declareModInv, generator = declareModInv,
testCase = Just generateModInvTests testCase = Just generateModInvTest
} }
declareModInv :: Word -> [Word] -> SourceFile Span declareModInv :: Word -> [Word] -> SourceFile Span
@@ -221,11 +218,10 @@ declareModInv bitsize _ =
} }
|] |]
generateModInvTests :: RandomGen g => Word -> g -> [Map String String] generateModInvTest :: RandomGen g => Word -> g -> (Map String String, g)
generateModInvTests size g = go g numTestCases generateModInvTest size g = go g
where where
go _ 0 = [] go g0 =
go g0 i =
let (x, g1) = generateNum g0 size let (x, g1) = generateNum g0 size
(y, g2) = generateNum g1 size (y, g2) = generateNum g1 size
z = recipModInteger x y z = recipModInteger x y
@@ -234,12 +230,12 @@ generateModInvTests size g = go g numTestCases
("z", showX z), ("a", showX a), ("z", showX z), ("a", showX a),
("b", showX b), ("v", showX v)] ("b", showX b), ("v", showX v)]
in if z == 0 in if z == 0
then go g2 i then go g2
else assert (z < y) $ else assert (z < y) $
assert ((x * z) `mod` y == 1) $ assert ((x * z) `mod` y == 1) $
assert (((a * x) + (b * y)) == v) $ assert (((a * x) + (b * y)) == v) $
assert (v == gcd x y) $ assert (v == gcd x y) $
tcase : go g2 (i - 1) (tcase, g2)
extendedGCD :: Integer -> Integer -> (Integer, Integer, Integer) extendedGCD :: Integer -> Integer -> (Integer, Integer, Integer)
extendedGCD x y = (a, b, g * (v finalState)) extendedGCD x y = (a, b, g * (v finalState))

View File

@@ -13,16 +13,13 @@ import Language.Rust.Syntax
import RustModule import RustModule
import System.Random(RandomGen) import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 1000
modulusOps :: RustModule modulusOps :: RustModule
modulusOps = RustModule { modulusOps = RustModule {
predicate = \ me others -> (me * 2) `elem` others, predicate = \ me others -> (me * 2) `elem` others,
outputName = "modops", outputName = "modops",
isUnsigned = True, isUnsigned = True,
generator = declareModOps, generator = declareModOps,
testCase = Just generateModulusTests testCase = Just generateModulusTest
} }
declareModOps :: Word -> [Word] -> SourceFile Span declareModOps :: Word -> [Word] -> SourceFile Span
@@ -110,11 +107,10 @@ declareModOps bitsize _ =
} }
|] |]
generateModulusTests :: RandomGen g => Word -> g -> [Map String String] generateModulusTest :: RandomGen g => Word -> g -> (Map String String, g)
generateModulusTests size g = go g numTestCases generateModulusTest size g = go g
where where
go _ 0 = [] go g0 =
go g0 i =
let (x, g1) = generateNum g0 size let (x, g1) = generateNum g0 size
(y, g2) = generateNum g1 size (y, g2) = generateNum g1 size
(m, g3) = generateNum g2 size (m, g3) = generateNum g2 size
@@ -126,7 +122,7 @@ generateModulusTests size g = go g numTestCases
("e", showX (powModInteger x y m)) ("e", showX (powModInteger x y m))
] ]
in if y < 2 in if y < 2
then go g3 i then go g3
else tcase : go g3 (i - 1) else (tcase, g3)

View File

@@ -19,16 +19,13 @@ import Language.Rust.Syntax
import RustModule import RustModule
import System.Random(RandomGen) import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
safeMultiplyOps :: RustModule safeMultiplyOps :: RustModule
safeMultiplyOps = RustModule { safeMultiplyOps = RustModule {
predicate = \ me others -> (me * 2) `elem` others, predicate = \ me others -> (me * 2) `elem` others,
outputName = "safe_mul", outputName = "safe_mul",
isUnsigned = True, isUnsigned = True,
generator = declareSafeMulOperators, generator = declareSafeMulOperators,
testCase = Just generateSafeTests testCase = Just generateSafeTest
} }
unsafeMultiplyOps :: RustModule unsafeMultiplyOps :: RustModule
@@ -37,7 +34,7 @@ unsafeMultiplyOps = RustModule {
outputName = "unsafe_mul", outputName = "unsafe_mul",
isUnsigned = True, isUnsigned = True,
generator = declareUnsafeMulOperators, generator = declareUnsafeMulOperators,
testCase = Just generateUnsafeTests testCase = Just generateUnsafeTest
} }
declareSafeMulOperators :: Word -> [Word] -> SourceFile Span declareSafeMulOperators :: Word -> [Word] -> SourceFile Span
@@ -289,31 +286,17 @@ inVars instr =
-- ----------------------------------------------------------------------------- -- -----------------------------------------------------------------------------
generateSafeTests :: RandomGen g => Word -> g -> [Map String String] generateSafeTest :: RandomGen g => Word -> g -> (Map String String, g)
generateSafeTests size g = go g numTestCases generateSafeTest size g0 = (tcase, g2)
where where
go _ 0 = [ (x, g1) = generateNum g0 size
Map.fromList [("x", "0"), ("y", "0"), ("z", "0")] (y, g2) = generateNum g1 size
, (let x = (2 ^ size) - 1 tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX (x * y))]
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)
generateUnsafeTests :: RandomGen g => Word -> g -> [Map String String] generateUnsafeTest :: RandomGen g => Word -> g -> (Map String String, g)
generateUnsafeTests size g = go g numTestCases generateUnsafeTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateNum g0 size
go g0 i = (y, g2) = generateNum g1 size
let (x, g1) = generateNum g0 size z = (x * y) .&. ((2 ^ size) - 1)
(y, g2) = generateNum g1 size tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)]
z = (x * y) .&. ((2 ^ size) - 1)
tcase = Map.fromList [("x", showX x), ("y", showX y),
("z", showX z)]
in tcase : go g2 (i - 1)

View File

@@ -8,7 +8,7 @@ module RustModule(
) )
where where
import Control.Monad(forM_) import Control.Monad(forM_, unless)
import Data.Char(toUpper) import Data.Char(toUpper)
import Data.List(isPrefixOf, partition) import Data.List(isPrefixOf, partition)
import Data.Map.Strict(Map) import Data.Map.Strict(Map)
@@ -19,15 +19,29 @@ import Language.Rust.Data.Position(Span, spanOf)
import Language.Rust.Pretty(writeSourceFile) import Language.Rust.Pretty(writeSourceFile)
import Language.Rust.Quote(item, sourceFile) import Language.Rust.Quote(item, sourceFile)
import Language.Rust.Syntax(Item(..), SourceFile(..), Visibility(..)) import Language.Rust.Syntax(Item(..), SourceFile(..), Visibility(..))
import System.CPUTime(getCPUTime)
import System.IO(Handle,hPutStrLn) import System.IO(Handle,hPutStrLn)
import System.Random(RandomGen(..)) 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 { data RustModule = RustModule {
predicate :: Word -> [Word] -> Bool, predicate :: Word -> [Word] -> Bool,
outputName :: String, outputName :: String,
isUnsigned :: Bool, isUnsigned :: Bool,
generator :: Word -> [Word] -> SourceFile Span, 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 { data Task = Task {
@@ -96,96 +110,34 @@ generateTests :: RandomGen g =>
Maybe Task Maybe Task
generateTests size rng m = fmap builder (testCase m) generateTests size rng m = fmap builder (testCase m)
where where
builder testGeneration = builder testGenerator =
let outFile = "testdata/" ++ outputName m ++ "/" ++ testFile (isUnsigned m) size 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 in Task outFile testGenAction
-- basicTasks ++ moduleTasks writeTestCases :: RandomGen g =>
-- where Handle -> g ->
-- basicTasks = go rng files sizes (g -> (Map String String, g)) ->
-- moduleTasks = generateModules basicTasks IO ()
-- -- writeTestCases hndl rng nextTest =
-- go :: RandomGen g => g -> [RustModule] -> [Word] -> [Task] do startTime <- getCPUTime
-- go _ [] _ = [] let stopTime = startTime + targetTestGenerationPicos
-- go g (_:rest) [] = go g rest sizes go 0 stopTime rng
-- go g files'@(file:_) (size:rest) where
-- | not (predicate file size sizes) = go g files' rest go x endTime g
-- | otherwise = | x >= maximumTestCases = return ()
-- let (myg, theirg) = split g | x < minimumTestCases = emit x endTime g
-- tasks = go theirg files' rest | otherwise =
-- (signedBit, prefix) | isUnsigned file = ("unsigned", "u") do now <- getCPUTime
-- | otherwise = ("signed", "i") unless (now >= endTime) $
-- mainTask = Task { emit x endTime g
-- outputFile = "src" </> signedBit </> (prefix ++ show size) </> --
-- outputName file ++ ".rs", emit x endTime g =
-- writer = \ hndl -> writeSourceFile hndl (generator file size sizes) do let (test, g') = nextTest g
-- } writeTestCase hndl test
-- in case testCase file of go (x + 1) endTime g'
-- Nothing ->
-- mainTask : tasks writeTestCase :: Handle -> Map String String -> IO ()
-- Just caseGenerator -> writeTestCase hndl test =
-- let testTask = Task { forM_ (Map.toList test) $ \ (key, value) ->
-- outputFile = "testdata" </> outputName file </> testFile (isUnsigned file) size, hPutStrLn hndl (key ++ ": " ++ value)
-- 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)

View File

@@ -17,16 +17,13 @@ import Language.Rust.Syntax
import RustModule import RustModule
import System.Random(RandomGen) import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
safeScaleOps :: RustModule safeScaleOps :: RustModule
safeScaleOps = RustModule { safeScaleOps = RustModule {
predicate = \ me others -> (me + 64) `elem` others, predicate = \ me others -> (me + 64) `elem` others,
outputName = "safe_scale", outputName = "safe_scale",
isUnsigned = True, isUnsigned = True,
generator = declareSafeScaleOperators, generator = declareSafeScaleOperators,
testCase = Just generateSafeTests testCase = Just generateSafeTest
} }
unsafeScaleOps :: RustModule unsafeScaleOps :: RustModule
@@ -35,7 +32,7 @@ unsafeScaleOps = RustModule {
outputName = "unsafe_scale", outputName = "unsafe_scale",
isUnsigned = True, isUnsigned = True,
generator = declareUnsafeScaleOperators, generator = declareUnsafeScaleOperators,
testCase = Just generateUnsafeTests testCase = Just generateUnsafeTest
} }
declareSafeScaleOperators :: Word -> [Word] -> SourceFile Span 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] generateSafeTest :: RandomGen g => Word -> g -> (Map String String, g)
generateSafeTests size g = go g numTestCases generateSafeTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateNum g0 size
go g0 i = (y, g2) = generateNum g1 64
let (x, g1) = generateNum g0 size tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX (x * y))]
(y, g2) = generateNum g1 64
tcase = Map.fromList [("x", showX x), ("y", showX y),
("z", showX (x * y))]
in tcase : go g2 (i - 1)
generateUnsafeTests :: RandomGen g => Word -> g -> [Map String String] generateUnsafeTest :: RandomGen g => Word -> g -> (Map String String, g)
generateUnsafeTests size g = go g numTestCases generateUnsafeTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateNum g0 size
go g0 i = (y, g2) = generateNum g1 64
let (x, g1) = generateNum g0 size z = (x * y) .&. ((2 ^ size) - 1)
(y, g2) = generateNum g1 64 tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)]
z = (x * y) .&. ((2 ^ size) - 1)
tcase = Map.fromList [("x", showX x), ("y", showX y),
("z", showX z)]
in tcase : go g2 (i - 1)

View File

@@ -14,16 +14,13 @@ import Language.Rust.Syntax
import RustModule import RustModule
import System.Random(RandomGen) import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
shiftOps :: RustModule shiftOps :: RustModule
shiftOps = RustModule { shiftOps = RustModule {
predicate = \ _ _ -> True, predicate = \ _ _ -> True,
outputName = "shift", outputName = "shift",
isUnsigned = True, isUnsigned = True,
generator = declareShiftOperators, generator = declareShiftOperators,
testCase = Just generateTests testCase = Just generateTest
} }
signedShiftOps :: RustModule signedShiftOps :: RustModule
@@ -32,7 +29,7 @@ signedShiftOps = RustModule {
outputName = "sshift", outputName = "sshift",
isUnsigned = False, isUnsigned = False,
generator = declareSignedShiftOperators, generator = declareSignedShiftOperators,
testCase = Just generateSignedTests testCase = Just generateSignedTest
} }
declareShiftOperators :: Word -> [Word] -> SourceFile Span 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] generateTest :: RandomGen g => Word -> g -> (Map String String, g)
generateTests size g = go g numTestCases generateTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateNum g0 size
go g0 i = (y, g2) = generateNum g1 size
let (x, g1) = generateNum g0 size s = y `mod` fromIntegral size
(y, g2) = generateNum g1 size l = modulate (x `shiftL` fromIntegral s) size
s = y `mod` fromIntegral size r = modulate (x `shiftR` fromIntegral s) size
l = modulate (x `shiftL` fromIntegral s) size tcase = Map.fromList [("x", showX x), ("s", showX s),
r = modulate (x `shiftR` fromIntegral s) size ("l", showX l), ("r", showX r)]
tcase = Map.fromList [("x", showX x), ("s", showX s),
("l", showX l), ("r", showX r)]
in tcase : go g2 (i - 1)
generateSignedTest :: RandomGen g => Word -> g -> (Map String String, g)
generateSignedTests :: RandomGen g => Word -> g -> [Map String String] generateSignedTest size g0 = (tcase, g2)
generateSignedTests size g = go g numTestCases
where where
go _ 0 = [] (x, g1) = generateSignedNum g0 size
go g0 i = (y, g2) = generateNum g1 size
let (x, g1) = generateSignedNum g0 size s = y `mod` fromIntegral size
(y, g2) = generateNum g1 size l = modulate (x `shiftL` fromIntegral s) size
s = y `mod` fromIntegral size r = modulate (x `shiftR` fromIntegral s) size
l = modulate (x `shiftL` fromIntegral s) size tcase = Map.fromList [("x", showX x), ("s", showX s),
r = modulate (x `shiftR` fromIntegral s) size ("l", showX l), ("r", showX r)]
tcase = Map.fromList [("x", showX x), ("s", showX s),
("l", showX l), ("r", showX r)]
in tcase : go g2 (i - 1)

View File

@@ -19,16 +19,13 @@ import Language.Rust.Syntax
import RustModule import RustModule
import System.Random(RandomGen) import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
safeSubtractOps :: RustModule safeSubtractOps :: RustModule
safeSubtractOps = RustModule { safeSubtractOps = RustModule {
predicate = \ me others -> (me + 64) `elem` others, predicate = \ me others -> (me + 64) `elem` others,
outputName = "safe_sub", outputName = "safe_sub",
isUnsigned = True, isUnsigned = True,
generator = declareSafeSubtractOperators, generator = declareSafeSubtractOperators,
testCase = Just generateSafeTests testCase = Just generateSafeTest
} }
safeSignedSubtractOps :: RustModule safeSignedSubtractOps :: RustModule
@@ -37,7 +34,7 @@ safeSignedSubtractOps = RustModule {
outputName = "safe_ssub", outputName = "safe_ssub",
isUnsigned = False, isUnsigned = False,
generator = declareSafeSignedSubtractOperators, generator = declareSafeSignedSubtractOperators,
testCase = Just generateSafeSignedTests testCase = Just generateSafeSignedTest
} }
unsafeSubtractOps :: RustModule unsafeSubtractOps :: RustModule
@@ -46,7 +43,7 @@ unsafeSubtractOps = RustModule {
outputName = "unsafe_sub", outputName = "unsafe_sub",
isUnsigned = True, isUnsigned = True,
generator = declareUnsafeSubtractOperators, generator = declareUnsafeSubtractOperators,
testCase = Just generateUnsafeTests testCase = Just generateUnsafeTest
} }
unsafeSignedSubtractOps :: RustModule unsafeSignedSubtractOps :: RustModule
@@ -55,7 +52,7 @@ unsafeSignedSubtractOps = RustModule {
outputName = "unsafe_ssub", outputName = "unsafe_ssub",
isUnsigned = False, isUnsigned = False,
generator = declareUnsafeSignedSubtractOperators, generator = declareUnsafeSignedSubtractOperators,
testCase = Just generateUnsafeSignedTests testCase = Just generateUnsafeSignedTest
} }
declareSafeSubtractOperators :: Word -> [Word] -> SourceFile Span declareSafeSubtractOperators :: Word -> [Word] -> SourceFile Span
@@ -321,54 +318,36 @@ generateSetters useLastCarry maxI resName i
where where
target = mkIdent resName target = mkIdent resName
generateSafeTests :: RandomGen g => Word -> g -> [Map String String] generateSafeTest :: RandomGen g => Word -> g -> (Map String String, g)
generateSafeTests size g = go g numTestCases generateSafeTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateNum g0 size
go g0 i = (y, g2) = generateNum g1 size
let (x, g1) = generateNum g0 size r | x < y = (2 ^ (size + 64)) + (x - y)
(y, g2) = generateNum g1 size | otherwise = x - y
r | x < y = (2 ^ (size + 64)) + (x - y) tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX r)]
| otherwise = x - y
tcase = Map.fromList [("x", showX x),
("y", showX y),
("z", showX r)]
in tcase : go g2 (i - 1)
generateSafeSignedTests :: RandomGen g => Word -> g -> [Map String String] generateSafeSignedTest :: RandomGen g => Word -> g -> (Map String String, g)
generateSafeSignedTests size g = go g numTestCases generateSafeSignedTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateSignedNum g0 size
go g0 i = (y, g2) = generateSignedNum g1 size
let (x, g1) = generateSignedNum g0 size r | x < y = (2 ^ (size + 64)) + (x - y)
(y, g2) = generateSignedNum g1 size | otherwise = x - y
r | x < y = (2 ^ (size + 64)) + (x - y) tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX r)]
| otherwise = x - y
tcase = Map.fromList [("x", showX x),
("y", showX y),
("z", showX r)]
in tcase : go g2 (i - 1)
generateUnsafeTests :: RandomGen g => Word -> g -> [Map String String] generateUnsafeTest :: RandomGen g => Word -> g -> (Map String String, g)
generateUnsafeTests size g = go g numTestCases generateUnsafeTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateNum g0 size
go g0 i = (y, g2) = generateNum g1 size
let (x, g1) = generateNum g0 size z = (x - y) .&. ((2 ^ size) - 1)
(y, g2) = generateNum g1 size tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)]
z = (x - y) .&. ((2 ^ size) - 1)
tcase = Map.fromList [("x", showX x), ("y", showX y),
("z", showX z)]
in tcase : go g2 (i - 1)
generateUnsafeSignedTests :: RandomGen g => Word -> g -> [Map String String] generateUnsafeSignedTest :: RandomGen g => Word -> g -> (Map String String, g)
generateUnsafeSignedTests size g = go g numTestCases generateUnsafeSignedTest size g0 = (tcase, g2)
where where
go _ 0 = [] (x, g1) = generateSignedNum g0 size
go g0 i = (y, g2) = generateSignedNum g1 size
let (x, g1) = generateSignedNum g0 size z = (x - y) .&. ((2 ^ size) - 1)
(y, g2) = generateSignedNum g1 size tcase = Map.fromList [("x", showX x), ("y", showX y), ("z", showX z)]
z = (x - y) .&. ((2 ^ size) - 1)
tcase = Map.fromList [("x", showX x), ("y", showX y),
("z", showX z)]
in tcase : go g2 (i - 1)