Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[project-description] Fix extraction of the ns-3 version.
[simgrid.git] / docs / source / Platform_cpp.rst
1 .. raw:: html
2
3    <object id="TOC" data="graphical-toc.svg" type="image/svg+xml"></object>
4    <script>
5    window.onload=function() { // Wait for the SVG to be loaded before changing it
6      var elem=document.querySelector("#TOC").contentDocument.getElementById("ExamplesBox")
7      elem.style="opacity:0.93999999;fill:#ff0000;fill-opacity:0.1;stroke:#000000;stroke-width:0.35277778;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1";
8    }
9    </script>
10    <br/>
11    <br/>
12
13 .. _platform_cpp:
14
15 C++ Platforms
16 #############
17
18 Using XML to describe the platforms is very convenient. It provides a
19 human-readable, quick way to start your experiments. Although, XML format brings
20 several drawbacks as your platforms get larger and more complex (see :ref:`platform_cpp_beyond`).
21
22 In this case, it may be more interesting to write your platform directly
23 in C++ code. It allows you to programmatically describe your platform and
24 remove the intermediate XML parser during simulations. Take care to follow
25 the recommendations in :ref:`Modeling Hints <howto>` to keep a clear separation
26 of concerns between your platform and your application.
27
28 Describing Resources
29 ********************
30
31 A platform in SimGrid is composed of several resources organized in different
32 Netzones. The different resources, such as hosts, disks and links, follow the same
33 idiom: create()->set()->set()->seal().
34
35 .. code-block:: c++
36
37     NetZone* zone      = s4u::create_star_zone("zone0");
38     Link* l_up   = zone->create_link("link_up", "125MBps")->set_latency("24us")->seal();
39     Host* host   = zone->create_host("host0", "1Gf")->seal();
40     zone->seal();
41
42 The first NetZone created will be the root zone of your platform. You're allowed to modified
43 an object as long as you did not seal it.
44
45 For more details about how to describe the platforms, please give a look at :ref:`examples<platform_cpp_example>`
46 or directly at the S4U API.
47
48 Links
49 =====
50
51 In the XML, you are allowed to do the following description:
52
53 .. code-block:: xml
54
55     <link id="1" bandwidth="10kBps" latency="10ms" sharing_policy="SPLITDUPLEX"/>
56
57     <route src="S1" dst="C1" symmetrical="NO">
58       <link_ctn id="1" direction="DOWN"/>
59     </route>
60
61 It is important to notice that this is a syntactic sugar provided by the XML to ease
62 the link utilization. A split-duplex link means that upgoing communications do not
63 share the bandwidth with downgoing communications. To emulate this behavior,
64 under the hood, SimGrid creates 2 links in this case: the *1_UP*
65 link and the *1_DOWN* link. As you can see, the selection of link to use
66 in the <route> tag is done by the ``direction=`` parameter.
67
68 Using the C++ interface, you can use the specific function to create these 2 links. Note
69 that you need to define the direction in the add_route function when adding a route containing
70 a split-duplex link. Otherwise, SimGrid cannot know which link (UP/DOWN) to use.
71
72 .. code-block:: cpp
73
74     auto* link = zone->create_split_duplex_link("1", "125MBps")->set_latency("24us")->seal();
75
76     zone->add_route(S1, C1, nullptr, nullptr, {{link, LinkInRoute::Direction::UP}});
77
78 .. note::
79     Do not use set_sharing_policy(SharingPolicy::SPLITDUPLEX).
80     SimGrid will complain since set_sharing_policy should be used only with (SHARED and FATPIPE)
81
82
83 Loading the platform
84 ====================
85
86 The C++ interface to build the platforms give you freedom to organize your code
87 as you wish, separating (or unifying) your application from your platform code.
88 However, we provide a small hack if you want to keep the same structure of the
89 old code with XML platforms. You can pass a library (.so) file to ``Engine::load_platform``
90 function, having a predefined function implemented. When loading the platform, the
91 Engine will look for a function with this signature: "**void load_platform(const sg4::Engine& e)**", and
92 execute it. It could be an easy way to make the transition between XML and C++ if necessary.
93
94 For more details, please refer to the cpp and CMakeLists.txt files in
95 `examples/platform <https://framagit.org/simgrid/simgrid/tree/master/examples/platforms>`_.
96
97
98 .. _platform_cpp_example:
99
100 Example
101 *******
102
103 The best way to build your C++ platform is starting from some examples.
104 Give a look in the examples folder in `examples/ <https://framagit.org/simgrid/simgrid/tree/master/examples/>`_.
105 For instance, the file `examples/cpp/clusters-multicpu/s4u-clusters-multicpu.cpp <https://framagit.org/simgrid/simgrid/-/blob/master/examples/cpp/clusters-multicpu/s4u-clusters-multicpu.cpp>`_ shows how to build complex platforms composed of
106 clusters of clusters.
107
108 Here, we present a complete example showing how to create 3 regulars clusters
109 connected through a shared link.
110
111 .. literalinclude:: ../../examples/platforms/griffon.cpp
112    :language: cpp
113
114
115 .. _platform_cpp_beyond:
116
117 Beyond the XML: the power of C++ platforms
118 ******************************************
119
120 This section describes one of the advantages of using C++ code to write your platforms.
121
122 Let's see an example of the description of a Fat-Tree in XML (:ref:`platform_examples_fattree`)
123
124 .. literalinclude:: ../../examples/platforms/cluster_fat_tree.xml
125    :language: xml
126    :lines: 1-3,10-
127
128 Our cluster *bob* is composed of 16 hosts with the same 1Gf CPU power.
129
130 Imagine now that you want to simulate the same **Fat-Tree topology with** more complex **hosts**,
131 composed of **1 CPU, 1 GPU and some interconnecting bus**.
132
133 Unfortunately, this is not possible with the XML description since its syntax obliges
134 that the leaves in your Fat-Tree to be single Hosts. However, with the C++ API, your
135 leaves can be composed of other zones, creating a **Fat-Tree of FullZones** for example.
136
137 Consequently, you can describe the desired platform as follows:
138
139 .. code-block:: c++
140
141     sg4::Engine e(&argc, argv);
142     sg4::create_fatTree_zone("bob", e.get_netzone_root(), {2, {4, 4}, {1, 2}, {1, 2}}, {create_hostzone, create_loopback, {}}, 125e6,
143                            50e-6, sg4::Link::SharingPolicy::SPLITDUPLEX)->seal();
144
145 Note that the leaves and loopback links are defined through callbacks, as follows:
146
147 .. code-block:: c++
148
149     /* create the loopback link for each leaf in the Fat-Tree */
150     static sg4::Link* create_loopback(sg4::NetZone* zone, const std::vector<unsigned int>& /*coord*/, int id)
151     {
152         // note that you could set different loopback links for each leaf
153         return zone->create_link("limiter-" + std::to_string(id), 1e6)->seal();
154     }
155
156     /* create each leaf in the Fat-Tree, return a pair composed of: <object (host, zone), gateway> */
157     static std::pair<simgrid::kernel::routing::NetPoint*, simgrid::kernel::routing::NetPoint*>
158     create_hostzone(const sg4::NetZone* zone, const std::vector<unsigned int>& /*coord*/, int id)
159     {
160       /* creating zone */
161       std::string hostname = "host" + std::to_string(id);
162       auto* host_zone = sg4::create_full_zone(hostname);
163       /* setting my parent zone */
164       host_zone->set_parent(zone);
165
166       /* creating CPU */
167       std::string cpu_name  = hostname + "-cpu" + std::to_string(i);
168       const sg4::Host* cpu = host_zone->create_host(cpu_name, 1e9)->seal();
169       /* creating GPU */
170       std::string gpu_name  = hostname + "-gpu" + std::to_string(i);
171       const sg4::Host* gpu = host_zone->create_host(gpu_name, 1e12)->seal();
172       /* connecting them */
173       sg4::Link* link   = host_zone->create_link("link-" + cpu_name, 10e9)->set_latency(10e-9)->seal();
174       host_zone->add_route(cpu->get_netpoint(), gpu->get_netpoint(), nullptr, nullptr, {sg4::LinkInRoute(link)});
175
176       host_zone->seal();
177       /* cpu is the gateway for this host */
178       return std::make_pair(host_zone->get_netpoint(), cpu->get_netpoint());
179     }
180
181 The code is straightforward and can be easily adapted to more complex environments thanks to the flexibility
182 provided by the C++ API.