00001
00009 #ifndef __CONTROLPOINTS_H__
00010 #define __CONTROLPOINTS_H__
00011
00012 #include "conv-config.h"
00013
00014 #if CMK_WITH_CONTROLPOINT
00015
00016
00017 #include "ControlPoints.decl.h"
00018
00019 #include <vector>
00020 #include <map>
00021 #include <cmath>
00022 #include <pup_stl.h>
00023 #include <string>
00024 #include <set>
00025 #include <cmath>
00026 #include <math.h>
00027 #include <iostream>
00028 #include <iomanip>
00029 #include <fstream>
00030 #include <string>
00031 #include <sstream>
00032 #include <set>
00033 #include <vector>
00034 #include <utility>
00035 #include <limits>
00036 #include <algorithm>
00037 #include <float.h>
00038 #include <charm-api.h>
00039
00040 #include "LBDatabase.h"
00041 #include "arrayRedistributor.h"
00042 #include "pathHistory.h"
00043
00044
00045 #include <cp_effects.h>
00046
00052 #define DEBUG 0
00053
00054 extern CProxy_controlPointManager controlPointManagerProxy;
00055 extern int random_seed;
00056 extern long controlPointSamplePeriod;
00057 extern int whichTuningScheme;
00058 extern bool writeDataFileAtShutdown;
00059 extern bool shouldFilterOutputData;
00060 extern bool loadDataFileAtStartup;
00061 extern char CPDataFilename[512];
00062
00063
00064
00065 void registerCPChangeCallback(CkCallback cb, bool frameworkShouldAdvancePhase);
00066
00067 void setFrameworkAdvancePhase(bool frameworkShouldAdvancePhase);
00068
00069
00070 void registerControlPointTiming(double time);
00071
00073 void controlPointTimingStamp();
00074 FLINKAGE void FTN_NAME(CONTROLPOINTTIMINGSTAMP,controlpointtimingstamp)();
00075
00076
00080 void gotoNextPhase();
00081 FLINKAGE void FTN_NAME(GOTONEXTPHASE,gotonextphase)();
00082
00085 int controlPoint2Pow(const char *name, int c1, int c2);
00086
00089 int controlPoint(const char *name, int lb, int ub);
00090
00093 FLINKAGE int FTN_NAME(CONTROLPOINT,controlpoint)(CMK_TYPEDEF_INT4 *lb, CMK_TYPEDEF_INT4 *ub);
00094
00095
00098 int controlPoint(const char *name, std::vector<int>& values);
00099
00101 void ControlPointWriteOutputToDisk();
00102
00106 void gotoNextPhase();
00107
00108
00109
00110
00112 class controlPointMsg : public CMessage_controlPointMsg {
00113 public:
00114 char *data;
00115 };
00116
00117
00118
00119
00120
00122 class idleTimeContainer {
00123 public:
00124 double min;
00125 double avg;
00126 double max;
00127
00128 idleTimeContainer(){
00129 min = -1.0;
00130 max = -1.0;
00131 avg = -1.0;
00132 }
00133
00134 bool isValid() const{
00135 return (min >= 0.0 && avg >= min && max >= avg && max <= 1.0);
00136 }
00137
00138 void print() const{
00139 if(isValid())
00140 CkPrintf("[%d] Idle Time is Min=%.2lf%% Avg=%.2lf%% Max=%.2lf%%\n", CkMyPe(), min*100.0, avg*100.0, max*100.0);
00141 else
00142 CkPrintf("[%d] Idle Time is invalid\n", CkMyPe(), min*100.0, avg*100.0, max*100.0);
00143 }
00144
00145 };
00146
00147
00149 class overheadContainer {
00150 public:
00151 double min;
00152 double avg;
00153 double max;
00154
00155 overheadContainer(){
00156 min = -1.0;
00157 max = -1.0;
00158 avg = -1.0;
00159 }
00160
00161 bool isValid() const{
00162 return (min >= 0.0 && avg >= min && max >= avg && max <= 1.0);
00163 }
00164
00165 void print() const{
00166 if(isValid())
00167 CkPrintf("[%d] Overhead Time is Min=%.2lf%% Avg=%.2lf%% Max=%.2lf%%\n", CkMyPe(), min*100.0, avg*100.0, max*100.0);
00168 else
00169 CkPrintf("[%d] Overhead Time is invalid\n", CkMyPe(), min*100.0, avg*100.0, max*100.0);
00170 }
00171
00172 };
00173
00174
00175
00179 class instrumentedPhase {
00180 public:
00181 std::map<std::string,int> controlPoints;
00182 std::vector<double> times;
00183
00184 #if USE_CRITICAL_PATH_HEADER_ARRAY
00185 std::vector<PathHistoryTableEntry> criticalPaths;
00186 #endif
00187
00188 double memoryUsageMB;
00189
00190 idleTimeContainer idleTime;
00191 overheadContainer overheadTime;
00192
00193
00195 double bytesPerInvoke;
00196
00198 double grainSize;
00199
00200
00201 instrumentedPhase(){
00202 memoryUsageMB = -1.0;
00203 grainSize = -1.0;
00204 bytesPerInvoke = -1.0;
00205 }
00206
00207 void clear(){
00208 controlPoints.clear();
00209 times.clear();
00210 memoryUsageMB = -1.0;
00211 grainSize = -1.0;
00212 bytesPerInvoke = -1.0;
00213
00214 }
00215
00216
00217 bool haveValueForName(const char* name){
00218 std::string n(name);
00219 return (controlPoints.count(n)>0);
00220 }
00221
00222 void operator=(const instrumentedPhase& p){
00223 controlPoints = p.controlPoints;
00224 times = p.times;
00225 memoryUsageMB = p.memoryUsageMB;
00226 }
00227
00228
00229
00230 bool operator<(const instrumentedPhase& p){
00231 CkAssert(hasSameKeysAs(p));
00232 std::map<std::string,int>::iterator iter1 = controlPoints.begin();
00233 std::map<std::string,int>::const_iterator iter2 = p.controlPoints.begin();
00234 for(;iter1 != controlPoints.end() && iter2 != p.controlPoints.end(); iter1++, iter2++){
00235 if(iter1->second < iter2->second){
00236 return true;
00237 }
00238 }
00239 return false;
00240 }
00241
00242
00243
00244 bool hasValidControlPointValues(){
00245 std::map<std::string,int>::iterator iter;
00246 for(iter = controlPoints.begin();iter != controlPoints.end(); iter++){
00247 if(iter->second == -1){
00248 return false;
00249 }
00250 }
00251 return true;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 bool operator==(const instrumentedPhase& p){
00285 CkAssert(hasSameKeysAs(p));
00286 std::map<std::string,int>::iterator iter1 = controlPoints.begin();
00287 std::map<std::string,int>::const_iterator iter2 = p.controlPoints.begin();
00288 for(;iter1 != controlPoints.end() && iter2 != p.controlPoints.end(); iter1++, iter2++){
00289 if(iter1->second != iter2->second){
00290 return false;
00291 }
00292 }
00293 return true;
00294 }
00295
00298 bool hasSameKeysAs(const instrumentedPhase& p){
00299
00300 if(controlPoints.size() != p.controlPoints.size())
00301 return false;
00302
00303 std::map<std::string,int>::iterator iter1 = controlPoints.begin();
00304 std::map<std::string,int>::const_iterator iter2 = p.controlPoints.begin();
00305
00306 for(;iter1 != controlPoints.end() && iter2 != p.controlPoints.end(); iter1++, iter2++){
00307 if(iter1->first != iter2->first)
00308 return false;
00309 }
00310
00311 return true;
00312 }
00313
00314
00315 void addAllNames(std::set<std::string> names_) {
00316
00317 std::set<std::string> names = names_;
00318
00319
00320 std::map<std::string,int>::iterator iter;
00321
00322 for(iter = controlPoints.begin(); iter != controlPoints.end(); iter++){
00323 names.erase(iter->first);
00324 }
00325
00326
00327 std::set<std::string>::iterator iter2;
00328 for(iter2 = names.begin(); iter2 != names.end(); iter2++){
00329 controlPoints.insert(std::make_pair(*iter2,-1));
00330 CkPrintf("One of the datasets was missing a value for %s, so -1 was used\n", iter2->c_str());
00331 }
00332
00333 }
00334
00335
00336
00337 void print() const {
00338 std::map<std::string,int>::const_iterator iter;
00339
00340 if(controlPoints.size() == 0){
00341 CkPrintf("no control point values found\n");
00342 }
00343
00344 for(iter = controlPoints.begin(); iter != controlPoints.end(); iter++){
00345 const std::string name = iter->first;
00346 const int val = iter->second;
00347 CkPrintf("%s ---> %d\n", name.c_str(), val);
00348 }
00349
00350 }
00351
00353 double medianTime(){
00354 std::vector<double> sortedTimes = times;
00355 std::sort(sortedTimes.begin(), sortedTimes.end());
00356 if(sortedTimes.size()>0){
00357 return sortedTimes[sortedTimes.size() / 2];
00358 } else {
00359 CkAbort("Cannot compute medianTime for empty sortedTimes vector");
00360 return -1;
00361 }
00362 }
00363
00364
00365 };
00366
00367
00369 class instrumentedData {
00370 public:
00371
00373 std::vector<instrumentedPhase*> phases;
00374
00376 std::set<std::string> getNames(){
00377 std::set<std::string> names;
00378
00379 std::vector<instrumentedPhase*>::iterator iter;
00380 for(iter = phases.begin();iter!=phases.end();iter++) {
00381
00382 std::map<std::string,int>::iterator iter2;
00383 for(iter2 = (*iter)->controlPoints.begin(); iter2 != (*iter)->controlPoints.end(); iter2++){
00384 names.insert(iter2->first);
00385 }
00386
00387 }
00388 return names;
00389
00390 }
00391
00392
00393 void cleanupNames(){
00394 std::set<std::string> names = getNames();
00395
00396 std::vector<instrumentedPhase*>::iterator iter;
00397 for(iter = phases.begin();iter!=phases.end();iter++) {
00398 (*iter)->addAllNames(names);
00399 }
00400 }
00401
00402
00404 bool filterOutOnePhase(){
00405 #if 1
00406
00407 std::vector<instrumentedPhase*>::iterator iter;
00408 for(iter = phases.begin(); iter != phases.end(); iter++) {
00409 if(! (*iter)->hasValidControlPointValues() || (*iter)->times.size()==0){
00410
00411 phases.erase(iter);
00412 return true;
00413 } else {
00414
00415 }
00416 }
00417 #endif
00418 return false;
00419 }
00420
00422 void filterOutIncompletePhases(){
00423 bool done = false;
00424 while(filterOutOnePhase()){
00425
00426 }
00427 }
00428
00429
00430 std::string toString(){
00431 std::ostringstream s;
00432
00433
00434 s << "# HEADER:\n";
00435 s << "# Data for use with Isaac Dooley's Control Point Framework\n";
00436 s << "# Number of instrumented timings in this file:\n";
00437 s << phases.size() << "\n" ;
00438
00439 if(phases.size() > 0){
00440
00441 std::map<std::string,int> &ps = phases[0]->controlPoints;
00442 std::map<std::string,int>::iterator cpiter;
00443
00444
00445 s << "# SCHEMA:\n";
00446 s << "# number of named control points:\n";
00447 s << ps.size() << "\n";
00448 for(cpiter = ps.begin(); cpiter != ps.end(); cpiter++){
00449 s << cpiter->first << "\n";
00450 }
00451
00452
00453 s << "# DATA:\n";
00454 s << "# There are " << ps.size() << " control points\n";
00455 s << "# number of recorded phases: " << phases.size() << "\n";
00456
00457 s << "# Memory (MB)\tIdle Min\tIdle Avg\tIdle Max\tOverhead Min\tOverhead Avg\tOverhead Max\tByte Per Invoke\tGrain Size\t";
00458 for(cpiter = ps.begin(); cpiter != ps.end(); cpiter++){
00459 s << cpiter->first << "\t";
00460 }
00461 s << "Median Timing\tTimings\n";
00462
00463
00464 std::vector<instrumentedPhase*>::iterator runiter;
00465 for(runiter=phases.begin();runiter!=phases.end();runiter++){
00466
00467
00468 s << (*runiter)->memoryUsageMB << "\t";
00469
00470 s << (*runiter)->idleTime.min << "\t" << (*runiter)->idleTime.avg << "\t" << (*runiter)->idleTime.max << "\t";
00471 s << (*runiter)->overheadTime.min << "\t" << (*runiter)->overheadTime.avg << "\t" << (*runiter)->overheadTime.max << "\t";
00472
00473
00474 s << (*runiter)->bytesPerInvoke << "\t";
00475
00476 s << (*runiter)->grainSize << "\t";
00477
00478
00479
00480 for(cpiter = (*runiter)->controlPoints.begin(); cpiter != (*runiter)->controlPoints.end(); cpiter++){
00481 s << cpiter->second << "\t";
00482 }
00483
00484
00485 if((*runiter)->times.size()>0){
00486 s << (*runiter)->medianTime() << "\t";
00487 } else {
00488 s << "-1\t";
00489 }
00490
00491
00492 std::vector<double>::iterator titer;
00493 for(titer = (*runiter)->times.begin(); titer != (*runiter)->times.end(); titer++){
00494 s << *titer << " ";
00495 }
00496
00497 s << "\n";
00498
00499 }
00500
00501 }
00502
00503 return s.str();
00504
00505 }
00506
00507
00509 void verify(){
00510 if(phases.size() > 1){
00511 instrumentedPhase *firstpoint = phases[0];
00512 std::vector<instrumentedPhase*>::iterator iter;
00513 for(iter = phases.begin();iter!=phases.end();iter++){
00514 CkAssert( firstpoint->hasSameKeysAs(*(*iter)));
00515 }
00516 }
00517 }
00518
00519
00520
00521 instrumentedPhase* findBest(){
00522 CkAssert(phases.size()>1);
00523
00524 double total_time = 0.0;
00525 int total_count = 0;
00526
00527 instrumentedPhase * best_phase;
00528
00529 #if OLDMAXDOUBLE
00530 double best_phase_avgtime = std::numeric_limits<double>::max();
00531 #else
00532 double best_phase_avgtime = DBL_MAX;
00533 #endif
00534
00535 int valid_phase_count = 0;
00536
00537 std::vector<instrumentedPhase*>::iterator iter;
00538 for(iter = phases.begin();iter!=phases.end();iter++){
00539 if((*iter)->hasValidControlPointValues()){
00540 valid_phase_count++;
00541
00542 double total_for_phase = 0.0;
00543 int phase_count = 0;
00544
00545
00546 std::vector<double>::iterator titer;
00547 for(titer = (*iter)->times.begin(); titer != (*iter)->times.end(); titer++){
00548 total_count++;
00549 total_time += *titer;
00550 total_for_phase += *titer;
00551 phase_count ++;
00552 }
00553
00554 double phase_average_time = total_for_phase / (double)phase_count;
00555
00556 if(phase_average_time < best_phase_avgtime){
00557 best_phase = *iter;
00558 best_phase_avgtime = phase_average_time;
00559 }
00560
00561 }
00562 }
00563
00564 CkAssert(total_count > 0);
00565
00566 double avg = total_time / total_count;
00567
00568 if(CkMyPe() == 0){
00569 CkPrintf("Best average time for a phase was %.1lf\n", best_phase_avgtime);
00570 CkPrintf("Mean time for all %d times in the %d valid recorded phases was %.1lf\n", total_count, valid_phase_count, avg );
00571 }
00572
00573
00574 double sumx=0.0;
00575 for(iter = phases.begin();iter!=phases.end();iter++){
00576 if((*iter)->hasValidControlPointValues()){
00577 std::vector<double>::iterator titer;
00578 for(titer = (*iter)->times.begin(); titer != (*iter)->times.end(); titer++){
00579 sumx += (avg - *titer)*(avg - *titer);
00580 }
00581 }
00582 }
00583
00584 double std_dev = sqrt(sumx / total_count);
00585
00586 if(CkMyPe() == 0){
00587 CkPrintf("Standard Deviation for previous runs was %.2lf or %.1lf%% of mean\n", std_dev, std_dev/avg*100.0);
00588 CkPrintf("The best phase average time was %.1lf%% faster than the mean\n", (avg-best_phase_avgtime)/avg*100.0);
00589
00590 }
00591
00592 return best_phase;
00593 }
00594
00595 };
00596
00597
00599 class simplexScheme {
00600 private:
00604 typedef enum simplexStateEnumT {beginning, reflecting, expanding, contracting, doneExpanding, stillContracting} simplexStateT;
00605
00607 std::set<int> simplexIndices;
00608 simplexStateT simplexState;
00609
00611 double alpha;
00612
00613 double beta;
00614
00615 double gamma;
00616
00617
00619 int firstSimplexPhase;
00620
00621
00622 int worstPhase;
00623 double worstTime;
00624 std::vector<double> worst;
00625
00626
00627 std::vector<double> centroid;
00628
00629
00630 int bestPhase;
00631 double bestTime;
00632 std::vector<double> best;
00633
00634
00635 std::vector<double> P;
00636 int pPhase;
00637
00638
00639 std::vector<double> P2;
00640 int p2Phase;
00641
00642
00643 std::set<int> stillMustContractList;
00644
00645 bool useBestKnown;
00646
00647 void computeCentroidBestWorst(std::map<std::string, std::pair<int,int> > & controlPointSpace, std::map<std::string,int> &newControlPoints, const int phase_id, instrumentedData &allData);
00648
00649 void doReflection(std::map<std::string, std::pair<int,int> > & controlPointSpace, std::map<std::string,int> &newControlPoints, const int phase_id, instrumentedData &allData);
00650 void doExpansion(std::map<std::string, std::pair<int,int> > & controlPointSpace, std::map<std::string,int> &newControlPoints, const int phase_id, instrumentedData &allData);
00651 void doContraction(std::map<std::string, std::pair<int,int> > & controlPointSpace, std::map<std::string,int> &newControlPoints, const int phase_id, instrumentedData &allData);
00652
00653
00654 std::vector<double> pointCoords(instrumentedData &allData, int i);
00655
00656 inline int keepInRange(int v, int lb, int ub){
00657 if(v < lb)
00658 return lb;
00659 if(v > ub)
00660 return ub;
00661 return v;
00662 }
00663
00664 void printSimplex(instrumentedData &allData){
00665 char s[2048];
00666 s[0] = '\0';
00667 for(std::set<int>::iterator iter = simplexIndices.begin(); iter != simplexIndices.end(); ++iter){
00668 sprintf(s+strlen(s), "%d: ", *iter);
00669
00670 for(std::map<std::string,int>::iterator citer = allData.phases[*iter]->controlPoints.begin(); citer != allData.phases[*iter]->controlPoints.end(); ++citer){
00671 sprintf(s+strlen(s), " %d", citer->second);
00672 }
00673
00674 sprintf(s+strlen(s), "\n");
00675 }
00676 CkPrintf("Current simplex is:\n%s\n", s);
00677 }
00678
00679 public:
00680
00681 simplexScheme() :
00682 simplexState(beginning),
00683 alpha(1.0), beta(0.5), gamma(2.0),
00684 firstSimplexPhase(-1),
00685 useBestKnown(false)
00686 {
00687
00688 CkAssert(alpha >= 0);
00689 CkAssert(beta >= 0.0 && beta <= 1.0);
00690 CkAssert(gamma >= 1.0);
00691 }
00692
00693 void adapt(std::map<std::string, std::pair<int,int> > & controlPointSpace, std::map<std::string,int> &newControlPoints, const int phase_id, instrumentedData &allData);
00694
00695 };
00696
00697
00698
00699 class controlPointManager : public CBase_controlPointManager {
00700 public:
00701
00702 instrumentedData allData;
00703
00705 std::map<std::string, std::pair<int,int> > controlPointSpace;
00706
00708 std::set<std::string> staticControlPoints;
00709
00711 std::map<std::string, std::set<int> > affectsPrioritiesEP;
00713 std::map<std::string, std::set<int> > affectsPrioritiesArray;
00714
00715
00717 std::map<std::string,int> newControlPoints;
00718 int generatedPlanForStep;
00719
00720 simplexScheme s;
00721
00722
00724 CkCallback controlPointChangeCallback;
00725 bool haveControlPointChangeCallback;
00726 bool frameworkShouldAdvancePhase;
00727
00728 int phase_id;
00729
00730 bool alreadyRequestedMemoryUsage;
00731 bool alreadyRequestedIdleTime;
00732 bool alreadyRequestedAll;
00733
00734 bool exitWhenReady;
00735
00736
00737 controlPointManager();
00738
00739 ~controlPointManager();
00740
00741 void pup(PUP::er &p);
00742
00743 controlPointManager(CkMigrateMessage* m) : CBase_controlPointManager(m) {
00744
00745 }
00746
00747
00749 void loadDataFile();
00750
00752 void writeDataFile();
00753
00755 void setCPCallback(CkCallback cb, bool _frameworkShouldAdvancePhase);
00756
00757 void setFrameworkAdvancePhase(bool _frameworkShouldAdvancePhase);
00758
00761 void processControlPoints();
00762
00764 bool controlPointAffectsThisEP(int ep);
00765
00767 bool controlPointAffectsThisArray(int array);
00768
00770 void generatePlan();
00771
00773 instrumentedPhase *currentPhaseData();
00774
00776 instrumentedPhase *previousPhaseData();
00777
00779 instrumentedPhase *twoAgoPhaseData();
00780
00782 void gotoNextPhase();
00783
00785 void setTiming(double time);
00786
00788 void checkForShutdown();
00789
00794 void exitIfReady();
00795
00797 void doExitNow();
00798
00800 void writeOutputToDisk();
00801
00802
00804 void requestMemoryUsage(CkCallback cb);
00806 void gatherMemoryUsage(CkReductionMsg *msg);
00807
00808
00810 void requestIdleTime(CkCallback cb);
00812 void gatherIdleTime(CkReductionMsg *msg);
00813
00814
00816 void requestAll(CkCallback cb);
00818 void gatherAll(CkReductionMsg *msg);
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829 };
00830
00831 #endif
00832
00834 #endif