Revision 7dfaafb1 src/hbal.hs
b/src/hbal.hs | ||
---|---|---|
27 | 27 |
, optOneline :: Bool |
28 | 28 |
, optNodef :: FilePath |
29 | 29 |
, optInstf :: FilePath |
30 |
, optMaxRounds :: Int
|
|
30 |
, optMaxLength :: Int
|
|
31 | 31 |
, optMaster :: String |
32 | 32 |
} deriving Show |
33 | 33 |
|
... | ... | |
39 | 39 |
, optOneline = False |
40 | 40 |
, optNodef = "nodes" |
41 | 41 |
, optInstf = "instances" |
42 |
, optMaxRounds = -1
|
|
42 |
, optMaxLength = -1
|
|
43 | 43 |
, optMaster = "" |
44 | 44 |
} |
45 | 45 |
|
... | ... | |
47 | 47 |
we find a valid solution or we exceed the maximum depth. |
48 | 48 |
|
49 | 49 |
-} |
50 |
iterateDepth :: Cluster.Table -- The starting table |
|
51 |
-> Int -- ^ Current round |
|
52 |
-> Int -- ^ Max rounds |
|
50 |
iterateDepth :: Cluster.Table -- ^ The starting table |
|
51 |
-> Int -- ^ Remaining length |
|
52 |
-> [(Int, String)] -- ^ Node idx to name list |
|
53 |
-> [(Int, String)] -- ^ Inst idx to name list |
|
54 |
-> Int -- ^ Max node name len |
|
55 |
-> Int -- ^ Max instance name len |
|
56 |
-> [[String]] -- ^ Current command list |
|
53 | 57 |
-> Bool -- ^ Wheter to be silent |
54 |
-> IO Cluster.Table -- The resulting table |
|
55 |
iterateDepth ini_tbl cur_round max_rounds oneline = |
|
58 |
-> IO (Cluster.Table, [[String]]) -- ^ The resulting table and |
|
59 |
-- commands |
|
60 |
iterateDepth ini_tbl max_rounds ktn kti nmlen imlen cmd_strs oneline = |
|
56 | 61 |
let Cluster.Table ini_nl ini_il ini_cv ini_plc = ini_tbl |
57 | 62 |
all_inst = Container.elems ini_il |
58 | 63 |
node_idx = Container.keys ini_nl |
... | ... | |
60 | 65 |
(Cluster.Table _ _ fin_cv fin_plc) = fin_tbl |
61 | 66 |
ini_plc_len = length ini_plc |
62 | 67 |
fin_plc_len = length fin_plc |
63 |
allowed_next = (max_rounds < 0 || cur_round < max_rounds)
|
|
68 |
allowed_next = (max_rounds < 0 || length fin_plc < max_rounds)
|
|
64 | 69 |
in |
65 | 70 |
do |
66 |
unless oneline $ printf " - round %d: " cur_round |
|
67 |
hFlush stdout |
|
68 |
let msg = |
|
69 |
if fin_cv < ini_cv then |
|
70 |
if not allowed_next then |
|
71 |
printf "%.8f, %d moves (stopping due to round limit)\n" |
|
72 |
fin_cv |
|
73 |
(fin_plc_len - ini_plc_len) |
|
74 |
else |
|
75 |
printf "%.8f, %d moves\n" fin_cv |
|
76 |
(fin_plc_len - ini_plc_len) |
|
77 |
else |
|
78 |
"no improvement, stopping\n" |
|
79 |
unless oneline $ do |
|
80 |
putStr msg |
|
71 |
let |
|
72 |
(sol_line, cmds) = Cluster.printSolutionLine ini_il ktn kti |
|
73 |
nmlen imlen (head fin_plc) |
|
74 |
upd_cmd_strs = cmds:cmd_strs |
|
75 |
unless (oneline || fin_plc_len == ini_plc_len) $ do |
|
76 |
putStrLn sol_line |
|
81 | 77 |
hFlush stdout |
82 | 78 |
(if fin_cv < ini_cv then -- this round made success, try deeper |
83 | 79 |
if allowed_next |
84 |
then iterateDepth fin_tbl (cur_round + 1) max_rounds oneline |
|
80 |
then iterateDepth fin_tbl max_rounds ktn kti |
|
81 |
nmlen imlen upd_cmd_strs oneline |
|
85 | 82 |
-- don't go deeper, but return the better solution |
86 |
else return fin_tbl
|
|
83 |
else return (fin_tbl, upd_cmd_strs)
|
|
87 | 84 |
else |
88 |
return ini_tbl)
|
|
85 |
return (ini_tbl, cmd_strs))
|
|
89 | 86 |
|
90 | 87 |
-- | Options list and functions |
91 | 88 |
options :: [OptDescr (Options -> Options)] |
... | ... | |
108 | 105 |
, Option ['m'] ["master"] |
109 | 106 |
(ReqArg (\ m opts -> opts { optMaster = m }) "ADDRESS") |
110 | 107 |
"collect data via RAPI at the given ADDRESS" |
111 |
, Option ['r'] ["max-rounds"] |
|
112 |
(ReqArg (\ i opts -> opts { optMaxRounds = (read i)::Int }) "N") |
|
113 |
"do not run for more than R rounds(useful for very unbalanced clusters)" |
|
108 |
, Option ['l'] ["max-length"] |
|
109 |
(ReqArg (\ i opts -> opts { optMaxLength = (read i)::Int }) "N") |
|
110 |
"cap the solution at this many moves (useful for very unbalanced \ |
|
111 |
\clusters)" |
|
114 | 112 |
] |
115 | 113 |
|
116 | 114 |
-- | Command line parser, using the 'options' structure. |
... | ... | |
167 | 165 |
ini_cv (Cluster.printStats nl) |
168 | 166 |
|
169 | 167 |
unless oneline $ putStrLn "Trying to minimize the CV..." |
170 |
fin_tbl <- iterateDepth ini_tbl 1 (optMaxRounds opts) oneline |
|
168 |
let mlen_fn = maximum . (map length) . snd . unzip |
|
169 |
imlen = mlen_fn kti |
|
170 |
nmlen = mlen_fn ktn |
|
171 |
|
|
172 |
(fin_tbl, cmd_strs) <- iterateDepth ini_tbl (optMaxLength opts) |
|
173 |
ktn kti nmlen imlen [] oneline |
|
171 | 174 |
let (Cluster.Table fin_nl _ fin_cv fin_plc) = fin_tbl |
172 | 175 |
ord_plc = reverse fin_plc |
173 |
unless oneline $ printf "Final coefficients: overall %.8f, %s\n" |
|
174 |
fin_cv |
|
175 |
(Cluster.printStats fin_nl) |
|
176 |
unless oneline $ do |
|
177 |
(if null fin_plc |
|
178 |
then printf "No solution found\n" |
|
179 |
else printf "Final coefficients: overall %.8f, %s\n" |
|
180 |
fin_cv (Cluster.printStats fin_nl)) |
|
176 | 181 |
|
177 | 182 |
unless oneline $ printf "Solution length=%d\n" (length ord_plc) |
178 | 183 |
|
179 |
let (sol_strs, cmd_strs) = Cluster.printSolution il ktn kti ord_plc |
|
180 |
unless oneline $ putStr $ unlines $ sol_strs |
|
181 | 184 |
when (optShowCmds opts) $ |
182 | 185 |
do |
183 | 186 |
putStrLn "" |
184 | 187 |
putStrLn "Commands to run to reach the above solution:" |
185 |
putStr $ unlines $ map (" echo gnt-instance " ++) $ concat cmd_strs |
|
188 |
putStr $ unlines $ map (" echo gnt-instance " ++) |
|
189 |
$ concat $ reverse cmd_strs |
|
186 | 190 |
when (optShowNodes opts) $ |
187 | 191 |
do |
188 | 192 |
let (orig_mem, orig_disk) = Cluster.totalResources nl |
Also available in: Unified diff