Zoltan is added as thirdParty package

This commit is contained in:
Hamidreza
2025-05-15 21:58:43 +03:30
parent 83a6e4baa1
commit d7479cf1bd
3392 changed files with 318142 additions and 1 deletions

69
thirdParty/Zoltan/src/lb/README vendored Normal file
View File

@ -0,0 +1,69 @@
# @HEADER
#
########################################################################
#
# Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
# Copyright 2012 Sandia Corporation
#
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the Corporation nor the names of the
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Questions? Contact Karen Devine kddevin@sandia.gov
# Erik Boman egboman@sandia.gov
#
########################################################################
#
# @HEADER
LB DIRECTORY -- Zoltan load-balancing tools.
------------------------------------------------------------------------
lb_balance.c -- Routines for computing new partitions and
managing memory for allocated by Zoltan but returned
to the application.
lb_eval.c -- Routines for evaluating the quality of partitions.
lb_init.c -- Routines to initialize Zoltan's load-balancing tools.
lb_migrate.c -- Routines to provide help for data migration.
lb_set_method.c -- Routines to set the load-balancing method.
lb_set_fn.c -- Routines to register callback functions specific to
load-balancing tools.
lb_const.h -- Zoltan data structures for load balancing;
these data structures are private to the
library (i.e., not seen by the application).
Also includes macros and prototypes for Zoltan
load-balancing functions.

1122
thirdParty/Zoltan/src/lb/lb_balance.c vendored Normal file

File diff suppressed because it is too large Load Diff

122
thirdParty/Zoltan/src/lb/lb_box_assign.c vendored Normal file
View File

@ -0,0 +1,122 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
/****************************************************************************/
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);
}
/****************************************************************************/
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);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

380
thirdParty/Zoltan/src/lb/lb_const.h vendored Normal file
View File

@ -0,0 +1,380 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifndef __LB_CONST_H
#define __LB_CONST_H
#include "zoltan.h"
#include "zoltan_dd.h"
#include "params_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*
* Type definitions for functions that depend on
* load-balancing method.
*/
struct Zoltan_Struct;
typedef int ZOLTAN_LB_FN(struct Zoltan_Struct *, float *, int *,
ZOLTAN_ID_PTR *, ZOLTAN_ID_PTR *, int **, int **,
int *, ZOLTAN_ID_PTR *,
ZOLTAN_ID_PTR *, int **, int **);
typedef void ZOLTAN_LB_FREE_DATA_FN(struct Zoltan_Struct *);
typedef int ZOLTAN_LB_COPY_DATA_FN(struct Zoltan_Struct *to, struct Zoltan_Struct const *from);
typedef size_t ZOLTAN_LB_SERIALIZE_DATA_SIZE_FN(struct Zoltan_Struct const *);
typedef void ZOLTAN_LB_SERIALIZE_DATA_FN(struct Zoltan_Struct const *, char **);
typedef void ZOLTAN_LB_DESERIALIZE_DATA_FN(struct Zoltan_Struct *, char **);
typedef int ZOLTAN_LB_POINT_ASSIGN_FN(struct Zoltan_Struct *, double *, int *,
int *);
typedef int ZOLTAN_LB_BOX_ASSIGN_FN(struct Zoltan_Struct *,
double, double, double,
double, double, double,
int*, int*, int *, int *);
/*
* Define the possible load balancing methods allowed.
*/
typedef enum Zoltan_LB_Method {
NONE = -1,
BLOCK,
CYCLIC,
RANDOM,
RCB,
PARMETIS,
JOSTLE,
REFTREE,
RIB,
HSFC,
GRAPH,
HYPERGRAPH,
HIER,
ZOLTAN_LB_MAX_METHODS /* This entry should always be last. */
} ZOLTAN_LB_METHOD;
/*
* Values indicating which lists (import, export, export including
* exports "to myself", both, or none) should
* be returned by Zoltan_LB_Balance. ZOLTAN_LB_NO_LISTS must always be zero;
* other values should always be greater than zero.
*/
#define ZOLTAN_LB_NO_LISTS 0
#define ZOLTAN_LB_IMPORT_LISTS 1
#define ZOLTAN_LB_EXPORT_LISTS 2
#define ZOLTAN_LB_COMPLETE_EXPORT_LISTS 3
#define ZOLTAN_LB_ALL_LISTS 4
#define ZOLTAN_LB_CANDIDATE_LISTS 5
/*
******************************************************
* Define default values for key parameters.
******************************************************
*/
#define ZOLTAN_LB_IMBALANCE_TOL_DEF 1.1
#define ZOLTAN_AUTO_MIGRATE_DEF FALSE
#define ZOLTAN_MIGRATE_ONLY_PROC_CHANGES_DEF 1
#define ZOLTAN_LB_RETURN_LISTS_DEF ZOLTAN_LB_ALL_LISTS
#define ZOLTAN_LB_APPROACH_DEF "repartition"
/* Struct for part size info. */
struct Zoltan_part_info {
float Size; /* Desired part size. */
int Part_id; /* Part id. */
int Idx; /* Part weight index. */
int Global_num; /* Global part numbers? */
};
/* LB_struct. Contains all information about a load balancing "object" */
struct Zoltan_LB_Struct {
int Part_Info_Len; /* Actual length of Part_Info arrays. */
int Part_Info_Max_Len; /* Allocated length of Part_Info arrays. */
struct Zoltan_part_info *Part_Info; /* Array of part size info. */
int Num_Global_Parts; /* The total number of parts.
Set in Zoltan_LB_Build_PartDist. */
int Num_Global_Parts_Param; /* The number of global parts specified.
If parameter NUM_LOCAL_PARTS or
NUM_GLOBAL_PARTS is not set,
Num_Global_Parts_Param == Num_Proc. */
int Num_Local_Parts_Param; /* The number of local parts specified.
If parameter NUM_LOCAL_PARTS or
NUM_GLOBAL_PARTS is not set,
Num_Local_Parts_Param == -1. */
int Prev_Global_Parts_Param; /* The previous values of
Num_Global_Parts_Param. Stored to
prevent unnecessary re-creations of
PartDist. */
int Prev_Local_Parts_Param; /* The previous values of
Num_Local_Parts_Param. Stored to
prevent unnecessary re-creations of
PartDist. */
int Single_Proc_Per_Part; /* Flag indicating whether a part can
be spread across multiple processors.
Happens only when NUM_GLOBAL_PARTS
is set to be < zz->Num_Proc. */
int Remap_Flag; /* Flag indicating whether parts
should be remapped to reduce data mvmt. */
int *Remap; /* Remapping array; relabels computed
parts to decrease data mvmt. */
int *OldRemap; /* Remapping array computed in previous
invocation of partitioning. */
int Return_Lists; /* Flag indicating which lists (if any)
should be returned by Zoltan_LB_Balance.*/
int Uniform_Parts; /* Flag indicating whether parts are
uniformly sized. */
int *PartDist; /* Array describing distribution of
parts to processors.
If Single_Proc_Per_Part, part i
is located on processor PartDist[i].
If !Single_Proc_Per_Part, part i
is located on processors PartDist[i] to
PartDist[i+1]-1. */
int *ProcDist; /* Array describing distribution of
processors to parts.
If processor i has zero parts,
ProcDist[i] = -1. Otherwise,
ProcDist[i] has the lowest part
number of parts on processor i. */
ZOLTAN_LB_METHOD Method; /* Method to be used for load balancing. */
char Method_Name[MAX_PARAM_STRING_LEN];
/* String for method to be used. */
ZOLTAN_LB_FN *LB_Fn; /* Pointer to the function that performs
the load balancing; this ptr is set
based on the method used. */
char Approach[MAX_PARAM_STRING_LEN];
/* String describing load balance approach. */
float *Imbalance_Tol; /* Tolerance to which to load balance;
Imbalance_Tol = 1.1 implies 10% imbalance
is acceptable, i.e. max/avg = 1.1.
Imbalance_Tol may be an array of
dimension Obj_Weight_Dim. */
int Imb_Tol_Len; /* Length of Imbalance_Tol array. */
void *Data_Structure; /* Data structure used by the load
balancer; cast by the method routines
to the appropriate data type. */
ZOLTAN_LB_FREE_DATA_FN *Free_Structure;
/* Pointer to function that frees the
Data_Structure memory. */
ZOLTAN_LB_COPY_DATA_FN *Copy_Structure;
/* Pointer to function that copies the
Data_Structure */
ZOLTAN_LB_SERIALIZE_DATA_SIZE_FN *Serialize_Structure_Size;
/* Pointer to function that returns the
buffer size to serialize the LB data */
ZOLTAN_LB_SERIALIZE_DATA_FN *Serialize_Structure;
/* Pointer to function that copies LB data
into a buffer to serialize the data */
ZOLTAN_LB_DESERIALIZE_DATA_FN *Deserialize_Structure;
/* Pointer to function that copies data from
a buffer to initialize the LB struct */
ZOLTAN_LB_POINT_ASSIGN_FN *Point_Assign;
/* Pointer to the function that performs
Point_Assign; this ptr is set based on
the method used. */
ZOLTAN_LB_BOX_ASSIGN_FN *Box_Assign;
/* Pointer to the function that performs
Box_Assign; this ptr is set based on
the method used. */
};
struct Zoltan_Migrate_Struct {
int Auto_Migrate; /* Flag indicating whether the load
balancer should automatically
help the application
migrate data. Some applications may
prefer to do it themselves. */
int Only_Proc_Changes; /* Pack and unpack objects during
migration ONLY if they are assigned
to a new processor. If part
number changes but processor does
not, do not pack and unpack. */
/*
* Pointers to routines that depend on the application.
*/
ZOLTAN_PRE_MIGRATE_PP_FN *Pre_Migrate_PP;
/* Function that performs application
specific pre-processing (including
part lists). Optional
for migration. */
ZOLTAN_PRE_MIGRATE_PP_FORT_FN *Pre_Migrate_PP_Fort;
/* Fortran version */
void *Pre_Migrate_PP_Data; /* Ptr to user defined data to be
passed to Pre_Migrate_PP() */
ZOLTAN_MID_MIGRATE_PP_FN *Mid_Migrate_PP;
/* Function that performs application
specific processing (including
part lists) between packing
and unpacking. Optional
for migration. */
ZOLTAN_MID_MIGRATE_PP_FORT_FN *Mid_Migrate_PP_Fort;
/* Fortran version */
void *Mid_Migrate_PP_Data; /* Ptr to user defined data to be
passed to Mid_Migrate_PP() */
ZOLTAN_POST_MIGRATE_PP_FN *Post_Migrate_PP;
/* Function that performs application
specific post-processing (including
part lists). Optional
for migration. */
ZOLTAN_POST_MIGRATE_PP_FORT_FN *Post_Migrate_PP_Fort;
/* Fortran version */
void *Post_Migrate_PP_Data; /* Ptr to user defined data to be
passed to Post_Migrate_PP() */
ZOLTAN_PRE_MIGRATE_FN *Pre_Migrate; /* Function that performs application
specific pre-processing. Optional
for migration. */
ZOLTAN_PRE_MIGRATE_FORT_FN *Pre_Migrate_Fort;
/* Fortran version */
void *Pre_Migrate_Data; /* Ptr to user defined data to be
passed to Pre_Migrate() */
ZOLTAN_MID_MIGRATE_FN *Mid_Migrate; /* Function that performs application
specific processing between packing
and unpacking. Optional
for migration. */
ZOLTAN_MID_MIGRATE_FORT_FN *Mid_Migrate_Fort;
/* Fortran version */
void *Mid_Migrate_Data; /* Ptr to user defined data to be
passed to Mid_Migrate() */
ZOLTAN_POST_MIGRATE_FN *Post_Migrate;/* Function that performs application
specific post-processing. Optional
for migration. */
ZOLTAN_POST_MIGRATE_FORT_FN *Post_Migrate_Fort;
/* Fortran version */
void *Post_Migrate_Data; /* Ptr to user defined data to be
passed to Post_Migrate() */
};
/*****************************************************************************/
/* PROTOTYPES */
extern int Zoltan_LB_Set_LB_Method(struct Zoltan_Struct *, char *);
extern void Zoltan_LB_Free_Struct(struct Zoltan_LB_Struct *);
extern int Zoltan_LB_Part_To_Proc(struct Zoltan_Struct *, int, ZOLTAN_ID_PTR);
extern int Zoltan_LB_Proc_To_Part(struct Zoltan_Struct *, int, int *, int *);
extern int Zoltan_LB_Get_Part_Sizes(struct Zoltan_Struct *, int, float *);
extern int Zoltan_LB_Build_PartDist(struct Zoltan_Struct *);
extern int Zoltan_LB_Remap(struct Zoltan_Struct *, int *, int, int *, int *,
int *, int);
extern size_t Zoltan_LB_Serialize_Size(struct Zoltan_Struct const *);
extern void Zoltan_LB_Serialize(struct Zoltan_Struct const *, char **);
extern void Zoltan_LB_Deserialize(struct Zoltan_Struct *, char **);
extern int Zoltan_LB_Copy_Struct(struct Zoltan_Struct *to,
struct Zoltan_Struct const *from);
extern int Zoltan_LB_Special_Free_Part(struct Zoltan_Struct *,
ZOLTAN_ID_PTR *, ZOLTAN_ID_PTR *, int **, int **);
/* PARTITIONING FUNCTIONS */
extern ZOLTAN_LB_FN Zoltan_Block;
extern ZOLTAN_LB_FN Zoltan_Cyclic;
extern ZOLTAN_LB_FN Zoltan_Random;
extern ZOLTAN_LB_FN Zoltan_RCB;
extern ZOLTAN_LB_FN Zoltan_Octpart;
extern ZOLTAN_LB_FN Zoltan_Graph;
#ifdef ZOLTAN_PARMETIS
extern ZOLTAN_LB_FN Zoltan_ParMetis;
#endif
#if defined(ZOLTAN_SCOTCH) || defined(ZOLTAN_PTSCOTCH)
extern ZOLTAN_LB_FN Zoltan_Scotch;
#endif
extern ZOLTAN_LB_FN Zoltan_Reftree_Part;
extern ZOLTAN_LB_FN Zoltan_RIB;
extern ZOLTAN_LB_FN Zoltan_HSFC;
extern ZOLTAN_LB_FN Zoltan_PHG;
extern ZOLTAN_LB_FN Zoltan_Hier;
/* FREE DATA_STRUCTURE FUNCTIONS */
extern ZOLTAN_LB_FREE_DATA_FN Zoltan_RCB_Free_Structure;
extern ZOLTAN_LB_FREE_DATA_FN Zoltan_RIB_Free_Structure;
extern ZOLTAN_LB_FREE_DATA_FN Zoltan_Oct_Free_Structure;
extern ZOLTAN_LB_FREE_DATA_FN Zoltan_Reftree_Free_Structure;
extern ZOLTAN_LB_FREE_DATA_FN Zoltan_HSFC_Free_Structure;
extern ZOLTAN_LB_FREE_DATA_FN Zoltan_PHG_Free_Structure;
extern ZOLTAN_LB_FREE_DATA_FN Zoltan_Hier_Free_Structure;
/* COPY DATA_STRUCTURE FUNCTIONS */
extern ZOLTAN_LB_COPY_DATA_FN Zoltan_RCB_Copy_Structure;
extern ZOLTAN_LB_COPY_DATA_FN Zoltan_RIB_Copy_Structure;
extern ZOLTAN_LB_COPY_DATA_FN Zoltan_HSFC_Copy_Structure;
extern ZOLTAN_LB_COPY_DATA_FN Zoltan_Hier_Copy_Structure;
extern ZOLTAN_LB_COPY_DATA_FN Zoltan_PHG_Copy_Structure;
/* SERIALIZE DATA_STRUCTURE FUNCTIONS */
extern ZOLTAN_LB_SERIALIZE_DATA_SIZE_FN Zoltan_RCB_Serialize_Structure_Size;
extern ZOLTAN_LB_SERIALIZE_DATA_FN Zoltan_RCB_Serialize_Structure;
extern ZOLTAN_LB_DESERIALIZE_DATA_FN Zoltan_RCB_Deserialize_Structure;
extern ZOLTAN_LB_SERIALIZE_DATA_SIZE_FN
Zoltan_Serialize_Structure_Size_Not_Implemented;
extern ZOLTAN_LB_SERIALIZE_DATA_FN Zoltan_Serialize_Structure_Not_Implemented;
extern ZOLTAN_LB_DESERIALIZE_DATA_FN Zoltan_Deserialize_Structure_Not_Implemented;
/* POINT_ASSIGN FUNCTIONS */
extern ZOLTAN_LB_POINT_ASSIGN_FN Zoltan_RB_Point_Assign;
extern ZOLTAN_LB_POINT_ASSIGN_FN Zoltan_HSFC_Point_Assign;
/* BOX_ASSIGN FUNCTIONS */
extern ZOLTAN_LB_BOX_ASSIGN_FN Zoltan_RB_Box_Assign;
extern ZOLTAN_LB_BOX_ASSIGN_FN Zoltan_HSFC_Box_Assign;
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

127
thirdParty/Zoltan/src/lb/lb_copy.c vendored Normal file
View File

@ -0,0 +1,127 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
#define COPY_BUFFER(buf, type, num) \
if (from->buf) { \
to->buf = (type *)ZOLTAN_MALLOC((num) * sizeof(type)); \
if (!to->buf) { \
ZOLTAN_PRINT_ERROR(proc, yo, "Insufficient memory."); \
Zoltan_LB_Free_Struct(to); \
return ZOLTAN_MEMERR; \
} \
memcpy(to->buf, from->buf, (num) * sizeof(type)); \
} \
else { \
to->buf = NULL; \
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*
* This file contains routines for copying LB and Migrate structures.
* The target of the copy should be a valid structure.
* These routines should be called only by Zoltan.
*/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
int Zoltan_LB_Copy_Struct(ZZ *toZZ, ZZ const *fromZZ)
{
char *yo = "Zoltan_LB_Copy_Struct";
int proc = fromZZ->Proc;
struct Zoltan_LB_Struct *to = &(toZZ->LB);
struct Zoltan_LB_Struct const *from = &(fromZZ->LB);
Zoltan_LB_Free_Struct(&(toZZ->LB));
if (!from){
return ZOLTAN_OK;
}
*to = *from;
COPY_BUFFER(Part_Info, struct Zoltan_part_info, to->Part_Info_Max_Len);
COPY_BUFFER(Remap, int, to->Num_Global_Parts);
COPY_BUFFER(OldRemap, int, to->Num_Global_Parts);
COPY_BUFFER(PartDist, int, to->Num_Global_Parts + 1);
COPY_BUFFER(ProcDist, int, fromZZ->Num_Proc + 1);
COPY_BUFFER(Imbalance_Tol, float, to->Imb_Tol_Len);
if (from->Data_Structure) {
to->Data_Structure = NULL;
if (!from->Copy_Structure)
{
/*
* Some Zoltan codes don't save their Data_Structure after
* partitioning. However if they do, they must define a
* copy function.
*/
ZOLTAN_PRINT_ERROR(fromZZ->Proc, yo, "A Copy function must be defined");
return ZOLTAN_WARN;
}
from->Copy_Structure(toZZ, fromZZ);
}
return ZOLTAN_OK;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

1844
thirdParty/Zoltan/src/lb/lb_eval.c vendored Normal file

File diff suppressed because it is too large Load Diff

171
thirdParty/Zoltan/src/lb/lb_free.c vendored Normal file
View File

@ -0,0 +1,171 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
#include "all_allo_const.h"
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*
* This file contains routines for freeing arrays allocated by Zoltan and
* returned to the application; these functions are all callable by the
* application.
*
* Also includes routine for freeing memory in zz->LB (LB_Struct).
* This routine should be called only by Zoltan.
*/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
int Zoltan_LB_Free_Part(
ZOLTAN_ID_PTR *global_ids, /* Array of global IDs */
ZOLTAN_ID_PTR *local_ids, /* Array of local IDs */
int **procs, /* Array of processor IDs */
int **to_part /* Array of partition assignments */
)
{
/*
* Routine to free the arrays returning the results of the load balancing.
*/
ZOLTAN_FREE(global_ids);
ZOLTAN_FREE(local_ids);
ZOLTAN_FREE(procs);
ZOLTAN_FREE(to_part);
return (ZOLTAN_OK);
}
int Zoltan_LB_Special_Free_Part(
ZZ *zz,
ZOLTAN_ID_PTR *global_ids, /* Array of global IDs */
ZOLTAN_ID_PTR *local_ids, /* Array of local IDs */
int **procs, /* Array of processor IDs */
int **to_part /* Array of partition assignments */
)
{
/*
* Routine to free the arrays returning the results of the load balancing.
* This routine should be used within Zoltan to ensure that F90-allocated
* arrays are freed correctly.
* For example, Zoltan SPECIAL_MALLOCs return arrays, but then needs to
* free them while changing the return list format. Zoltan should call
* Zoltan_LB_Special_Free Part (not Zoltan_LB_Free_Part) to SPECIAL_FREE
* the memory that was SPECIAL_MALLOCed.
*
* External applications do not need to use this routine,
* as the correct malloc/free protocal for their language will be observed.
*/
Zoltan_Special_Free(zz, (void **)global_ids, ZOLTAN_SPECIAL_MALLOC_GID);
Zoltan_Special_Free(zz, (void **)local_ids, ZOLTAN_SPECIAL_MALLOC_LID);
Zoltan_Special_Free(zz, (void **)procs, ZOLTAN_SPECIAL_MALLOC_INT);
Zoltan_Special_Free(zz, (void **)to_part, ZOLTAN_SPECIAL_MALLOC_INT);
return (ZOLTAN_OK);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int Zoltan_LB_Free_Data(
ZOLTAN_ID_PTR *import_global_ids, /* Array of global IDs for non-local objects
assigned to this processor in the new
decomposition. */
ZOLTAN_ID_PTR *import_local_ids, /* Array of local IDs for non-local objects
assigned to the processor in the new
decomposition. */
int **import_procs, /* Array of processor IDs of processors owning
the non-local objects that are assigned to
this processor in 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. */
)
{
/*
* Routine to free the arrays returning the results of the load balancing.
*/
Zoltan_LB_Free_Part(import_global_ids, import_local_ids, import_procs, NULL);
Zoltan_LB_Free_Part(export_global_ids, export_local_ids, export_procs, NULL);
return (ZOLTAN_OK);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void Zoltan_LB_Free_Struct(struct Zoltan_LB_Struct *lb)
{
ZOLTAN_FREE(&(lb->Imbalance_Tol));
lb->Imb_Tol_Len = 0;
ZOLTAN_FREE(&(lb->Remap));
ZOLTAN_FREE(&(lb->PartDist));
ZOLTAN_FREE(&(lb->ProcDist));
if (lb->Part_Info) ZOLTAN_FREE(&(lb->Part_Info));
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

327
thirdParty/Zoltan/src/lb/lb_init.c vendored Normal file
View File

@ -0,0 +1,327 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
#include "lb_init_const.h"
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void Zoltan_Migrate_Init(struct Zoltan_Migrate_Struct *mig)
{
mig->Auto_Migrate = ZOLTAN_AUTO_MIGRATE_DEF;
mig->Only_Proc_Changes = ZOLTAN_MIGRATE_ONLY_PROC_CHANGES_DEF;
mig->Pre_Migrate_PP = NULL;
mig->Mid_Migrate_PP = NULL;
mig->Post_Migrate_PP = NULL;
mig->Pre_Migrate = NULL;
mig->Mid_Migrate = NULL;
mig->Post_Migrate = NULL;
mig->Pre_Migrate_PP_Fort = NULL;
mig->Mid_Migrate_PP_Fort = NULL;
mig->Post_Migrate_PP_Fort = NULL;
mig->Pre_Migrate_Fort = NULL;
mig->Mid_Migrate_Fort = NULL;
mig->Post_Migrate_Fort = NULL;
mig->Pre_Migrate_PP_Data = NULL;
mig->Mid_Migrate_PP_Data = NULL;
mig->Post_Migrate_PP_Data = NULL;
mig->Pre_Migrate_Data = NULL;
mig->Mid_Migrate_Data = NULL;
mig->Post_Migrate_Data = NULL;
}
void Zoltan_LB_Init(struct Zoltan_LB_Struct *lb, int num_proc)
{
int i;
lb->Num_Global_Parts = num_proc;
lb->Num_Global_Parts_Param = -1;
lb->Num_Local_Parts_Param = -1;
lb->Prev_Global_Parts_Param = -2;
lb->Prev_Local_Parts_Param = -2;
lb->Single_Proc_Per_Part = 1;
lb->PartDist = NULL;
lb->ProcDist = NULL;
lb->Part_Info_Max_Len = 0;
lb->Part_Info_Len = 0;
lb->Part_Info = NULL;
lb->Method = RCB;
lb->LB_Fn = Zoltan_RCB;
lb->Remap_Flag = 1;
lb->Remap = NULL;
lb->OldRemap = NULL;
lb->Return_Lists = ZOLTAN_LB_RETURN_LISTS_DEF;
lb->Uniform_Parts = 1;
lb->Data_Structure = NULL;
lb->Free_Structure = Zoltan_RCB_Free_Structure;
lb->Copy_Structure = Zoltan_RCB_Copy_Structure;
lb->Serialize_Structure_Size = Zoltan_RCB_Serialize_Structure_Size;
lb->Serialize_Structure = Zoltan_RCB_Serialize_Structure;
lb->Deserialize_Structure = Zoltan_RCB_Deserialize_Structure;
lb->Point_Assign = Zoltan_RB_Point_Assign;
lb->Box_Assign = Zoltan_RB_Box_Assign;
lb->Imb_Tol_Len = 10;
lb->Imbalance_Tol = (float *)ZOLTAN_MALLOC((lb->Imb_Tol_Len)*sizeof(float));
for (i=0; i<lb->Imb_Tol_Len; i++)
lb->Imbalance_Tol[i] = ZOLTAN_LB_IMBALANCE_TOL_DEF;
strcpy(lb->Approach, ZOLTAN_LB_APPROACH_DEF);
}
/*****************************************************************************/
/*****************************************************************************/
size_t Zoltan_LB_Serialize_Size(struct Zoltan_Struct const *zz)
{
size_t bufSize = 0;
struct Zoltan_LB_Struct *lb = &(zz->LB);
/* Copy 12 integers from zz->LB */
bufSize += 12 * sizeof(int);
/* LB_Method_Name */
bufSize += MAX_PARAM_STRING_LEN;
/* Part_Info array */
bufSize += lb->Part_Info_Len * sizeof(struct Zoltan_part_info);
/* Imbalance_Tol array */
bufSize += lb->Imb_Tol_Len * sizeof(float);
/* lb->Approach */
bufSize += MAX_PARAM_STRING_LEN;
/* Remap array */
bufSize += sizeof(int);
if (lb->Remap != NULL)
bufSize += lb->Num_Global_Parts * sizeof(int);
/* Method specific data */
if (lb->Serialize_Structure_Size != NULL)
bufSize += lb->Serialize_Structure_Size(zz);
return bufSize;
}
/*****************************************************************************/
void Zoltan_LB_Serialize(struct Zoltan_Struct const *zz, char **buf)
{
char *bufptr = *buf;
struct Zoltan_LB_Struct *lb = &(zz->LB);
/* Copy 12 integers; if add more, update Zoltan_LB_Serialize_Size */
int *intptr = (int *) bufptr;
*intptr = lb->Num_Global_Parts; intptr++;
*intptr = lb->Num_Global_Parts_Param; intptr++;
*intptr = lb->Num_Local_Parts_Param; intptr++;
*intptr = lb->Prev_Global_Parts_Param; intptr++;
*intptr = lb->Prev_Local_Parts_Param; intptr++;
*intptr = lb->Single_Proc_Per_Part; intptr++;
*intptr = lb->Part_Info_Max_Len; intptr++;
*intptr = lb->Part_Info_Len; intptr++;
*intptr = lb->Remap_Flag; intptr++;
*intptr = lb->Return_Lists; intptr++;
*intptr = lb->Uniform_Parts; intptr++;
*intptr = lb->Imb_Tol_Len; intptr++;
bufptr = (char *) intptr;
/* Copy LB_Method name */
strcpy(bufptr, lb->Method_Name);
bufptr += MAX_PARAM_STRING_LEN;
/* Copy Part_Info */
if (lb->Part_Info_Len) {
size_t tmpSize = lb->Part_Info_Len * sizeof(struct Zoltan_part_info);
memcpy(bufptr, (char *)(lb->Part_Info), tmpSize);
bufptr += tmpSize;
}
/* Copy Imbalance_Tol */
if (lb->Imb_Tol_Len) {
size_t tmpSize = lb->Imb_Tol_Len * sizeof(float);
memcpy(bufptr, (char *)(lb->Imbalance_Tol), tmpSize);
bufptr += tmpSize;
}
/* Copy lb->Approach */
strcpy(bufptr, lb->Approach);
bufptr += MAX_PARAM_STRING_LEN;
/* Copy Remap array; needed by Point_Assign */
if (lb->Remap != NULL) {
int *intptr = (int *)bufptr;
*intptr = 1; // Sending Remap data
bufptr += sizeof(int);
int nbytes = lb->Num_Global_Parts * sizeof(int);
memcpy(bufptr, lb->Remap, nbytes);
bufptr += nbytes;
}
else {
int *intptr = (int *)bufptr;
*intptr = 0; // Not sending Remap data
bufptr += sizeof(int);
}
/* Serialize the method-specific load balancing data; advance bufptr */
if (lb->Serialize_Structure != NULL)
lb->Serialize_Structure(zz, &bufptr);
*buf = bufptr;
}
/*****************************************************************************/
void Zoltan_LB_Deserialize(struct Zoltan_Struct *zz, char **buf)
{
char *bufptr = *buf;
struct Zoltan_LB_Struct *lb = &(zz->LB);
int orig_Imb_Tol_Len = lb->Imb_Tol_Len;
/* Copy 12 integers into zz->LB */
int *intptr = (int *) bufptr;
lb->Num_Global_Parts = *intptr; intptr++;
lb->Num_Global_Parts_Param = *intptr; intptr++;
lb->Num_Local_Parts_Param = *intptr; intptr++;
lb->Prev_Global_Parts_Param = *intptr; intptr++;
lb->Prev_Local_Parts_Param = *intptr; intptr++;
lb->Single_Proc_Per_Part = *intptr; intptr++;
lb->Part_Info_Max_Len = *intptr; intptr++;
lb->Part_Info_Len = *intptr; intptr++;
lb->Remap_Flag = *intptr; intptr++;
lb->Return_Lists = *intptr; intptr++;
lb->Uniform_Parts = *intptr; intptr++;
lb->Imb_Tol_Len = *intptr; intptr++;
bufptr = (char *) intptr;
/* Reset the functions (Point_Assign, etc.) associated with the LB_Method */
strcpy(lb->Method_Name, bufptr);
bufptr += MAX_PARAM_STRING_LEN;
Zoltan_Set_Param(zz, "LB_METHOD", lb->Method_Name);
/* Copy Part_Info */
if (lb->Part_Info_Len) {
size_t tmpSize = lb->Part_Info_Len * sizeof(struct Zoltan_part_info);
lb->Part_Info = (struct Zoltan_part_info *) ZOLTAN_MALLOC(tmpSize);
memcpy((char *)(lb->Part_Info), bufptr, tmpSize);
bufptr += tmpSize;
}
/* Copy Imbalance_Tol */
if (lb->Imb_Tol_Len) {
size_t tmpSize = lb->Imb_Tol_Len * sizeof(float);
if (lb->Imb_Tol_Len > orig_Imb_Tol_Len) {
if (lb->Imbalance_Tol != NULL) ZOLTAN_FREE(&(lb->Imbalance_Tol));
lb->Imbalance_Tol = (float *) ZOLTAN_MALLOC(tmpSize);
}
memcpy((char *)(lb->Imbalance_Tol), bufptr, tmpSize);
bufptr += tmpSize;
}
/* Copy lb->Approach */
strcpy(lb->Approach, bufptr);
bufptr += MAX_PARAM_STRING_LEN;
/* Copy Remap array; needed by Point_Assign */
int nbytes = lb->Num_Global_Parts * sizeof(int);
intptr = (int *) bufptr;
bufptr += sizeof(int);
if (*intptr) { // Remap data was sent
lb->Remap = (int *) ZOLTAN_MALLOC(nbytes);
memcpy(lb->Remap, bufptr, nbytes);
bufptr += nbytes;
}
else {
lb->Remap = NULL;
}
/* Deserialize the method-specific load balancing data; advance bufptr */
if (lb->Deserialize_Structure != NULL)
lb->Deserialize_Structure(zz, &bufptr);
*buf = bufptr;
}
/****************************************************************************/
/* Functions for serializations that are not yet implemented.
* These are placeholders until someone requests them.
*/
size_t Zoltan_Serialize_Structure_Size_Not_Implemented(ZZ const *zz)
{
return 0;
}
void Zoltan_Serialize_Structure_Not_Implemented(ZZ const *zz, char **buf)
{
char msg[1024];
sprintf(msg, "Zoltan_Serialize_Structure not implemented for method %s; "
"no data will be copied.\n"
"Contact Zoltan developers to request serialization of this "
"method", zz->LB.Method_Name);
ZOLTAN_PRINT_WARN(zz->Proc,
"Zoltan_Serialize_Structure_Not_Implemented", msg);
}
void Zoltan_Deserialize_Structure_Not_Implemented(ZZ *zz, char **buf)
{
char msg[1024];
sprintf(msg, "Zoltan_Deserialize_Structure not implemented for method %s; "
"no data will be copied.\n"
"Contact Zoltan developers to request serialization of this "
"method", zz->LB.Method_Name);
ZOLTAN_PRINT_WARN(zz->Proc,
"Zoltan_Deserialize_Structure_Not_Implemented", msg);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,65 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifndef __LB_INIT_CONST_H
#define __LB_INIT_CONST_H
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
extern void Zoltan_Migrate_Init(struct Zoltan_Migrate_Struct *);
extern void Zoltan_LB_Init(struct Zoltan_LB_Struct *, int);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

397
thirdParty/Zoltan/src/lb/lb_invert.c vendored Normal file
View File

@ -0,0 +1,397 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
#include "all_allo_const.h"
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*
* This file contains routines implementing the list inverting tools
* Zoltan_Invert_Lists and Zoltan_Compute_Destinations.
* These functions are all callable by the application.
*/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
static int check_invert_input(ZZ *, int, int *, int *, int *, int *, int *);
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int Zoltan_Invert_Lists(
ZZ *zz, /* Zoltan structure. */
int num_in, /* Number of objects in the input lists. */
ZOLTAN_ID_PTR in_global_ids, /* Array of input global IDs. */
ZOLTAN_ID_PTR in_local_ids, /* Array of input local IDs. */
int *in_procs, /* Array of processor IDs of processors owning
the input objects. */
int *in_to_part, /* Optional: Array of partition numbers to
which input objects should be assigned. */
int *num_out, /* Returned value: Number of output objs. */
ZOLTAN_ID_PTR *out_global_ids,/* Returned value: Array of global IDs of
output objects. */
ZOLTAN_ID_PTR *out_local_ids, /* Returned value: Array of local IDs of
output objects. */
int **out_procs, /* Returned value: Array of processor IDs
to which output objects are assigned. */
int **out_to_part /* Optional: Returned value: Array of
partition numbers to which output
objects should be assigned. */
)
{
/*
* Routine to compute the inverse map. Can be used in two ways:
* 1. Given, for each processor, a list of objects to be received by the
* processor, compute the list of objects that the processor needs to send
* to other processors to satisfy their needs.
* 2. Given, for each processor, a list of objects to be sent to other
* processors, compute the list of objects that the processor needs to receive
* to satisfy its needs.
*/
char *yo = "Zoltan_Invert_Lists";
char msg[256];
ZOLTAN_COMM_OBJ *comm_plan; /* Object returned communication routines */
int msgtag, msgtag2; /* Message tags for communication routines */
int num_gid_entries = zz->Num_GID;
int num_lid_entries = zz->Num_LID;
int include_parts; /* Flag indicating whether to compute
inverse list for partitions. */
int ierr, ret_ierr = ZOLTAN_OK;
ZOLTAN_TRACE_ENTER(zz, yo);
/*
* Return if this processor is not in the Zoltan structure's
* communicator.
*/
if (ZOLTAN_PROC_NOT_IN_COMMUNICATOR(zz)) {
ZOLTAN_TRACE_EXIT(zz, yo);
return (ZOLTAN_OK);
}
/*
* Check that all procs use the same id types.
*/
ierr = check_invert_input(zz, num_in, in_procs, in_to_part,
&num_gid_entries, &num_lid_entries, &include_parts);
if (ierr != ZOLTAN_OK) {
ZOLTAN_TRACE_EXIT(zz, yo);
return ierr;
}
/* Initialize returned arrays. */
*out_global_ids = NULL;
*out_local_ids = NULL;
*out_procs = NULL;
if (include_parts) *out_to_part = NULL;
/*
* Compute communication map and num_out, the number of objs this
* processor has to out to establish the new decomposition.
*/
msgtag = 32767;
ierr = Zoltan_Comm_Create(&comm_plan, num_in, in_procs, zz->Communicator,
msgtag, num_out);
if (ierr != ZOLTAN_OK) {
sprintf(msg, "Error %s returned from Zoltan_Comm_Create.",
(ierr == ZOLTAN_MEMERR ? "ZOLTAN_MEMERR" : "ZOLTAN_FATAL"));
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
ret_ierr = ierr;
goto End;
}
ZOLTAN_TRACE_DETAIL(zz, yo, "Done comm create");
/*
* Allocate space for the object tags that need to be outed. Communicate
* to get the list of objects to be outed.
*/
if (*num_out > 0) {
if (!Zoltan_Special_Malloc(zz,(void **)out_global_ids,*num_out,
ZOLTAN_SPECIAL_MALLOC_GID)) {
ret_ierr = ZOLTAN_MEMERR;
goto End;
}
if (num_lid_entries) {
if (!Zoltan_Special_Malloc(zz,(void **)out_local_ids,*num_out,
ZOLTAN_SPECIAL_MALLOC_LID)) {
ret_ierr = ZOLTAN_MEMERR;
goto End;
}
}
if (!Zoltan_Special_Malloc(zz,(void **)out_procs,*num_out,
ZOLTAN_SPECIAL_MALLOC_INT)) {
ret_ierr = ZOLTAN_MEMERR;
goto End;
}
if (include_parts) {
if (!Zoltan_Special_Malloc(zz,(void **)out_to_part,*num_out,
ZOLTAN_SPECIAL_MALLOC_INT)) {
ret_ierr = ZOLTAN_MEMERR;
goto End;
}
}
}
/*
* Use the communication plan to send global IDs, local IDs, and processor
* numbers. Do in separate communications to avoid a memory copy and to
* simplify implementation when a data type is added to the comm. package
* (to support heterogeneous computing).
*/
msgtag2 = 32766;
ierr = Zoltan_Comm_Do(comm_plan, msgtag2, (char *) in_global_ids,
(int) (sizeof(ZOLTAN_ID_TYPE)*(num_gid_entries)),
(char *) *out_global_ids);
if (ierr != ZOLTAN_OK) {
sprintf(msg, "Error %s returned from Zoltan_Comm_Do.",
(ierr == ZOLTAN_MEMERR ? "ZOLTAN_MEMERR" : "ZOLTAN_FATAL"));
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
ret_ierr = ierr;
}
if (num_lid_entries) {
msgtag2--;
ierr = Zoltan_Comm_Do(comm_plan, msgtag2, (char *) in_local_ids,
(int) (sizeof(ZOLTAN_ID_TYPE)*num_lid_entries),
(char *) *out_local_ids);
if (ierr != ZOLTAN_OK) {
sprintf(msg, "Error %s returned from Zoltan_Comm_Do.",
(ierr == ZOLTAN_MEMERR ? "ZOLTAN_MEMERR" : "ZOLTAN_FATAL"));
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
ret_ierr = ierr;
}
}
Zoltan_Comm_Info(comm_plan, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, *out_procs, NULL);
if (include_parts) {
msgtag2--;
ierr = Zoltan_Comm_Do(comm_plan, msgtag2, (char *) in_to_part,
(int) sizeof(int), (char *) *out_to_part);
if (ierr != ZOLTAN_OK) {
sprintf(msg, "Error %s returned from Zoltan_Comm_Do.",
(ierr == ZOLTAN_MEMERR ? "ZOLTAN_MEMERR" : "ZOLTAN_FATAL"));
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
ret_ierr = ierr;
}
}
ZOLTAN_TRACE_DETAIL(zz, yo, "Done comm_do");
End:
Zoltan_Comm_Destroy(&comm_plan);
if (ret_ierr == ZOLTAN_MEMERR) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory.");
Zoltan_Special_Free(zz,(void**)out_global_ids,ZOLTAN_SPECIAL_MALLOC_GID);
Zoltan_Special_Free(zz,(void**)out_local_ids,ZOLTAN_SPECIAL_MALLOC_LID);
Zoltan_Special_Free(zz,(void**)out_procs,ZOLTAN_SPECIAL_MALLOC_INT);
if (include_parts)
Zoltan_Special_Free(zz,(void**)out_to_part,ZOLTAN_SPECIAL_MALLOC_INT);
}
ZOLTAN_TRACE_EXIT(zz, yo);
return (ret_ierr);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
static int check_invert_input(
ZZ *zz,
int in_num,
int *in_procs,
int *in_to_part,
int *num_gid_entries,
int *num_lid_entries,
int *include_parts
)
{
/*
* Routine to ensure that all processors have the same values of
* zz->Num_GID and zz->Num_LID, and to compute include_parts flag globally.
* All processors return the same error code.
*/
char *yo = "check_invert_input";
char msg[256];
int loc_tmp[5];
int glob_min[5] = {0,0,0,0,0};
int glob_max[5] = {0,0,0,0,0};
int do_not_include_parts;
int ierr = ZOLTAN_OK;
loc_tmp[0] = zz->Num_GID;
loc_tmp[1] = zz->Num_LID;
/*
* Check both max and min values of IDs so that all processors can
* return the same error code.
*/
MPI_Allreduce(loc_tmp, glob_min, 2,
MPI_INT, MPI_MIN, zz->Communicator);
/*
* For MPI_MAX operation:
* include_parts == if any proc has in_num > 0 and specifies in_to_part.
* do_not_include_parts == if any proc has in_num > 0 and does not specify
* in_to_part.
* Error: if include_parts && do_not_include_parts
* Error: if any processor has in_num > 0 && in_procs == NULL.
*/
loc_tmp[2] = (in_num > 0 && in_procs == NULL);
loc_tmp[3] = (in_num > 0 && in_to_part != NULL);
loc_tmp[4] = (in_num > 0 && in_to_part == NULL);
MPI_Allreduce(loc_tmp, glob_max, 5,
MPI_INT, MPI_MAX, zz->Communicator);
if (glob_min[0] == glob_max[0])
*num_gid_entries = glob_max[0];
else {
ierr = ZOLTAN_FATAL;
if (zz->Num_GID != glob_max[0]){
sprintf(msg, "Inconsistent global id sizes: Num_GID = %d "
"but global max is %d\n", zz->Num_GID, glob_max[0]);
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
}
}
if (glob_min[1] == glob_max[1])
*num_lid_entries = glob_max[1];
else {
ierr = ZOLTAN_FATAL;
if (zz->Num_LID != glob_max[1]){
sprintf(msg, "Inconsistent local id sizes: Num_LID = %d "
"but global max is %d\n", zz->Num_LID, glob_max[1]);
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
}
}
if (glob_max[2]) {
ierr = ZOLTAN_FATAL;
if (loc_tmp[2] == glob_max[2]) {
sprintf(msg,
"Inconsistent input: # objects = %d but proc array is NULL\n",
in_num);
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
}
}
*include_parts = glob_max[3];
do_not_include_parts = glob_max[4];
if (*include_parts && do_not_include_parts) {
ierr = ZOLTAN_FATAL;
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Inconsistent input; some processors "
"include partition arrays while others do not.");
}
return ierr;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int Zoltan_Compute_Destinations(
ZZ *zz,
int num_in,
ZOLTAN_ID_PTR in_global_ids,
ZOLTAN_ID_PTR in_local_ids,
int *in_procs,
int *num_out,
ZOLTAN_ID_PTR *out_global_ids,
ZOLTAN_ID_PTR *out_local_ids,
int **out_procs
)
{
/*
* Wrapper around Zoltan_Invert_Lists, with NULL for excluded partition arrays.
* Maintained for backward compatibility.
* Arguments are analogous to Zoltan_Invert_Lists.
*/
char *yo = "Zoltan_Compute_Destinations";
int ierr;
ZOLTAN_TRACE_ENTER(zz, yo);
ierr = Zoltan_Invert_Lists(zz, num_in,
in_global_ids, in_local_ids, in_procs, NULL,
num_out,
out_global_ids, out_local_ids, out_procs, NULL);
ZOLTAN_TRACE_EXIT(zz, yo);
return ierr;
}
/*****************************************************************************/
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

929
thirdParty/Zoltan/src/lb/lb_migrate.c vendored Normal file
View File

@ -0,0 +1,929 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*
* This file contains routines implementing the migration-help tools.
* These functions are all callable by the application.
*/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
static int check_input(ZZ *, int, int *);
static int actual_arrays(ZZ *, int, int, int, ZOLTAN_ID_PTR, ZOLTAN_ID_PTR,
int *, int *, int *, ZOLTAN_ID_PTR *, ZOLTAN_ID_PTR *, int **, int **, int *);
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
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 */
size_t 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);
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
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;
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
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;
}
/****************************************************************************/
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;
}
/****************************************************************************/
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

250
thirdParty/Zoltan/src/lb/lb_part2proc.c vendored Normal file
View File

@ -0,0 +1,250 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
#include "zz_util_const.h"
/* Routines to handle mapping of parts to processors. */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
static int Zoltan_LB_Build_ProcDist(ZZ *);
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int Zoltan_LB_Part_To_Proc(ZZ *zz, int part, ZOLTAN_ID_PTR gid)
{
/* Routine that maps parts to processors.
* If a part is entirely within a processor, that processor's rank is
* returned.
* If a part is spread across several processors, find the range of its
* processors.
* If a gid is not given (gid == NULL) return the lowest-numbered processor
* in the range. (RCB and RIB depend upon this feature.)
* If a gid is given and zz->Proc is in the range, return zz->Proc.
* If a gid is given and zz->Proc is not in the range,
* hash the input gid to a processor within the range of processors.
* NOTE: The special case of returning zz->Proc when it is within range
* reduces data movement, but can result in different processor assignments
* for the same gid on different processors.
* If all processors must map a gid to the same processor, this special
* case must be removed.
*
*/
char *yo = "Zoltan_LB_Part_To_Proc";
int proc;
int *pdist = zz->LB.PartDist; /* Temporary variable */
int num_procs_for_part;
int hash_value;
char msg[256];
ZOLTAN_TRACE_ENTER(zz, yo);
if (zz->LB.PartDist == NULL) {
/* number of parts == number of procs, uniformly distributed.
* return input part. */
proc = part;
}
else if (part >= 0 && part < zz->LB.Num_Global_Parts) {
/* number of parts != number of procs or
* non-uniform distribution of parts */
num_procs_for_part = pdist[part+1] - pdist[part];
if (zz->LB.Single_Proc_Per_Part || num_procs_for_part <= 1)
proc = pdist[part];
else if (gid != NULL && zz->Proc >= pdist[part] && zz->Proc < pdist[part+1])
/* zz->Proc is in range of procs holding part; return zz->Proc
* to prevent data movement for exported items. */
proc = zz->Proc;
else {
/* Map the gid to a processor within range for the part.
* Use Zoltan_Hash to attempt to evenly distribute the gids to
* processors holding the part. */
if (gid != NULL)
hash_value = Zoltan_Hash(gid, zz->Num_GID, num_procs_for_part);
else {
hash_value = 0;
}
proc = pdist[part] + hash_value;
}
}
else {
sprintf(msg, "Invalid part number: %d", part);
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
proc = -1;
}
ZOLTAN_TRACE_EXIT(zz, yo);
return proc;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int Zoltan_LB_Proc_To_Part(
ZZ *zz,
int proc, /* Input: processor number */
int *nparts, /* Output: Number of parts on processor proc (>= 0) */
int *fpart /* Output: Part number of first part on proc. */
)
{
/* Routine that returns the number of parts and the part number
* of the lowest-numbered part on a given processor.
* If there are no parts on a processor, nparts = 0 and fpart = -1.
*/
char *yo = "Zoltan_LB_Proc_To_Part";
int *partdist = zz->LB.PartDist;
int *procdist;
int ierr = ZOLTAN_OK;
int tmp;
if (proc < 0 || proc >= zz->Num_Proc) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Input proc is out of range.");
ierr = ZOLTAN_FATAL;
*nparts = 0;
*fpart = -1;
goto End;
}
if (partdist == NULL) {
*nparts = 1;
*fpart = proc;
}
else {
if (zz->LB.ProcDist == NULL) {
ierr = Zoltan_LB_Build_ProcDist(zz);
if (ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN) {
*nparts = 0;
*fpart = -1;
goto End;
}
}
procdist = zz->LB.ProcDist;
if (procdist[proc] == -1) {
*nparts = 0;
*fpart = -1;
}
else {
tmp = proc+1;
while (procdist[tmp] == -1) tmp++;
*nparts = procdist[tmp] - procdist[proc];
*nparts = ((*nparts < 1) ? 1 : *nparts);
*fpart = procdist[proc];
}
}
End:
return ierr;
}
/*****************************************************************************/
static int Zoltan_LB_Build_ProcDist(
ZZ *zz
)
{
/* Routine that computes the inverse of array LB.PartDist.
* Builds array LB.ProcDist that maps processors to parts.
* Entry i of LB.ProcDist is the lowest part number on processor i.
* If processor i has no parts, ProcDist[i] = -1.
*/
char *yo = "Zoltan_LB_Build_ProcDist";
int ierr = ZOLTAN_OK;
int *partdist = zz->LB.PartDist;
int *procdist;
int i, j;
if (partdist != NULL) {
procdist = zz->LB.ProcDist
= (int *) ZOLTAN_MALLOC((zz->Num_Proc+1) * sizeof(int));
if (procdist == NULL) {
ierr = ZOLTAN_MEMERR;
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
goto End;
}
for (j = 0, i = 0; i < zz->Num_Proc; i++) {
if (partdist[j] == i) {
/* Part j is on processor i */
procdist[i] = j;
while (partdist[j] == i) j++;
}
else if (!zz->LB.Single_Proc_Per_Part)
/* processor i has continuation of previous processor's part */
procdist[i] = procdist[i-1];
else
/* processor i has no parts */
procdist[i] = -1;
}
procdist[zz->Num_Proc] = zz->LB.Num_Global_Parts;
}
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL) {
printf("%d LB.ProcDist: ", zz->Proc);
for (i = 0; i <= zz->Num_Proc; i++)
printf("%d ", zz->LB.ProcDist[i]);
printf("\n");
}
End:
return ierr;
}
/*****************************************************************************/
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,106 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
/****************************************************************************/
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);
}
/****************************************************************************/
int Zoltan_LB_Point_PP_Assign (
ZZ *zz,
double *x,
int *proc,
int *part)
{
/* Returns processor and partition to which a point should be assigned. */
char *yo = "Zoltan_LB_Point_PP_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 ;
}
return zz->LB.Point_Assign(zz, x, proc, part); /* call appropriate method */
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

869
thirdParty/Zoltan/src/lb/lb_remap.c vendored Normal file
View File

@ -0,0 +1,869 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
#include "phg_hypergraph.h"
#include <limits.h>
/*
* Values indicating how part remapping should be done.
*/
#define ZOLTAN_LB_REMAP_NONE 0
#define ZOLTAN_LB_REMAP_PROCESSORS 1
#define ZOLTAN_LB_REMAP_PARTS 2
#define HEINFO_ENTRIES 3
static int gather_and_build_remap(ZZ *, int *, int, int *);
static int set_remap_type(ZZ *, int *);
static int malloc_HEinfo(ZZ *, int, int **);
static int do_match(ZZ*, HGraph *, int *, int);
static int matching_pgm(ZZ *, HGraph *, int *, int *);
static int local_HEs_from_import_lists(ZZ *, int, int, int *, int *, int *,
int *, int **);
static int local_HEs_from_export_lists(ZZ *, int, int, int *, int *, int *,
int *, int **);
static float measure_stays(ZZ *, HGraph *, int, int *, char *);
/******************************************************************************/
int Zoltan_LB_Remap(
ZZ *zz,
int *new_map, /* Upon return, flag indicating whether part or proc
assignments actually changed due to remapping. */
int nobj, /* # objs the processor knows about after partitioning */
int *proc, /* processors for the objs;
if export_list_flag == 1,
proc contains new proc assignment
else
proc contains old proc assignment
Upon return, proc contains remapped new proc
assignment regardless of export_list_flag's value. */
int *old_part, /* old part assignments for the objs */
int *new_part, /* new part assignments for the objs.
Upon return, new_part contains remapped new
part assignments */
int export_list_flag /* Flag indicating whether the algorithm computes
export lists or import lists. The HG for matching
is built differently depending on whether
the algorithm knows export or import info. */
)
{
char *yo = "Zoltan_LB_Remap";
int ierr = ZOLTAN_OK;
int i;
int remap_type; /* Type of remapping to be done:
Procs, Parts, or None */
int HEcnt = 0; /* Number of local hyperedges */
int *HEinfo = NULL; /* Array of HE info; for each HE, two pins and
one edge weight. Stored as a single vector
to minimize communication calls. */
*new_map = 0;
/* Determine type of remapping that is appropriate */
ierr = set_remap_type(zz, &remap_type);
if (remap_type != ZOLTAN_LB_REMAP_NONE) {
/* Build local hyperedges */
if (export_list_flag)
ierr = local_HEs_from_export_lists(zz, remap_type,
nobj, proc, old_part, new_part,
&HEcnt, &HEinfo);
else
ierr = local_HEs_from_import_lists(zz, remap_type,
nobj, proc, old_part, new_part,
&HEcnt, &HEinfo);
if (ierr < 0) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error building local HEs");
goto End;
}
/* Gather local hyperedges to each processor; build remap vector */
ierr = gather_and_build_remap(zz, new_map, HEcnt, HEinfo);
if (ierr < 0) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo,
"Error returned from gather_and_build_remap.");
goto End;
}
if (*new_map) {
/* Update part and processor information for algorithms */
for (i = 0; i < nobj; i++) {
new_part[i] = zz->LB.Remap[new_part[i]];
proc[i] = Zoltan_LB_Part_To_Proc(zz, new_part[i], NULL);
}
}
}
End:
ZOLTAN_FREE(&HEinfo);
return(ierr);
}
/******************************************************************************/
static int local_HEs_from_import_lists(
ZZ *zz,
int remap_type, /* type of remapping to do: parts, procs, or none. */
int nobj, /* # objs the processor knows about (keep + imports) */
int *proc, /* On input, old processor assignment for each obj;
Upon return, remapped new proc assignment for
each obj. */
int *old_part, /* old part assignments for each objs */
int *new_part, /* On input, new part assignments for each objs.
Upon return, remapped new part assignments */
int *HEcnt, /* # of HEs allocated. */
int **HEinfo /* Array of HE info; for each HE, two pins and
one edge weight. Stored as a single vector
to minimize communication calls. */
)
{
/* Routine to remap parts (to new processors or new part numbers)
* to reduce data movement.
* This routine assumes the load-balancing algorithm built import lists.
* Objects described are those that ENDED UP on my_proc due to load balancing.
* For all these objects, new_proc == my_proc.
*/
char *yo = "local_HEs_from_import_lists";
int ierr = ZOLTAN_OK;
int i, cnt, tmp;
int *tmp_HEinfo;
int old_size; /* # of old entries to remap to. If remapping
parts to processors, old_size = Num_Procs;
if renumbering parts, old_size = old
num parts. */
int fp; /* First part on this processor in new
decomposition. */
int np; /* # of parts on this processor in new
decomposition. */
int my_proc = zz->Proc; /* This processor's rank. */
int minp, maxp; /* Lowest and highest part numbers on this
processor in old decomposition;
part numbers are assumed to be dense,
but no particular distribution is assumed. */
int HEwgt_size; /* # of HE weights allocated. */
int *HEwgt = NULL; /* Array of HE weights. Initially includes
zero weights; later zero-weights are removed.*/
if (remap_type == ZOLTAN_LB_REMAP_PROCESSORS) {
/* Renumber new processors to minimize changes in proc assignment. */
HEwgt_size = zz->Num_Proc;
HEwgt = (int *) ZOLTAN_CALLOC(HEwgt_size, sizeof(int));
if (!HEwgt) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
ierr = ZOLTAN_MEMERR;
goto End;
}
for (i = 0; i < nobj; i++)
HEwgt[proc[i]]++; /* At this point, proc has old proc assignments */
*HEcnt = 0;
for (i = 0; i < HEwgt_size; i++)
if (HEwgt[i] != 0) (*HEcnt)++;
ierr = malloc_HEinfo(zz, *HEcnt, HEinfo);
if (ierr < 0)
goto End;
tmp_HEinfo = *HEinfo;
cnt = 0;
for (i = 0; i < HEwgt_size; i++) {
if (HEwgt[i] != 0) {
tmp = cnt * HEINFO_ENTRIES;
tmp_HEinfo[tmp] = i; /* Old processor number */
tmp_HEinfo[tmp+1] = my_proc; /* New processor number */
tmp_HEinfo[tmp+2] = HEwgt[i]; /* shift non-zero weights down. */
cnt++;
}
}
}
else { /* ZOLTAN_LB_REMAP_PARTS */
/* Renumber new parts to minimize changes in part assignment */
for (minp = INT_MAX, maxp = 0, i = 0; i < nobj; i++) {
if (old_part[i] < minp) minp = old_part[i];
if (old_part[i] > maxp) maxp = old_part[i];
}
/* Don't include old part numbers that are greater than
* zz->LB.Num_Global_Parts - 1; they are not valid values for
* remapping of new part numbers.
*/
if (minp >= zz->LB.Num_Global_Parts)
minp = zz->LB.Num_Global_Parts-1;
if (maxp >= zz->LB.Num_Global_Parts)
maxp = zz->LB.Num_Global_Parts-1;
old_size = maxp - minp + 1;
Zoltan_LB_Proc_To_Part(zz, my_proc, &np, &fp);
HEwgt_size = np * old_size;
if (HEwgt_size > 0) {
HEwgt = (int *) ZOLTAN_CALLOC(HEwgt_size, sizeof(int));
if (!HEwgt) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
ierr = ZOLTAN_MEMERR;
goto End;
}
}
for (i = 0; i < nobj; i++) {
if (old_part[i] < zz->LB.Num_Global_Parts) {
/* Include only HEs to old parts numbered
* 0 to zz->LB.Num_Global_Parts-1; these are the only valid
* remapping values for the new part numbers.
*/
tmp = (new_part[i]-fp) * old_size;
HEwgt[tmp + (old_part[i]-minp)]++;
}
}
*HEcnt = 0;
for (i = 0; i < HEwgt_size; i++)
if (HEwgt[i] != 0) (*HEcnt)++;
ierr = malloc_HEinfo(zz, *HEcnt, HEinfo);
if (ierr < 0)
goto End;
tmp_HEinfo = *HEinfo;
cnt = 0;
for (i = 0; i < HEwgt_size; i++) {
if (HEwgt[i] != 0) {
tmp = cnt * HEINFO_ENTRIES;
tmp_HEinfo[tmp] = i%old_size + minp; /* Old part number */
tmp_HEinfo[tmp+1] = i/old_size + fp; /* New part number */
tmp_HEinfo[tmp+2] = HEwgt[i]; /* shift non-zero weights down. */
cnt++;
}
}
}
End:
if (HEwgt) ZOLTAN_FREE(&HEwgt);
return ierr;
}
/******************************************************************************/
static int local_HEs_from_export_lists(
ZZ *zz,
int remap_type, /* type of remapping to do: parts, procs, or none. */
int nobj, /* # objs the processor knows about (keep + exports) */
int *new_proc, /* On input, new processor assignment for each obj;
Upon return, remapped new proc assignment for
each obj. */
int *old_part, /* old part assignments for each objs */
int *new_part, /* On input, new part assignments for each objs.
Upon return, remapped new part assignments */
int *HEcnt, /* # of HEs allocated. */
int **HEinfo /* Array of HE info; for each HE, two pins and
one edge weight. Stored as a single vector
to minimize communication calls. */
)
{
/* Routine to remap parts (to new processors or new part numbers)
* to reduce data movement.
* This routine assumes the load-balancing algorithm built export lists.
* Objects described are those that STARTED on zz->Proc due to load balancing.
* For all these objects, old_proc == zz->Proc.
*/
char *yo = "local_HEs_from_export_lists";
int ierr = ZOLTAN_OK;
int i, cnt, tmp;
int *tmp_HEinfo;
int my_proc = zz->Proc; /* This processor's rank. */
int nimp = 0;
int *imp_proc = NULL, /* Temporary arrays if inversion of export to */
*imp_old_part = NULL, /* import lists is needed. */
*imp_new_part = NULL;
int HEwgt_size; /* # of HE weights allocated. */
int *HEwgt = NULL; /* Array of HE weights. Initially includes
zero weights; later zero-weights are removed.*/
if (remap_type == ZOLTAN_LB_REMAP_PROCESSORS) {
/* Build HEs based on processor assignment.
* We know the old processor for all objects we are keeping and all
* export objects -- it is my_proc!
* We also know the new processor number for all objects initially on
* my_proc (since we built export lists.)
* This case is a special case of part remapping; it is easy to
* build the hyperedges in this special case.
*/
HEwgt_size = zz->Num_Proc;
HEwgt = (int *) ZOLTAN_CALLOC(HEwgt_size, sizeof(int));
if (!HEwgt) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
ierr = ZOLTAN_MEMERR;
goto End;
}
for (i = 0; i < nobj; i++)
HEwgt[new_proc[i]]++;
*HEcnt = 0;
for (i = 0; i < HEwgt_size; i++)
if (HEwgt[i] != 0) (*HEcnt)++;
ierr = malloc_HEinfo(zz, *HEcnt, HEinfo);
if (ierr < 0)
goto End;
tmp_HEinfo = *HEinfo;
cnt = 0;
for (i = 0; i < HEwgt_size; i++) {
if (HEwgt[i] != 0) {
tmp = cnt * HEINFO_ENTRIES;
tmp_HEinfo[tmp] = my_proc; /* Old processor number */
tmp_HEinfo[tmp+1] = i; /* New processor number */
tmp_HEinfo[tmp+2] = HEwgt[i]; /* shift non-zero weights down. */
cnt++;
}
}
}
else { /* ZOLTAN_LB_REMAP_PARTS */
/* Cannot renumber parts given export lists without summing HE weights
* across processors. This summation is not straightforward. Also, a
* potentially large number of HEs may exist
* (max_old_part_number * zz->Num_Global_Parts). Rather than build
* this large matrix, just compute import lists from the export lists
* and run the import-list algorithm.
*/
ZOLTAN_COMM_OBJ *plan;
int msg_tag = 22345;
ierr = Zoltan_Comm_Create(&plan, nobj, new_proc, zz->Communicator,
msg_tag, &nimp);
if (nimp > 0) {
imp_proc = (int *) ZOLTAN_MALLOC(3 * nimp * sizeof(int));
imp_old_part = imp_proc + nimp;
imp_new_part = imp_old_part + nimp;
if (!imp_proc) {
ierr = ZOLTAN_MEMERR;
ZOLTAN_PRINT_ERROR(my_proc, yo, "Memory error.");
goto End;
}
}
ierr = Zoltan_Comm_Info(plan, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, imp_proc, NULL);
msg_tag++;
ierr = Zoltan_Comm_Do(plan, msg_tag, (char *) old_part, sizeof(int),
(char *) imp_old_part);
msg_tag++;
ierr = Zoltan_Comm_Do(plan, msg_tag, (char *) new_part, sizeof(int),
(char *) imp_new_part);
Zoltan_Comm_Destroy(&plan);
ierr = local_HEs_from_import_lists(zz, remap_type, nimp, imp_proc,
imp_old_part, imp_new_part,
HEcnt, HEinfo);
}
End:
if (HEwgt) ZOLTAN_FREE(&HEwgt);
if (imp_proc) ZOLTAN_FREE(&imp_proc);
return ierr;
}
/******************************************************************************/
static int set_remap_type(
ZZ *zz,
int *remap_type
)
{
int ierr = ZOLTAN_OK;
/* Set remap type based on distribution of parts to processors. */
if (zz->LB.Remap_Flag == 0) {
/* No remapping requested */
*remap_type = ZOLTAN_LB_REMAP_NONE;
}
else if (!(zz->LB.Uniform_Parts)) {
/* Remapping does not respect requested non-uniform part sizes;
no remapping done. */
*remap_type = ZOLTAN_LB_REMAP_NONE;
ierr = ZOLTAN_WARN;
}
else if (!(zz->LB.Single_Proc_Per_Part)) {
/* Some parts spread across >1 processor; remapping not supported. */
*remap_type = ZOLTAN_LB_REMAP_NONE;
ierr = ZOLTAN_WARN;
}
else if (zz->LB.PartDist == NULL) {
/* # Parts == # Processors, uniformly distributed; remap processors */
*remap_type = ZOLTAN_LB_REMAP_PROCESSORS;
}
else {
/* # Parts != # processors, or parts not uniformly distributed */
*remap_type = ZOLTAN_LB_REMAP_PARTS;
}
return ierr;
}
/******************************************************************************/
static int do_match(
ZZ *zz,
HGraph *hg, /* Hypergraph data structure on which to do the matching. */
int *match, /* Matching array -- output */
int limit /* max number of matches that are allowed */
)
{
/* Temporary function; will be replace by a real matching function later. */
int ierr = ZOLTAN_OK;
int i;
/* Default initialization -- no change in mapping */
for (i = 0; i < hg->nVtx; i++)
match[i] = i;
ierr = matching_pgm(zz, hg, match, &limit);
return ierr;
}
/******************************************************************************/
static int malloc_HEinfo(
ZZ *zz,
int HEcnt, /* Number of HEs to allocate */
int **HEinfo /* Array of HE info; for each HE, two pins and
one edge weight. Stored as a single vector
to minimize communication calls. */
)
{
/* Routine for allocating HEs to use in remap's matching routine. */
char *yo = "malloc_HEinfo";
int ierr = ZOLTAN_OK;
if (HEcnt) {
*HEinfo = (int *) ZOLTAN_MALLOC(HEINFO_ENTRIES * HEcnt * sizeof(int));
if (*HEinfo == NULL) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
ierr = ZOLTAN_MEMERR;
}
}
else
*HEinfo = NULL;
return ierr;
}
/******************************************************************************/
static int gather_and_build_remap(
ZZ *zz,
int *new_map, /* Upon return, flag indicating whether parts
assignments were changed due to remap. */
int HEcnt, /* # of HEs allocated. */
int *HEinfo /* Array of HE info; for each HE, two pins and
one edge weight. Stored as a single vector
to minimize communication calls. */
)
{
char *yo = "gather_and_remap";
int ierr = ZOLTAN_OK;
int i, uidx, tmp;
int *each_size = NULL; /* sizes (# HEs * HEINFO_ENTRIES) for each proc */
int *recvbuf = NULL; /* Receive buffer for gatherv */
int *displs = NULL; /* Displacement buffer for gatherv */
int send_size; /* Local # HEs * HEINFO_ENTRIES */
int total_size; /* Total # ints in gatherv */
int total_HEcnt; /* Total (across all procs) number of HEs. */
int max0, max1; /* Max values of pin 0 and pin 1 for each HE. */
int *match = NULL; /* Vector describing the matching.
match[i] = j ==> match[j] = i ==>
vertices i and j are matched. */
int *used = NULL; /* Vector indicating which parts are used
in the matching. */
int limit; /* Maximum number of matches that are allowed */
HGraph hg; /* Hypergraph for matching */
float before_remap = 0, /* Amount of data that overlaps between old and */
after_remap = 0; /* new decomposition before and after remapping,
respectively. */
float with_oldremap = 0; /* Amount of data that overlaps between old and
new decomposition using the OldRemap vector
(remapping from the previous decomposition). */
/* Gather HEs from each processor into a local complete HG. */
each_size = (int *) ZOLTAN_MALLOC(zz->Num_Proc * sizeof(int));
if (!each_size) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
ierr = ZOLTAN_MEMERR;
goto End;
}
send_size = HEcnt * HEINFO_ENTRIES;
MPI_Allgather(&send_size, 1, MPI_INT, each_size, 1, MPI_INT,
zz->Communicator);
for (total_size = 0, i = 0; i < zz->Num_Proc; i++) {
total_size += each_size[i];
}
recvbuf = (int *) ZOLTAN_MALLOC((zz->Num_Proc + total_size) * sizeof(int));
displs = recvbuf + total_size;
if (!recvbuf) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
ierr = ZOLTAN_MEMERR;
goto End;
}
displs[0] = 0;
for (i = 1; i < zz->Num_Proc; i++)
displs[i] = displs[i-1] + each_size[i-1];
MPI_Allgatherv(HEinfo, send_size, MPI_INT,
recvbuf, each_size, displs, MPI_INT, zz->Communicator);
total_HEcnt = total_size / HEINFO_ENTRIES;
for (max0 = -1, max1 = -1, i = 0; i < total_HEcnt; i++) {
tmp = i * HEINFO_ENTRIES;
if (recvbuf[tmp] > max0) max0 = recvbuf[tmp];
if (recvbuf[tmp+1] > max1) max1 = recvbuf[tmp+1];
}
/* Increment max0 and max1 so that they are the maximum number of unique
pin values for pin0 and pin1 respectively; i.e., allow pin value == 0. */
max0++;
max1++;
/* Sanity check */
/* Ideally, max1 should equal LB.Num_Global_Parts, but ParMETIS3 sometimes
* does not return the correct number of non-empty parts, allowing
* max1 to be less than LB.Num_Global_Parts.
* (e.g., ewgt.adaptive-partlocal1-v3.4.?).
*/
if (max1 > zz->LB.Num_Global_Parts)
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Unexpected value for max1.");
/* Set up global HG */
Zoltan_HG_HGraph_Init(&hg);
if (total_HEcnt) {
hg.nVtx = max0 + zz->LB.Num_Global_Parts;
hg.nEdge = total_HEcnt;
hg.nPins = total_HEcnt * 2; /* two pins per HE */
hg.EdgeWeightDim = 1;
hg.ewgt = (float *) ZOLTAN_MALLOC(total_HEcnt * sizeof(float));
hg.hindex = (int *) ZOLTAN_MALLOC((total_HEcnt + 1) * sizeof(int));
hg.hvertex = (int *) ZOLTAN_MALLOC((hg.nPins) * sizeof(int));
if (!hg.ewgt || !hg.hindex || !hg.hvertex) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
ierr = ZOLTAN_MEMERR;
goto End;
}
for (i = 0; i < total_HEcnt; i++) {
tmp = i * HEINFO_ENTRIES;
hg.hindex[i] = i+i;
hg.hvertex[i+i] = recvbuf[tmp];
hg.hvertex[i+i+1] = (int)recvbuf[tmp+1]+max0;
hg.ewgt[i] = recvbuf[tmp+2];
}
hg.hindex[total_HEcnt] = total_HEcnt + total_HEcnt;
ierr = Zoltan_HG_Create_Mirror(zz, &hg);
if (ierr < 0) goto End;
}
before_remap = measure_stays(zz, &hg, max0, NULL, "BEFORE");
/* Compute the amount of overlap when using the old remap vector. */
with_oldremap = measure_stays(zz, &hg, max0, zz->LB.OldRemap, "WITHOLD");
/* Do matching */
match = (int *) ZOLTAN_CALLOC(hg.nVtx + zz->LB.Num_Global_Parts, sizeof(int));
used = match + hg.nVtx;
if (hg.nVtx && !match) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
ierr = ZOLTAN_MEMERR;
goto End;
}
/* Max # matches allowed */
limit = (max0 < zz->LB.Num_Global_Parts ? max0 : zz->LB.Num_Global_Parts);
do_match(zz, &hg, match, limit);
/* Build remapping vector, if non-trivial matching was returned. */
*new_map = 0;
for (i = 0; i < zz->LB.Num_Global_Parts; i++)
if (match[i+max0] != i+max0) {
*new_map = 1;
break;
}
if (*new_map) {
zz->LB.Remap = (int *) ZOLTAN_MALLOC(zz->LB.Num_Global_Parts * sizeof(int));
if (!(zz->LB.Remap)) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
ierr = ZOLTAN_MEMERR;
goto End;
}
/* First, process all parts that were matched. Mark matched parts as used.*/
for (i = 0; i < zz->LB.Num_Global_Parts; i++) {
zz->LB.Remap[i] = -1;
tmp = match[i+max0];
if (tmp != i+max0) {
zz->LB.Remap[i] = tmp;
used[tmp] = 1;
}
}
/* Second, process unmatched parts; if possible, keep same part number. */
for (i = 0; i < zz->LB.Num_Global_Parts; i++) {
if (zz->LB.Remap[i] > -1) continue; /* Already processed part i */
/* match[i+max0] == i+max0 */
if (!used[i]) { /* Keep the same part number if it is not used */
zz->LB.Remap[i] = i;
used[i] = 1;
}
}
/* Third, process remaining unmatched parts; assign them to
unused parts.*/
for (uidx = 0, i = 0; i < zz->LB.Num_Global_Parts; i++) {
if (zz->LB.Remap[i] > -1) continue; /* Already processed part i */
/* match[i+max0] == i+max0 */
while (used[uidx]) uidx++; /* Find next unused part */
zz->LB.Remap[i] = uidx;
used[uidx] = 1;
}
}
if (*new_map)
after_remap = measure_stays(zz, &hg, max0, zz->LB.Remap, "AFTER ");
if ((before_remap >= after_remap) && (before_remap >= with_oldremap)) {
/* No benefit from remapping; don't keep it! */
ZOLTAN_FREE(&zz->LB.Remap);
ZOLTAN_FREE(&zz->LB.OldRemap);
*new_map = 0;
}
else if (with_oldremap >= after_remap) {
/* The old remap vector is better than the new one; keep the old one. */
ZOLTAN_FREE(&zz->LB.Remap);
zz->LB.Remap = zz->LB.OldRemap;
zz->LB.OldRemap = NULL;
*new_map = 1;
}
else {
/* Going to use the new remap vector; free the old one. */
ZOLTAN_FREE(&zz->LB.OldRemap);
}
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL && zz->Proc == zz->Debug_Proc &&
zz->LB.Remap)
for (i = 0; i < zz->LB.Num_Global_Parts; i++)
printf("%d REMAP Part %d to Part %d\n", zz->Proc, i, zz->LB.Remap[i]);
End:
ZOLTAN_FREE(&match);
ZOLTAN_FREE(&each_size);
ZOLTAN_FREE(&recvbuf);
Zoltan_HG_HGraph_Free(&hg);
return ierr;
}
/******************************************************************************/
static float measure_stays(
ZZ *zz,
HGraph *hg,
int max0,
int *remapvec,
char *when
)
{
/* Routine that measures and prints the amount of data that doesn't move
* as described by the hypergraph.
*/
float stay = 0.;
int tmp, i;
for (i = 0; i < hg->nEdge; i++) {
tmp = i + i;
if (remapvec) {
if (hg->hvertex[tmp] == (int)remapvec[hg->hvertex[tmp+1]-max0])
stay += hg->ewgt[i];
}
else {
if (hg->hvertex[tmp] == (hg->hvertex[tmp+1]-max0))
stay += hg->ewgt[i];
}
}
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL && zz->Proc == zz->Debug_Proc)
printf("%d REMAP--%s: TOTAL AMT STAY = %g\n\n",
zz->Proc, when, stay);
return(stay);
}
/******************************************************************************/
/* path growing matching, hypergraph version */
static int matching_pgm (ZZ *zz, HGraph *hg, int *match, int *limit)
{
int i, j, k, side = 0, edge, vertex, *Match[2] = {NULL, NULL};
int limits[2], neighbor, next_vertex, pins;
double w[2]={0.0,0.0}, weight, max_weight, *sims = NULL;
char *yo = "matching_pgm";
limits[0] = limits[1] = *limit;
Match[0] = match;
if (hg->nVtx) {
if (!(Match[1] = (int*) ZOLTAN_MALLOC (hg->nVtx * sizeof(int)))
|| !(sims = (double*) ZOLTAN_CALLOC (hg->nVtx, sizeof(double))) ) {
Zoltan_Multifree (__FILE__, __LINE__, 2, &Match[1], &sims);
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
return ZOLTAN_MEMERR;
}
}
for (i = 0; i < hg->nVtx; i++)
Match[1][i] = i;
for (i = 0; i < hg->nVtx && limits[side] > 0; i++) {
if (Match[0][i] == i && Match[1][i] == i) {
vertex = i;
while (vertex > 0 && limits[side] > 0) {
max_weight = 0.0;
next_vertex = -1;
for (j = hg->vindex[vertex]; j < hg->vindex[vertex+1]; j++) {
edge = hg->vedge[j];
pins = hg->hindex[edge+1] - hg->hindex[edge];
weight = 2.0 / ((pins-1)*pins);
if (hg->ewgt)
weight *= hg->ewgt[edge];
for (k = hg->hindex[edge]; k < hg->hindex[edge+1]; k++) {
neighbor = hg->hvertex[k];
if (neighbor != vertex && Match[0][neighbor] == neighbor &&
Match[1][neighbor]==neighbor)
sims[neighbor] += weight;
}
}
for (j = hg->vindex[vertex]; j < hg->vindex[vertex+1]; j++) {
edge = hg->vedge[j];
for (k = hg->hindex[edge]; k < hg->hindex[edge+1]; k++) {
neighbor = hg->hvertex[k];
if (sims[neighbor] > 0.0) {
if (sims[neighbor] > max_weight) {
max_weight = sims[neighbor];
next_vertex = neighbor;
}
sims[neighbor] = 0.0;
}
}
}
if (next_vertex >= 0) {
Match[side][vertex] = next_vertex;
Match[side][next_vertex] = vertex;
limits[side]--;
w[side] += max_weight;
side = 1-side;
}
vertex = next_vertex;
}
}
}
if (w[0] < w[1]) {
for (i = 0; i < hg->nVtx; i++)
match[i] = Match[1][i];
*limit = limits[1];
}
else
*limit = limits[0];
Zoltan_Multifree (__FILE__, __LINE__, 2, &Match[1], &sims);
return ZOLTAN_OK;
}
/******************************************************************************/
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

138
thirdParty/Zoltan/src/lb/lb_set_fn.c vendored Normal file
View File

@ -0,0 +1,138 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int Zoltan_Set_Pre_Migrate_PP_Fn(
ZZ *zz,
ZOLTAN_PRE_MIGRATE_PP_FN *fn,
void *data
)
{
zz->Migrate.Pre_Migrate_PP = fn;
zz->Migrate.Pre_Migrate_PP_Data = data;
return ZOLTAN_OK;
}
/*****************************************************************************/
int Zoltan_Set_Mid_Migrate_PP_Fn(
ZZ *zz,
ZOLTAN_MID_MIGRATE_PP_FN *fn,
void *data
)
{
zz->Migrate.Mid_Migrate_PP = fn;
zz->Migrate.Mid_Migrate_PP_Data = data;
return ZOLTAN_OK;
}
/*****************************************************************************/
int Zoltan_Set_Post_Migrate_PP_Fn(
ZZ *zz,
ZOLTAN_POST_MIGRATE_PP_FN *fn,
void *data
)
{
zz->Migrate.Post_Migrate_PP = fn;
zz->Migrate.Post_Migrate_PP_Data = data;
return ZOLTAN_OK;
}
/*****************************************************************************/
int Zoltan_Set_Pre_Migrate_Fn(
ZZ *zz,
ZOLTAN_PRE_MIGRATE_FN *fn,
void *data
)
{
zz->Migrate.Pre_Migrate = fn;
zz->Migrate.Pre_Migrate_Data = data;
return ZOLTAN_OK;
}
/*****************************************************************************/
int Zoltan_Set_Mid_Migrate_Fn(
ZZ *zz,
ZOLTAN_MID_MIGRATE_FN *fn,
void *data
)
{
zz->Migrate.Mid_Migrate = fn;
zz->Migrate.Mid_Migrate_Data = data;
return ZOLTAN_OK;
}
/*****************************************************************************/
int Zoltan_Set_Post_Migrate_Fn(
ZZ *zz,
ZOLTAN_POST_MIGRATE_FN *fn,
void *data
)
{
zz->Migrate.Post_Migrate = fn;
zz->Migrate.Post_Migrate_Data = data;
return ZOLTAN_OK;
}
/*****************************************************************************/
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

299
thirdParty/Zoltan/src/lb/lb_set_method.c vendored Normal file
View File

@ -0,0 +1,299 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
#include "zz_util_const.h"
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*
* This file contains routines to set the load-balancing method.
*/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int Zoltan_LB_Set_LB_Method(ZZ *zz, char *method_name)
{
/*
* Function to set the load balancing method to be used.
* Input:
* zz -- The Zoltan structure to which this method
* applies.
* method_name -- String specifying the desired method.
*
* Output:
* zz->LB.* -- Appropriate fields set to designated values.
*/
char *yo = "Zoltan_LB_Set_LB_Method";
char msg[256];
char *method_upper;
int error = ZOLTAN_OK;
/*
* Compare method_name string with standard strings for methods.
* If a match is found, set zz->LB.Method and other pointers.
* But first free any left-over data from the previous method.
*/
if (zz->LB.Free_Structure != NULL)
zz->LB.Free_Structure(zz);
/*
* Convert method_name to all upper case.
* Do not change the original string.
*/
error = Zoltan_Clean_String(method_name, &method_upper);
if (error) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo,
"Error returned from Zoltan_Clean_String; No method set.");
goto End;
}
strcpy(zz->LB.Method_Name, method_upper);
if (strcmp(method_upper, "BLOCK") == 0) {
zz->LB.Method = BLOCK;
zz->LB.LB_Fn = Zoltan_Block;
zz->LB.Free_Structure = NULL;
zz->LB.Copy_Structure = NULL;
zz->LB.Serialize_Structure_Size = NULL;
zz->LB.Serialize_Structure = NULL; /* Nothing to serialize in this method */
zz->LB.Deserialize_Structure = NULL;
}
else if (strcmp(method_upper, "CYCLIC") == 0) {
zz->LB.Method = CYCLIC;
zz->LB.LB_Fn = Zoltan_Cyclic;
zz->LB.Free_Structure = NULL;
zz->LB.Copy_Structure = NULL;
zz->LB.Serialize_Structure_Size = NULL;
zz->LB.Serialize_Structure = NULL; /* Nothing to serialize in this method */
zz->LB.Deserialize_Structure = NULL;
}
else if (strcmp(method_upper, "RANDOM") == 0) {
zz->LB.Method = RANDOM;
zz->LB.LB_Fn = Zoltan_Random;
zz->LB.Free_Structure = NULL;
zz->LB.Copy_Structure = NULL;
zz->LB.Serialize_Structure_Size = NULL;
zz->LB.Serialize_Structure = NULL; /* Nothing to serialize in this method */
zz->LB.Deserialize_Structure = NULL;
}
else if (strcmp(method_upper, "RCB") == 0) {
zz->LB.Method = RCB;
zz->LB.LB_Fn = Zoltan_RCB;
zz->LB.Free_Structure = Zoltan_RCB_Free_Structure;
zz->LB.Copy_Structure = Zoltan_RCB_Copy_Structure;
zz->LB.Serialize_Structure_Size = Zoltan_RCB_Serialize_Structure_Size;
zz->LB.Serialize_Structure = Zoltan_RCB_Serialize_Structure;
zz->LB.Deserialize_Structure = Zoltan_RCB_Deserialize_Structure;
zz->LB.Point_Assign = Zoltan_RB_Point_Assign;
zz->LB.Box_Assign = Zoltan_RB_Box_Assign;
}
else if (strcmp(method_upper, "OCTPART") == 0) {
ZOLTAN_PRINT_ERROR(zz->Proc, yo,
"OCTPART method is no longer supported in Zoltan; "
"Try LB_METHOD=HSFC for similar results.");
error = ZOLTAN_FATAL;
goto End;
}
else if (strcmp(method_upper, "GRAPH") == 0){
zz->LB.Method = GRAPH;
zz->LB.LB_Fn = Zoltan_Graph;
/* Next two are useful only when using PHG */
zz->LB.Free_Structure = Zoltan_PHG_Free_Structure;
zz->LB.Copy_Structure = Zoltan_PHG_Copy_Structure;
zz->LB.Serialize_Structure_Size =
Zoltan_Serialize_Structure_Size_Not_Implemented; /* TODO */
zz->LB.Serialize_Structure =
Zoltan_Serialize_Structure_Not_Implemented; /* TODO */
zz->LB.Deserialize_Structure =
Zoltan_Deserialize_Structure_Not_Implemented; /* TODO */
zz->LB.Point_Assign = NULL;
zz->LB.Box_Assign = NULL;
}
/* PARMETIS is here for backward compatibility.
* New way: LB_METHOD = GRAPH
* GRAPH_PACKAGE = PARMETIS or SCOTCH or PHG
*/
else if (strcmp(method_upper, "PARMETIS") == 0){
#ifdef ZOLTAN_PARMETIS
zz->LB.Method = GRAPH;
zz->LB.LB_Fn = Zoltan_ParMetis;
zz->LB.Free_Structure = NULL;
zz->LB.Copy_Structure = NULL;
zz->LB.Serialize_Structure_Size = NULL;
zz->LB.Serialize_Structure = NULL; /* Nothing to serialize in this method */
zz->LB.Deserialize_Structure = NULL;
zz->LB.Point_Assign = NULL;
zz->LB.Box_Assign = NULL;
#else
ZOLTAN_PRINT_ERROR(zz->Proc, yo,
"ParMETIS method selected but "
"ParMETIS not compiled into Zoltan.");
error = ZOLTAN_FATAL;
goto End;
#endif
}
else if (strcmp(method_upper, "REFTREE") == 0) {
zz->LB.Method = REFTREE;
zz->LB.LB_Fn = Zoltan_Reftree_Part;
zz->LB.Free_Structure = Zoltan_Reftree_Free_Structure;
zz->LB.Copy_Structure = NULL;
zz->LB.Serialize_Structure_Size = NULL;
zz->LB.Serialize_Structure = NULL; /* Nothing to serialize in this method */
zz->LB.Deserialize_Structure = NULL;
zz->LB.Point_Assign = NULL;
zz->LB.Box_Assign = NULL;
}
else if (strcmp(method_upper, "RIB") == 0) {
zz->LB.Method = RIB;
zz->LB.LB_Fn = Zoltan_RIB;
zz->LB.Free_Structure = Zoltan_RIB_Free_Structure;
zz->LB.Copy_Structure = Zoltan_RIB_Copy_Structure;
zz->LB.Serialize_Structure_Size =
Zoltan_Serialize_Structure_Size_Not_Implemented; /* TODO */
zz->LB.Serialize_Structure =
Zoltan_Serialize_Structure_Not_Implemented; /* TODO */
zz->LB.Deserialize_Structure =
Zoltan_Deserialize_Structure_Not_Implemented; /* TODO */
zz->LB.Point_Assign = Zoltan_RB_Point_Assign;
zz->LB.Box_Assign = Zoltan_RB_Box_Assign;
}
else if (strcmp(method_upper, "HSFC") == 0) {
zz->LB.Method = HSFC;
zz->LB.LB_Fn = Zoltan_HSFC;
zz->LB.Free_Structure = Zoltan_HSFC_Free_Structure;
zz->LB.Copy_Structure = Zoltan_HSFC_Copy_Structure;
zz->LB.Serialize_Structure_Size =
Zoltan_Serialize_Structure_Size_Not_Implemented; /* TODO */
zz->LB.Serialize_Structure =
Zoltan_Serialize_Structure_Not_Implemented; /* TODO */
zz->LB.Deserialize_Structure =
Zoltan_Deserialize_Structure_Not_Implemented; /* TODO */
zz->LB.Point_Assign = Zoltan_HSFC_Point_Assign;
zz->LB.Box_Assign = Zoltan_HSFC_Box_Assign;
}
else if ((strcmp(method_upper, "HYPERGRAPH") == 0)
|| (strcmp(method_upper, "PHG") == 0)){
/* HYPERGRAPH is a family of methods. */
/* PHG is Zoltan's standard parallel hypergraph partitioner. */
zz->LB.Method = HYPERGRAPH;
zz->LB.LB_Fn = Zoltan_PHG;
zz->LB.Free_Structure = Zoltan_PHG_Free_Structure;
zz->LB.Copy_Structure = Zoltan_PHG_Copy_Structure;
zz->LB.Serialize_Structure_Size =
Zoltan_Serialize_Structure_Size_Not_Implemented; /* TODO */
zz->LB.Serialize_Structure =
Zoltan_Serialize_Structure_Not_Implemented; /* TODO */
zz->LB.Deserialize_Structure =
Zoltan_Deserialize_Structure_Not_Implemented; /* TODO */
zz->LB.Point_Assign = NULL;
zz->LB.Box_Assign = NULL;
}
else if (strcmp(method_upper, "HIER") == 0) {
zz->LB.Method = HIER;
zz->LB.LB_Fn = Zoltan_Hier;
zz->LB.Free_Structure = Zoltan_Hier_Free_Structure;
zz->LB.Copy_Structure = Zoltan_Hier_Copy_Structure;
zz->LB.Serialize_Structure_Size =
Zoltan_Serialize_Structure_Size_Not_Implemented; /* TODO */
zz->LB.Serialize_Structure =
Zoltan_Serialize_Structure_Not_Implemented; /* TODO */
zz->LB.Deserialize_Structure =
Zoltan_Deserialize_Structure_Not_Implemented; /* TODO */
zz->LB.Point_Assign = NULL;
zz->LB.Box_Assign = NULL;
}
else if (strcmp(method_upper, "NONE") == 0) {
zz->LB.Method = NONE;
zz->LB.LB_Fn = NULL;
zz->LB.Free_Structure = NULL;
zz->LB.Copy_Structure = NULL;
zz->LB.Serialize_Structure_Size = NULL;
zz->LB.Serialize_Structure = NULL; /* Nothing to serialize in this method */
zz->LB.Deserialize_Structure = NULL;
zz->LB.Point_Assign = NULL;
zz->LB.Box_Assign = NULL;
}
/*
* SET OTHER METHODS HERE!!
*/
else {
sprintf(msg, "Invalid LB method specified: %s\n", method_name);
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
error = ZOLTAN_FATAL;
goto End;
}
if (zz->Proc == zz->Debug_Proc && zz->Debug_Level >= ZOLTAN_DEBUG_PARAMS) {
printf("ZOLTAN Load balancing method = %d (%s)\n",
zz->LB.Method, method_name);
}
End:
ZOLTAN_FREE(&method_upper);
return (error);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,290 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zz_const.h"
#include "zz_util_const.h"
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*
* This file contains routines to set the part sizes.
*/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int Zoltan_LB_Set_Part_Sizes(ZZ *zz, int global_num,
int len, int *part_ids, int *wgt_idx, float *part_sizes)
{
/*
* Function to set the desired part sizes. This function
* only sets values locally. Later, Zoltan_LB_Get_Part_Sizes
* collects all the information across processors.
*
* Input:
* zz -- The Zoltan structure to which this method
* applies.
* global_num -- Global part numbers? (0 for local numbers)
* len -- Length of arrays wgt_idx, part_idx, part_sizes
* part_ids -- Array of part ids (local or global)
* wgt_idx -- Array of indices between 0 and Obj_Wgt_Dim-1
* part_sizes -- Array of floats that gives the desired part
* size for each weight and each part, i.e.,
* part_sizes[i] corresponds to wgt_idx[i] and part_id[i]
*
* Output:
* zz->LB.* -- Appropriate fields set to designated values.
* Return value -- Error code.
*/
char *yo = "Zoltan_LB_Set_Part_Sizes";
int i, j, maxlen=0;
int error = ZOLTAN_OK;
const int INIT_NUM_PART = 64; /* Initial allocation for Part_Info array. */
ZOLTAN_TRACE_ENTER(zz, yo);
/* len = -1 will nullify all part sizes set on this proc */
if (len == -1){
zz->LB.Part_Info_Len = 0;
goto End;
}
/* Verify input. */
if ((part_ids==NULL) || (part_sizes==NULL)){
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Invalid input argument NULL.");
error = ZOLTAN_FATAL;
goto End;
}
/* Do we need more space? */
if ((!zz->LB.Part_Info) || (zz->LB.Part_Info_Max_Len==0)){
maxlen = INIT_NUM_PART; /* Start with space for INIT_NUM_PART */
zz->LB.Part_Info = (struct Zoltan_part_info *) ZOLTAN_MALLOC(maxlen *
sizeof(struct Zoltan_part_info));
}
if (zz->LB.Part_Info_Len + len > zz->LB.Part_Info_Max_Len){
maxlen = 2*(zz->LB.Part_Info_Len + len); /* Double the length */
zz->LB.Part_Info = (struct Zoltan_part_info *) ZOLTAN_REALLOC( zz->LB.Part_Info,
maxlen * sizeof(struct Zoltan_part_info));
}
if (zz->LB.Part_Info == NULL){
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
error = ZOLTAN_MEMERR;
goto End;
}
/* Add new data to part info array. */
for (i=0,j=zz->LB.Part_Info_Len; i<len; i++,j++){
zz->LB.Part_Info[j].Size = part_sizes[i];
zz->LB.Part_Info[j].Part_id = part_ids[i];
zz->LB.Part_Info[j].Idx = (wgt_idx ? wgt_idx[i] : 0);
zz->LB.Part_Info[j].Global_num = global_num;
}
/* Update values in LB. */
zz->LB.Part_Info_Len += len;
if (maxlen > zz->LB.Part_Info_Max_Len)
zz->LB.Part_Info_Max_Len = maxlen;
End:
ZOLTAN_TRACE_EXIT(zz, yo);
return error;
}
/***************************************************************************/
int Zoltan_LB_Get_Part_Sizes(ZZ *zz, int part_dim, float *part_sizes)
{
/*
* Function to get the scaled part sizes.
*
* Input:
* zz -- The Zoltan structure to which this method
* applies.
* part_dim -- The number of object weights per part.
* (This usually equals lb->Obj_Wgt_Dim.)
*
* Output:
* part_sizes -- Array of floats that gives the set part
* sizes, scaled such that they sum to one.
*/
int i, j, nparts, fpart;
int num_global_parts = zz->LB.Num_Global_Parts;
float *temp_part_sizes=NULL, *sum=NULL;
int error = ZOLTAN_OK;
char msg[128];
static char *yo = "Zoltan_LB_Get_Part_Sizes";
ZOLTAN_TRACE_ENTER(zz, yo);
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL)
printf("[%1d] Debug: num_global_parts = %d\n", zz->Proc, num_global_parts);
/* Barrier to make sure all procs have finished Zoltan_LB_Set_Part_Sizes */
MPI_Barrier(zz->Communicator);
/* For convenience, if no weights are used, set part_dim to 1 */
if (part_dim==0) part_dim = 1;
if (part_sizes == NULL){
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Input argument part_sizes is NULL.");
error = ZOLTAN_FATAL;
goto End;
}
/* Find max Part_Info_Len over all procs to see if they are all zero. */
MPI_Allreduce((void*) &(zz->LB.Part_Info_Len), (void*) &j,
1, MPI_INT, MPI_MAX, zz->Communicator);
if (j == 0){
/* Uniform part sizes. */
zz->LB.Uniform_Parts = 1;
for (i = 0; i < num_global_parts*part_dim; i++)
part_sizes[i] = 1.0 / (float)num_global_parts;
}
else {
/* Get the part sizes set by the user (application).
* Each processor puts its data in a part_dim * num_global_parts
* array. Then we gather all the data across processors.
* Out-of-range part size data is ignored.
*/
zz->LB.Uniform_Parts = 0;
/* Pack LB.Part_Info into temp array */
temp_part_sizes = (float *)ZOLTAN_MALLOC(num_global_parts*part_dim
*sizeof(float));
sum = (float *)ZOLTAN_MALLOC(part_dim*sizeof(float));
if ((!temp_part_sizes) || (!sum)){
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
error = ZOLTAN_MEMERR;
goto End;
}
for (i = 0; i < num_global_parts*part_dim; i++){
temp_part_sizes[i] = -1.0;
}
for (i = 0; i < zz->LB.Part_Info_Len; i++){
/* Only assemble part sizes for parts and weights
in the requested range. */
if (zz->LB.Part_Info[i].Idx < part_dim){
j = zz->LB.Part_Info[i].Part_id;
if (zz->LB.Part_Info[i].Global_num == 0) {
Zoltan_LB_Proc_To_Part(zz, zz->Proc, &nparts, &fpart);
j += fpart;
}
if (j >= num_global_parts){
sprintf(msg, "Part number %d is >= num_global_parts %d.",
j, num_global_parts);
ZOLTAN_PRINT_WARN(zz->Proc, yo, msg);
error = ZOLTAN_WARN;
}
else
temp_part_sizes[j*part_dim + zz->LB.Part_Info[i].Idx]
= zz->LB.Part_Info[i].Size;
}
}
/* Reduce over all procs */
MPI_Allreduce((void*) temp_part_sizes, (void*) part_sizes,
num_global_parts*part_dim, MPI_FLOAT, MPI_MAX, zz->Communicator);
/* Check for errors. Scale the sizes so they sum to one for each weight. */
for (j = 0; j < part_dim; j++)
sum[j] = 0.0;
for (i = 0; i < num_global_parts; i++){
for (j = 0; j < part_dim; j++){
if (part_sizes[i*part_dim+j]<0)
part_sizes[i*part_dim+j] = 1.0; /* default value if not set */
sum[j] += part_sizes[i*part_dim+j];
}
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL){
printf("[%1d] In %s: Part size %1d (before scaling) = ",
zz->Proc, yo, i);
for (j = 0; j < part_dim; j++)
printf("%f, ", part_sizes[i*part_dim+j]);
printf("\n");
}
}
/* Check for sum[j] == 0 (error). */
for (j = 0; j < part_dim; j++) {
if (sum[j] == 0.0) {
sprintf(msg, "Sum of weights (component %1d) is zero.", j);
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
error = ZOLTAN_FATAL;
goto End;
}
}
/* Normalize part sizes */
for (i = 0; i < num_global_parts; i++)
for (j = 0; j < part_dim; j++)
part_sizes[i*part_dim+j] /= sum[j];
}
End:
if (temp_part_sizes) ZOLTAN_FREE(&temp_part_sizes);
if (sum) ZOLTAN_FREE(&sum);
ZOLTAN_TRACE_EXIT(zz, yo);
return error;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

File diff suppressed because it is too large Load Diff