11from __future__ import division
22
33import numpy as np
4+ import math
45
56from collections import defaultdict
67from itertools import groupby , chain
78from operator import itemgetter
89
10+
911# Convert standard time in float format to discrete time in "step" format.
1012def step (time , period , digits ):
1113 s = time - (time % period )
1214 s = s + period if time % period != 0 else s
1315 return round (s , digits )
1416
17+
1518# Generate list of time steps between the specified interval. Similar to
1619# Python's range(), with float support.
1720def steps (start , stop , period , digits ):
@@ -20,7 +23,8 @@ def steps(start, stop, period, digits):
2023 yield round (r , digits )
2124 r += period
2225
23- def map_layout (data ):
26+
27+ def map_layout (data ,layout_info ):
2428 m = {}
2529 sled_id = 0
2630 draw_id = 0
@@ -50,12 +54,17 @@ def map_layout(data):
5054
5155 sled_id += 1
5256
57+ layout_info ["n_racks" ] = rack_id + 1
58+ layout_info ["n_drawers" ] = (draw_id + 1 )* layout_info ["n_racks" ]
59+ layout_info ["sleds_drawer" ] = (sled_id / layout_info ["n_racks" ])/ (draw_id + 1 )
60+
5361 return m
5462
63+
5564def distance (layout , a , b ):
5665 d = 0
5766 if a != b :
58- d = 1
67+ d = 1
5968 if layout [a ]["sled_id" ] != layout [b ]["sled_id" ]:
6069 d = 10
6170 if layout [a ]["draw_id" ] != layout [b ]["draw_id" ]:
@@ -64,6 +73,7 @@ def distance(layout, a, b):
6473 d = 1000
6574 return d
6675
76+
6777def fragmentation (layout , subset ):
6878 f = 0.0
6979 by_rack = defaultdict (list )
@@ -83,12 +93,64 @@ def fragmentation(layout, subset):
8393
8494 return f / len (by_rack )
8595
96+
97+ def system_fragmentation (layout , used , layout_info ):
98+ blocks_total = math .ceil (layout_info ["n_drawers" ]/ layout_info ["n_racks" ])
99+ blocks_resources = layout_info ["sleds_drawer" ]
100+ resources_total = blocks_total * blocks_resources
101+ resources_used = defaultdict (list )
102+ blocks_seen = defaultdict (list )
103+
104+ #Determine which sids are used
105+ for sid in used :
106+ if layout [sid ]["rack_id" ] not in resources_used :
107+ resources_used [layout [sid ]["rack_id" ]] = 1
108+ blocks_seen [layout [sid ]["rack_id" ]] = []
109+ else :
110+ resources_used [layout [sid ]["rack_id" ]] += 1
111+
112+ if layout [sid ]['draw_id' ] not in blocks_seen [layout [sid ]["rack_id" ]]:
113+ blocks_seen [layout [sid ]["rack_id" ]].append (layout [sid ]['draw_id' ])
114+
115+ sum_f = 0
116+ for rf in resources_used :
117+ f = 0
118+ blocks_used = len (blocks_seen [rf ])
119+ min_blocks = math .ceil ((resources_used [rf ] / resources_total )* blocks_total )
120+
121+ if min_blocks == 1 and blocks_used == blocks_total :
122+ f = 1
123+ elif min_blocks == 0 :
124+ f = 0
125+ elif blocks_used == min_blocks :
126+ f = 0
127+ else :
128+ f = (blocks_used - min_blocks ) / blocks_total
129+
130+ sum_f += f
131+
132+ if sum_f == 0 :
133+ return 0
134+ else :
135+ return sum_f / layout_info ["n_racks" ]
136+
137+
86138def list_sockets (nodes ):
87139 return list (chain .from_iterable (nodes ))
88140
141+
89142def list_free_sockets (free ):
90143 nodes = []
91144 for f in free .values ():
92145 for l , n in f .iteritems ():
93146 nodes .append (n )
94147 return list (chain .from_iterable (chain .from_iterable (nodes )))
148+
149+
150+ def list_used_sockets (free ,layout ):
151+ used = []
152+ for sid in layout :
153+ if sid not in free :
154+ used .append (sid )
155+
156+ return used
0 commit comments