Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
7136e330c5ff9a25369210b2d1d91130219b08e3
[simgrid.git] / examples / cpp / engine-filtering / s4u-engine-filtering.cpp
1 /* Copyright (c) 2017-2022. 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 #include <simgrid/s4u.hpp>
7
8 /* This example shows how to use sg4::Engine::get_filtered_hosts() to retrieve
9  * all hosts that match a given criteria. This criteria can be specified either with:
10  *   - an inlined callback
11  *   - a boolean function, such as filter_speed_more_than_50Mf() below
12  *   - a functor (= function object), that can either be stateless such as filter::SingleCore below, or that can save
13  *     state such as filter::FrequencyChanged below
14  *
15  * This file provides examples for each of these categories. You should implement your own filters in your code.
16  */
17
18 XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_engine_filtering, "Messages specific for this s4u example");
19 namespace sg4 = simgrid::s4u;
20
21 namespace filter {
22 /* First example of thing that we can use as a filtering criteria: a simple boolean function */
23 static bool filter_speed_more_than_50Mf(const sg4::Host* host)
24 {
25   return host->get_speed() > 50E6;
26 }
27
28 /* Second kind of thing that we can use as a filtering criteria: a functor (=function object).
29  * This one is a bit stupid: it's a lot of boilerplate over a dummy boolean function.
30  */
31 class SingleCore {
32 public:
33   bool operator()(const sg4::Host* host) const { return host->get_core_count() == 1; }
34 };
35
36 /* This functor is a bit more complex, as it saves the current state when created.
37  * Then, it allows one to easily retrieve the hosts which frequency changed since the functor creation.
38  */
39 class FrequencyChanged {
40   std::map<sg4::Host*, unsigned long> host_list;
41
42 public:
43   explicit FrequencyChanged(const sg4::Engine& e)
44   {
45     std::vector<sg4::Host*> list = e.get_all_hosts();
46     for (auto& host : list) {
47       host_list.insert({host, host->get_pstate()});
48     }
49   }
50
51   bool operator()(sg4::Host* host) { return host->get_pstate() != host_list.at(host); }
52
53   unsigned long get_old_speed_state(sg4::Host* host) { return host_list.at(host); }
54 };
55 }
56 int main(int argc, char* argv[])
57 {
58   sg4::Engine e(&argc, argv);
59   e.load_platform(argv[1]);
60
61   /* Use a lambda function to filter hosts: We only want multicore hosts */
62   XBT_INFO("Hosts currently registered with this engine: %zu", e.get_host_count());
63   std::vector<sg4::Host*> list = e.get_filtered_hosts([](const sg4::Host* host) { return host->get_core_count() > 1; });
64
65   for (auto& host : list)
66     XBT_INFO("The following hosts have more than one core: %s", host->get_cname());
67
68   xbt_assert(list.size() == 1);
69
70   /* Use a function object (functor) without memory */
71   list = e.get_filtered_hosts(filter::SingleCore());
72
73   for (auto& host : list)
74     XBT_INFO("The following hosts are SingleCore: %s", host->get_cname());
75
76   /* Use a function object that uses memory to filter */
77   XBT_INFO("A simple example: Let's retrieve all hosts that changed their frequency");
78   filter::FrequencyChanged filter(e);
79   e.host_by_name("MyHost2")->set_pstate(2);
80   list = e.get_filtered_hosts(filter);
81
82   for (auto& host : list)
83     XBT_INFO("The following hosts changed their frequency: %s (from %.1ff to %.1ff)", host->get_cname(),
84              host->get_pstate_speed(filter.get_old_speed_state(host)), host->get_speed());
85
86   /* You can also just use any regular function (namespaced on need) to filter  */
87   list = e.get_filtered_hosts(filter::filter_speed_more_than_50Mf);
88
89   for (auto& host : list)
90     XBT_INFO("The following hosts have a frequency > 50Mf: %s", host->get_cname());
91
92   return 0;
93 }