Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
continue to mess up with simdag
[simgrid.git] / src / simdag / simdag_private.hpp
1 /* Copyright (c) 2006-2021. 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/Engine.hpp>
7 #include <simgrid/s4u/Host.hpp>
8 #include <simgrid/simdag.h>
9 #include <xbt/Extendable.hpp>
10
11 #include <set>
12 #include <string>
13 #include <vector>
14
15 #ifndef SIMDAG_PRIVATE_HPP
16 #define SIMDAG_PRIVATE_HPP
17 #if SIMGRID_HAVE_JEDULE
18 #include "simgrid/jedule/jedule_sd_binding.h"
19 #endif
20
21 namespace simgrid{
22 extern template class XBT_PUBLIC xbt::Extendable<sd::Task>;
23
24 namespace sd{
25 class Global;
26
27 class Task : public xbt::Extendable<Task> {
28   friend sd::Global;
29
30   std::string name_;
31   double amount_;
32
33   e_SD_task_kind_t kind_   = SD_TASK_NOT_TYPED;
34   e_SD_task_state_t state_ = SD_NOT_SCHEDULED;
35   bool marked_             = false; /* used to check if the task DAG has some cycle*/
36   double start_time_       = -1;
37   double finish_time_      = -1;
38   kernel::resource::Action* surf_action_;
39   unsigned short watch_points_ = 0; /* bit field xor()ed with masks */
40   double rate_                 = -1;
41
42   double alpha_ = 0; /* used by typed parallel tasks */
43
44   /* dependencies */
45   std::set<Task*> dependencies_;
46   std::vector<Task*> successors_;
47
48   /* scheduling parameters (only exist in state SD_SCHEDULED) */
49   std::vector<s4u::Host*>* allocation_;
50   double* flops_amount_;
51   double* bytes_amount_;
52
53 protected:
54   void set_start_time(double start) { start_time_ = start; }
55
56   void set_sender_side_allocation(unsigned long count, const std::vector<s4u::Host*>* sender);
57   void set_receiver_side_allocation(unsigned long count, const std::vector<s4u::Host*>* receiver);
58
59 public:
60   static Task* create(const std::string& name, double amount, void* userdata);
61   static Task* create_comm_e2e(const std::string& name, double amount, void* userdata);
62   static Task* create_comp_seq(const std::string& name, double amount, void* userdata);
63   static Task* create_comp_par_amdahl(const std::string& name, double amount, void* userdata, double alpha);
64   static Task* create_comm_par_mxn_1d_block(const std::string& name, double amount, void* userdata);
65
66   void distribute_comp_amdahl(unsigned long count);
67   void build_MxN_1D_block_matrix(unsigned long src_nb, unsigned long dst_nb);
68
69   /** @brief Adds a dependency between with 'task'
70    *  @a task will depend on this Task, i.e., it cannot start before this task is finished.
71    */
72   void dependency_add(Task* task);
73   bool dependency_exist(Task* task) const;
74   /** @brief Remove a dependency with 'task' */
75   void dependency_remove(Task* task);
76   void clear_successors() { successors_.clear(); }
77
78   void set_name(const std::string& name) { name_ = name; }
79   const std::string& get_name() const { return name_; }
80   const char* get_cname() const { return name_.c_str(); }
81
82   /** @brief Sets the total amount of work of a task
83    * For sequential typed tasks (COMP_SEQ and COMM_E2E), it also sets the appropriate values in the flops_amount and
84    * bytes_amount arrays respectively. Nothing more than modifying task->amount is done for parallel typed tasks
85    * (COMP_PAR_AMDAHL and COMM_PAR_MXN_1D_BLOCK) as the distribution of the amount of work is done at scheduling time.
86    */
87   void set_amount(double amount);
88   double get_amount() const { return amount_; }
89   /** @brief Returns the remaining amount of work (computation or data transfer) to do before completion */
90   double get_remaining_amount() const;
91   /** @brief Returns the start time of a task */
92   double get_start_time() const;
93   /** @brief Returns the finish time of a task
94    * If the state is not completed yet, the returned value is an estimation of the task finish time. This value can
95    * vary until the task is completed.
96    */
97   double get_finish_time() const;
98
99   void set_state(e_SD_task_state_t new_state);
100   e_SD_task_state_t get_state() const { return state_; }
101
102   void mark() { marked_ = true; }
103   void unmark() { marked_ = false; }
104   bool is_marked() const { return marked_; }
105
106   const std::set<Task*>& get_dependencies() const { return dependencies_; }
107   std::set<Task*> get_predecessors() const;
108   std::set<Task*> get_inputs() const;
109   const std::vector<Task*>& get_successors() const { return successors_; }
110   std::vector<Task*> get_outputs() const;
111
112   unsigned long has_unsolved_dependencies() const { return dependencies_.size(); }
113   unsigned long is_waited_by() const { return successors_.size(); }
114   void released_by(Task* pred);
115   void produced_by(Task* pred);
116
117   void set_kind(e_SD_task_kind_t kind) { kind_ = kind; }
118   e_SD_task_kind_t get_kind() const { return kind_; }
119
120   void set_alpha(double alpha) { alpha_ = alpha; }
121   /** @brief Sets the rate of a task
122    *
123    * This will change the network bandwidth a task can use. This rate  cannot be dynamically changed. Once the task has
124    * started, this call is ineffective. This rate depends on both the nominal bandwidth on the route onto which the task
125    * is scheduled (@see SD_task_get_current_bandwidth) and the amount of data to transfer.
126    *
127    * To divide the nominal bandwidth by 2, the rate then has to be :
128    *    rate = bandwidth/(2*amount)
129    */
130   void set_rate(double rate);
131
132   unsigned long get_allocation_size() const { return allocation_->size(); }
133   std::vector<s4u::Host*>* get_allocation() const { return allocation_; }
134
135   /** @brief Adds a watch point to a task
136    * sd::simulate() stops as soon as the @ref e_SD_task_state_t "state" of this task becomes the one given as argument.
137    * The watched state cannot be #SD_NOT_SCHEDULED
138    */
139   void watch(e_SD_task_state_t state);
140   /** @brief Removes a watch point on 'state' from a task */
141   void unwatch(e_SD_task_state_t state);
142
143   /** @brief Displays debugging information about a task */
144   void dump() const;
145
146   void do_schedule();
147   void schedule(const std::vector<s4u::Host*>& hosts, const double* flops_amount, const double* bytes_amount,
148                 double rate);
149   void schedulev(const std::vector<s4u::Host*>& hosts);
150   /**
151    * @brief Unschedules a task. Its state becomes #SD_NOT_SCHEDULED. You can schedule it again afterwards */
152   void unschedule();
153
154   void run();
155   void destroy();
156 };
157
158 class Global {
159 public:
160   explicit Global(int* argc, char** argv) : engine_(new simgrid::s4u::Engine(argc, argv)) {}
161   bool watch_point_reached = false; /* has a task just reached a watch point? */
162   std::set<Task*> initial_tasks;
163   std::set<Task*> runnable_tasks;
164   std::set<Task*> completed_tasks;
165   std::set<Task*> return_set;
166   s4u::Engine* engine_;
167 };
168
169 } // namespace sd
170 } // namespace simgrid
171
172 extern XBT_PRIVATE std::unique_ptr<simgrid::sd::Global> sd_global;
173
174 /* SimDag private functions */
175 XBT_PRIVATE bool acyclic_graph_detail(const_xbt_dynar_t dag);
176 XBT_PRIVATE void uniq_transfer_task_name(SD_task_t task);
177 XBT_PRIVATE const char *__get_state_name(e_SD_task_state_t state);
178 #endif