The Original CHomP Software
mwsubdiv.h
Go to the documentation of this file.
1
3
13
14// Copyright (C) 1997-2020 by Pawel Pilarczyk.
15//
16// This file is part of my research software package. This is free software:
17// you can redistribute it and/or modify it under the terms of the GNU
18// General Public License as published by the Free Software Foundation,
19// either version 3 of the License, or (at your option) any later version.
20//
21// This software is distributed in the hope that it will be useful,
22// but WITHOUT ANY WARRANTY; without even the implied warranty of
23// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24// GNU General Public License for more details.
25//
26// You should have received a copy of the GNU General Public License
27// along with this software; see the file "license.txt". If not,
28// please, see <https://www.gnu.org/licenses/>.
29
30// Started in November 2005. Last revision: February 19, 2009.
31
32
33#ifndef _CHOMP_MULTIWORK_MWSUBDIV_H_
34#define _CHOMP_MULTIWORK_MWSUBDIV_H_
35
36#include <cmath>
37#include <iostream>
38#include <fstream>
39#include <string>
40#include <sstream>
41#include <exception>
42
43#include "chomp/system/config.h"
46#include "chomp/system/arg.h"
48#include "chomp/cubes/cube.h"
49#include "chomp/multiwork/mw.h"
50
51
52// --------------------------------------------------
53// --------------- the output syntax ----------------
54// --------------------------------------------------
55
56// The syntax of lines in the text data file:
57// + n intervals. - data no. n sent
58// * n result level cube. - cube no. n received
59// # level cube. - cube subdivided
60
61// The syntax of lines in the log file of a coordinator:
62// + n. - data no. n prepared
63// * n result. - cube no. n received by the coordinator
64// ! Message. - data rejected by one of the workers (error)
65
66// The syntax of lines in the log file of a worker:
67// - n. - data no. n received by the worker
68// = n result. - data no. n sent back from the worker
69// ! Message. - data rejected by the worker (error)
70
71namespace chomp {
72namespace multiwork {
73
92
93
94// --------------------------------------------------
95// ---------------- the worker class -----------------
96// --------------------------------------------------
97
102typedef int (*fcompute) (const double *left, const double *right,
103 int dim, int level);
104
106template <int dim, class coord>
108{
109public:
111 mwSubWorker (fcompute _compute);
112
113private:
115 int Process (mwData &data);
116
119
120}; /* class mwSubWorker */
121
122// --------------------------------------------------
123
124template <int dim, class coord>
126 compute (_compute)
127{
128 return;
129} /* mwSubWorker<dim,coord>::mwSubWorker */
130
131// --------------------------------------------------
132
133template <int dim, class coord>
135{
136 // decode the number of the data pack to process
137 int current = 0;
138 data >> current;
139
140 // say which data pack is being processed
141 sout << "- " << current << ".\n";
142
143 // decode the subdivision level
144 int level = 0;
145 data >> level;
146
147 // decode the information on whether this is a full box or a probe
148 bool full = false;
149 data >> full;
150
151 // the intervals
152 double left [dim];
153 double right [dim];
154 for (int i = 0; i < dim; ++ i)
155 {
156 data >> left [i];
157 if (full)
158 data >> right [i];
159 }
160
161 // the marker of the end of data
162 int dataEndMarker = 0;
163 data >> dataEndMarker;
164 if (dataEndMarker != 13)
165 {
166 data. Reset ();
167 sout << "! Incompatible data received. Rejecting it.\n";
168 return mwReject;
169 }
170
171 // rune one set of computations
172 int result = compute (left, full ? right : left, dim, level);
173
174 // if the result is wrong then reject this piece of data
175 if (result < 0)
176 {
177 sout << "! Data no. " << current <<
178 " produced a negative result. Rejecting it.\n";
179 return mwReject;
180 }
181
182 // say what has been computed
183 sout << "= " << current << " " << result << ".\n";
184
185 // send back the data containing the result of the processing
186 data. Reset ();
187 data << current;
188 data << result;
189 return mwOk;
190} /* mwSubWorker<dim,coord>::Process */
191
192
193// --------------------------------------------------
194// --------------- subdivision points ---------------
195// --------------------------------------------------
196
201template <class coord>
202inline double mwSubdivPoint (const double &left, const double &right,
203 coord part, coord full)
204{
205 // uncomment if using CAPD to switch the rounding mode to the nearest
206// round_nearest ();
207
208 // if this is a boundary subdivision point then return the bound
209 if (part == 0)
210 return left;
211 else if (part == full)
212 return right;
213
214 // divide 'part' and 'full' by their largest common divisor
215 // which is a power of two
216 while (!(part & 1) && !(full & 1))
217 {
218 part >>= 1;
219 full >>= 1;
220 }
221
222 // compute the corresponding subdivision point of the interval
223 double fraction = static_cast<double> (part) / full;
224 return (left + (right - left) * fraction);
225} /* mwSubdivPoint */
226
227
228// --------------------------------------------------
229// ----------------- initial probes -----------------
230// --------------------------------------------------
231
234template <int dim, class coord>
236{
237public:
239 mwIniProbes (int level = 2);
240
242 ~mwIniProbes ();
243
247
249 bool available () const;
250
251private:
254
257
259 coord left [dim];
260
262 coord right [dim];
263
266
268 const coord *next;
269
270}; /* class mwIniProbes */
271
272// --------------------------------------------------
273
274template <int dim, class coord>
276{
277 if (level < 2)
278 throw "Too low initial level. Should be at least 2.";
279 for (int i = 0; i < dim; ++ i)
280 {
281 this -> left [i] = 1;
282 this -> right [i] = 1 << level;
283 }
284 this -> rect = tRectangle<coord> (this -> left, this -> right, dim);
285 this -> next = this -> rect. get ();
286 return;
287} /* mwIniProbes::mwIniProbes */
288
289template <int dim, class coord>
291{
292 return;
293} /* mwIniProbes::mwIniProbes */
294
295template <int dim, class coord>
297 (const mwIniProbes<dim,coord> &)
298{
299 return *this;
300} /* mwIniProbes::operator = */
301
302template <int dim, class coord>
304{
305 return;
306} /* mwIniProbes::~mwIniProbes */
307
308template <int dim, class coord>
310{
311 tCubeFix<dim,coord> q (this -> next, dim);
312 this -> next = this -> rect. get ();
313 return q;
314} /* mwIniProbes::get */
315
316template <int dim, class coord>
318{
319 return !!(this -> next);
320} /* mwIniProbes::available */
321
322
323// --------------------------------------------------
324// ------------- boxes around a vertex --------------
325// --------------------------------------------------
326
329template <int dim, class coord>
331{
332public:
334 mwBoxes (const tCubeFix<dim,coord> &q);
335
337 ~mwBoxes ();
338
342
344 bool available () const;
345
346private:
348 mwBoxes (const mwBoxes<dim,coord> &);
349
352
354 coord left [dim];
355
357 coord right [dim];
358
361
363 const coord *next;
364
365}; /* class mwBoxes */
366
367// --------------------------------------------------
368
369template <int dim, class coord>
371{
372 q. coord (this -> left);
373 for (int i = 0; i < dim; ++ i)
374 {
375 this -> right [i] = left [i] + 1;
376 -- (this -> left [i]);
377 }
378 this -> rect = tRectangle<coord> (this -> left, this -> right, dim);
379 this -> next = this -> rect. get ();
380 return;
381} /* mwBoxes::mwBoxes */
382
383template <int dim, class coord>
385{
386 return;
387} /* mwBoxes::mwBoxes */
388
389template <int dim, class coord>
391 (const mwBoxes<dim,coord> &)
392{
393 return *this;
394} /* mwBoxes::operator = */
395
396template <int dim, class coord>
398{
399 return;
400} /* mwBoxes::~mwBoxes */
401
402template <int dim, class coord>
404{
405 const coord *current = this -> next;
406 this -> next = this -> rect. get ();
407 return tCubeFix<dim,coord> (current, dim);
408} /* mwBoxes::get */
409
410template <int dim, class coord>
412{
413 return !!(this -> next);
414} /* mwBoxes::available */
415
416
417// --------------------------------------------------
418// ---------------- corners of a box ----------------
419// --------------------------------------------------
420
423template <int dim, class coord>
425{
426public:
429
431 ~mwCorners ();
432
436
438 bool available () const;
439
440private:
443
446
448 coord left [dim];
449
451 coord right [dim];
452
455
457 const coord *next;
458
459}; /* class mwCorners */
460
461// --------------------------------------------------
462
463template <int dim, class coord>
465{
466 q. coord (this -> left);
467 for (int i = 0; i < dim; ++ i)
468 {
469 this -> right [i] = left [i] + 2;
470 }
471 this -> rect = tRectangle<coord> (this -> left, this -> right, dim);
472 this -> next = this -> rect. get ();
473 return;
474} /* mwCorners::mwCorners */
475
476template <int dim, class coord>
478{
479 return;
480} /* mwCorners::mwCorners */
481
482template <int dim, class coord>
484 (const mwCorners<dim,coord> &)
485{
486 return *this;
487} /* mwCorners::operator = */
488
489template <int dim, class coord>
491{
492 return;
493} /* mwCorners::~mwCorners */
494
495template <int dim, class coord>
497{
498 const coord *current = this -> next;
499 this -> next = this -> rect. get ();
500 return tCubeFix<dim,coord> (current, dim);
501} /* mwCorners::get */
502
503template <int dim, class coord>
505{
506 return !!(this -> next);
507} /* mwCorners::available */
508
509
510// --------------------------------------------------
511// ---------------- data pack class -----------------
512// --------------------------------------------------
513
517template <int dim, class coord>
519{
520public:
523
525 mwSubDataPack (int _num, const tCubeFix<dim,coord> &_q,
526 int _level, bool _full):
527 num (_num), q (_q), level (_level), full (_full) {}
528
529 // the default copy constructor and operator = is good;
530 // no destructor is necessary
531
533 int num;
534
537
539 int level;
540
542 bool full;
543
544}; /* class mwSubDataPack */
545
546
547// --------------------------------------------------
548// ------------- the coordinator class --------------
549// --------------------------------------------------
550
553template <int dim, class coord>
555{
557 static const int ppMaxSubdiv = 8 * sizeof (coord) - 2;
558
560// static const int ppMaxSubdiv;
561
564
566 static const int ppMaxDim = ppCube::MaxDim;
567
570
573
576
577public:
580
582 mwSubCoordinator (const char *filename,
583 int _inilevel, int _maxlevel, bool _flushfile,
584 const double *_paramLeft, const double *_paramRight);
585
588
589private:
590 // --- the MultiWork interface functions ---
591
593 int Prepare (mwData &data);
594
596 int Accept (mwData &data);
597
599 int Reject (mwData &data);
600
601 // --- classes of probes and boxes ---
602
606
610
613
616
619
623
626
629
630 // --- small subroutines ---
631
635 bool FindMinCube
636 (const typename mwSubCoordinator<dim,coord>::ppCubes tab [],
638 int minlevel, int maxlevel, int &level,
640
644 (const typename mwSubCoordinator<dim,coord>::ppCube &q);
645
649 (const typename mwSubCoordinator<dim,coord>::ppCube &box,
650 const typename mwSubCoordinator<dim,coord>::ppCube &corner);
651
656 (const typename mwSubCoordinator<dim,coord>::ppCube &q);
657
662 int Contained (const typename mwSubCoordinator<dim,coord>::ppCube &q,
663 int level,
664 const typename mwSubCoordinator<dim,coord>::ppCubes tab [],
665 int minlevel) const;
666
667 // --- processing specific boxes and probes ---
668
670 void NegativeProbe (const ppCube &q, int level);
671
673 void GoodProbe (const ppCube &q, int level);
674
676 void FailedBox (const ppCube &q, int level);
677
679 void SuccessfulBox (const ppCube &q, int level);
680
681 // --- parameters of the computations ---
682
684 double paramLeft [dim];
685
687 double paramRight [dim];
688
692
695
698
702
703 // --- results file ---
704
706 std::ofstream f;
707
710
712 int ReadResults (std::istream &in);
713
714 // --- data packs ---
715
718
721
724
725 // --- statistics ---
726
729
732
735
739
740}; /* class mwSubCoordinator */
741
742// --------------------------------------------------
743
744template <int dim, class coord>
746
747// --------------------------------------------------
748
749template <int dim, class coord>
751{
752 return;
753} /* mwSubCoordinator<dim,coord>::mwSubCoordinator */
754
755template <int dim, class coord>
757 int _inilevel, int _maxlevel, bool _flushfile,
758 const double *_paramLeft, const double *_paramRight):
759 inilevel ((_inilevel < 2) ? 2 : _inilevel),
760 maxlevel ((_maxlevel <= inilevel) ? (inilevel + 1) : _maxlevel),
761 iniProbes (inilevel),
762 flushfile (_flushfile),
763 current (0), sentlen (0),
764 countNegative (0), countGood (0),
765 countFailed (0), countSuccessful (0)
766{
767 // display a warning if no file name is provided
768 if (!filename || !*filename)
769 sout << "WARNING: No results file name given. "
770 "Computation results will not be saved.\n";
771
772 // initialize the subdivision levels
773 if (maxlevel > ppMaxSubdiv)
774 {
775 sout << "WARNING: Max subdivision level decreased from " <<
776 maxlevel << " to " << ppMaxSubdiv << ".\n";
778 if (inilevel >= maxlevel)
779 inilevel = maxlevel - 1;
780 }
781
782 // read the previously computed results of the computations
783 if (filename && *filename)
784 {
785 std::ifstream in (filename);
786 if (!in)
787 sout << "Note: Could not open the results file. "
788 "Any previous results will be ignored.\n";
789 else
790 {
791 this -> ReadResults (in);
792 in. close ();
793 }
794 }
795
796 // open the results file for appending
797 if (filename && *filename)
798 {
799 f. open (filename, std::ios::out | std::ios::app);
800 f << "; Started on " << currenttime ();
801 if (flushfile)
802 f << std::flush;
803 }
804
805 // copy the left and right ends of the intervals
806 for (int i = 0; i < dim; ++ i)
807 {
808 paramLeft [i] = _paramLeft [i];
809 paramRight [i] = _paramRight [i];
810 }
811
812 return;
813} /* mwSubCoordinator<dim,coord>::mwSubCoordinator */
814
815template <int dim, class coord>
817{
818 f << "; A total of " << (countNegative + countGood) <<
819 " probes and " << (countFailed + countSuccessful) <<
820 " boxes have been processed.\n";
821 f << "; The verification was negative for " << countNegative <<
822 " probes, and " << countGood << " probes were good.\n";
823 f << "; The verification failed for " << countFailed <<
824 " boxes, and was successful for " << countSuccessful <<
825 " boxes.\n";
826 f << "; Finished on " << currenttime ();
827 f << "; ---------------------------------------------------\n";
828 f. close ();
829 return;
830} /* mwSubCoordinator<dim,coord>::~mwSubCoordinator */
831
832// --------------------------------------------------
833
834template <int dim, class coord>
836 (const typename mwSubCoordinator<dim,coord>::ppCubes tab [],
837 const typename mwSubCoordinator<dim,coord>::ppCubes sent [],
838 int minlevel, int maxlevel,
839 int &level, typename mwSubCoordinator<dim,coord>::ppCube &q)
840{
841 for (int l = minlevel; l < maxlevel; ++ l)
842 {
843 const ppCubes &theSet = tab [l];
844 const ppCubes &sentSet = sent [l];
845 int number = theSet. size ();
846 for (int i = number - 1; i >= 0; -- i)
847 {
848 const ppCube &c = theSet [i];
849 if (!sentSet. check (c))
850 {
851 level = l;
852 q = c;
853 return true;
854 }
855 }
856 }
857 return false;
858} /* mwSubCoordinator::FindMinCube */
859
860template <int dim, class coord>
862{
863 // prepare a data pack to send
864 ppPack &pack = sent [sentlen];
865
866 // if there is any initial probe that has not yet been processed
867 // then take this probe
868 bool iniProbe = false;
869 while (iniProbes. available ())
870 {
871 pack = ppPack (current, iniProbes. get (), inilevel, false);
872 if (iniProcessed. check (pack. q))
873 {
874 iniProcessed. remove (pack. q);
875 continue;
876 }
877 else
878 {
879 iniProbe = true;
880 break;
881 }
882 }
883
884 // otherwise send a probe or a box which is waiting to be verified
885 if (!iniProbe)
886 {
887 // find a probe for testing at the lowest level available
888 int levelT = 0;
889 ppCube cubeT;
890 bool foundT = this -> FindMinCube (Test, CurProbes,
891 inilevel, maxlevel, levelT, cubeT);
892
893 // find a box that is waiting at the lowest level available
894 int levelW = 0;
895 ppCube cubeW;
896 bool foundW = this -> FindMinCube (Waiting, CurBoxes,
897 inilevel, maxlevel, levelW, cubeW);
898
899 // if no cube for processing can be found, then interrupt
900 if (!foundT && !foundW)
901 return mwNoData;
902
903 // send the probe found if this is the right thing to do
904 if (foundT && (!foundW || (levelT <= levelW)))
905 {
906 pack = ppPack (current, cubeT, levelT, false);
907 CurProbes [levelT]. add (cubeT);
908 }
909 // otherwise send the box found
910 else
911 {
912 pack = ppPack (current, cubeW, levelW, true);
913 CurBoxes [levelW]. add (cubeW);
914 }
915 }
916
917 // prepare the intervals of parameters corresponding to the cube
918 coord c [ppMaxDim];
919 pack. q. coord (c);
920 int fullSize = 1 << pack. level;
921 double left [ppMaxDim];
922 double right [ppMaxDim];
923 for (int i = 0; i < dim; ++ i)
924 {
925 // prepare the probe or the left corner of the box
926 left [i] = mwSubdivPoint (paramLeft [i], paramRight [i],
927 c [i], fullSize);
928
929 // if this is a full box then compute the right corner, too
930 if (pack. full)
931 {
932 // prepare the right corner of the box
933 right [i] = mwSubdivPoint (paramLeft [i],
934 paramRight [i], c [i] + 1, fullSize);
935
936 // if the resolution of the representable numbers
937 // has been reached then set this level to be
938 // the strict upper bound for the subdivision level
939 if (left [i] == right [i])
940 {
941 // leave a note of this situation in the file
942 f << "; The resolution of representable "
943 "numbers exceeded.\n; Decreasing "
944 "max level from " << maxlevel <<
945 " to " << pack. level << ".\n";
946 if (flushfile)
947 f << std::flush;
948
949 // notify the user about this situation
950 sout << "WARNING: The resolution of "
951 "representable numbers exceeded.\n"
952 "Decreasing max level from " <<
953 maxlevel << " to " << pack. level <<
954 ".\n";
955
956 // decrease the max level limit
957 maxlevel = pack. level;
958 return mwNoData;
959 }
960 }
961 }
962
963 // write th information on the prepared cube to the results file
964 f << "+ " << pack. num;
965 for (int i = 0; i < dim; ++ i)
966 {
967 f << (i ? "x[" : " [") << left [i];
968 if (pack. full)
969 f << "," << right [i];
970 f << "]";
971 }
972 f << ".\n";
973 if (flushfile)
974 f << std::flush;
975
976 // send the data pack number
977 data << pack. num;
978
979 // send the subdivision level
980 data << pack. level;
981
982 // send the information on whether this is a full box or a probe
983 data << pack. full;
984
985 // send the intervals (left and right ends where applicable)
986 for (int i = 0; i < dim; ++ i)
987 {
988 data << left [i];
989 if (pack. full)
990 data << right [i];
991 }
992
993 // append the data end marker for extra verification
994 const int dataEndMarker = 13;
995 data << dataEndMarker;
996
997 // show a message on which data pack has been prepared
998 sout << "+ " << pack. num << ".\n";
999
1000 // increase the counters
1001 ++ current;
1002 ++ sentlen;
1003
1004 return mwOk;
1005} /* mwSubCoordinator<dim,coord>::Prepare */
1006
1007// --------------------------------------------------
1008
1009template <int dim, class coord>
1012 (const typename mwSubCoordinator<dim,coord>::ppCube &q)
1013{
1014 coord c [dim];
1015 q. coord (c);
1016 for (int i = 0; i < dim; ++ i)
1017 c [i] <<= 1;
1018 return ppCube (c, dim);
1019} /* mwSubCoordinator::UpLevel */
1020
1021template <int dim, class coord>
1024 (const typename mwSubCoordinator<dim,coord>::ppCube &box,
1025 const typename mwSubCoordinator<dim,coord>::ppCube &corner)
1026{
1027 coord cBox [dim];
1028 box. coord (cBox);
1029 coord cCorner [dim];
1030 corner. coord (cCorner);
1031 for (int i = 0; i < dim; ++ i)
1032 {
1033 if (cBox [i] == cCorner [i])
1034 cBox [i] <<= 1;
1035 else
1036 cBox [i] = (cBox [i] << 1) + 1;
1037 }
1038 return ppCube (cBox, dim);
1039} /* mwSubCoordinator::UpLevel */
1040
1041template <int dim, class coord>
1044 (const typename mwSubCoordinator<dim,coord>::ppCube &q)
1045{
1046 coord c [dim];
1047 q. coord (c);
1048 for (int i = 0; i < dim; ++ i)
1049 c [i] >>= 1;
1050 return ppCube (c, dim);
1051} /* mwSubCoordinator::DownLevel */
1052
1053template <int dim, class coord>
1055 (const typename mwSubCoordinator<dim,coord>::ppCube &q, int level,
1056 const typename mwSubCoordinator<dim,coord>::ppCubes tab [],
1057 int minlevel) const
1058{
1059 // verify if the box itself is contained in any set of boxes
1060 if (tab [level]. check (q))
1061 return level;
1062
1063 // subdivide the box and verify at a higher level
1064 if (minlevel < inilevel)
1065 minlevel = inilevel;
1066 ppCube box = q;
1067 while (-- level > minlevel)
1068 {
1069 box = DownLevel (box);
1070 if (tab [level]. check (box))
1071 return level;
1072 }
1073
1074 return 0;
1075} /* mwSubCoordinator::Contained */
1076
1077template <int dim, class coord>
1079{
1080 // add the probe to the set of negative probes
1081 Negative [level]. add (q);
1082 sbug << "@ NegProbe [" << level << "]: " << q << "\n";
1083
1084 // boxes around this probe automatically fail, so remove them
1085 // from the queue and interpret them as failed boxes
1086 mwBoxes<dim,coord> boxes (q);
1087 while (boxes. available ())
1088 {
1089 // take a box which has this probe in its corner
1090 ppCube box = boxes. get ();
1091
1092 // if it is waiting for processing but was not sent yet
1093 // then pretend it has just returned as a failed box
1094 if (Waiting [level]. check (box) &&
1095 !CurBoxes [level]. check (box))
1096 {
1097 sbug << "# FailedBox [" << level << "]: " <<
1098 box << "\n";
1099 Waiting [level]. remove (box);
1100 FailedBox (box, level);
1101 }
1102 }
1103
1104 return;
1105} /* mwSubCoordinator::NegativeProbe */
1106
1107template <int dim, class coord>
1109{
1110 // if it is already known that this probe is good then skip it
1111 if (Good [level]. check (q))
1112 {
1113 sbug << "@ GoodKnown [" << level << "]: " << q << "\n";
1114 return;
1115 }
1116
1117 // add the probe to the set of good probes at its level
1118 Good [level]. add (q);
1119 sbug << "@ GoodProbe [" << level << "]: " << q << "\n";
1120
1121 // if the next level is beyond the scope then quit here
1122 if (level + 1 == maxlevel)
1123 return;
1124
1125 // transfer the probe to the next level and remember that it is good
1126 ppCube probe = UpLevel (q);
1127 Good [level + 1]. add (probe);
1128 sbug << "+ GoodProbe [" << (level + 1) << "]: " << probe << "\n";
1129
1130 // consider all the boxes which contain this probe
1131 mwBoxes<dim,coord> boxes (probe);
1132 while (boxes. available ())
1133 {
1134 // if the box is not contained in any larger successful box
1135 // then add it to the waiting list
1136 ppCube box = boxes. get ();
1137 if (!Contained (box, level + 1, Successful, 0))
1138 {
1139
1140 Waiting [level + 1]. add (box);
1141 sbug << "+ Waiting [" << (level + 1) << "]: " <<
1142 box << "\n";
1143 }
1144 }
1145
1146 return;
1147} /* mwSubCoordinator::GoodProbe */
1148
1149template <int dim, class coord>
1151{
1152 // add the box to the list of boxes which failed
1153 Failed [level]. add (q);
1154 sbug << "@ FailedBox [" << level << "]: " << q << "\n";
1155
1156 // if no further subdivisions are to be considered then quit here
1157 if (level + 1 == maxlevel)
1158 return;
1159
1160 // consider all the corners of the box
1161 mwCorners<dim,coord> corners (q);
1162 while (corners. available ())
1163 {
1164 // take the next corner of the box
1165 ppCube c = corners. get ();
1166
1167 // if this is a negative probe then skip it
1168 if (Negative [level]. check (c))
1169 continue;
1170
1171 // if this probe has not yet been checked
1172 // then add it to the list of probes to test
1173 if (!Good [level]. check (c))
1174 {
1175 Test [level]. add (c);
1176 sbug << "+ Test [" << level << "]: " << c << "\n";
1177 continue;
1178 }
1179
1180 // add a twice smaller box located at the given corner
1181 // to the list of boxes which wait for being verified,
1182 // unless the result for this box is already known
1183 ppCube box = UpLevel (q, c);
1184 if (!Successful [level + 1]. check (box) &&
1185 !Failed [level + 1]. check (box))
1186 {
1187 Waiting [level + 1]. add (box);
1188 sbug << "+ Waiting [" << (level + 1) << "]: " <<
1189 box << "\n";
1190 }
1191
1192 // mark the probe as good at the higher subdivision level
1193 ppCube probe = UpLevel (c);
1194 Good [level + 1]. add (probe);
1195 sbug << "+ Good [" << (level + 1) << "]: " << probe << "\n";
1196 }
1197
1198 return;
1199} /* mwSubCoordinator::FailedBox */
1200
1201template <int dim, class coord>
1203{
1204 // if the box has already been added then skip it
1205 if (Successful [level]. check (q))
1206 {
1207 sbug << "@ SuccessKnown [" << level << "]: " << q << "\n";
1208 return;
1209 }
1210
1211 // if this box is already contained in a larger successful box
1212 // then ignore it
1213 if (Contained (q, level, Successful, 0))
1214 {
1215 sbug << "@ SuccessSubset [" << level << "]: " << q << "\n";
1216 return;
1217 }
1218
1219 // add the box to the set of successful boxes which form the set A
1220 Successful [level]. add (q);
1221 sbug << "@ SuccessBox [" << level << "]: " << q << "\n";
1222
1223 // consider all the vertices of this box
1224 mwCorners<dim,coord> corners (q);
1225 while (corners. available ())
1226 {
1227 // take the next corner of the box
1228 ppCube c = corners. get ();
1229
1230 // remove the corner probe from a list of probes to test
1231 if (Test [level]. check (c))
1232 {
1233 Test [level]. remove (c);
1234 sbug << "- Test [" << level << "]: " << c << "\n";
1235 }
1236
1237 // remove the corner box from a list of boxes to test
1238 ppCube cornerBox = UpLevel (q, c);
1239 if (Waiting [level + 1]. check (cornerBox))
1240 {
1241 Waiting [level + 1]. remove (cornerBox);
1242 sbug << "- Waiting [" << (level + 1) << "]: " <<
1243 cornerBox << "\n";
1244 // note: there might be some boxes contained in q
1245 // waiting at deeper levels, but determining them
1246 // might be quite inefficient,
1247 // so they are not cleaned in this implementation
1248 // of the algorithm
1249 }
1250
1251 // if the probe is already known to be good then skip it
1252 if (Good [level]. check (c))
1253 continue;
1254
1255 // add the probe to the list of good ones
1256 Good [level]. add (c);
1257 sbug << "+ Good [" << level << "]: " << c << "\n";
1258
1259 // propagate the probe one level deeper and mark it as good
1260 ppCube probe = UpLevel (c);
1261 Good [level + 1]. add (probe);
1262 sbug << "+ Good [" << (level + 1) << "]: " << probe << "\n";
1263
1264 // consider all the boxes which contain this probe
1265 mwBoxes<dim,coord> boxes (probe);
1266 while (boxes. available ())
1267 {
1268 // take the next box
1269 ppCube box = boxes. get ();
1270
1271 // if this box is not contained in any successful
1272 // larger box then add it to the waiting list
1273 if (!Contained (box, level + 1, Successful, 0))
1274 {
1275 Waiting [level + 1]. add (box);
1276 sbug << "+ Waiting [" << (level + 1) <<
1277 "]: " << box << "\n";
1278 }
1279 }
1280 }
1281
1282 return;
1283} /* mwSubCoordinator::SuccessfulBox */
1284
1285template <int dim, class coord>
1287{
1288 // decode the data pack number
1289 int n = 0;
1290 data >> n;
1291
1292 // decode the result
1293 int result = 0;
1294 data >> result;
1295
1296 // say what has been received
1297 sout << "* " << n << " " << result << ".\n";
1298
1299 // find this data among the data packs that were sent for processing
1300 int pos = 0;
1301 while ((pos < sentlen) && (sent [pos]. num != n))
1302 ++ pos;
1303 if (pos >= sentlen)
1304 {
1305 sout << "ERROR: Wrong data pack number received "
1306 "from a worker.\n";
1307 return mwError;
1308 }
1309 const ppPack &pack = sent [pos];
1310
1311 // save the data to the output file
1312 f << (pack. full ? "* " : "@ ") << n << " " << result <<
1313 " " << pack. level << " " << pack. q << ".\n";
1314 if (flushfile)
1315 f << std::flush;
1316
1317 // extract the data from the data pack
1318 const ppCube &q = pack. q;
1319 int level = pack. level;
1320 bool full = pack. full;
1321
1322 // remove the cube from appropriate sets and process it
1323 if (full)
1324 {
1325 CurBoxes [level]. remove (q);
1326 Waiting [level]. remove (q);
1327 if (result)
1328 {
1329 ++ countSuccessful;
1330 SuccessfulBox (q, level);
1331 }
1332 else
1333 {
1334 ++ countFailed;
1335 FailedBox (q, level);
1336 }
1337 }
1338 else
1339 {
1340 CurProbes [level]. remove (q);
1341 Test [level]. remove (q);
1342 if (result)
1343 {
1344 ++ countGood;
1345 GoodProbe (q, level);
1346 }
1347 else
1348 {
1349 ++ countNegative;
1350 NegativeProbe (q, level);
1351 }
1352 }
1353
1354 // remove the data pack from the table containing the data packs
1355 -- sentlen;
1356 if (pos != sentlen)
1357 sent [pos] = sent [sentlen];
1358
1359 return mwOk;
1360} /* mwSubCoordinator<dim,coord>::Accept */
1361
1362template <int dim, class coord>
1364{
1365 // decode the number
1366 int n = 0;
1367 data >> n;
1368
1369 // say that data has been rejected
1370 sout << "!!! Data no. " << n << " rejected.\n";
1371
1372 return mwError;
1373} /* mwSubCoordinator<dim,coord>::Reject */
1374
1375// --------------------------------------------------
1376
1377template <int dim, class coord>
1379{
1380 ignorecomments (in);
1381 while (!in. eof ())
1382 {
1383 // read the first char and interprete the line
1384 int ch = in. get ();
1385
1386 // ignore the line if it contains no useful information
1387 if ((ch != '*') && (ch != '@'))
1388 {
1389 ignoreline (in);
1390 ignorecomments (in);
1391 continue;
1392 }
1393
1394 // read the data number if relevant
1395 if ((ch == '*') || (ch == '@'))
1396 {
1397 int n = -1;
1398 in >> n;
1399 if (n < 0)
1400 break;
1401 }
1402
1403 // read the result if any
1404 int result = -1;
1405 if ((ch == '*') || (ch == '@'))
1406 {
1407 in >> result;
1408 if (result < 0)
1409 break;
1410 }
1411
1412 // read the subdivision level of the cube
1413 int level = -1;
1414 in >> level;
1415 if (level < 0)
1416 break;
1417
1418 // read the cube itself
1419 ppCube q;
1420 in >> q;
1421
1422 // make sure that there is the dot which ends the line
1423 if (in. peek () != '.')
1424 break;
1425
1426 // ignore the remaining part of the line
1427 ignoreline (in);
1428 ignorecomments (in);
1429
1430 // process the data as necessary
1431 if (ch == '*')
1432 {
1433 Waiting [level]. remove (q);
1434 if (result)
1435 SuccessfulBox (q, level);
1436 else
1437 FailedBox (q, level);
1438 }
1439 else if (ch == '@')
1440 {
1441 if (level == inilevel)
1442 iniProcessed. add (q);
1443 else
1444 Test [level]. remove (q);
1445 if (result)
1446 GoodProbe (q, level);
1447 else
1448 NegativeProbe (q, level);
1449 }
1450 }
1451
1452 return 0;
1453} /* mwSubCoordinator<dim,coord>::ReadResults */
1454
1455
1456// --------------------------------------------------
1457// ---------------------- MAIN ----------------------
1458// --------------------------------------------------
1459
1463template <int dim, class coord>
1464int mwSubdivMain (int argc, char *argv [],
1465 const char *title, const char *helpinfo,
1466 int defaultPortNumber, int controlNumber,
1467 const double *paramLeft, const double *paramRight,
1468 int minSubdivLevel, fcompute compute)
1469{
1470 const char *arginfo = "\
1471Command line arguments (at least '-w' or '-m N' must be specified):\n\
1472-w [port] - run as a worker (by default the program runs as a coordinator),\n\
1473-c [port] - run as a coordinator only (don't process any data locally),\n\
1474-p port - set the port number for the multi-work communication,\n\
1475-k - keep workers waiting after the computations have been completed,\n\
1476computer:port - use this connection at start-up (can be repeated),\n\
1477-s FILE - save the workers' list to this file (default: mwsubdiv.txt),\n\
1478-r FILE - retrieve the workers' list from this file (def: mwsubdiv.txt),\n\
1479-f filename - results file (new results will be appended); coord only!\n\
1480--flush - flush the results file very frequently (slows down the program),\n\
1481-i N - set the initial subdivision level (some minimum is enforced),\n\
1482-m N - set the maximal subdivision level (default: inilevel + 2),\n\
1483-q - quit all the workers who are waiting (provide addresses or use -r),\n\
1484--quiet - do not display any messages on the standard output,\n\
1485--log filename - save the console output to the given file,\n\
1486--help - show this brief help information and exit.\n\
1487For more information ask the author at http://www.PawelPilarczyk.com/.";
1488
1489 // prepare user-configurable data
1490 char *retrieveworkers = 0;
1491 char *saveworkers = 0;
1492 const int maxaddr = 1024;
1493 char *addr [maxaddr];
1494 int naddr = 0;
1495 int portnum = -1;
1496 int workport = -1;
1497 int coordport = -1;
1498 bool keepworkers = false;
1499 bool quitworkers = false;
1500 char *filename = 0;
1501 int inilevel = 0;
1502 int maxlevel = 0;
1503 bool flushfile = false;
1504
1505 // interprete the command-line arguments
1506 arguments a;
1507 arg (a, 0, addr, naddr, maxaddr);
1508 arg (a, "r", retrieveworkers, "mwsubdiv.txt");
1509 arg (a, "s", saveworkers, "mwsubdiv.txt");
1510 arg (a, "f", filename);
1511 arg (a, "i", inilevel);
1512 arg (a, "m", maxlevel);
1513 arg (a, "w", workport, defaultPortNumber);
1514 arg (a, "p", portnum);
1515 arg (a, "c", coordport, defaultPortNumber);
1516 argswitch (a, "k", keepworkers, true);
1517 argswitch (a, "q", quitworkers, true);
1518 argswitch (a, "-flush", flushfile, true);
1519 arghelp (a);
1520
1521 argstreamprepare (a);
1522 int argresult = a. analyze (argc, argv);
1523 argstreamset ();
1524
1525 // show the program's main title
1526 if (argresult >= 0)
1527 sout << title << '\n';
1528
1529 // if something was incorrect, show an additional message and exit
1530 if (argresult < 0)
1531 {
1532 sout << "Call with '--help' for help.\n";
1533 return 2;
1534 }
1535
1536 // set the right port number and determine if to run as a worker
1537 // or as a coordinator, with or without local work
1538 int port = defaultPortNumber;
1539 bool localwork = (coordport < 0);
1540 if (coordport >= 0)
1541 port = coordport;
1542 bool worker = (workport >= 0);
1543 if (workport >= 0)
1544 port = workport;
1545 if (portnum >= 0)
1546 port = portnum;
1547
1548 // if no data packs are to be processed, don't run the program
1549 if (!maxlevel && !worker && !quitworkers)
1550 argresult = 1;
1551
1552 // if help requested, show help information
1553 if (argresult > 0)
1554 {
1555 sout << helpinfo << '\n' << arginfo << '\n';
1556 return 1;
1557 }
1558
1559 // try running the main function and catch an error message if thrown
1560 try
1561 {
1562 // set an appropriate program time message
1563 program_time = "Aborted after:";
1564 program_time = 1;
1565
1566 // quit all the workers from the list if requested to
1567 if (quitworkers)
1568 {
1569 // prepare a dummy coordinator class
1571
1572 // set up the parameters necessary for identification
1573 c. Port (port);
1574 c. ControlNumber (controlNumber);
1575
1576 // prepare a list of workers' addresses
1577 if (retrieveworkers)
1578 c. Load (retrieveworkers);
1579 for (int i = 0; i < naddr; ++ i)
1580 c. Add (addr [i]);
1581
1582 // quit all the workers which appear in the list
1583 sout << "Quitting workers... ";
1584 c. QuitWorkers ();
1585 sout << "Done.\n";
1586 }
1587
1588 // run as a worker if requested to
1589 else if (worker)
1590 {
1591 // prepare a worker object
1592 mwSubWorker<dim,coord> w (compute);
1593
1594 // set up various options of the worker object
1595 w. Port (port);
1596 w. ControlNumber (controlNumber);
1597 for (int i = 0; i < naddr; ++ i)
1598 w. Add (addr [i]);
1599
1600 // run the computations
1601 sout << "Running as a worker...\n";
1602 int result = w. Work ();
1603 if (result == mwOk)
1604 sout << "Work completed successfully.\n";
1605 else
1606 sout << "Could not work - probably "
1607 "an error occurred.\n";
1608 }
1609
1610 // run as a coordinator otherwise
1611 else
1612 {
1613 // make a correction to the subdivision level bounds
1614 if (inilevel <= minSubdivLevel)
1615 inilevel = minSubdivLevel;
1616 if (maxlevel <= inilevel)
1617 maxlevel = inilevel + 2;
1618
1619 // prepare a local worker and a coordinator
1620 mwSubWorker<dim,coord> w (compute);
1621 mwSubCoordinator<dim,coord> c (filename, inilevel,
1622 maxlevel, flushfile, paramLeft, paramRight);
1623
1624 // set up various options of the coordinator
1625 c. KeepWorkers (keepworkers);
1626 c. Port (port);
1627 c. ControlNumber (controlNumber);
1628 for (int i = 0; i < naddr; ++ i)
1629 c. Add (addr [i]);
1630 if (retrieveworkers)
1631 c. Load (retrieveworkers);
1632
1633 // run the computations
1634 sout << "Running as a coordinator...\n";
1635 int result = c. Coordinate (localwork ? &w : 0);
1636 if (result == mwOk)
1637 sout << "The task completed successfully.\n";
1638 else
1639 sout << "Could not coordinate - probably "
1640 "an error occurred.\n";
1641
1642 // save the connected workers if necessary
1643 if (saveworkers)
1644 c. SaveWorkers (saveworkers);
1645 }
1646
1647 // set an appropriate program time message
1648 program_time = "Total time used:";
1649
1650 // finalize
1651 return 0;
1652 }
1653 catch (const char *msg)
1654 {
1655 sout << "ERROR: " << msg << '\n';
1656 return -1;
1657 }
1658 catch (const std::exception &e)
1659 {
1660 sout << "ERROR: " << e. what () << '\n';
1661 return -1;
1662 }
1663 catch (...)
1664 {
1665 sout << "ABORT: An unknown error occurred.\n";
1666 return -1;
1667 }
1668} /* mwSubdivMain */
1669
1670
1671} // namespace multiwork
1672} // namespace chomp
1673
1674#endif // _CHOMP_MULTIWORK_MWSUBDIV_H_
1675
1677
This file contains the definition of a class which can be used to parse the command line of a program...
#define argstreamprepare(a)
This macrodefinition sets up command line arguments for the analysis of typical arguments related to ...
Definition: arg.h:838
#define argstreamset()
This macrodefinition sets up the streams defined in the module "textfile.h", based on the analyzed co...
Definition: arg.h:852
The objects of this class gather the expected command-line arguments and decode them.
Definition: arg.h:534
This is a template for a set of objects of the given type.
Definition: hashsets.h:185
A container for elements placed in a table (like a vector) that is actually built of many smaller tab...
Definition: multitab.h:65
This class defines a hypercube in R^n with edges parallel to the axes and with size 1 in each directi...
Definition: cubefix.h:72
static const int MaxDim
The maximal dimension of a cube (unused).
Definition: cubefix.h:81
This class can be used for iterating a rectangular set of points, given its left and right bound.
Definition: pointset.h:1627
This is a helper class for iterating all the boxes which share a given vertex.
Definition: mwsubdiv.h:331
tRectangle< coord > rect
The actual box iterator.
Definition: mwsubdiv.h:360
bool available() const
Returns true iff there is at least one more box available.
Definition: mwsubdiv.h:411
coord left[dim]
The coordinates of the leftmost corner of the iterated area.
Definition: mwsubdiv.h:354
const coord * next
The next coordinates to return or 0 if none.
Definition: mwsubdiv.h:363
tCubeFix< dim, coord > get()
Returns the next available box or throws an error message if all the boxes have already been taken.
Definition: mwsubdiv.h:403
coord right[dim]
The coordinates of the rightmost corner of the iterated area.
Definition: mwsubdiv.h:357
mwBoxes< dim, coord > & operator=(const mwBoxes< dim, coord > &)
The assignment operator is not allowed.
Definition: mwsubdiv.h:391
mwBoxes(const tCubeFix< dim, coord > &q)
The only constructor allowed.
Definition: mwsubdiv.h:370
~mwBoxes()
The destructor.
Definition: mwsubdiv.h:397
This class defines a generic coordinator task object for the multi-work distributed computations fram...
Definition: mwcoord.h:127
This is a helper class for iterating all the corners of a given box.
Definition: mwsubdiv.h:425
tCubeFix< dim, coord > get()
Returns the next available corner or throws an error message if all the corners have already been tak...
Definition: mwsubdiv.h:496
mwCorners< dim, coord > & operator=(const mwCorners< dim, coord > &)
The assignment operator is not allowed.
Definition: mwsubdiv.h:484
bool available() const
Returns true iff there is at least one more box available.
Definition: mwsubdiv.h:504
coord left[dim]
The coordinates of the leftmost corner of the iterated area.
Definition: mwsubdiv.h:448
tRectangle< coord > rect
The actual corner iterator.
Definition: mwsubdiv.h:454
mwCorners(const tCubeFix< dim, coord > &q)
The only constructor allowed.
Definition: mwsubdiv.h:464
~mwCorners()
The destructor.
Definition: mwsubdiv.h:490
coord right[dim]
The coordinates of the rightmost corner of the iterated area.
Definition: mwsubdiv.h:451
const coord * next
The next coordinates to return or 0 if none.
Definition: mwsubdiv.h:457
This class is used to convert data structures into a single sequence of bytes and to retrieve this da...
Definition: mwdata.h:67
This is a helper class for producing an initial set of probes to test the interior of the requested a...
Definition: mwsubdiv.h:236
const coord * next
The next coordinates to return or 0 if none.
Definition: mwsubdiv.h:268
mwIniProbes< dim, coord > & operator=(const mwIniProbes< dim, coord > &)
The assignment operator is not allowed.
Definition: mwsubdiv.h:297
mwIniProbes(int level=2)
The only constructor allowed.
Definition: mwsubdiv.h:275
coord right[dim]
The coordinates of the rightmost corner of the iterated area.
Definition: mwsubdiv.h:262
~mwIniProbes()
The destructor.
Definition: mwsubdiv.h:303
tRectangle< coord > rect
The actual probe iterator.
Definition: mwsubdiv.h:265
tCubeFix< dim, coord > get()
Returns the next available probe or throws an error message if all the probes have already been taken...
Definition: mwsubdiv.h:309
coord left[dim]
The coordinates of the leftmost corner of the iterated area.
Definition: mwsubdiv.h:259
bool available() const
Returns true iff there is at least one more probe available.
Definition: mwsubdiv.h:317
This class defines a coordinator for the multi-work subdivision framework.
Definition: mwsubdiv.h:555
static mwSubCoordinator< dim, coord >::ppCube UpLevel(const typename mwSubCoordinator< dim, coord >::ppCube &q)
Returns a probe with respect to a higher level grid, that is, multiplies all the coordinates by 2.
Definition: mwsubdiv.h:1012
~mwSubCoordinator()
The destructor.
Definition: mwsubdiv.h:816
static const int ppMaxSubdiv
The maximal feasible subdivision level.
Definition: mwsubdiv.h:557
static const int ppMaxDim
The maximal dimension of cubes.
Definition: mwsubdiv.h:566
void NegativeProbe(const ppCube &q, int level)
A function for acquiring a negative probe.
Definition: mwsubdiv.h:1078
bool flushfile
Should the results file be flushed after every write?
Definition: mwsubdiv.h:709
bool FindMinCube(const typename mwSubCoordinator< dim, coord >::ppCubes tab[], const typename mwSubCoordinator< dim, coord >::ppCubes sent[], int minlevel, int maxlevel, int &level, typename mwSubCoordinator< dim, coord >::ppCube &q)
Finds a cube at the lowest level (>= min, < max) of the given set of cubes that was not sent,...
Definition: mwsubdiv.h:836
void GoodProbe(const ppCube &q, int level)
A function for acquiring a good probe.
Definition: mwsubdiv.h:1108
void FailedBox(const ppCube &q, int level)
A function for acquiring a box for which the verification failed.
Definition: mwsubdiv.h:1150
tCubeFix< dim, coord > ppCube
The maximal feasible subdivision level.
Definition: mwsubdiv.h:563
int inilevel
The level of subdivisions in the parameter space at which the actual computations begin.
Definition: mwsubdiv.h:691
ppCubes Failed[ppMaxSubdiv]
The set F: Boxes for which the verification failed.
Definition: mwsubdiv.h:618
mwIniProbes< dim, coord > iniProbes
An iterator of initial probes.
Definition: mwsubdiv.h:697
ppCubes CurBoxes[ppMaxSubdiv]
Part of the set C: Currently processed boxes.
Definition: mwsubdiv.h:628
int countFailed
The number of processed boxes for which the verification failed.
Definition: mwsubdiv.h:734
int countGood
The number of processed probes which turn out to be good.
Definition: mwsubdiv.h:731
std::ofstream f
A file to append the results to.
Definition: mwsubdiv.h:706
double paramRight[dim]
The right (maximal) vertices of the parameter cube.
Definition: mwsubdiv.h:687
int Contained(const typename mwSubCoordinator< dim, coord >::ppCube &q, int level, const typename mwSubCoordinator< dim, coord >::ppCubes tab[], int minlevel) const
Verifies if the given box is contained in a box at any level greater than or equal to the given minim...
Definition: mwsubdiv.h:1055
ppCubes Negative[ppMaxSubdiv]
The set N: Probes for which the verification of the property was negative.
Definition: mwsubdiv.h:605
int sentlen
The number of data packs sent for processing.
Definition: mwsubdiv.h:723
ppCubes Good[ppMaxSubdiv]
The set G: Good probes, that is, probes for which the property was verified successfully.
Definition: mwsubdiv.h:609
ppCubes Test[ppMaxSubdiv]
The set T: Probes which have to be sent for testing.
Definition: mwsubdiv.h:612
int Prepare(mwData &data)
A function for preparing data by a coordinator.
Definition: mwsubdiv.h:861
double paramLeft[dim]
The left (minimal) vertices of the parameter cube.
Definition: mwsubdiv.h:684
int countNegative
The number of processed probes with negative result.
Definition: mwsubdiv.h:728
hashedset< ppCube > ppCubes
The type of a set of cubes in the parameter space.
Definition: mwsubdiv.h:569
void SuccessfulBox(const ppCube &q, int level)
A function for acquiring a successful box.
Definition: mwsubdiv.h:1202
int current
The counter of data packs prepared by a coordinator.
Definition: mwsubdiv.h:717
ppCubes Successful[ppMaxSubdiv]
The set A: Boxes which are successfully verified to satisfy the given property and thus are contained...
Definition: mwsubdiv.h:622
mwSubDataPack< dim, coord > ppPack
The type of a sent data pack kept in an internal array.
Definition: mwsubdiv.h:575
int ReadResults(std::istream &in)
A procedure for reading the previously computed results.
Definition: mwsubdiv.h:1378
ppCubes Waiting[ppMaxSubdiv]
The set W: Boxes waiting for verification.
Definition: mwsubdiv.h:625
mwSubCoordinator()
The constructor of an uninitialized coordinator.
Definition: mwsubdiv.h:750
static mwSubCoordinator< dim, coord >::ppCube DownLevel(const typename mwSubCoordinator< dim, coord >::ppCube &q)
Returns a box with respect to a higher level grid which contains the given box, that is,...
Definition: mwsubdiv.h:1044
ppCubes CurProbes[ppMaxSubdiv]
Part of the set C2: Currently processed probes.
Definition: mwsubdiv.h:615
multitable< ppPack > sent
The data packs sent for processing.
Definition: mwsubdiv.h:720
int maxlevel
The maximal allowed level of subdivision in the parameter space.
Definition: mwsubdiv.h:694
int Accept(mwData &data)
A function for accepting results by a coordinator.
Definition: mwsubdiv.h:1286
int countSuccessful
The number of processed boxes for which the verification was successful.
Definition: mwsubdiv.h:738
ppCubes iniProcessed
A set of previously processed initial probes (used only if continuing the computations).
Definition: mwsubdiv.h:701
int Reject(mwData &data)
A function for taking rejected data by a coordinator.
Definition: mwsubdiv.h:1363
tRectangle< coord > ppRect
The kind of rectangle used to iterate ranges of cubes.
Definition: mwsubdiv.h:572
This is a helper class which defines a single data pack used in the communication between coordinator...
Definition: mwsubdiv.h:519
mwSubDataPack(int _num, const tCubeFix< dim, coord > &_q, int _level, bool _full)
A nice constructor.
Definition: mwsubdiv.h:525
mwSubDataPack()
The default constructor.
Definition: mwsubdiv.h:522
int level
The subdivision level of the cube.
Definition: mwsubdiv.h:539
bool full
Is this a full cube (or just a probe)?
Definition: mwsubdiv.h:542
tCubeFix< dim, coord > q
The cube sent to a worker.
Definition: mwsubdiv.h:536
int num
The number of the data pack.
Definition: mwsubdiv.h:533
This class defines a worker for the multi-work subdivision framework.
Definition: mwsubdiv.h:108
mwSubWorker(fcompute _compute)
The constructor.
Definition: mwsubdiv.h:125
fcompute compute
The address of a function to use for the computations.
Definition: mwsubdiv.h:118
int Process(mwData &data)
A function for processing the data by a worker.
Definition: mwsubdiv.h:134
This class defines a generic worker task object for the multi-work distributed computations framework...
Definition: mwworker.h:55
This file contains some precompiler definitions which indicate the operating system and/or compiler u...
This file includes header files with various definitions of full cubes and defines the standard types...
This is the main header file in the MultiWork group which includes all the other header files.
void setstreams(const char *logfilename, char *seqfilename, bool quiet, bool debug)
Sets the parameters of the output streams depending on the file names acquired from the command line.
Definition: arg.h:806
void argstreams(arguments &a, char *&logfilename, char *&seqfilename, bool &quiet, bool &debug)
Adds typical command line arguments for manipulating output streams.
Definition: arg.h:793
void ignoreline(std::istream &in)
Ignores the input characters until the end of a line, including this end of the line.
Definition: textfile.h:376
outputstream sout
A replacement for standard output stream, with optional logging and other features provided by the cl...
std::string commandline(int argc, char *argv[])
Returns the entire command line as a single string.
Definition: textfile.h:441
void arg(arguments &a, const char *name, type &value)
Adds a command line argument.
Definition: arg.h:604
outputstream sbug
An output stream for writing additional debug messages.
timeused program_time
The external variable which measures the time used by the program from its start.
const char * currenttime(void)
Retrieves the current time as a pointer to a C-style string.
Definition: textfile.h:454
void ignorecomments(std::istream &in)
Ignores white characters (spaces, tabulators, CRs and LFs), as well as comments from the input text f...
Definition: textfile.h:385
void argswitch(arguments &arg, const char *name, type &value, const type &defaultvalue)
Defines a command line argument which is a switch, that is, there is no value given for it in the com...
Definition: arg.h:745
outputstream slog
The output stream to which one can send messages for logging only.
void arghelp(arguments &a)
Adds the typical arguments which should make the program display help information.
Definition: arg.h:778
double mwSubdivPoint(const double &left, const double &right, coord part, coord full)
Returns a subdivision point corresponding to the given fraction of the provided interval.
Definition: mwsubdiv.h:202
@ mwNoData
There is no data to be sent to workers, for example, because everything has been already sent.
Definition: mwconfig.h:166
@ mwReject
The data has been rejected.
Definition: mwconfig.h:169
@ mwError
A serious error occurred.
Definition: mwconfig.h:162
@ mwOk
Everything is fine.
Definition: mwconfig.h:159
int(* fcompute)(const double *left, const double *right, int dim, int level)
The type of a function which computes a value of interest for the given product of intervals.
Definition: mwsubdiv.h:102
int mwSubdivMain(int argc, char *argv[], const char *title, const char *helpinfo, int defaultPortNumber, int controlNumber, const double *paramLeft, const double *paramRight, int minSubdivLevel, fcompute compute)
The main procedure for running the computations in the multiwork subdivision framework.
Definition: mwsubdiv.h:1464
This namespace contains the entire CHomP library interface.
Definition: bitmaps.h:51
This file contains the definition of a set of n-dimensional points with integer coordinates and sever...
This file contains some useful functions related to the text input/output procedures.
This file defines a simple data structure which can be used to measure time used by the program (or s...