Skip to content

Commit 861f350

Browse files
Alex McKennavmchale
authored andcommitted
Add concurrent normalization
Co-authored-by: Vanessa McHale <[email protected]>
1 parent 2ef08d6 commit 861f350

File tree

30 files changed

+965
-573
lines changed

30 files changed

+965
-573
lines changed

.ci/bindist/linux/debian/focal/buildinfo.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626
"src": {"type": "hackage", "version": "0.7.0.12"},
2727
"cabal_debian_options": ["--disable-tests"]
2828
},
29+
{
30+
"name": "atomic-primops",
31+
"src": {"type": "hackage", "version": "0.8.4"},
32+
"cabal_debian_options": ["--disable-tests"]
33+
},
34+
{
35+
"name": "lockfree-queue",
36+
"src": {"type": "hackage", "version": "0.2.3.1"},
37+
"cabal_debian_options": ["--disable-tests"]
38+
},
2939
{
3040
"name": "ghc-tcplugins-extra",
3141
"src": {"type": "hackage"}

benchmark/benchmark-normalization.hs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Clash.Netlist.Types (TopEntityT(topId))
1515

1616
import Criterion.Main
1717

18+
import qualified Control.Concurrent.MVar as MVar
1819
import qualified Control.Concurrent.Supply as Supply
1920
import Control.DeepSeq (NFData(..), rwhnf)
2021
import Data.List (isPrefixOf, partition)
@@ -42,7 +43,7 @@ main = do
4243
benchFile :: [FilePath] -> FilePath -> Benchmark
4344
benchFile idirs src =
4445
env (setupEnv idirs src) $
45-
\ ~(clashEnv, clashDesign, supplyN) -> do
46+
\ ~(clashEnv, clashDesign, supplyN, lock) -> do
4647
bench ("normalization of " ++ src)
4748
(nfIO
4849
(normalizeEntity
@@ -51,18 +52,20 @@ benchFile idirs src =
5152
(ghcTypeToHWType (opt_intWidth (envOpts clashEnv)))
5253
ghcEvaluator
5354
evaluator
55+
lock
5456
(fmap topId (designEntities clashDesign))
5557
supplyN
5658
(topId (head (designEntities clashDesign)))))
5759

5860
setupEnv
5961
:: [FilePath]
6062
-> FilePath
61-
-> IO (ClashEnv, ClashDesign, Supply.Supply)
63+
-> IO (ClashEnv, ClashDesign, Supply.Supply, MVar.MVar ())
6264
setupEnv idirs src = do
6365
(clashEnv, clashDesign) <- runInputStage idirs src
6466
supplyN <- Supply.newSupply
65-
return (clashEnv, clashDesign ,supplyN)
67+
lock <- MVar.newMVar ()
68+
return (clashEnv, clashDesign ,supplyN, lock)
6669

6770
instance NFData Supply.Supply where
6871
rnf = rwhnf

benchmark/common/BenchmarkCommon.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Clash.GHC.Evaluator
1515
import Clash.GHC.GenerateBindings
1616
import Clash.GHC.NetlistTypes
1717

18+
import qualified Control.Concurrent.MVar as MVar
1819
import qualified Control.Concurrent.Supply as Supply
1920

2021
defaultTests :: [FilePath]
@@ -57,6 +58,7 @@ runNormalisationStage
5758
-> IO (ClashEnv, ClashDesign, Id)
5859
runNormalisationStage idirs src = do
5960
supplyN <- Supply.newSupply
61+
lock <- MVar.newMVar ()
6062
(env, design) <- runInputStage idirs src
6163
let topEntityNames = fmap topId (designEntities design)
6264
let topEntity = head topEntityNames
@@ -65,5 +67,6 @@ runNormalisationStage idirs src = do
6567
(ghcTypeToHWType (opt_intWidth (opts idirs)))
6668
ghcEvaluator
6769
evaluator
70+
lock
6871
topEntityNames supplyN topEntity
6972
return (env, design{designBindings=transformedBindings},topEntity)

benchmark/profiling/run/profile-normalization-run.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Clash.GHC.PartialEval
77
import Clash.GHC.Evaluator
88
import Clash.GHC.NetlistTypes (ghcTypeToHWType)
99

10+
import qualified Control.Concurrent.MVar as MVar
1011
import qualified Control.Concurrent.Supply as Supply
1112
import Control.DeepSeq (deepseq)
1213
import Data.Binary (decode)
@@ -32,6 +33,7 @@ main = do
3233
benchFile :: [FilePath] -> FilePath -> IO ()
3334
benchFile idirs src = do
3435
supplyN <- Supply.newSupply
36+
lock <- MVar.newMVar ()
3537
(bindingsMap,tcm,tupTcm,primMap,reprs,topEntityNames,topEntity) <- setupEnv src
3638
putStrLn $ "Doing normalization of " ++ src
3739

@@ -47,6 +49,7 @@ benchFile idirs src = do
4749
(ghcTypeToHWType (opt_intWidth (envOpts clashEnv)))
4850
ghcEvaluator
4951
evaluator
52+
lock
5053
topEntityNames supplyN topEntity
5154
res `deepseq` putStrLn ".. done\n"
5255

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CHANGED: Add concurrent normalization flag [#2074](https://github.com/clash-lang/clash-compiler/pull/2074)

clash-ghc/clash-ghc.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ executable clash
7777
executable clashi
7878
Main-Is: src-ghc/Interactive.hs
7979
Build-Depends: base, clash-ghc
80-
GHC-Options: -Wall -Wcompat -rtsopts -with-rtsopts=-A128m
80+
GHC-Options: -Wall -Wcompat -threaded -rtsopts -with-rtsopts=-A128m
8181
if flag(dynamic)
8282
GHC-Options: -dynamic
8383
extra-libraries: pthread

clash-ghc/src-ghc/Clash/GHC/ClashFlags.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ flagsClash r = [
8989
, defFlag "fclash-inline-workfree-limit" $ IntSuffix (liftEwM . setInlineWFLimit r)
9090
, defFlag "fclash-edalize" $ NoArg (liftEwM (setEdalize r))
9191
, defFlag "fclash-no-render-enums" $ NoArg (liftEwM (setNoRenderEnums r))
92+
, defFlag "fclash-concurrent-normalization" $ NoArg (liftEwM (setConcurrentNormalization r))
9293
]
9394

9495
-- | Print deprecated flag warning
@@ -313,6 +314,9 @@ setAggressiveXOptBB r = modifyIORef r (\c -> c { opt_aggressiveXOptBB = True })
313314
setEdalize :: IORef ClashOpts -> IO ()
314315
setEdalize r = modifyIORef r (\c -> c { opt_edalize = True })
315316

317+
setConcurrentNormalization :: IORef ClashOpts -> IO ()
318+
setConcurrentNormalization r = modifyIORef r (\c -> c { opt_concurrentNormalization = True })
319+
316320
setRewriteHistoryFile :: IORef ClashOpts -> String -> IO ()
317321
setRewriteHistoryFile r arg = do
318322
let fileNm = case drop (length "-fclash-debug-history=") arg of

clash-lib/clash-lib.cabal

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ Library
130130
aeson-pretty >= 0.8 && < 0.9,
131131
ansi-terminal >= 0.8.0.0 && < 0.12,
132132
array,
133-
async >= 2.2.0 && < 2.3,
134133
attoparsec >= 0.10.4.0 && < 0.15,
135134
base >= 4.11 && < 5,
136135
base16-bytestring >= 0.1.1 && < 1.1,
@@ -155,6 +154,10 @@ Library
155154
hint >= 0.7 && < 0.10,
156155
interpolate >= 0.2.0 && < 1.0,
157156
lens >= 4.10 && < 5.1.0,
157+
lifted-async >=0.10 && <0.11,
158+
lifted-base >=0.2 && <0.3,
159+
lockfree-queue >=0.2 && <0.3,
160+
monad-control >=1.0 && <1.1,
158161
mtl >= 2.1.2 && < 2.3,
159162
ordered-containers >= 0.2 && < 0.3,
160163
prettyprinter >= 1.2.0.1 && < 1.8,
@@ -166,6 +169,7 @@ Library
166169
text >= 1.2.2 && < 2.1,
167170
time >= 1.4.0.1 && < 1.14,
168171
transformers >= 0.5.2.0 && < 0.7,
172+
transformers-base,
169173
trifecta >= 1.7.1.1 && < 2.2,
170174
vector >= 0.11 && < 1.0,
171175
vector-binary-instances >= 0.2.3.5 && < 0.3,

clash-lib/src/Clash/Core/PartialEval/Monad.hs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{-|
2-
Copyright : (C) 2020-2021, QBayLogic B.V.
2+
Copyright : (C) 2020-2022, QBayLogic B.V.
33
License : BSD2 (see the file LICENSE)
44
Maintainer : QBayLogic B.V. <[email protected]>
55
@@ -84,7 +84,7 @@ import Clash.Core.Util (mkUniqSystemId, mkUniqSystemTyVar)
8484
import Clash.Core.Var (Id, TyVar, Var)
8585
import Clash.Core.VarEnv
8686
import Clash.Driver.Types (Binding(..))
87-
import Clash.Rewrite.WorkFree (isWorkFree)
87+
import Clash.Rewrite.WorkFree (isWorkFreePure)
8888

8989
{-
9090
NOTE [RWS monad]
@@ -311,7 +311,11 @@ workFreeValue :: Value -> Eval Bool
311311
workFreeValue = \case
312312
VNeutral _ -> pure False
313313
VThunk x _ -> do
314-
bindings <- fmap (fmap asTerm) . genvBindings <$> getGlobalEnv
315-
isWorkFree workFreeCache bindings x
314+
env <- getGlobalEnv
315+
let bindings = fmap (fmap asTerm) (genvBindings env)
316+
let (cache, wf) = isWorkFreePure (genvWorkCache env) bindings x
317+
318+
modifyGlobalEnv (\genv -> genv { genvWorkCache = cache })
319+
pure wf
316320

317321
_ -> pure True

clash-lib/src/Clash/Core/PartialEval/NormalForm.hs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{-|
2-
Copyright : (C) 2020-2021, QBayLogic B.V.,
3-
2022 , Google Inc.
2+
Copyright : (C) 2020-2022, QBayLogic B.V.
43
License : BSD2 (see the file LICENSE)
54
Maintainer : QBayLogic B.V. <[email protected]>
65
@@ -29,11 +28,9 @@ module Clash.Core.PartialEval.NormalForm
2928
, Normal(..)
3029
, LocalEnv(..)
3130
, GlobalEnv(..)
32-
, workFreeCache
3331
) where
3432

3533
import Control.Concurrent.Supply (Supply)
36-
import Control.Lens (Lens', lens)
3734
import Data.IntMap.Strict (IntMap)
3835
import Data.Map.Strict (Map)
3936

@@ -201,6 +198,3 @@ data GlobalEnv = GlobalEnv
201198
-- ^ Cache for the results of isWorkFree. This is required to use
202199
-- Clash.Rewrite.WorkFree.isWorkFree.
203200
}
204-
205-
workFreeCache :: Lens' GlobalEnv (VarEnv Bool)
206-
workFreeCache = lens genvWorkCache (\env x -> env { genvWorkCache = x })

0 commit comments

Comments
 (0)