root/hiersort/sim/Config.hs

Revision 1, 12.3 kB (checked in by thesz, 2 years ago)

Initial commit

Line 
1 -- | Config.hs
2 -- Configuration parameters, all at once.
3 --
4 -- Copytight (C) 2007, 2008 Serguey Zefirov
5 --
6 -- This program is free software; you can redistribute it and/or modify
7 -- it under the terms of the GNU General Public License as published by
8 -- the Free Software Foundation; either version 3, or (at your option)
9 -- any later version.
10 -- See file COPYING or visit http://www.gnu.org/licenses for details.
11
12 module Config(
13                  Config(..)
14                 ,NodeConfig(..)
15                 ,getHierParams
16                 ,getProcessorChanWidth
17                 ,getHierProcWidth
18                 ,parseCommandLine
19                 ,readTaskParam
20         ) where
21
22
23 import Data.Char
24 import qualified Data.Map as M
25 import Data.Maybe
26 import System.Environment
27 import System.Exit
28 import Control.Monad
29
30 import InterfaceTypes
31
32 -------------------------------------------------------------------------------
33 -- Data and defaults declaration.
34
35
36 data Config = Config {
37                 -- Runner parameters.
38                  cfgDebug                       :: Bool
39                 -- Processor instantiating parameters.
40                 ,cfgProcMaxThreads              :: Int  -- max threads served
41                 ,cfgProcParThreads              :: Int  -- parallel threads in one cycle
42                 ,cfgProcShedulePolicy           :: ProcShedulingPolicy
43                 ,cfgProcOutWidth                :: Int  -- processor output width.
44                 -- Matcher parameters.
45                 ,cfgProcMatcherSize             :: Int
46                 ,cfgProcMatcherForceUp          :: Int
47                 ,cfgProcMatcherDnWidth          :: Int
48                 -- Up buffer parameters.
49                 ,cfgUpBufMaxLen                 :: Int  -- upstream buffer size
50                 -- Presorter parameters.
51                 ,cfgPresorterMaxLen             :: Int  -- presorterarable filter size
52                 -- Run parameters.
53                 ,cfgMaxWait                     :: Integer      -- max number of clocks to wait
54                 -- Task parameters.
55                 ,cfgTaskSettings                :: M.Map String String
56                 -- Hierarchy parameters.
57                 ,cfgHierDepth                   :: Int
58                 ,cfgHierBaseSortSize            :: Int
59                 ,cfgHierBaseSortHeight          :: Int
60                 ,cfgHierSortSizeInc             :: Maybe Double
61                 ,cfgHierSortSizeMul             :: Double
62                 ,cfgHierSortForceUpRatio        :: Double
63                 ,cfgHierSortHeightInc           :: Maybe Double
64                 ,cfgHierSortHeightMul           :: Double
65                 -- width
66                 ,cfgHierBaseProcChanWidth       :: Int
67                 ,cfgHierChanWidthInc            :: Double
68                 ,cfgHierChanPresortUpWidthInc   :: Double
69         }
70         deriving Show
71
72 -- Default config.
73 defConfig = Config {
74 #ifndef DEBUG
75                  cfgDebug                = False
76 #else
77                  cfgDebug                = True
78 #endif
79                 ,cfgProcMaxThreads       = 1
80                 ,cfgProcParThreads       = 1
81                 ,cfgProcShedulePolicy    = SheduleWindow
82                 ,cfgUpBufMaxLen          = 6
83                 ,cfgPresorterMaxLen      = 6
84                 ,cfgHierDepth            = 0
85                 ,cfgProcMatcherSize      = 4
86                 ,cfgProcMatcherForceUp   = 4
87                 ,cfgProcMatcherDnWidth   = 1
88                 ,cfgProcOutWidth         = 4
89                 ,cfgMaxWait              = 1000000000
90                 ,cfgTaskSettings         = M.empty
91                 ,cfgHierBaseSortSize     = 16
92                 ,cfgHierBaseSortHeight   = 4
93                 ,cfgHierSortSizeInc      = Nothing
94                 ,cfgHierSortSizeMul      = 1.05
95                 ,cfgHierSortForceUpRatio = 0.9
96                 ,cfgHierSortHeightInc    = Nothing
97                 ,cfgHierSortHeightMul    = 1.5
98                 -- widths
99                 ,cfgHierBaseProcChanWidth     = 1
100                 ,cfgHierChanWidthInc          = 0.0
101                 ,cfgHierChanPresortUpWidthInc = 0.0
102         }
103
104
105 -------------------------------------------------------------------------------
106 -- Get hierarch parameters from config.
107
108 -- Parameters for node in communication hierarchy.
109 data NodeConfig = NodeConfig {
110                 -- sorters
111                  nodeCfgSortSize                :: Int
112                 ,nodeCfgSortForceUp             :: Int
113                 ,nodeCfgSortHeight              :: Int
114                 -- channels
115                 ,nodeCfgUpChanWidth             :: Int  -- from/to uplevel
116                 ,nodeCfgDownChanWidth           :: Int  -- from/to downlevel
117                 ,nodeCfgPreUpChanWidth          :: Int  -- presort->upbuf
118                 ,nodeCfgPreSortChanWidth        :: Int  -- presort->sortmach
119         }
120         deriving Show
121
122 -- Getting parameters for nodes from configuration.
123 -- It returns a list of node parameters, the length of
124 -- list is the depth of hierarchy.
125 getHierParams cfg = reverse $ take depth nodeConfigs
126         where
127                 depth = cfgHierDepth cfg
128                 heightChange = case cfgHierSortHeightInc cfg of
129                         Nothing -> (cfgHierSortHeightMul cfg*)
130                         Just i  -> (i+)
131                 lenChange = case cfgHierSortSizeInc cfg of
132                         Nothing -> (cfgHierSortSizeMul cfg*)
133                         Just i  -> (i+)
134                
135                 heights = iterate heightChange (toEnum $ cfgHierBaseSortHeight cfg)
136                 lengths = iterate lenChange (toEnum $ cfgHierBaseSortSize cfg)
137                 forceUps = map (cfgHierSortForceUpRatio cfg*) lengths
138                 downChanWidths =
139                           iterate (+cfgHierChanWidthInc cfg)
140                         $ toEnum $ getProcessorChanWidth cfg
141                 upChanWidths = tail downChanWidths
142                 presortUpChanWidths =
143                         iterate (+cfgHierChanPresortUpWidthInc cfg)
144                         $ (/2) $ toEnum $ getProcessorChanWidth cfg
145                 mkNodeConfig (l,fu,h) (dcw,ucw,pucw)
146                         | fu > l || fu < 1 = error "Force up ratio seem bigger that 1 or too small."
147                         | otherwise = NodeConfig {
148                                  nodeCfgSortSize    = fromEnum $ l+0.5
149                                 ,nodeCfgSortForceUp = fromEnum $ fu+0.5
150                                 ,nodeCfgSortHeight  = fromEnum $ h+0.5
151                                 ,nodeCfgUpChanWidth = fromEnum $ ucw+0.5
152                                 ,nodeCfgDownChanWidth = fromEnum $ dcw+0.5
153                                 ,nodeCfgPreUpChanWidth = fromEnum $ pucw+0.5
154                                 ,nodeCfgPreSortChanWidth = fromEnum $ dcw+ucw/2+0.5
155                                 }
156                 nodeConfigs = zipWith mkNodeConfig
157                         (zip3 lengths forceUps heights)
158                         (zip3 downChanWidths upChanWidths presortUpChanWidths)
159
160 getProcessorChanWidth cfg = cfgHierBaseProcChanWidth cfg
161
162 getHierProcWidth cfg = case getHierParams cfg of
163         [] -> getProcessorChanWidth cfg
164         (p:_) -> nodeCfgUpChanWidth p
165
166 -------------------------------------------------------------------------------
167 -- Command-line parameters parsing.
168
169 parseCommandLine = do
170         args <- getArgs
171         parseAnyArgs defConfig args
172
173 parseAnyArgs config args = do
174         parsed <- foldM (flip parseArg) config args
175         validate parsed
176
177 -- We can perform some validation here. If we need one.
178 -- (actually, we need one, but we are too lazy and prefer to stay away
179 -- from negative widths, for example)
180 validate config = return config
181
182 halt words = do
183         putStrLn $ unwords words
184         putStrLn "Halted."
185         exitFailure
186
187 usage words = do
188         putStrLn $ unwords words
189         usageBody
190
191 usageFunc _ _ = usageBody
192
193 usageBody = do
194         pn <- getProgName
195         putStrLn $ unwords ["usage:",pn,"<options>"]
196         putStrLn ""
197         putStrLn "Options are:"
198         putStrLn usageText
199         exitFailure
200         where
201                 argNames = map fst argFunctions
202                 argDescs = map (fst . snd) argFunctions
203                 maxArgLen = maximum $ (0:) $ map length argNames
204                 expArgNames = map (\n -> replicate (maxArgLen - length n) ' '++"--"++n) argNames
205                 usageText = unlines $ zipWith (\a d -> a++" - "++d) expArgNames argDescs
206
207 parseArg argS config
208         | Just (func,val) <- splitArgS argS = do
209                 func val config
210         | otherwise = usage ["unknown or invalid command-line argument",argS]
211
212 splitArgS argS = do
213         argthenval <- strip argS
214         (arg,val) <- split argthenval
215         func <- findFunc arg
216         return (func,val)
217         where
218                 strip ('-':'-':argthenval) = Just argthenval
219                 strip _                    = Nothing
220                 split atv = case span (/='=') atv of
221                         (arg,'=':val) -> Just (arg,val)
222                         _             -> Nothing
223                 findFunc arg =
224                         fmap (snd . snd) $
225                         listToMaybe $
226                         dropWhile ((/=arg) . fst) argFunctions
227
228 argFunctions = [
229                  ("help"                 ,("print usage",usageFunc))
230                 ,("debug"                ,("print debug information",boolReadChanger chgCfgDebug))
231                 ,("file"                 ,("load options from file (one --option=val per line, // and # EOL comments",readConfigFile))
232                 ,("procMaxThreads"       ,("execution unit max threads",readChanger chgCfgProcMaxThreads))
233                 ,("procParThreads"       ,("parallel threads in one cycle",readChanger chgCfgProcParThreads))
234                 ,("procMatcherSize"      ,("matcher size for processor",readChanger chgCfgProcMatcherSize))
235                 ,("procMatcherForceUp"   ,("matcher force up limit",readChanger chgCfgProcMatcherForceUp))
236                 ,("procMatcherDnWidth"   ,("number of pairs to generate in one tick",readChanger chgCfgProcMatcherDnWidth))
237                 ,("procShedulePolicy"    ,("processor shedule policy: "++show [SheduleAllWorkBack ..],readChanger chgCfgProcShedulePolicy))
238                 ,("procOutWidth"         ,("processor output width",readChanger chgCfgProcOutWidth))
239                 ,("upBufMaxLen"          ,("upbuf capacity",readChanger chgCfgUpBufMaxLen))
240                 ,("presorterMaxLen"      ,("presorter capacity",readChanger chgCfgPresorterMaxLen))
241                 ,("hierDepth"            ,("depth of hierarchy",readChanger chgCfgHierDepth))
242                 ,("maxWait"              ,("maximum number of cycles to wait program termination.",readChanger chgCfgMaxWait))
243                 ,("taskOption"           ,("set option for task at hand.",changeTaskSetting))
244                 ,("hierBaseSortSize"     ,("size of sorter in lowest node",readChanger chgCfgHierBaseSortSize))
245                 ,("hierBaseSortHeight"   ,("capacity of sorter per lowest node",readChanger chgCfgHierBaseSortHeight))
246                 ,("hierSortSizeInc"      ,("increment for node sorter size",readChanger chgCfgHierSortSizeInc))
247                 ,("hierSortSizeMul"      ,("multiplier for node sorter size",readChanger chgCfgHierSortSizeMul))
248                 ,("hierSortForceUpRatio" ,("sort machine fill ratio for forwarding tokens up",readChanger chgCfgHierSortForceUpRatio))
249                 ,("hierSortHeightInc"    ,("incrment for node sorter capacity",readChanger chgCfgHierSortHeightInc))
250                 ,("hierSortHeightMul"    ,("multiplier for node sorter capacity",readChanger chgCfgHierSortHeightMul))
251                 ,("hierBaseProcChanWidth",("base processor element channel width.",readChanger chgCfgHierBaseProcChanWidth))
252                 ,("hierChanWidthInc"     ,("channel width hierarchy increment.",readChanger chgCfgHierChanWidthInc))
253                 ,("hierChanPresortUpWidthInc",("hierarchy internal bus width from presorter to upstream buffer.",readChanger chgCfgHierChanPresortUpWidthInc))
254         ]
255
256 -------------------------------------------------------------------------------
257 -- Parsers for different value types.
258
259 readChanger :: Read a => (a -> Config -> Config) -> String -> Config -> IO Config
260 readChanger f val cfg = case readsPrec 0 val of
261         [(r,"")] -> return $ f r cfg
262         _ -> halt [show val,"does not parse."]
263
264 boolReadChanger :: (Bool -> Config -> Config) -> String -> Config -> IO Config
265 boolReadChanger f val cfg
266         | elem lowVal ["off","false","0"] = return $ f False cfg
267         | elem lowVal ["on","true","1"] = return $ f True cfg
268         where
269                 lowVal = map toLower val
270
271 -------------------------------------------------------------------------------
272 -- Change different parts of config.
273
274 chgCfgDebug b cfg = cfg { cfgDebug = b }
275 chgCfgProcMaxThreads i cfg = cfg { cfgProcMaxThreads = i }
276 chgCfgProcParThreads i cfg = cfg { cfgProcParThreads = i }
277 chgCfgUpBufMaxLen i cfg = cfg { cfgUpBufMaxLen = i }
278 chgCfgPresorterMaxLen i cfg = cfg { cfgPresorterMaxLen = i }
279 chgCfgHierDepth i cfg = cfg { cfgHierDepth = i }
280 chgCfgMaxWait i cfg = cfg { cfgMaxWait = i }
281 chgCfgProcMatcherSize i cfg = cfg { cfgProcMatcherSize = i }
282 chgCfgProcMatcherForceUp i cfg = cfg { cfgProcMatcherForceUp = i }
283 chgCfgProcMatcherDnWidth i cfg = cfg { cfgProcMatcherDnWidth = i }
284 chgCfgProcShedulePolicy i cfg = cfg { cfgProcShedulePolicy = i }
285 chgCfgProcOutWidth i cfg = cfg { cfgProcOutWidth = i }
286 chgCfgHierBaseSortSize i cfg = cfg { cfgHierBaseSortSize = i }
287 chgCfgHierBaseSortHeight i cfg = cfg { cfgHierBaseSortHeight = i }
288 chgCfgHierSortSizeInc i cfg = cfg { cfgHierSortSizeInc = Just i }
289 chgCfgHierSortSizeMul i cfg = cfg { cfgHierSortSizeMul = i }
290 chgCfgHierSortForceUpRatio i cfg = cfg { cfgHierSortForceUpRatio = i }
291 chgCfgHierSortHeightInc i cfg = cfg { cfgHierSortHeightInc = Just i }
292 chgCfgHierSortHeightMul i cfg = cfg { cfgHierSortHeightMul = i }
293 chgCfgHierBaseProcChanWidth i cfg = cfg { cfgHierBaseProcChanWidth = i }
294 chgCfgHierChanWidthInc i cfg = cfg { cfgHierChanWidthInc = i }
295 chgCfgHierChanPresortUpWidthInc i cfg = cfg { cfgHierChanPresortUpWidthInc = i }
296
297 -------------------------------------------------------------------------------
298 -- Change task settings.
299
300 changeTaskSetting val cfg
301         | valid = return newcfg
302         | otherwise = halt [show val, "isn't in 'key=value' syntax"]
303         where
304                 (valid,key,value) = case span (/='=') val of
305                         (key,'=':value) -> (True,key,value)
306                         _               -> (False,undefined,undefined)
307                 newcfg = cfg { cfgTaskSettings = M.insert key value (cfgTaskSettings cfg) }
308
309 -------------------------------------------------------------------------------
310 -- Read (as in invoking Read class member) task parameter.
311
312 readTaskParam :: (Read a) => String -> a -> Config -> a
313 readTaskParam pname def cfg = case M.lookup pname (cfgTaskSettings cfg) of
314         Nothing -> def
315         Just val -> case readsPrec 0 val of
316                 [(r,"")] -> r
317                 _ -> error $ unwords [show val,"isn't valid for",pname]
318
319 -------------------------------------------------------------------------------
320 -- Read config file.
321
322 stripWhite = dropWhile isSpace . reverse . dropWhile isSpace . reverse
323
324 readConfigFile fn cfg = do
325         text <- readFile fn
326         let args = filter (not . isComment) $ map stripWhite $ lines text
327         parseAnyArgs cfg args
328         where
329                 isComment ('/':'/':_) = True
330                 isComment ('#':_) = True
331                 isComment "" = True
332                 isComment _ = False
Note: See TracBrowser for help on using the browser.