Logo AND Algorithmique Numérique Distribuée

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