Logo AND Algorithmique Numérique Distribuée

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