static int Zoltan_PHG_Output_Parts ( ZZ *zz, ZHG *zhg, Partition hg_parts /* Output partitions relative to the 2D distribution of zhg->HG */ ) { /* Function to map the computed partition from the distribution in HGraph * to the input distribution */ static char *yo = "Zoltan_PHG_Output_Parts"; int i; int msg_tag = 31000; int ierr = ZOLTAN_OK; int nObj = zhg->nObj; int *outparts = NULL; int *sendbuf = NULL; HGraph *phg = &(zhg->HG); zhg->Output_Parts = outparts = (int*) ZOLTAN_MALLOC (nObj * sizeof(int)); if (zhg->VtxPlan != NULL) { /* Get the partition information from the 2D decomposition back to the * original owning processor for each GID. */ sendbuf = (int*) ZOLTAN_MALLOC(zhg->nRecv_GNOs * sizeof(int)); for (i = 0; i < zhg->nRecv_GNOs; i++) sendbuf[i] = hg_parts[VTX_GNO_TO_LNO(phg, zhg->Recv_GNOs[i])]; ierr = Zoltan_Comm_Do_Reverse(zhg->VtxPlan, msg_tag, (char*) sendbuf, sizeof(int), NULL, (char *) outparts); if (ierr) { ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error from Zoltan_Comm_Do_Reverse"); goto End; } ZOLTAN_FREE(&sendbuf); Zoltan_Comm_Destroy(&(zhg->VtxPlan)); } else { for (i = 0; i < zhg->nRecv_GNOs; i++) outparts[i] = hg_parts[zhg->Recv_GNOs[i]]; } if (zz->LB.Remap_Flag) { int new_map; int *newproc = (int *) ZOLTAN_MALLOC(nObj * sizeof(int)); int num_gid_entries = zz->Num_GID; if (nObj && !newproc) { ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error."); ierr = ZOLTAN_MEMERR; goto End; } for (i = 0; i < nObj; i++){ newproc[i] = Zoltan_LB_Part_To_Proc(zz, outparts[i], &(zhg->GIDs[i*num_gid_entries])); if (newproc[i]<0){ ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Zoltan_LB_Part_To_Proc returned invalid processor number."); ierr = ZOLTAN_FATAL; ZOLTAN_FREE(&newproc); goto End; } } ierr = Zoltan_LB_Remap(zz, &new_map, nObj, newproc, zhg->Input_Parts, outparts, 1); if (ierr < 0) ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from Zoltan_LB_Remap"); ZOLTAN_FREE(&newproc); } End: if (zhg->Recv_GNOs) ZOLTAN_FREE(&(zhg->Recv_GNOs)); zhg->nRecv_GNOs = 0; return ierr; }
static int Zoltan_Postprocess_Partition (ZZ *zz, ZOLTAN_Third_Graph *gr, ZOLTAN_Third_Part *prt, ZOLTAN_Output_Part *part, ZOLTAN_ID_PTR global_ids, ZOLTAN_ID_PTR local_ids) { static char * yo = "Zoltan_Postprocess_Partition"; int ierr = ZOLTAN_OK; int i, j, nsend; int *newproc, *tmp_part, *tmp_input_part; int num_gid_entries = zz->Num_GID; int num_lid_entries = zz->Num_LID; /* Partitioning */ /* Determine new processor and number of objects to export */ newproc = (int *) ZOLTAN_MALLOC(gr->num_obj * sizeof(int)); if (gr->num_obj && !newproc){ /* Not enough memory */ ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Out of memory. "); } for (i=0; i<gr->num_obj; i++){ newproc[i] = Zoltan_LB_Part_To_Proc(zz, (int)prt->part[i], &(global_ids[i*num_gid_entries])); if (newproc[i]<0){ ZOLTAN_FREE(&newproc); ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL, "Zoltan_LB_Part_To_Proc returned invalid processor number."); } } if (zz->LB.Remap_Flag) { int new_map; if (sizeof(indextype) == sizeof(int)){ ierr = Zoltan_LB_Remap(zz, &new_map, gr->num_obj, newproc, (int *)prt->input_part, (int *)prt->part, 1); } else{ tmp_part = (int *)ZOLTAN_MALLOC(sizeof(int) * gr->num_obj); tmp_input_part = (int *)ZOLTAN_MALLOC(sizeof(int) * gr->num_obj); if (gr->num_obj && (!tmp_part || !tmp_input_part)){ ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Not enough memory."); } for (i=0; i < gr->num_obj; i++){ tmp_part[i] = (int)prt->part[i]; tmp_input_part[i] = (int)prt->input_part[i]; } ierr = Zoltan_LB_Remap(zz, &new_map, gr->num_obj, newproc, tmp_input_part, tmp_part, 1); for (i=0; i < gr->num_obj; i++){ prt->part[i] = (indextype)tmp_part[i]; prt->input_part[i] = (indextype)tmp_input_part[i]; } ZOLTAN_FREE(&tmp_part); ZOLTAN_FREE(&tmp_input_part); } if (ierr < 0) { ZOLTAN_FREE(&newproc); ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL, "Error returned from Zoltan_LB_Remap"); } } nsend = 0; for (i=0; i<gr->num_obj; i++){ if ((prt->part[i] != prt->input_part[i]) || ((!part->compute_only_part_changes) && (newproc[i] != zz->Proc))) nsend++; if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL) printf("[%1d] DEBUG: local object %1d: old part = " TPL_IDX_SPEC ", new part = " TPL_IDX_SPEC "\n", zz->Proc, i, prt->input_part[i], prt->part[i]); } /* Create export lists */ if (zz->LB.Return_Lists){ if (zz->LB.Return_Lists == ZOLTAN_LB_CANDIDATE_LISTS) { ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL, "Candidate Lists not supported in GRAPH;" "change RETURN_LISTS parameter."); } part->num_exp = nsend; if (nsend > 0) { if (!Zoltan_Special_Malloc(zz,(void **)part->exp_gids,nsend,ZOLTAN_SPECIAL_MALLOC_GID)) { ZOLTAN_FREE(&newproc); ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Not enough memory."); } if (!Zoltan_Special_Malloc(zz,(void **)part->exp_lids,nsend,ZOLTAN_SPECIAL_MALLOC_LID)) { Zoltan_Special_Free(zz,(void **)part->exp_gids,ZOLTAN_SPECIAL_MALLOC_GID); ZOLTAN_FREE(&newproc); ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Not enough memory."); } if (!Zoltan_Special_Malloc(zz,(void **)part->exp_procs,nsend,ZOLTAN_SPECIAL_MALLOC_INT)) { Zoltan_Special_Free(zz,(void **)part->exp_lids,ZOLTAN_SPECIAL_MALLOC_LID); Zoltan_Special_Free(zz,(void **)part->exp_gids,ZOLTAN_SPECIAL_MALLOC_GID); ZOLTAN_FREE(&newproc); ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Not enough memory."); } if (!Zoltan_Special_Malloc(zz,(void **)part->exp_part,nsend,ZOLTAN_SPECIAL_MALLOC_INT)) { Zoltan_Special_Free(zz,(void **)part->exp_lids,ZOLTAN_SPECIAL_MALLOC_LID); Zoltan_Special_Free(zz,(void **)part->exp_gids,ZOLTAN_SPECIAL_MALLOC_GID); Zoltan_Special_Free(zz,(void **)part->exp_procs,ZOLTAN_SPECIAL_MALLOC_INT); ZOLTAN_FREE(&newproc); ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Not enough memory."); } j = 0; for (i=0; i<gr->num_obj; i++){ if ((prt->part[i] != prt->input_part[i]) || ((!part->compute_only_part_changes) && (newproc[i] != zz->Proc))){ /* Object should move to new partition or processor */ ZOLTAN_SET_GID(zz, &((*(part->exp_gids))[j*num_gid_entries]), &(global_ids[i*num_gid_entries])); if (num_lid_entries) ZOLTAN_SET_LID(zz, &((*(part->exp_lids))[j*num_lid_entries]), &(local_ids[i*num_lid_entries])); (*(part->exp_part))[j] = (int)prt->part[i]; (*(part->exp_procs))[j] = newproc[i]; /* printf("[%1d] Debug: Move object %1d to part %1d, proc %1d\n", */ /* zz->Proc, i, prt->part[i], newproc[i]); */ j++; } } } } ZOLTAN_FREE(&newproc); return (ZOLTAN_OK); }