Logo AND Algorithmique Numérique Distribuée

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