Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Make HostL07 behave more like the regular Host
[simgrid.git] / src / surf / surf_routing_cluster_fat_tree.hpp
1 /* Copyright (c) 2014-2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #ifndef SURF_ROUTING_CLUSTER_FAT_TREE_HPP_
8 #define SURF_ROUTING_CLUSTER_FAT_TREE_HPP_
9
10 #include <xbt/base.h>
11
12 #include "surf_routing_cluster.hpp"
13
14
15 /** \file surf_routing_cluster_fat_tree.cpp
16  *  The class AsClusterFatTree describes PGFT, as introduced by Eitan Zahavi
17  * in "D-Mod-K Routing Providing Non-Blocking Traffic for Shift Permutations
18  * on Real Life Fat Trees" (2010). RLFT are PGFT with some restrictions to 
19  * address real world constraints, which are not currently enforced. 
20  */
21
22 class XBT_PRIVATE FatTreeNode;
23 class XBT_PRIVATE FatTreeLink;
24
25 /** \brief A node in a fat tree.
26  * A FatTreeNode can either be a switch or a processing node. Switches are
27  * identified by a negative ID. This class is closely related to fat
28  */
29 class FatTreeNode {
30 public:
31   /** Unique ID which identifies every node. */
32   int id;
33   /* Level into the tree, with 0 being the leafs.
34    */
35   unsigned int level; 
36   /* \brief Position into the level, starting from 0.
37    */
38   unsigned int position; 
39   /** In order to link nodes between them, each one must be assigned a label,
40    * consisting of l integers, l being the levels number of the tree. Each label
41    * is unique in the level, and the way it is generated allows the construction
42    * of a fat tree which fits the desired topology.
43    */
44   std::vector<unsigned int> label;
45
46   /** Links to the lower level, where the position in the vector corresponds to
47    * a port number. 
48    */
49   std::vector<FatTreeLink*> children;
50   /** Links to the upper level, where the position in the vector corresponds to
51    * a port number. 
52    */ 
53   std::vector<FatTreeLink*> parents;
54
55   /** Virtual link standing for the node global capacity.
56    */
57   Link* limiterLink;
58   /** If present, communications from this node to this node will pass through it
59    * instead of passing by an upper level switch.
60    */
61   Link* loopback;
62   FatTreeNode(sg_platf_cluster_cbarg_t cluster, int id, int level,
63               int position);
64 };
65
66
67
68 /** \brief Link in a fat tree.
69  *
70  * Represents a single, duplex link in a fat tree. This is necessary to have a tree.
71  * It is equivalent to a physical link.
72  */
73 class FatTreeLink {
74 public:
75   FatTreeLink(sg_platf_cluster_cbarg_t cluster, FatTreeNode *source,
76               FatTreeNode *destination);
77   /** Link going up in the tree
78    */
79   Link *upLink; 
80   /** Link going down in the tree
81    */
82   Link *downLink;
83   /** Upper end of the link
84    */
85   FatTreeNode *upNode;
86   /** Lower end of the link
87    */
88   FatTreeNode *downNode;
89 };
90
91
92 /** \brief Fat tree representation and routing.
93  *
94  * Generate fat trees according to the topology asked for. Almost everything
95  * is based on the work of Eitan Zahavi in "D-Mod-K Routing Providing
96  * Non-Blocking Traffic for Shift Permutations on Real Life Fat Trees" (2010).
97  *
98  * The exact topology is described in the mandatory topo_parameters
99  * field, and follow the "h ; m_h, ..., m_1 ; w_h, ..., w_1 ; p_h, ..., p_1" format.
100  * h stands for the switches levels number, i.e. the fat tree is of height h,
101  * without the processing nodes. m_i stands for the number of lower level nodes
102  * connected to a node in level i. w_i stands for the number of upper levels
103  * nodes connected to a node in level i-1. p_i stands for the number of 
104  * parallel links connecting two nodes between level i and i - 1. Level h is
105  * the topmost switch level, level 1 is the lowest switch level, and level 0
106  * represents the processing nodes. The number of provided nodes must be exactly
107  * the number of processing nodes required to fit the topology, which is the
108  * product of the m_i's.
109  *
110  * Routing is made using a destination-mod-k scheme.
111  */
112 class XBT_PRIVATE AsClusterFatTree : public AsCluster {
113 public:
114   AsClusterFatTree();
115   ~AsClusterFatTree();
116   virtual void getRouteAndLatency(RoutingEdge *src, RoutingEdge *dst,
117                                   sg_platf_route_cbarg_t into,
118                                   double *latency);
119
120   /** \brief Generate the fat tree
121    * 
122    * Once all processing nodes have been added, this will make sure the fat
123    * tree is generated by calling generateLabels(), generateSwitches() and 
124    * then connection all nodes between them, using their label.
125    */
126   virtual void create_links();
127   /** \brief Read the parameters in topo_parameters field.
128    *
129    * It will also store the cluster for future use.
130    */
131   void parse_specific_arguments(sg_platf_cluster_cbarg_t cluster);
132   /** \brief Add a processing node.
133    */
134   void addProcessingNode(int id);
135   void generateDotFile(const string& filename = "fatTree.dot") const;
136
137 private:
138   
139   //description of a PGFT (TODO : better doc)
140   unsigned int levels;
141   std::vector<unsigned int> lowerLevelNodesNumber; // number of children by node
142   std::vector<unsigned int> upperLevelNodesNumber; // number of parents by node
143   std::vector<unsigned int> lowerLevelPortsNumber; // ports between each level l and l-1
144   
145   std::map<int, FatTreeNode*> computeNodes;
146   std::vector<FatTreeNode*> nodes;
147   std::vector<FatTreeLink*> links;
148   std::vector<unsigned int> nodesByLevel;
149
150   sg_platf_cluster_cbarg_t cluster;
151
152   void addLink(FatTreeNode *parent, unsigned int parentPort,
153                FatTreeNode *child, unsigned int childPort);
154   int getLevelPosition(const unsigned int level);
155   void generateLabels();
156   void generateSwitches();
157   int connectNodeToParents(FatTreeNode *node);
158   bool areRelated(FatTreeNode *parent, FatTreeNode *child);
159   bool isInSubTree(FatTreeNode *root, FatTreeNode *node);
160 };
161 #endif