• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#    Copyright 2015-2017 ARM Limited
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#     http://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
16"""A Topology can be defined as an arrangement of
17fundamental nodes, in various levels. Each topology
18has a default level "all" which has each node represented
19as a group. For example:
20
21    +--------+---------------------------------------+
22    | level  |     groups                            |
23    +========+=======================================+
24    | all    | :code:`[[0, 1, 2, 3, 4]]`             |
25    +--------+---------------------------------------+
26    | cluster| :code:`[[0, 1], [2, 3, 4]]`           |
27    +--------+---------------------------------------+
28    | cpu    | :code:`[[0], [1], [2], [3], [4], [5]]`|
29    +--------+---------------------------------------+
30
31"""
32
33class Topology(object):
34    """Topology object allows grouping of
35    pivot values (called nodes) at multiple levels.
36    The implementation is targeted towards CPU topologies
37    but can be used generically as well
38
39    :param clusters: clusters can be defined as a
40        list of groups which are again lists of nodes.
41
42        .. note::
43
44            This is not a mandatory
45            argument but can be used to quickly create typical
46            CPU topologies.
47
48        For Example:
49        ::
50
51            from trappy.stats.Topology import Topology
52
53            CLUSTER_A = [0, 1]
54            CLUTSER_B = [2, 3]
55
56            clusters = [CLUSTER_A, CLUSTER_B]
57            topology = Topology(clusters=clusters)
58
59    :type clusters: list
60    """
61
62    def __init__(self, clusters=[]):
63        self._levels = {}
64        self._nodes = set()
65
66        if len(clusters):
67            self.add_to_level("cluster", clusters)
68            cpu_level = []
69            for node in self.flatten():
70                cpu_level.append([node])
71            self.add_to_level("cpu", cpu_level)
72
73    def __repr__(self):
74        repr_str = ""
75        for level_name in self._levels:
76            repr_str += level_name + " " + \
77                        self.get_level(level_name).__repr__() + \
78                        "\n"
79        return repr_str
80
81    def add_to_level(self, level_name, level_vals):
82        """Add a group to a level
83
84        This function allows to append a
85        group of nodes to a level. If the level
86        does not exist a new level is created
87
88        :param level_name: The name of the level
89        :type level_name: str
90
91        :level_vals: groups containing nodes
92        :type level_vals: list of lists:
93        """
94
95        if level_name not in self._levels:
96            self._levels[level_name] = []
97
98        self._levels[level_name] += level_vals
99
100        for group in level_vals:
101            self._nodes = self._nodes.union(set(group))
102
103    def get_level(self, level_name):
104        """Returns the groups of nodes associated
105        with a level
106
107        :param level_name: The name of the level
108        :type level_name: str
109        """
110
111        if level_name == "all":
112            return [self.flatten()]
113        else:
114            return self._levels[level_name]
115
116    def get_index(self, level, node):
117        """Return the index of the node in the
118        level's list of nodes
119
120        :param level: The name of the level
121        :type level_name: str
122
123        :param node: The group for which the inde
124            is required
125
126            .. todo::
127
128                Change name of the arg to group
129
130        :type node: list
131        """
132
133        nodes = self.get_level(level)
134        return nodes.index(node)
135
136    def get_node(self, level, index):
137        """Get the group at the index in
138        the level
139
140        :param level: The name of the level
141        :type level_name: str
142
143        :param index: Index of the group in
144            the list
145        :type index: int
146        """
147
148        nodes = self.get_level(level)
149        return nodes[index]
150
151    def __iter__(self):
152        return self._levels.__iter__()
153
154    def flatten(self):
155        """Return a flattened list of nodes in the
156        topology
157        """
158        return list(self._nodes)
159
160    def level_span(self, level):
161        """Return the number of groups in a level
162
163        :param level: The name of the level
164        :type level_name: str
165        """
166        if level == "all":
167            return len(self._nodes)
168        else:
169            return len(self._levels[level])
170
171    def has_level(self, level):
172        """Returns true if level is present
173
174        :param level: The name of the level
175        :type level_name: str
176        """
177
178        return (level in self._levels)
179
180