61 lines
2.8 KiB
Python
61 lines
2.8 KiB
Python
from collections import defaultdict
|
|
|
|
class CityRelocator(object):
|
|
def __init__(self):
|
|
self.server = None
|
|
self.kernels = 0
|
|
self.model_ids = []
|
|
|
|
def setController(self, controller):
|
|
self.kernels = controller.kernels
|
|
self.server = controller.server
|
|
self.model_ids = controller.model_ids
|
|
self.districts = defaultdict(list)
|
|
for m in controller.total_model.componentSet:
|
|
self.districts[m.district].append(m)
|
|
self.districts = [self.districts[i] for i in range(len(self.districts))]
|
|
|
|
def getRelocations(self, GVT, activities, horizon):
|
|
# Ignore activities variable
|
|
# Fetch all models and their activity
|
|
if GVT < 100.0:
|
|
return {}
|
|
previous_district_allocation = [district[0].location for district in self.districts]
|
|
relocate = {}
|
|
district_activities = defaultdict(float)
|
|
for i in range(self.kernels):
|
|
for model_id, activity in self.server.getProxy(i).getCompleteActivity().items():
|
|
district_activities[self.model_ids[model_id].district] += activity
|
|
district_activities = [district_activities[i] for i in range(len(district_activities))]
|
|
print("All loads: " + str(district_activities))
|
|
avg_activity_per_node = float(sum(district_activities)) / self.kernels
|
|
print("Avg: " + str(avg_activity_per_node))
|
|
running_activity = 0.0
|
|
district_allocation = []
|
|
to_allocate = []
|
|
for district, activity in enumerate(district_activities):
|
|
if abs(running_activity - avg_activity_per_node) < abs(running_activity - avg_activity_per_node + activity):
|
|
# Enough activity for this node, so put all these districts there
|
|
district_allocation.append(to_allocate)
|
|
running_activity = activity
|
|
to_allocate = [district]
|
|
else:
|
|
running_activity += activity
|
|
to_allocate.append(district)
|
|
if len(district_allocation) < self.kernels:
|
|
# Still have to add the last node
|
|
district_allocation.append(to_allocate)
|
|
else:
|
|
district_allocation[-1].extend(to_allocate)
|
|
print("Migrating to %s" % district_allocation)
|
|
for node, districts in enumerate(district_allocation):
|
|
for district in districts:
|
|
if previous_district_allocation[district] == node or (previous_district_allocation[district] < node and GVT > horizon):
|
|
continue
|
|
print("Moving " + str(district) + " to " + str(node))
|
|
for model in self.districts[district]:
|
|
relocate[model.model_id] = node
|
|
return relocate
|
|
|
|
def useLastStateOnly(self):
|
|
return False
|