aGrUM  0.16.0
schedulerBasic_tpl.h
Go to the documentation of this file.
1 
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 
31 # include <agrum/agrum.h>
32 # include <limits>
33 
34 namespace gum {
35 
37  template < typename GUM_SCALAR >
38  SchedulerBasic< GUM_SCALAR >::SchedulerBasic() : Scheduler< GUM_SCALAR >() {
39  // for debugging purposes
40  GUM_CONSTRUCTOR(SchedulerBasic);
41  }
42 
44  template < typename GUM_SCALAR >
46  const SchedulerBasic< GUM_SCALAR >& from) :
47  Scheduler< GUM_SCALAR >(from) {
48  // for debugging purposes
49  GUM_CONS_CPY(SchedulerBasic);
50  }
51 
53  template < typename GUM_SCALAR >
55  // for debugging purposes
56  GUM_DESTRUCTOR(SchedulerBasic);
57  }
58 
60  template < typename GUM_SCALAR >
61  SchedulerBasic< GUM_SCALAR >* SchedulerBasic< GUM_SCALAR >::newFactory() const {
62  return new SchedulerBasic< GUM_SCALAR >(*this);
63  }
64 
66  template < typename GUM_SCALAR >
67  bool SchedulerBasic< GUM_SCALAR >::execute(Schedule< GUM_SCALAR >& schedule) {
68  const NodeSet& available = schedule.availableOperations();
69 
70  while (!available.empty()) {
71  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
72  iter != available.endSafe();
73  ++iter) {
74  schedule.execute(*iter);
75  }
76  }
77 
78  return (schedule.scheduling_dag().size() == 0);
79  }
80 
82  template < typename GUM_SCALAR >
83  bool SchedulerBasic< GUM_SCALAR >::execute(Schedule< GUM_SCALAR >& schedule,
84  Size k) {
85  const NodeSet& available = schedule.availableOperations();
86 
87  while (!available.empty() && k) {
88  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
89  iter != available.endSafe() && k;
90  ++iter, --k) {
91  schedule.execute(*iter);
92  }
93  }
94 
95  return !k || (schedule.scheduling_dag().size() == 0);
96  }
97 
100  template < typename GUM_SCALAR >
102  const Schedule< GUM_SCALAR >& schedule) const {
103  NodeSet available = schedule.availableOperations();
104  DAG dag = schedule.scheduling_dag();
105  float nb_operations = 0;
106 
107  while (!available.empty()) {
108  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
109  iter != available.endSafe();
110  ++iter) {
111  NodeId id = *iter;
112  nb_operations += schedule.nbOperations(id);
113  const NodeSet& children = dag.children(id);
114 
115  for (typename NodeSet::const_iterator_safe iter_children =
116  children.beginSafe();
117  iter_children != children.endSafe();
118  ++iter_children) {
119  if (dag.parents(*iter_children).size() == 1) {
120  available.insert(*iter_children);
121  }
122  }
123 
124  dag.eraseNode(id);
125  available.erase(iter);
126  }
127  }
128 
129  return nb_operations;
130  }
131 
134  template < typename GUM_SCALAR >
136  const Schedule< GUM_SCALAR >& schedule, Size k) const {
137  NodeSet available = schedule.availableOperations();
138  DAG dag = schedule.scheduling_dag();
139  float nb_operations = 0;
140 
141  while (!available.empty() && k) {
142  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
143  iter != available.endSafe() && k;
144  ++iter, --k) {
145  NodeId id = *iter;
146  nb_operations += schedule.nbOperations(id);
147  const NodeSet& children = dag.children(id);
148 
149  for (typename NodeSet::const_iterator_safe iter_children =
150  children.beginSafe();
151  iter_children != children.endSafe();
152  ++iter_children) {
153  if (dag.parents(*iter_children).size() == 1) {
154  available.insert(*iter_children);
155  }
156  }
157 
158  dag.eraseNode(id);
159  available.erase(iter);
160  }
161  }
162 
163  return nb_operations;
164  }
165 
167  template < typename GUM_SCALAR >
168  std::pair< long, long > SchedulerBasic< GUM_SCALAR >::memoryUsage(
169  const Schedule< GUM_SCALAR >& schedule) const {
170  NodeSet available = schedule.availableOperations();
171  DAG dag = schedule.scheduling_dag();
172  long max_memory = 0;
173  long current_memory = 0;
174 
175  while (!available.empty()) {
176  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
177  iter != available.endSafe();
178  ++iter) {
179  NodeId id = *iter;
180 
181  std::pair< long, long > mem_op = schedule.memoryUsage(id);
182 
183  if ((std::numeric_limits< long >::max() - current_memory < mem_op.first)
184  || (std::numeric_limits< long >::max() - current_memory
185  < mem_op.second)) {
186  GUM_ERROR(OutOfBounds, "memory usage out of long int range");
187  }
188 
189  if (current_memory + mem_op.first > max_memory)
190  max_memory = current_memory + mem_op.first;
191 
192  current_memory += mem_op.second;
193 
194  const NodeSet& children = dag.children(id);
195 
196  for (typename NodeSet::const_iterator_safe iter_children =
197  children.beginSafe();
198  iter_children != children.endSafe();
199  ++iter_children) {
200  if (dag.parents(*iter_children).size() == 1) {
201  available.insert(*iter_children);
202  }
203  }
204 
205  dag.eraseNode(id);
206  available.erase(iter);
207  }
208  }
209 
210  return std::pair< long, long >(max_memory, current_memory);
211  }
212 
215  template < typename GUM_SCALAR >
216  std::pair< long, long > SchedulerBasic< GUM_SCALAR >::memoryUsage(
217  const Schedule< GUM_SCALAR >& schedule, Size k) const {
218  NodeSet available = schedule.availableOperations();
219  DAG dag = schedule.scheduling_dag();
220  long max_memory = 0;
221  long current_memory = 0;
222 
223  while (!available.empty() && k) {
224  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
225  iter != available.endSafe() && k;
226  ++iter, --k) {
227  NodeId id = *iter;
228 
229  std::pair< long, long > mem_op = schedule.memoryUsage(id);
230 
231  if ((std::numeric_limits< long >::max() - current_memory < mem_op.first)
232  || (std::numeric_limits< long >::max() - current_memory
233  < mem_op.second)) {
234  GUM_ERROR(OutOfBounds, "memory usage out of long int range");
235  }
236 
237  if (current_memory + mem_op.first > max_memory)
238  max_memory = current_memory + mem_op.first;
239 
240  current_memory += mem_op.second;
241 
242  const NodeSet& children = dag.children(id);
243 
244  for (typename NodeSet::const_iterator_safe iter_children =
245  children.beginSafe();
246  iter_children != children.endSafe();
247  ++iter_children) {
248  if (dag.parents(*iter_children).size() == 1) {
249  available.insert(*iter_children);
250  }
251  }
252 
253  dag.eraseNode(id);
254  available.erase(iter);
255  }
256  }
257 
258  return std::pair< long, long >(max_memory, current_memory);
259  }
260 
261 } /* namespace gum */
262 
263 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
std::pair< long, long > memoryUsage(const Schedule< GUM_SCALAR > &) const
returns the memory consumption used during the execution of a schedule
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
SchedulerBasic< GUM_SCALAR > * newFactory() const
virtual constructor
bool execute(Schedule< GUM_SCALAR > &)
execute all the operations of a given schedule
SetIteratorSafe< NodeId > const_iterator_safe
Definition: set.h:180
SchedulerBasic()
default constructor
virtual ~SchedulerBasic()
destructor
Scheduler()
default constructor
float nbOperations(const Schedule< GUM_SCALAR > &) const
returns an estimation of the number of elementary operations needed to perform a given schedule ...
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
Size NodeId
Type for node ids.
Definition: graphElements.h:98
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:613
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55