Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Runs examples with C++ platform description
authorBruno Donassolo <bruno.donassolo@inria.fr>
Mon, 15 Mar 2021 17:45:25 +0000 (18:45 +0100)
committerBruno Donassolo <bruno.donassolo@inria.fr>
Fri, 4 Jun 2021 11:42:15 +0000 (13:42 +0200)
*Loading platform
- Generates library files for C++ platforms. They can be loaded by the
engine using the same load_platform method.

- The Engine::load_platform will verify if the extension is .so, it'll
open the file using dlopen and search for the load_platform symbol.

- The platform so must contain a load_platform function that will be
called by the engine to generate the platform properly.

*Implementing an example
- Added a CMakeLists.txt in examples/platform to generate the .so for
each example.

- Pass to the tesh files a new variable "libdir" containing the
directory where the libraries are located.

MANIFEST.in
examples/cpp/CMakeLists.txt
examples/cpp/actor-create/s4u-actor-create.cpp
examples/cpp/actor-create/s4u-actor-create.tesh
examples/platforms/CMakeLists.txt [new file with mode: 0644]
examples/platforms/small_platform.cpp [new file with mode: 0644]
src/s4u/s4u_Engine.cpp
tools/cmake/DefinePackages.cmake

index 56c61a9..0963f6a 100644 (file)
@@ -1871,6 +1871,7 @@ include examples/cpp/CMakeLists.txt
 include examples/deprecated/java/CMakeLists.txt
 include examples/deprecated/msg/mc/CMakeLists.txt
 include examples/deprecated/simdag/CMakeLists.txt
+include examples/platforms/CMakeLists.txt
 include examples/platforms/bypassRoute.xml
 include examples/platforms/bypassZoneRoute.xml
 include examples/platforms/cloud.xml
@@ -1923,6 +1924,7 @@ include examples/platforms/routing_cluster.lua
 include examples/platforms/routing_cluster.xml
 include examples/platforms/routing_none.xml
 include examples/platforms/simulacrum_7_hosts.xml
+include examples/platforms/small_platform.cpp
 include examples/platforms/small_platform.lua
 include examples/platforms/small_platform.xml
 include examples/platforms/small_platform_constant.xml
index 0260d9c..a240894 100644 (file)
@@ -90,6 +90,7 @@ foreach (example actor-create actor-daemon actor-exiting actor-join actor-kill
   if(NOT DEFINED _${example}_disable)
     add_executable       (s4u-${example} EXCLUDE_FROM_ALL ${_${example}_sources})
     add_dependencies     (tests s4u-${example})
+    add_dependencies     (s4u-${example} platf_cpp)
     target_link_libraries(s4u-${example} simgrid)
     set_target_properties(s4u-${example} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${example})
 
@@ -101,6 +102,7 @@ foreach (example actor-create actor-daemon actor-exiting actor-join actor-kill
 
     ADD_TESH_FACTORIES(s4u-${example} "${_${example}_factories}"
                                       --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example}
+                                      --setenv libdir=${CMAKE_BINARY_DIR}/lib
                                       --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms
                                       --cd ${CMAKE_CURRENT_SOURCE_DIR}/${example}
                                       ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}.tesh)
index 1875ae3..3373d82 100644 (file)
@@ -45,9 +45,9 @@ static void receiver(const std::string& mailbox_name)
 static void forwarder(int argc, char** argv)
 {
   xbt_assert(argc >= 3, "Actor forwarder requires 2 parameters, but got only %d", argc - 1);
-  sg4::Mailbox* in             = sg4::Mailbox::by_name(argv[1]);
-  sg4::Mailbox* out            = sg4::Mailbox::by_name(argv[2]);
-  auto* msg                    = in->get<std::string>();
+  sg4::Mailbox* in  = sg4::Mailbox::by_name(argv[1]);
+  sg4::Mailbox* out = sg4::Mailbox::by_name(argv[2]);
+  auto* msg         = in->get<std::string>();
   XBT_INFO("Forward '%s'.", msg->c_str());
   out->put(msg, msg->size());
 }
@@ -60,9 +60,11 @@ static void forwarder(int argc, char** argv)
 class Sender {
 public:
   std::string mbox  = "mb42";
-  std::string msg = "GaBuZoMeu";
+  std::string msg   = "GaBuZoMeu";
   explicit Sender() = default; /* Sending the default message */
-  explicit Sender(const std::string& arg) : msg(arg) { /* Sending the specified message */}
+  explicit Sender(const std::string& arg) : msg(arg)
+  { /* Sending the specified message */
+  }
   explicit Sender(std::vector<std::string> args)
   {
     /* This constructor is used when we start the actor from the deployment file */
@@ -90,7 +92,7 @@ int main(int argc, char** argv)
   sg4::Engine e(&argc, argv);
 
   /* Then you should load a platform file, describing your simulated platform */
-  e.load_platform("../../platforms/small_platform.xml");
+  e.load_platform(argv[1]);
 
   /* And now you have to ask SimGrid to actually start your actors.
    *
index 994a3f9..4849e12 100644 (file)
@@ -1,6 +1,18 @@
 #!/usr/bin/env tesh
 
-$ ${bindir:=.}/s4u-actor-create
+$ ${bindir:=.}/s4u-actor-create ../../platforms/small_platform.xml
+> [Tremblay:sender1:(2) 0.000000] [s4u_actor_create/INFO] Hello s4u, I have something to send
+> [Jupiter:sender2:(3) 0.000000] [s4u_actor_create/INFO] Hello s4u, I have something to send
+> [Fafard:sender:(4) 0.000000] [s4u_actor_create/INFO] Hello s4u, I have something to send
+> [Fafard:receiver:(1) 0.000000] [s4u_actor_create/INFO] Hello s4u, I'm ready to get any message you'd want on mb42
+> [Fafard:sender:(4) 0.016392] [s4u_actor_create/INFO] I'm done. See you.
+> [Ginette:forwarder:(5) 0.016392] [s4u_actor_create/INFO] Forward 'PopPop!'.
+> [Tremblay:sender1:(2) 0.025709] [s4u_actor_create/INFO] I'm done. See you.
+> [Jupiter:sender2:(3) 0.070434] [s4u_actor_create/INFO] I'm done. See you.
+> [Fafard:receiver:(1) 0.086825] [s4u_actor_create/INFO] I received 'GaBuZoMeu', 'GloubiBoulga' and 'PopPop!'
+> [Fafard:receiver:(1) 0.086825] [s4u_actor_create/INFO] I'm done. See you.
+
+$ ${bindir:=.}/s4u-actor-create ${libdir:=.}/libsmall_platform.so
 > [Tremblay:sender1:(2) 0.000000] [s4u_actor_create/INFO] Hello s4u, I have something to send
 > [Jupiter:sender2:(3) 0.000000] [s4u_actor_create/INFO] Hello s4u, I have something to send
 > [Fafard:sender:(4) 0.000000] [s4u_actor_create/INFO] Hello s4u, I have something to send
diff --git a/examples/platforms/CMakeLists.txt b/examples/platforms/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ab567db
--- /dev/null
@@ -0,0 +1,7 @@
+add_custom_target(platf_cpp COMMENT "C++ platform description")
+add_dependencies(tests platf_cpp)
+foreach (platf small_platform)
+  add_library       (${platf} SHARED ${platf}.cpp)
+  target_link_libraries(${platf} simgrid)
+  add_dependencies(platf_cpp ${platf})
+endforeach()
diff --git a/examples/platforms/small_platform.cpp b/examples/platforms/small_platform.cpp
new file mode 100644 (file)
index 0000000..5496ea4
--- /dev/null
@@ -0,0 +1,134 @@
+/* Copyright (c) 2006-2021. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <simgrid/s4u.hpp>
+namespace sg4 = simgrid::s4u;
+
+/**
+ * @brief Create the hosts in the platform
+ *
+ * @param zone Zone to insert the hosts
+ */
+static void create_sp_hosts(sg4::NetZone* zone)
+{
+  zone->create_host("Tremblay", {"98.095Mf"})->seal();
+  zone->create_host("Jupiter", {"76.296Mf"})->seal();
+  zone->create_host("Fafard", {"76.296Mf"})->seal();
+  zone->create_host("Ginette", {"48.492Mf"})->seal();
+  zone->create_host("Bourassa", {"48.492Mf"})->seal();
+  zone->create_host("Jacquelin", {"137.333Mf"})->seal();
+  zone->create_host("Boivin", {"98.095Mf"})->seal();
+}
+
+/**
+ * @brief Create the links in the platform
+ *
+ * They'll be used later in the routes.
+ *
+ * @param zone Netzone
+ */
+static void create_sp_links(sg4::NetZone* zone)
+{
+  zone->create_link("6", {"41.279125MBps"})->set_latency("59.904us")->seal();
+  zone->create_link("3", {"34.285625MBps"})->set_latency("514.433us")->seal();
+  zone->create_link("7", {"11.618875MBps"})->set_latency("189.98us")->seal();
+  zone->create_link("9", {"7.20975MBps"})->set_latency("1.461517ms")->seal();
+  zone->create_link("2", {"118.6825MBps"})->set_latency("136.931us")->seal();
+  zone->create_link("8", {"8.158MBps"})->set_latency("270.544us")->seal();
+  zone->create_link("1", {"34.285625MBps"})->set_latency("514.433us")->seal();
+  zone->create_link("4", {"10.099625MBps"})->set_latency("479.78us")->seal();
+  zone->create_link("0", {"41.279125MBps"})->set_latency("59.904us")->seal();
+  zone->create_link("5", {"27.94625MBps"})->set_latency("278.066us")->seal();
+  zone->create_link("145", {"2.583375MBps"})->set_latency("410.463us")->seal();
+  zone->create_link("10", {"34.285625MBps"})->set_latency("514.433us")->seal();
+  zone->create_link("11", {"118.6825MBps"})->set_latency("136.931us")->seal();
+  zone->create_link("16", {"34.285625MBps"})->set_latency("514.433us")->seal();
+  zone->create_link("17", {"118.6825MBps"})->set_latency("136.931us")->seal();
+  zone->create_link("44", {"10.314625MBps"})->set_latency("6.932556ms")->seal();
+  zone->create_link("47", {"10.314625MBps"})->set_latency("6.932556ms")->seal();
+  zone->create_link("54", {"15.376875MBps"})->set_latency("35.083019ms")->seal();
+  zone->create_link("56", {"21.41475MBps"})->set_latency("29.5890617ms")->seal();
+  zone->create_link("59", {"11.845375MBps"})->set_latency("370.788us")->seal();
+  zone->create_link("78", {"27.94625MBps"})->set_latency("278.066us")->seal();
+  zone->create_link("79", {"8.42725MBps"})->set_latency("156.056us")->seal();
+  zone->create_link("80", {"15.376875MBps"})->set_latency("35.083019ms")->seal();
+
+  /* single FATPIPE links for loopback */
+  zone->create_link("loopback", {"498MBps"})
+      ->set_latency("15us")
+      ->set_sharing_policy(sg4::Link::SharingPolicy::FATPIPE)
+      ->seal();
+}
+
+/**
+ * @brief Auxiliary function to create a single route
+ *
+ * It translates the parameters from string to proper API
+ * @param e S4U Engine
+ * @param src Source hostname
+ * @param dst Destination hostname
+ * @param links List of links to use in this route
+ */
+static void create_single_route(const sg4::Engine& e, std::string const& src, std::string const& dst,
+                                std::vector<std::string> const& links)
+{
+  std::vector<sg4::Link*> link_list;
+  for (auto& link : links) {
+    link_list.push_back(e.link_by_name(link));
+  }
+  sg4::NetZone* zone = e.get_netzone_root();
+  zone->add_route(e.netpoint_by_name(src), e.netpoint_by_name(dst), nullptr, nullptr, link_list);
+}
+
+/** @brief Creates the routes in the platform */
+static void create_sp_routes(const sg4::Engine& e)
+{
+  auto nodes = std::vector<std::string>{"Tremblay", "Jupiter", "Fafard", "Ginette", "Bourassa"};
+  for (const auto& name : nodes) {
+    create_single_route(e, name, name, {"loopback"});
+  }
+  create_single_route(e, "Tremblay", "Jupiter", {"9"});
+  create_single_route(e, "Tremblay", "Fafard", {"4", "3", "2", "0", "1", "8"});
+  create_single_route(e, "Tremblay", "Ginette", {"4", "3", "5"});
+  create_single_route(e, "Tremblay", "Bourassa", {"4", "3", "2", "0", "1", "6", "7"});
+  create_single_route(e, "Jupiter", "Fafard", {"9", "4", "3", "2", "0", "1", "8"});
+  create_single_route(e, "Jupiter", "Bourassa", {"9", "4", "3", "2", "0", "1", "6", "7"});
+  create_single_route(e, "Fafard", "Ginette", {"8", "1", "0", "2", "5"});
+  create_single_route(e, "Jupiter", "Jacquelin", {"145"});
+  create_single_route(e, "Jupiter", "Boivin", {"47"});
+  create_single_route(e, "Jupiter", "Ginette", {"9", "4", "3", "5"});
+  create_single_route(e, "Fafard", "Bourassa", {"8", "6", "7"});
+  create_single_route(e, "Ginette", "Bourassa", {"5", "2", "0", "1", "6", "7"});
+  create_single_route(e, "Ginette", "Jacquelin", {"145"});
+  create_single_route(e, "Ginette", "Boivin", {"47"});
+  create_single_route(e, "Bourassa", "Jacquelin", {"145"});
+  create_single_route(e, "Bourassa", "Boivin", {"47"});
+  create_single_route(e, "Jacquelin", "Boivin", {"145", "59", "56", "54", "17", "16", "10", "11", "44", "47"});
+  create_single_route(e, "Jacquelin", "Fafard", {"145", "59", "56", "54", "17", "16", "10", "6", "9", "79", "78"});
+  create_single_route(e, "Jacquelin", "Tremblay", {"145", "59", "56", "54", "2", "3"});
+  create_single_route(e, "Boivin", "Tremblay", {"47", "44", "11", "10", "16", "0", "3"});
+  create_single_route(e, "Boivin", "Fafard", {"47", "44", "11", "6", "9", "79", "78", "80"});
+}
+
+/**
+ * @brief Programmatic version of small_platform.xml
+ *
+ * Possible not the best example since we need to describe each component manually,
+ * but it illustrates the new API
+ */
+extern "C" void load_platform(const sg4::Engine& e);
+void load_platform(const sg4::Engine& e)
+{
+  auto* root_zone = sg4::create_full_zone("zone0");
+
+  /* create hosts */
+  create_sp_hosts(root_zone);
+  /* create links */
+  create_sp_links(root_zone);
+  /* create routes */
+  create_sp_routes(e);
+  /* finally seal the root zone */
+  root_zone->seal();
+}
\ No newline at end of file
index e04b057..a97f220 100644 (file)
 #include "src/mc/mc_replay.hpp"
 #include "src/surf/network_interface.hpp"
 #include "surf/surf.hpp" // routing_platf. FIXME:KILLME. SOON
+#include <boost/algorithm/string/predicate.hpp>
 #include <simgrid/Exception.hpp>
 
 #include <algorithm>
+#include <dlfcn.h>
 #include <string>
 
 XBT_LOG_NEW_CATEGORY(s4u, "Log channels of the S4U (Simgrid for you) interface");
@@ -109,7 +111,19 @@ const std::vector<simgrid::kernel::resource::Model*>& Engine::get_all_models() c
 void Engine::load_platform(const std::string& platf) const
 {
   double start = xbt_os_time();
-  parse_platform_file(platf);
+  if (boost::algorithm::ends_with(platf, ".so")) {
+    void* handle = dlopen(platf.c_str(), RTLD_LAZY);
+    xbt_assert(handle, "Impossible to open platform file: %s", platf.c_str());
+    typedef void (*load_fct_t)(const Engine&);
+    dlerror();
+    load_fct_t callable     = (load_fct_t)dlsym(handle, "load_platform");
+    const char* dlsym_error = dlerror();
+    xbt_assert(not dlsym_error, "Error: %s", dlsym_error);
+    callable(*this);
+    dlclose(handle);
+  } else {
+    parse_platform_file(platf);
+  }
 
   double end = xbt_os_time();
   XBT_DEBUG("PARSE TIME: %g", (end - start));
index 9f92cf6..7785ac5 100644 (file)
@@ -998,6 +998,7 @@ set(txt_files
 # The list of cmake build directories is constructed from the following list.
 # Add your CMakeLists file here to see your subdir built.
 set(CMAKEFILES_TXT
+  examples/platforms/CMakeLists.txt
   examples/c/CMakeLists.txt
   examples/cpp/CMakeLists.txt
   examples/smpi/CMakeLists.txt
@@ -1167,6 +1168,7 @@ set(PLATFORMS_EXAMPLES
   examples/platforms/storage/content/storage_content.txt
   examples/platforms/small_platform.xml
   examples/platforms/small_platform.lua
+  examples/platforms/small_platform.cpp
   examples/platforms/small_platform_constant.xml
   examples/platforms/small_platform_failures.xml
   examples/platforms/small_platform_fatpipe.xml