Merge branch 'charm' of charmgit:charm into charm
authorIsaac Dooley <idooley2@krakenpf1.nics.utk.edu>
Tue, 26 Jan 2010 18:06:46 +0000 (13:06 -0500)
committerIsaac Dooley <idooley2@krakenpf1.nics.utk.edu>
Tue, 26 Jan 2010 18:06:46 +0000 (13:06 -0500)
1  2 
src/ck-cp/controlPoints.C

index 0eaca99b25b7441fc91a333dedae29b1e6fa0139,2dd0ce32aafa520695075763e4eddb94e2f04915..9698c61a7186b578a967a3ab74ca5009217251cb
@@@ -40,6 -40,13 +40,13 @@@ static void periodicProcessControlPoint
  /* readonly */ bool shouldGatherAll;
  
  
+ /// The control point values to be used for the first few phases if the strategy doesn't choose to do something else.
+ /// These probably come from the command line arguments, so are available only on PE 0
+ std::map<std::string, int> defaultControlPointValues;
  typedef enum tuningSchemeEnum {RandomSelection, SimulatedAnnealing, ExhaustiveSearch, CriticalPathAutoPrioritization, UseBestKnownTiming, UseSteering, MemoryAware}  tuningScheme;
  
  
@@@ -103,21 -110,16 +110,16 @@@ CkReductionMsg *idleTimeReduction(int n
  /// A reduction type that combines idle, overhead, and memory measurements
  CkReduction::reducerType allMeasuresReductionType;
  /// A reducer that combines idle, overhead, and memory measurements
+ #define ALL_REDUCTION_SIZE 12
  CkReductionMsg *allMeasuresReduction(int nMsg,CkReductionMsg **msgs){
-   double ret[7];
+   double ret[ALL_REDUCTION_SIZE];
    if(nMsg > 0){
-     CkAssert(msgs[0]->getSize()==7*sizeof(double));
+     CkAssert(msgs[0]->getSize()==ALL_REDUCTION_SIZE*sizeof(double));
      double *m=(double *)msgs[0]->getData();
-     ret[0]=m[0];
-     ret[1]=m[1];
-     ret[2]=m[2];
-     ret[3]=m[3];
-     ret[4]=m[4];
-     ret[5]=m[5];
-     ret[6]=m[6];
+     memcpy(ret, m, ALL_REDUCTION_SIZE*sizeof(double) );
    }
    for (int i=1;i<nMsg;i++) {
-     CkAssert(msgs[i]->getSize()==7*sizeof(double));
+     CkAssert(msgs[i]->getSize()==ALL_REDUCTION_SIZE*sizeof(double));
      double *m=(double *)msgs[i]->getData();
      // idle time (min/sum/max)
      ret[0]=min(ret[0],m[0]);
      ret[5]=max(ret[5],m[5]);
      // mem usage (max)
      ret[6]=max(ret[6],m[6]);
+     // bytes per invocation for two types of entry methods
+     ret[7]+=m[7];
+     ret[8]+=m[8];
+     ret[9]+=m[9];
+     ret[10]+=m[10];
+     // Grain size (avg)
+     ret[11]+=m[11];
    }  
-   return CkReductionMsg::buildNew(7*sizeof(double),ret);   
+   return CkReductionMsg::buildNew(ALL_REDUCTION_SIZE*sizeof(double),ret);   
  }
  
  
@@@ -269,10 -278,17 +278,17 @@@ controlPointManager::controlPointManage
        iss >> ips->memoryUsageMB;
        //     CkPrintf("Memory usage loaded from file: %d\n", ips.memoryUsageMB);
  
+       // Read idle time
        iss >> ips->idleTime.min;
        iss >> ips->idleTime.avg;
        iss >> ips->idleTime.max;
  
+       // read bytePerInvoke
+       iss >> ips->bytesPerInvoke;
+       // read grain size
+       iss >> ips->grainSize;
        // Read control point values
        for(int cp=0;cp<numControlPointNames;cp++){
        int cpvalue;
        ips->controlPoints.insert(make_pair(names[cp],cpvalue));
        }
  
+       // ignore median time
+       double mt;
+       iss >> mt;
+       // Read all times
        double time;
  
        while(iss >> time){
    }
  
    /// User can register a callback that is called when application should advance to next phase
-   void controlPointManager::setGranularityCallback(CkCallback cb, bool _frameworkShouldAdvancePhase){
+   void controlPointManager::setCPCallback(CkCallback cb, bool _frameworkShouldAdvancePhase){
      frameworkShouldAdvancePhase = _frameworkShouldAdvancePhase;
      granularityCallback = cb;
      haveGranularityCallback = true;
  
    /// Entry method called on all PEs to request CPU utilization statistics and memory usage
    void controlPointManager::requestAll(CkCallback cb){
-     const double i = localControlPointTracingInstance()->idleRatio();
-     const double o = localControlPointTracingInstance()->overheadRatio();
-     const double m = localControlPointTracingInstance()->memoryUsageMB();
-     
-     double data[3+3+1];
+     TraceControlPoints *t = localControlPointTracingInstance();
+     double data[ALL_REDUCTION_SIZE];
  
      double *idle = data;
      double *over = data+3;
      double *mem = data+6;
+     double *msgBytes = data+7;  
+     double *grainsize = data+11;  
  
+     const double i = t->idleRatio();
      idle[0] = i;
      idle[1] = i;
      idle[2] = i;
  
+     const double o = t->overheadRatio();
      over[0] = o;
      over[1] = o;
      over[2] = o;
  
+     const double m = t->memoryUsageMB();
      mem[0] = m;
+     msgBytes[0] = t->b2;
+     msgBytes[1] = t->b3;
+     msgBytes[2] = t->b2mlen;
+     msgBytes[3] = t->b3mlen;
+     grainsize[0] = t->grainSize();
      
      localControlPointTracingInstance()->resetAll();
  
-     contribute(7*sizeof(double),data,allMeasuresReductionType, cb);
+     contribute(ALL_REDUCTION_SIZE*sizeof(double),data,allMeasuresReductionType, cb);
    }
    
    /// All processors reduce their memory usages in requestIdleTime() to this method
    void controlPointManager::gatherAll(CkReductionMsg *msg){
+     CkAssert(msg->getSize()==ALL_REDUCTION_SIZE*sizeof(double));
      int size=msg->getSize() / sizeof(double);
-     CkAssert(size==7);
      double *data=(double *) msg->getData();
          
      double *idle = data;
      double *over = data+3;
      double *mem = data+6;
+     double *msgBytes = data+7;
+     double *granularity = data+11;
  
      //    std::string b = allData.toString();
  
        
        CkPrintf("Stored idle time min=%lf, mem=%lf in prevPhase=%p\n", (double)prevPhase->idleTime.min, (double)prevPhase->memoryUsageMB, prevPhase);
  
+       double bytesPerInvoke2 = msgBytes[2] / msgBytes[0];
+       double bytesPerInvoke3 = msgBytes[3] / msgBytes[1];
+       /** The average of the grain sizes on all PEs in us */
+       prevPhase->grainSize = (granularity[0] / (double)CkNumPes());
+       CkPrintf("Bytes Per Invokation 2 = %f\n", bytesPerInvoke2);
+       CkPrintf("Bytes Per Invokation 3 = %f\n", bytesPerInvoke3);
+       CkPrintf("Bytes Per us of work 2 = %f\n", bytesPerInvoke2/prevPhase->grainSize);
+       CkPrintf("Bytes Per us of work 3 = %f\n", bytesPerInvoke3/prevPhase->grainSize);
+       if(bytesPerInvoke2 > bytesPerInvoke3)
+       prevPhase->bytesPerInvoke = bytesPerInvoke2;
+       else
+       prevPhase->bytesPerInvoke = bytesPerInvoke3;
        //      prevPhase->print();
        // CkPrintf("prevPhase=%p number of timings=%d\n", prevPhase, prevPhase->times.size() );
  
@@@ -909,8 -961,8 +961,8 @@@ public
      int usec = (int)((time - (double)sec)*1000000.0);
      random_seed =  sec ^ usec;
  #endif
+     
+     
      double period;
      bool haveSamplePeriod = CmiGetArgDoubleDesc(args->argv,"+CPSamplePeriod", &period,"The time between Control Point Framework samples (in seconds)");
      if(haveSamplePeriod){
      } else {
        controlPointSamplePeriod =  DEFAULT_CONTROL_POINT_SAMPLE_PERIOD;
      }
+     
+     
+     
      whichTuningScheme = RandomSelection;
  
  
        whichTuningScheme = MemoryAware;
      }
  
+     char *defValStr = NULL;
+     if( CmiGetArgStringDesc(args->argv, "+CPDefaultValues", &defValStr, "Specify the default control point values used for the first couple phases") ){
+       CkPrintf("You specified default value string: %s\n", defValStr);
+       
+       // Parse the string, looking for commas
+      
+       char *tok = strtok(defValStr, ",");
+       while (tok) {
+       // split on the equal sign
+       int len = strlen(tok);
+       char *eqsign = strchr(tok, '=');
+       if(eqsign != NULL && eqsign != tok){
+         *eqsign = '\0';
+         char *cpname = tok;
+         std::string cpName(tok);
+         char *cpDefVal = eqsign+1;      
+         int v=-1;
+         if(sscanf(cpDefVal, "%d", &v) == 1){
+           CkPrintf("Command Line Argument Specifies that Control Point \"%s\" defaults to %d\n", cpname, v);
+           CkAssert(CkMyPe() == 0); // can only access defaultControlPointValues on PE 0
+           defaultControlPointValues[cpName] = v;
+         }
+       }
+       tok = strtok(NULL, ",");
+       }
+     }
  
      shouldGatherAll = false;
      shouldGatherMemoryUsage = false;
        loadDataFileAtStartup = true;
      }
  
      controlPointManagerProxy = CProxy_controlPointManager::ckNew();
    }
    ~controlPointMain(){}
  };
  
  /// An interface callable by the application.
- void registerGranularityChangeCallback(CkCallback cb, bool frameworkShouldAdvancePhase){
+ void registerCPChangeCallback(CkCallback cb, bool frameworkShouldAdvancePhase){
    CkAssert(CkMyPe() == 0);
    CkPrintf("Application has registered a control point change callback\n");
-   controlPointManagerProxy.ckLocalBranch()->setGranularityCallback(cb, frameworkShouldAdvancePhase);
+   controlPointManagerProxy.ckLocalBranch()->setCPCallback(cb, frameworkShouldAdvancePhase);
  }
  
  /// An interface callable by the application.
@@@ -1083,7 -1164,7 +1164,7 @@@ void controlPointManager::generatePlan(
      instrumentedPhase *twoAgoPhase = twoAgoPhaseData();
      instrumentedPhase *prevPhase = previousPhaseData();
   
 -    if(phase_id%4 == 0){
 +    if(phase_id%2 == 0){
        CkPrintf("Steering (memory based) based on 2 phases ago:\n");
        twoAgoPhase->print();
        CkPrintf("\n");
@@@ -1391,9 -1472,17 +1472,17 @@@ int controlPoint(const char *name, int 
    
  
    if( phase_id < 4 ){
-     // For the first few phases, just use the lower bound. 
-     // This ensures that the ranges for all the control points known before we do anything fancy
+     // For the first few phases, just use the lower bound, or the default if one was provided 
+     // This ensures that the ranges for all the control points are known before we do anything fancy
      result = lb;
+     if(defaultControlPointValues.count(std::string(name)) > 0){
+       int v = defaultControlPointValues[std::string(name)];
+       CkPrintf("Startup phase using default value of %d for  \"%s\"\n", v, name);   
+       result = v;
+     }
    } else if(controlPointSpace.count(std::string(name)) == 0){
      // if this is the first time we've seen the CP, then return the lower bound
      result = lb;