Source code for pypdevs.relocators.boundaryRelocator

# Copyright 2014 Modelling, Simulation and Design Lab (MSDL) at 
# McGill University and the University of Antwerp (http://msdl.cs.mcgill.ca/)
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Base class for a relocator that supports boundary construction and maintenance
"""

[docs]class BoundaryRelocator(object): """ Main class """
[docs] def __init__(self): """ Constructor """ pass
[docs] def setController(self, controller): """ Set the controller of this relocator :param controller: the controller object which can be used to fetch all required information about the model """ self.server = controller.server self.model_ids = controller.model_ids self.kernels = controller.kernels # All location queries should happen on this CACHE # This is NOT a live version of the locations and is only a temporary # version for testing some possible relocations. # However, this version SHOULD be stable, that is: it is never updated again self.locations = [model.location for model in self.model_ids] # Create all boundaries for all nodes self.boundaries = [{} for _ in range(controller.kernels)] self.constructBoundaries(self.model_ids)
[docs] def fetchModelActivity(self, model): """ Get the activity of a specific model. It will also cache the activity of all models at the same node to make subsequent calls much faster. :param model: the model to fetch the activity of, can be remote :returns: the activity of the model """ try: # Try locally return self.model_activities[model.model_id] except KeyError: # 'Cache miss' proxy = self.server.getProxy(model.location) self.model_activities.update(proxy.getCompleteActivity()) return self.model_activities[model.model_id]
[docs] def constructBoundaries(self, models): """ Construct the boundaries for the specified models :param models: the models to be added to the boundary """ for model in models: location = self.locations[model.model_id] for iport in model.IPorts: for port in iport.inline: if self.locations[port.host_DEVS.model_id] != location: self.boundaries[location].setdefault( self.locations[port.host_DEVS.model_id], set()).add(model) for oport in model.OPorts: for port, _ in oport.routing_outline: if self.locations[port.host_DEVS.model_id] != location: self.boundaries[location].setdefault( self.locations[port.host_DEVS.model_id], set()).add(model)
[docs] def removeBoundaries(self, models): """ Remove the boundaries provided by the specified models :param models: the models to be removed from the boundaries list """ for model in models: location = self.locations[model.model_id] boundaries = self.boundaries[location] # Only here for efficiency ms = set([model]) for dest in boundaries: boundaries[dest] -= ms
[docs] def scheduleMove(self, model_id, destination): """ Schedule the move of a model to another destination; this operation is reversible :param model_id: the model_id of the model to move :param destination: the destination of the model """ self.relocate[model_id] = destination model = self.model_ids[model_id] source = self.locations[model_id] update = set([model]) self.removeBoundaries(update) for iport in model.IPorts: for port in iport.inline: update.add(port.host_DEVS) for oport in model.OPorts: for port, _ in oport.routing_outline: update.add(port.host_DEVS) # Now update contains all the models that should be updated # Perform the update 'in cache' self.locations[model_id] = destination self.removeBoundaries(update) self.constructBoundaries(update) activity = self.fetchModelActivity(model) self.node_activities[source] -= activity self.node_activities[destination] += activity
[docs] def getRelocations(self, gvt, activities, horizon): """ Return all pending relocations :param gvt: current GVT :param activities: activities being passed on the GVT ring :param horizon: the activity horizon :returns: all relocations that should be executed """ # This is only a base 'abstract' class raise NotImplementedError()
[docs] def useLastStateOnly(self): """ Determines whether or not the activities of all steps should be accumulated, or only a single state should be used. :returns: boolean -- True if the relocator works with a single state """ raise NotImplementedError()