cryptol/bench/Main.hs
Aaron Tomb d76f21f89e Update benchmarks to find Prelude and CryptolTC.z3
Since they don’t run in the normal REPL environment, they need to know
about where to find the Prelude and CryptolTC.z3 more directly.
2017-03-21 12:31:04 -07:00

161 lines
5.8 KiB
Haskell

-- |
-- Module : $Header$
-- Copyright : (c) 2015-2016 Galois, Inc.
-- License : BSD3
-- Maintainer : cryptol@galois.com
-- Stability : provisional
-- Portability : portable
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import qualified Data.Text.Lazy as T
import qualified Data.Text.Lazy.IO as T
import System.FilePath ((</>))
import qualified System.Directory as Dir
import qualified Cryptol.Eval as E
import qualified Cryptol.Eval.Monad as E
import qualified Cryptol.Eval.Value as E
import qualified Cryptol.ModuleSystem.Base as M
import qualified Cryptol.ModuleSystem.Env as M
import qualified Cryptol.ModuleSystem.Monad as M
import qualified Cryptol.ModuleSystem.NamingEnv as M
import qualified Cryptol.Parser as P
import qualified Cryptol.Parser.AST as P
import qualified Cryptol.Parser.NoInclude as P
import qualified Cryptol.Symbolic as S
import qualified Cryptol.Symbolic.Value as S
import qualified Cryptol.TypeCheck as T
import qualified Cryptol.TypeCheck.AST as T
import qualified Cryptol.Utils.Ident as I
import qualified Data.SBV.Dynamic as SBV
import Criterion.Main
main :: IO ()
main = do
cd <- Dir.getCurrentDirectory
defaultMain [
bgroup "parser" [
parser "Prelude" "lib/Cryptol.cry"
, parser "Extras" "lib/Cryptol/Extras.cry"
, parser "PreludeWithExtras" "bench/data/PreludeWithExtras.cry"
, parser "BigSequence" "bench/data/BigSequence.cry"
, parser "BigSequenceHex" "bench/data/BigSequenceHex.cry"
, parser "AES" "bench/data/AES.cry"
, parser "SHA512" "bench/data/SHA512.cry"
]
, bgroup "typechecker" [
tc cd "Prelude" "lib/Cryptol.cry"
, tc cd "Extras" "lib/Cryptol/Extras.cry"
, tc cd "PreludeWithExtras" "bench/data/PreludeWithExtras.cry"
, tc cd "BigSequence" "bench/data/BigSequence.cry"
, tc cd "BigSequenceHex" "bench/data/BigSequenceHex.cry"
, tc cd "AES" "bench/data/AES.cry"
, tc cd "SHA512" "bench/data/SHA512.cry"
]
, bgroup "conc_eval" [
ceval cd "AES" "bench/data/AES.cry" "bench_correct"
, ceval cd "ZUC" "bench/data/ZUC.cry" "ZUC_TestVectors"
, ceval cd "SHA512" "bench/data/SHA512.cry" "testVector1 ()"
]
, bgroup "sym_eval" [
seval cd "AES" "bench/data/AES.cry" "bench_correct"
, seval cd "ZUC" "bench/data/ZUC.cry" "ZUC_TestVectors"
, seval cd "SHA512" "bench/data/SHA512.cry" "testVector1 ()"
]
]
-- | Make a benchmark for parsing a Cryptol module
parser :: String -> FilePath -> Benchmark
parser name path =
env (T.readFile path) $ \(~bytes) ->
bench name $ nfIO $ do
let cfg = P.defaultConfig
{ P.cfgSource = path
, P.cfgPreProc = P.guessPreProc path
}
case P.parseModule cfg bytes of
Right pm -> return pm
Left err -> error (show err)
-- | Make a benchmark for typechecking a Cryptol module. Does parsing
-- in the setup phase in order to isolate typechecking
tc :: String -> String -> FilePath -> Benchmark
tc cd name path =
let withLib = M.withPrependedSearchPath [cd </> "lib"] in
let setup = do
bytes <- T.readFile path
let cfg = P.defaultConfig
{ P.cfgSource = path
, P.cfgPreProc = P.guessPreProc path
}
Right pm = P.parseModule cfg bytes
menv <- M.initialModuleEnv
(Right ((prims, scm, tcEnv), menv'), _) <- M.runModuleM menv $ withLib $ do
-- code from `loadModule` and `checkModule` in
-- `Cryptol.ModuleSystem.Base`
let pm' = M.addPrelude pm
M.loadDeps pm'
Right nim <- M.io (P.removeIncludesModule path pm')
npm <- M.noPat nim
(tcEnv,declsEnv,scm) <- M.renameModule npm
prims <- if P.thing (P.mName pm) == I.preludeName
then return (M.toPrimMap declsEnv)
else M.getPrimMap
return (prims, scm, tcEnv)
return (prims, scm, tcEnv, menv')
in env setup $ \ ~(prims, scm, tcEnv, menv) ->
bench name $ nfIO $ M.runModuleM menv $ withLib $ do
let act = M.TCAction { M.tcAction = T.tcModule
, M.tcLinter = M.moduleLinter (P.thing (P.mName scm))
, M.tcPrims = prims
}
M.typecheck act scm tcEnv
ceval :: String -> String -> FilePath -> T.Text -> Benchmark
ceval cd name path expr =
let withLib = M.withPrependedSearchPath [cd </> "lib"] in
let setup = do
menv <- M.initialModuleEnv
(Right (texpr, menv'), _) <- M.runModuleM menv $ withLib $ do
m <- M.loadModuleByPath path
M.setFocusedModule (T.mName m)
let Right pexpr = P.parseExpr expr
(_, texpr, _) <- M.checkExpr pexpr
return texpr
return (texpr, menv')
in env setup $ \ ~(texpr, menv) ->
bench name $ nfIO $ E.runEval $ do
env' <- E.evalDecls (S.allDeclGroups menv) mempty
(e :: E.Value) <- E.evalExpr env' texpr
E.forceValue e
seval :: String -> String -> FilePath -> T.Text -> Benchmark
seval cd name path expr =
let withLib = M.withPrependedSearchPath [cd </> "lib"] in
let setup = do
menv <- M.initialModuleEnv
(Right (texpr, menv'), _) <- M.runModuleM menv $ withLib $ do
m <- M.loadModuleByPath path
M.setFocusedModule (T.mName m)
let Right pexpr = P.parseExpr expr
(_, texpr, _) <- M.checkExpr pexpr
return texpr
return (texpr, menv')
in env setup $ \ ~(texpr, menv) ->
bench name $ nfIO $ E.runEval $ do
env' <- E.evalDecls (S.allDeclGroups menv) mempty
(e :: S.Value) <- E.evalExpr env' texpr
E.io $ SBV.compileToSMTLib SBV.SMTLib2 False $
return (S.fromVBit e)