Home | History | Annotate | Download | only in stats
      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
     17 fundamental nodes, in various levels. Each topology
     18 has a default level "all" which has each node represented
     19 as 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 
     33 class 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