Ejemplo n.º 1
0
/*
 * void Zoltan_Oct_addRegion(pOctant octant, pRegion region)
 * add a region to oct's list
 */
int Zoltan_Oct_addRegion(ZZ *zz, pOctant oct, pRegion region) { 
  char *yo = "Zoltan_Oct_addRegion";
  pRegion entry;                      /* pointer to new entry in region list */

  if(oct == NULL) 
    return ZOLTAN_WARN;

  entry = (pRegion) ZOLTAN_MALLOC(sizeof(Region));   /* malloc space for region */
  if(entry == NULL) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Cannot allocated memory for region.");
    return ZOLTAN_MEMERR;
  }

  entry->Global_ID = ZOLTAN_MALLOC_GID(zz);
  entry->Local_ID = ZOLTAN_MALLOC_LID(zz);
  /* copy region information into the entry */
  vector_set(entry->Coord, region->Coord);
  entry->Weight = region->Weight;
  ZOLTAN_SET_GID(zz, entry->Global_ID, region->Global_ID);
  ZOLTAN_SET_LID(zz, entry->Local_ID, region->Local_ID);
  entry->Proc = region->Proc;

  /* attach region to region list */
  entry->next = oct->list; 
  oct->list = entry;
  return ZOLTAN_OK;
}
Ejemplo n.º 2
0
static void Zoltan_Reftree_List_Other_Leaves(ZZ *zz, ZOLTAN_REFTREE *subroot, 
       ZOLTAN_ID_PTR list, int *count)

{
/*
 * Function to make a list of the leaves not assigned to this processor
 */
int j;   /* loop counter */

  if (subroot->num_child == 0) {

  /*
   * If there are no children, then add it to the list if it is not
   * assigned to this processor
   */

    if (!subroot->assigned_to_me) {
      ZOLTAN_SET_GID(zz, &(list[(*count)*zz->Num_GID]),subroot->global_id);
      *count += 1;
    }

  }
  else {

  /*
   * If there are children, traverse the subtrees
   */

    for (j=0; j<subroot->num_child; j++) {
      Zoltan_Reftree_List_Other_Leaves(zz, &(subroot->children[j]),list,count);
    }
  }
}
Ejemplo n.º 3
0
/*
 *  Function that initializes the region data structure.  It uses the 
 *  global ID, coordinates and weight provided by the application.  
 */
static void initialize_region(ZZ *zz, pRegion *ret, ZOLTAN_ID_PTR global_id,
                              ZOLTAN_ID_PTR local_id, int wgtflag, float wgt,
                              int num_dim, double *geom_vec) 
{
  pRegion reg;
  int i;
  reg = (pRegion) ZOLTAN_MALLOC(sizeof(Region));
  *ret = reg;
  reg->Global_ID = ZOLTAN_MALLOC_GID(zz);
  reg->Local_ID = ZOLTAN_MALLOC_LID(zz);
  ZOLTAN_SET_GID(zz, reg->Global_ID, global_id);
  ZOLTAN_SET_LID(zz, reg->Local_ID, local_id);
  reg->Proc = zz->Proc;
  /* reg->Proc = 0; */
  reg->Coord[0] = reg->Coord[1] = reg->Coord[2] = 0.0;
  for (i = 0; i < num_dim; i++)
    reg->Coord[i] = geom_vec[i];

#if 0
  Zoltan_Print_Sync_Start(zz->Communicator, TRUE);
    fprintf(stderr, "Result info on %d: %d %d %d  %lf  %lf  %lf\n", zz->Proc, 
	    reg->Local_ID, reg->Global_ID, reg->Proc,
	    reg->Coord[0], reg->Coord[1], reg->Coord[2]); 
  Zoltan_Print_Sync_End(zz->Communicator, TRUE);
#endif

  if (wgtflag)
    reg->Weight = wgt;
  else
    reg->Weight = 1;

  reg->next = NULL;
}
Ejemplo n.º 4
0
/*
 * int Zoltan_Oct_copy_info(pRegion *destination, pRegion source)
 *
 * Copies region information from the source to the destination
 */
static int Zoltan_Oct_copy_info(ZZ *zz, pRegion src, pRegion *dest) {
  pRegion copy;
  char *yo = "Zoltan_Oct_copy_info";
  int ierr = ZOLTAN_OK;

  /* mallloc space for destination */
  copy = (pRegion) ZOLTAN_MALLOC(sizeof(Region));
  if(copy == NULL) {
    ZOLTAN_TRACE_EXIT(zz, yo);
    return ZOLTAN_MEMERR;
  }
  copy->Global_ID = ZOLTAN_MALLOC_GID(zz);
  copy->Local_ID  = ZOLTAN_MALLOC_LID(zz);
  if (copy->Global_ID == NULL || (zz->Num_LID && copy->Local_ID == NULL)) {
    ZOLTAN_TRACE_EXIT(zz, yo);
    return ZOLTAN_MEMERR;
  }
  
  /* set up return pointer */
  *dest = copy;

  /* copy all important information */
  vector_set(copy->Coord, src->Coord);
  copy->Weight = src->Weight;
  ZOLTAN_SET_GID(zz, copy->Global_ID, src->Global_ID);
  ZOLTAN_SET_LID(zz, copy->Local_ID, src->Local_ID);
  copy->Proc = src->Proc;
  copy->attached = 0;
  return ierr;
}
Ejemplo n.º 5
0
  /* This function may work on any distribution of the bipartite graph */
int
Zoltan_ZG_Register(ZZ* zz, ZG* graph, int* properties)
{
  static char *yo = "Zoltan_ZG_Register";
  int ierr = ZOLTAN_OK;
  int *props;
  struct Zoltan_DD_Struct *dd;
  int size;
  ZOLTAN_ID_PTR GID;

  ZOLTAN_TRACE_ENTER(zz, yo);
  size = graph->mtx.mtx.nY;
  dd = graph->mtx.mtx.ddY;

  if (graph->bipartite) { /* Need to construct another properties array with only the fixed elements ! */
    int vertlno;

    if (graph->fixObj) {
      dd = graph->mtx.mtx.ddX;
    }
    props = (int*)ZOLTAN_MALLOC(sizeof(int)*size);
    if (graph->mtx.mtx.nY  && props == NULL) MEMORY_ERROR;
    GID = ZOLTAN_MALLOC_GID_ARRAY(zz, size);
    if (size && GID == NULL) MEMORY_ERROR;
    for (size = 0, vertlno = 0 ; vertlno < graph->mtx.mtx.nY ; ++vertlno) {
      if (graph->fixed_vertices[vertlno]) {
	props[size] = properties[vertlno];
	ZOLTAN_SET_GID(zz, GID+ size*zz->Num_GID,
		       graph->mtx.mtx.yGID+vertlno*zz->Num_GID);
	size ++;
      }
    }
  }
  else {
    props = properties;
    GID = graph->mtx.mtx.yGID;
    if (graph->mtx.mtx.ddY == NULL) {
      ierr = Zoltan_DD_Create (&graph->mtx.mtx.ddY, zz->Communicator, 1, zz->Num_GID,
			       1, graph->mtx.mtx.globalY/zz->Num_Proc, 0);
      CHECK_IERR;
      /* Hope a linear assignment will help a little */
      Zoltan_DD_Set_Neighbor_Hash_Fn1(graph->mtx.mtx.ddY, graph->mtx.mtx.globalX/zz->Num_Proc);
    }
    dd = graph->mtx.mtx.ddY;
  }
  /* Make our new numbering public */
  ierr = Zoltan_DD_Update (dd, GID, NULL, NULL, props, size);
  CHECK_IERR;

  End:
  if (graph->bipartite) {
    ZOLTAN_FREE(&props);
    ZOLTAN_FREE(&GID);
  }

  ZOLTAN_TRACE_EXIT(zz, yo);
  return (ierr);
}
Ejemplo n.º 6
0
static int Zoltan_Reftree_Export_Lists(ZZ *zz, ZOLTAN_REFTREE *subroot, 
                            int *num_export, ZOLTAN_ID_PTR *export_global_ids,
                            ZOLTAN_ID_PTR *export_local_ids,
                            int **export_to_partition, int **export_procs)
{
/*
 * Function to build the export lists
 */
int i, ierr;

/*
 * if this subtree has no leaves assigned to this processor then there can be
 * no exports below it
 */

  if (!subroot->assigned_to_me) return(ZOLTAN_OK);

  if (subroot->num_child == 0) {

/*
 * if this is a leaf, put it on the export lists if it is to be exported
 */

    if (export_it(subroot,zz,&ierr)) {
      ZOLTAN_SET_GID(zz, &((*export_global_ids)[(*num_export)*zz->Num_GID]),
                     subroot->global_id);
      ZOLTAN_SET_LID(zz, &((*export_local_ids)[(*num_export)*zz->Num_LID]),
                     subroot->local_id);
      (*export_to_partition)[*num_export] = subroot->partition;
      (*export_procs)[*num_export] = Zoltan_LB_Part_To_Proc(zz,subroot->partition,subroot->global_id);
      *num_export += 1;
    }
    if (ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN) return(ierr);
  }
  else {

/*
 * if it is not a leaf, traverse the subtree
 */

    for (i=0; i<subroot->num_child; i++) {
      ierr = Zoltan_Reftree_Export_Lists(zz, &(subroot->children[i]),num_export,
                                         export_global_ids,export_local_ids,
                                         export_to_partition,export_procs);
      if (ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN) return(ierr);
    }
  }
  return(ZOLTAN_OK);
}
Ejemplo n.º 7
0
void Zoltan_Reftree_Hash_Insert(ZZ *zz, ZOLTAN_REFTREE *reftree_node,
                            struct Zoltan_Reftree_hash_node **hashtab, int size)
{
int i;
struct Zoltan_Reftree_hash_node *new_entry;

  i = Zoltan_Hash(reftree_node->global_id, zz->Num_GID, (unsigned int)size);

  new_entry = (struct Zoltan_Reftree_hash_node *)
              ZOLTAN_MALLOC(sizeof(struct Zoltan_Reftree_hash_node));
  new_entry->gid = ZOLTAN_MALLOC_GID(zz);
  ZOLTAN_SET_GID(zz, new_entry->gid,reftree_node->global_id);
  new_entry->reftree_node = reftree_node;
  new_entry->next = hashtab[i];
  hashtab[i] = new_entry;
}
Ejemplo n.º 8
0
void Zoltan_Reftree_IntHash_Insert(ZZ *zz, ZOLTAN_ID_PTR gid, int lid,
                                   struct Zoltan_Reftree_inthash_node **hashtab,
                                   int size)
{
int i;
struct Zoltan_Reftree_inthash_node *new_entry;

  i = Zoltan_Hash(gid, zz->Num_GID, (unsigned int)size);

  new_entry = (struct Zoltan_Reftree_inthash_node *)
              ZOLTAN_MALLOC(sizeof(struct Zoltan_Reftree_inthash_node));
  new_entry->gid = ZOLTAN_MALLOC_GID(zz);
  ZOLTAN_SET_GID(zz, new_entry->gid,gid);
  new_entry->lid = lid;
  new_entry->next = hashtab[i];
  hashtab[i] = new_entry;
}
Ejemplo n.º 9
0
int Zoltan_Order_Get_GID_Order(
    struct Zoltan_Struct       *zz,
    ZOLTAN_ID_PTR               global_ids,
    ZOLTAN_ID_PTR               order_ids
)
{
    int * proctab;
    ZOLTAN_ID_PTR sendgidtab;
    int * sendtab, *recvtab;
    int i;
    int nrecv;
    struct Zoltan_Comm_Obj *plan;
    int ierr = ZOLTAN_OK;
    int *vtxdist;
    int tag = 24061986;
    int offset;

    zz->Order.gidrank = order_ids;

    if (!strcmp(zz->Order.order_type, "LOCAL")) {
        for (i = 0 ; i < zz->Order.nbr_objects ; ++i) {
            order_ids[i] = global_ids[zz->Order.rank[i] - zz->Order.start_index];
        }
        return (ZOLTAN_OK);
    }

    ierr = Zoltan_Get_Distribution(zz, &vtxdist);
    if (ierr != ZOLTAN_OK) return (ierr);

    proctab = (int*) ZOLTAN_MALLOC(3*zz->Order.nbr_objects*sizeof(int));
    sendgidtab = ZOLTAN_MALLOC_GID_ARRAY(zz, 2*zz->Order.nbr_objects);
    if (proctab == NULL)  {
        ZOLTAN_FREE(&vtxdist);
        return (ZOLTAN_MEMERR);
    }
    if (sendgidtab == NULL) {
        ZOLTAN_FREE(&proctab);
        ZOLTAN_FREE(&vtxdist);
        return (ZOLTAN_MEMERR);
    }
    sendtab = proctab + zz->Order.nbr_objects;
    recvtab = sendtab + zz->Order.nbr_objects;

    for (i = 0 ; i < zz->Order.nbr_objects ; ++i) {
        proctab[i] = Zoltan_Get_Processor_Graph(vtxdist, zz->Num_Proc, zz->Order.rank[i] - zz->Order.start_index);
        sendtab[i] = zz->Order.rank[i] - zz->Order.start_index;
    }

    ierr = Zoltan_Comm_Create(&plan, zz->Order.nbr_objects, proctab, zz->Communicator, tag++,
                              &nrecv);
    if (ierr != ZOLTAN_OK) {
        ZOLTAN_FREE(&sendgidtab);
        ZOLTAN_FREE(&proctab);
        ZOLTAN_FREE(&vtxdist);
        return (ierr);
    }

    ierr = Zoltan_Comm_Do(plan, tag++, (char *) sendtab, sizeof(int), (char *) recvtab);

    if (ierr != ZOLTAN_OK) {
        ZOLTAN_FREE(&sendgidtab);
        ZOLTAN_FREE(&proctab);
        ZOLTAN_FREE(&vtxdist);
        return (ierr);
    }

    offset = vtxdist[zz->Proc];
    for (i = 0 ; i < zz->Order.nbr_objects ; ++i) {
        int position;
        position = recvtab[i]-offset;
        ZOLTAN_SET_GID(zz, &sendgidtab[i], &global_ids[position]);
    }

    ierr = Zoltan_Comm_Do_Reverse(plan, tag++, (char *) sendgidtab, zz->Num_GID*sizeof(int), NULL,
                                  (char *) order_ids);

    Zoltan_Comm_Destroy(&plan);
    ZOLTAN_FREE(&sendgidtab);
    ZOLTAN_FREE(&proctab);
    ZOLTAN_FREE(&vtxdist);

    return (ierr);
}
Ejemplo n.º 10
0
static int actual_arrays(
    ZZ *zz,
    int num_gid_entries,
    int num_lid_entries,
    int num,
    ZOLTAN_ID_PTR gids,
    ZOLTAN_ID_PTR lids,
    int *procs,
    int *to_part,
    int *actual_num,
    ZOLTAN_ID_PTR *actual_gids,
    ZOLTAN_ID_PTR *actual_lids,
    int **actual_procs,
    int **actual_to_part,
    int *actual_allocated
)
{
    char *yo = "actual_arrays";
    int i, j;

    /*
     *  Test whether to pack objects that have changed partition
     *  but not changed processor.
     *  If packing them, the actual objects == objects passed to this function.
     *  If not packing them, build arrays with them stripped out.
     */

    *actual_allocated = 0;
    if (!(zz->Migrate.Only_Proc_Changes)) {
        /* Pack all objects, even if they are not changing processor. */
        *actual_num = num;
        *actual_gids = gids;
        *actual_lids = lids;
        *actual_procs = procs;
        *actual_to_part = to_part;
    }
    else {  /* zz->Migrate.Only_Proc_Changes */
        /* Pack only objects that are actually changing processor. */
        *actual_num = 0;
        for (i = 0; i < num; i++)
            if (procs[i] != zz->Proc)
                (*actual_num)++;

        if (*actual_num == num) {
            /*  Number of actual objects == number of objects in input arrays. */
            /*  No stripping needed. */
            *actual_gids = gids;
            *actual_lids = lids;
            *actual_procs = procs;
            *actual_to_part = to_part;
        }
        else if (*actual_num != num && *actual_num > 0) {
            /*  Number of actual_num < num.  Build arrays  */
            /*  containing only actual objects. */
            *actual_allocated = 1;
            *actual_gids = ZOLTAN_MALLOC_GID_ARRAY(zz, *actual_num);
            *actual_lids = ZOLTAN_MALLOC_LID_ARRAY(zz, *actual_num);
            *actual_procs = (int *) ZOLTAN_MALLOC(sizeof(int) * (*actual_num));
            if (to_part != NULL)
                *actual_to_part = (int *) ZOLTAN_MALLOC(sizeof(int)*(*actual_num));
            if (*actual_gids == NULL || (num_lid_entries && *actual_lids == NULL) ||
                    *actual_procs == NULL ||
                    (to_part != NULL && *actual_to_part == NULL)) {
                ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory Error.");
                Zoltan_Multifree(__FILE__, __LINE__, 4,
                                 actual_gids, actual_lids,
                                 actual_procs, actual_to_part);
                return (ZOLTAN_MEMERR);
            }

            for (j = 0, i = 0; i < num; i++) {
                if (procs[i] != zz->Proc) {
                    ZOLTAN_SET_GID(zz,
                                   *actual_gids + j*num_gid_entries,
                                   gids + i*num_gid_entries);
                    if (num_lid_entries)
                        ZOLTAN_SET_LID(zz,
                                       *actual_lids + j*num_lid_entries,
                                       lids + i*num_lid_entries);
                    (*actual_procs)[j] = procs[i];
                    if (to_part) (*actual_to_part)[j] = to_part[i];
                    j++;
                }
            }
        }
    }
    return ZOLTAN_OK;
}
Ejemplo n.º 11
0
int Zoltan_Migrate(
    ZZ *zz,                      /* Zoltan structure.                  */
    int num_import,              /* Number of non-local objects assigned to the
                                  processor in the new decomposition.        */
    ZOLTAN_ID_PTR import_global_ids, /* Array of global IDs for non-local objects
                                  assigned to this processor in the new
                                  decomposition; this field can be NULL if
                                  the application doesn't provide import IDs.*/
    ZOLTAN_ID_PTR import_local_ids,  /* Array of local IDs for non-local objects
                                  assigned to the processor in the new
                                  decomposition; this field can be NULL if the
                                  application does not provide import IDs.   */
    int *import_procs,           /* Array of processor IDs of processors owning
                                  the non-local objects that are assigned to
                                  this processor in the new decomposition; this
                                  field can be NULL if the application does
                                  not provide import IDs.                    */
    int *import_to_part,         /* Array of partition numbers to which imported
                                  objects should be assigned.                */
    int num_export,              /* Number of objs to be exported
                                  to other processors to establish the new
                                  decomposition.                             */
    ZOLTAN_ID_PTR export_global_ids, /* Array of global IDs of
                                  objects to be exported to other processors
                                  to establish the new decomposition.        */
    ZOLTAN_ID_PTR export_local_ids,  /* Array of local IDs of
                                  objects to be exported to other processors
                                  to establish the new decomposition.        */
    int *export_procs,           /* Array of processor IDs
                                  to which objects will be exported
                                  to establish the new decomposition.        */
    int *export_to_part          /* Array of partition numbers to which exported
                                  objects should be assigned.                */
)
{
    /*
     *  Routine to help perform migration.  If migration pre-processing routine
     *  (ZOLTAN_PRE_MIGRATE_FN) is specified, this routine first calls that fn.
     *  It then calls a function to obtain the size of the migrating objects
     *  (ZOLTAN_OBJ_SIZE_FN).  The routine next calls an application-specified
     *  object packing routine (ZOLTAN_PACK_OBJ_FN) for each object
     *  to be exported.  It develops the needed communication map to move the
     *  objects to other processors.  It performs the communication according
     *  to the map, and then calls an application-specified object unpacking
     *  routine (ZOLTAN_UNPACK_OBJ_FN) for each object imported.
     */

    char *yo = "Zoltan_Migrate";
    int num_gid_entries, num_lid_entries;  /* lengths of global & local ids */
    int *sizes = NULL;       /* sizes (in bytes) of the object data for export. */
    int id_size;             /* size (in bytes) of ZOLTAN_GID + padding for
                            alignment                                       */
    int tag_size;            /* size (in bytes) of ZOLTAN_GID + one int
                            (for message size) */
    char *export_buf = NULL; /* buffer for packing export data.                 */
    char *import_buf = NULL; /* buffer for receiving imported data.             */
    char *tmp;               /* temporary pointer into buffers.                 */
    int i;                   /* loop counter.                                   */
    int tmp_size;            /* size of a single object's data.                 */
    int *idx = NULL;         /* index used for multi-fn packs and unpacks.      */
    int idx_cnt = 0;         /* index counter for idx array.                    */
    ZOLTAN_ID_PTR tmp_id = NULL; /* pointer to storage for a global ID in comm
                                buf  */
    ZOLTAN_ID_PTR lid;       /* temporary pointer to a local ID; used to pass
                            NULL to query functions when NUM_LID_ENTRIES=0. */
    ZOLTAN_COMM_OBJ *imp_plan = NULL; /* Comm obj built from import lists. */
    ZOLTAN_COMM_OBJ *exp_plan = NULL; /* Comm obj built from export lists. */
    int msgtag, msgtag2;     /* Tags for communication routines                 */
    int total_send_size;     /* Total size of outcoming message (in #items)     */
    int total_recv_size;     /* Total size of incoming message (in #items)      */
    int aligned_int;         /* size of an int padded for alignment             */
    int dest;                /* temporary destination partition.                */
    int include_parts = 0;   /* flag indicating whether partition info is
                            provided */
    int ierr = ZOLTAN_OK;
    int actual_num_exp = 0;
    int actual_exp_allocated = 0;
    ZOLTAN_ID_PTR actual_exp_gids = NULL;    /* Arrays containing only objs to  */
    ZOLTAN_ID_PTR actual_exp_lids = NULL;    /* actually be packed.  Objs that  */
    int *actual_exp_procs = NULL;            /* are changing partition but not  */
    int *actual_exp_to_part = NULL;          /* processor may not be included.  */
    int actual_num_imp = 0;
    int actual_imp_allocated = 0;
    ZOLTAN_ID_PTR actual_imp_gids = NULL;    /* Arrays containing only objs to  */
    ZOLTAN_ID_PTR actual_imp_lids = NULL;    /* actually be imported. Objs that  */
    int *actual_imp_procs = NULL;            /* are changing partition but not  */
    int *actual_imp_to_part = NULL;          /* processor may not be included.  */

    ZOLTAN_TRACE_ENTER(zz, yo);

    /*
     *  Return if this processor is not in the Zoltan structure's
     *  communicator.
     */

    if (ZOLTAN_PROC_NOT_IN_COMMUNICATOR(zz)) {
        goto End;
    }

    /*
     *  Check that all procs use the same id types.
     */

    ierr = check_input(zz,
                       ((num_export >= 0 && export_to_part) ||
                        (num_import >= 0 && import_to_part)),
                       &include_parts);
    if (ierr != ZOLTAN_OK)
        goto End;

    num_gid_entries = zz->Num_GID;
    num_lid_entries = zz->Num_LID;

    /*
     *  Check that all necessary query functions are available.
     */

    if (zz->Get_Obj_Size == NULL && zz->Get_Obj_Size_Multi == NULL) {
        ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Must register a "
                           "ZOLTAN_OBJ_SIZE_FN or ZOLTAN_OBJ_SIZE_MULTI_FN function "
                           "to use the migration-help tools.");
        ierr = ZOLTAN_FATAL;
        goto End;
    }

    if (zz->Pack_Obj == NULL && zz->Pack_Obj_Multi == NULL) {
        ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Must register a "
                           "ZOLTAN_PACK_OBJ_FN or ZOLTAN_PACK_OBJ_MULTI_FN function "
                           "to use the migration-help tools.");
        ierr = ZOLTAN_FATAL;
        goto End;
    }

    if (zz->Unpack_Obj == NULL && zz->Unpack_Obj_Multi == NULL) {
        ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Must register a "
                           "ZOLTAN_UNPACK_OBJ_FN or ZOLTAN_UNPACK_OBJ_MULTI_FN function "
                           "to use the migration-help tools.");
        ierr = ZOLTAN_FATAL;
        goto End;
    }


    if (num_export >= 0) {

        /* Build the actual export arrays */
        ierr = actual_arrays(zz, num_gid_entries, num_lid_entries,
                             num_export, export_global_ids, export_local_ids,
                             export_procs, export_to_part,
                             &actual_num_exp, &actual_exp_gids, &actual_exp_lids,
                             &actual_exp_procs, &actual_exp_to_part,
                             &actual_exp_allocated);
        if (ierr < 0)
            goto End;

        /* Compute communication map based on actual exports.  */

        msgtag = 32767;
        ierr = Zoltan_Comm_Create(&exp_plan, actual_num_exp, actual_exp_procs,
                                  zz->Communicator, msgtag, &actual_num_imp);
        if (ierr < 0) {
            ZOLTAN_PRINT_ERROR(zz->Proc,yo,"Error returned from Zoltan_Comm_Create.");
            goto End;
        }
    }

    else if (num_import >= 0) {

        /* Build the actual import arrays */
        ierr = actual_arrays(zz, num_gid_entries, num_lid_entries,
                             num_import, import_global_ids, import_local_ids,
                             import_procs, import_to_part,
                             &actual_num_imp, &actual_imp_gids, &actual_imp_lids,
                             &actual_imp_procs, &actual_imp_to_part,
                             &actual_imp_allocated);
        if (ierr < 0)
            goto End;

        /* Compute communication map based on imports.  */
        msgtag = 32767;
        ierr = Zoltan_Comm_Create(&imp_plan, actual_num_imp, actual_imp_procs,
                                  zz->Communicator, msgtag, &actual_num_exp);
        if (ierr < 0) {
            ZOLTAN_PRINT_ERROR(zz->Proc,yo,"Error returned from Zoltan_Comm_Create.");
            goto End;
        }

        /* Compute actual export lists for packing objects */
        if (actual_num_exp > 0) {
            actual_exp_allocated = 1;
            actual_exp_gids = ZOLTAN_MALLOC_GID_ARRAY(zz, actual_num_exp);
            actual_exp_lids = ZOLTAN_MALLOC_LID_ARRAY(zz, actual_num_exp);
            actual_exp_procs = (int *) ZOLTAN_MALLOC(sizeof(int) * actual_num_exp);
            if (include_parts)
                actual_exp_to_part = (int *) ZOLTAN_MALLOC(sizeof(int)*actual_num_exp);
            if (actual_exp_gids == NULL ||
                    (num_lid_entries && actual_exp_lids == NULL) ||
                    actual_exp_procs == NULL ||
                    (import_to_part != NULL && actual_exp_to_part == NULL)) {
                Zoltan_Multifree(__FILE__, __LINE__, 4,
                                 &actual_exp_gids, &actual_exp_lids,
                                 &actual_exp_procs, &actual_exp_to_part);
                ierr = ZOLTAN_MEMERR;
                goto End;
            }
        }

        msgtag2 = 32766;
        ierr = Zoltan_Comm_Do(imp_plan, msgtag2, (char *) actual_imp_gids,
                              (int) (sizeof(ZOLTAN_ID_TYPE)*(num_gid_entries)),
                              (char *) actual_exp_gids);
        if (ierr < 0) {
            ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from Zoltan_Comm_Do.");
            goto End;
        }

        if (num_lid_entries) {
            msgtag2--;
            ierr = Zoltan_Comm_Do(imp_plan, msgtag2, (char *) actual_imp_lids,
                                  (int) (sizeof(ZOLTAN_ID_TYPE)*num_lid_entries),
                                  (char *) actual_exp_lids);
            if (ierr < 0) {
                ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from Zoltan_Comm_Do.");
                goto End;
            }
        }

        Zoltan_Comm_Info(imp_plan, NULL, NULL, NULL, NULL, NULL, NULL,
                         NULL, NULL, NULL, NULL, NULL, actual_exp_procs, NULL);

        if (include_parts) {
            msgtag2--;
            ierr = Zoltan_Comm_Do(imp_plan, msgtag2, (char *) actual_imp_to_part,
                                  (int) sizeof(int), (char *) actual_exp_to_part);
            if (ierr < 0) {
                ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from Zoltan_Comm_Do.");
                goto End;
            }
        }

        /* Create inverse plan (i.e., plan based on exports) so can set
         * variable sizes.
         * (Zoltan_Comm_Do_Reverse(imp_plan, ...) allows sending variable
         * but does not tell how large to allocate receive buffer.
         */
        ierr = Zoltan_Comm_Invert_Plan(&imp_plan);
        exp_plan = imp_plan;
        imp_plan = NULL;
    }
    else {
        ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Import or export lists needed.");
        ierr = ZOLTAN_FATAL;
        goto End;
    }

    if (zz->Migrate.Pre_Migrate_PP != NULL) {
        zz->Migrate.Pre_Migrate_PP(zz->Migrate.Pre_Migrate_PP_Data,
                                   num_gid_entries, num_lid_entries,
                                   num_import, import_global_ids,
                                   import_local_ids, import_procs, import_to_part,
                                   num_export, export_global_ids,
                                   export_local_ids, export_procs, export_to_part,
                                   &ierr);
        if (ierr < 0) {
            ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                               "ZOLTAN_PRE_MIGRATE_PP_FN function.");
            goto End;
        }
    }

    if (zz->Migrate.Pre_Migrate != NULL) {
        zz->Migrate.Pre_Migrate(zz->Migrate.Pre_Migrate_Data,
                                num_gid_entries, num_lid_entries,
                                num_import, import_global_ids,
                                import_local_ids, import_procs,
                                num_export, export_global_ids,
                                export_local_ids, export_procs,
                                &ierr);
        if (ierr < 0) {
            ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                               "ZOLTAN_PRE_MIGRATE_FN function.");
            goto End;
        }
    }

    ZOLTAN_TRACE_DETAIL(zz, yo, "Done pre-migration processing");

    id_size = Zoltan_Align(num_gid_entries * sizeof(ZOLTAN_ID_TYPE));
    /* Note that alignment is not strictly necessary
       when ZOLTAN_ID_TYPE is int or unsigned int. */
    aligned_int = Zoltan_Align(sizeof(int));
    tag_size = id_size + aligned_int;

    /*
     * For each object, allow space for its global ID and its data plus
     * one int (for the object data size).
     * Zoltan will pack the global IDs; the application must pack the data
     * through the pack routine.  Zoltan needs the global IDs for unpacking,
     * as the order of the data received during communication is not
     * necessarily the same order as import_global_ids[].
     * Zoltan also needs to communicate the sizes of the objects because
     * only the sender knows the size of each object.
     */
    if (actual_num_exp > 0) {
        sizes = (int *) ZOLTAN_MALLOC(actual_num_exp * sizeof(int));
        if (!sizes) {
            ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
            ierr = ZOLTAN_MEMERR;
            goto End;
        }

        if (zz->Get_Obj_Size_Multi != NULL) {
            zz->Get_Obj_Size_Multi(zz->Get_Obj_Size_Multi_Data,
                                   num_gid_entries, num_lid_entries, actual_num_exp,
                                   actual_exp_gids, actual_exp_lids, sizes, &ierr);
            if (ierr < 0) {
                ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                                   "ZOLTAN_OBJ_SIZE_MULTI function.");
                goto End;
            }
        }
        else {
            for (i = 0; i < actual_num_exp; i++) {
                lid = (num_lid_entries ? &(actual_exp_lids[i*num_lid_entries]) : NULL);
                sizes[i] = zz->Get_Obj_Size(zz->Get_Obj_Size_Data,
                                            num_gid_entries, num_lid_entries,
                                            &(actual_exp_gids[i*num_gid_entries]),
                                            lid, &ierr);
                if (ierr < 0) {
                    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                                       "ZOLTAN_OBJ_SIZE function.");
                    goto End;
                }
            }
        }

        total_send_size = 0;

        for (i = 0; i < actual_num_exp; i++) {
            sizes[i] = Zoltan_Align(sizes[i]);
            total_send_size += sizes[i] + tag_size;
        }
        export_buf = (char *) ZOLTAN_CALLOC(total_send_size, sizeof(char));
        if (!export_buf) {
            ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
            ierr = ZOLTAN_MEMERR;
            goto End;
        }

        if (zz->Pack_Obj_Multi != NULL) {
            /* Allocate an index array for ZOLTAN_PACK_OBJ_MULTI_FN. */
            idx = (int *) ZOLTAN_MALLOC(actual_num_exp * sizeof(int));
            if (!idx) {
                ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
                ierr = ZOLTAN_MEMERR;
                goto End;
            }
        }

        /*
         *  Pack the objects for export.
         */

        idx_cnt = 0;
        tmp = export_buf;
        for (i = 0; i < actual_num_exp; i++) {

            /* Pack the object's global ID */
            tmp_id = (ZOLTAN_ID_PTR) tmp;
            ZOLTAN_SET_GID(zz, tmp_id, &(actual_exp_gids[i*num_gid_entries]));
            tmp += id_size;

            /* Pack the object's size */
            *((int *)tmp) = sizes[i];
            tmp += aligned_int;

            /* If using ZOLTAN_PACK_OBJ_MULTI_FN, build the index array. */
            idx_cnt += tag_size;
            if (idx != NULL) {
                idx[i] = idx_cnt;
            }
            tmp += sizes[i];
            idx_cnt += sizes[i];
        }

        if (zz->Pack_Obj_Multi != NULL) {
            if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL) {
                printf("[%1d] DEBUG in %s: Packing objects with multi-pack\n",
                       zz->Proc, yo);
            }
            zz->Pack_Obj_Multi(zz->Pack_Obj_Multi_Data,
                               num_gid_entries, num_lid_entries, actual_num_exp,
                               actual_exp_gids, actual_exp_lids,
                               (actual_exp_to_part!=NULL ? actual_exp_to_part
                                : actual_exp_procs),
                               sizes, idx, export_buf, &ierr);
            if (ierr < 0) {
                ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                                   "ZOLTAN_PACK_OBJ_MULTI function.");
                goto End;
            }
        }
        else {
            tmp = export_buf + tag_size;
            for (i = 0; i < actual_num_exp; i++) {
                if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL) {
                    printf("[%1d] DEBUG in %s: Packing object with gid ", zz->Proc, yo);
                    ZOLTAN_PRINT_GID(zz, &(actual_exp_gids[i*num_gid_entries]));
                    printf("size = %d bytes\n", sizes[i]);
                }

                /* Pack the object's data */
                lid = (num_lid_entries ? &(actual_exp_lids[i*num_lid_entries]) : NULL);
                dest = (actual_exp_to_part != NULL ? actual_exp_to_part[i]
                        : actual_exp_procs[i]);
                zz->Pack_Obj(zz->Pack_Obj_Data,
                             num_gid_entries, num_lid_entries,
                             &(actual_exp_gids[i*num_gid_entries]), lid, dest,
                             sizes[i], tmp, &ierr);
                if (ierr < 0) {
                    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                                       "ZOLTAN_PACK_OBJ function.");
                    goto End;
                }
                tmp += sizes[i] + tag_size;
            }
        }
        ZOLTAN_FREE(&idx);
        tmp_id = NULL;
    }

    ZOLTAN_TRACE_DETAIL(zz, yo, "Done packing objects");


    /* Modify sizes[] to contain message sizes, not object sizes */
    for (i=0; i<actual_num_exp; i++) {
        sizes[i] += tag_size;
    }

    msgtag--;
    ierr = Zoltan_Comm_Resize(exp_plan, sizes, msgtag, &total_recv_size);
    if (ierr < 0) {
        ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from Zoltan_Comm_Resize.");
        goto End;
    }

    if (actual_num_imp > 0) {
        import_buf = (char *) ZOLTAN_MALLOC(total_recv_size);
        if (!import_buf) {
            ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
            ierr = ZOLTAN_MEMERR;
            goto End;
        }
    }

    /*
     *  Send the export data using the communication plan.
     */

    msgtag2 = 32765;
    ierr = Zoltan_Comm_Do(exp_plan, msgtag2, export_buf, 1, import_buf);
    if (ierr < 0) {
        ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from Zoltan_Comm_Do.");
        goto End;
    }

    /*
     *  Free whatever memory we can.
     */

    Zoltan_Comm_Destroy(&exp_plan);
    ZOLTAN_FREE(&export_buf);
    ZOLTAN_FREE(&sizes);

    ZOLTAN_TRACE_DETAIL(zz, yo, "Done communication");

    /*
     *  Perform application-specified processing before unpacking the data.
     */
    if (zz->Migrate.Mid_Migrate_PP != NULL) {
        zz->Migrate.Mid_Migrate_PP(zz->Migrate.Mid_Migrate_PP_Data,
                                   num_gid_entries, num_lid_entries,
                                   num_import, import_global_ids,
                                   import_local_ids, import_procs, import_to_part,
                                   num_export, export_global_ids,
                                   export_local_ids, export_procs, export_to_part,
                                   &ierr);
        if (ierr < 0) {
            ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                               "ZOLTAN_MID_MIGRATE_PP_FN function.");
            goto End;
        }
    }

    if (zz->Migrate.Mid_Migrate != NULL) {
        zz->Migrate.Mid_Migrate(zz->Migrate.Mid_Migrate_Data,
                                num_gid_entries, num_lid_entries,
                                num_import, import_global_ids,
                                import_local_ids, import_procs,
                                num_export, export_global_ids,
                                export_local_ids, export_procs,
                                &ierr);
        if (ierr < 0) {
            ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                               "ZOLTAN_MID_MIGRATE_FN function.");
            goto End;
        }
    }

    /*
     *  Unpack the object data.
     */

    if (actual_num_imp > 0) {

        if (zz->Unpack_Obj_Multi != NULL) {

            /* Allocate and fill input arrays for Unpack_Obj_Multi. */
            sizes = (int *) ZOLTAN_MALLOC(actual_num_imp * sizeof(int));
            tmp_id = (ZOLTAN_ID_PTR) ZOLTAN_MALLOC_GID_ARRAY(zz, actual_num_imp);
            idx = (int *) ZOLTAN_MALLOC(actual_num_imp * sizeof(int));
            if (!sizes || !tmp_id || !idx) {
                ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
                ierr = ZOLTAN_MEMERR;
                goto End;
            }

            tmp = import_buf;
            idx_cnt = 0;
            for (i = 0; i < actual_num_imp; i++) {

                /* Unpack the object's global ID */
                ZOLTAN_SET_GID(zz, &(tmp_id[i*num_gid_entries]), (ZOLTAN_ID_PTR) tmp);
                tmp += id_size;

                /* Unpack the object's size */
                sizes[i] = *((int *)tmp);
                tmp += aligned_int;

                /* If using ZOLTAN_UNPACK_OBJ_MULTI_FN, build the index array. */
                idx_cnt += tag_size;
                if (idx != NULL) {
                    idx[i] = idx_cnt;
                }

                tmp += sizes[i];
                idx_cnt += sizes[i];
            }

            if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL) {
                printf("[%1d] DEBUG in %s: Unpacking objects with multi-fn\n",
                       zz->Proc,yo);
            }
            zz->Unpack_Obj_Multi(zz->Unpack_Obj_Multi_Data, num_gid_entries,
                                 actual_num_imp, tmp_id, sizes, idx, import_buf, &ierr);
            ZOLTAN_FREE(&import_buf);
            ZOLTAN_FREE(&sizes);
            ZOLTAN_FREE(&tmp_id);
            ZOLTAN_FREE(&idx);
            if (ierr < 0) {
                ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                                   "ZOLTAN_UNPACK_OBJ_MULTI_FN.");
                goto End;
            }
        }
        else {
            tmp = import_buf;
            for (i = 0; i < actual_num_imp; i++) {
                tmp_size = *((int *)(tmp + id_size));
                if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL) {
                    printf("[%1d] DEBUG in %s: Unpacking object with gid ", zz->Proc, yo);
                    ZOLTAN_PRINT_GID(zz, (ZOLTAN_ID_PTR)tmp);
                    printf("size = %d bytes\n", tmp_size);
                }

                /* Unpack the object's data */

                zz->Unpack_Obj(zz->Unpack_Obj_Data, num_gid_entries,
                               (ZOLTAN_ID_PTR) tmp, tmp_size,
                               tmp + tag_size, &ierr);
                if (ierr < 0) {
                    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                                       "ZOLTAN_UNPACK_OBJ_FN.");
                    goto End;
                }
                tmp += (tmp_size + tag_size);
            }
            ZOLTAN_FREE(&import_buf);
        }
    }

    ZOLTAN_TRACE_DETAIL(zz, yo, "Done unpacking objects");

    if (zz->Migrate.Post_Migrate_PP != NULL) {
        zz->Migrate.Post_Migrate_PP(zz->Migrate.Post_Migrate_PP_Data,
                                    num_gid_entries, num_lid_entries,
                                    num_import, import_global_ids,
                                    import_local_ids, import_procs, import_to_part,
                                    num_export, export_global_ids,
                                    export_local_ids, export_procs, export_to_part,
                                    &ierr);
        if (ierr < 0) {
            ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                               "ZOLTAN_POST_MIGRATE_PP_FN function.");
            goto End;
        }
    }

    if (zz->Migrate.Post_Migrate != NULL) {
        zz->Migrate.Post_Migrate(zz->Migrate.Post_Migrate_Data,
                                 num_gid_entries, num_lid_entries,
                                 num_import, import_global_ids,
                                 import_local_ids, import_procs,
                                 num_export, export_global_ids,
                                 export_local_ids, export_procs,
                                 &ierr);
        if (ierr < 0) {
            ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from "
                               "ZOLTAN_POST_MIGRATE_FN function.");
            goto End;
        }
    }

End:

    if (actual_exp_allocated) {
        Zoltan_Multifree(__FILE__, __LINE__, 4,
                         &actual_exp_gids, &actual_exp_lids,
                         &actual_exp_procs, &actual_exp_to_part);
    }
    if (actual_imp_allocated) {
        Zoltan_Multifree(__FILE__, __LINE__, 4,
                         &actual_imp_gids, &actual_imp_lids,
                         &actual_imp_procs, &actual_imp_to_part);
    }

    if (ierr < 0) {
        if (exp_plan) Zoltan_Comm_Destroy(&exp_plan);
        Zoltan_Multifree(__FILE__, __LINE__, 5,
                         &import_buf, &tmp_id, &sizes, &idx, &export_buf);
    }
    ZOLTAN_TRACE_EXIT(zz, yo);
    return (ierr);
}
Ejemplo n.º 12
0
int Zoltan_Random(
  ZZ *zz,                       /* The Zoltan structure.                     */
  float *part_sizes,            /* Input:  Array of size zz->LB.Num_Global_Parts
                                   * zz->Obj_Weight_Dim
                                   containing the percentage of work to be
                                   assigned to each partition.               */
  int *num_import,              /* Return -1. Random uses only export lists. */
  ZOLTAN_ID_PTR *import_global_ids, /* Not used. */
  ZOLTAN_ID_PTR *import_local_ids,  /* Not used. */
  int **import_procs,           /* Not used. */
  int **import_to_part,         /* Not used. */
  int *num_export,              /* Output: Number of objects to export. */
  ZOLTAN_ID_PTR *export_global_ids, /* Output: GIDs to export. */
  ZOLTAN_ID_PTR *export_local_ids,  /* Output: LIDs to export. */
  int **export_procs,           /* Output: Processsors to export to. */
  int **export_to_part          /* Output: Partitions to export to. */
)
{
  int ierr = ZOLTAN_OK;
  int i, count, num_obj;
  int max_export;
  double rand_frac = 1.0;       /* Default is to move all objects. */
  ZOLTAN_ID_PTR global_ids = NULL;
  ZOLTAN_ID_PTR local_ids = NULL; 
  int *parts = NULL;
  float *dummy = NULL;
  static char *yo = "Zoltan_Random";
  static int first_time = 1;

  ZOLTAN_TRACE_ENTER(zz, yo);

  /* Synchronize the random number generator. 
   * This synchronization is needed only for sanity in our nightly testing. 
   * If some other operation (eg., Zoltan_LB_Eval) changes the status of 
   * the random number generator, the answers here will change.  They won't
   * be wrong, but they will be different from our accepted answers.
   */
  if (first_time) {
    Zoltan_Srand(zz->Seed, NULL);
    Zoltan_Rand(NULL);
    first_time=0;
  }

  /* No import lists computed. */
  *num_import = -1;

  /* Get parameter values. */
  Zoltan_Bind_Param(Random_params, "RANDOM_MOVE_FRACTION", (void *) &rand_frac);
  Zoltan_Assign_Param_Vals(zz->Params, Random_params, zz->Debug_Level, 
                           zz->Proc, zz->Debug_Proc);

  /* Get list of local objects. */
  ierr = Zoltan_Get_Obj_List(zz, &num_obj, &global_ids, &local_ids, 0,
                             &dummy, &parts);

  /* Bound number of objects to export. */
  max_export = 1.5*rand_frac*num_obj;

  /* Allocate export lists. */
  *export_global_ids = *export_local_ids = NULL;
  *export_procs = *export_to_part = NULL;
  if (max_export > 0) {
    if (!Zoltan_Special_Malloc(zz, (void **)export_global_ids, max_export,
                               ZOLTAN_SPECIAL_MALLOC_GID)
     || !Zoltan_Special_Malloc(zz, (void **)export_local_ids, max_export,
                               ZOLTAN_SPECIAL_MALLOC_LID)
     || !Zoltan_Special_Malloc(zz, (void **)export_procs, max_export,
                               ZOLTAN_SPECIAL_MALLOC_INT)
     || !Zoltan_Special_Malloc(zz, (void **)export_to_part, max_export,
                               ZOLTAN_SPECIAL_MALLOC_INT)) {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
      ierr = ZOLTAN_MEMERR;
      goto End;
    }
  }

  /* Randomly assign ids to procs. */
  count=0;
  for (i=0; i<num_obj; i++){
    /* Randomly select some objects to move (export) */
    if ((count<max_export) && (Zoltan_Rand(NULL)<rand_frac*ZOLTAN_RAND_MAX)){
      /* export_global_ids[count] = global_ids[i]; */
      ZOLTAN_SET_GID(zz, &((*export_global_ids)[count*zz->Num_GID]),
                     &global_ids[i*zz->Num_GID]);
      if (local_ids)
        /* export_local_ids[count] = local_ids[i]; */
        ZOLTAN_SET_LID(zz, &((*export_local_ids)[count*zz->Num_LID]),
                       &local_ids[i*zz->Num_LID]);
      /* Randomly pick new partition number. */
      (*export_to_part)[count] = Zoltan_Rand_InRange(NULL, zz->LB.Num_Global_Parts);
      /* Processor number is derived from partition number. */
      (*export_procs)[count] = Zoltan_LB_Part_To_Proc(zz, 
                     (*export_to_part)[count], &global_ids[i*zz->Num_GID]);

      /* printf("Debug: Export gid %u to part %d and proc %d.\n", (*export_global_ids)[count], (*export_to_part)[count], (*export_procs)[count]); */

      ++count;
    }
  }
  (*num_export) = count;

End:
  /* Free local memory, but not export lists. */
  ZOLTAN_FREE(&global_ids);
  ZOLTAN_FREE(&local_ids);
  ZOLTAN_FREE(&parts);

  ZOLTAN_TRACE_EXIT(zz, yo);
  return ierr;
}
Ejemplo n.º 13
0
/*
 * void Zoltan_Oct_fix_tags()
 *
 * fixes the import tags so that region tags that were previously
 * exported aren't counted when imported back.
 */
int Zoltan_Oct_fix_tags(ZZ *zz, ZOLTAN_ID_PTR *import_global_ids, 
			ZOLTAN_ID_PTR *import_local_ids, int **import_procs, 
			int **import_to_part, int nrectags, 
			pRegion import_regs) {
  char *yo = "Zoltan_Oct_fix_tags";
  int i;                                  /* index counter */
  int ierr = ZOLTAN_OK;
  int num_gid_entries = zz->Num_GID;
  int num_lid_entries = zz->Num_LID;

    /* allocate memory */

    if (!Zoltan_Special_Malloc(zz,(void **)import_global_ids,nrectags,
                           ZOLTAN_SPECIAL_MALLOC_GID)) {
      ZOLTAN_PRINT_ERROR(zz->Proc,yo, "Insufficient memory.");
      ZOLTAN_TRACE_EXIT(zz, yo);
      return ZOLTAN_MEMERR;
    }
    if (!Zoltan_Special_Malloc(zz,(void **)import_local_ids,nrectags,
                           ZOLTAN_SPECIAL_MALLOC_LID)) {
      Zoltan_Special_Free(zz,(void **)import_global_ids,
			  ZOLTAN_SPECIAL_MALLOC_GID); 
      ZOLTAN_PRINT_ERROR(zz->Proc,yo, "Insufficient memory.");
      ZOLTAN_TRACE_EXIT(zz, yo);
      return ZOLTAN_MEMERR;
    }
    if (!Zoltan_Special_Malloc(zz,(void **)import_procs,nrectags,
                           ZOLTAN_SPECIAL_MALLOC_INT)) {
      Zoltan_Special_Free(zz,(void **)import_global_ids,
			  ZOLTAN_SPECIAL_MALLOC_GID);
      Zoltan_Special_Free(zz,(void **)import_local_ids,
			  ZOLTAN_SPECIAL_MALLOC_LID);
      ZOLTAN_PRINT_ERROR(zz->Proc,yo, "Insufficient memory.");
      ZOLTAN_TRACE_EXIT(zz, yo);
      return ZOLTAN_MEMERR;
    }
    if (!Zoltan_Special_Malloc(zz,(void **)import_to_part,nrectags,
                           ZOLTAN_SPECIAL_MALLOC_INT)) {
      Zoltan_Special_Free(zz,(void **)import_global_ids,
			  ZOLTAN_SPECIAL_MALLOC_GID);
      Zoltan_Special_Free(zz,(void **)import_local_ids,
			  ZOLTAN_SPECIAL_MALLOC_LID);
      Zoltan_Special_Free(zz,(void **)import_procs,ZOLTAN_SPECIAL_MALLOC_INT);
      ZOLTAN_PRINT_ERROR(zz->Proc,yo, "Insufficient memory.");
      ZOLTAN_TRACE_EXIT(zz, yo);
      return ZOLTAN_MEMERR;
    }

    /* for each region imported, look at its originating processor */
    for(i=0; i<nrectags; i++) {
      ZOLTAN_SET_GID(zz, &((*import_global_ids)[i*num_gid_entries]),
                 import_regs[i].Global_ID);
      ZOLTAN_SET_LID(zz, &((*import_local_ids)[i*num_lid_entries]),
                 import_regs[i].Local_ID);
      (*import_procs)[i]   = import_regs[i].newProc;
      /*(*import_to_part)[i] = zz->Proc;*/
      (*import_to_part)[i] = import_regs[i].newProc;
    }

    return ierr;
}
Ejemplo n.º 14
0
/*
 * void malloc_new_objects();
 *
 * gets the tags being imported into this processor, and sets up the
 * import_tags array, and the nrectags array.
 */
static int malloc_new_objects(ZZ *zz, int nsentags, pRegion exported_tags, 
			      ZOLTAN_ID_PTR exported_gids,
			      ZOLTAN_ID_PTR exported_lids, int *tag_pids,
			      int *nstags, pRegion *ex_tags,
			      pRegion prev_tags, ZOLTAN_ID_PTR prev_gids,
			      ZOLTAN_ID_PTR prev_lids, int npimtags,
			      float *c3)
{
  char *yo = "malloc_new_objects";
  int i;                                  /* index counter */
  int nreceives;                          /* number of messages received */
  pRegion t_b_exp;                        /* array of tags to be exported */
  pRegion tmp = NULL;
  ZOLTAN_ID_PTR tmp_gids = NULL;
  ZOLTAN_ID_PTR tmp_lids = NULL;
  int msgtag, msgtag2;
  int j;
  int ierr = ZOLTAN_OK;
  int num_gid_entries = zz->Num_GID;
  int num_lid_entries = zz->Num_LID;
  float im_load;
  ZOLTAN_COMM_OBJ *comm_plan;  /* Object returned by communication routines */

  im_load = 0;
  msgtag = 32767;

  ierr = Zoltan_Comm_Create(&comm_plan, nsentags, tag_pids, zz->Communicator,
				msgtag, &nreceives);
  if(ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, 
		       "Error returned from Zoltan_Comm_Create.");
    ZOLTAN_TRACE_EXIT(zz, yo);
    return(ierr);
  }


  if (nreceives > 0) {
    tmp = (pRegion) ZOLTAN_MALLOC(nreceives * sizeof(Region));
    tmp_gids = ZOLTAN_MALLOC_GID_ARRAY(zz, nreceives);
    tmp_lids = ZOLTAN_MALLOC_LID_ARRAY(zz, nreceives);
    if(tmp == NULL || !tmp_gids || (num_lid_entries && !tmp_lids)) {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory.");
      ZOLTAN_FREE(&tmp);
      ZOLTAN_FREE(&tmp_gids);
      ZOLTAN_FREE(&tmp_lids);
      ZOLTAN_TRACE_EXIT(zz, yo);
      return ZOLTAN_MEMERR;
    }
  }
  
  msgtag2 = 32766;
  ierr = Zoltan_Comm_Do(comm_plan, msgtag2, (char *) exported_tags,
			sizeof(Region), (char *) tmp);
  if(ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from Zoltan_Comm_Do.");
    ZOLTAN_TRACE_EXIT(zz, yo);
    ZOLTAN_FREE(&tmp);
    ZOLTAN_FREE(&tmp_gids);
    ZOLTAN_FREE(&tmp_lids);
    return(ierr);
  }

  msgtag2--;
  ierr = Zoltan_Comm_Do(comm_plan, msgtag2, (char *) exported_gids,
			sizeof(ZOLTAN_ID_TYPE)*num_gid_entries, 
			(char *) tmp_gids);
  if (ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from Zoltan_Comm_Do.");
    fprintf(stderr, "OCT %s Error %s returned from Zoltan_Comm_Do\n", yo,
            (ierr == ZOLTAN_MEMERR ? "ZOLTAN_MEMERR" : "ZOLTAN_FATAL"));
    ZOLTAN_FREE(&tmp);
    ZOLTAN_FREE(&tmp_gids);
    ZOLTAN_FREE(&tmp_lids);
    return(ierr);
  }

  if (num_lid_entries > 0) {
    msgtag2--;
    ierr = Zoltan_Comm_Do(comm_plan, msgtag2, (char *) exported_lids,
			  sizeof(ZOLTAN_ID_TYPE)*num_lid_entries,
			  (char *) tmp_lids);
    if (ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN) {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error returned from Zoltan_Comm_Do.");
      ZOLTAN_FREE(&tmp);
      ZOLTAN_FREE(&tmp_gids);
      ZOLTAN_FREE(&tmp_lids);
      return(ierr);
    }
  }

  ierr = Zoltan_Comm_Destroy(&comm_plan);
  if(ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, 
		       "Error returned from Zoltan_Comm_Destroy.");
    ZOLTAN_TRACE_EXIT(zz, yo);
    ZOLTAN_FREE(&tmp);
    return(ierr);
  }

  /* get each message sent, and store region in import array */
  j=0;
  for (i=0; i<nreceives; i++) {
    im_load += tmp[i].Weight;
    if(tmp[i].newProc != zz->Proc) {
      j++;
    }
  }
  
  if((j + npimtags) != 0) {                   /* malloc import array */
    if((t_b_exp = (pRegion)ZOLTAN_MALLOC((j+npimtags)*sizeof(Region)))==NULL){
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory.");
      ZOLTAN_TRACE_EXIT(zz, yo);
      ZOLTAN_FREE(&tmp);
      ZOLTAN_FREE(&tmp_gids);
      ZOLTAN_FREE(&tmp_lids);
      return ZOLTAN_MEMERR;
    }
  }
  else
    t_b_exp = NULL;

  /* setup return pointer */
  (*ex_tags) = t_b_exp;

  j=0;
  for (i=0; i<nreceives; i++) {
    if(tmp[i].newProc != zz->Proc) {
      t_b_exp[j] = tmp[i];
      t_b_exp[j].Global_ID = ZOLTAN_MALLOC_GID(zz);
      t_b_exp[j].Local_ID  = ZOLTAN_MALLOC_LID(zz);
      if (!(t_b_exp[j].Global_ID) ||
	  (num_lid_entries && !(t_b_exp[j].Local_ID))) {
        ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory.");
        ZOLTAN_TRACE_EXIT(zz, yo);
        ZOLTAN_FREE(&tmp);
        ZOLTAN_FREE(&tmp_gids);
        ZOLTAN_FREE(&tmp_lids);
        return ZOLTAN_MEMERR;
      }
      ZOLTAN_SET_GID(zz, t_b_exp[j].Global_ID,
		     &(tmp_gids[i*num_gid_entries]));
      ZOLTAN_SET_LID(zz, t_b_exp[j].Local_ID, &(tmp_lids[i*num_lid_entries]));
      j++;
    }
  }
  
  if(npimtags > 0) {
    for(i=0; i<npimtags; i++) {
      t_b_exp[j] = prev_tags[i];
      t_b_exp[j].Global_ID = ZOLTAN_MALLOC_GID(zz);
      t_b_exp[j].Local_ID  = ZOLTAN_MALLOC_LID(zz);
      if (!(t_b_exp[j].Global_ID) ||
	  (num_lid_entries && !(t_b_exp[j].Local_ID))) {
        ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory.");
        ZOLTAN_TRACE_EXIT(zz, yo);
        ZOLTAN_FREE(&tmp);
        ZOLTAN_FREE(&tmp_gids);
        ZOLTAN_FREE(&tmp_lids);
        return ZOLTAN_MEMERR;
      }
      ZOLTAN_SET_GID(zz, t_b_exp[j].Global_ID,
		     &(prev_gids[i*num_gid_entries]));
      ZOLTAN_SET_LID(zz, t_b_exp[j].Local_ID, 
		     &(prev_lids[i*num_lid_entries]));
      j++;
    }
  }
  *nstags = j;

  ZOLTAN_FREE(&tmp);
  ZOLTAN_FREE(&tmp_gids);
  ZOLTAN_FREE(&tmp_lids);

  if((*nstags == 0) && (*ex_tags != NULL)) {
    ZOLTAN_TRACE_DETAIL(zz, yo,
                 "Fatal error, import tags not empty but no tags received\n");
    return ZOLTAN_FATAL;
  }

  *c3 = im_load;
  return ierr;
}
Ejemplo n.º 15
0
/*
 * 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;
}
Ejemplo n.º 16
0
int Zoltan_Block(
  ZZ *zz,                       /* The Zoltan structure.                     */
  float *part_sizes,            /* Input:  Array of size zz->LB.Num_Global_Parts
                                   containing the percentage of work to be
                                   assigned to each partition.               */
  int *num_import,              /* Return -1. We use only export lists. */
  ZOLTAN_ID_PTR *import_global_ids, /* Not used. */
  ZOLTAN_ID_PTR *import_local_ids,  /* Not used. */
  int **import_procs,           /* Not used. */
  int **import_to_part,         /* Not used. */
  int *num_export,              /* Output: Number of objects to export. */
  ZOLTAN_ID_PTR *export_global_ids, /* Output: GIDs to export. */
  ZOLTAN_ID_PTR *export_local_ids,  /* Output: LIDs to export. */
  int **export_procs,           /* Output: Processsors to export to. */
  int **export_to_part          /* Output: Partitions to export to. */
)
{
  int ierr = ZOLTAN_OK;
  int i, count, num_obj;
  int wtflag = 0;
  ZOLTAN_ID_PTR global_ids = NULL;
  ZOLTAN_ID_PTR local_ids = NULL; 
  int *parts = NULL;
  int *newparts = NULL;
  float *wgts = NULL;
  static char *yo = "Zoltan_Block";

  ZOLTAN_TRACE_ENTER(zz, yo);

  /* No import lists computed. */
  *num_import = -1;
  *export_global_ids = *export_local_ids = NULL;
  *export_procs = *export_to_part = NULL;

  /* Get list of local objects. */
  if (zz->Obj_Weight_Dim > 1) {
    ierr = ZOLTAN_FATAL;
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, 
                      "OBJ_WEIGHT_DIM > 1 not supported by LB_METHOD BLOCK.");
    goto End;
  }
  wtflag = (zz->Obj_Weight_Dim>0 ? 1 : 0);
  ierr = Zoltan_Get_Obj_List(zz, &num_obj, &global_ids, &local_ids, wtflag,
                             &wgts, &parts);

  /* Compute the new partition numbers. */
  newparts = (int *) ZOLTAN_MALLOC(num_obj * sizeof(int));
  if (num_obj && (!newparts)){
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
    ierr = ZOLTAN_MEMERR;
    goto End;
  }
  block_part(zz, num_obj, wtflag, wgts, part_sizes, newparts);

  /* Check how many partition numbers changed. */
  count=0;
  for (i=0; i<num_obj; i++){
    if (newparts[i] != parts[i])
      ++count;
  }
  (*num_export) = count;

  /* Allocate export lists. */
  if ((*num_export) > 0) {
    if (!Zoltan_Special_Malloc(zz, (void **)export_global_ids, (*num_export),
                               ZOLTAN_SPECIAL_MALLOC_GID)
     || !Zoltan_Special_Malloc(zz, (void **)export_local_ids, (*num_export),
                               ZOLTAN_SPECIAL_MALLOC_LID)
     || !Zoltan_Special_Malloc(zz, (void **)export_procs, (*num_export),
                               ZOLTAN_SPECIAL_MALLOC_INT)
     || !Zoltan_Special_Malloc(zz, (void **)export_to_part, (*num_export),
                               ZOLTAN_SPECIAL_MALLOC_INT)) {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
      ierr = ZOLTAN_MEMERR;
      goto End;
    }
  }

  /* Loop over objects and fill export lists. */
  count=0;
  for (i=0; i<num_obj; i++){
    if (newparts[i] != parts[i]){
      /* export_global_ids[count] = global_ids[i]; */
      ZOLTAN_SET_GID(zz, &((*export_global_ids)[count*zz->Num_GID]),
                     &global_ids[i*zz->Num_GID]);
      if (local_ids)
        /* export_local_ids[count] = local_ids[i]; */
        ZOLTAN_SET_LID(zz, &((*export_local_ids)[count*zz->Num_LID]),
                       &local_ids[i*zz->Num_LID]);
      /* Set new partition number. */
      (*export_to_part)[count] = newparts[i];
      /* Processor is derived from partition number. */
      (*export_procs)[count] = Zoltan_LB_Part_To_Proc(zz, 
                     (*export_to_part)[count], &global_ids[i*zz->Num_GID]);

      ++count;
    }
  }

End:
  /* Free local memory, but not export lists. */
  ZOLTAN_FREE(&global_ids);
  ZOLTAN_FREE(&local_ids);
  ZOLTAN_FREE(&parts);
  ZOLTAN_FREE(&newparts);
  if (wtflag) ZOLTAN_FREE(&wgts);

  ZOLTAN_TRACE_EXIT(zz, yo);
  return ierr;
}
Ejemplo n.º 17
0
int Zoltan_Oct_migreg_migrate_orphans(ZZ *zz, pRegion RegionList, int nregions,
                               int level, Map *array, int *c1, int *c2) {
  int     i, j, k;                    /* index counters */
  pRegion ptr;                        /* region in the mesh */
  COORD   origin;                     /* centroid coordinate information */
  pRegion *regions = NULL;            /* an array of regions */
  int     *npids = NULL;
  Region  *regions2 = NULL;           /* an array of regions */
  int     *npids2 = NULL;
  int     nreg;                       /* number of regions */
  COORD   min,                        /* minimum bounds of an octant */
          max;                        /* maximum bounds of an octant */
  COORD   cmin,                       /* minimum bounds of a child octant */
          cmax;                       /* maximum bounds of a child octant */
  COORD   rmin,                       /* minimum bounds of a remote octant */
          rmax;                       /* maximum bounds of a remote octant */
  int     new_num;
  int     n;
  int     dir = 0;
  pRList  RootList;              
  pOctant RootOct;
  OCT_Global_Info *OCT_info = (OCT_Global_Info *)(zz->LB.Data_Structure);
  char *yo = "Zoltan_Oct_migreg_migrate_orphans_static";
  int ierr = ZOLTAN_OK;
  ZOLTAN_ID_PTR gids2, lids2;
  int num_gid_entries = zz->Num_GID;
  int num_lid_entries = zz->Num_LID;

  if(nregions > 0) {
    /* create the array of messages to be sent to other processors */
    /* Array = (Message *) ZOLTAN_MALLOC(nregions * sizeof(Message)); */
    
    if((regions = (pRegion *) ZOLTAN_MALLOC(nregions * sizeof(pRegion))) == NULL) {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory.");
      ZOLTAN_TRACE_EXIT(zz, yo);
      return ZOLTAN_MEMERR;
    }
    if((npids = (int *) ZOLTAN_MALLOC(nregions * sizeof(int))) == NULL) {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory.");
      ZOLTAN_TRACE_EXIT(zz, yo);
      ZOLTAN_FREE(&regions);
      return ZOLTAN_MEMERR;
    }
  }
  ptr = RegionList;
  n = nreg = 0;
  while((ptr != NULL) && (nregions > 0)) {
    if(ptr->attached == 1) {
      /* if region already attached to an octant, then skip to next region */
      ptr = ptr->next;
      continue;
    }

    /* region not attached, have to find which processor to send to */
    j=0;
    dir = 0;
    vector_set(min, OCT_info->OCT_gmin);
    vector_set(max, OCT_info->OCT_gmax);
    /* 
     * for each level of refinement, find which child region belongs to.
     * translate which child to which entry in map array.
     */
    for(i=0; i<level; i++) {
      Zoltan_Oct_bounds_to_origin(min, max, origin);
      if(OCT_info->OCT_dimension == 2)
	j = j * 4;
      else
	j = j * 8;
      k = Zoltan_Oct_child_which(OCT_info,origin, ptr->Coord);
      new_num = Zoltan_Oct_convert_idx_from_map(OCT_info, dir, k);
      dir = Zoltan_Oct_get_child_dir(OCT_info, dir, new_num);
      j += new_num;
      Zoltan_Oct_child_bounds(min, max, origin, k, cmin, cmax);
      vector_set(min, cmin);
      vector_set(max, cmax);
    }
    /* inform message which processor to send to */
    npids[n] = array[j].npid;
    RootList = array[j].list;
    while((RootOct = RL_nextRootOctant(&RootList))) {
      Zoltan_Oct_bounds(RootOct,rmin,rmax);
      if (Zoltan_Oct_in_box_closure(OCT_info, ptr->Coord ,rmin, rmax)) {
	npids[n] = RootOct->npid;
	break;
      }
    }
    if((npids[n] != -1) && (npids[n] != zz->Proc)) {
      Zoltan_Oct_copy_info(zz, ptr, &(regions[n++]));
    }
    else {
      Zoltan_Oct_insert_orphan(zz, *ptr);
    }
    nreg++;                                      /* increment region counter */
    ptr = ptr->next;                                  /* look at next region */
  }

  /*
   * if regions looked at != number of regions in region list, 
   * then there is an error
   */
  if (nreg!=nregions) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "regions found != to expected number of regions");
    return ZOLTAN_FATAL;
  }

  regions2 = (Region *) ZOLTAN_MALLOC(n * sizeof(Region));
  gids2 = ZOLTAN_MALLOC_GID_ARRAY(zz, n);
  lids2 = ZOLTAN_MALLOC_LID_ARRAY(zz, n);
  npids2 = (int *) ZOLTAN_MALLOC(n * sizeof(int));
  
  for(i=0; i<n; i++) {
    npids2[i] = npids[i];
    vector_set(regions2[i].Coord, regions[i]->Coord);
    regions2[i].Weight = regions[i]->Weight;
    regions2[i].Global_ID = &(gids2[i*num_gid_entries]);
    regions2[i].Local_ID = (num_lid_entries 
                              ? &(lids2[i*num_lid_entries]) 
                              : NULL);
    ZOLTAN_SET_GID(zz, &(gids2[i*num_gid_entries]), regions[i]->Global_ID);
    ZOLTAN_SET_LID(zz, &(lids2[i*num_lid_entries]), regions[i]->Local_ID);
    regions2[i].Proc = regions[i]->Proc;
    regions2[i].attached = 0;
  }

  *c1 = n;
  /* migrate the orphan regions according to the message array */
  Zoltan_Oct_migreg_migrate_regions(zz, regions2, gids2, lids2, npids2, n, c2);
  
  for (i=0; i < n; i++) {
    ZOLTAN_FREE(&(regions[i]->Global_ID));
    ZOLTAN_FREE(&(regions[i]->Local_ID));
    ZOLTAN_FREE(&(regions[i]));
  }
  ZOLTAN_FREE(&regions);
  ZOLTAN_FREE(&npids);
  ZOLTAN_FREE(&regions2);
  ZOLTAN_FREE(&gids2);
  ZOLTAN_FREE(&lids2);
  ZOLTAN_FREE(&npids2);

  return ierr;
}
Ejemplo n.º 18
0
static int Zoltan_PHG_Return_Lists (
  ZZ *zz,
  ZHG *zhg,
  int *num_exp,
  ZOLTAN_ID_PTR *exp_gids,
  ZOLTAN_ID_PTR *exp_lids,
  int **exp_procs,
  int **exp_to_part)
{
/* Routine to build export lists of ZOLTAN_LB_FN. */
char *yo = "Zoltan_PHG_Return_Lists";
int i, j;
int ierr = ZOLTAN_OK;
int eproc;
int num_gid_entries   = zz->Num_GID;
int num_lid_entries   = zz->Num_LID;
int nObj              = zhg->nObj;
Partition input_parts = zhg->Input_Parts;
ZOLTAN_ID_PTR gids    = zhg->GIDs;
ZOLTAN_ID_PTR lids    = zhg->LIDs;
int *outparts         = zhg->Output_Parts; 

  if (zz->LB.Return_Lists == ZOLTAN_LB_NO_LISTS) 
    goto End;

  /* Count number of objects with new partitions or new processors. */
  *num_exp = 0;
  for (i = 0; i < nObj; i++) {
    eproc = Zoltan_LB_Part_To_Proc(zz, outparts[i], &gids[i*num_gid_entries]);
    if (outparts[i] != input_parts[i] || zz->Proc != eproc)
      (*num_exp)++;
  }

  /* Allocate memory for return lists. */
  if (*num_exp > 0) {
    if (!Zoltan_Special_Malloc(zz, (void**)exp_gids, *num_exp,
                               ZOLTAN_SPECIAL_MALLOC_GID)
     || !Zoltan_Special_Malloc(zz, (void**)exp_lids, *num_exp,
                               ZOLTAN_SPECIAL_MALLOC_LID)
     || !Zoltan_Special_Malloc(zz, (void**)exp_procs, *num_exp,
                               ZOLTAN_SPECIAL_MALLOC_INT)
     || !Zoltan_Special_Malloc(zz, (void**)exp_to_part, *num_exp,
                               ZOLTAN_SPECIAL_MALLOC_INT)) {
        Zoltan_Special_Free(zz,(void**)exp_gids,   ZOLTAN_SPECIAL_MALLOC_GID);
        Zoltan_Special_Free(zz,(void**)exp_lids,   ZOLTAN_SPECIAL_MALLOC_LID);
        Zoltan_Special_Free(zz,(void**)exp_procs,  ZOLTAN_SPECIAL_MALLOC_INT);
        Zoltan_Special_Free(zz,(void**)exp_to_part,ZOLTAN_SPECIAL_MALLOC_INT);
        ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
        ierr = ZOLTAN_MEMERR;
        goto End;
     }

    for (j = 0, i = 0; i < nObj; i++) {
      eproc = Zoltan_LB_Part_To_Proc(zz, outparts[i], &gids[i*num_gid_entries]);
      if (outparts[i] != input_parts[i] || eproc != zz->Proc) {
        ZOLTAN_SET_GID(zz, &((*exp_gids)[j*num_gid_entries]),
                           &(gids[i*num_gid_entries]));
        if (num_lid_entries > 0)
          ZOLTAN_SET_LID(zz, &((*exp_lids)[j*num_lid_entries]),
                             &(lids[i*num_lid_entries]));
        (*exp_procs)  [j] = eproc;
        (*exp_to_part)[j] = outparts[i];
        j++;
      }
    }
  }

End:

  return ierr;
}
Ejemplo n.º 19
0
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);
}