aGrUM  0.14.2
schedulerBasic_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Pierre-Henri WUILLEMIN et Christophe GONZALES *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
26 #ifndef DOXYGEN_SHOULD_SKIP_THIS
27 
28 # include <agrum/agrum.h>
29 # include <limits>
30 
31 namespace gum {
32 
34  template < typename GUM_SCALAR >
35  SchedulerBasic< GUM_SCALAR >::SchedulerBasic() : Scheduler< GUM_SCALAR >() {
36  // for debugging purposes
37  GUM_CONSTRUCTOR(SchedulerBasic);
38  }
39 
41  template < typename GUM_SCALAR >
43  const SchedulerBasic< GUM_SCALAR >& from) :
44  Scheduler< GUM_SCALAR >(from) {
45  // for debugging purposes
46  GUM_CONS_CPY(SchedulerBasic);
47  }
48 
50  template < typename GUM_SCALAR >
52  // for debugging purposes
53  GUM_DESTRUCTOR(SchedulerBasic);
54  }
55 
57  template < typename GUM_SCALAR >
58  SchedulerBasic< GUM_SCALAR >* SchedulerBasic< GUM_SCALAR >::newFactory() const {
59  return new SchedulerBasic< GUM_SCALAR >(*this);
60  }
61 
63  template < typename GUM_SCALAR >
64  bool SchedulerBasic< GUM_SCALAR >::execute(Schedule< GUM_SCALAR >& schedule) {
65  const NodeSet& available = schedule.availableOperations();
66 
67  while (!available.empty()) {
68  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
69  iter != available.endSafe();
70  ++iter) {
71  schedule.execute(*iter);
72  }
73  }
74 
75  return (schedule.scheduling_dag().size() == 0);
76  }
77 
79  template < typename GUM_SCALAR >
80  bool SchedulerBasic< GUM_SCALAR >::execute(Schedule< GUM_SCALAR >& schedule,
81  Size k) {
82  const NodeSet& available = schedule.availableOperations();
83 
84  while (!available.empty() && k) {
85  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
86  iter != available.endSafe() && k;
87  ++iter, --k) {
88  schedule.execute(*iter);
89  }
90  }
91 
92  return !k || (schedule.scheduling_dag().size() == 0);
93  }
94 
97  template < typename GUM_SCALAR >
99  const Schedule< GUM_SCALAR >& schedule) const {
100  NodeSet available = schedule.availableOperations();
101  DAG dag = schedule.scheduling_dag();
102  float nb_operations = 0;
103 
104  while (!available.empty()) {
105  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
106  iter != available.endSafe();
107  ++iter) {
108  NodeId id = *iter;
109  nb_operations += schedule.nbOperations(id);
110  const NodeSet& children = dag.children(id);
111 
112  for (typename NodeSet::const_iterator_safe iter_children =
113  children.beginSafe();
114  iter_children != children.endSafe();
115  ++iter_children) {
116  if (dag.parents(*iter_children).size() == 1) {
117  available.insert(*iter_children);
118  }
119  }
120 
121  dag.eraseNode(id);
122  available.erase(iter);
123  }
124  }
125 
126  return nb_operations;
127  }
128 
131  template < typename GUM_SCALAR >
133  const Schedule< GUM_SCALAR >& schedule, Size k) const {
134  NodeSet available = schedule.availableOperations();
135  DAG dag = schedule.scheduling_dag();
136  float nb_operations = 0;
137 
138  while (!available.empty() && k) {
139  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
140  iter != available.endSafe() && k;
141  ++iter, --k) {
142  NodeId id = *iter;
143  nb_operations += schedule.nbOperations(id);
144  const NodeSet& children = dag.children(id);
145 
146  for (typename NodeSet::const_iterator_safe iter_children =
147  children.beginSafe();
148  iter_children != children.endSafe();
149  ++iter_children) {
150  if (dag.parents(*iter_children).size() == 1) {
151  available.insert(*iter_children);
152  }
153  }
154 
155  dag.eraseNode(id);
156  available.erase(iter);
157  }
158  }
159 
160  return nb_operations;
161  }
162 
164  template < typename GUM_SCALAR >
165  std::pair< long, long > SchedulerBasic< GUM_SCALAR >::memoryUsage(
166  const Schedule< GUM_SCALAR >& schedule) const {
167  NodeSet available = schedule.availableOperations();
168  DAG dag = schedule.scheduling_dag();
169  long max_memory = 0;
170  long current_memory = 0;
171 
172  while (!available.empty()) {
173  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
174  iter != available.endSafe();
175  ++iter) {
176  NodeId id = *iter;
177 
178  std::pair< long, long > mem_op = schedule.memoryUsage(id);
179 
180  if ((std::numeric_limits< long >::max() - current_memory < mem_op.first)
181  || (std::numeric_limits< long >::max() - current_memory
182  < mem_op.second)) {
183  GUM_ERROR(OutOfBounds, "memory usage out of long int range");
184  }
185 
186  if (current_memory + mem_op.first > max_memory)
187  max_memory = current_memory + mem_op.first;
188 
189  current_memory += mem_op.second;
190 
191  const NodeSet& children = dag.children(id);
192 
193  for (typename NodeSet::const_iterator_safe iter_children =
194  children.beginSafe();
195  iter_children != children.endSafe();
196  ++iter_children) {
197  if (dag.parents(*iter_children).size() == 1) {
198  available.insert(*iter_children);
199  }
200  }
201 
202  dag.eraseNode(id);
203  available.erase(iter);
204  }
205  }
206 
207  return std::pair< long, long >(max_memory, current_memory);
208  }
209 
212  template < typename GUM_SCALAR >
213  std::pair< long, long > SchedulerBasic< GUM_SCALAR >::memoryUsage(
214  const Schedule< GUM_SCALAR >& schedule, Size k) const {
215  NodeSet available = schedule.availableOperations();
216  DAG dag = schedule.scheduling_dag();
217  long max_memory = 0;
218  long current_memory = 0;
219 
220  while (!available.empty() && k) {
221  for (typename NodeSet::const_iterator_safe iter = available.beginSafe();
222  iter != available.endSafe() && k;
223  ++iter, --k) {
224  NodeId id = *iter;
225 
226  std::pair< long, long > mem_op = schedule.memoryUsage(id);
227 
228  if ((std::numeric_limits< long >::max() - current_memory < mem_op.first)
229  || (std::numeric_limits< long >::max() - current_memory
230  < mem_op.second)) {
231  GUM_ERROR(OutOfBounds, "memory usage out of long int range");
232  }
233 
234  if (current_memory + mem_op.first > max_memory)
235  max_memory = current_memory + mem_op.first;
236 
237  current_memory += mem_op.second;
238 
239  const NodeSet& children = dag.children(id);
240 
241  for (typename NodeSet::const_iterator_safe iter_children =
242  children.beginSafe();
243  iter_children != children.endSafe();
244  ++iter_children) {
245  if (dag.parents(*iter_children).size() == 1) {
246  available.insert(*iter_children);
247  }
248  }
249 
250  dag.eraseNode(id);
251  available.erase(iter);
252  }
253  }
254 
255  return std::pair< long, long >(max_memory, current_memory);
256  }
257 
258 } /* namespace gum */
259 
260 #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
gum is the global namespace for all aGrUM entities
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:177
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:45
Size NodeId
Type for node ids.
Definition: graphElements.h:97
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:610
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52