26 #ifndef DOXYGEN_SHOULD_SKIP_THIS 36 template <
typename GUM_SCALAR >
38 MultiDimImplementation< GUM_SCALAR >* (*combine)(
39 const MultiDimImplementation< GUM_SCALAR >&,
40 const MultiDimImplementation< GUM_SCALAR >&)) :
41 ScheduleCombination< GUM_SCALAR >(),
48 template <
typename GUM_SCALAR >
50 const ScheduleCombinationBasic< GUM_SCALAR >& from) :
58 template <
typename GUM_SCALAR >
65 template <
typename GUM_SCALAR >
66 ScheduleCombinationBasic< GUM_SCALAR >*
68 return new ScheduleCombinationBasic< GUM_SCALAR >(*this);
72 template <
typename GUM_SCALAR >
74 MultiDimImplementation< GUM_SCALAR >* (*
combine)(
75 const MultiDimImplementation< GUM_SCALAR >&,
76 const MultiDimImplementation< GUM_SCALAR >&)) {
81 template <
typename GUM_SCALAR >
82 MultiDimImplementation< GUM_SCALAR >* (
84 const MultiDimImplementation< GUM_SCALAR >&,
85 const MultiDimImplementation< GUM_SCALAR >&) {
91 template <
typename GUM_SCALAR >
93 const Sequence< const DiscreteVariable* >& seq1,
94 const Sequence< const DiscreteVariable* >& seq2)
const {
95 if (seq1.empty() && seq2.empty())
return 0;
99 for (
const auto var : seq1)
100 size *= var->domainSize();
102 for (
const auto var : seq2)
103 if (!seq1.exists(var)) size *= var->domainSize();
109 template <
typename GUM_SCALAR >
111 const Set<
const ScheduleMultiDim< GUM_SCALAR >* >&
set,
112 Schedule< GUM_SCALAR >& schedule) {
114 if (
set.size() < 2) {
116 "the set passed to a ScheduleCombinationBasic" 117 " should at least contain two elements");
121 std::vector< const ScheduleMultiDim< GUM_SCALAR >* > tables(
set.size());
126 for (
const auto sched :
set) {
136 std::vector< bool > is_t_new(tables.size(),
false);
141 std::pair< Idx, Idx > pair;
143 PriorityQueue< std::pair< Idx, Idx >,
Size > queue;
145 for (
Idx i = 0; i < tables.size(); ++i) {
147 const Sequence< const DiscreteVariable* >& seq1 =
148 tables[i]->variablesSequence();
150 for (
Idx j = i + 1; j < tables.size(); ++j) {
152 queue.insert(pair,
_combinedSize(seq1, tables[j]->variablesSequence()));
162 for (
Idx k = 1; k < tables.size(); ++k) {
166 Idx tj = pair.second;
170 ScheduleCombine< GUM_SCALAR > comb(*(tables[ti]), *(tables[tj]),
_combine);
171 NodeId comb_id = schedule.insert(comb);
176 if (tables[ti] && is_t_new[ti]) {
177 ScheduleDeleteMultiDim< GUM_SCALAR > del(*(tables[ti]));
178 NodeId del_id = schedule.insert(del);
179 const NodeSet& set_i = schedule.operationsInvolving(*(tables[ti]));
180 schedule.forceAfter(del_id, set_i);
183 if (tables[tj] && is_t_new[tj]) {
184 ScheduleDeleteMultiDim< GUM_SCALAR > del(*(tables[tj]));
185 NodeId del_id = schedule.insert(del);
186 const NodeSet& set_j = schedule.operationsInvolving(*(tables[tj]));
187 schedule.forceAfter(del_id, set_j);
190 tables[ti] = &(
static_cast< const ScheduleCombine< GUM_SCALAR >&
> 192 (schedule.operation(comb_id))
199 for (
Idx ind = 0; ind < tj; ++ind) {
208 for (
Idx ind = tj + 1; ind < tables.size(); ++ind) {
217 const Sequence< const DiscreteVariable* >& seq1 =
218 tables[ti]->variablesSequence();
222 for (
Idx ind = 0; ind < ti; ++ind) {
225 newsize =
_combinedSize(seq1, tables[ind]->variablesSequence());
226 queue.setPriority(pair, newsize);
232 for (
Idx ind = ti + 1; ind < tables.size(); ++ind) {
235 newsize =
_combinedSize(seq1, tables[ind]->variablesSequence());
236 queue.setPriority(pair, newsize);
253 template <
typename GUM_SCALAR >
254 INLINE ScheduleMultiDim< GUM_SCALAR >
256 const Set<
const MultiDimImplementation< GUM_SCALAR >* >&
set,
257 Schedule< GUM_SCALAR >& schedule) {
262 template <
typename GUM_SCALAR >
263 template <
template <
typename >
class TABLE >
264 INLINE ScheduleMultiDim< GUM_SCALAR >
266 const Set<
const TABLE< GUM_SCALAR >* >&
set,
267 Schedule< GUM_SCALAR >& schedule) {
272 template <
typename GUM_SCALAR >
274 const Set<
const ScheduleMultiDim< GUM_SCALAR >* >&
set,
275 const Schedule< GUM_SCALAR >& schedule) {
277 if (
set.size() < 2)
return 0.0f;
282 std::vector< const Sequence< const DiscreteVariable* >* > tables(
set.size());
287 for (
const auto sched :
set) {
288 tables[i] = &(sched->variablesSequence());
298 std::vector< bool > is_t_new(tables.size(),
false);
303 std::pair< Idx, Idx > pair;
304 PriorityQueue< std::pair< Idx, Idx >,
Size > queue;
306 for (
Idx i = 0; i < tables.size(); ++i) {
309 for (
Idx j = i + 1; j < tables.size(); ++j) {
311 queue.insert(pair,
_combinedSize(*(tables[i]), *(tables[j])));
320 for (
Idx k = 1; k < tables.size(); ++k) {
324 Idx tj = pair.second;
327 Sequence< const DiscreteVariable* >* new_seq =
328 new Sequence< const DiscreteVariable* >;
329 const Sequence< const DiscreteVariable* >& seq1 = *(tables[ti]);
330 const Sequence< const DiscreteVariable* >& seq2 = *(tables[tj]);
334 for (
const auto var : seq1) {
335 new_size *= var->domainSize();
336 new_seq->insert(var);
339 for (
const auto var : seq2)
340 if (!seq1.exists(var)) {
341 new_size *= var->domainSize();
342 new_seq->insert(var);
349 if (tables[ti] && is_t_new[ti])
delete tables[ti];
351 if (tables[tj] && is_t_new[tj])
delete tables[tj];
353 tables[ti] = new_seq;
360 for (
Idx ind = 0; ind < tj; ++ind) {
369 for (
Idx ind = tj + 1; ind < tables.size(); ++ind) {
381 for (
Idx ind = 0; ind < ti; ++ind) {
385 queue.setPriority(pair, newsize);
391 for (
Idx ind = ti + 1; ind < tables.size(); ++ind) {
395 queue.setPriority(pair, newsize);
414 template <
typename GUM_SCALAR >
416 const Set<
const MultiDimImplementation< GUM_SCALAR >* >&
set,
417 const Schedule< GUM_SCALAR >& schedule) {
422 template <
typename GUM_SCALAR >
423 template <
template <
typename >
class TABLE >
425 const Set<
const TABLE< GUM_SCALAR >* >&
set,
426 const Schedule< GUM_SCALAR >& schedule) {
431 template <
typename GUM_SCALAR >
433 const Set<
const ScheduleMultiDim< GUM_SCALAR >* >&
set,
434 const Schedule< GUM_SCALAR >& schedule) {
436 if (
set.size() < 2)
return std::pair< long, long >(0, 0);
439 long current_memory = 0;
442 std::vector< const Sequence< const DiscreteVariable* >* > tables(
set.size());
443 std::vector< Size > table_size(
set.size());
448 for (
const auto tab :
set) {
449 tables[i] = &(tab->variablesSequence());
452 for (
const auto var : tab->variablesSequence())
453 size *= var->domainSize();
455 table_size[i] = size;
465 std::vector< bool > is_t_new(tables.size(),
false);
470 std::pair< Idx, Idx > pair;
472 PriorityQueue< std::pair< Idx, Idx >,
Size > queue;
474 for (
Idx i = 0; i < tables.size(); ++i) {
477 for (
Idx j = i + 1; j < tables.size(); ++j) {
479 queue.insert(pair,
_combinedSize(*(tables[i]), *(tables[j])));
488 for (
Idx k = 1; k < tables.size(); ++k) {
492 Idx tj = pair.second;
495 Sequence< const DiscreteVariable* >* new_seq =
496 new Sequence< const DiscreteVariable* >;
497 const Sequence< const DiscreteVariable* >& seq1 = *(tables[ti]);
498 const Sequence< const DiscreteVariable* >& seq2 = *(tables[tj]);
502 for (
const auto var : seq1) {
503 if (std::numeric_limits< long >::max() / (long)var->domainSize()
505 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
507 new_size *= long(var->domainSize());
508 new_seq->insert(var);
511 for (
const auto var : seq2) {
512 if (!seq1.exists(var)) {
513 if (std::numeric_limits< long >::max() / (long)var->domainSize()
515 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
517 new_size *= long(var->domainSize());
518 new_seq->insert(var);
522 if (std::numeric_limits< long >::max() - current_memory < new_size) {
523 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
526 current_memory += new_size;
528 if (current_memory > max_memory) { max_memory = current_memory; }
531 if (tables[ti] && is_t_new[ti]) {
533 current_memory -= long(table_size[ti]);
536 if (tables[tj] && is_t_new[tj]) {
538 current_memory -= long(table_size[tj]);
541 tables[ti] = new_seq;
543 table_size[ti] = new_size;
549 for (
Idx ind = 0; ind < tj; ++ind) {
558 for (
Idx ind = tj + 1; ind < tables.size(); ++ind) {
570 for (
Idx ind = 0; ind < ti; ++ind) {
574 queue.setPriority(pair, newsize);
580 for (
Idx ind = ti + 1; ind < tables.size(); ++ind) {
584 queue.setPriority(pair, newsize);
599 return std::pair< long, long >(max_memory, current_memory);
603 template <
typename GUM_SCALAR >
604 INLINE std::pair< long, long >
606 const Set<
const MultiDimImplementation< GUM_SCALAR >* >&
set,
607 const Schedule< GUM_SCALAR >& schedule) {
612 template <
typename GUM_SCALAR >
613 template <
template <
typename >
class TABLE >
614 INLINE std::pair< long, long >
616 const Set<
const TABLE< GUM_SCALAR >* >&
set,
617 const Schedule< GUM_SCALAR >& schedule) {
virtual float nbOperations(const Set< const ScheduleMultiDim< GUM_SCALAR > * > &set, const Schedule< GUM_SCALAR > &schedule)=0
returns a rough estimate of the number of operations that will be performed to compute the combinatio...
ScheduleCombination()
default constructor
A class to combine efficiently several ScheduleMultiDims.
virtual ~ScheduleCombinationBasic()
destructor
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
virtual float nbOperations(const Set< const ScheduleMultiDim< GUM_SCALAR > * > &set, const Schedule< GUM_SCALAR > &schedule)
returns a rough estimate of the number of operations that will be performed to compute the combinatio...
Size _combinedSize(const Sequence< const DiscreteVariable * > &seq1, const Sequence< const DiscreteVariable * > &seq2) const
returns the domain size of the Cartesian product of the union of all the variables in seq1 and seq2 ...
virtual ScheduleCombinationBasic< GUM_SCALAR > * newFactory() const
virtual constructor
virtual std::pair< long, long > memoryUsage(const Set< const ScheduleMultiDim< GUM_SCALAR > * > &set, const Schedule< GUM_SCALAR > &schedule)=0
returns the memory consumption used during the combination
virtual ScheduleMultiDim< GUM_SCALAR > combine(const Set< const ScheduleMultiDim< GUM_SCALAR > * > &set, Schedule< GUM_SCALAR > &schedule)=0
gum is the global namespace for all aGrUM entities
virtual MultiDimImplementation< GUM_SCALAR > *(*)(const MultiDimImplementation< GUM_SCALAR > &, const MultiDimImplementation< GUM_SCALAR > &) combineFunction()
returns the combination function currently used by the combinator
virtual std::pair< long, long > memoryUsage(const Set< const ScheduleMultiDim< GUM_SCALAR > * > &set, const Schedule< GUM_SCALAR > &schedule)
returns the memory consumption used during the combination
ScheduleCombinationBasic(MultiDimImplementation< GUM_SCALAR > *(*combine)(const MultiDimImplementation< GUM_SCALAR > &, const MultiDimImplementation< GUM_SCALAR > &))
default constructor
MultiDimImplementation< GUM_SCALAR > *(* _combine)(const MultiDimImplementation< GUM_SCALAR > &t1, const MultiDimImplementation< GUM_SCALAR > &t2)
the function used to combine two tables
virtual ScheduleMultiDim< GUM_SCALAR > combine(const Set< const ScheduleMultiDim< GUM_SCALAR > * > &set, Schedule< GUM_SCALAR > &)
virtual void setCombineFunction(MultiDimImplementation< GUM_SCALAR > *(*combine)(const MultiDimImplementation< GUM_SCALAR > &, const MultiDimImplementation< GUM_SCALAR > &))
changes the function used for combining two TABLES
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Size NodeId
Type for node ids.
#define GUM_ERROR(type, msg)