Ejemplo n.º 1
0
/*
 * void Zoltan_Oct_setcildren(pOctant octant, pOctant children, int *cpids)
 *
 * sets the child pointers to point to the children
 */
void Zoltan_Oct_setchildren(pOctant oct, pOctant *children, int *cpids) {
  int i;
  for(i = 0; i < 8; i++) {
    Zoltan_Oct_setchild(oct, i, children[i]);
    Zoltan_Oct_setCpid(oct, i, cpids[i]);
  }
}
Ejemplo n.º 2
0
/*
 * Zoltan_Oct_terminal_refine(oct)
 *
 * subdivide a terminal octant and divvy up
 * its regions to the 8 children; recurse if
 * necessary to satisfy MAXOCTREGIONS
 *
 */
static void Zoltan_Oct_terminal_refine(ZZ *zz, pOctant oct,int count) 
{
  COORD min,                     /* coordinates of minimum bounds of region */
        max,                     /* coordinates of maximum bounds of region */
        origin;                  /* origin of region */
  pOctant child[8];              /* array of child octants */
  int cnum;                      /* child number */
  int i;                         /* index counter */
  pRegion region;                /* a region to be associated to an octant */
  pRegion entry;
  COORD cmin[8], cmax[8];
  OCT_Global_Info *OCT_info = (OCT_Global_Info *) (zz->LB.Data_Structure);

  for(i=0;i<3;i++)
    min[i] = max[i] = 0;
  
  /* upper limit of refinement levels */
  /* ATTN: may not be used anymore, but can be put back in if necessary */
  if (count>=20) {
    fprintf(stderr, "OCT ERROR: Zoltan_Oct_terminal_refine: bailing out at "
                    "10 levels\n");
    abort();
  }
  oct_nref++;                               /* increment refinement counter */

  /* octant should be terminal in order to be refined (subdivided) */
  if (!Zoltan_Oct_isTerminal(oct)) {
    fprintf(stderr,"OCT ref_octant: oct not terminal\n");
    abort();
  }

  /* get the bounds of an octant */
  Zoltan_Oct_bounds(oct,min,max);
  /* calculate the origin from the bounds */
  Zoltan_Oct_bounds_to_origin(min,max,origin);

  region = Zoltan_Oct_regionlist(oct);     /* Get list while still terminal */
  oct->list = NULL;  /* remove regions from octant, it won't be terminal */

  /* create the children and set their id's */

  Zoltan_Oct_child_bounds_wrapper(OCT_info,oct, cmin, cmax);
  for (i=0; i<8; i++) {
    if(OCT_info->OCT_dimension == 2) {
      /* KDDKDD 3/01 see changes to Zoltan_Oct_child_bounds_wrapper that allow this
       * KDDKDD 3/01 test to work for GRAY and HILBERT mappings.
       */
      if(cmin[i][2] > OCT_info->OCT_gmin[2]) {     /* ignore the z+ octants */
	child[i] = NULL;
	continue;
      }
    }
    
    child[i]=Zoltan_Oct_POct_new(OCT_info);          /* create a new octant */
    child[i]->dir = Zoltan_Oct_get_child_dir(OCT_info, oct->dir, i);
                  /* create a new octant */
    /* set the child->parent link */
    Zoltan_Oct_POct_setparent(OCT_info, child[i], oct, zz->Proc);
    Zoltan_Oct_setchildnum(child[i], i);       /* which child of the parent */
    Zoltan_Oct_setchild(oct, i, child[i]);    /* set the parent->child link */
#ifdef LGG_MIGOCT
    Zoltan_Oct_setID(child[i], Zoltan_Oct_nextId());    /* set child id num */
#endif /* LGG_MIGOCT */
    Zoltan_Oct_setbounds(child[i], cmin[i], cmax[i]);   /* set child bounds */
    Zoltan_Oct_setCpid(oct, i, zz->Proc);    /* set child to be a local oct */
    /* Zoltan_Oct_setOrientation(child[i], 
	      Zoltan_Oct_child_orientation(oct->orientation, oct->which));  */
  }

  /* assign newly created children to child array*/
  if(OCT_info->OCT_dimension == 3) {
    if(Zoltan_Oct_children(oct, child) != 8) {
      /* 
       * if subdivision of oct was successful, oct should have 8 children; 
       * thus a return value of 0 here is a fatal error
       */
      fprintf(stderr, "OCT ref_octant: subdivide failed, %d children.\n",
	      Zoltan_Oct_children(oct, child));
      abort();
    }
  }
  else
    if(Zoltan_Oct_children(oct, child) != 4) {
      /* 
       * if subdivision of oct was successful, oct should have 4 children; 
       * thus a return value of 0 here is a fatal error
       */
      fprintf(stderr, 
	      "OCT ref_octant:subdivide failed, %d children, expected 4\n",
	      Zoltan_Oct_children(oct, child));
      abort();
    }

  /* iterate through and find which child each region should belong to */
  while(region != NULL) {
    entry = region->next;
    cnum=Zoltan_Oct_child_which_wrapper(OCT_info,oct, region->Coord);
    /* add region to octant's regionlist */
    Zoltan_Oct_addRegion(zz, child[cnum], region);
    ZOLTAN_FREE(&(region->Global_ID));
    ZOLTAN_FREE(&(region->Local_ID));
    ZOLTAN_FREE(&region);
    region = entry;
  }

  for (i=0; i<8; i++)                                          /* Recursion */
    if(child[i] != NULL)
      /* KDDKDD  Replaced the following to allow multiple regions with the
       * KDDKDD same coordinates to be placed in the same octant.
      if (Zoltan_Oct_nRegions(child[i]) > MAXOCTREGIONS) {
       */
      if (Zoltan_Oct_nUniqueRegions(OCT_info,child[i]) > MAXOCTREGIONS) {
	Zoltan_Oct_terminal_refine(zz, child[i],count+1);
      }
}
Ejemplo n.º 3
0
static int Zoltan_Oct_Update_Connections(
ZZ *zz,
pOctant *octs,      /* octs[nocts]    */
int *newpids,       /* newpids[nocts] */
pOctant *newocts,   /* newocts[nocts] */
int nocts)          /* number of octants leaving this processor */
{
  int i, j;
  int nsends;
  int nreceives;
  pOctant parent;
  pOctant child;
  int ppid;
  int cpid;
  int childnum;
  int *despid = NULL;
  Update_msg umsg;
  Update_msg *localumsg = NULL;
  Update_msg *remoteumsg = NULL;
  Update_msg *rcv_umsg = NULL;
  int localcount;
  int remotecount;
  int ierr = ZOLTAN_OK;


  ZOLTAN_COMM_OBJ *comm_plan;           /* Object returned by communication routines */
  char *yo = "Zoltan_Oct_Update_Connections";
  OCT_Global_Info *OCT_info = (OCT_Global_Info *) zz->LB.Data_Structure;
  localcount=0;
  remotecount=0;

  /* count number of sends */
  nsends = 0;
  for (i=0; i<nocts; i++)              
    if (newpids[i]!=zz->Proc)
      nsends++;

  if(nocts > 0) {
    if((remoteumsg = (Update_msg *) ZOLTAN_MALLOC((nocts+1) * sizeof(Update_msg)*9)) == NULL) {
      ZOLTAN_TRACE_EXIT(zz, yo);
      return ZOLTAN_MEMERR;
    }
    
    if((localumsg  = (Update_msg *) ZOLTAN_MALLOC((nocts+1) * sizeof(Update_msg)*9)) == NULL) {
      ZOLTAN_TRACE_EXIT(zz, yo);
      ZOLTAN_FREE(&remoteumsg);
      return ZOLTAN_MEMERR;
    }
    
    if((despid = (int *) ZOLTAN_MALLOC((nocts+1) * sizeof(int)*9)) == NULL) {
      ZOLTAN_TRACE_EXIT(zz, yo);
      ZOLTAN_FREE(&remoteumsg);
      ZOLTAN_FREE(&localumsg);
      return ZOLTAN_MEMERR;
    }
  }
  else {
    remoteumsg = NULL;
    localumsg = NULL;
    despid = NULL;
  }
  localcount = 0;
  remotecount = 0;

  for (i=0; i<nocts; i++)                       /* Send connection updates */
    if (newpids[i]!=zz->Proc) {
	parent = Zoltan_Oct_parent(octs[i]); 
        ppid   = Zoltan_Oct_Ppid(octs[i]); 
        childnum = Zoltan_Oct_childnum(octs[i]);
	if (parent) {      /* Let parent of oct[i] know that it's moving   */
	  if (ppid==zz->Proc) {
	    FILLUPDATEMSG(localumsg[localcount], parent, childnum, newocts[i], newpids[i]);
	    localcount++;
	  }
	  else {
	    FILLUPDATEMSG(remoteumsg[remotecount], parent, childnum, newocts[i], newpids[i]);
	    despid[remotecount++] = ppid;
	  }
	}
	for (j=0; j<8; j++) {
	  child = Zoltan_Oct_child(octs[i],j);
	  cpid = octs[i]->cpid[j];
	  /* Tell child of oct[i] that it is moving */
	  if (child) {
	    if (cpid==zz->Proc) {
	      /* NOTE: -1 signals PARENT   */
	      FILLUPDATEMSG(localumsg[localcount], child, -1, newocts[i], newpids[i]);
	      localcount++;
	    }
	    else {
	      /* NOTE: -1 signals PARENT   */
	      FILLUPDATEMSG(remoteumsg[remotecount], child, -1, newocts[i], newpids[i]); 
	      despid[remotecount++] = cpid;
	    }
	  }
	}
    }

  ierr = Zoltan_Comm_Create(&comm_plan, remotecount, despid, zz->Communicator,
			MigUpdCommCreate, &nreceives);
  if(ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN) {
    ZOLTAN_TRACE_EXIT(zz, yo);
    ZOLTAN_FREE(&remoteumsg);
    ZOLTAN_FREE(&localumsg);
    ZOLTAN_FREE(&despid);
    return (ierr);
  }


/*   if(nreceives > 0) { */
    if((rcv_umsg = (Update_msg *) ZOLTAN_MALLOC((nreceives +1) * sizeof(Update_msg)*9)) == NULL) {
      ZOLTAN_TRACE_EXIT(zz, yo);
      ZOLTAN_FREE(&remoteumsg);
      ZOLTAN_FREE(&localumsg);
      ZOLTAN_FREE(&despid);
      return ZOLTAN_MEMERR;
    }

    
    ierr = Zoltan_Comm_Do(comm_plan, MigUpdCommDo, (char *) remoteumsg,
		      sizeof(Update_msg), (char *) rcv_umsg);
    if(ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN) {
      ZOLTAN_TRACE_EXIT(zz, yo);
      ZOLTAN_FREE(&remoteumsg);
      ZOLTAN_FREE(&localumsg);
      ZOLTAN_FREE(&despid);
      ZOLTAN_FREE(&rcv_umsg);
      return (ierr);
    }

/*   } */
/*   else { */
/*     rcv_umsg = NULL; */
/*   } */
  /* update new octants */
  for (i=0; i< (localcount+nreceives); i++)  {   
    if (i<localcount) 
      umsg=localumsg[i];
    else 
      umsg=rcv_umsg[i-localcount];
    if (umsg.childnum>=0) {
      Zoltan_Oct_setchild(umsg.oct,umsg.childnum,umsg.newptr);
      Zoltan_Oct_setCpid(umsg.oct,umsg.childnum,umsg.newpid);
    }
    else {
      if((Zoltan_Oct_data_newpid(umsg.oct) ==  OCT_info->OCT_localpid) ||
	 ((Zoltan_Oct_data_newpid(umsg.oct) !=  OCT_info->OCT_localpid) && (umsg.newpid == OCT_info->OCT_localpid)))
	Zoltan_Oct_POct_setparent(OCT_info, umsg.oct,umsg.newptr,umsg.newpid);
      else {
	umsg.oct->ppid = umsg.newpid;
	umsg.oct->parent = umsg.newptr;
      }
    }
  }

  ierr = Zoltan_Comm_Destroy(&comm_plan);
  if(ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN) {
    ZOLTAN_TRACE_EXIT(zz, yo);
    ZOLTAN_FREE(&remoteumsg);
    ZOLTAN_FREE(&localumsg);
    ZOLTAN_FREE(&despid);
    ZOLTAN_FREE(&rcv_umsg);
    return (ierr);
  }

  ZOLTAN_FREE(&remoteumsg);
  ZOLTAN_FREE(&localumsg);
  ZOLTAN_FREE(&rcv_umsg);
  ZOLTAN_FREE(&despid);
  return ierr;
}