Example #1
0
int Zoltan_LB_Point_Assign (
 ZZ *zz,
 double *x,
 int *proc)
{
/* Returns processor to which a point should be assigned. */
  char *yo = "Zoltan_LB_Point_Assign";
  if (zz->LB.Point_Assign == NULL) {
    /* function not supported by current decomposition method */
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, 
                   "Point_Assign not supported by chosen partitioning method.");
    return ZOLTAN_FATAL;  
  }

  if (zz->LB.PartDist != NULL) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, 
      "Non-uniform distribution of partitions over processors is specified; "
      "use Zoltan_LB_Point_PP_Assign.");
    return ZOLTAN_FATAL;
  }

  /* call appropriate method; pass proc in partition argument for greater
   * efficiency within LB.Point_Assign (Zoltan is partition-based). */
  return zz->LB.Point_Assign(zz, x, NULL, proc); 
}
Example #2
0
/*
 * Compute an array that contains the cumulative sum of objects
 * on each processor.
 *
 * Memory for the vtxdist array is allocated here,
 * but must be freed by the calling routine.
 *
 */
int Zoltan_Get_Distribution(ZZ *zz, int **vtxdist)
{
  int ierr = ZOLTAN_OK, num_obj;
  char *yo = "Zoltan_Get_Distribution";

  num_obj = zz->Get_Num_Obj(zz->Get_Num_Obj_Data, &ierr);
  if (ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN){
    /* Return error code */
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error in Get_Num_Obj.");
    return (ierr);
  }
  
  *vtxdist = (int *) ZOLTAN_MALLOC((zz->Num_Proc+1)*sizeof(int));
  if (num_obj>0){
    if (!(*vtxdist)){
      /* Not enough memory */
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Out of memory.");
      return ZOLTAN_MEMERR;
    }
  }
  
  /* Construct *vtxdist[i] = the number of objects on all procs < i. */
  /* Scan to compute partial sums of the number of objs */
  MPI_Scan (&num_obj, *vtxdist, 1, MPI_INT, MPI_SUM, zz->Communicator);
  /* Gather data from all procs */
  MPI_Allgather (&((*vtxdist)[0]), 1, MPI_INT, 
                 &((*vtxdist)[1]), 1, MPI_INT, zz->Communicator);
  (*vtxdist)[0] = 0;
  
  return ZOLTAN_OK;
}
Example #3
0
int Zoltan_LB_Box_Assign (
 ZZ *zz,
 double xlo,
 double ylo,
 double zlo,
 double xhi,
 double yhi,
 double zhi,
 int *procs,
 int *count)
{
  char *yo = "Zoltan_LB_Box_Assign";
  int tmp = 0;

  if (zz->LB.Box_Assign == NULL) {
    /* function not supported by current decomposition method */
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, 
                   "Box_Assign not supported by chosen partitioning method.");
    return ZOLTAN_FATAL;  
  }

  if (zz->LB.PartDist != NULL) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo,
      "Non-uniform distribution of partitions over processors is specified; "
      "use Zoltan_LB_Box_PP_Assign.");
    return ZOLTAN_FATAL;
  }

  /* Call appropriate method.  Pass procs and count in partition arguments
   * for greater efficiency in LB.Box_Assign (Zoltan is partition-based.) */
  return zz->LB.Box_Assign(zz, xlo, ylo, zlo, xhi, yhi, zhi, NULL, &tmp, 
                           procs, count);
}
Example #4
0
int Zoltan_DD_Set_Neighbor_Hash_Fn1 (
 Zoltan_DD_Directory *dd,          /* directory state information */
 int size)                         /* number of reserved GIDs per CPU */
   {
   char *yo = "Zoltan_DD_Set_Hash_Fn1";
  struct dd_nh1_struct *hashdata;

   if (dd == NULL || size < 1)  {
      ZOLTAN_PRINT_ERROR (0, yo, "Invalid input argument");
      return ZOLTAN_FATAL;
   }

  hashdata = (struct dd_nh1_struct*) ZOLTAN_MALLOC(sizeof(struct dd_nh1_struct));
  if (hashdata == NULL) {
    ZOLTAN_PRINT_ERROR (0, yo, "Memory error");
    return ZOLTAN_FATAL;
  }

   hashdata->groupsize   = size;
   dd->hash    = (DD_Hash_fn*) &dd_nh1;
   dd->cleanup = (DD_Cleanup_fn*) &Zoltan_DD_default_cleanup;
   dd->hashdata = hashdata;
   hashdata->max_gid = size * dd->nproc;     /* larger GIDs out of range */

   return ZOLTAN_OK;
   }
Example #5
0
int Zoltan_DD_Set_Neighbor_Hash_Fn3 (
 Zoltan_DD_Directory *dd,          /* directory state information */
 int total)                        /* total number of GIDS */
{
  char *yo = "Zoltan_DD_Set_Hash_Fn3";
  struct dd_nh3_struct *hashdata;

  if (dd == NULL || total < 1) {
    ZOLTAN_PRINT_ERROR (0, yo, "Invalid input argument");
    return ZOLTAN_FATAL;
  }

  hashdata = (struct dd_nh3_struct*) ZOLTAN_MALLOC(sizeof(struct dd_nh3_struct));
  if (hashdata == NULL) {
    ZOLTAN_PRINT_ERROR (0, yo, "Memory error");
    return ZOLTAN_FATAL;
  }

  hashdata->total_    = total;
  hashdata->average   = total / dd->nproc;
  hashdata->remainder = total % dd->nproc;
  hashdata->breakpt   = (hashdata->average+1) * hashdata->remainder;

  dd->hash    = (DD_Hash_fn*) &dd_nh3;
  dd->hashdata    = hashdata;
  dd->cleanup = (DD_Cleanup_fn*)&Zoltan_DD_default_cleanup;

  return ZOLTAN_OK;
}
Example #6
0
/* Routine to set function pointers corresponding to input-string options. */
int Zoltan_PHG_Set_Part_Options (ZZ *zz, PHGPartParams *hgp)
{
  int err;
  char *yo = "Zoltan_PHG_Set_Part_Options";  

  if (hgp->bal_tol < 1.0)  {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Invalid PHG_BALANCE_TOLERANCE.");
    return ZOLTAN_FATAL;
  }

  /* Set coarsening method. */
  hgp->matching = NULL;
  if (!(Zoltan_PHG_Set_Matching_Fn (hgp)))  {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Invalid PHG_COARSENING_METHOD.");
    return ZOLTAN_FATAL;
  }

  /* Set (serial) coarse partitioning method.  NOTE: May need parallel
   * partitioning method later if reduction to 1 proc fails              */
  hgp->CoarsePartition = Zoltan_PHG_Set_CoarsePartition_Fn(hgp, &err);
  if (err != ZOLTAN_OK)  {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Invalid PHG_COARSEPARTITION_METHOD.");
      return ZOLTAN_FATAL;
  }

  /* Set refinement method. */
  if (!(hgp->Refinement = Zoltan_PHG_Set_Refinement_Fn(hgp->refinement_str)))  {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Invalid PHG_REFINEMENT_METHOD.");
    return ZOLTAN_FATAL;
  }
  return ZOLTAN_OK;
}
Example #7
0
static int coarse_part_greedy (
  ZZ *zz,
  HGraph *hg,
  int p,
  float *part_sizes,
  Partition part,
  PHGPartParams *hgp
)
{
  int start;
#if 0
  /* UVC commented out to avoid warning */
  int scaling;
  float *new_ewgt=NULL;
#endif
  float *old_ewgt=NULL; 
  int err = ZOLTAN_OK;
  char *yo = "coarse_part_greedy";

  if (hg->nVtx == 0) return ZOLTAN_OK; /* Nothing to do. */

#if 0 /* Disable edge scaling for now since collective comm causes hang. TODO */
  /* Scale the edge weights */
  if (hg->nEdge) {
    if (!(new_ewgt = (float*) ZOLTAN_MALLOC(hg->nEdge * sizeof(float))))
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Out of memory")
    else {
      if (hgp->edge_scaling)
        scaling = hgp->edge_scaling;
      else
        /* Pick a random scaling. */
        scaling = Zoltan_Rand(NULL) % 4; /* scaling is in [0,3] */
      /* Temporarily scale the edge weights (save old weights) */
      Zoltan_PHG_Scale_Edges (zz, hg, new_ewgt, scaling);
      old_ewgt = hg->ewgt;
      hg->ewgt = new_ewgt;
    }
  }
#endif

  /* Start at random vertex */
  start = Zoltan_Rand(NULL) % (hg->nVtx);

  if (p==2)
    /* Call greedy method. */
    err = greedy_grow_part(zz, hg, start, p, part_sizes, part, hgp);
  else
    /* We should always do bisection?? */
    ZOLTAN_PRINT_ERROR (zz->Proc, yo, "Invalid value for p, expected p=2.");

  /* Restore original edge weights */
  if (old_ewgt){
    ZOLTAN_FREE(&(hg->ewgt));
    hg->ewgt = old_ewgt;
    old_ewgt = NULL;
  }

  return err;
}
Example #8
0
/*
 * gather_by_list
 * input:   a list of processors, a message to be sent to these processors,
 *          and a receive buffer to get data back.
 *        
 *  output: concatenated messages from other processors in rbuff, with
 *          appropriate size info in rbuff_size.
 */
int gather_by_list(int procs_length, int   *procs,
                   int sbuff_size,   char  *sbuff, 
                   int *rbuff_size,  char **rbuff, MPI_Comm *comm)
{
    int i, receive_size, mtag, err, myProc;
    char            *send;
    ZOLTAN_COMM_OBJ *plan;
    static char     *yo = "gather_by_list";

    MPI_Comm_rank(*comm, &myProc);

    if (!(send  = (char*) ZOLTAN_MALLOC(procs_length * sizeof(int)))) {
        ZOLTAN_PRINT_ERROR(myProc, yo, "Insufficient memory");
        return ZOLTAN_MEMERR;
    }
    
    mtag = 0;
    for (i = 0; i < procs_length; ++i)
        ((int*)send)[i] = sbuff_size;
    
    /* create and resize communication plan */
    err = Zoltan_Comm_Create(&plan, procs_length, procs, *comm, 
            mtag++, &receive_size);
    if (err < 0)
        ZOLTAN_PRINT_ERROR(myProc, yo, "Zoltan_Comm_Create failed.");    
    err = Zoltan_Comm_Resize(plan, (int*)send, mtag++, rbuff_size);
    if (err < 0)
        ZOLTAN_PRINT_ERROR(myProc, yo, "Zoltan_Comm_Resize failed.");

    ZOLTAN_FREE(&send);
    
    /* allocate send and receive buffer */
    if ((!(*rbuff = (char*) ZOLTAN_MALLOC(*rbuff_size)) && (*rbuff_size != 0))
      ||!(  send  = (char*) ZOLTAN_MALLOC(sbuff_size * procs_length))) {
        printf("failed allocating %d + %d * %d bytes. . .", *rbuff_size, sbuff_size, procs_length);
        fflush(NULL);
        ZOLTAN_PRINT_ERROR(myProc, yo, "Insufficient Memory");
        return ZOLTAN_MEMERR;
    }

    /* copy message for each processor */
    for (i = 0; i < procs_length; ++i)
        memcpy(send + i * sbuff_size, sbuff, sbuff_size);
    
    /* finally, we can do the communication */
    err = Zoltan_Comm_Do(plan, mtag++, send, 1, *rbuff);
    if (err < 0)
        ZOLTAN_PRINT_ERROR(myProc, yo, "Zoltan_Comm_Do failed.");

    /* clean up */
    Zoltan_Comm_Destroy(&plan);
    ZOLTAN_FREE(&send);
    return err;
}
Example #9
0
static int check_input(
    ZZ *zz,
    int parts,
    int *include_parts
)
{
    /*
     * Routine to ensure that all processors have the same values of
     * zz->Num_GID and zz->Num_LID.
     * Also, check whether partitions are included on any processors; if so,
     * set include_parts to true.
     * All processors return the same error code.
     */
    char *yo = "check_input";
    char msg[256];
    int loc_tmp[6];
    int glob[] = {0, 0, 0, 0, 0, 0};
    int ierr = ZOLTAN_OK;

    loc_tmp[0] = zz->Num_GID;
    loc_tmp[1] = zz->Num_LID;
    loc_tmp[2] = parts;
    loc_tmp[3] = -(zz->Num_GID);
    loc_tmp[4] = -(zz->Num_LID);
    loc_tmp[5] = -(parts);

    /*
     * Check both max and min values of IDs so that all processors can
     * return the same error code.
     */

    MPI_Allreduce(loc_tmp, glob, 6,
                  MPI_INT, MPI_MIN, zz->Communicator);
    *include_parts = -(glob[5]);

    if ((glob[0] != -(glob[3])) ||
            (glob[1] != -(glob[4])))
        ierr = ZOLTAN_FATAL;

    if (zz->Num_GID != -(glob[3])) {
        sprintf(msg, "Inconsistent global id sizes: Num_GID = %d "
                "but global max is %d\n", zz->Num_GID, -(glob[3]));
        ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
    }

    if (zz->Num_LID != -(glob[4])) {
        sprintf(msg, "Inconsistent local id sizes: Num_LID = %d "
                "but global max is %d\n", zz->Num_LID, -(glob[4]));
        ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
    }

    return ierr;
}
Example #10
0
int Zoltan_Help_Migrate(
    ZZ *zz,
    int num_import,
    ZOLTAN_ID_PTR import_global_ids,
    ZOLTAN_ID_PTR import_local_ids,
    int *import_procs,
    int num_export,
    ZOLTAN_ID_PTR export_global_ids,
    ZOLTAN_ID_PTR export_local_ids,
    int *export_procs
)
{
    /*
     *  Wrapper around Zoltan_Migrate with NULL pointers for partition arrays.
     *  Maintained for backward compatibility.
     *  Arguments are same as for Zoltan_Migrate.
     */

    char *yo = "Zoltan_Help_Migrate";
    int ierr;

    ZOLTAN_TRACE_ENTER(zz, yo);

    if (zz->LB.PartDist != NULL) {
        ZOLTAN_PRINT_ERROR(zz->Proc, yo,
                           "Non-uniform distribution of partitions over processors is specified; "
                           "use Zoltan_Migrate\n");
        ierr = ZOLTAN_FATAL;
        goto End;
    }

    if (zz->Migrate.Pre_Migrate_PP || zz->Migrate.Mid_Migrate_PP ||
            zz->Migrate.Post_Migrate_PP) {
        ZOLTAN_PRINT_ERROR(zz->Proc, yo,
                           "Partition information not available in Zoltan_Help_Migrate for "
                           "ZOLTAN_*_MIGRATE_PP_FNs; use ZOLTAN_*_MIGRATE_FNs instead.");
        ierr = ZOLTAN_FATAL;
        goto End;
    }

    /*
     * Wrapper (for backward compatilibity) around Zoltan_Migrate.
     * Passes NULL for partition assignment arrays.
     */
    ierr = Zoltan_Migrate(zz, num_import, import_global_ids, import_local_ids,
                          import_procs, NULL,
                          num_export, export_global_ids, export_local_ids,
                          export_procs, NULL);

End:
    ZOLTAN_TRACE_EXIT(zz, yo);
    return ierr;
}
Example #11
0
int Zoltan_DD_Set_Neighbor_Hash_Fn2 (
 Zoltan_DD_Directory *dd,     /* directory state information */
 int *proc,                   /* list of processors for following info */
 int *low,                    /* lowest GID for corresponding processor */
 int *high,                   /* highest GID for corresponding processor */
 int n)                       /* number of processors in above lists */
   {
   int i;
   char *yo = "Zoltan_DD_Set_Hash_Fn2";
   struct dd_nh2_struct *hashdata;


   if (dd == NULL || proc == NULL || low == NULL || high == NULL)  {
      ZOLTAN_PRINT_ERROR (0, yo, "Invalid input argument");
      return ZOLTAN_FATAL;
   }

  hashdata = (struct dd_nh2_struct*) ZOLTAN_MALLOC(sizeof(struct dd_nh2_struct));
  if (hashdata == NULL) {
    ZOLTAN_PRINT_ERROR (0, yo, "Memory error");
    return ZOLTAN_FATAL;
  }


   /* register functions for automatic invocation */
   dd->hash    = (DD_Hash_fn*) &dd_nh2;
   dd->cleanup = (DD_Cleanup_fn*)&dd_nh2_cleanup;
   dd->hashdata = hashdata;

   /* malloc and initialize storage for range information structures */
   hashdata->ptr = (Range_Info*)  ZOLTAN_MALLOC (n * sizeof (Range_Info));
   if (hashdata->ptr == NULL)  {
      ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Unable to Malloc range info");
      return ZOLTAN_MEMERR;
   }
   for (i = 0;  i < n; i++)  {
      hashdata->ptr[i].high = high[i] ;
      hashdata->ptr[i].low  = low [i] ;
      hashdata->ptr[i].proc = (proc[i] < n) ? proc[i] : 0;
   }

   /* do not assume user lists were ordered */
   qsort (hashdata->ptr, n, sizeof (Range_Info), compare_sort);

   hashdata->low_limit   = hashdata->ptr[0].low;
   hashdata->high_limit  = hashdata->ptr[n-1].high;
   hashdata->debug_level = dd->debug_level;
   hashdata->count       = n;
   hashdata->nproc       = dd->nproc;

   return ZOLTAN_OK;
   }
Example #12
0
double Zoltan_PHG_Compute_Balance (
  ZZ *zz,
  HGraph *hg,
  float *part_sizes,
  int wgtidx,/* compute balance w.r.t. this component of vwgt and part_sizes */
  int p,
  Partition part
)
{
  int i;
  double *lsize_w, *size_w, max_imbal, tot_w;
  char *yo = "Zoltan_PHG_Compute_Balance";
  int part_dim = (hg->VtxWeightDim ? hg->VtxWeightDim : 1);
  
  if (!hg || !hg->comm || !hg->comm->row_comm)  {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Unable to compute balance");
    return 1.0;
  }  
  
  if (!(lsize_w = (double*) ZOLTAN_CALLOC (2*p, sizeof(double)))) {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory.");
      return ZOLTAN_MEMERR;
  }
  size_w = lsize_w + p;
  
  if (hg->vwgt)
    for (i = 0; i < hg->nVtx; i++)
      lsize_w[part[i]] += hg->vwgt[i*hg->VtxWeightDim+wgtidx];
  else
    for (i = 0; i < hg->nVtx; i++)
      lsize_w[part[i]]++;
        
  MPI_Allreduce(lsize_w, size_w, p, MPI_DOUBLE, MPI_SUM, hg->comm->row_comm);
  
  max_imbal = tot_w = 0.0;
  for (i = 0; i < p; i++) 
      tot_w += size_w[i];
  if (tot_w) {
      for (i = 0; i < p; i++) {
          float this_part_size = part_sizes[i*part_dim+wgtidx];
          if (this_part_size) {
              double ib=(size_w[i]-this_part_size*tot_w)/(this_part_size*tot_w);
              if (ib>max_imbal)
                  max_imbal = ib;
          }
      }
  }

  ZOLTAN_FREE (&lsize_w);

  return  1.0+max_imbal;
}
Example #13
0
int Zoltan_Map_First(ZZ *zz, ZOLTAN_MAP* map, int **key, int *data)
{
  char *yo = "Zoltan_Map_First";
  ZOLTAN_ENTRY *entry = NULL;
  int i;

  *key = NULL;
  *data = ZOLTAN_NOT_FOUND;

  if (map){

    if (map->entry_count == 0){
      map->prev_index = -1;
      map->prev_hash_index = -1;
      map->prev = NULL;
    }
    else{
      if (!map->dynamicEntries){
	map->prev_index = 0;
	entry = map->top;
      }
      else{

	/* find the first entry in the map */

	for (i=0; i <= map->max_index; i++){
	  if (map->entries[i]){

	    map->prev_hash_index = i;
	    entry = map->prev = map->entries[i];
	    break;
	  }
	}
	if (!entry){
	  ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Entry not found\n");
	  return ZOLTAN_FATAL;
	}
      }

      *key = entry->key;
      *data = entry->data;
    }
  }
  else {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Invalid map\n");
    return ZOLTAN_FATAL;
  }

  return ZOLTAN_OK;
}
Example #14
0
int Zoltan_Map_Find(ZZ *zz, ZOLTAN_MAP* map, int *key, int *data)
{
  char *yo = "Zoltan_Map_Find";
  int index, match;
  ZOLTAN_ENTRY *element;
  ZOLTAN_ID_PTR zkey = (ZOLTAN_ID_PTR)key;

  *data = ZOLTAN_NOT_FOUND;

  if (!map){
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Map specified does not exist\n");
    return ZOLTAN_FATAL;
  }

  index = Zoltan_Hash(zkey, map->id_size, map->max_index);

  element = map->entries[index];
  match = 0;

  while (element != NULL){
    match = key_match(map->id_size, element->key, key);
    if (match){
      *data = element->data;
      break;
    }
    element = element->next;
  }
  return ZOLTAN_OK;
}
Example #15
0
int Zoltan_KVHash_Insert(KVHash *hash, ZOLTAN_GNO_TYPE key, int value)
{
    int i;
    
    G2LHashNode *ptr;

    i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *)&key, hash->num_gid_entries, (unsigned int) hash->maxsize);
    for (ptr=hash->table[i]; ptr && ptr->gno!=key; ptr = ptr->next);
    if (!ptr) {
        if (hash->size >= hash->maxsize) {
            ZOLTAN_PRINT_ERROR(-1, "Zoltan_KVHash_Insert", "Hash is full!");
            return -1;
        }
        
        ptr = &(hash->nodes[hash->size]);
        ptr->gno = key;
        ptr->lno = value;
        ptr->next = hash->table[i];
        hash->table[i] = ptr;
        ++hash->size;
    } else
        value = ptr->lno;

    return value;   
}
Example #16
0
int Zoltan_G2LHash_Insert(G2LHash *hash, ZOLTAN_GNO_TYPE gno)
{
    int i, lno;
    G2LHashNode *ptr;

    if (gno<hash->base || gno>hash->baseend) {
        i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *)&gno, hash->num_gid_entries, (unsigned int) hash->maxsize);
        for (ptr=hash->table[i]; ptr && ptr->gno!=gno; ptr = ptr->next);
        if (!ptr) {
            if (hash->size >= hash->maxsize) {
                char st[2048];
                sprintf(st, "Hash is full! #entries=%d  maxsize=%d", hash->size, hash->maxsize);
                ZOLTAN_PRINT_ERROR(-1, "Zoltan_G2LHash_G2L", st);
                return -1;
            }
            ptr = &(hash->nodes[hash->size]);
            ptr->gno = gno;
            lno = ptr->lno = hash->nlvtx + hash->size;
            ptr->next = hash->table[i];
            hash->table[i] = ptr;
            ++hash->size;
        } else
            lno = ptr->lno;
    } else
        return gno-hash->base;

    return lno;
}
Example #17
0
/* Random partitioning. Sequence partitioning with vertices in random order. */
static int coarse_part_random (
  ZZ *zz,
  HGraph *hg,
  int p,
  float *part_sizes,
  Partition part,
  PHGPartParams *hgp
)
{
    int i, err=0, *order=NULL;
    char *yo = "coarse_part_random";

    if (!(order  = (int*) ZOLTAN_MALLOC (hg->nVtx*sizeof(int)))) {
        ZOLTAN_FREE (&order);
        ZOLTAN_PRINT_ERROR (zz->Proc, yo, "Insufficient memory.");
        return ZOLTAN_MEMERR;
    }
    for (i=0; i<hg->nVtx; i++) {
        order[i] = i;
    }

    /* Randomly permute order array */
    Zoltan_Rand_Perm_Int (order, hg->nVtx, NULL);
        
    /* Call sequence partitioning with random order array. */
    err = seq_part (zz, hg, order, p, part_sizes, part, hgp);

    ZOLTAN_FREE (&order);
    return err;
}
Example #18
0
int Zoltan_RCB_Copy_Structure(ZZ *toZZ, ZZ const *fromZZ)
{
  char *yo = "Zoltan_RCB_Copy_Structure";
  RCB_STRUCT *to;
  RCB_STRUCT const *from;

  from = (RCB_STRUCT const *)fromZZ->LB.Data_Structure;
  Zoltan_RCB_Free_Structure(toZZ);

  if (!from){
    return(ZOLTAN_OK);
  }

  to = (RCB_STRUCT *)ZOLTAN_MALLOC(sizeof(RCB_STRUCT));
  if (to == NULL) {
    ZOLTAN_PRINT_ERROR(fromZZ->Proc, yo, "Insufficient memory.");
    return(ZOLTAN_MEMERR);
  }

  toZZ->LB.Data_Structure = (void *)to;
  *to = *from;

  COPY_BUFFER(Tree_Ptr, struct rcb_tree, fromZZ->LB.Num_Global_Parts);

  COPY_BUFFER(Box, struct rcb_box, 1);

  return ZOLTAN_OK;
}
Example #19
0
int Zoltan_LB_Box_PP_Assign (
 ZZ *zz,
 double xlo,
 double ylo,
 double zlo,
 double xhi,
 double yhi,
 double zhi,
 int *procs,
 int *proc_count,
 int *parts,
 int *part_count)
{
  char *yo = "Zoltan_LB_Box_PP_Assign";

  if (zz->LB.Box_Assign == NULL) {
    /* function not supported by current decomposition method */
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, 
                   "Box_Assign not supported by chosen partitioning method.");
    return ZOLTAN_FATAL;  
  }

  /* Call appropriate method.  Pass procs and count in partition arguments
   * for greater efficiency in LB.Box_Assign (Zoltan is partition-based.) */
  return zz->LB.Box_Assign(zz, xlo, ylo, zlo, xhi, yhi, zhi, procs, proc_count,
                           parts, part_count);
}
Example #20
0
int phg_map_GIDs_to_processes(ZZ *zz, ZOLTAN_ID_PTR eid, int size, 
                             int lenGID, int **hashedProc, int nprocs)
{
int i, j;
int *procList;
static char *yo = "map_GIDs_to_processes";

  *hashedProc = NULL;

  if (size < 1){
    return ZOLTAN_OK;
  }

  procList = (int *)ZOLTAN_MALLOC(sizeof(int) * size);

  if (!procList){
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error."); 
    return ZOLTAN_MEMERR;
  }

  for (i=0; i<size; i++){
    j = Zoltan_Hash(eid, lenGID, nprocs);
    procList[i] = j;
    eid += lenGID;
  }

  *hashedProc = procList;

  return ZOLTAN_OK;
}
Example #21
0
ZOLTAN_ID_PTR ZOLTAN_Malloc_ID(int n, char *file, int line)
{
/*
 * Allocates an array of size n of ZOLTAN_ID_TYPEs and initializes them.
 */

ZOLTAN_ID_PTR tmp;
char *yo = "ZOLTAN_Malloc_ID";

  /* 
   * Don't use ZOLTAN_MALLOC macro here; prefer to pass file and line 
   * where ZOLTAN_Malloc_ID was called.
   */
  tmp = (ZOLTAN_ID_PTR) Zoltan_Malloc(n * sizeof(ZOLTAN_ID_TYPE), file, line);

  if (tmp != NULL) {
    ZOLTAN_INIT_ID(n,tmp);
  }
  else if (n > 0) {
    char msg[256];
    sprintf(msg, "NULL pointer returned; malloc called from %s, line %d.",
            file, line);
    ZOLTAN_PRINT_ERROR(-1, yo, msg);
  }

  return tmp;
}
Example #22
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;
}
Example #23
0
/*
 * gather_row
 * input:   our processor location, a message, and space to hold a return
 *          message.
 * output:  received messages from each processor in our row in rbuff.
 */
int gather_row(int nProc_x, int nProc_y, int myProc_x, int myProc_y, 
               int sbuff_size, char *sbuff, int *rbuff_size, char **rbuff,
               MPI_Comm *comm)
{
    int  i, my_proc, err;
    int  *procs;
    static char *yo = "gather_row";
    
    /* create list of processors to send to (everyone in our row but us)     */
    /* this assumes a linear left->right numbering of processors in our grid */
    myProc_y *= nProc_x;
    my_proc = myProc_x + myProc_y;
    
    if (!(procs = (int*)  ZOLTAN_MALLOC((nProc_x) * sizeof(int)))) {
        ZOLTAN_PRINT_ERROR(my_proc, yo, "Insufficient memory");
        return ZOLTAN_MEMERR;
    }
    
    /*
      for (i = 0; i < myProc_x; ++i)
          procs[i] = myProc_y + i;
      for (i = myProc_x; i < nProc_x - 1; ++i)
          procs[i] = myProc_y + i + 1;
    */

    /* do self communication */
    for (i = 0; i < nProc_x; ++i)
      procs[i] = myProc_y + i;  
    
    err = gather_by_list(nProc_x, procs, 
                         sbuff_size, sbuff, rbuff_size, rbuff, comm);
    
    ZOLTAN_FREE(&procs);
    return err;
}
Example #24
0
void Zoltan_DD_Destroy (Zoltan_DD_Directory **dd)
{
   char *yo = "ZOLTAN_DD_Destroy";

   /* input sanity check */
   if (dd == NULL || *dd == NULL) {
      ZOLTAN_PRINT_ERROR (0, yo, "Input argument dd is NULL");
      return;
   }
   if ((*dd)->debug_level > 4)
      ZOLTAN_TRACE_IN ((*dd)->my_proc, yo, NULL);

   ZOLTAN_FREE(&((*dd)->nodelist));
   ZOLTAN_FREE(&((*dd)->nodedata));

   /* execute user registered cleanup function, if needed */
   if ((*dd)->cleanup != NULL)
       (*dd)->cleanup((*dd)->hashdata);

   MPI_Comm_free (&((*dd)->comm));    /* free MPI Comm, ignore errors */

   if ((*dd)->debug_level > 4)
      ZOLTAN_TRACE_OUT ((*dd)->my_proc, yo, NULL);

   ZOLTAN_FREE (dd);                  /* free directory structure     */
   return;
}
Example #25
0
static int get_current_part(ZOLTAN_REFTREE *subroot, ZZ *zz, int *ierr)
{
/*
 * Function to return the current partition of an object.
 * If there is no user defined get_partition function, then the returned
 * value only indicates whether or not the partition number is this
 * processor's number.
 */

char *yo = "get_current_part";
int result;

  *ierr = ZOLTAN_OK;

/* if the user registered a partition function, then use it */
  if (zz->Get_Part != NULL) {
    result = zz->Get_Part(zz->Get_Part_Data,zz->Num_GID,zz->Num_LID,
                               subroot->global_id,subroot->local_id, ierr);
    if (*ierr != ZOLTAN_OK && *ierr != ZOLTAN_WARN) {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo,
                         "Error returned from ZOLTAN_PART_FN");
    }
  }
  else if (zz->Get_Part_Multi != NULL) {
/* Not the best use of Multi function, but best I can do. KDD */
    zz->Get_Part_Multi(zz->Get_Part_Multi_Data,
                            zz->Num_GID,zz->Num_LID,1,
                            subroot->global_id,subroot->local_id,
                            &result,ierr);
    if (*ierr != ZOLTAN_OK && *ierr != ZOLTAN_WARN) {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo,
                         "Error returned from ZOLTAN_PART_MULTI_FN");
    }
  }
  else {

/* otherwise, return my processor number if the object is assigned to
   this processor, or any other value if it is not */

    if (subroot->assigned_to_me)
      result = zz->Proc;
    else
      result = zz->Proc-1;
  }

  return(result);
}
Example #26
0
int Zoltan_Heap_Input (HEAP *h, int element, float value)
{
static char *yo = "Zoltan_Heap_Input";

  if (element >= h->space) {
     ZOLTAN_PRINT_ERROR(0, yo, "Inserted heap element out of range!\n");
     return ZOLTAN_FATAL;
     }
  if (h->n >= h->space) {
     ZOLTAN_PRINT_ERROR(0, yo, "Heap is full!\n");
     return ZOLTAN_FATAL;
     }
  h->value[element] = value;
  h->pos[element]   = h->n;
  h->ele[(h->n)++]  = element;
  return ZOLTAN_OK;
}
Example #27
0
int Zoltan_Drum_Stop_Monitors(ZZ *zz) {
  int ierr;
  char *yo = "Zoltan_Drum_Stop_Monitors";
  FILE *fp;

  if ((zz->Drum.use_drum == 0) || (zz->Drum.start_monitors == 0))
    return ZOLTAN_OK;

  if (!zz->Drum.dmm) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "DRUM not initialized");
    return ZOLTAN_FATAL;
  }

  ierr = DRUM_stopMonitoring(zz->Drum.dmm);
  if (ierr == DRUM_FATAL) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Unable to stop DRUM monitors");
    return ZOLTAN_FATAL;
  }

  ierr = DRUM_computePowers(zz->Drum.dmm);
  if (ierr == DRUM_FATAL) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Unable to compute DRUM powers");
    return ZOLTAN_FATAL;
  }

  /* print the "power file" if it was requested */
  if (zz->Proc == 0 && strcmp(zz->Drum.power_filename,"")) {
    fp = fopen(zz->Drum.power_filename, "a");
    if (fp) {
      DRUM_printMachineModel(zz->Drum.dmm, fp);
      fclose(fp);
    }
    else {
      ZOLTAN_PRINT_WARN(zz->Proc, yo, "Could not open power file");
      return ZOLTAN_WARN;
    }
  }
  else {
    if (zz->Proc == 0) {
      printf("Skipping power file output\n"); fflush(stdout);
    }
  }

  return ZOLTAN_OK;
}
Example #28
0
int Zoltan_Drum_Start_Monitors(ZZ *zz) {
  int ierr;
  char *yo = "Zoltan_Drum_Start_Monitors";

  if ((zz->Drum.use_drum == 0) || (zz->Drum.start_monitors == 0))
    return ZOLTAN_OK;

  if (!zz->Drum.dmm) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "DRUM not initialized");
    return ZOLTAN_FATAL;
  }

  ierr = DRUM_startMonitoring(zz->Drum.dmm);
  if (ierr == DRUM_FATAL) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Unable to start DRUM monitors");
    return ZOLTAN_FATAL;
  }
  return ZOLTAN_OK;
}
Example #29
0
static int DD_Find_Local (Zoltan_DD_Directory *dd,
 ZOLTAN_ID_PTR gid,         /* incoming GID to locate (in)            */
 ZOLTAN_ID_PTR lid,         /* gid's LID (out)                        */
 char *user,                /* gid's user data (out)                  */
 int *partition,            /* gid's partition number (out)           */
 int *owner)                /* gid's owner (processor number) (out)   */
{
   DD_Node *ptr;
   DD_NodeIdx nodeidx;
   int      index;
   char    *yo = "DD_Find_Local";

   /* input sanity check */
   if (dd == NULL || owner == NULL || gid == NULL)  {
      ZOLTAN_PRINT_ERROR ((dd == NULL) ? 0 : dd->my_proc, yo, "Invalid input");
      return ZOLTAN_FATAL;
   }
   if (dd->debug_level > 5)
      ZOLTAN_TRACE_IN (dd->my_proc, yo, NULL);

   /* compute offset into hash table to find head of linked list */
   index = Zoltan_DD_Hash2 (gid, dd->gid_length, dd->table_length,
                            dd->hashdata, NULL);
   /* walk link list until end looking for matching global ID */
   for (nodeidx = dd->table[index]; nodeidx != -1;
        nodeidx = dd->nodelist[nodeidx].next) {
      ptr = dd->nodelist + nodeidx;
      if (ZOLTAN_EQ_ID (dd->gid_length, gid, ptr->gid) == TRUE)  {
         /* matching global ID found! Return gid's information */
         if (lid) ZOLTAN_SET_ID(dd->lid_length, lid, ptr->gid + dd->gid_length);
         if (user) memcpy(user, ptr->gid + (dd->gid_length + dd->lid_length),
                          dd->user_data_length);

         if (owner)     *owner     = ptr->owner;
         if (partition) *partition = ptr->partition;

         if (dd->debug_level > 5)
            ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);
         return ZOLTAN_OK;
      }
   }


   if (owner != NULL)
      *owner = -1;    /* JDT Added -1 owner not found */
   if (dd->debug_level > 5)
      ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);

   if (dd->debug_level > 0)  {
      ZOLTAN_PRINT_INFO(dd->my_proc, yo, "GID not found");
      return ZOLTAN_WARN;
   }
   return ZOLTAN_WARN;
}
Example #30
0
void Zoltan_DD_Stats (
 Zoltan_DD_Directory *dd)   /* directory state information */
   {
   int node_count = 0 ;     /* counts Nodes in local directory      */
   int maxlength  = 0;      /* length of longest linked list        */
   int list_count = 0 ;     /* number of linked lints in hash table */

   int      length ;
   int      i ;
   DD_Node *ptr ;
   char     str[100] ;      /* used to build message string */
   char    *yo = "Zoltan_DD_Stats" ;


   /* Input sanity check */
   if (dd == NULL)
      {
      ZOLTAN_PRINT_ERROR (0, yo, "Invalid input argument.") ;
      return ;
      }

   if (dd->debug_level > 4)
      ZOLTAN_TRACE_IN (dd->my_proc, yo, NULL) ;

   /* walk down each list in hash table to find every Node */
   for (i = 0 ; i < dd->table_length ; i++)
      {
      length = 0 ;                    /* reset length for next count */
      if (dd->table[i] != NULL)
         list_count++ ;               /* count of distict linked lists */

      for (ptr = dd->table[i] ; ptr != NULL ; ptr = ptr->next)
         {
         if (dd->debug_level > 6)
            {
            sprintf (str, "GID %4u, Owner %d, Table Index %d.", *ptr->gid,
             ptr->owner, i) ;
            ZOLTAN_PRINT_INFO (dd->my_proc, yo, str) ;
            }
         length++ ;                  /* linked list length */
         node_count++ ;              /* count of Nodes */
         }
      if (length > maxlength)
         maxlength = length ;        /* save length of longest linked list */
      }

   sprintf (str, "Hash table size %d, %d nodes on %d lists, max list length %d.",
    dd->table_length, node_count, list_count, maxlength) ;
   ZOLTAN_PRINT_INFO (dd->my_proc, yo, str) ;

   if (dd->debug_level > 4)
      ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL) ;
   }