aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
schedule.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /** @file
23  * @brief Class containing a schedule of operations to perform on multidims
24  *
25  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26  */
27 #ifndef GUM_SCHEDULE_H
28 #define GUM_SCHEDULE_H
29 
30 #include <utility>
31 
32 #include <agrum/agrum.h>
33 
34 #include <agrum/tools/core/hashTable.h>
35 #include <agrum/tools/core/set.h>
36 #include <agrum/tools/graphs/DAG.h>
37 #include <agrum/tools/graphs/graphElements.h>
38 
39 #include <agrum/tools/graphicalModels/inference/scheduler/scheduleCliqueStoreMultiDim.h>
40 #include <agrum/tools/graphicalModels/inference/scheduler/scheduleCombine.h>
41 #include <agrum/tools/graphicalModels/inference/scheduler/scheduleDeleteMultiDim.h>
42 #include <agrum/tools/graphicalModels/inference/scheduler/scheduleOperation.h>
43 #include <agrum/tools/graphicalModels/inference/scheduler/scheduleProject.h>
44 #include <agrum/tools/graphicalModels/inference/scheduler/scheduleSeparatorStoreMultiDim.h>
45 
46 namespace gum {
47 
48  /**
49  * @class Schedule
50  * @brief Class containing a schedule of operations to perform on multidims
51  *
52  * A Schedule class contains a set of operations to be scheduled. It is able
53  *to
54  * indicate which operations can currently be performed (because all their
55  * arguments have already been computed). In addition, it is possible to
56  *insert
57  * new operations into the schedule (at a specific place) and to remove some
58  * operations.
59  *
60  * @warning In the Schedule class does not guarantee that the schedule can
61  *always
62  * be performed, i.e., that there always exists a sequence in which all the
63  * operations of the schedule can be performed. It is up to the user to check
64  * this (function schedulePossible () may help here).
65  */
66  template < typename GUM_SCALAR >
67  class Schedule {
68  public:
69  /// to identify correctly the ids that correspond to ScheduleOperation ids
70  using OperationId = Idx;
71 
72  /// to identify correctly the ids that correspond to ScheduleMultiDim ids
73  using MultiDimId = Idx;
74 
75  // ############################################################################
76  /// @name Constructors / Destructors
77  // ############################################################################
78  /// @{
79 
80  /// default constructor (construct an empty sequence)
81  Schedule();
82 
83  /// copy constructor
84  Schedule(const Schedule< GUM_SCALAR >&);
85 
86  /// destructor
87  ~Schedule();
88 
89  /// @}
90 
91  // ############################################################################
92  /// @name Operators
93  // ############################################################################
94 
95  /// @{
96 
97  /// copy operator
98  Schedule< GUM_SCALAR >& operator=(const Schedule< GUM_SCALAR >&);
99 
100  /// @}
101 
102  // ############################################################################
103  /// @name Accessors/Modifiers
104  // ############################################################################
105  /// @{
106 
107  /// inserts an operation to be scheduled
108  /** The Schedule class is able to determined by itself when the operation
109  * should be performed.
110  * @warning operations are inserted by copy */
112 
113  /** @brief adds a constraint indicating that an operation cannot be
114  * performed
115  * before another one */
116  void forceAfter(const ScheduleOperation< GUM_SCALAR >& op_to_force,
117  const ScheduleOperation< GUM_SCALAR >& op_before);
118  void forceAfter(NodeId op_to_force, NodeId op_before);
119 
120  /** @brief adds a constraint indicating that an operation cannot be
121  * performed
122  * before a set of operations */
123  void forceAfter(const ScheduleOperation< GUM_SCALAR >& op_to_force,
124  const Set< const ScheduleOperation< GUM_SCALAR >* >& ops_before);
125  void forceAfter(NodeId op_to_force, const NodeSet& ops_before);
126 
127  /** @brief adds a constraint indicating that an operation must be performed
128  * before another one */
129  void forceBefore(const ScheduleOperation< GUM_SCALAR >& op_to_force,
130  const ScheduleOperation< GUM_SCALAR >& op_after);
131  void forceBefore(NodeId op_to_force, NodeId op_after);
132 
133  /** @brief adds a constraint indicating that an operation must be performed
134  * before a set of operations */
135  void forceBefore(const ScheduleOperation< GUM_SCALAR >& op_to_force,
136  const Set< const ScheduleOperation< GUM_SCALAR >* >& ops_after);
137  void forceBefore(NodeId op_to_force, const NodeSet& ops_after);
138 
139  /// returns a DAG indicating in which order the operations can be performed
140  /** In this DAG, each node corresponds to an operation and an operation
141  * can be performed only if its ancestors have all been performed. */
142  const DAG& scheduling_dag() const;
143 
144  /// returns the scheduleOperation corresponding to an id in the DAG
145  /** @throws NotFound exception is raised if the DAG does not contain the id
146  */
147  const ScheduleOperation< GUM_SCALAR >& operation(NodeId) const;
148 
149  /// returns the id of the node corresponding to a given ScheduleOperation
150  /** @throws NotFound exception is raised the operation does not belong to
151  * the Schedule */
152  NodeId nodeId(const ScheduleOperation< GUM_SCALAR >&) const;
153 
154  /// resturns the association between operations anf nodeIds
155  const NodeProperty< const ScheduleOperation< GUM_SCALAR >* >& operations() const;
156 
157  /// returns the set of operations involving a given multidim table
160 
161  /// returns the set of ScheduleOperations that can be executed at once
162  /** The scheduleOperations that can be executed at once are those that
163  have no parent or whose parents have already been executed. */
164  const NodeSet& availableOperations() const;
165 
166  /// executes a given operation (if this one is available)
167  /** Note that, whenever an operation is performed, the list of available
168  * operations is updated and the operation itslef is removed from the
169  * schedule
170  * @throws OperationNotAllowed exception is thrown if the operation cannot
171  * be
172  * executed yet because some of its arguments have not already been computed
173  * @throws NotFound exception is thrown if the operation cannot be found */
174  void execute(NodeId);
175  void execute(const ScheduleOperation< GUM_SCALAR >&);
176 
177  /** @brief returns an estimation of the number of elementary operations
178  * needed
179  * to perform a given ScheduleOperation */
180  float nbOperations(NodeId) const;
181  float nbOperations(ScheduleOperation< GUM_SCALAR >&) const;
182 
183  /// returns the memory consumption used during the execution of an operation
184  /** Actually, this function does not return a precise account of the memory
185  * used by the scheduleOperation but a rough estimate based on the sizes
186  * of the tables involved in the operation.
187  * @return a pair of memory consumption: the first one is the maximum
188  * amount of memory used during the ScheduleOperation and the second one is
189  * the
190  * amount of memory still used at the end of the operation ( the memory used
191  * by
192  * the resulting table ) */
193  std::pair< long, long > memoryUsage(NodeId) const;
194  std::pair< long, long > memoryUsage(ScheduleOperation< GUM_SCALAR >&) const;
195 
196  /// @}
197 
198  private:
199  /// the DAG of the operations to perform
200  /** Operations can be scheduled as a DAG: nodes without parents can be
201  * executed directly. The other nodes need their parents to be executed to
202  * get all their arguments constructed. */
203  mutable DAG _dag_;
204 
205  /// a hashtable assigning to each node of the DAG an operation
207 
208  /// a hashtable assigning to each operation id a node id in the DAG
210 
211  /** @brief a hashtable assigning to each ScheduleMultiDim resulting from a
212  * computation the MultiDimOperation node id that created it */
214 
215  /// a list of operations whose parents are not properly set
216  /** when entering operations to be performed in a "wrong" order, it may
217  * happen that the parents of some operations in the DAG are not properly
218  * set (the parents being inserted after the child). We keep a list of
219  * such nodes and, whenever we wish to perform the schedule or get its DAG,
220  * we compute the correct set of parents of the operations of this list
221  * and, when this is done, we remove them from the list. As such, when the
222  * list is empty, the schedule can be performed. */
224 
225  /// the set of operations that can be executed at once
227 
228  /// for each multidim, store the set of operations involving it
230 
231  /** @brief updates the set of parents for the nodes whoses parents are not
232  * correct yet and update accordingly the available operations */
233  void _updateWrongParents_() const;
234  };
235 
236 } /* namespace gum */
237 
238 // always include the template implementation
239 #include <agrum/tools/graphicalModels/inference/scheduler/schedule_tpl.h>
240 
241 #endif /* GUM_SCHEDULE_H */
DAG _dag_
the DAG of the operations to perform
Definition: schedule.h:203
float nbOperations(ScheduleOperation< GUM_SCALAR > &) const
inserts an operation to be scheduled
void forceBefore(NodeId op_to_force, const NodeSet &ops_after)
inserts an operation to be scheduled
void execute(NodeId)
executes a given operation (if this one is available)
void _updateWrongParents_() const
updates the set of parents for the nodes whoses parents are not correct yet and update accordingly th...
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
void execute(const ScheduleOperation< GUM_SCALAR > &)
inserts an operation to be scheduled
void forceAfter(NodeId op_to_force, NodeId op_before)
inserts an operation to be scheduled
NodeId nodeId(const ScheduleOperation< GUM_SCALAR > &) const
returns the id of the node corresponding to a given ScheduleOperation
Schedule(const Schedule< GUM_SCALAR > &)
copy constructor
std::pair< long, long > memoryUsage(ScheduleOperation< GUM_SCALAR > &) const
inserts an operation to be scheduled
void forceAfter(const ScheduleOperation< GUM_SCALAR > &op_to_force, const Set< const ScheduleOperation< GUM_SCALAR > * > &ops_before)
adds a constraint indicating that an operation cannot be performed before a set of operations ...
NodeId insert(const ScheduleOperation< GUM_SCALAR > &)
inserts an operation to be scheduled
HashTable< MultiDimId, NodeSet *> _multidim2operations_
for each multidim, store the set of operations involving it
Definition: schedule.h:229
const NodeSet & operationsInvolving(const ScheduleMultiDim< GUM_SCALAR > &table) const
returns the set of operations involving a given multidim table
const DAG & scheduling_dag() const
returns a DAG indicating in which order the operations can be performed
const NodeSet & availableOperations() const
returns the set of ScheduleOperations that can be executed at once
~Schedule()
destructor
Schedule< GUM_SCALAR > & operator=(const Schedule< GUM_SCALAR > &)
copy operator
HashTable< OperationId, NodeId > _operation2node_
a hashtable assigning to each operation id a node id in the DAG
Definition: schedule.h:209
NodeSet _operations_available_
the set of operations that can be executed at once
Definition: schedule.h:226
std::pair< long, long > memoryUsage(NodeId) const
returns the memory consumption used during the execution of an operation
const NodeSet & operationsInvolving(MultiDimId table_id) const
inserts an operation to be scheduled
HashTable< MultiDimId, NodeId > _created_multidims_
a hashtable assigning to each ScheduleMultiDim resulting from a computation the MultiDimOperation nod...
Definition: schedule.h:213
const ScheduleOperation< GUM_SCALAR > & operation(NodeId) const
returns the scheduleOperation corresponding to an id in the DAG
Schedule()
default constructor (construct an empty sequence)
void forceBefore(const ScheduleOperation< GUM_SCALAR > &op_to_force, const Set< const ScheduleOperation< GUM_SCALAR > * > &ops_after)
adds a constraint indicating that an operation must be performed before a set of operations ...
void forceAfter(NodeId op_to_force, const NodeSet &ops_before)
inserts an operation to be scheduled
void forceBefore(NodeId op_to_force, NodeId op_after)
inserts an operation to be scheduled
float nbOperations(NodeId) const
returns an estimation of the number of elementary operations needed to perform a given ScheduleOperat...
NodeProperty< ScheduleOperation< GUM_SCALAR > *> _node2operation_
a hashtable assigning to each node of the DAG an operation
Definition: schedule.h:206
const NodeProperty< const ScheduleOperation< GUM_SCALAR > *> & operations() const
resturns the association between operations anf nodeIds
NodeSet _operations_with_wrong_parents_
a list of operations whose parents are not properly set
Definition: schedule.h:223