Exemple #1
0
/*
 * Zoltan_Oct_POct_new(OCT_Global_Info *)
 *
 * create a new octant on the local processor and return
 * a pointer to it.  It will have no parents or children.
 */
extern pOctant Zoltan_Oct_POct_new(OCT_Global_Info *OCT_info) {
  pOctant newoct = Zoltan_Oct_new();
  if(!newoct)
    return NULL;
  newoct->ppid = OCT_info->OCT_localpid;
  Zoltan_Oct_modify_newpid(newoct, OCT_info->OCT_localpid);
  
  return newoct;
}
Exemple #2
0
/*
 * void Zoltan_Oct_costs_init(pOctant octant)
 *
 * initialize costs for the subtree rooted at octant
 * ATTN: This function may not be necessary anymore
 */
static void Zoltan_Oct_costs_init(OCT_Global_Info *OCT_info,pOctant octant) {

    pOctant children[8];                 /* children of the octant */
    int i;                               /* index counter */

    Zoltan_Oct_modify_newpid(octant, OCT_info->OCT_localpid);
    Zoltan_Oct_modify_cost(octant, 0);

    if (!Zoltan_Oct_isTerminal(octant)) {
        Zoltan_Oct_children(octant,children);
        for (i=0; i<8; i++) {
            if(Zoltan_Oct_POct_local(OCT_info, octant, i))
                Zoltan_Oct_costs_init(OCT_info,children[i]);
        }
    }
}
Exemple #3
0
/*
 * void Zoltan_Oct_tag_subtree(pOctant octant, int partition_number)
 *
 * marks all the octants within the subtree to be in the current partition
 */
static void Zoltan_Oct_tag_subtree(OCT_Global_Info *OCT_info,pOctant octant, 
				   int part) {
  pOctant children[8];                                /* children of octant */
  int i;                                              /* index counter */

  /* modify NPID so octant know where to migrate to */
  Zoltan_Oct_modify_newpid(octant, part);

  if (Zoltan_Oct_isTerminal(octant))
    return;

  /* if octant has children, have to tag them too */
  Zoltan_Oct_children(octant,children);
  
  for (i=0; i<8; i++)                       /* Simple - just visit in order */
    /* if (children[i] && Zoltan_Oct_local(OCT_info, children[i])) */
    if(children[i] && Zoltan_Oct_POct_local(OCT_info, octant,i))
      Zoltan_Oct_tag_subtree(OCT_info,children[i],part);
}
Exemple #4
0
/*
 * void Zoltan_Oct_visit(pOctant octant)
 * 
 * This routine references the following (static) global variables:
 *
 *   partition - (RW) number of the partition we are currently working on
 *   total     - (RW) total cost of all *previous* partitions
 *   pcost     - (RW) partition cost for current partition
 *   optcost   - (RO) optimal partition cost
 */
static void Zoltan_Oct_visit(ZZ *zz, pOctant octant, float *part_sizes) {
  float cost;                /* Cost of this octant */
  float togo;                /* Remaining room in current partition */
  float behind;              /* How many to make up for from all prev parts */
  pOctant children[8];       /* children of the octant */
  int i;                     /* index counter */
  COORD origin;              /* center of the octant */
  double volume;             /* volume of the octant */
  double prod[3];            /* product of octant origin and its volume */
  OCT_Global_Info *OCT_info = (OCT_Global_Info *)(zz->LB.Data_Structure);

  DFS_Part_Count++;
  cost = Zoltan_Oct_costs_value(octant);      /* get the cost of the octant */
  /*behind = partition * optcost - total;*/     /* calcuate how much behind */
  behind = (tmpcost*globalcost) - total;        /* calcuate how much behind */
  
  if(0)
    fprintf(stderr,"LGG[%d] pc=%f, c=%f, ps=%f, b=%f\n", partition, pcost,
	    cost, optsize, behind);
  /* If octant does not overflow the current partition, then use it. */
  /*if( cost==0 || (pcost+cost) <= (optcost+behind)) {*/
  if(cost==0 || ((pcost+cost) <= (optsize+behind))) {
    Zoltan_Oct_tag_subtree(OCT_info,octant,partition);
    /*fprintf(stderr,"LGG[%d] pc=%f, c=%f, ps=%f, b=%f\n", partition, pcost,
	    cost, optsize, behind);*/
    pcost+=cost;
    
    Zoltan_Oct_origin_volume(octant, origin, &volume);
    
    vector_cmult(prod,volume,origin);
    pmass+=volume;
    vector_add(pcoord,pcoord,prod);
    
    return;
  }

  /* 
   * Can't use entire octant because it is too big. If it has suboctants, 
   * visit them.
   */
  
  if (!Zoltan_Oct_isTerminal(octant)) {
    Zoltan_Oct_modify_newpid(octant, partition);                 /* Nonterm */
    Zoltan_Oct_children(octant,children);

    for (i=0; i<8; i++)                    /* Simple - just visit in order */
      if(children[i] && Zoltan_Oct_POct_local(OCT_info, octant,i))
        Zoltan_Oct_visit(zz,children[i],part_sizes);
    return;
  }
  
  /* 
   * No suboctants!
   * We've hit bottom - have to decide whether to add to
   * the current partition or start a new one.
   */
  togo = behind + optsize - pcost;

  /*printf("proc=%d, part=%d, b=%f, pcost=%f, cost=%f, os=%f\n",
	 zz->Proc, partition, behind, pcost, cost, optsize);*/

  if ((cost-togo) >= togo) {
    /*printf("proc=%d, part=%d, togo=%f, pcost=%f, cost=%f, g=%f\n",
	   zz->Proc, partition, togo, pcost, cost, globalcost);*/
    /*
     * End current part and start new one. We are more "over" than "under"
     */
    tmpcost += part_sizes[partition];
    partition++;                               /* Move on to next partition */
    while((part_sizes[partition] == 0) && (partition < (zz->Num_Proc - 1)))
      partition++;
    optsize = part_sizes[partition]*globalcost;
    total += pcost;
    pcost = 0;
    pmass = 0;
    vector_set_comp(pcoord,0,0,0);
  }

  /*** Add terminal octant to current partition */
  Zoltan_Oct_modify_newpid(octant, partition);
  pcost += cost;

  Zoltan_Oct_origin_volume(octant, origin, &volume);

  vector_cmult(prod,volume,origin);
  pmass += volume;
  vector_add(pcoord,pcoord,prod);
}