• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SpiNNakerManchester / PACMAN / 8911737749

01 May 2024 03:54PM UTC coverage: 88.011% (+1.9%) from 86.14%
8911737749

push

github

Christian-B
merged in master

2278 of 2641 branches covered (86.26%)

Branch coverage included in aggregate %.

4725 of 5316 relevant lines covered (88.88%)

0.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.38
/pacman/utilities/algorithm_utilities/routing_algorithm_utilities.py
1
# Copyright (c) 2021 The University of Manchester
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
6
#
7
#     https://www.apache.org/licenses/LICENSE-2.0
8
#
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
# See the License for the specific language governing permissions and
13
# limitations under the License.
14

15
from typing import List, Optional, Tuple
1✔
16

17
from spinn_utilities.typing.coords import XY
1✔
18
from spinn_machine import Chip
1✔
19

20
from pacman.data import PacmanDataView
1✔
21
from pacman.model.graphs import AbstractVirtual
1✔
22
from pacman.model.graphs.application import (
1✔
23
    ApplicationEdgePartition, ApplicationVertex)
24
from pacman.model.graphs.machine import MachineVertex
1✔
25

26

27
def get_app_partitions() -> List[ApplicationEdgePartition]:
1✔
28
    """
29
    Find all application partitions.
30

31
    .. note::
32
        Where a vertex splitter indicates that it has internal
33
        partitions but is not the source of an external partition, a "fake"
34
        empty application partition is added.  This allows the calling
35
        algorithm to loop over the returned list and look at the set of
36
        edges *and* internal partitions to get a complete picture of *all*
37
        targets for each source machine vertex at once.
38

39
    :return: list of partitions
40

41
        .. note::
42
            Where there are only internal multicast partitions, the partition
43
            will have no edges.  Caller should use
44
            `vertex.splitter.get_internal_multicast_partitions` for details.
45
    :rtype: list(ApplicationEdgePartition)
46
    """
47
    # Find all partitions that need to be dealt with
48
    # Make a copy which we can edit
49
    partitions = list(PacmanDataView.iterate_partitions())
1✔
50
    sources = frozenset(p.pre_vertex for p in partitions)
1✔
51

52
    # Convert internal partitions to self-connected partitions
53
    for v in PacmanDataView.iterate_vertices():
1✔
54
        if not isinstance(v, ApplicationVertex) or not v.splitter:
1!
55
            continue
×
56
        internal_partitions = v.splitter.get_internal_multicast_partitions()
1✔
57
        if v not in sources and internal_partitions:
1✔
58
            # guarantee order
59
            for identifier in dict.fromkeys(
1✔
60
                    p.identifier for p in internal_partitions):
61
                # Add a partition with no edges to identify this as internal
62
                partitions.append(ApplicationEdgePartition(identifier, v))
1✔
63
    return partitions
1✔
64

65

66
def longest_dimension_first(
1✔
67
        vector: Tuple[int, int, int], start: XY) -> List[Tuple[int, XY]]:
68
    """
69
    List the (x, y) steps on a longest-dimension first route.
70

71
    :param tuple(int,int,int) vector: (x, y, z)
72
        The vector which the path should cover.
73
    :param tuple(int,int) start: (x, y)
74
        The coordinates from which the path should start.
75

76
        .. note::
77
            This is a 2D coordinate.
78
    :return: min route
79
    :rtype: list(tuple(int,tuple(int, int)))
80
    """
81
    return vector_to_nodes(
1✔
82
        sorted(enumerate(vector), key=(lambda x: abs(x[1])), reverse=True),
83
        start)
84

85

86
def vector_to_nodes(dm_vector: List[XY], start: XY) -> List[Tuple[int, XY]]:
1✔
87
    """
88
    Convert a vector to a set of nodes.
89

90
    :param list(tuple(int,int)) dm_vector:
91
        A vector made up of a list of (dimension, magnitude), where dimensions
92
        are x=0, y=1, z=diagonal=2
93
    :param tuple(int,int) start: The x, y coordinates of the start
94
    :return: A list of (link_id, (target_x, target_y)) of nodes on a route
95
    :rtype: list(tuple(int,tuple(int, int)))
96
    """
97
    machine = PacmanDataView.get_machine()
1✔
98
    x, y = start
1✔
99

100
    out = []
1✔
101

102
    for dimension, magnitude in dm_vector:
1✔
103
        if magnitude == 0:
1✔
104
            continue
1✔
105

106
        if dimension == 0:  # x
1✔
107
            if magnitude > 0:
1✔
108
                # Move East (0) magnitude times
109
                for _ in range(magnitude):
1✔
110
                    x, y = machine.xy_over_link(x, y, 0)
1✔
111
                    out.append((0, (x, y)))
1✔
112
            else:
113
                # Move West (3) -magnitude times
114
                for _ in range(magnitude, 0):
1✔
115
                    x, y = machine.xy_over_link(x, y, 3)
1✔
116
                    out.append((3, (x, y)))
1✔
117
        elif dimension == 1:  # y
1✔
118
            if magnitude > 0:
1✔
119
                # Move North (2) magnitude times
120
                for _ in range(magnitude):
1✔
121
                    x, y = machine.xy_over_link(x, y, 2)
1✔
122
                    out.append((2, (x, y)))
1✔
123
            else:
124
                # Move South (5) -magnitude times
125
                for _ in range(magnitude, 0):
1✔
126
                    x, y = machine.xy_over_link(x, y, 5)
1✔
127
                    out.append((5, (x, y)))
1✔
128
        else:  # z
129
            if magnitude > 0:
1✔
130
                # Move SouthWest (4) magnitude times
131
                for _ in range(magnitude):
1✔
132
                    x, y = machine.xy_over_link(x, y, 4)
1✔
133
                    out.append((4, (x, y)))
1✔
134
            else:
135
                # Move NorthEast (1) -magnitude times
136
                for _ in range(magnitude, 0):
1✔
137
                    x, y = machine.xy_over_link(x, y, 1)
1✔
138
                    out.append((1, (x, y)))
1✔
139
    return out
1✔
140

141

142
def vertex_xy(vertex: MachineVertex) -> XY:
1✔
143
    """
144
    :param MachineVertex vertex:
145
    :rtype: tuple(int,int)
146
    """
147
    if not isinstance(vertex, AbstractVirtual):
1✔
148
        placement = PacmanDataView.get_placement_of_vertex(vertex)
1✔
149
        return placement.x, placement.y
1✔
150
    link_data = vertex.get_link_data(PacmanDataView.get_machine())
1✔
151
    return link_data.connected_chip_x, link_data.connected_chip_y
1✔
152

153

154
def vertex_chip(vertex: MachineVertex) -> Chip:
1✔
155
    """
156
    :param MachineVertex vertex:
157
    :rtype: ~spinn_machine.Chip
158
    """
159
    machine = PacmanDataView.get_machine()
×
160
    if not isinstance(vertex, AbstractVirtual):
×
161
        placement = PacmanDataView.get_placement_of_vertex(vertex)
×
162
        return machine[placement.x, placement.y]
×
163
    link_data = vertex.get_link_data(machine)
×
164
    return machine[link_data.connected_chip_x, link_data.connected_chip_y]
×
165

166

167
def vertex_xy_and_route(vertex: MachineVertex) -> Tuple[
1✔
168
        XY, Tuple[MachineVertex, Optional[int], Optional[int]]]:
169
    """
170
    Get the non-virtual chip coordinates, the vertex, and processor or
171
    link to follow to get to the vertex.
172

173
    :param MachineVertex vertex:
174
    :return: the (x,y) coordinates of the target vertex mapped to a tuple of
175
        the vertex, core and link.
176
        One of core or link is provided the other is `None`
177
    :rtype: tuple(tuple(int, int), tuple(MachineVertex, int, None)) or
178
        tuple(tuple(int, int), tuple(MachineVertex, None, int))
179
    """
180
    if not isinstance(vertex, AbstractVirtual):
1✔
181
        placement = PacmanDataView.get_placement_of_vertex(vertex)
1✔
182
        return (placement.x, placement.y), (vertex, placement.p, None)
1✔
183
    machine = PacmanDataView.get_machine()
1✔
184
    link_data = vertex.get_link_data(machine)
1✔
185
    return ((link_data.connected_chip_x, link_data.connected_chip_y),
1✔
186
            (vertex, None, link_data.connected_link))
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc