def __call__(self, machine_graph, machine, plan_n_timesteps): """ :param MachineGraph machine_graph: The machine_graph to place :param ~spinn_machine.Machine machine: The machine with respect to which to partition the application graph :param int plan_n_timesteps: number of timesteps to plan for :return: A set of placements :rtype: Placements :raise PacmanPlaceException: If something goes wrong with the placement """ # check that the algorithm can handle the constraints self._check_constraints(machine_graph.vertices) placements = Placements() vertices = sort_vertices_by_known_constraints(machine_graph.vertices) # Iterate over vertices and generate placements progress = ProgressBar(machine_graph.n_vertices, "Placing graph vertices") resource_tracker = ResourceTracker( machine, plan_n_timesteps, self._generate_radial_chips(machine)) vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph) all_vertices_placed = set() for vertex in progress.over(vertices): if vertex not in all_vertices_placed: vertices_placed = self._place_vertex(vertex, resource_tracker, machine, placements, vertices_on_same_chip, machine_graph) all_vertices_placed.update(vertices_placed) return placements
def __call__(self, machine_graph, machine, plan_n_timesteps): """ Place each vertex in a machine graph on a core in the machine. :param machine_graph: The machine_graph to place :type machine_graph:\ :py:class:`pacman.model.graphs.machine.MachineGraph` :param machine: A SpiNNaker machine object. :type machine: :py:class:`spinn_machine.Machine` :param plan_n_timesteps: number of timesteps to plan for :type plan_n_timesteps: int :return placements: Placements of vertices on the machine :rtype :py:class:`pacman.model.placements.Placements` """ # check that the algorithm can handle the constraints ResourceTracker.check_constraints(machine_graph.vertices) placements = Placements() vertices = sort_vertices_by_known_constraints(machine_graph.vertices) # Iterate over vertices and generate placements progress = ProgressBar(machine_graph.n_vertices, "Placing graph vertices") resource_tracker = ResourceTracker( machine, plan_n_timesteps, self._generate_random_chips(machine)) vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph) vertices_placed = set() for vertex in progress.over(vertices): if vertex not in vertices_placed: vertices_placed.update(self._place_vertex( vertex, resource_tracker, machine, placements, vertices_on_same_chip)) return placements
def __setup_objects(self, app_graph, machine, plan_n_time_steps, pre_allocated_resources): """ sets up the machine_graph, resource_tracker, vertices, \ progress bar. :param ApplicationGraph app_graph: app graph :param ~spinn_machine.Machine machine: machine :param int plan_n_time_steps: the number of time steps to run for. :param pre_allocated_resources: pre allocated res from other systems. :type PreAllocatedResourceContainer or None :return: (machine graph, res tracker, verts, progress bar) :rtype: tuple(MachineGraph, ResourceTracker, list(ApplicationVertex), ~.ProgressBar) """ # Load the vertices and create the machine_graph to fill machine_graph = MachineGraph(label="partitioned graph for {}".format( app_graph.label), application_graph=app_graph) resource_tracker = ResourceTracker( machine, plan_n_time_steps, preallocated_resources=pre_allocated_resources) # sort out vertex's by placement constraints vertices = sort_vertices_by_known_constraints(app_graph.vertices) # Group vertices that are supposed to be the same size self.order_vertices_for_dependent_splitters(vertices) # Set up the progress progress = ProgressBar(len(app_graph.vertices), self.__PROGRESS_BAR_VERTICES) return machine_graph, resource_tracker, vertices, progress
def __call__(self, machine_graph, machine, plan_n_timesteps): """ Place each vertex in a machine graph on a core in the machine. :param MachineGraph machine_graph: The machine_graph to place :param ~spinn_machine.Machine machine: A SpiNNaker machine object. :param int plan_n_timesteps: number of timesteps to plan for :return placements: Placements of vertices on the machine :rtype: Placements """ # check that the algorithm can handle the constraints ResourceTracker.check_constraints(machine_graph.vertices) placements = Placements() vertices = sort_vertices_by_known_constraints(machine_graph.vertices) # Iterate over vertices and generate placements progress = ProgressBar(machine_graph.n_vertices, "Placing graph vertices") resource_tracker = ResourceTracker( machine, plan_n_timesteps, self._generate_random_chips(machine)) vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph) vertices_placed = set() for vertex in progress.over(vertices): if vertex not in vertices_placed: vertices_placed.update( self._place_vertex(vertex, resource_tracker, machine, placements, vertices_on_same_chip)) return placements
def __call__(self, machine_graph, machine, plan_n_timesteps): """ :param MachineGraph machine_graph: The machine_graph to place :param ~spinn_machine.Machine machine: A SpiNNaker machine object. :param int plan_n_timesteps: number of timesteps to plan for :return: Placements of vertices on the machine :rtype: Placements """ # check that the algorithm can handle the constraints self._check_constraints( machine_graph.vertices, additional_placement_constraints={SameChipAsConstraint}) # in order to test isomorphism include: # placements_copy = Placements() placements = Placements() vertices = sort_vertices_by_known_constraints(machine_graph.vertices) progress = ProgressBar( machine_graph.n_vertices, "Placing graph vertices") resource_tracker = ResourceTracker( machine, plan_n_timesteps, self._generate_hilbert_chips(machine)) # get vertices which must be placed on the same chip vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph) # iterate over vertices and generate placements all_vertices_placed = set() for vertex in progress.over(vertices): if vertex not in all_vertices_placed: vertices_placed = self._place_vertex( vertex, resource_tracker, machine, placements, vertices_on_same_chip) all_vertices_placed.update(vertices_placed) return placements
def __call__(self, machine_graph, machine, plan_n_timesteps): """ Place a machine_graph so that each vertex is placed on a core :param machine_graph: The machine_graph to place :type machine_graph:\ :py:class:`pacman.model.graphs.machine.MachineGraph` :param machine:\ The machine with respect to which to partition the application\ graph :type machine: :py:class:`spinn_machine.Machine` :param plan_n_timesteps: number of timesteps to plan for :type plan_n_timesteps: int :return: A set of placements :rtype: :py:class:`pacman.model.placements.Placements` :raise pacman.exceptions.PacmanPlaceException: \ If something goes wrong with the placement """ # check that the algorithm can handle the constraints ResourceTracker.check_constraints(machine_graph.vertices) placements = Placements() vertices = sort_vertices_by_known_constraints(machine_graph.vertices) # Iterate over vertices and generate placements progress = ProgressBar(vertices, "Placing graph vertices") resource_tracker = ResourceTracker(machine, plan_n_timesteps) for vertex in progress.over(vertices): # Create and store a new placement anywhere on the board (x, y, p, _, _) = resource_tracker.allocate_constrained_resources( vertex.resources_required, vertex.constraints, None) placement = Placement(vertex, x, y, p) placements.add_placement(placement) return placements
def __call__(self, machine_graph, machine): """ Place a machine_graph so that each vertex is placed on a core :param machine_graph: The machine_graph to place :type machine_graph:\ :py:class:`pacman.model.graphs.machine.MachineGraph` :return: A set of placements :rtype: :py:class:`pacman.model.placements.Placements` :raise pacman.exceptions.PacmanPlaceException: \ If something goes wrong with the placement """ # check that the algorithm can handle the constraints ResourceTracker.check_constraints(machine_graph.vertices) placements = Placements() vertices = sort_vertices_by_known_constraints(machine_graph.vertices) # Iterate over vertices and generate placements progress = ProgressBar(vertices, "Placing graph vertices") resource_tracker = ResourceTracker(machine) for vertex in progress.over(vertices): # Create and store a new placement anywhere on the board (x, y, p, _, _) = resource_tracker.allocate_constrained_resources( vertex.resources_required, vertex.constraints, None) placement = Placement(vertex, x, y, p) placements.add_placement(placement) return placements
def __call__(self, machine_graph, machine, plan_n_timesteps): """ :param machine_graph: The machine_graph to place :type machine_graph:\ :py:class:`pacman.model.graphs.machine.MachineGraph` :param machine:\ The machine with respect to which to partition the application\ graph :type machine: :py:class:`spinn_machine.Machine` :param plan_n_timesteps: number of timesteps to plan for :type plan_n_timesteps: int :return: A set of placements :rtype: :py:class:`pacman.model.placements.Placements` :raise pacman.exceptions.PacmanPlaceException: \ If something goes wrong with the placement """ # check that the algorithm can handle the constraints self._check_constraints(machine_graph.vertices) # Sort the vertices into those with and those without # placement constraints placements = Placements() constrained = list() unconstrained = set() for vertex in machine_graph.vertices: if locate_constraints_of_type( vertex.constraints, AbstractPlacerConstraint): constrained.append(vertex) else: unconstrained.add(vertex) # Iterate over constrained vertices and generate placements progress = ProgressBar( machine_graph.n_vertices, "Placing graph vertices") resource_tracker = ResourceTracker( machine, plan_n_timesteps, self._generate_radial_chips(machine)) constrained = sort_vertices_by_known_constraints(constrained) for vertex in progress.over(constrained, False): self._place_vertex(vertex, resource_tracker, machine, placements) while unconstrained: # Place the subgraph with the overall most connected vertex max_connected_vertex = self._find_max_connected_vertex( unconstrained, machine_graph) self._place_unconstrained_subgraph( max_connected_vertex, machine_graph, unconstrained, machine, placements, resource_tracker, progress) # finished, so stop progress bar and return placements progress.end() return placements
def _run(self, machine_graph, machine, plan_n_timesteps): """ :param MachineGraph machine_graph: The machine_graph to place :param ~spinn_machine.Machine machine: The machine with respect to which to partition the application graph :param int plan_n_timesteps: number of timesteps to plan for :return: A set of placements :rtype: ~pacman.model.placements.Placements :raise PacmanPlaceException: If something goes wrong with the placement """ # check that the algorithm can handle the constraints self._check_constraints(machine_graph.vertices) # Sort the vertices into those with and those without # placement constraints placements = Placements() constrained = list() unconstrained = set() for vertex in machine_graph.vertices: if locate_constraints_of_type(vertex.constraints, AbstractPlacerConstraint): constrained.append(vertex) else: unconstrained.add(vertex) # Iterate over constrained vertices and generate placements progress = ProgressBar(machine_graph.n_vertices, "Placing graph vertices") resource_tracker = ResourceTracker( machine, plan_n_timesteps, self._generate_radial_chips(machine)) constrained = sort_vertices_by_known_constraints(constrained) vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph) for vertex in progress.over(constrained, False): self._place_vertex(vertex, resource_tracker, machine, placements, vertices_on_same_chip, machine_graph) while unconstrained: # Place the subgraph with the overall most connected vertex max_connected_vertex = self._find_max_connected_vertex( unconstrained, machine_graph) self._place_unconstrained_subgraph(max_connected_vertex, machine_graph, unconstrained, machine, placements, resource_tracker, progress, vertices_on_same_chip) # finished, so stop progress bar and return placements progress.end() return placements
def _sort_vertices_for_one_to_one_connection(self, machine_graph, same_chip_vertex_groups): """ :param machine_graph: the graph to place :return: list of sorted vertices """ sorted_vertices = list() found_list = set() # order vertices based on constraint priority vertices = sort_vertices_by_known_constraints(machine_graph.vertices) for vertex in vertices: if vertex not in found_list: # vertices that are one to one connected with vertex and are # not forced off chip connected_vertices = self._find_one_to_one_vertices( vertex, machine_graph) # create list for each vertex thats connected haven't already # been seen before new_list = OrderedSet() for found_vertex in connected_vertices: if found_vertex not in found_list: new_list.add(found_vertex) # looks for vertices that have same chip constraints but not # found by the one to one connection search. same_chip_vertices = list() for found_vertex in new_list: for same_chip_constrained_vertex in \ same_chip_vertex_groups[found_vertex]: if same_chip_constrained_vertex not in new_list: same_chip_vertices.append( same_chip_constrained_vertex) # add these newly found vertices to the list new_list.update(same_chip_vertices) sorted_vertices.append(new_list) found_list.update(new_list) # locate vertices which have no output or input, and add them for # placement for vertex in vertices: if vertex not in found_list: sorted_vertices.append([vertex]) return sorted_vertices
def __call__(self, machine_graph, machine, plan_n_timesteps): """ Place each vertex in a machine graph on a core in the machine. :param machine_graph: The machine_graph to place :type machine_graph:\ :py:class:`pacman.model.graphs.machine.MachineGraph` :param machine: A SpiNNaker machine object. :type machine: :py:class:`spinn_machine.Machine` :param plan_n_timesteps: number of timesteps to plan for :type plan_n_timesteps: int :return placements: Placements of vertices on the machine :rtype :py:class:`pacman.model.placements.Placements` """ # check that the algorithm can handle the constraints self._check_constraints( machine_graph.vertices, additional_placement_constraints={SameChipAsConstraint}) # in order to test isomorphism include: # placements_copy = Placements() placements = Placements() vertices = sort_vertices_by_known_constraints(machine_graph.vertices) progress = ProgressBar( machine_graph.n_vertices, "Placing graph vertices") resource_tracker = ResourceTracker( machine, plan_n_timesteps, self._generate_hilbert_chips(machine)) # get vertices which must be placed on the same chip vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph) # iterate over vertices and generate placements all_vertices_placed = set() for vertex in progress.over(vertices): if vertex not in all_vertices_placed: vertices_placed = self._place_vertex( vertex, resource_tracker, machine, placements, vertices_on_same_chip) all_vertices_placed.update(vertices_placed) return placements
def __call__(self, machine_graph, machine): # check that the algorithm can handle the constraints self._check_constraints(machine_graph.vertices) placements = Placements() vertices = sort_vertices_by_known_constraints(machine_graph.vertices) # Iterate over vertices and generate placements progress = ProgressBar(machine_graph.n_vertices, "Placing graph vertices") resource_tracker = ResourceTracker( machine, self._generate_radial_chips(machine)) vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph) all_vertices_placed = set() for vertex in progress.over(vertices): if vertex not in all_vertices_placed: vertices_placed = self._place_vertex(vertex, resource_tracker, machine, placements, vertices_on_same_chip) all_vertices_placed.update(vertices_placed) return placements
def __call__(self, machine_graph, machine): """ :param machine_graph: The machine_graph to measure :type machine_graph:\ :py:class:`pacman.model.graph.machine.MachineGraph` :return: The size of the graph in number of chips :rtype: int """ # check that the algorithm can handle the constraints ResourceTracker.check_constraints(machine_graph.vertices) ordered_vertices = sort_vertices_by_known_constraints( machine_graph.vertices) # Iterate over vertices and allocate progress = ProgressBar(machine_graph.n_vertices, "Measuring the graph") resource_tracker = ResourceTracker(machine) for vertex in progress.over(ordered_vertices): resource_tracker.allocate_constrained_resources( vertex.resources_required, vertex.constraints) return len(resource_tracker.keys)
def __call__(self, machine_graph, machine, plan_n_timesteps): """ :param ~.MachineGraph machine_graph: :param ~.Machine machine: :param int plan_n_timesteps: :rtype: int """ # check that the algorithm can handle the constraints ResourceTracker.check_constraints(machine_graph.vertices) ordered_vertices = sort_vertices_by_known_constraints( machine_graph.vertices) # Iterate over vertices and allocate progress = ProgressBar(machine_graph.n_vertices, "Measuring the graph") resource_tracker = ResourceTracker(machine, plan_n_timesteps) for vertex in progress.over(ordered_vertices): resource_tracker.allocate_constrained_resources( vertex.resources_required, vertex.constraints) return len(resource_tracker.keys)
def __call__(self, machine_graph, machine): """ :param machine_graph: The machine_graph to measure :type machine_graph:\ :py:class:`pacman.model.graph.machine.MachineGraph` :return: The size of the graph in number of chips :rtype: int """ # check that the algorithm can handle the constraints ResourceTracker.check_constraints(machine_graph.vertices) ordered_vertices = sort_vertices_by_known_constraints( machine_graph.vertices) # Iterate over vertices and allocate progress = ProgressBar(machine_graph.n_vertices, "Measuring the graph") resource_tracker = ResourceTracker(machine) for vertex in progress.over(ordered_vertices): resource_tracker.allocate_constrained_resources( vertex.resources_required, vertex.constraints) return len(resource_tracker.keys)
def __call__(self, machine_graph, machine): # check that the algorithm can handle the constraints self._check_constraints(machine_graph.vertices) # Sort the vertices into those with and those without # placement constraints placements = Placements() constrained = list() unconstrained = set() for vertex in machine_graph.vertices: if locate_constraints_of_type(vertex.constraints, AbstractPlacerConstraint): constrained.append(vertex) else: unconstrained.add(vertex) # Iterate over constrained vertices and generate placements progress = ProgressBar(machine_graph.n_vertices, "Placing graph vertices") resource_tracker = ResourceTracker( machine, self._generate_radial_chips(machine)) constrained = sort_vertices_by_known_constraints(constrained) for vertex in progress.over(constrained, False): self._place_vertex(vertex, resource_tracker, machine, placements) while unconstrained: # Place the subgraph with the overall most connected vertex max_connected_vertex = self._find_max_connected_vertex( unconstrained, machine_graph) self._place_unconstrained_subgraph(max_connected_vertex, machine_graph, unconstrained, machine, placements, resource_tracker, progress) # finished, so stop progress bar and return placements progress.end() return placements
def __call__(self, machine_graph, machine, plan_n_timesteps): """ :param machine_graph: The machine_graph to place :type machine_graph:\ :py:class:`pacman.model.graphs.machine.MachineGraph` :param machine:\ The machine with respect to which to partition the application\ graph :type machine: :py:class:`spinn_machine.Machine` :param plan_n_timesteps: number of timesteps to plan for :type plan_n_timesteps: int :return: A set of placements :rtype: :py:class:`pacman.model.placements.Placements` :raise pacman.exceptions.PacmanPlaceException: \ If something goes wrong with the placement """ # check that the algorithm can handle the constraints self._check_constraints(machine_graph.vertices) placements = Placements() vertices = sort_vertices_by_known_constraints(machine_graph.vertices) # Iterate over vertices and generate placements progress = ProgressBar( machine_graph.n_vertices, "Placing graph vertices") resource_tracker = ResourceTracker( machine, plan_n_timesteps, self._generate_radial_chips(machine)) vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph) all_vertices_placed = set() for vertex in progress.over(vertices): if vertex not in all_vertices_placed: vertices_placed = self._place_vertex( vertex, resource_tracker, machine, placements, vertices_on_same_chip) all_vertices_placed.update(vertices_placed) return placements
def __call__( self, graph, machine, plan_n_timesteps, preallocated_resources=None): """ :param graph: The application_graph to partition :type graph:\ :py:class:`pacman.model.graph.application.ApplicationGraph` :param machine: The machine with respect to which to partition the\ application_graph :type machine: :py:class:`spinn_machine.Machine` :param plan_n_timesteps: number of timesteps to plan for :type plan_n_timesteps: int :return: \ A machine_graph of partitioned vertices and partitioned edges :rtype:\ :py:class:`pacman.model.graph.machine.MachineGraph` :raise pacman.exceptions.PacmanPartitionException: \ If something goes wrong with the partitioning """ ResourceTracker.check_constraints(graph.vertices) utils.check_algorithm_can_support_constraints( constrained_vertices=graph.vertices, abstract_constraint_type=AbstractPartitionerConstraint, supported_constraints=[MaxVertexAtomsConstraint, SameAtomsAsVertexConstraint, FixedVertexAtomsConstraint]) # Load the vertices and create the machine_graph to fill machine_graph = MachineGraph( label="partitioned graph for {}".format(graph.label)) graph_mapper = GraphMapper() # sort out vertex's by placement constraints vertices = sort_vertices_by_known_constraints(graph.vertices) # Set up the progress n_atoms = 0 for vertex in vertices: n_atoms += vertex.n_atoms progress = ProgressBar(n_atoms, "Partitioning graph vertices") resource_tracker = ResourceTracker( machine, plan_n_timesteps, preallocated_resources=preallocated_resources) # Group vertices that are supposed to be the same size vertex_groups = get_same_size_vertex_groups(vertices) # Partition one vertex at a time for vertex in vertices: # check that the vertex hasn't already been partitioned machine_vertices = graph_mapper.get_machine_vertices(vertex) # if not, partition if machine_vertices is None: self._partition_vertex( vertex, plan_n_timesteps, machine_graph, graph_mapper, resource_tracker, progress, vertex_groups) progress.end() generate_machine_edges(machine_graph, graph_mapper, graph) return machine_graph, graph_mapper, resource_tracker.chips_used
def __call__(self, graph, machine, preallocated_resources=None): """ :param graph: The application_graph to partition :type graph:\ :py:class:`pacman.model.graph.application.ApplicationGraph` :param machine: The machine with respect to which to partition the\ application_graph :type machine: :py:class:`spinn_machine.Machine` :return: \ A machine_graph of partitioned vertices and partitioned edges :rtype:\ :py:class:`pacman.model.graph.machine.MachineGraph` :raise pacman.exceptions.PacmanPartitionException: \ If something goes wrong with the partitioning """ ResourceTracker.check_constraints(graph.vertices) utils.check_algorithm_can_support_constraints( constrained_vertices=graph.vertices, abstract_constraint_type=AbstractPartitionerConstraint, supported_constraints=[MaxVertexAtomsConstraint, SameAtomsAsVertexConstraint, FixedVertexAtomsConstraint]) # Load the vertices and create the machine_graph to fill machine_graph = MachineGraph( label="partitioned graph for {}".format(graph.label)) graph_mapper = GraphMapper() # sort out vertex's by placement constraints vertices = placer_utils.sort_vertices_by_known_constraints( graph.vertices) # Set up the progress n_atoms = 0 for vertex in vertices: n_atoms += vertex.n_atoms progress = ProgressBar(n_atoms, "Partitioning graph vertices") resource_tracker = ResourceTracker( machine, preallocated_resources=preallocated_resources) # Group vertices that are supposed to be the same size vertex_groups = partition_utils.get_same_size_vertex_groups(vertices) # Partition one vertex at a time for vertex in vertices: # check that the vertex hasn't already been partitioned machine_vertices = graph_mapper.get_machine_vertices(vertex) # if not, partition if machine_vertices is None: self._partition_vertex( vertex, machine_graph, graph_mapper, resource_tracker, progress, vertex_groups) progress.end() partition_utils.generate_machine_edges( machine_graph, graph_mapper, graph) return machine_graph, graph_mapper, resource_tracker.chips_used