6 This tutorial presents the basics to understand how DAG are represented in Simgrid and how to simulate their workflow.
11 Directed Acyclic Graph:
15 \mathcal{G} = (\mathcal{V},\mathcal{E})
17 Set of vertices representing :ref:`Activities <API_s4u_Activity>`:
21 \mathcal{V} = {v_i | i = 1, ..., V}
23 Set of edges representing precedence constraints between :ref:`Activities <API_s4u_Activity>`:
27 \mathcal{E} = {e_i,j | (i,j) \in {1, ..., V} x {1, ..., V}}
29 .. image:: /tuto_dag/img/dag.svg
32 Representing Vertices/Activities
33 ................................
35 There is two types of :ref:`Activities <API_s4u_Activity>` that can represent Vertices: :ref:`Exec <API_s4u_Exec>` and :ref:`Comm <API_s4u_Comm>`.
36 Thoses activities must be initiated and configured to properly describe your worflow.
38 An Exec represents the execution of an amount of flop on a :ref:`Host <API_s4u_Host>` of your platform.
42 ExecPtr exec = Exec::init();
43 exec->set_flops_amount(int);
44 exec->set_host(Host*);
47 A Comm represents a data transfer between two :ref:`Hosts <API_s4u_Host>` of your platform.
51 CommPtr comm = Comm::sendto_init();
52 comm->set_source(Host*);
53 comm->set_destination(Host*);
56 Representing Edges/Dependencies
57 ...............................
59 An activity will not start until all of its dependencies have been completed.
60 Activities may have any number of successors.
61 Dependencies between Activities are created using :cpp:func:`Activity::add_successor(ActivityPtr)`.
65 exec->add_successor(comm);
67 The Activity ``comm`` will not start until ``exec`` has been completed.
72 The goal of this lab is to describe the following DAG:
74 .. image:: /tuto_dag/img/dag1.svg
77 In this DAG we want ``c1`` to compute 1e9 flops, ``c2`` to compute 5e9 flops and ``c3`` to compute 2e9 flops.
78 There is also a data transfer of 5e8 bytes between ``c1`` and ``c3``.
80 First of all, include the Simgrid library and define the log category.
84 #include "simgrid/s4u.hpp"
86 XBT_LOG_NEW_DEFAULT_CATEGORY(main, "Messages specific for this s4u tutorial");
88 Inside the ``main`` function create an instance of :ref:`Engine <API_s4u_Engine>` and load the platform.
92 simgrid::s4u::Engine e(&argc, argv);
93 e.load_platform(argv[1]);
95 Retrieve pointers to some hosts.
99 simgrid::s4u::Host* tremblay = e.host_by_name("Tremblay");
100 simgrid::s4u::Host* jupiter = e.host_by_name("Jupiter");
102 Initiate the activities.
106 simgrid::s4u::ExecPtr c1 = simgrid::s4u::Exec::init();
107 simgrid::s4u::ExecPtr c2 = simgrid::s4u::Exec::init();
108 simgrid::s4u::ExecPtr c3 = simgrid::s4u::Exec::init();
109 simgrid::s4u::CommPtr t1 = simgrid::s4u::Comm::sendto_init();
111 Give names to thoses activities.
120 Set the amount of work for each activity.
124 c1->set_flops_amount(1e9);
125 c2->set_flops_amount(5e9);
126 c3->set_flops_amount(2e9);
127 t1->set_payload_size(5e8);
129 Define the dependencies between the activities.
133 c1->add_successor(t1);
134 t1->add_successor(c3);
135 c2->add_successor(c3);
137 Set the location of each Exec activity and source and destination for the Comm activity.
141 c1->set_host(tremblay);
142 c2->set_host(jupiter);
143 c3->set_host(jupiter);
144 t1->set_source(tremblay);
145 t1->set_destination(jupiter);
147 Start the executions of Activities without dependencies.
154 Add a callback to monitor the activities.
158 Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
159 XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", activity.get_cname(), activity.get_start_time(),
160 activity.get_finish_time());
163 Finally, run the simulation.
169 The execution of this code should give you the following output:
173 [10.194200] [main/INFO] Activity 'c1' is complete (start time: 0.000000, finish time: 10.194200)
174 [65.534235] [main/INFO] Activity 'c2' is complete (start time: 0.000000, finish time: 65.534235)
175 [85.283378] [main/INFO] Activity 't1' is complete (start time: 10.194200, finish time: 85.283378)
176 [111.497072] [main/INFO] Activity 'c3' is complete (start time: 85.283378, finish time: 111.497072)
178 Lab 2: Import a DAG from a file
181 In this lab we present how to import a DAG into you Simgrid simulation, either using a DOT file, a JSON file, or a DAX file.
183 The files presented in this lab describe the following DAG:
185 .. image:: /tuto_dag/img/dag2.svg
191 A DOT file describes a workflow in accordance with the graphviz format.
193 The following DOT file describes the workflow presented at the beginning of this lab:
202 root->c1 [size="2e8"];
203 root->c2 [size="1e8"];
206 c3->end [size="2e8"];
209 It can be imported as a vector of Activities into Simgrid using :cpp:func:`create_DAG_from_DOT(const std::string& filename)`. Then, you have to assign hosts to your Activities.
213 #include "simgrid/s4u.hpp"
215 XBT_LOG_NEW_DEFAULT_CATEGORY(main, "Messages specific for this s4u example");
217 int main(int argc, char* argv[]) {
218 simgrid::s4u::Engine e(&argc, argv);
219 e.load_platform(argv[1]);
221 std::vector<simgrid::s4u::ActivityPtr> dag = simgrid::s4u::create_DAG_from_dot(argv[2]);
223 simgrid::s4u::Host* tremblay = e.host_by_name("Tremblay");
224 simgrid::s4u::Host* jupiter = e.host_by_name("Jupiter");
225 simgrid::s4u::Host* fafard = e.host_by_name("Fafard");
227 dynamic_cast<simgrid::s4u::Exec*>(dag[0].get())->set_host(fafard);
228 dynamic_cast<simgrid::s4u::Exec*>(dag[1].get())->set_host(tremblay);
229 dynamic_cast<simgrid::s4u::Exec*>(dag[2].get())->set_host(jupiter);
230 dynamic_cast<simgrid::s4u::Exec*>(dag[3].get())->set_host(jupiter);
231 dynamic_cast<simgrid::s4u::Exec*>(dag[8].get())->set_host(jupiter);
233 for (const auto& a : dag) {
234 if (auto* comm = dynamic_cast<simgrid::s4u::Comm*>(a.get())) {
235 auto pred = dynamic_cast<simgrid::s4u::Exec*>((*comm->get_dependencies().begin()).get());
236 auto succ = dynamic_cast<simgrid::s4u::Exec*>(comm->get_successors().front().get());
237 comm->set_source(pred->get_host())->set_destination(succ->get_host());
241 simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
242 XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", activity.get_cname(), activity.get_start_time(),
243 activity.get_finish_time());
250 The execution of this code should give you the following output:
254 [0.000000] [main/INFO] Activity 'root' is complete (start time: 0.000000, finish time: 0.000000)
255 [33.394394] [main/INFO] Activity 'root->c2' is complete (start time: 0.000000, finish time: 33.394394)
256 [39.832311] [main/INFO] Activity 'root->c1' is complete (start time: 0.000000, finish time: 39.832311)
257 [50.026511] [main/INFO] Activity 'c1' is complete (start time: 39.832311, finish time: 50.026511)
258 [98.928629] [main/INFO] Activity 'c2' is complete (start time: 33.394394, finish time: 98.928629)
259 [125.115689] [main/INFO] Activity 'c1->c3' is complete (start time: 50.026511, finish time: 125.115689)
260 [151.329383] [main/INFO] Activity 'c3' is complete (start time: 125.115689, finish time: 151.329383)
261 [151.743605] [main/INFO] Activity 'c3->end' is complete (start time: 151.329383, finish time: 151.743605)
262 [151.743605] [main/INFO] Activity 'end' is complete (start time: 151.743605, finish time: 151.743605)
267 A JSON file describes a workflow in accordance with the `wfformat <https://github.com/wfcommons/wfformat>`_ .
269 The following JSON file describes the workflow presented at the beginning of this lab:
274 "name": "simple_json",
275 "schemaVersion": "1.0",
278 "executedAt": "2023-03-09T00:00:00-00:00",
285 "machine": "Tremblay"
304 "parents": ["t1","c2"],
310 {"nodeName": "Tremblay"},
311 {"nodeName": "Jupiter"}
316 It can be imported as a vector of Activities into Simgrid using :cpp:func:`create_DAG_from_json(const std::string& filename)`.
320 #include "simgrid/s4u.hpp"
322 XBT_LOG_NEW_DEFAULT_CATEGORY(main, "Messages specific for this s4u example");
324 int main(int argc, char* argv[]) {
325 simgrid::s4u::Engine e(&argc, argv);
326 e.load_platform(argv[1]);
328 std::vector<simgrid::s4u::ActivityPtr> dag = simgrid::s4u::create_DAG_from_json(argv[2]);
330 simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
331 XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", activity.get_cname(), activity.get_start_time(),
332 activity.get_finish_time());
339 The execution of this code should give you the following output:
343 [10.194200] [main/INFO] Activity 'c1' is complete (start time: 0.000000, finish time: 10.194200)
344 [65.534235] [main/INFO] Activity 'c2' is complete (start time: 0.000000, finish time: 65.534235)
345 [85.283378] [main/INFO] Activity 't1' is complete (start time: 10.194200, finish time: 85.283378)
346 [111.497072] [main/INFO] Activity 'c3' is complete (start time: 85.283378, finish time: 111.497072)
348 From a DAX file [deprecated]
349 ............................
351 A DAX file describes a workflow in accordance with the `Pegasus <http://pegasus.isi.edu/>`_ format.
353 The following DAX file describes the workflow presented at the beginning of this lab:
357 <?xml version="1.0" encoding="UTF-8"?>
358 <adag xmlns="http://pegasus.isi.edu/schema/DAX" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
359 xsi:schemaLocation="http://pegasus.isi.edu/schema/DAX http://pegasus.isi.edu/schema/dax-2.1.xsd"
361 <job id="1" name="c1" runtime="10">
362 <uses file="i1" link="input" register="true" transfer="true" optional="false" type="data" size="2e8"/>
363 <uses file="o1" link="output" register="true" transfer="true" optional="false" type="data" size="5e8"/>
365 <job id="2" name="c2" runtime="50">
366 <uses file="i2" link="input" register="true" transfer="true" optional="false" type="data" size="1e8"/>
368 <job id="3" name="c3" runtime="20">
369 <uses file="o1" link="input" register="true" transfer="true" optional="false" type="data" size="5e8"/>
370 <uses file="o3" link="output" register="true" transfer="true" optional="false" type="data" size="2e8"/>
378 It can be imported as a vector of Activities into Simgrid using :cpp:func:`create_DAG_from_DAX(std::string)`.
382 #include "simgrid/s4u.hpp"
384 XBT_LOG_NEW_DEFAULT_CATEGORY(main, "Messages specific for this s4u example");
386 int main(int argc, char* argv[]) {
387 simgrid::s4u::Engine e(&argc, argv);
388 e.load_platform(argv[1]);
390 std::vector<simgrid::s4u::ActivityPtr> dag = simgrid::s4u::create_DAG_from_DAX(argv[2]);
392 simgrid::s4u::Host* tremblay = e.host_by_name("Tremblay");
393 simgrid::s4u::Host* jupiter = e.host_by_name("Jupiter");
394 simgrid::s4u::Host* fafard = e.host_by_name("Fafard");
396 dynamic_cast<simgrid::s4u::Exec*>(dag[0].get())->set_host(fafard);
397 dynamic_cast<simgrid::s4u::Exec*>(dag[1].get())->set_host(tremblay);
398 dynamic_cast<simgrid::s4u::Exec*>(dag[2].get())->set_host(jupiter);
399 dynamic_cast<simgrid::s4u::Exec*>(dag[3].get())->set_host(jupiter);
400 dynamic_cast<simgrid::s4u::Exec*>(dag[8].get())->set_host(jupiter);
402 for (const auto& a : dag) {
403 if (auto* comm = dynamic_cast<simgrid::s4u::Comm*>(a.get())) {
404 auto pred = dynamic_cast<simgrid::s4u::Exec*>((*comm->get_dependencies().begin()).get());
405 auto succ = dynamic_cast<simgrid::s4u::Exec*>(comm->get_successors().front().get());
406 comm->set_source(pred->get_host())->set_destination(succ->get_host());
410 simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
411 XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", activity.get_cname(), activity.get_start_time(),
412 activity.get_finish_time());