/* * pOctant Zoltan_Oct_POct_nextDfs(pOctant octant) * * returns the next octant in a DFS ordering */ pOctant Zoltan_Oct_POct_nextDfs(OCT_Global_Info *OCT_info, pOctant octant) { pOctant parent, /* parent of an octant */ child; /* child of an octant */ int pid; int i; /* index counter */ if (!octant) return(NULL); for (i=0; i<8; i++) { child = Zoltan_Oct_child(octant,i); pid = Zoltan_Oct_Cpid(octant,i); if ((pid == OCT_info->OCT_localpid) && child) return(child); /* Go down */ } parent = Zoltan_Oct_parent(octant); pid = Zoltan_Oct_Ppid(octant); while ((pid == OCT_info->OCT_localpid) && parent) { for (i=octant->which; i<7; i++) { child = Zoltan_Oct_child(parent,i+1); pid = Zoltan_Oct_Cpid(parent, i+1); if ((pid == OCT_info->OCT_localpid) && child) return(child); } octant=parent; /* Go up */ parent = Zoltan_Oct_parent(octant); pid = Zoltan_Oct_Ppid(octant); } return(NULL); /* no more octants remain in dfs ordering */ }
/* KDDKDDFREE Changed oct to *oct to allow NULL from ZOLTAN_FREE to propagate back * KDDKDDFREE to the calling routine. */ void Zoltan_Oct_POct_free(OCT_Global_Info *OCT_info, pOctant *oct) { /* KDDKDDFREE This variable no longer needed. pRList RootList = Zoltan_Oct_POct_localroots(OCT_info); * KDDKDDFREE */ /* traverse through local root list, if octant a local root */ if(Zoltan_Oct_Ppid(*oct) != OCT_info->OCT_localpid) { /* KDDKDDFREE Now passing pointer to OCT_rootlist so that, if * KDDKDDFREE head of list is deleted, this pointer can be updated * KDDKDDFREE appropriately (i.e., no longer points to deleted entry). */ RL_delRootOctant(OCT_info, &(OCT_info->OCT_rootlist), *oct); } /* free up space in memory */ Zoltan_Oct_free(OCT_info, oct); }
/* * Zoltan_Oct_POct_setparent(pOctant octant, pOctant parent, int parent_processor_id) * * sets the parent of the octant. If the parent is offprocessor, then * add octant to the local root list */ void Zoltan_Oct_POct_setparent(OCT_Global_Info *OCT_info, pOctant oct, pOctant parent, int ppid) { pRList RootList = Zoltan_Oct_POct_localroots(OCT_info); if(Zoltan_Oct_Ppid(oct) == OCT_info->OCT_localpid) { if(ppid != OCT_info->OCT_localpid) { RL_addRootOctant(RootList, oct); /* was local -- now nonlocal */ } } else { if(ppid == OCT_info->OCT_localpid) { /* KDDKDDFREE Now passing pointer to OCT_rootlist so that, if * KDDKDDFREE head of list is deleted, this pointer can be updated * KDDKDDFREE appropriately (i.e., no longer points to deleted entry). */ RL_delRootOctant(OCT_info, &(OCT_info->OCT_rootlist), oct); /* was foreign -- now local */ } } oct->ppid=ppid; oct->parent=parent; if(parent && (ppid == OCT_info->OCT_localpid) && (oct->mapidx < 0)) oct->mapidx=parent->mapidx; }
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; }