int maxh(TreeNode *root)
		{
			if(root==NULL)
				return 0;
			else
			{
				return 1 + max(maxh(root->left),maxh(root->right));
			}
		}
		bool isBalanced(TreeNode *root) {
			// Start typing your C/C++ solution below
			// DO NOT write int main() function
			if(root==NULL)
				return true;
			if(abs(maxh(root->right)-maxh(root->left)) > 1)
				return 0;
			else
				return isBalanced(root->right) && isBalanced(root->left);
		}
Esempio n. 3
0
void GreedyCommLB::work(LDStats* stats)
{
    int pe,obj,com;
    ObjectRecord *x;
    int i;
    
    if (_lb_args.debug()) CkPrintf("In GreedyCommLB strategy\n",CkMyPe());
    npe = stats->nprocs();
    nobj = stats->n_objs;

    // nmigobj is calculated as the number of migratable objects
    // ObjectHeap maxh is of size nmigobj
    nmigobj = stats->n_migrateobjs;

    stats->makeCommHash();

    assigned_array = new int[nobj];

    object_graph = new graph[nobj];

    init_data(assigned_array,object_graph,npe,nobj);

#define MAXDOUBLE   1e10;

    // processor heap
    processors = new processorInfo[npe];
    for (int p=0; p<npe; p++) {
      processors[p].Id = p;
      processors[p].backgroundLoad = stats->procs[p].bg_walltime;
      processors[p].computeLoad = 0;
      processors[p].pe_speed = stats->procs[p].pe_speed;
      if (!stats->procs[p].available) {
        processors[p].load = MAXDOUBLE;
      }
      else {
        processors[p].load = 0;
        if (!_lb_args.ignoreBgLoad())
          processors[p].load = processors[p].backgroundLoad;
      }
    }


    // assign communication graph
    for(com =0; com< stats->n_comm;com++) {
         int xcoord=0,ycoord=0;
	 LDCommData &commData = stats->commData[com];
	 if((!commData.from_proc())&&(commData.recv_type()==LD_OBJ_MSG))
	 {
		xcoord = stats->getHash(commData.sender);
		ycoord = stats->getHash(commData.receiver.get_destObj());
		if((xcoord == -1)||(ycoord == -1))
		    if (_lb_args.ignoreBgLoad() || stats->complete_flag==0) continue;
		    else CkAbort("Error in search\n");
		add_graph(xcoord,ycoord,commData.bytes, commData.messages);
	 }
         else if (commData.recv_type()==LD_OBJLIST_MSG) {
		int nobjs;
		LDObjKey *objs = commData.receiver.get_destObjs(nobjs);
		xcoord = stats->getHash(commData.sender);
		for (int i=0; i<nobjs; i++) {
		  ycoord = stats->getHash(objs[i]);
		  if((xcoord == -1)||(ycoord == -1))
		    if (_lb_args.migObjOnly()) continue;
		    else CkAbort("Error in search\n");
//printf("Multicast: %d => %d %d %d\n", xcoord, ycoord, commData.bytes, commData.messages);
		  add_graph(xcoord,ycoord,commData.bytes, commData.messages);
		}
         }
    }

    // only build heap with migratable objects, 
    // mapping nonmigratable objects to the same processors
    ObjectHeap maxh(nmigobj+1);
    for(obj=0; obj < stats->n_objs; obj++) {
      LDObjData &objData = stats->objData[obj];
      int onpe = stats->from_proc[obj];
      if (!objData.migratable) {
        if (!stats->procs[onpe].available) {
	  CmiAbort("Load balancer is not be able to move a nonmigratable object out of an unavailable processor.\n");
        }
        alloc(onpe, obj, objData.wallTime);
	update(stats, obj, onpe);	     // update communication cost on other pes
      }
      else {
        x = new ObjectRecord;
        x->id = obj;
        x->pos = obj;
        x->val = objData.wallTime;
        x->pe = onpe;
        maxh.insert(x);
      }
    }

    minHeap *lightProcessors = new minHeap(npe);
    for (i=0; i<npe; i++)
      if (stats->procs[i].available)
        lightProcessors->insert((InfoRecord *) &(processors[i]));

    int id,maxid,minpe=0;
    double temp,total_time,min_temp;
    // for(pe=0;pe < count;pe++)
    //	CkPrintf("avail for %d = %d\n",pe,stats[pe].available);

    double *pe_comm = new double[npe];
    for (int i=0; i<npe; i++) pe_comm[i] = 0.0;

    for(id = 0;id<nmigobj;id++){
	x  = maxh.deleteMax();

	maxid = x->id;

        processorInfo *donor = (processorInfo *) lightProcessors->deleteMin();
	CmiAssert(donor);
	int first_avail_pe = donor->Id;
	temp = compute_com(stats, maxid, first_avail_pe);
	min_temp = temp;
	//total_time = temp + alloc_array[first_avail_pe][nobj];
	total_time = temp + donor->load; 
	minpe = first_avail_pe;
	
    	// search all procs for best
 	// optimization: only search processors that it communicates
	// and the minimum of all others
        CkVec<int> commPes;
        graph * ptr = object_graph[maxid].next;
    
 	// find out all processors that this obj communicates
	double commload = 0.0;			// total comm load
        for(int com=0;(com<2*nobj)&&(ptr != NULL);com++,ptr=ptr->next){
	  int destObj = ptr->id;
	  if(assigned_array[destObj] == 0)  // this obj has not been assigned
	    continue;
	  int destPe = stats->to_proc[destObj];
	  if(stats->procs[destPe].available == 0) continue;
	  
	  double cload = alpha*ptr->nmsg + beeta*ptr->data;
	  pe_comm[destPe] += cload;
	  commload += cload;

          int exist = 0;
	  for (int pp=0; pp<commPes.size(); pp++)
            if (destPe == commPes[pp]) { exist=1; break; }    // duplicated
	  if (!exist) commPes.push_back(destPe);
        }

	int k;
	for(k = 0; k < commPes.size(); k++){
	    pe = commPes[k];
            processorInfo *commpe = (processorInfo *) &processors[pe];
	    
	    temp = commload - pe_comm[pe];
	    
	    //CkPrintf("check id = %d, processor = %d,com = %lf, pro = %lf, comp=%lf\n", maxid,pe,temp,alloc_array[pe][nobj],total_time);
	    if(total_time > (temp + commpe->load)){
		minpe = pe;
		total_time = temp + commpe->load;
		min_temp = temp;
	    }
	}
	/* CkPrintf("check id = %d, processor = %d, obj = %lf com = %lf, pro = %lf, comp=%lf\n", maxid,minpe,x->load,min_temp,alloc_array[minpe][nobj],total_time); */
	
	//    CkPrintf("before 2nd alloc\n");
        stats->assign(maxid, minpe);
	
	alloc(minpe, maxid, x->val + min_temp);

	// now that maxid assigned to minpe, update other pes load
	update(stats, maxid, minpe);

        // update heap
 	lightProcessors->insert(donor);
	for(k = 0; k < commPes.size(); k++) {
	    pe = commPes[k];
            processorInfo *commpe = (processorInfo *) &processors[pe];
            lightProcessors->update(commpe);
	    pe_comm[pe] = 0.0;			// clear
        }

	delete x;
    }
    
    // free up memory
    delete [] pe_comm;

    delete [] processors;
    delete [] assigned_array;

    delete lightProcessors;

    for(int oindex= 0; oindex < nobj; oindex++){
      graph * ptr = &object_graph[oindex];
      ptr = ptr->next;
      
      while(ptr != NULL){
	graph *cur = ptr;
	ptr = ptr->next;
	delete cur;
      }
    }
    delete [] object_graph;

}