Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Added some work in the creation of links in the fat trees, basically the repartion...
authorStéphane Castelli <stephane.castelli@loria.fr>
Tue, 15 Apr 2014 15:51:18 +0000 (17:51 +0200)
committerStéphane Castelli <stephane.castelli@loria.fr>
Tue, 15 Apr 2014 15:51:18 +0000 (17:51 +0200)
Method to generate a .dot file, almost done

Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid

CMakeLists.txt
buildtools/Cmake/Flags.cmake
doc/doxygen/install.doc
include/smpi/smpi.h
src/mc/mc_checkpoint.c
src/mc/mc_global.c
src/surf/surf_routing.cpp
src/surf/surf_routing_cluster_fat_tree.cpp
src/surf/surf_routing_cluster_fat_tree.hpp
src/xbt/mmalloc/mmorecore.c
teshsuite/simdag/platforms/bogus_disk_attachment.tesh

index 4803a26..edd9041 100644 (file)
@@ -99,6 +99,9 @@ if(${CMAKE_C_COMPILER_ID} STREQUAL "GNU")
   endif()
 endif()
 
+exec_program("${CMAKE_LINKER} --version" OUTPUT_VARIABLE "LINKER_VERSION")
+string(REGEX MATCH "[0-9].[0-9]*" LINKER_VERSION "${LINKER_VERSION}")
+
 string(REGEX MATCH "cl.exe" VBC "${CMAKE_C_COMPILER}")
 if(VBC)
   message(FATAL_ERROR "VB is not yet supported by Simgrid.")
index 5e959e3..675587b 100644 (file)
@@ -36,7 +36,7 @@ if(enable_compile_optimizations)
       endif()
     else()    
       # On non-windows, 4.6 is enough for that
-      if(COMPILER_C_VERSION_MAJOR_MINOR STRGREATER "4.5")
+      if(COMPILER_C_VERSION_MAJOR_MINOR STRGREATER "4.5" AND LINKER_VERSION STRGREATER "2.22")
         set(optCFLAGS "${optCFLAGS} -flto ")
       endif()
     endif()
index 63aebcf..b557898 100644 (file)
@@ -130,7 +130,7 @@ Note that compile-time options are very different from @ref options
 
 The default configuration should be ok for most usages, but if you
 need to change something, there is several ways to do so. First, you
-can use environment variable. For example, you can change the used
+can use environment variables. For example, you can change the used
 compilers by issuing these commands before launching cmake:
 
 @verbatim
@@ -138,6 +138,9 @@ export CC=gcc-4.4
 export CXX=g++-4.4
 @endverbatim
 
+Note that other variables are available, such as CFLAGS and CXXFLAGS to add
+options for respectively the C compiler and the C++ compiler.
+
 Another way to do so is to use the -D argument of cmake as follows.
 Note that the terminating dot is mandatory (see @ref
 install_cmake_outsrc to understand its meaning).
index 5fd5a7c..0efadf2 100644 (file)
@@ -99,6 +99,11 @@ SG_BEGIN_DECL()
 #define MPI_INTEGER8 MPI_DATATYPE_NULL
 #define MPI_COMPLEX MPI_DATATYPE_NULL
 #define MPI_DOUBLE_COMPLEX MPI_DATATYPE_NULL
+#define MPI_2DOUBLE_PRECISION MPI_DATATYPE_NULL
+#define MPI_REAL MPI_DATATYPE_NULL
+#define MPI_LOGICAL MPI_DATATYPE_NULL
+#define MPI_DOUBLE_PRECISION MPI_DATATYPE_NULL
+#define MPI_INTEGER MPI_DATATYPE_NULL
 
 #define MPI_DISTRIBUTE_BLOCK 0
 #define MPI_DISTRIBUTE_NONE 1
index e455677..7864e2c 100644 (file)
@@ -54,7 +54,7 @@ static void local_variable_free_voidp(void *v){
 
 static void MC_region_destroy(mc_mem_region_t reg)
 {
-  xbt_free(reg->data);
+  munmap(reg->data, reg->size);
   xbt_free(reg);
 }
 
@@ -87,8 +87,10 @@ static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size)
   mc_mem_region_t new_reg = xbt_new(s_mc_mem_region_t, 1);
   new_reg->start_addr = start_addr;
   new_reg->size = size;
-  new_reg->data = xbt_malloc(size);
+  new_reg->data = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
   memcpy(new_reg->data, start_addr, size);
+  mprotect(new_reg->data, size, PROT_READ);
+  madvise(new_reg->data, size, MADV_MERGEABLE);
 
   XBT_DEBUG("New region : type : %d, data : %p (real addr %p), size : %zu", type, new_reg->data, start_addr, size);
   
index 55cf908..acbc818 100644 (file)
@@ -800,14 +800,6 @@ static void MC_init_debug_info(void) {
   mc_libsimgrid_info = MC_find_object_info(maps, libsimgrid_path, 0);
   mc_object_infos[1] = mc_libsimgrid_info;
 
-#ifdef MADV_MERGEABLE
-  for(int i=0; i!=mc_object_infos_size; ++i) {
-    void* start = mc_object_infos[i]->start_rw;
-    void* end = mc_object_infos[i]->end_rw;
-    madvise(start, (char*)end - (char*)start, MADV_MERGEABLE);
-  }
-#endif
-
   // Use information of the other objects:
   MC_post_process_object_info(mc_binary_info);
   MC_post_process_object_info(mc_libsimgrid_info);
index f62f852..a4bbe30 100644 (file)
@@ -1252,7 +1252,7 @@ static void check_disk_attachment()
          StoragePtr storage = static_cast<StoragePtr>(xbt_lib_get_level(xbt_lib_get_elm_or_null(storage_lib, key), SURF_STORAGE_LEVEL));
          host_elm = sg_routing_edge_by_name_or_null(storage->p_attach);
          if(!host_elm)
-                 surf_parse_error("Enable to attach storage %s: host %s doesn't exist.", storage->getName(), storage->p_attach);
+                 surf_parse_error("Unable to attach storage %s: host %s doesn't exist.", storage->getName(), storage->p_attach);
     }
   }
 }
index 5cb6728..f852c36 100644 (file)
@@ -3,37 +3,92 @@
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string/classification.hpp>
 
+#include <iostream>
+#include <fstream>
 
-AsClusterFatTree::AsClusterFatTree() : levels(0) {}
 
+AsClusterFatTree::AsClusterFatTree() : levels(0) {}
 
+AsClusterFatTree::~AsClusterFatTree() {
+  for (int i = 0 ; i < this->nodes.size() ; i++) {
+    delete this->nodes[i];
+  }
+}
 
 void AsClusterFatTree::getRouteAndLatency(RoutingEdgePtr src,
                                           RoutingEdgePtr dst,
                                           sg_platf_route_cbarg_t into,
-                                          double *latency) {
+                                          double *latency) const{
   // TODO
 }
 
-void AsClusterFatTree::create_links() {
+/* This function makes the assumption that parse_specific_arguments() and
+ * addNodes() have already been called
+ */
+void AsClusterFatTree::create_links(sg_platf_cluster_cbarg_t cluster) {
+
   if(this->levels == 0) {
     return;
   }
-  
-  for (unsigned int i = 0 ; i < this->levels) {
-    
-  }
+  std::vector<int> nodesByLevel(this->levels); 
+  int nodesRequired = 0;
+
+
+    for (int i = 0 ; i < this->levels ; i++) {
+      int nodesInThisLevel = 1;
+      
+      for (int j = 0 ;  j < i ; j++) {
+        nodesInThisLevel *= this->upperLevelNodesNumber[j];
+      }
+      
+      for (int j = i+1 ; j < this->levels ; j++) {
+        nodesInThisLevel *= this->lowerLevelNodesNumber[j];
+      }
+
+      nodesByLevel[i] = nodesInThisLevel;
+      nodesRequired += nodesInThisLevel;
+    }
+   
+    if(nodesRequired > this->nodes.size()) {
+      surf_parse_error("There is not enough nodes to fit to the described topology. Please check your platform description (We need %d nodes, we only got %lu)", nodesRequired, this->nodes.size());
+      return;
+    }
+
+    // Nodes are totally ordered, by level and then by position, in this->nodes
+    int k = 0;
+    for (int i = 0 ; i < this->levels ; i++) {
+      for (int j = 0 ; j < nodesByLevel[i] ; j++) {
+        this->nodes[k]->level = i;
+        this->nodes[k]->position = j;
 
+        if (i == 0) {
+          
+        }
+        else if (i == this->levels - 1) {
+          
+        }
+        else {
+          
+        }
+      }
+    }
 }
 
 
+void AsClusterFatTree::addNodes(std::vector<int> const& id) {
+  for (int i = 0 ; i < id.size() ; i++) {
+    this->nodes.push_back(new FatTreeNode(id[i]));
+  }
+}
 
 void AsClusterFatTree::parse_specific_arguments(sg_platf_cluster_cbarg_t 
                                                 cluster) {
   std::vector<string> parameters;
   std::vector<string> tmp;
   boost::split(parameters, cluster->topo_parameters, boost::is_any_of(";"));
-  
+
+  // TODO : we have to check for zeros and negative numbers, or it might crash
   if (parameters.size() != 4){
     surf_parse_error("Fat trees are defined by the levels number and 3 vectors" 
                      ", see the documentation for more informations");
@@ -41,7 +96,7 @@ void AsClusterFatTree::parse_specific_arguments(sg_platf_cluster_cbarg_t
   }
 
   // The first parts of topo_parameters should be the levels number
-  this->levels = std::atoi(tmp[0].c_str());
+  this->levels = std::atoi(tmp[0].c_str()); // stoi() only in C++11...
 
   // Then, a l-sized vector standing for the childs number by level
   boost::split(tmp, parameters[1], boost::is_any_of(","));
@@ -54,7 +109,7 @@ void AsClusterFatTree::parse_specific_arguments(sg_platf_cluster_cbarg_t
   }
   
   // Then, a l-sized vector standing for the parents number by level
-   boost::split(tmp, parameters[2], boost::is_any_of(","));
+  boost::split(tmp, parameters[2], boost::is_any_of(","));
   if(tmp.size() != this->levels) {
     surf_parse_error("Fat trees are defined by the levels number and 3 vectors" 
                      ", see the documentation for more informations"); 
@@ -74,4 +129,37 @@ void AsClusterFatTree::parse_specific_arguments(sg_platf_cluster_cbarg_t
     this->lowerLevelPortsNumber.push_back(std::atoi(tmp[i].c_str())); 
   }
 }
+
+
+void AsClusterFatTree::generateDotFile(string filename) {
+  ofstream file;
+  /* Maybe should we get directly a char*, as open takes strings only beginning
+   * with c++11...
+   */
+  file.open(filename.c_str(), ios::out | ios::trunc); 
   
+  if(file.is_open()) {
+    /* TODO : Iterate through a map takes 10 chars with c++11, 100 with c++98.
+     * All I have to do is write it down...
+     */
+
+    // file << "graph AsClusterFatTree {\n";
+    // for (std::map<std::pair<int,int>, FatTreeLink*>::iterator link = this->links.begin() ; link != this->links.end() ; link++ ) {
+    //   for (int j = 0 ; j < link->ports ; j++) {
+    //   file << this->links[i]->source.id 
+    //        << " -- " this->links[i]->destination.id
+    //        << ";\n";
+    //   }
+    // }
+    // file << "}";
+    // file.close();
+  }
+  else {
+    std::cerr << "Unable to open file " << filename << std::endl;
+    return;
+  }
+}
+
+FatTreeNode::FatTreeNode(int id, int level, int position) : id(id),
+                                                            level(level),
+                                                            position(position){}
index d45cdbf..96ba5c9 100644 (file)
 #define SURF_ROUTING_CLUSTER_FAT_TREE_HPP_
 
 
+/* The class AsClusterFatTree describes PGFT, as introduced by Eitan Zahavi
+ * in "D-Mod-K Routing Providing Non-Blocking Traffic for Shift Permutations
+ * on Real Life Fat Trees" (2010). RLFT are PGFT with some restrictions to 
+ * address real world constraints, which are not currently enforced (but it 
+ * should certainly be checked for)
+ */
 
-class FatTreeLink;
-class FatTreeNode;
+class FatTreeNode {
+public:
+  int id; // ID as given by the user
+  int level; // The 0th level represents the leafs of the PGFT
+  int position; // Position in the level
+  
+  /* We can see the sizes sum of the two following vectors as the device 
+   * ports number. If we use the notations used in Zahavi's paper, 
+   * children.size() = m_level and parents.size() = w_(level+1)
+   * 
+   */
+  std::vector<FatTreeNode*> children;  // m, apply from lvl 0 to levels - 1 
+  std::vector<FatTreeNode*> parents; // w, apply from lvl 1 to levels
+  FatTreeNode(int id, int level=-1, int position=-1);
+};
+
+class FatTreeLink {
+private:
+  unsigned int ports;
+  std::vector<NetworkLink> linksUp; // From source to destination
+  std::vector<NetworkLink> linksDown; // From destination to source
+  FatTreeNode source;
+  FatTreeNode destination;
+public:
+  FatTreeLink(int source, int destination, unsigned int ports = 0);
+  NetworkLink getLink(int number = 0) const;
+};
 
 class AsClusterFatTree : public AsCluster {
 public:
   AsClusterFatTree();
-  virtual void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency);
-  virtual void create_links();
+  ~AsClusterFatTree();
+  virtual void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency) const;
+  virtual void create_links(sg_platf_cluster_cbarg_t cluster);
   void parse_specific_arguments(sg_platf_cluster_cbarg_t cluster);
+  void addNodes(std::vector<int> const& id);
+  void generateDotFile(string filename = "fatTree.dot");
 
 protected:
   //description of a PGFT (TODO : better doc)
@@ -28,15 +62,11 @@ protected:
   std::vector<int> upperLevelNodesNumber;
   std::vector<int> lowerLevelPortsNumber;
   
-  std::vector<FatTreeNode> nodes;
+  std::vector<FatTreeNode*> nodes;
+  std::map<std::pair<int,int>, FatTreeLink*> links;
+  
 };
 
-class FatTreeLink {
-public:
-};
-class FatTreeNode {
-  int id;
-  std::string name;
-};
+
   
 #endif
index 38f6d8b..9fbf7a9 100644 (file)
@@ -124,10 +124,6 @@ void *mmorecore(struct mdesc *mdp, ssize_t size)
         abort();
       }
 
-#ifdef MADV_MERGEABLE
-      madvise(mapto, mapbytes, MADV_MERGEABLE);
-#endif
-
       if (mdp->top == 0)
         mdp->base = mdp->breakval = mapto;
 
index 534cd7f..02e5e4a 100644 (file)
@@ -1,4 +1,4 @@
 ! expect signal SIGABRT
 $ ${bindir:=.}/flatifier bogus_disk_attachment.xml "--log=root.fmt:[%10.6r]%e[%i:%P@%h]%e%m%n"
 > [  0.000000] [0:@] surf_workstation_model_init_ptask_L07
-> [  0.000000] [0:@] Parse error at bogus_disk_attachment.xml:26: Enable to attach storage cdisk: host plouf doesn't exist.
+> [  0.000000] [0:@] Parse error at bogus_disk_attachment.xml:26: Unable to attach storage cdisk: host plouf doesn't exist.