/* * float Zoltan_Oct_costs_weight(pOctant octant) * * calculates the cost of an octant. returns the cost.. */ static float Zoltan_Oct_costs_weight(pOctant octant) { pRegion region; /* a region from the list */ float cost; /* cost of the octant */ region = Zoltan_Oct_regionlist(octant); cost=0; /* iterate through the region list, summing each of their weights */ while (region != NULL) { cost += region->Weight; region = region->next; } return cost; }
/* * Zoltan_Oct_terminal_coarsen(oct) * * remove octant's children, accumulating regions * to octant * */ static void Zoltan_Oct_terminal_coarsen(ZZ *zz, OCT_Global_Info *OCT_info, pOctant oct) { pOctant child; /* child of an octant */ pRegion region; /* region associated with an octant */ int i; /* index counter */ pRegion regionlist[8]; /* an array of region lists */ oct_ncoarse++; /* increment coarsening counter */ for(i=0; i<8; i++) { /* get the ith child of an octant */ child = Zoltan_Oct_child(oct,i); /* cannot coarsen if child is off-processor */ /* if(!Zoltan_Oct_POct_local(child)) X */ /* cannot be off-processor */ if(!Zoltan_Oct_POct_local(OCT_info, oct, i)) { fprintf(stderr,"OCT Zoltan_Oct_terminal_coarsen: child not local\n"); abort(); } if(!Zoltan_Oct_isTerminal(child)) { fprintf(stderr,"OCT Zoltan_Oct_terminal_coarsen: child not terminal\n"); abort(); } /* get each child's region list */ regionlist[i] = Zoltan_Oct_regionlist(child); /* delete each child */ /* KDDKDDFREE Change child to &child. */ Zoltan_Oct_POct_free(OCT_info, &child); oct->child[i] = NULL; } oct->numChild = 0; /* * copy contents of each region list into region list * of coarsened parent (which is now a terminal octant) */ for(i=0; i < 8; i++) { region = regionlist[i]; /* go through the regionlist and add to octant */ while(region != NULL) { Zoltan_Oct_addRegion(zz, oct,region); region = region->next; } } }
/* * void tag_regions() * Iterates through the list of octants on the processor and finds which * are to be migrated. It then looks at the region list for those octants * and stores the migrating regions into the export_tags array. */ static int tag_regions(ZZ *zz, pOctant *octs, int *newpids, int nocts, Region **exported_tags, ZOLTAN_ID_PTR *exported_gids, ZOLTAN_ID_PTR *exported_lids, int *nsentags, int **tag_pids, Region **p_tags, ZOLTAN_ID_PTR *p_gids, ZOLTAN_ID_PTR *p_lids, int *npimtags, float *c2, int *max_objs) { char *yo = "tag_regions"; int i; /* index counter */ pRegion regionlist; /* list of region on this processor */ int index; /* index counter */ int index2; /* yet another index counter */ int count; /* count of objects exported form this processor */ int count2; /* count of objects that are kept on processor */ int count3; int *exported_pids; /* array of pids where regions are being exported to */ pRegion mtags; /* object tags of objects to be migrated */ pRegion ptags; /* tags of objects that were previously migrated */ float ex_load; int ierr = ZOLTAN_OK; int num_gid_entries = zz->Num_GID; int num_lid_entries = zz->Num_LID; ex_load = 0; (*max_objs) = 0; if (!nsentags) return ierr; /* find how many objects have been exported */ count = 0; /* find number of local objs to export */ count2 = 0; count3 = 0; for (i=0; i<nocts; i++) { if(Zoltan_Oct_isTerminal(octs[i])) { (*max_objs) += Zoltan_Oct_nRegions(octs[i]); regionlist = Zoltan_Oct_regionlist(octs[i]); while(regionlist != NULL) { count3++; if(regionlist->Proc != zz->Proc) { count++; if(newpids[i] != zz->Proc) regionlist->newProc = newpids[i]; else regionlist->newProc = zz->Proc; } else { if(newpids[i] != zz->Proc) { count2++; regionlist->newProc = newpids[i]; } else regionlist->newProc = zz->Proc; } regionlist = regionlist->next; /* get next region */ } } } #if 0 { { if (newpids[i]!=zz->Proc) { count+=Zoltan_Oct_nRegions(octs[i]); } else { pRegion regions; regions = Zoltan_Oct_regionlist(octs[i]); while(regions != NULL) { if(regions->Proc != zz->Proc) count2++; regions = regions->next; } } } } #endif /* set up the return pointers */ *nsentags = count; *npimtags = count2; if (!exported_tags) { return ierr; } if (count > 0) { /* allocate some space */ if((mtags=(pRegion)ZOLTAN_MALLOC((unsigned)count*sizeof(Region)))==NULL){ ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory."); ZOLTAN_TRACE_EXIT(zz, yo); return ZOLTAN_MEMERR; } if((exported_pids = (int *)ZOLTAN_MALLOC((unsigned)count*sizeof(int))) == NULL){ ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory."); ZOLTAN_TRACE_EXIT(zz, yo); ZOLTAN_FREE(&mtags); return ZOLTAN_MEMERR; } *exported_gids = ZOLTAN_MALLOC_GID_ARRAY(zz, count); *exported_lids = ZOLTAN_MALLOC_LID_ARRAY(zz, count); if(!(*exported_gids) || (num_lid_entries && !(*exported_lids))) { ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory."); ZOLTAN_TRACE_EXIT(zz, yo); ZOLTAN_FREE(&mtags); ZOLTAN_FREE(&exported_pids); return ZOLTAN_MEMERR; } } else { mtags = NULL; exported_pids = NULL; *exported_gids = NULL; *exported_lids = NULL; } /* set up return pointers */ *exported_tags=mtags; *tag_pids = exported_pids; if (count2 > 0) { /* allocate some space */ if((ptags=(pRegion)ZOLTAN_MALLOC((unsigned)count2*sizeof(Region)))==NULL){ ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient Memory."); ZOLTAN_TRACE_EXIT(zz, yo); ZOLTAN_FREE(&mtags); ZOLTAN_FREE(&exported_pids); ZOLTAN_FREE(exported_gids); ZOLTAN_FREE(exported_lids); return ZOLTAN_MEMERR; } *p_gids = ZOLTAN_MALLOC_GID_ARRAY(zz, count2); *p_lids = ZOLTAN_MALLOC_LID_ARRAY(zz, count2); if(!(*p_gids) || (num_lid_entries && !(*p_lids))) { ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient Memory."); ZOLTAN_TRACE_EXIT(zz, yo); ZOLTAN_FREE(&mtags); ZOLTAN_FREE(&exported_pids); ZOLTAN_FREE(exported_gids); ZOLTAN_FREE(exported_lids); ZOLTAN_FREE(&ptags); ZOLTAN_FREE(p_gids); ZOLTAN_FREE(p_lids); return ZOLTAN_MEMERR; } } else { ptags = NULL; *p_gids = NULL; *p_lids = NULL; } /* set up return pointers */ *p_tags=ptags; index = index2 = 0; for (i=0; i<nocts; i++) { if(Zoltan_Oct_isTerminal(octs[i])) { regionlist = Zoltan_Oct_regionlist(octs[i]); while(regionlist != NULL) { if(regionlist->Proc != zz->Proc) { /* place information in the appropritate array */ mtags[index] = *regionlist; ZOLTAN_SET_GID(zz, &((*exported_gids)[index*num_gid_entries]), regionlist->Global_ID); ZOLTAN_SET_LID(zz, &((*exported_lids)[index*num_lid_entries]), regionlist->Local_ID); /*ex_load += (float)(regionlist->Weight);*/ exported_pids[index] = regionlist->Proc; index++; /* increment counter */ } else if(newpids[i] != zz->Proc) { ptags[index2] = *regionlist; /* get region information */ ZOLTAN_SET_GID(zz, &((*p_gids)[index2*num_gid_entries]), regionlist->Global_ID); ZOLTAN_SET_LID(zz, &((*p_lids)[index2*num_lid_entries]), regionlist->Local_ID); index2++; /* increment counter */ } regionlist = regionlist->next; /* get next region */ } } } if (index!=count) { /* error check */ ZOLTAN_TRACE_DETAIL(zz, yo, "Fatal error, inconsistent number of regions.\n"); return ZOLTAN_FATAL; } *c2 = ex_load; return ierr; }
/* * 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(®ion); 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); } }