00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef _coord_h_
00035 #define _coord_h_
00036
00037 #include <iostream>
00038 #include <fstream>
00039 #include <iomanip>
00040 #include <vector>
00041
00042 #include "chomp/system/config.h"
00043 #include "chomp/system/textfile.h"
00044 #include "chomp/system/timeused.h"
00045 #include "chomp/multiwork/mw.h"
00046
00047 #include "bitvect.h"
00048
00049
00050 namespace unifexp {
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 class Coordinator: public chomp::multiwork::mwCoordinator
00061 {
00062 public:
00063
00064 Coordinator (int _controlNumber,
00065 const char *_filename, bool _flushfile,
00066 double _paramMin, double _paramMax, bool _intervals,
00067 double _deltaMin, double _deltaMax, double _resolution,
00068 double _lambdaMin, double _lambdaMax, const char *_mapName,
00069 const char *_partName, int _partCountMin, int _partCountMax,
00070 int _startLevel, int _finalLevel,
00071 int _computeDelta, int _computeDelta0,
00072 int _computeLambda, int _computeC, int _computeLambda0,
00073 int _rigorous, int _sparseGraph);
00074
00075
00076 ~Coordinator ();
00077
00078 private:
00079
00080 int Prepare (chomp::multiwork::mwData &data);
00081
00082
00083 int Accept (chomp::multiwork::mwData &data);
00084
00085
00086 int Reject (chomp::multiwork::mwData &data);
00087
00088
00089
00090
00091 int controlNumber;
00092
00093
00094 std::ofstream f;
00095
00096
00097 bool flushfile;
00098
00099
00100 double paramMin;
00101
00102
00103 double paramMax;
00104
00105
00106 bool intervals;
00107
00108
00109 double deltaMin;
00110
00111
00112 double deltaMax;
00113
00114
00115 double resolution;
00116
00117
00118 double lambdaMin;
00119
00120
00121 double lambdaMax;
00122
00123
00124 std::string mapName;
00125
00126
00127 std::string partName;
00128
00129
00130 int partCountMin;
00131
00132
00133 int partCountMax;
00134
00135
00136
00137
00138
00139 bool readResults (const char *filename);
00140
00141
00142
00143 void openResults (const char *filename, bool newFile);
00144
00145
00146 int currentLevel;
00147
00148
00149 int currentItem;
00150
00151
00152 int startLevel;
00153
00154
00155 int finalLevel;
00156
00157
00158 bool singleItem;
00159
00160
00161 int computeDelta;
00162
00163
00164 int computeDelta0;
00165
00166
00167 int computeLambda;
00168
00169
00170 int computeC;
00171
00172
00173 int computeLambda0;
00174
00175
00176 int rigorous;
00177
00178
00179 int sparseGraph;
00180
00181
00182 std::vector<bitVector *> processed;
00183
00184
00185 int loprec;
00186
00187
00188 int hiprec;
00189
00190
00191 int numberOfItems (int level) const;
00192
00193
00194 void updateProcessed (int level);
00195
00196 };
00197
00198
00199
00200 inline bool Coordinator::readResults (const char *filename)
00201 {
00202 using namespace chomp::homology;
00203
00204
00205 if (!filename && !*filename)
00206 return false;
00207
00208
00209 std::ifstream in (filename);
00210 if (!in)
00211 return false;
00212
00213
00214 ignorecomments (in);
00215 while (in. peek () != EOF)
00216 {
00217 if (in. peek () != '*')
00218 {
00219 ignoreline (in);
00220 ignorecomments (in);
00221 continue;
00222 }
00223 in. get ();
00224 ignorecomments (in);
00225 int cLevel = -1, cColon = -1, cItem = -1;
00226 in >> cLevel;
00227 ignorecomments (in);
00228 cColon = in. get ();
00229 ignorecomments (in);
00230 in >> cItem;
00231 if ((cLevel >= 0) && (cColon == ':') && (cItem >= 0) &&
00232 (cItem < numberOfItems (cLevel)))
00233 {
00234 updateProcessed (cLevel);
00235 processed [cLevel] -> mark (cItem);
00236 }
00237 ignoreline (in);
00238 ignorecomments (in);
00239 }
00240 return true;
00241 }
00242
00243 inline void Coordinator::openResults (const char *filename, bool newFile)
00244 {
00245 using namespace chomp::homology;
00246
00247
00248 if (!filename && !*filename)
00249 return;
00250
00251
00252 f. open (filename, std::ios::out | std::ios::app);
00253 f << "; Started on " << currenttime ();
00254 if (!f)
00255 fileerror (filename);
00256
00257
00258 if (newFile)
00259 {
00260 f << "; level:num parMin parMax k delta lambda logC lambda0 "
00261 "compTime\n";
00262 }
00263
00264
00265 loprec = f. precision ();
00266 hiprec = 15;
00267
00268 return;
00269 }
00270
00271 inline Coordinator::Coordinator (int _controlNumber,
00272 const char *_filename, bool _flushfile,
00273 double _paramMin, double _paramMax, bool _intervals,
00274 double _deltaMin, double _deltaMax, double _resolution,
00275 double _lambdaMin, double _lambdaMax, const char *_mapName,
00276 const char *_partName, int _partCountMin, int _partCountMax,
00277 int _startLevel, int _finalLevel,
00278 int _computeDelta, int _computeDelta0,
00279 int _computeLambda, int _computeC, int _computeLambda0,
00280 int _rigorous, int _sparseGraph):
00281 controlNumber (_controlNumber), flushfile (_flushfile),
00282 paramMin (_paramMin), paramMax (_paramMax), intervals (_intervals),
00283 deltaMin (_deltaMin), deltaMax (_deltaMax), resolution (_resolution),
00284 lambdaMin (_lambdaMin), lambdaMax (_lambdaMax),
00285 mapName (_mapName), partName (_partName),
00286 partCountMin (_partCountMin), partCountMax (_partCountMax),
00287 currentLevel (_startLevel), currentItem (0),
00288 startLevel (_startLevel), finalLevel (_finalLevel),
00289 singleItem (false),
00290 computeDelta (_computeDelta), computeDelta0 (_computeDelta0),
00291 computeLambda (_computeLambda), computeC (_computeC),
00292 computeLambda0 (_computeLambda0), rigorous (_rigorous),
00293 sparseGraph (_sparseGraph),
00294 loprec (6), hiprec (6)
00295 {
00296 using namespace chomp::homology;
00297
00298
00299 if ((startLevel < 0) || (finalLevel < startLevel))
00300 throw "Incorrect start/final levels requested.";
00301
00302
00303 if ((paramMin == paramMax) && (deltaMin == deltaMax) &&
00304 (lambdaMin == lambdaMax) && (partCountMin == partCountMax))
00305 {
00306 singleItem = true;
00307 currentLevel = finalLevel = startLevel = 0;
00308 }
00309
00310
00311 if (paramMin == paramMax)
00312 intervals = false;
00313
00314
00315 if (_filename && *_filename)
00316 {
00317
00318 bool resultsRead = this -> readResults (_filename);
00319 if (!resultsRead)
00320 {
00321 sout << "Note: Could not open the results file. "
00322 "Any previous results will be ignored.\n";
00323 }
00324
00325
00326 openResults (_filename, !resultsRead);
00327 }
00328
00329
00330 else
00331 sout << "Warning: Results will not be saved to a file.";
00332
00333 return;
00334 }
00335
00336 inline Coordinator::~Coordinator ()
00337 {
00338 using namespace chomp::homology;
00339
00340 f << "; Finished on " << currenttime ();
00341 f. close ();
00342 for (std::vector<bitVector *>::iterator it = processed. begin ();
00343 it != processed. end (); ++ it)
00344 {
00345 delete *it;
00346 }
00347 return;
00348 }
00349
00350 inline int Coordinator::numberOfItems (int level) const
00351 {
00352 if (singleItem)
00353 return 1;
00354 else if (!intervals && (level == startLevel))
00355 return (1 << level) + 1;
00356 else
00357 return 1 << level;
00358 }
00359
00360 inline void Coordinator::updateProcessed (int level)
00361 {
00362 while (processed. size () <= static_cast<unsigned> (level))
00363 {
00364 int nItems = numberOfItems (processed. size ());
00365 processed. push_back (new bitVector (nItems));
00366 }
00367 return;
00368 }
00369
00370 inline int Coordinator::Prepare (chomp::multiwork::mwData &data)
00371 {
00372 using namespace chomp::homology;
00373 using namespace chomp::multiwork;
00374
00375
00376 data. Reset ();
00377
00378
00379 int nItems = 0;
00380 while (1)
00381 {
00382
00383 updateProcessed (currentLevel);
00384 nItems = numberOfItems (currentLevel);
00385 if (currentItem < nItems)
00386 {
00387 currentItem = processed [currentLevel] ->
00388 findUnmarked (currentItem, nItems);
00389 }
00390
00391
00392 if ((currentItem < nItems) && !intervals &&
00393 (currentLevel != startLevel) && !(currentItem & 1))
00394 {
00395 ++ currentItem;
00396 continue;
00397 }
00398
00399
00400 if (currentItem < nItems)
00401 {
00402 processed [currentLevel] -> mark (currentItem);
00403 break;
00404 }
00405
00406
00407 if (currentLevel == finalLevel)
00408 return mwNoData;
00409
00410
00411 ++ currentLevel;
00412 currentItem = 0;
00413 }
00414
00415
00416 double paramMin1 = (paramMin == paramMax) ? paramMin : (paramMin +
00417 currentItem * (paramMax - paramMin) / (1 << currentLevel));
00418 double paramMax1 = intervals ? (paramMin + (currentItem + 1) *
00419 (paramMax - paramMin) / (1 << currentLevel)) : paramMin1;
00420 double delta1 = (deltaMin == deltaMax) ? deltaMin :
00421 exp (log (deltaMin) + currentItem * (log (deltaMax) -
00422 log (deltaMin)) / (1 << currentLevel));
00423 double lambda1 = (lambdaMin == lambdaMax) ? lambdaMin : (lambdaMin +
00424 currentItem * (lambdaMax - lambdaMin) / (1 << currentLevel));
00425 int partCount1 = (partCountMin == partCountMax) ? partCountMin :
00426 static_cast <int> ((partCountMin +
00427 static_cast<double> (currentItem) *
00428 (partCountMax - partCountMin) / (1 << currentLevel)));
00429
00430
00431 data << currentLevel;
00432 data << currentItem;
00433 data << mapName;
00434 data << partName;
00435 data << partCount1;
00436 data << paramMin1;
00437 data << paramMax1;
00438 data << delta1;
00439 data << resolution;
00440 data << lambda1;
00441 data << computeDelta;
00442 data << computeDelta0;
00443 data << computeLambda;
00444 data << computeC;
00445 data << computeLambda0;
00446 data << rigorous;
00447 data << sparseGraph;
00448 data << loprec;
00449 data << hiprec;
00450 data << controlNumber;
00451
00452
00453 sout << "+ " << currentLevel << ":" << currentItem << ".\n";
00454
00455 ++ currentItem;
00456 return mwOk;
00457 }
00458
00459 inline int Coordinator::Accept (chomp::multiwork::mwData &data)
00460 {
00461 using namespace chomp::homology;
00462 using namespace chomp::multiwork;
00463
00464
00465 int cLevel = 0, cItem = 0;
00466 data >> cLevel;
00467 data >> cItem;
00468 double pMin = 0;
00469 double pMax = 0;
00470 data >> pMin;
00471 data >> pMax;
00472 int partCount = 0;
00473 data >> partCount;
00474 double deltaBad = 0;
00475 double delta = 0;
00476 double lambda = 0;
00477 double logC = 0;
00478 double lambda0 = 0;
00479 data >> deltaBad;
00480 data >> delta;
00481 data >> lambda;
00482 data >> logC;
00483 data >> lambda0;
00484 double compTime = 0;
00485 data >> compTime;
00486 int ctrl = 0;
00487 data >> ctrl;
00488 if (ctrl != controlNumber)
00489 {
00490 f << "! Wrong data received.\n";
00491 throw "Wrong data received from a worker.";
00492 }
00493
00494
00495 sout << "* " << cLevel << ":" << cItem << " [" << pMin << "," <<
00496 pMax << "] k=" << partCount << " d=" << delta <<
00497 " l=" << lambda << " lC=" << logC << " l0=" << lambda0 <<
00498 " (" << compTime << "s)" << "\n";
00499
00500
00501 f << "* " << cLevel << ":" << cItem << " " <<
00502 pMin << " " << pMax << " " << partCount << " " <<
00503 std::setprecision (hiprec) << delta << " " <<
00504 lambda << " " << logC << " " << lambda0 << " " <<
00505 std::setprecision (loprec) << compTime << "\n";
00506
00507
00508 if (flushfile)
00509 f << std::flush;
00510
00511 return mwOk;
00512 }
00513
00514 inline int Coordinator::Reject (chomp::multiwork::mwData &data)
00515 {
00516 using namespace chomp::homology;
00517 using namespace chomp::multiwork;
00518
00519
00520 int cLevel = 0, cItem = 0;
00521 data >> cLevel;
00522 data >> cItem;
00523
00524
00525 sout << "Data " << cLevel << ":" << cItem << " has been rejected.\n";
00526 throw "Data rejected by a worker.";
00527
00528 return mwOk;
00529 }
00530
00531
00532 }
00533
00534 #endif // _coord_h_
00535
00536
00537