52#ifndef DOXYGEN_SHOULD_SKIP_THIS
64 template <
class TABLE >
68 GUM_CONSTRUCTOR(MultiDimCombinationDefault);
72 template <
class TABLE >
73 MultiDimCombinationDefault< TABLE >::MultiDimCombinationDefault(
74 const MultiDimCombinationDefault< TABLE >& from) :
75 MultiDimCombination< TABLE >(), _combine_(from._combine_) {
77 GUM_CONS_CPY(MultiDimCombinationDefault);
81 template <
class TABLE >
82 MultiDimCombinationDefault< TABLE >::~MultiDimCombinationDefault() {
84 GUM_DESTRUCTOR(MultiDimCombinationDefault);
88 template <
class TABLE >
89 MultiDimCombinationDefault< TABLE >* MultiDimCombinationDefault< TABLE >::clone()
const {
90 return new MultiDimCombinationDefault< TABLE >(_combine_);
94 template <
class TABLE >
95 void MultiDimCombinationDefault< TABLE >::setCombinationFunction(TABLE (*combine)(
const TABLE&,
101 template <
class TABLE >
102 TABLE (*MultiDimCombinationDefault< TABLE >::combinationFunction())(
const TABLE&,
const TABLE&) {
107 template <
class TABLE >
108 void MultiDimCombinationDefault< TABLE >::execute(TABLE& container,
109 const Set< const TABLE* >& set)
const {
110 TABLE* res = execute(set);
111 container = std::move(*res);
116 template <
class TABLE >
117 TABLE* MultiDimCombinationDefault< TABLE >::execute(
const Set< const TABLE* >& set)
const {
119 if (set.size() < 2) {
121 "the set passed to a MultiDimCombinationDefault"
122 " should at least contain two elements");
126 std::vector< const IScheduleMultiDim* > tables;
127 tables.reserve(set.size());
128 for (
const auto table: set) {
129 tables.push_back(
new ScheduleMultiDim< TABLE >(*table,
false));
133 auto ops_plus_res = operations(tables);
134 for (
auto op: ops_plus_res.first) {
139 auto& schedule_result =
const_cast< ScheduleMultiDim< TABLE >&
>(
140 static_cast< const ScheduleMultiDim< TABLE >&
>(*ops_plus_res.second));
144 auto result = schedule_result.exportMultiDim();
147 _freeData_(tables, ops_plus_res.first);
153 template <
class TABLE >
154 double MultiDimCombinationDefault< TABLE >::nbOperations(
155 const Set<
const Sequence< const DiscreteVariable* >* >& set)
const {
157 if (set.size() < 2)
return 0.0;
160 std::vector< const IScheduleMultiDim* > tables;
161 tables.reserve(set.size());
162 for (
const auto ptrVars: set) {
163 tables.push_back(
new ScheduleMultiDim< TABLE >(*ptrVars));
167 auto ops_plus_res = operations(tables);
168 double nb_operations = 0.0;
169 for (
const auto op: ops_plus_res.first) {
170 nb_operations += op->nbOperations();
174 _freeData_(tables, ops_plus_res.first);
176 return nb_operations;
180 template <
class TABLE >
181 double MultiDimCombinationDefault< TABLE >::nbOperations(
const Set< const TABLE* >& set)
const {
183 if (set.size() < 2)
return 0.0;
186 Set< const Sequence< const DiscreteVariable* >* > var_set(set.size());
188 for (
const auto ptrTab: set) {
189 var_set << &(ptrTab->variablesSequence());
192 return nbOperations(var_set);
196 template <
class TABLE >
197 std::pair< double, double > MultiDimCombinationDefault< TABLE >::memoryUsage(
198 const Set<
const Sequence< const DiscreteVariable* >* >& set)
const {
200 if (set.size() < 2)
return {0.0, 0.0};
203 std::vector< const IScheduleMultiDim* > tables;
204 tables.reserve(set.size());
205 for (
const auto ptrVars: set) {
206 tables.push_back(
new ScheduleMultiDim< TABLE >(*ptrVars));
210 auto ops_plus_res = operations(tables);
212 double max_memory = 0.0;
213 double end_memory = 0.0;
215 for (
const auto op: ops_plus_res.first) {
216 const auto usage = op->memoryUsage();
217 if (end_memory + usage.first > max_memory) max_memory = end_memory + usage.first;
218 end_memory += usage.second;
222 _freeData_(tables, ops_plus_res.first);
224 return {max_memory, end_memory};
228 template <
class TABLE >
229 std::pair< double, double >
230 MultiDimCombinationDefault< TABLE >::memoryUsage(
const Set< const TABLE* >& set)
const {
232 if (set.size() < 2)
return {0.0, 0.0};
235 Set< const Sequence< const DiscreteVariable* >* > var_set(set.size());
237 for (
const auto ptrTab: set) {
238 var_set << &(ptrTab->variablesSequence());
241 return memoryUsage(var_set);
246 template <
class TABLE >
248 MultiDimCombinationDefault< TABLE >::_combinedSize_(
const IScheduleMultiDim& table1,
249 const IScheduleMultiDim& table2)
const {
250 auto size =
double(table1.domainSize());
251 const auto& vars1 = table1.variablesSequence();
252 const auto& vars2 = table2.variablesSequence();
253 for (
const auto ptrVar: vars2)
254 if (!vars1.exists(ptrVar)) size *=
double(ptrVar->domainSize());
260 template <
class TABLE >
261 std::pair< std::vector< ScheduleOperator* >,
const IScheduleMultiDim* >
262 MultiDimCombinationDefault< TABLE >::operations(
263 const std::vector< const IScheduleMultiDim* >& original_tables,
264 const bool is_result_persistent)
const {
266 const Size tabsize = original_tables.size();
267 if (tabsize < 2)
return {};
271 std::vector< const IScheduleMultiDim* > tables = original_tables;
274 std::vector< ScheduleOperator* > operations;
275 operations.reserve(2 * tables.size());
281 std::vector< bool > is_t_new(tabsize,
false);
286 std::pair< Size, Size > pair;
287 PriorityQueue< std::pair< Size, Size >,
double > queue;
289 for (Size i = Size(0); i < tabsize; ++i) {
292 for (Size j = i + 1; j < tabsize; ++j) {
294 queue.insert(pair, _combinedSize_(*tables[i], *tables[j]));
300 const IScheduleMultiDim* resulting_table =
nullptr;
301 ScheduleOperator* resulting_op =
nullptr;
307 for (Size k = 1; k < tabsize; ++k) {
310 const Size ti = pair.first;
311 const Size tj = pair.second;
314 auto combination =
new ScheduleBinaryCombination< TABLE, TABLE, TABLE >(
315 static_cast< const ScheduleMultiDim< TABLE >&
>(*tables[ti]),
316 static_cast< const ScheduleMultiDim< TABLE >&
>(*tables[tj]),
318 operations.push_back(combination);
319 resulting_table = &combination->result();
320 resulting_op = combination;
324 auto deletion =
new ScheduleDeletion< TABLE >(
325 static_cast< const ScheduleMultiDim< TABLE >&
>(*tables[ti]));
326 operations.push_back(deletion);
329 auto deletion =
new ScheduleDeletion< TABLE >(
330 static_cast< const ScheduleMultiDim< TABLE >&
>(*tables[tj]));
331 operations.push_back(deletion);
335 tables[ti] = resulting_table;
337 tables[tj] =
nullptr;
340 for (Size ind = 0; ind < tj; ++ind) {
341 if (tables[ind] !=
nullptr) {
348 for (Size ind = tj + 1; ind < tabsize; ++ind) {
349 if (tables[ind] !=
nullptr) {
358 for (Size ind = 0; ind < ti; ++ind) {
359 if (tables[ind] !=
nullptr) {
361 queue.setPriority(pair, _combinedSize_(*resulting_table, *(tables[ind])));
366 for (Size ind = ti + 1; ind < tabsize; ++ind) {
367 if (tables[ind] !=
nullptr) {
369 queue.setPriority(pair, _combinedSize_(*resulting_table, *(tables[ind])));
376 if (is_result_persistent) { resulting_op->makeResultsPersistent(
true); }
378 return {operations, resulting_table};
382 template <
class TABLE >
383 std::pair< std::vector< ScheduleOperator* >,
const IScheduleMultiDim* >
384 MultiDimCombinationDefault< TABLE >::operations(
const Set< const IScheduleMultiDim* >& set,
385 const bool is_result_persistent)
const {
386 std::vector< const IScheduleMultiDim* > vect;
387 vect.reserve(set.size());
388 for (
const auto elt: set) {
391 return operations(vect, is_result_persistent);
395 template <
class TABLE >
396 void MultiDimCombinationDefault< TABLE >::_freeData_(
397 std::vector< const IScheduleMultiDim* >& tables,
398 std::vector< ScheduleOperator* >& operations)
const {
399 for (
auto op: operations)
402 for (
auto table: tables)
Exception: the number of arguments passed to a function is not what was expected.
MultiDimCombinationDefault(TABLE(*combine)(const TABLE &, const TABLE &))
Default constructor.
A generic interface to combine efficiently several MultiDim tables.
#define GUM_ERROR(type, msg)
gum is the global namespace for all aGrUM entities
priority queues (in which an element cannot appear more than once)