29 #ifndef DOXYGEN_SHOULD_SKIP_THIS 39 template <
typename GUM_SCALAR >
41 MultiDimImplementation< GUM_SCALAR >* (*combine)(
42 const MultiDimImplementation< GUM_SCALAR >&,
43 const MultiDimImplementation< GUM_SCALAR >&)) :
44 ScheduleCombination< GUM_SCALAR >(),
51 template <
typename GUM_SCALAR >
53 const ScheduleCombinationBasic< GUM_SCALAR >& from) :
61 template <
typename GUM_SCALAR >
68 template <
typename GUM_SCALAR >
69 ScheduleCombinationBasic< GUM_SCALAR >*
71 return new ScheduleCombinationBasic< GUM_SCALAR >(*this);
75 template <
typename GUM_SCALAR >
77 MultiDimImplementation< GUM_SCALAR >* (*
combine)(
78 const MultiDimImplementation< GUM_SCALAR >&,
79 const MultiDimImplementation< GUM_SCALAR >&)) {
84 template <
typename GUM_SCALAR >
85 MultiDimImplementation< GUM_SCALAR >* (
87 const MultiDimImplementation< GUM_SCALAR >&,
88 const MultiDimImplementation< GUM_SCALAR >&) {
94 template <
typename GUM_SCALAR >
96 const Sequence< const DiscreteVariable* >& seq1,
97 const Sequence< const DiscreteVariable* >& seq2)
const {
98 if (seq1.empty() && seq2.empty())
return 0;
102 for (
const auto var : seq1)
103 size *= var->domainSize();
105 for (
const auto var : seq2)
106 if (!seq1.exists(var)) size *= var->domainSize();
112 template <
typename GUM_SCALAR >
114 const Set<
const ScheduleMultiDim< GUM_SCALAR >* >&
set,
115 Schedule< GUM_SCALAR >& schedule) {
117 if (
set.size() < 2) {
119 "the set passed to a ScheduleCombinationBasic" 120 " should at least contain two elements");
124 std::vector< const ScheduleMultiDim< GUM_SCALAR >* > tables(
set.size());
129 for (
const auto sched :
set) {
139 std::vector< bool > is_t_new(tables.size(),
false);
144 std::pair< Idx, Idx > pair;
146 PriorityQueue< std::pair< Idx, Idx >,
Size > queue;
148 for (
Idx i = 0; i < tables.size(); ++i) {
150 const Sequence< const DiscreteVariable* >& seq1 =
151 tables[i]->variablesSequence();
153 for (
Idx j = i + 1; j < tables.size(); ++j) {
155 queue.insert(pair,
_combinedSize(seq1, tables[j]->variablesSequence()));
165 for (
Idx k = 1; k < tables.size(); ++k) {
169 Idx tj = pair.second;
173 ScheduleCombine< GUM_SCALAR > comb(*(tables[ti]), *(tables[tj]),
_combine);
174 NodeId comb_id = schedule.insert(comb);
179 if (tables[ti] && is_t_new[ti]) {
180 ScheduleDeleteMultiDim< GUM_SCALAR > del(*(tables[ti]));
181 NodeId del_id = schedule.insert(del);
182 const NodeSet& set_i = schedule.operationsInvolving(*(tables[ti]));
183 schedule.forceAfter(del_id, set_i);
186 if (tables[tj] && is_t_new[tj]) {
187 ScheduleDeleteMultiDim< GUM_SCALAR > del(*(tables[tj]));
188 NodeId del_id = schedule.insert(del);
189 const NodeSet& set_j = schedule.operationsInvolving(*(tables[tj]));
190 schedule.forceAfter(del_id, set_j);
193 tables[ti] = &(
static_cast< const ScheduleCombine< GUM_SCALAR >&
> 195 (schedule.operation(comb_id))
202 for (
Idx ind = 0; ind < tj; ++ind) {
211 for (
Idx ind = tj + 1; ind < tables.size(); ++ind) {
220 const Sequence< const DiscreteVariable* >& seq1 =
221 tables[ti]->variablesSequence();
225 for (
Idx ind = 0; ind < ti; ++ind) {
228 newsize =
_combinedSize(seq1, tables[ind]->variablesSequence());
229 queue.setPriority(pair, newsize);
235 for (
Idx ind = ti + 1; ind < tables.size(); ++ind) {
238 newsize =
_combinedSize(seq1, tables[ind]->variablesSequence());
239 queue.setPriority(pair, newsize);
256 template <
typename GUM_SCALAR >
257 INLINE ScheduleMultiDim< GUM_SCALAR >
259 const Set<
const MultiDimImplementation< GUM_SCALAR >* >&
set,
260 Schedule< GUM_SCALAR >& schedule) {
265 template <
typename GUM_SCALAR >
266 template <
template <
typename >
class TABLE >
267 INLINE ScheduleMultiDim< GUM_SCALAR >
269 const Set<
const TABLE< GUM_SCALAR >* >&
set,
270 Schedule< GUM_SCALAR >& schedule) {
275 template <
typename GUM_SCALAR >
277 const Set<
const ScheduleMultiDim< GUM_SCALAR >* >&
set,
278 const Schedule< GUM_SCALAR >& schedule) {
280 if (
set.size() < 2)
return 0.0f;
285 std::vector< const Sequence< const DiscreteVariable* >* > tables(
set.size());
290 for (
const auto sched :
set) {
291 tables[i] = &(sched->variablesSequence());
301 std::vector< bool > is_t_new(tables.size(),
false);
306 std::pair< Idx, Idx > pair;
307 PriorityQueue< std::pair< Idx, Idx >,
Size > queue;
309 for (
Idx i = 0; i < tables.size(); ++i) {
312 for (
Idx j = i + 1; j < tables.size(); ++j) {
314 queue.insert(pair,
_combinedSize(*(tables[i]), *(tables[j])));
323 for (
Idx k = 1; k < tables.size(); ++k) {
327 Idx tj = pair.second;
330 Sequence< const DiscreteVariable* >* new_seq =
331 new Sequence< const DiscreteVariable* >;
332 const Sequence< const DiscreteVariable* >& seq1 = *(tables[ti]);
333 const Sequence< const DiscreteVariable* >& seq2 = *(tables[tj]);
337 for (
const auto var : seq1) {
338 new_size *= var->domainSize();
339 new_seq->insert(var);
342 for (
const auto var : seq2)
343 if (!seq1.exists(var)) {
344 new_size *= var->domainSize();
345 new_seq->insert(var);
352 if (tables[ti] && is_t_new[ti])
delete tables[ti];
354 if (tables[tj] && is_t_new[tj])
delete tables[tj];
356 tables[ti] = new_seq;
363 for (
Idx ind = 0; ind < tj; ++ind) {
372 for (
Idx ind = tj + 1; ind < tables.size(); ++ind) {
384 for (
Idx ind = 0; ind < ti; ++ind) {
388 queue.setPriority(pair, newsize);
394 for (
Idx ind = ti + 1; ind < tables.size(); ++ind) {
398 queue.setPriority(pair, newsize);
417 template <
typename GUM_SCALAR >
419 const Set<
const MultiDimImplementation< GUM_SCALAR >* >&
set,
420 const Schedule< GUM_SCALAR >& schedule) {
425 template <
typename GUM_SCALAR >
426 template <
template <
typename >
class TABLE >
428 const Set<
const TABLE< GUM_SCALAR >* >&
set,
429 const Schedule< GUM_SCALAR >& schedule) {
434 template <
typename GUM_SCALAR >
436 const Set<
const ScheduleMultiDim< GUM_SCALAR >* >&
set,
437 const Schedule< GUM_SCALAR >& schedule) {
439 if (
set.size() < 2)
return std::pair< long, long >(0, 0);
442 long current_memory = 0;
445 std::vector< const Sequence< const DiscreteVariable* >* > tables(
set.size());
446 std::vector< Size > table_size(
set.size());
451 for (
const auto tab :
set) {
452 tables[i] = &(tab->variablesSequence());
455 for (
const auto var : tab->variablesSequence())
456 size *= var->domainSize();
458 table_size[i] = size;
468 std::vector< bool > is_t_new(tables.size(),
false);
473 std::pair< Idx, Idx > pair;
475 PriorityQueue< std::pair< Idx, Idx >,
Size > queue;
477 for (
Idx i = 0; i < tables.size(); ++i) {
480 for (
Idx j = i + 1; j < tables.size(); ++j) {
482 queue.insert(pair,
_combinedSize(*(tables[i]), *(tables[j])));
491 for (
Idx k = 1; k < tables.size(); ++k) {
495 Idx tj = pair.second;
498 Sequence< const DiscreteVariable* >* new_seq =
499 new Sequence< const DiscreteVariable* >;
500 const Sequence< const DiscreteVariable* >& seq1 = *(tables[ti]);
501 const Sequence< const DiscreteVariable* >& seq2 = *(tables[tj]);
505 for (
const auto var : seq1) {
506 if (std::numeric_limits< long >::max() / (long)var->domainSize()
508 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
510 new_size *= long(var->domainSize());
511 new_seq->insert(var);
514 for (
const auto var : seq2) {
515 if (!seq1.exists(var)) {
516 if (std::numeric_limits< long >::max() / (long)var->domainSize()
518 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
520 new_size *= long(var->domainSize());
521 new_seq->insert(var);
525 if (std::numeric_limits< long >::max() - current_memory < new_size) {
526 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
529 current_memory += new_size;
531 if (current_memory > max_memory) { max_memory = current_memory; }
534 if (tables[ti] && is_t_new[ti]) {
536 current_memory -= long(table_size[ti]);
539 if (tables[tj] && is_t_new[tj]) {
541 current_memory -= long(table_size[tj]);
544 tables[ti] = new_seq;
546 table_size[ti] = new_size;
552 for (
Idx ind = 0; ind < tj; ++ind) {
561 for (
Idx ind = tj + 1; ind < tables.size(); ++ind) {
573 for (
Idx ind = 0; ind < ti; ++ind) {
577 queue.setPriority(pair, newsize);
583 for (
Idx ind = ti + 1; ind < tables.size(); ++ind) {
587 queue.setPriority(pair, newsize);
602 return std::pair< long, long >(max_memory, current_memory);
606 template <
typename GUM_SCALAR >
607 INLINE std::pair< long, long >
609 const Set<
const MultiDimImplementation< GUM_SCALAR >* >&
set,
610 const Schedule< GUM_SCALAR >& schedule) {
615 template <
typename GUM_SCALAR >
616 template <
template <
typename >
class TABLE >
617 INLINE std::pair< long, long >
619 const Set<
const TABLE< GUM_SCALAR >* >&
set,
620 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
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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)