SUNphi  1.0
Partitioner.hpp
Go to the documentation of this file.
1 #ifndef _PARTITIONER_HPP
2 #define _PARTITIONER_HPP
3 
4 /// \file Partitioner.hpp
5 ///
6 /// \brief Split a grid into subgrids
7 
8 #include <functional>
9 #include <set>
10 
11 #include <lattice/Grid.hpp>
12 
13 #include <debug/Warning.hpp>
14 #include <math/Partition.hpp>
15 #include <metaprogramming/UniversalReferences.hpp>
16 
17 namespace SUNphi
18 {
19  /// A generic grid to type-erase the actual grid
20  ///
21  /// While looping on all possible realization of a grid, there is
22  /// little point in keeping updated the hash-table and other
23  /// features of the target grid. We make a dedicated, simplified
24  /// version of the grid, and work with it. We could make the Grid
25  /// a dynamic polymorhic class but this way we risk to introduce
26  /// severe performances degradation when calling any method
27  /// (e.g. neighbors search)
28  template <int NDims, // Number of dimensions
29  typename Coord, // Type of coordinate values
30  typename Idx> // Type of index of points
31  class ShadowGrid
32  {
34 
35  /// Volume of the grid, stored as optional value
36  ///
37  /// Storing as optional allows to check if the value is set or not
38  /// in a coincise way
39  std::optional<Vol> mutable volume;
40 
41  /// Sdes of the grid
42  std::optional<Coords> mutable sides;
43 
44  public:
45 
46  /// Reference to the actual grid
47  const void* actualGrid;
48 
49  /// Unset the volume
50  void unSetVol()
51  const
52  {
53  volume.reset();
54  }
55 
56  /// Unset the sides
57  void unSetSides()
58  const
59  {
60  sides.reset();
61  }
62 
63  /// Set the volume to \c v
64  bool setVol(const Vol& v)
65  const
66  {
67  if(volIsSet() and volume!=v)
68  return
69  false;
70  else
71  {
72  volume=
73  v;
74 
75  return
76  true;
77  }
78  }
79 
80  /// Set the sides to \c s
81  bool setSides(const Sides& s)
82  const
83  {
84  if(sidesAreSet() and sides!=s)
85  return
86  false;
87  else
88  {
89  sides=
90  s;
91 
93 
94  return
95  true;
96  }
97  }
98 
99  /// Get the volume
100  const Vol& getVol()
101  const
102  {
103  return
104  volume.value();
105  }
106 
107  /// Get the sides
108  const Sides& getSides()
109  const
110  {
111  return
112  sides.value();
113  }
114 
115  /// Get a given side
116  const Side& getSide(int mu)
117  const
118  {
119  return
120  getSides()[mu];
121  }
122 
123  /// Get the volume from sides
124  const Vol getVolFromSides()
125  const
126  {
127  /// Returned value
128  Vol v=
129  1;
130 
131  for(int mu=0;mu<getSides().size();mu++)
132  v*=
133  getSide(mu);
134 
135  return
136  v;
137  }
138 
139  /// Name for debug purpose
140  const char* name;
141 
142  /// Function to invocate setting the sides of the actual grid
143  const std::function<void(const Sides&)> setSidesOfActualGrid;
144 
145  /// Check if the volume is set
146  bool volIsSet()
147  const
148  {
149  return
150  static_cast<bool>(volume);
151  }
152 
153  /// Check if the sides are set
154  bool sidesAreSet()
155  const
156  {
157  return
158  static_cast<bool>(sides);
159  }
160 
161  /// Constructor taking the grid and type-erasing it
162  template <typename G>
163  ShadowGrid(G&& actualGrid,
164  const char* name) :
165  actualGrid(&actualGrid),
166  name(name),
168  {
170  })
171  {
172  /// Reads the sides
173  bool actualGridHasSetVolume=
174  true;
175 
176  actualGrid.forAllDims([&](int mu)
177  {
178  actualGridHasSetVolume&=
179  (actualGrid.side(mu)!=0);
180  });
181 
182  if(actualGridHasSetVolume)
183  setSides(actualGrid.sides());
184  else
185  {
186  /// Reads the volume
187  const auto actualVolume=
188  actualGrid.volume();
189 
190  if(actualVolume)
191  setVol(actualVolume);
192  }
193  }
194 
195  /// Comparison operator
196  bool operator<(const ShadowGrid& oth)
197  const
198  {
199  return
200  actualGrid<oth.actualGrid;
201  }
202  };
203 
204  /// Type to describe a partition relation between grid to be partitioned
205  template <int NDims, // Number of dimensions
206  typename Coord, // Type of coordinate values
207  typename Idx> // Type of index of points
209  {
210  public:
211 
212  /// Short alias of the ShadowGrid
213  using SGrid=
214  ShadowGrid<NDims,Coord,Idx>;
215 
216  /// List of relatives
217  std::array<const SGrid*,3> relatives;
218 
219  /// Position of father, child1 and child2 in the list of relatives
220  enum{FATHER,CHILD1,CHILD2,NO_RELATIVE};
221 
222  /// Pointer to the grid to be partitioned
223  const SGrid*& father=
224  relatives[FATHER];
225 
226  /// Pointer to the dividing grid
227  const SGrid*& child1=
228  relatives[CHILD1];
229 
230  /// Pointer to the divisor grid
231  const SGrid*& child2=
232  relatives[CHILD2];
233 
234  /// Returns whether we can deduce something:
235  ///
236  /// - father and child1 is set, so child2 can be deduced
237  /// - father and child2 is set, so child1 can be deduced
238  /// - child1 and child2 is set, so father can be deduced
240  const
241  {
242  /// Take trace of the last relative not fixed
243  int lastNotFixedRel=
244  NO_RELATIVE;
245 
246  /// Count how many relatives are fixed
247  int nFixed=
248  0;
249 
250  for(int iRel=0;iRel<3;iRel++)
251  if(relatives[iRel]->volIsSet())
252  nFixed++;
253  else
254  lastNotFixedRel=
255  iRel;
256 
257  if(nFixed==2)
258  return
259  lastNotFixedRel;
260  else
261  return
262  NO_RELATIVE;
263  }
264 
265  /// Constructor
266  PartitioningRelation(const SGrid* father,
267  const SGrid* child1,
268  const SGrid* child2)
269  : relatives{father,child1,child2}
270  {
271  if(&father==&child1)
272  CRASH<<"Father "<<father->name<<" must be different from child1 "<<child1->name;
273 
274  if(&father==&child2)
275  CRASH<<"Father "<<father->name<<" must be different from child2 "<<child2->name;
276 
277  if(&child1==&child2)
278  CRASH<<"Child1 "<<child1->name<<" must be different from child2 "<<child2->name;
279  }
280 
281  /// Comparison operator
283  const
284  {
285  return
287  }
288  };
289 
290  /// A program made of a set of pair of instructions
292  {
293  /// Action to be performed in the list
294  using Action=
295  std::function<bool(void)>;
296 
297  /// Pair of actions to be performed forward or backward
298  using Move=
300 
301  /// List of instrcutions to be executed
303 
304  /// Data used for loops
305  Vector<int> data;
306 
307  public:
308 
309  /// Adds an instruction into the program
310  void add(Action&& fw, ///< Instruction to be executed when advancing
311  Action&& bw) ///< Instruction to be exectued when rewinding
312  {
313  instructions.emplace_back(fw,bw);
314  }
315 
316  /// Runs the program
317  void exec()
318  {
319  /// Index of the current instruction
320  int i=
321  0;
322 
323  /// Current direction of motion
324  BACK_FORW dir=
325  FORW;
326 
327  do
328  {
329  RUNLOG<<"Instruction "<<i;
330 
332 
333  if(dir==FORW)
334  {
335  RUNLOG<<"Moving forward";
336 
338 
339  if(instructions[i].second())
340  {
341  RUNLOG<<"Success, moving to next instruction";
342 
343  i++;
344 
345  if(i==instructions.size())
346  {
347  RUNLOG<<"Arrived to the end of the program, rewinding";
348 
349  i--;
350 
351  dir=
352  BACK;
353  }
354  }
355  else
356  {
357  RUNLOG<<"Failed, reverting move backward";
358 
359  dir=
360  BACK;
361  }
362  }
363  else
364  {
365  RUNLOG<<"Moving backward";
366 
368 
369  if(instructions[i].first())
370  {
371  RUNLOG<<"Success, reverting move forward";
372 
373  dir=
374  FORW;
375  }
376  else
377  {
378  RUNLOG<<"Failed, moving to previous instruction";
379 
380  i--;
381  }
382  }
383  }
384  while(i>=0);
385  }
386  };
387 
388  /// Partition a set of grids enforcing to obay to certain rules
389  template <int NDims=4, // Number of dimensions
390  typename Coord=int32_t, // Type of coordinate values
391  typename Idx=int64_t> // Type of index of points
393  {
395 
396  /// Short alias for a Partition relation
397  using PartRel=
398  PartitioningRelation<NDims,Coord,Idx>;
399 
400  /// Short alias of the ShadowGrid
401  using SGrid=
402  ShadowGrid<NDims,Coord,Idx>;
403 
404  /// Instruction to be exectuted
405  using Instruction=
406  std::function<void(void)>;
407 
408  /// List of relation to be satisfied between all the grid to be partitioned
410 
411  /// List of grids to be partitioned
413 
414  /// Find the shadow of an actual grid
415  template <typename G>
416  const SGrid* findShadowOfGrid(G&& actualGrid)
417  const
418  {
419  /// Result of research
420  auto res=
421  std::find_if(grids.begin(),grids.end(),[&actualGrid](const SGrid& grid){return grid.actualGrid==&actualGrid;});
422 
423  if(res!=grids.end())
424  return
425  &*res;
426  else
427  return
428  nullptr;
429  }
430 
431  /// Pretend to set a volume for a grid
432  void pretendToSetVol(const SGrid* grid,
434  {
435  /// Dummy volue to set
437  0;
438 
439  grid->setVol(dummyVol);
441  }
442 
443  public:
444 
445  /// Determines if the volume has an upper bound coming from direct
446  /// fathers or if the volume is set
447  bool volIsBound(const SGrid* grid)
448  const
449  {
450  if(grid->volIsSet())
451  return
452  true;
453 
454  for(auto& father : this->getAllFathersOf(grid))
455  if(father->volIsSet())
456  return
457  true;
458 
459  return
460  false;
461  }
462 
463  /// Adds a grid to the list of grids to be partitioned
464  template <typename G>
465  const SGrid* addGrid(G&& grid,
466  const char* name)
467  {
468  return
470  }
471 
472  /// Adds a partition relation
473  template <typename GF,
474  typename GC1,
475  typename GC2>
477  GC1&& child1,
478  GC2&& child2)
479  {
480  /// Find father
481  const SGrid* sFather=
483 
484  /// Find child1
485  const SGrid* sChild1=
487 
488  /// Find child2
489  const SGrid* sChild2=
491 
492  if(sFather==nullptr)
493  CRASH<<"Father not found";
494 
495  if(sChild1==nullptr)
496  CRASH<<"Child1 not found";
497 
498  if(sChild2==nullptr)
499  CRASH<<"Child2 not found";
500 
501  return
503  }
504 
505  /// Gets the list of fathers to be checked
507  const
508  {
509  /// Returned list
511 
512  for(auto& father : this->getAllFathersOf(grid))
513  if(father->volIsSet())
515 
516  return
518  }
519 
520  /// Gets the list of children to be checked
522  const
523  {
524  /// Returned list
526 
527  for(auto& childPair : this->getAllChildrenOf(grid))
528  for(auto& child : {childPair.first,childPair.second})
529  if(child->volIsSet())
530  {
531  RUNLOG<<child->name<<" volume is set, will need to be checked";
532 
534  }
535 
536  return
538  }
539 
540  /// Returns a function which check the validity of a grid and move to next instruction
541  auto getGridChecker(const SGrid* grid)
542  const
543  {
545  RUNLOG<<"Creating the checker for "<<grid->name;
546 
547  return
548  [grid,
551  {
553  RUNLOG<<"Checking grid "<<grid->name;
554 
555  /// Current grid volume
556  const Vol& vol=
557  grid->getVol();
558 
559  /// Keep track if constraints are satisfied
560  bool isOk=
561  true;
562 
563  /// Looping on fathers
564  auto father=
566 
567  while(isOk and father!=fathersToBeChecked.end())
568  {
569  /// Volume of father
570  const auto fatherVol=
571  (*father)->getVol();
572 
573  isOk&=
574  (fatherVol%vol==0);
575 
576  RUNLOG<<"Father "<<(*father)->name<<" has volume "<<fatherVol<<(isOk?" ":" not")<<" divisible by his child "<<grid->name<<" "<<vol;
577 
578  father++;
579  }
580 
581  /// Looping on children
582  auto child=
584 
585  while(isOk and child!=childrenToBeChecked.end())
586  {
587  /// Volume of child
588  const auto childVol=
589  (*child)->getVol();
590 
591  isOk&=
592  (vol%childVol==0);
593 
594  RUNLOG<<"Child "<<(*child)->name<<" has volume "<<vol<<(isOk?" ":" not")<<" dividing his father "<<grid->name<<" "<<vol;
595 
596  child++;
597  }
598 
599  return
600  isOk;
601  };
602  }
603 
604  // /// Returns a function which tries to set the volume
605  // template <typename V>
606  // auto getVolSetter(const SGrid* grid,
607  // const V& vol)
608  // {
609  // return
610  // [grid,
611  // vol,
612  // checker=getGridChecker(grid)]()
613  // {
614  // RUNLOG<<"Setting volume of "<<grid->name<<" to "<<vol;
615  // grid->setVol(vol);
616 
617  // return
618  // checker();
619  // };
620  // }
621 
622  /// Returns a function which unset the volume
623  auto getVolUnsetter(const SGrid* grid)
624  {
625  return
626  [grid]()
627  {
628  grid->unSetVol();
629  };
630  }
631 
632  /// Returns a function which tries to set the volume deducing it from children
633  template <typename F>
635  const SGrid* child1,
636  const SGrid* child2,
637  F&& nextInstruction)
638  {
639  return
640  [grid,
641  child1,
642  child2,
643  nextInstruction]()
644  {
645  /// Deduced volume
646  const auto vol=
647  child1->getVol()*child2->getVol();
648 
650  RUNLOG<<"Setting volume of father "<<grid->name<<" to "<<vol<<" deduced by its children "<<child1->name<<" ("<<child1->getVol()<<") and "<<child2->name<<" ("<<child2->getVol()<<")";
651 
652  grid->setVol(vol);
653 
654  nextInstruction();
655 
656  grid->unSetVol();
657  };
658  }
659 
660  /// Returns a function which tries to set the volume deducing it from father and sister
661  template <typename F>
663  const SGrid* father,
664  const SGrid* sister,
665  F&& nextInstruction)
666  {
667  return
668  [grid,
669  father,
670  sister,
671  nextInstruction]()
672  {
673  /// Deduced volume
674  const Vol vol=
675  father->getVol()/sister->getVol();
676 
678  RUNLOG<<"Setting volume of children "<<grid->name<<" to "<<vol<<" deduced by its father "<<father->name<<" ("<<father->getVol()<<") and "<<sister->name<<" ("<<sister->getVol()<<")";
679  grid->setVol(vol);
680  nextInstruction();
681 
682  grid->unSetVol();
683  };
684  }
685 
686  /// Type to host an enforcceable relation
687  using EnforceableRel=
688  std::pair<const PartRel*,int>;
689 
690  /// Returns a list of all enforceable relations
692  const
693  {
694  Vector<EnforceableRel> list;
695 
696  for(auto& p : partitionRelations)
697  {
698  const int iDeducible=
699  p.getDeducible();
700 
701  if(iDeducible!=PartRel::NO_RELATIVE)
702  list.emplace_back(&p,iDeducible);
703  }
704 
705  return
706  list;
707  }
708 
709  /// Gets all fathers of a given grid
710  Vector<const SGrid*> getAllFathersOf(const SGrid* grid)
711  const
712  {
713  /// Returned list
714  Vector<const SGrid*> res;
715 
716  for(auto& p: partitionRelations)
717  for(int j=1;j<=2;j++)
718  if(p.relatives[j]==grid)
719  res.push_back(p.relatives[PartRel::FATHER]);
720 
721  return
722  res;
723  }
724 
725  /// Gets all children of a given grid
726  Vector<std::pair<const SGrid*,const SGrid*>> getAllChildrenOf(const SGrid* grid)
727  const
728  {
729  /// Result
730  Vector<std::pair<const SGrid*,const SGrid*>> res;
731 
732  for(auto& p : partitionRelations)
733  if(p.relatives[PartRel::FATHER]==grid)
734  res.push_back({p.relatives[PartRel::CHILD1],p.relatives[PartRel::CHILD2]});
735 
736  return
737  res;
738  }
739 
740  /// List all grids of the partitioning with fixed or unfixed volume, according to the parameter
741  Vector<const SGrid*> getAllGridsWithFixedOrUnfixedVol(const bool f)
742  const
743  {
744  /// List to be returned
745  Vector<const SGrid*> list;
746 
747  for(auto& grid : grids)
748  if(grid.volIsSet()==f)
749  list.push_back(&grid);
750 
751  return
752  list;
753  }
754 
755  /// List all grids of the partitioning with fixed volume
757  const
758  {
759  return
761  }
762 
763  /// List all grids of the partitioning with unfixed volume
765  const
766  {
767  return
769  }
770 
771  /// Print the partition relation in a Dot format
772  void printDot()
773  const
774  {
775  /// Labels of all partitions
776  std::map<const SGrid*,int> iChild;
777 
778  for(auto& g : partitionRelations)
779  {
780  /// Label of the father node
781  int& i=
782  iChild[g.father];
783 
784  RUNLOG<<g.father->name()<<" -> "<<g.father->name()<<i;
785 
786  for(auto& child : {g.child1,g.child2})
787  RUNLOG<<g.father->name()<<i<<" -> "<<child->name();
788 
789  i++;
790  }
791  }
792 
793  /// Return the greatest divisor of all the volumes
794  static Vol greatestDivisorOfVolumes(const Vector<const SGrid*>& list)
795  {
796  /// Greatest common divisor to be returned
797  Vol gcd=
798  0;
799 
800  for(auto& f : list)
801  gcd=
802  greatestCommonDivisor(gcd,f->getVol());
803 
804  return
805  gcd;
806  }
807 
808  /// Return the least common multiple of all the volumes
809  static Vol leastCommonMultipleOfVolumes(const Vector<const SGrid*>& list)
810  {
811  /// Least common multiple to be returned
812  Vol lcm=
813  1;
814 
815  for(auto& c : list)
816  lcm=
817  leastCommonMultiple(lcm,c->getVol());
818 
819  return
820  lcm;
821  }
822 
823  /// Return a conditional executer
824  template <typename C,
825  typename F>
827  F&& fun)
828  {
829  return
830  [checker,
831  fun]()
832  {
833  if(checker())
834  fun();
835  };
836  }
837 
838  /// Returns a function that enforce a given relation
839  template <typename Fun>
842  Fun fun)
843  {
844  /// Relation to be enforced
845  auto& r=
846  enfRel.first->relatives;
847 
848  /// Index of relative to enforce
849  const int w=
850  enfRel.second;
851 
852  RUNLOG<<"Could enforce connection between "<<r[0]->name<<" and its children "<<r[1]->name<<" and "<<r[2]->name<<" to element "<<w;
853 
854  pretendToSetVol(r[w],cleanup);
855 
856  /// Checker to be created before proceeding in the compilation
857  auto checker=
858  getGridChecker(r[w]);
859 
860  /// Next instruction
861  auto nextInstruction=
862  getConditionalExecuter(checker,compile(fun,cleanup));
863 
864  if(w==0)
865  return
866  getFatherVolDeducer(r[0],r[1],r[2],nextInstruction);
867  else
868  return
869  getChildVolDeducer(r[w],r[0],r[3-w],nextInstruction);
870  }
871 
872  /// Returns a function which loops on all possible volume of \c g
874  const Instruction& fun,
876  {
878  RUNLOG<<"Grid "<<g->name<<" can be looped";
879 
880  /// Precompute the list of fathers to check
881  Vector<const SGrid*> fathersList;
882  for(auto& f : getAllFathersOf(g))
883  if(f->volIsSet())
885 
886  /// Precompute the list of children to check
887  Vector<const SGrid*> childrenList;
888  for(auto& c : getAllChildrenOf(g))
889  for(auto& cp : {c.first,c.second})
890  if(cp->volIsSet())
892 
894 
895  /// Next instruction
896  auto nextInstruction=
898 
899  /// Returned instruction
900  auto instruction=
901  [g,
902  fathersList,
903  childrenList,
904  nextInstruction]()
905  {
907  RUNLOG<<"Looping on "<<g->name;
908 
909  /// Greatest divisor of all fathers'volume
912 
913  RUNLOG<<"Volume must divide "<<gcdFatherVol;
914 
915  /// Least common multiple of all children's volume
918 
919  RUNLOG<<"Volume must be divisible by "<<lcmChildrenVol;
920 
922  {
923  /// Volume to be looped is the quotient between fathers and children
924  const Vol volToPart=
926 
927  RUNLOG<<"VolToPart: "<<volToPart;
928 
930  [g,
933  (const Vol& v)
934  {
935  /// The volume to be assigned is the product with the children
936  const Vol actualVol=
938 
939  g->setVol(actualVol);
940 
942  RUNLOG<<"Grid "<<g->name<<" set to "<<actualVol;
943  nextInstruction();
944 
945  g->unSetVol();
946  });
947  }
948  };
949 
950  return
951  instruction;
952  }
953 
954  /// Returns the compiled partitioner
955  Instruction compile(const Instruction& fun, ///< Function to be executed at inner instruction
956  Vector<ScopeDoer<Instruction>>& cleanup) ///< Collection of tasks to cleanup after compilation ends
957  {
958  /// List of all unfixed volume
959  auto unfixedVolGridList=
961 
962  if(unfixedVolGridList.size()==0)
963  return
964  fun;
965 
966  /////////////////////////////////////////////////////////////////
967 
968  /// List of enforceable relations
969  const auto enforceableRelations=
971 
972  RUNLOG<<"Number of enforceable relations: "<<enforceableRelations.size();
973 
975  return
977 
978  /////////////////////////////////////////////////////////////////
979 
980  for(auto& g : unfixedVolGridList)
981  if(volIsBound(g))
982  return
984 
985  /////////////////////////////////////////////////////////////////
986 
987  WARNING<<"The program cannot be run";
988 
989  return
990  []()
991  {
992  CRASH<<"Trying to execute an ill-formed program";
993  };
994  }
995 
996  /// Compile the partitioner
998  {
999  /// Contains all quantity to be cleaned after compilation
1001 
1002  return
1003  compile(fun,cleanup);
1004  }
1005  };
1006 }
1007 
1008 #endif
Vector< const SGrid * > getAllFathersOf(const SGrid *grid) const
Gets all fathers of a given grid.
std::set< PartRel > partitionRelations
List of relation to be satisfied between all the grid to be partitioned.
bool setSides(const Sides &s) const
Set the sides to s.
Definition: Partitioner.hpp:81
const SGrid *& father
Pointer to the grid to be partitioned.
Instruction compile(const Instruction &fun)
Compile the partitioner.
A program made of a set of pair of instructions.
static Vol leastCommonMultipleOfVolumes(const Vector< const SGrid * > &list)
Return the least common multiple of all the volumes.
PartitioningRelation(const SGrid *father, const SGrid *child1, const SGrid *child2)
Constructor.
Vector< const SGrid * > getAllGridsWithUnfixedVol() const
List all grids of the partitioning with unfixed volume.
const std::function< void(const Sides &)> setSidesOfActualGrid
Function to invocate setting the sides of the actual grid.
const SGrid *& child1
Pointer to the dividing grid.
static Vol greatestDivisorOfVolumes(const Vector< const SGrid * > &list)
Return the greatest divisor of all the volumes.
bool sidesAreSet() const
Check if the sides are set.
Vector< std::pair< const SGrid *, const SGrid * > > getAllChildrenOf(const SGrid *grid) const
Gets all children of a given grid.
void add(Action &&fw, Action &&bw)
Adds an instruction into the program.
#define CRASH
Initialize the crasher.
Definition: Crash.hpp:13
ShadowGrid(G &&actualGrid, const char *name)
Constructor taking the grid and type-erasing it.
const Side & getSide(int mu) const
Get a given side.
const SGrid * findShadowOfGrid(G &&actualGrid) const
Find the shadow of an actual grid.
auto listAllEnforceableRelations() const
Returns a list of all enforceable relations.
Instruction getConditionalExecuter(C &&checker, F &&fun)
Return a conditional executer.
Vector< const SGrid * > getAllGridsWithFixedVol() const
List all grids of the partitioning with fixed volume.
Instruction getRelationEnforcer(const EnforceableRel &enfRel, Vector< ScopeDoer< Instruction >> &cleanup, Fun fun)
Returns a function that enforce a given relation.
std::set< SGrid > grids
List of grids to be partitioned.
const Vol getVolFromSides() const
Get the volume from sides.
void printDot() const
Print the partition relation in a Dot format.
ScopeIndenter(Logger &logger)
Create and increase indent level.
Definition: Logger.hpp:415
#define RUNLOG
Create the line.
Definition: Logger.hpp:432
BACK_FORW
Enumerate the possibity to loop backward or forward.
Definition: Position.hpp:41
bool operator<(const PartitioningRelation &oth) const
Comparison operator.
void divWithMod(Vector< TOut > &quotient, Vector< TOut > &remainder, const Vector &divisor) const
Returns the result and remainder of the division.
Definition: Vector.hpp:310
Logger runLog("/dev/stdout")
Global logger.
const void * actualGrid
Reference to the actual grid.
Definition: Partitioner.hpp:47
Vector< Move > instructions
List of instrcutions to be executed.
bool operator<(const ShadowGrid &oth) const
Comparison operator.
#define PROVIDE_COORDS_TYPES
Provide the type needed to deal with grids.
Definition: Grid.hpp:30
const Vol & getVol() const
Get the volume.
bool volIsSet() const
Check if the volume is set.
Vector< const SGrid * > getAllGridsWithFixedOrUnfixedVol(const bool f) const
List all grids of the partitioning with fixed or unfixed volume, according to the parameter...
#define SCOPE_INDENT(VAR)
Mark the stream to be more indented.
Definition: File.hpp:16
const char * name
Name for debug purpose.
#define WARNING
Starts a new line in bold brown.
Definition: Warning.hpp:9
const Sides & getSides() const
Get the sides.
void pretendToSetVol(const SGrid *grid, Vector< ScopeDoer< Instruction >> &cleanup)
Pretend to set a volume for a grid.
void unSetVol() const
Unset the volume.
Definition: Partitioner.hpp:50
bool setVol(const Vol &v) const
Set the volume to v.
Definition: Partitioner.hpp:64
void exec()
Runs the program.
const SGrid *& child2
Pointer to the divisor grid.
Instruction getVolumeLooper(const SGrid *g, const Instruction &fun, Vector< ScopeDoer< Instruction >> &cleanup)
Returns a function which loops on all possible volume of g.
void unSetSides() const
Unset the sides.
Definition: Partitioner.hpp:57
Vector< int > data
Data used for loops.