mirror of
https://github.com/PhasicFlow/phasicFlow.git
synced 2025-07-28 03:27:05 +00:00
Zoltan is added as thirdParty package
This commit is contained in:
64
thirdParty/Zoltan/src/tpls/README
vendored
Normal file
64
thirdParty/Zoltan/src/tpls/README
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
# @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
|
||||
|
||||
|
||||
PARMETIS DIRECTORY -- Routines to providing the interface to the
|
||||
ParMETIS and Jostle libraries.
|
||||
----------------------------------------------------------------
|
||||
|
||||
Files compiled into Zoltan:
|
||||
|
||||
parmetis_jostle_const.h -- Prototypes and definitions.
|
||||
|
||||
parmetis_jostle.c -- Routines to interpret parameters,
|
||||
build the necessary data structures,
|
||||
call the appropriate libraries,
|
||||
and create the Zoltan return lists.
|
||||
|
||||
verify_graph.c -- Routines to verify the correctness of a graph.
|
||||
|
||||
scatter_graph.c -- Routines to scatter a ParMetis-style graph to all
|
||||
processors.
|
||||
|
||||
build_graph.c -- Build ParMETIS/Jostle graph data structure.
|
167
thirdParty/Zoltan/src/tpls/build_graph.c
vendored
Normal file
167
thirdParty/Zoltan/src/tpls/build_graph.c
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* @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 <ctype.h>
|
||||
#include "zz_const.h"
|
||||
#include "zz_util_const.h"
|
||||
#include "all_allo_const.h"
|
||||
#include "params_const.h"
|
||||
#include "graph.h"
|
||||
|
||||
int Zoltan_Build_Graph(ZZ *zz, int *graph_type, int check_graph,
|
||||
int num_obj, ZOLTAN_ID_PTR global_ids, ZOLTAN_ID_PTR local_ids,
|
||||
int obj_wgt_dim, int * edge_wgt_dim,
|
||||
ZOLTAN_GNO_TYPE **vtxdist, int **xadj, ZOLTAN_GNO_TYPE **adjncy, float **ewgts,
|
||||
int **adjproc)
|
||||
{
|
||||
int ierr = ZOLTAN_OK;
|
||||
int local;
|
||||
|
||||
int my_num_obj;
|
||||
ZOLTAN_GNO_TYPE glb_obj;
|
||||
int my_obj_wgt_dim;
|
||||
ZG graph;
|
||||
|
||||
local = IS_LOCAL_GRAPH(*graph_type);
|
||||
ierr = Zoltan_ZG_Build (zz, &graph, local, 0,0,NULL,NULL); /* Normal graph */
|
||||
ierr = Zoltan_ZG_Export (zz, &graph,
|
||||
&glb_obj, &my_num_obj, &my_obj_wgt_dim, edge_wgt_dim,
|
||||
vtxdist, xadj, adjncy, adjproc,
|
||||
ewgts, NULL);
|
||||
|
||||
graph.mtx.mtx.pinwgt = NULL;
|
||||
graph.mtx.mtx.ystart = NULL;
|
||||
graph.mtx.mtx.yend = NULL;
|
||||
graph.mtx.mtx.pinGNO = NULL;
|
||||
graph.mtx.dist_y = NULL;
|
||||
Zoltan_ZG_Free(&graph);
|
||||
|
||||
return (ierr);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int Zoltan_Get_Num_Edges_Per_Obj(
|
||||
ZZ *zz,
|
||||
int num_obj,
|
||||
ZOLTAN_ID_PTR global_ids,
|
||||
ZOLTAN_ID_PTR local_ids,
|
||||
int **edges_per_obj,
|
||||
int *max_edges,
|
||||
int *num_edges
|
||||
)
|
||||
{
|
||||
/* Calls ZOLTAN_NUM_EDGE_FN or ZOLTAN_NUM_EDGE_MULTI_FN to obtain number
|
||||
* of edges per object.
|
||||
* Returns number of edges per object in array edges_per_obj.
|
||||
* Computes max edges per obj and total edges per obj.
|
||||
*/
|
||||
static char *yo = "Zoltan_Get_Num_Edges_Per_Obj";
|
||||
int ierr = ZOLTAN_OK;
|
||||
int i;
|
||||
int nedges;
|
||||
int num_gid_entries = zz->Num_GID;
|
||||
int num_lid_entries = zz->Num_LID;
|
||||
ZOLTAN_ID_PTR lid;
|
||||
|
||||
*max_edges = *num_edges = 0;
|
||||
if (num_obj) {
|
||||
|
||||
*edges_per_obj = (int *) ZOLTAN_MALLOC(num_obj * sizeof(int));
|
||||
if (*edges_per_obj == NULL) {
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
|
||||
ierr = ZOLTAN_MEMERR;
|
||||
goto End;
|
||||
}
|
||||
|
||||
if (zz->Get_Num_Edges_Multi) {
|
||||
zz->Get_Num_Edges_Multi(zz->Get_Num_Edges_Multi_Data,
|
||||
num_gid_entries, num_lid_entries, num_obj,
|
||||
global_ids, local_ids, *edges_per_obj, &ierr);
|
||||
if (ierr) {
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error in Get_Num_Edges_Multi.");
|
||||
goto End;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_obj; i++) {
|
||||
nedges = (*edges_per_obj)[i];
|
||||
*num_edges += nedges;
|
||||
if (nedges > *max_edges) *max_edges = nedges;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i=0; i< num_obj; i++) {
|
||||
lid = (num_lid_entries ? &(local_ids[i*num_lid_entries]) : NULL);
|
||||
nedges = zz->Get_Num_Edges(zz->Get_Num_Edges_Data,
|
||||
num_gid_entries, num_lid_entries,
|
||||
&(global_ids[i*num_gid_entries]),
|
||||
lid, &ierr);
|
||||
if (ierr) {
|
||||
/* Return error */
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Error in Get_Num_Edges.");
|
||||
goto End;
|
||||
}
|
||||
*num_edges += nedges;
|
||||
if (nedges > *max_edges) *max_edges = nedges;
|
||||
(*edges_per_obj)[i] = nedges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
End:
|
||||
return ierr;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* closing bracket for extern "C" */
|
||||
#endif
|
72
thirdParty/Zoltan/src/tpls/graph_util.h
vendored
Normal file
72
thirdParty/Zoltan/src/tpls/graph_util.h
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* @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 __COMMON_H
|
||||
#define __COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* if C++, define the rest of this header file as extern C */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "zoltan_util.h"
|
||||
#include "third_library_const.h"
|
||||
|
||||
extern int Zoltan_Verify_Graph(MPI_Comm, indextype *, indextype *,
|
||||
indextype *, weighttype *, weighttype *,
|
||||
int, int, int, int, int);
|
||||
|
||||
extern int Zoltan_Scatter_Graph(indextype **, indextype **,
|
||||
indextype **, weighttype **, indextype **, weighttype **,
|
||||
realtype **, int, int, ZZ *, ZOLTAN_COMM_OBJ **);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* closing bracket for extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
901
thirdParty/Zoltan/src/tpls/parmetis_interface.c
vendored
Normal file
901
thirdParty/Zoltan/src/tpls/parmetis_interface.c
vendored
Normal file
@ -0,0 +1,901 @@
|
||||
/*
|
||||
* @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 <ctype.h>
|
||||
#include "zz_const.h"
|
||||
#include "zz_util_const.h"
|
||||
#include "all_allo_const.h"
|
||||
#include "params_const.h"
|
||||
#include "order_const.h"
|
||||
#include "third_library.h"
|
||||
#include "parmetis_interface.h"
|
||||
#include "parmetis_interface_params.h"
|
||||
|
||||
/*********** COMPATIBILITY CHECKING AT COMPILE TIME ************/
|
||||
#ifdef ZOLTAN_PARMETIS
|
||||
#if (PARMETIS_MAJOR_VERSION < 3)
|
||||
#error "Specified version of ParMETIS is not compatible with Zoltan; upgrade to ParMETIS v3.1 or later, or build Zoltan without ParMETIS."
|
||||
#endif
|
||||
|
||||
#if (PARMETIS_MAJOR_VERSION == 3) && (PARMETIS_MINOR_VERSION < 1)
|
||||
#error "Specified version of ParMETIS is not compatible with Zoltan; upgrade to ParMETIS v3.1 or later, or build Zoltan without ParMETIS."
|
||||
#endif
|
||||
|
||||
/********** Workaround for memory bug in ParMETIS 3.1.0 **********/
|
||||
#ifndef PARMETIS_SUBMINOR_VERSION
|
||||
#define PARMETIS_SUBMINOR_VERSION 0
|
||||
#endif
|
||||
|
||||
#if (PARMETIS_MAJOR_VERSION == 3) && (PARMETIS_MINOR_VERSION == 1) && (PARMETIS_SUBMINOR_VERSION == 0)
|
||||
#define PARMETIS31_ALWAYS_FREES_VSIZE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static int pmv3method(char *alg);
|
||||
|
||||
static int mylog2(int x)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i=0 ; (1<<i) <= x ; ++i);
|
||||
return (i-1);
|
||||
}
|
||||
|
||||
static int Zoltan_Parmetis_Parse(ZZ*, indextype *, char*, realtype*, double *,
|
||||
ZOLTAN_Output_Order*);
|
||||
|
||||
|
||||
/**********************************************************/
|
||||
/* Interface routine for ParMetis: Partitioning */
|
||||
/**********************************************************/
|
||||
|
||||
int Zoltan_ParMetis(
|
||||
ZZ *zz, /* Zoltan structure */
|
||||
float *part_sizes, /* Input: Array of size zz->Num_Global_Parts
|
||||
containing the percentage of work to be
|
||||
assigned to each partition. */
|
||||
int *num_imp, /* number of objects to be imported */
|
||||
ZOLTAN_ID_PTR *imp_gids, /* global ids of objects to be imported */
|
||||
ZOLTAN_ID_PTR *imp_lids, /* local ids of objects to be imported */
|
||||
int **imp_procs, /* list of processors to import from */
|
||||
int **imp_to_part, /* list of partitions to which imported objects are
|
||||
assigned. */
|
||||
int *num_exp, /* number of objects to be exported */
|
||||
ZOLTAN_ID_PTR *exp_gids, /* global ids of objects to be exported */
|
||||
ZOLTAN_ID_PTR *exp_lids, /* local ids of objects to be exported */
|
||||
int **exp_procs, /* list of processors to export to */
|
||||
int **exp_to_part /* list of partitions to which exported objects are
|
||||
assigned. */
|
||||
)
|
||||
{
|
||||
char *yo = "Zoltan_ParMetis";
|
||||
int ierr;
|
||||
ZOLTAN_Third_Graph gr;
|
||||
ZOLTAN_Third_Geom *geo = NULL;
|
||||
ZOLTAN_Third_Vsize vsp;
|
||||
ZOLTAN_Third_Part prt;
|
||||
ZOLTAN_Output_Part part;
|
||||
|
||||
ZOLTAN_ID_PTR global_ids = NULL;
|
||||
ZOLTAN_ID_PTR local_ids = NULL;
|
||||
|
||||
int use_timers = 0;
|
||||
int timer_p = -1;
|
||||
int get_times = 0;
|
||||
double times[5];
|
||||
|
||||
double pmv3_itr = 0.0;
|
||||
realtype itr = 0.0;
|
||||
indextype options[MAX_PARMETIS_OPTIONS];
|
||||
char alg[MAX_PARAM_STRING_LEN];
|
||||
|
||||
#ifdef ZOLTAN_PARMETIS
|
||||
MPI_Comm comm = zz->Communicator;/* don't risk letting external packages */
|
||||
/* change our zz struct. */
|
||||
#endif
|
||||
|
||||
indextype i;
|
||||
realtype *imb_tols;
|
||||
indextype ncon;
|
||||
indextype edgecut;
|
||||
indextype wgtflag;
|
||||
indextype numflag = 0;
|
||||
indextype num_part = zz->LB.Num_Global_Parts; /* passed to ParMETIS. */
|
||||
|
||||
ZOLTAN_TRACE_ENTER(zz, yo);
|
||||
|
||||
Zoltan_Third_Init(&gr, &prt, &vsp, &part,
|
||||
imp_gids, imp_lids, imp_procs, imp_to_part,
|
||||
exp_gids, exp_lids, exp_procs, exp_to_part);
|
||||
|
||||
if (sizeof(realtype) != sizeof(float)) {
|
||||
int tmp = zz->LB.Num_Global_Parts * MAX(zz->Obj_Weight_Dim, 1);
|
||||
prt.input_part_sizes = (realtype *) ZOLTAN_MALLOC(tmp * sizeof(realtype));
|
||||
|
||||
for (i = 0; i < tmp; i++)
|
||||
prt.input_part_sizes[i] = (realtype) part_sizes[i];
|
||||
|
||||
/* KDD 2/2014: removed re-scaling part sizes so they sum to one.
|
||||
* part_sizes are already scaled in Zoltan_LB_Get_Part_Sizes.
|
||||
* plus, the code here was wrong for multiple object weights.
|
||||
* similar scaling code did not exist in the Scotch interface.
|
||||
*/
|
||||
prt.part_sizes = prt.input_part_sizes;
|
||||
}
|
||||
else
|
||||
prt.input_part_sizes = prt.part_sizes = (realtype *) part_sizes;
|
||||
|
||||
|
||||
ierr = Zoltan_Parmetis_Parse(zz, options, alg, &itr, &pmv3_itr, NULL);
|
||||
if ((ierr != ZOLTAN_OK) && (ierr != ZOLTAN_WARN)) {
|
||||
Zoltan_Third_Exit(&gr, geo, &prt, &vsp, &part, NULL);
|
||||
return (ierr);
|
||||
}
|
||||
|
||||
gr.graph_type = 0;
|
||||
|
||||
#ifdef ZOLTAN_PARMETIS
|
||||
SET_GLOBAL_GRAPH(&gr.graph_type);
|
||||
/* Select type of graph, negative because we impose them */
|
||||
/* TODO: add a parameter to select the type, shared with Scotch */
|
||||
/* if (strcmp (graph_type, "GLOBAL") != 0) { */
|
||||
/* gr.graph_type = - LOCAL_GRAPH; */
|
||||
/* if (zz->Num_Proc > 1) { */
|
||||
/* ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Distributed graph: cannot call METIS, switching to ParMetis"); */
|
||||
/* gr.graph_type = - GLOBAL_GRAPH; */
|
||||
/* retval = ZOLTAN_WARN; */
|
||||
/* } */
|
||||
/* } */
|
||||
#else /* graph is local */
|
||||
SET_LOCAL_GRAPH(&gr.graph_type);
|
||||
#endif /* ZOLTAN_PARMETIS */
|
||||
|
||||
|
||||
/* Some algorithms use geometry data */
|
||||
if (strncmp(alg, "PARTGEOM", 8) == 0){ /* PARTGEOM & PARTGEOMKWAY */
|
||||
geo = (ZOLTAN_Third_Geom*) ZOLTAN_MALLOC(sizeof(ZOLTAN_Third_Geom));
|
||||
memset (geo, 0, sizeof(ZOLTAN_Third_Geom));
|
||||
/* ParMETIS will crash if geometric method and some procs have no nodes. */
|
||||
/* Avoid fatal crash by setting scatter to level 2 or higher. */
|
||||
gr.scatter_min = 2;
|
||||
if (geo == NULL) {
|
||||
ZOLTAN_PRINT_ERROR (zz->Proc, yo, "Out of memory.");
|
||||
return (ZOLTAN_MEMERR);
|
||||
}
|
||||
if (strcmp(alg, "PARTGEOM") == 0) {
|
||||
gr.get_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
timer_p = Zoltan_Preprocess_Timer(zz, &use_timers);
|
||||
|
||||
/* Start timer */
|
||||
get_times = (zz->Debug_Level >= ZOLTAN_DEBUG_ATIME);
|
||||
if (get_times){
|
||||
MPI_Barrier(zz->Communicator);
|
||||
times[0] = Zoltan_Time(zz->Timer);
|
||||
}
|
||||
|
||||
vsp.vsize_malloc = 0;
|
||||
#ifdef PARMETIS31_ALWAYS_FREES_VSIZE
|
||||
if (!strcmp(alg, "ADAPTIVEREPART") && (zz->Num_Proc > 1)) {
|
||||
/* ParMETIS will free this memory; use malloc to allocate so
|
||||
ZOLTAN_MALLOC counters don't show an error. */
|
||||
vsp.vsize_malloc = 1 ;
|
||||
}
|
||||
#endif /* PARMETIS31_ALWAYS_FREES_VSIZE */
|
||||
|
||||
|
||||
ierr = Zoltan_Preprocess_Graph(zz, &global_ids, &local_ids, &gr,
|
||||
geo, &prt, &vsp);
|
||||
if ((ierr != ZOLTAN_OK) && (ierr != ZOLTAN_WARN)) {
|
||||
Zoltan_Third_Exit(&gr, geo, &prt, &vsp, &part, NULL);
|
||||
return (ierr);
|
||||
}
|
||||
|
||||
/* Get object sizes if requested */
|
||||
if (options[PMV3_OPT_USE_OBJ_SIZE] &&
|
||||
(zz->Get_Obj_Size || zz->Get_Obj_Size_Multi) &&
|
||||
(!strcmp(alg, "ADAPTIVEREPART") || gr.final_output))
|
||||
gr.showMoveVol = 1;
|
||||
|
||||
|
||||
/* Get a time here */
|
||||
if (get_times) times[1] = Zoltan_Time(zz->Timer);
|
||||
|
||||
/* Get ready to call ParMETIS */
|
||||
edgecut = -1;
|
||||
wgtflag = 2*(gr.obj_wgt_dim>0) + (gr.edge_wgt_dim>0);
|
||||
numflag = 0;
|
||||
ncon = (gr.obj_wgt_dim > 0 ? gr.obj_wgt_dim : 1);
|
||||
|
||||
if (!prt.part_sizes){
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL,"Input parameter part_sizes is NULL.");
|
||||
}
|
||||
if ((zz->Proc == 0) && (zz->Debug_Level >= ZOLTAN_DEBUG_ALL)) {
|
||||
for (i=0; i<num_part; i++){
|
||||
indextype j;
|
||||
|
||||
printf("Debug: Size(s) for part " TPL_IDX_SPEC " = ", i);
|
||||
for (j=0; j<ncon; j++)
|
||||
printf("%f ", prt.part_sizes[i*ncon+j]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* if (strcmp(alg, "ADAPTIVEREPART") == 0) */
|
||||
for (i = 0; i < num_part*ncon; i++)
|
||||
if (prt.part_sizes[i] == 0)
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL, "Zero-sized part(s) requested! "
|
||||
"ParMETIS 3.x will likely fail. Please use a "
|
||||
"different method, or remove the zero-sized "
|
||||
"parts from the problem.");
|
||||
|
||||
|
||||
/* Set Imbalance Tolerance for each weight component. */
|
||||
imb_tols = (realtype *) ZOLTAN_MALLOC(ncon * sizeof(realtype));
|
||||
if (!imb_tols){
|
||||
/* Not enough memory */
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Out of memory.");
|
||||
}
|
||||
for (i=0; i<ncon; i++)
|
||||
imb_tols[i] = (realtype) (zz->LB.Imbalance_Tol[i]);
|
||||
|
||||
/* Now we can call ParMetis */
|
||||
|
||||
/* Zoltan_Third_Graph_Print(zz, &gr, "Before calling parmetis"); */
|
||||
|
||||
|
||||
#ifdef ZOLTAN_PARMETIS
|
||||
if (!IS_LOCAL_GRAPH(gr.graph_type)) { /* May be GLOBAL or NO GRAPH */
|
||||
|
||||
/* First check for ParMetis 3 routines */
|
||||
if (strcmp(alg, "PARTKWAY") == 0){
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Calling the ParMETIS library "
|
||||
"ParMETIS_V3_PartKway");
|
||||
ParMETIS_V3_PartKway(gr.vtxdist, gr.xadj, gr.adjncy, gr.vwgt, gr.ewgts,
|
||||
&wgtflag, &numflag, &ncon, &num_part, prt.part_sizes,
|
||||
imb_tols, options, &edgecut, prt.part, &comm);
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Returned from the ParMETIS library");
|
||||
}
|
||||
else if (strcmp(alg, "PARTGEOMKWAY") == 0){
|
||||
indextype ndims = geo->ndims;
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Calling the ParMETIS library "
|
||||
"ParMETIS_V3_PartGeomKway");
|
||||
ParMETIS_V3_PartGeomKway(gr.vtxdist, gr.xadj, gr.adjncy, gr.vwgt,gr.ewgts,
|
||||
&wgtflag, &numflag, &ndims, geo->xyz, &ncon,
|
||||
&num_part, prt.part_sizes,
|
||||
imb_tols, options, &edgecut, prt.part, &comm);
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Returned from the ParMETIS library");
|
||||
}
|
||||
else if (strcmp(alg, "PARTGEOM") == 0){
|
||||
indextype ndims = geo->ndims;
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Calling the ParMETIS library "
|
||||
"ParMETIS_V3_PartGeom");
|
||||
ParMETIS_V3_PartGeom(gr.vtxdist, &ndims, geo->xyz, prt.part, &comm);
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Returned from the ParMETIS library");
|
||||
}
|
||||
else if (strcmp(alg, "ADAPTIVEREPART") == 0){
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Calling the ParMETIS library "
|
||||
"ParMETIS_V3_AdaptiveRepart");
|
||||
ParMETIS_V3_AdaptiveRepart(gr.vtxdist, gr.xadj, gr.adjncy, gr.vwgt,
|
||||
vsp.vsize, gr.ewgts, &wgtflag, &numflag, &ncon,
|
||||
&num_part, prt.part_sizes, imb_tols,
|
||||
&itr, options, &edgecut, prt.part, &comm);
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Returned from the ParMETIS library");
|
||||
}
|
||||
else if (strcmp(alg, "REFINEKWAY") == 0){
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Calling the ParMETIS library "
|
||||
"ParMETIS_V3_RefineKway");
|
||||
ParMETIS_V3_RefineKway(gr.vtxdist, gr.xadj, gr.adjncy, gr.vwgt, gr.ewgts,
|
||||
&wgtflag, &numflag, &ncon, &num_part,
|
||||
prt.part_sizes, imb_tols,
|
||||
options, &edgecut, prt.part, &comm);
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Returned from the ParMETIS library");
|
||||
}
|
||||
else {
|
||||
/* Sanity check: This should never happen! */
|
||||
char msg[256];
|
||||
sprintf(msg, "Unknown ParMetis algorithm %s.", alg);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL, msg);
|
||||
}
|
||||
}
|
||||
#endif /* ZOLTAN_PARMETIS */
|
||||
#ifdef ZOLTAN_METIS
|
||||
/* TODO: I don't know how to set balance ! */
|
||||
if (IS_LOCAL_GRAPH(gr.graph_type)) {
|
||||
/* Check for Metis routines */
|
||||
if (strcmp(alg, "PARTKWAY") == 0){
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Calling the METIS library ");
|
||||
/* Use default options for METIS */
|
||||
#if !defined(METIS_VER_MAJOR) || METIS_VER_MAJOR < 5
|
||||
options[0] = 0;
|
||||
METIS_WPartGraphKway (gr.vtxdist+1, gr.xadj, gr.adjncy,
|
||||
gr.vwgt, gr.ewgts, &wgtflag,
|
||||
&numflag, &num_part, prt.part_sizes,
|
||||
options, &edgecut, prt.part);
|
||||
#else
|
||||
METIS_SetDefaultOptions(options);
|
||||
METIS_PartGraphKway (gr.vtxdist+1, &ncon, gr.xadj, gr.adjncy,
|
||||
gr.vwgt, vsp.vsize, gr.ewgts, &num_part,
|
||||
prt.part_sizes, imb_tols, options,
|
||||
&edgecut, prt.part);
|
||||
#endif
|
||||
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Returned from the METIS library");
|
||||
}
|
||||
else {
|
||||
/* Sanity check: This should never happen! */
|
||||
char msg[256];
|
||||
sprintf(msg, "Unknown Metis algorithm %s.", alg);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL, msg);
|
||||
}
|
||||
}
|
||||
#endif /* ZOLTAN_METIS */
|
||||
|
||||
|
||||
/* Get a time here */
|
||||
if (get_times) times[2] = Zoltan_Time(zz->Timer);
|
||||
|
||||
|
||||
if (gr.final_output) {
|
||||
/* Do final output now because after the data will not be coherent:
|
||||
unscatter only unscatter part data, not graph */
|
||||
ierr = Zoltan_Postprocess_FinalOutput (zz, &gr, &prt, &vsp, use_timers, itr);
|
||||
}
|
||||
/* Ignore the timings of Final Ouput */
|
||||
if (get_times) times[3] = Zoltan_Time(zz->Timer);
|
||||
|
||||
ierr = Zoltan_Postprocess_Graph(zz, global_ids, local_ids, &gr,
|
||||
geo, &prt, &vsp, NULL, &part);
|
||||
|
||||
Zoltan_Third_Export_User(&part,
|
||||
num_imp, imp_gids, imp_lids, imp_procs, imp_to_part,
|
||||
num_exp, exp_gids, exp_lids, exp_procs, exp_to_part);
|
||||
|
||||
/* Get a time here */
|
||||
if (get_times) times[4] = Zoltan_Time(zz->Timer);
|
||||
|
||||
if (get_times) Zoltan_Third_DisplayTime(zz, times);
|
||||
|
||||
if (use_timers && timer_p >= 0)
|
||||
ZOLTAN_TIMER_STOP(zz->ZTime, timer_p, zz->Communicator);
|
||||
|
||||
Zoltan_Third_Exit(&gr, geo, &prt, &vsp, NULL, NULL);
|
||||
if (imb_tols != NULL) ZOLTAN_FREE(&imb_tols);
|
||||
if (geo != NULL) ZOLTAN_FREE(&geo);
|
||||
ZOLTAN_FREE(&global_ids);
|
||||
ZOLTAN_FREE(&local_ids);
|
||||
|
||||
ZOLTAN_TRACE_EXIT(zz, yo);
|
||||
|
||||
return (ierr);
|
||||
}
|
||||
|
||||
|
||||
static int Zoltan_Parmetis_Parse(
|
||||
ZZ* zz,
|
||||
indextype *options,
|
||||
char* alg,
|
||||
realtype* itr,
|
||||
double *pmv3_itr,
|
||||
ZOLTAN_Output_Order *ord
|
||||
)
|
||||
{
|
||||
static char * yo = "Zoltan_Parmetis_Parse";
|
||||
|
||||
int i;
|
||||
int output_level, seed, coarse_alg, fold, use_obj_size;
|
||||
|
||||
/* Always use ParMetis option array because Zoltan by default
|
||||
produces no output (silent mode). ParMetis requires options[0]=1
|
||||
when options array is to be used. */
|
||||
options[0] = 1;
|
||||
for (i = 1; i < MAX_PARMETIS_OPTIONS; i++)
|
||||
options[i] = 0;
|
||||
|
||||
/* Set the default option values. */
|
||||
output_level = 0;
|
||||
coarse_alg = 2;
|
||||
use_obj_size = 1;
|
||||
fold = 0;
|
||||
seed = GLOBAL_SEED;
|
||||
|
||||
if(ord == NULL) {
|
||||
/* Map LB_APPROACH to suitable PARMETIS_METHOD */
|
||||
if (!strcasecmp(zz->LB.Approach, "partition")){
|
||||
strcpy(alg, "PARTKWAY");
|
||||
}
|
||||
else if (!strcasecmp(zz->LB.Approach, "repartition")){
|
||||
strcpy(alg, "ADAPTIVEREPART");
|
||||
*pmv3_itr = 100.; /* Ratio of inter-proc comm. time to data redist. time;
|
||||
100 gives similar partition quality to GDiffusion */
|
||||
}
|
||||
else if (!strcasecmp(zz->LB.Approach, "refine")){
|
||||
strcpy(alg, "REFINEKWAY");
|
||||
}
|
||||
else { /* If no LB_APPROACH is set, use repartition */
|
||||
strcpy(alg, "ADAPTIVEREPART");
|
||||
*pmv3_itr = 100.; /* Ratio of inter-proc comm. time to data redist. time;
|
||||
100 gives similar partition quality to GDiffusion */
|
||||
}
|
||||
}
|
||||
else {
|
||||
strcpy(alg, "NODEND");
|
||||
}
|
||||
|
||||
Zoltan_Bind_Param(Parmetis_params, "PARMETIS_METHOD",
|
||||
(void *) alg);
|
||||
Zoltan_Bind_Param(Parmetis_params, "PARMETIS_OUTPUT_LEVEL",
|
||||
(void *) &output_level);
|
||||
Zoltan_Bind_Param(Parmetis_params, "PARMETIS_SEED",
|
||||
(void *) &seed);
|
||||
Zoltan_Bind_Param(Parmetis_params, "PARMETIS_ITR",
|
||||
(void *) pmv3_itr);
|
||||
Zoltan_Bind_Param(Parmetis_params, "PARMETIS_COARSE_ALG",
|
||||
(void *) &coarse_alg);
|
||||
Zoltan_Bind_Param(Parmetis_params, "PARMETIS_FOLD",
|
||||
(void *) &fold);
|
||||
|
||||
Zoltan_Assign_Param_Vals(zz->Params, Parmetis_params, zz->Debug_Level,
|
||||
zz->Proc, zz->Debug_Proc);
|
||||
|
||||
/* Copy option values to ParMetis options array */
|
||||
|
||||
/* In this version of Zoltan, processors and partitions are coupled. */
|
||||
/* This will likely change in future releases, and then the options */
|
||||
/* value should change to DISCOUPLED. */
|
||||
options[PMV3_OPTION_PSR] = COUPLED;
|
||||
|
||||
if (pmv3method(alg)){
|
||||
/* ParMetis 3.0 options */
|
||||
options[PMV3_OPTION_DBGLVL] = output_level;
|
||||
options[PMV3_OPTION_SEED] = seed;
|
||||
options[PMV3_OPT_USE_OBJ_SIZE] = use_obj_size;
|
||||
if (ord == NULL)
|
||||
*itr = (realtype)*pmv3_itr;
|
||||
}
|
||||
|
||||
/* If ordering, use ordering method instead of load-balancing method */
|
||||
if (ord && ord->order_opt){
|
||||
strcpy(alg, ord->order_opt->method);
|
||||
}
|
||||
|
||||
if ((zz->Num_Proc == 1) &&
|
||||
(!strcmp(alg, "ADAPTIVEREPART") ||
|
||||
!strcmp(alg, "REPARTLDIFFUSION") ||
|
||||
!strcmp(alg, "REPARTGDIFFUSION") ||
|
||||
!strcmp(alg, "REPARTREMAP") ||
|
||||
!strcmp(alg, "REPARTMLREMAP"))) {
|
||||
/* These ParMETIS methods fail on one processor; an MPI command assumes
|
||||
at least two processors. */
|
||||
char str[256];
|
||||
sprintf(str, "ParMETIS method %s fails on one processor due to a bug"
|
||||
" in ParMETIS v3.x; resetting method to PartKway.", alg);
|
||||
ZOLTAN_PRINT_WARN(zz->Proc, yo, str);
|
||||
|
||||
strcpy(alg, "PARTKWAY");
|
||||
return (ZOLTAN_WARN);
|
||||
}
|
||||
|
||||
return(ZOLTAN_OK);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static int pmv3method( char *alg)
|
||||
{
|
||||
/* Check if alg is a supported ParMetis 3.0 method */
|
||||
return ((!strcmp(alg, "PARTKWAY"))
|
||||
|| (!strcmp(alg, "PARTGEOMKWAY"))
|
||||
|| (!strcmp(alg, "ADAPTIVEREPART"))
|
||||
|| (!strcmp(alg, "REFINEKWAY"))
|
||||
|| (!strcmp(alg, "NODEND"))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* The ParMetis ordering routine piggy-backs on the ParMetis
|
||||
* partitioning routines.
|
||||
**************************************************************************/
|
||||
|
||||
int Zoltan_ParMetis_Order(
|
||||
ZZ *zz, /* Zoltan structure */
|
||||
int num_obj, /* Number of (local) objects to order. */
|
||||
ZOLTAN_ID_PTR gids, /* List of global ids (local to this proc) */
|
||||
/* The application must allocate enough space */
|
||||
ZOLTAN_ID_PTR lids, /* List of local ids (local to this proc) */
|
||||
/* The application must allocate enough space */
|
||||
ZOLTAN_ID_PTR rank, /* rank[i] is the rank of gids[i] */
|
||||
int *iperm,
|
||||
ZOOS *order_opt /* Ordering options, parsed by Zoltan_Order */
|
||||
)
|
||||
{
|
||||
static char *yo = "Zoltan_ParMetis_Order";
|
||||
int i, n, ierr;
|
||||
ZOLTAN_Output_Order ord;
|
||||
ZOLTAN_Third_Graph gr;
|
||||
|
||||
#ifdef ZOLTAN_PARMETIS
|
||||
MPI_Comm comm = zz->Communicator;/* don't want to risk letting external
|
||||
packages changing our communicator */
|
||||
#endif
|
||||
indextype numflag = 0;
|
||||
|
||||
int timer_p = 0;
|
||||
int get_times = 0;
|
||||
int use_timers = 0;
|
||||
double times[5];
|
||||
|
||||
ZOLTAN_ID_PTR l_gids = NULL;
|
||||
ZOLTAN_ID_PTR l_lids = NULL;
|
||||
|
||||
indextype options[MAX_PARMETIS_OPTIONS];
|
||||
char alg[MAX_PARAM_STRING_LEN];
|
||||
|
||||
ZOLTAN_TRACE_ENTER(zz, yo);
|
||||
|
||||
#ifdef ZOLTAN_PARMETIS
|
||||
#if TPL_USE_DATATYPE != TPL_METIS_DATATYPES
|
||||
|
||||
#ifdef TPL_FLOAT_WEIGHT
|
||||
i = 1;
|
||||
#else
|
||||
i = 0;
|
||||
#endif
|
||||
|
||||
if ((sizeof(indextype) != sizeof(idxtype)) ||
|
||||
(sizeof(weighttype) != sizeof(idxtype)) || i){
|
||||
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL,
|
||||
"Not supported: Multiple 3rd party libraries with incompatible "
|
||||
"data types.");
|
||||
return ZOLTAN_FATAL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
memset(&gr, 0, sizeof(ZOLTAN_Third_Graph));
|
||||
memset(&ord, 0, sizeof(ZOLTAN_Output_Order));
|
||||
memset(times, 0, sizeof(times));
|
||||
|
||||
ord.order_opt = order_opt;
|
||||
|
||||
if (!order_opt){
|
||||
/* If for some reason order_opt is NULL, allocate a new ZOOS here. */
|
||||
/* This should really never happen. */
|
||||
order_opt = (ZOOS *) ZOLTAN_MALLOC(sizeof(ZOOS));
|
||||
strcpy(order_opt->method,"PARMETIS");
|
||||
}
|
||||
|
||||
ierr = Zoltan_Parmetis_Parse(zz, options, alg, NULL, NULL, &ord);
|
||||
/* ParMetis only computes the rank vector */
|
||||
order_opt->return_args = RETURN_RANK;
|
||||
|
||||
/* Check that num_obj equals the number of objects on this proc. */
|
||||
/* This constraint may be removed in the future. */
|
||||
n = zz->Get_Num_Obj(zz->Get_Num_Obj_Data, &ierr);
|
||||
if ((ierr!= ZOLTAN_OK) && (ierr!= ZOLTAN_WARN)){
|
||||
/* Return error code */
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Get_Num_Obj returned error.");
|
||||
return(ZOLTAN_FATAL);
|
||||
}
|
||||
if (n != num_obj){
|
||||
/* Currently this is a fatal error. */
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Input num_obj does not equal the "
|
||||
"number of objects.");
|
||||
return(ZOLTAN_FATAL);
|
||||
}
|
||||
|
||||
/* Do not use weights for ordering */
|
||||
gr.obj_wgt_dim = -1;
|
||||
gr.edge_wgt_dim = -1;
|
||||
gr.num_obj = num_obj;
|
||||
|
||||
/* Check what ordering type is requested */
|
||||
if (order_opt){
|
||||
SET_GLOBAL_GRAPH(&gr.graph_type); /* GLOBAL by default */
|
||||
|
||||
#ifdef ZOLTAN_PARMETIS
|
||||
if ((strcmp(order_opt->method, "METIS") == 0))
|
||||
#endif /* ZOLTAN_PARMETIS */
|
||||
SET_LOCAL_GRAPH(&gr.graph_type);
|
||||
}
|
||||
gr.get_data = 1;
|
||||
|
||||
if (IS_LOCAL_GRAPH(gr.graph_type) && zz->Num_Proc > 1) {
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Serial ordering on more than 1 process: "
|
||||
"set ParMetis instead.");
|
||||
return(ZOLTAN_FATAL);
|
||||
}
|
||||
|
||||
timer_p = Zoltan_Preprocess_Timer(zz, &use_timers);
|
||||
|
||||
/* Start timer */
|
||||
get_times = (zz->Debug_Level >= ZOLTAN_DEBUG_ATIME);
|
||||
if (get_times){
|
||||
MPI_Barrier(zz->Communicator);
|
||||
times[0] = Zoltan_Time(zz->Timer);
|
||||
}
|
||||
|
||||
ierr = Zoltan_Preprocess_Graph(zz, &l_gids, &l_lids, &gr, NULL, NULL, NULL);
|
||||
if ((ierr != ZOLTAN_OK) && (ierr != ZOLTAN_WARN)) {
|
||||
Zoltan_Third_Exit(&gr, NULL, NULL, NULL, NULL, NULL);
|
||||
return (ierr);
|
||||
}
|
||||
|
||||
/* Allocate space for separator sizes */
|
||||
|
||||
if (IS_GLOBAL_GRAPH(gr.graph_type)) {
|
||||
if (Zoltan_TPL_Order_Init_Tree(&zz->TPL_Order, 2*zz->Num_Proc, zz->Num_Proc) != ZOLTAN_OK) {
|
||||
/* Not enough memory */
|
||||
Zoltan_Third_Exit(&gr, NULL, NULL, NULL, NULL, &ord);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Out of memory.");
|
||||
}
|
||||
ord.sep_sizes = (indextype*)ZOLTAN_MALLOC((2*zz->Num_Proc+1)*sizeof(indextype));
|
||||
if (ord.sep_sizes == NULL) {
|
||||
Zoltan_Third_Exit(&gr, NULL, NULL, NULL, NULL, &ord);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Out of memory.");
|
||||
}
|
||||
memset(ord.sep_sizes, 0, (2*zz->Num_Proc+1)*sizeof(int)); /* It seems parmetis don't initialize correctly */
|
||||
}
|
||||
|
||||
/* Allocate space for direct perm */
|
||||
ord.rank = (indextype *) ZOLTAN_MALLOC(gr.num_obj*sizeof(indextype));
|
||||
if (!ord.rank){
|
||||
/* Not enough memory */
|
||||
Zoltan_Third_Exit(&gr, NULL, NULL, NULL, NULL, &ord);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Out of memory.");
|
||||
}
|
||||
if (IS_LOCAL_GRAPH(gr.graph_type)){
|
||||
/* Allocate space for inverse perm */
|
||||
ord.iperm = (indextype *) ZOLTAN_MALLOC(gr.num_obj*sizeof(indextype));
|
||||
if (!ord.iperm){
|
||||
/* Not enough memory */
|
||||
Zoltan_Third_Exit(&gr, NULL, NULL, NULL, NULL, &ord);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Out of memory.");
|
||||
}
|
||||
}
|
||||
else
|
||||
ord.iperm = NULL;
|
||||
|
||||
/* Get a time here */
|
||||
if (get_times) times[1] = Zoltan_Time(zz->Timer);
|
||||
|
||||
#ifdef ZOLTAN_PARMETIS
|
||||
if (IS_GLOBAL_GRAPH(gr.graph_type)){
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Calling the ParMETIS library");
|
||||
|
||||
ParMETIS_V3_NodeND (gr.vtxdist, gr.xadj, gr.adjncy,
|
||||
&numflag, options, ord.rank, ord.sep_sizes, &comm);
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Returned from the ParMETIS library");
|
||||
|
||||
}
|
||||
else
|
||||
#endif /* ZOLTAN_PARMETIS */
|
||||
#if defined(ZOLTAN_METIS) || defined(ZOLTAN_PARMETIS)
|
||||
if (IS_LOCAL_GRAPH(gr.graph_type)) { /* Be careful : permutation parameters are in the opposite order */
|
||||
indextype numobj = gr.num_obj;
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Calling the METIS library");
|
||||
order_opt->return_args = RETURN_RANK|RETURN_IPERM; /* We provide directly all the permutations */
|
||||
#if !defined(METIS_VER_MAJOR) || METIS_VER_MAJOR < 5
|
||||
options[0] = 0; /* Use default options for METIS. */
|
||||
METIS_NodeND(&numobj, gr.xadj, gr.adjncy, &numflag, options,
|
||||
ord.iperm, ord.rank);
|
||||
#else
|
||||
METIS_SetDefaultOptions(options);
|
||||
METIS_NodeND(&numobj, gr.xadj, gr.adjncy, NULL, options,
|
||||
ord.iperm, ord.rank); /* NULL is vwgt -- new interface in v4 */
|
||||
#endif
|
||||
|
||||
|
||||
ZOLTAN_TRACE_DETAIL(zz, yo, "Returned from the METIS library");
|
||||
}
|
||||
#endif /* ZOLTAN_METIS */
|
||||
|
||||
/* Get a time here */
|
||||
if (get_times) times[2] = Zoltan_Time(zz->Timer);
|
||||
|
||||
if (IS_GLOBAL_GRAPH(gr.graph_type)){ /* Update Elimination tree */
|
||||
int numbloc;
|
||||
int start;
|
||||
int leaf;
|
||||
int *converttab;
|
||||
int levelmax;
|
||||
|
||||
levelmax = mylog2(zz->Num_Proc) + 1;
|
||||
converttab = (int*)ZOLTAN_MALLOC(zz->Num_Proc*2*sizeof(int));
|
||||
|
||||
memset(converttab, 0, zz->Num_Proc*2*sizeof(int));
|
||||
/* Determine the first node in each separator, store it in zz->TPL_Order.start */
|
||||
for (numbloc = 0, start=0, leaf=0; numbloc < zz->Num_Proc /2; numbloc++) {
|
||||
int father;
|
||||
|
||||
father = zz->Num_Proc + numbloc;
|
||||
converttab[start] = 2*numbloc;
|
||||
zz->TPL_Order.leaves[leaf++]=start;
|
||||
zz->TPL_Order.ancestor[start] = start + 2;
|
||||
converttab[start+1] = 2*numbloc+1;
|
||||
zz->TPL_Order.leaves[leaf++]=start+1;
|
||||
zz->TPL_Order.ancestor[start+1] = start + 2;
|
||||
start+=2;
|
||||
do {
|
||||
converttab[start] = father;
|
||||
if (father %2 == 0) {
|
||||
int nextoffset;
|
||||
int level;
|
||||
|
||||
level = mylog2(2*zz->Num_Proc - 1 - father);
|
||||
nextoffset = (1<<(levelmax-level));
|
||||
zz->TPL_Order.ancestor[start] = start+nextoffset;
|
||||
start++;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
zz->TPL_Order.ancestor[start] = start+1;
|
||||
start++;
|
||||
father = zz->Num_Proc + father/2;
|
||||
}
|
||||
} while (father < 2*zz->Num_Proc - 1);
|
||||
}
|
||||
|
||||
zz->TPL_Order.start[0] = 0;
|
||||
zz->TPL_Order.ancestor [2*zz->Num_Proc - 2] = -1;
|
||||
for (numbloc = 1 ; numbloc < 2*zz->Num_Proc ; numbloc++) {
|
||||
int oldblock=converttab[numbloc-1];
|
||||
zz->TPL_Order.start[numbloc] = zz->TPL_Order.start[numbloc-1] + ord.sep_sizes[oldblock];
|
||||
}
|
||||
|
||||
ZOLTAN_FREE(&converttab);
|
||||
ZOLTAN_FREE(&ord.sep_sizes);
|
||||
|
||||
zz->TPL_Order.leaves[zz->Num_Proc] = -1;
|
||||
zz->TPL_Order.nbr_leaves = zz->Num_Proc;
|
||||
zz->TPL_Order.nbr_blocks = 2*zz->Num_Proc-1;
|
||||
}
|
||||
else { /* No tree */
|
||||
zz->TPL_Order.nbr_blocks = 0;
|
||||
zz->TPL_Order.start = NULL;
|
||||
zz->TPL_Order.ancestor = NULL;
|
||||
zz->TPL_Order.leaves = NULL;
|
||||
}
|
||||
|
||||
/* Correct because no redistribution */
|
||||
memcpy(gids, l_gids, n*zz->Num_GID*sizeof(ZOLTAN_ID_TYPE));
|
||||
memcpy(lids, l_lids, n*zz->Num_LID*sizeof(ZOLTAN_ID_TYPE));
|
||||
|
||||
ierr = Zoltan_Postprocess_Graph (zz, l_gids, l_lids, &gr, NULL, NULL, NULL, &ord, NULL);
|
||||
|
||||
ZOLTAN_FREE(&l_gids);
|
||||
ZOLTAN_FREE(&l_lids);
|
||||
|
||||
/* Get a time here */
|
||||
if (get_times) times[3] = Zoltan_Time(zz->Timer);
|
||||
|
||||
if (get_times) Zoltan_Third_DisplayTime(zz, times);
|
||||
|
||||
if (use_timers)
|
||||
ZOLTAN_TIMER_STOP(zz->ZTime, timer_p, zz->Communicator);
|
||||
|
||||
if (sizeof(indextype) == sizeof(ZOLTAN_ID_TYPE)){
|
||||
memcpy(rank, ord.rank, gr.num_obj*sizeof(indextype));
|
||||
}
|
||||
else{
|
||||
for (i=0; i < gr.num_obj; i++){
|
||||
rank[i] = (ZOLTAN_ID_TYPE)ord.rank[i];
|
||||
}
|
||||
}
|
||||
|
||||
if ((ord.iperm != NULL) && (iperm != NULL)){
|
||||
if (sizeof(indextype) == sizeof(int)){
|
||||
memcpy(iperm, ord.iperm, gr.num_obj*sizeof(indextype));
|
||||
}
|
||||
else{
|
||||
for (i=0; i < gr.num_obj; i++){
|
||||
iperm[i] = (int)ord.iperm[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ord.iperm != NULL) ZOLTAN_FREE(&ord.iperm);
|
||||
ZOLTAN_FREE(&ord.rank);
|
||||
|
||||
/* Free all other "graph" stuff */
|
||||
Zoltan_Third_Exit(&gr, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
ZOLTAN_TRACE_EXIT(zz, yo);
|
||||
|
||||
return (ZOLTAN_OK);
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* ParMetis parameter routine */
|
||||
/*********************************************************************/
|
||||
|
||||
int Zoltan_ParMetis_Set_Param(
|
||||
char *name, /* name of variable */
|
||||
char *val) /* value of variable */
|
||||
{
|
||||
int status, i;
|
||||
PARAM_UTYPE result; /* value returned from Check_Param */
|
||||
int index; /* index returned from Check_Param */
|
||||
char *valid_methods[] = {
|
||||
"PARTKWAY", "PARTGEOMKWAY", "PARTGEOM",
|
||||
"REPARTLDIFFUSION", "REPARTGDIFFUSION",
|
||||
"REPARTREMAP", "REPARTMLREMAP",
|
||||
"REFINEKWAY", "ADAPTIVEREPART",
|
||||
"NODEND", /* for nested dissection ordering */
|
||||
NULL };
|
||||
|
||||
status = Zoltan_Check_Param(name, val, Parmetis_params, &result, &index);
|
||||
|
||||
if (status == 0){
|
||||
/* OK so far, do sanity check of parameter values */
|
||||
|
||||
if (strcmp(name, "PARMETIS_METHOD") == 0){
|
||||
status = 2;
|
||||
for (i=0; valid_methods[i] != NULL; i++){
|
||||
if (strcmp(val, valid_methods[i]) == 0){
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
98
thirdParty/Zoltan/src/tpls/parmetis_interface.h
vendored
Normal file
98
thirdParty/Zoltan/src/tpls/parmetis_interface.h
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* @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 __PARMETIS_INTERFACE_H
|
||||
#define __PARMETIS_INTERFACE_H
|
||||
|
||||
#include <limits.h>
|
||||
#include "zoltan_comm.h"
|
||||
#include "third_library_const.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* if C++, define the rest of this header file as extern C */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Guess the version number of ParMetis if not defined */
|
||||
/* PARMETIS_MAJOR_VERSION is only defined in version 3.0 and higher */
|
||||
#if (!defined(PARMETIS_MAJOR_VERSION))
|
||||
#define PARMETIS_MAJOR_VERSION 0
|
||||
#define PARMETIS_MINOR_VERSION 0
|
||||
#endif
|
||||
|
||||
/* ParMetis option defs. These must be identical to the defs
|
||||
* in defs.h in the version of ParMetis you are using!
|
||||
* Both ParMetis 2.0 and 3.0 defs are included below.
|
||||
*/
|
||||
#define PMV3_OPTION_DBGLVL 1
|
||||
#define PMV3_OPTION_SEED 2
|
||||
#define PMV3_OPTION_IPART 3
|
||||
#define PMV3_OPTION_PSR 3
|
||||
#define PMV3_OPT_USE_OBJ_SIZE 9 /* Added by EB, not in ParMetis */
|
||||
#if (PARMETIS_MAJOR_VERSION < 4)
|
||||
#define MAX_PARMETIS_OPTIONS 40 /* Max number of options +1 */
|
||||
#else
|
||||
#define MAX_PARMETIS_OPTIONS METIS_NOPTIONS
|
||||
#endif
|
||||
/* Other ParMetis constants we may need */
|
||||
#define GLOBAL_DBGLVL 0 /* Default debug level */
|
||||
#define GLOBAL_SEED 15 /* Default random seed */
|
||||
#define COUPLED 1 /* Processors coupled to partitions? */
|
||||
#define DISCOUPLED 2 /* Processors coupled to partitions? */
|
||||
|
||||
|
||||
int Zoltan_ParMetis(
|
||||
ZZ *, float *, int *, ZOLTAN_ID_PTR *, ZOLTAN_ID_PTR *,
|
||||
int **, int **, int *, ZOLTAN_ID_PTR *, ZOLTAN_ID_PTR *,
|
||||
int **, int **);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* closing bracket for extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
74
thirdParty/Zoltan/src/tpls/parmetis_interface_params.h
vendored
Normal file
74
thirdParty/Zoltan/src/tpls/parmetis_interface_params.h
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* @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 __PARMETIS_INTERFACE_PARAMS_H
|
||||
#define __PARMETIS_INTERFACE_PARAMS_H
|
||||
|
||||
#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"
|
||||
#include "params_const.h"
|
||||
|
||||
/********** parameters structure for parmetis methods **********/
|
||||
static PARAM_VARS Parmetis_params[] = {
|
||||
{ "PARMETIS_METHOD", NULL, "STRING", 0 },
|
||||
{ "PARMETIS_OUTPUT_LEVEL", NULL, "INT", 0 },
|
||||
{ "PARMETIS_SEED", NULL, "INT", 0 },
|
||||
{ "PARMETIS_ITR", NULL, "DOUBLE", 0 },
|
||||
{ "PARMETIS_COARSE_ALG", NULL, "INT", 0 },
|
||||
{ "PARMETIS_FOLD", NULL, "INT", 0 },
|
||||
{ NULL, NULL, NULL, 0 } };
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
774
thirdParty/Zoltan/src/tpls/postprocessing.c
vendored
Normal file
774
thirdParty/Zoltan/src/tpls/postprocessing.c
vendored
Normal file
@ -0,0 +1,774 @@
|
||||
/*
|
||||
* @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
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include "zz_const.h"
|
||||
#include "zz_util_const.h"
|
||||
#include "all_allo_const.h"
|
||||
#include "params_const.h"
|
||||
#include "order_const.h"
|
||||
#include "third_library.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* if C++, define the rest of this header file as extern C */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Auxiliary function prototypes. */
|
||||
static int
|
||||
Zoltan_Postprocess_UnScatter_Graph (ZZ *zz,
|
||||
ZOLTAN_Third_Graph *gr,
|
||||
ZOLTAN_Third_Part *prt,
|
||||
indextype **rank);
|
||||
static int
|
||||
Zoltan_Postprocess_Order (ZZ *zz,
|
||||
ZOLTAN_Third_Graph *gr,
|
||||
ZOLTAN_Output_Order *ord);
|
||||
|
||||
static int
|
||||
Zoltan_Postprocess_Partition (ZZ *zz,
|
||||
ZOLTAN_Third_Graph *gr,
|
||||
ZOLTAN_Third_Part *prt,
|
||||
ZOLTAN_Output_Part *part,
|
||||
ZOLTAN_ID_PTR global_ids,
|
||||
ZOLTAN_ID_PTR local_ids);
|
||||
|
||||
static int Compute_Bal(ZZ *, int, weighttype *, int, indextype *, double *);
|
||||
static int Compute_EdgeCut(ZZ *, int, indextype *, float *, indextype *, int *, double *);
|
||||
static float Compute_NetCut(ZZ *, int, indextype *, float *, indextype *, int *);
|
||||
static float Compute_ConCut(ZZ *, int, indextype *, float *, indextype *, int *);
|
||||
static int Compute_Adjpart(ZZ *, int, indextype *, indextype *, indextype *, int *, indextype *, int *);
|
||||
|
||||
|
||||
|
||||
int Zoltan_Postprocess_Graph(
|
||||
ZZ *zz, /* Zoltan structure */
|
||||
ZOLTAN_ID_PTR global_ids,
|
||||
ZOLTAN_ID_PTR local_ids,
|
||||
ZOLTAN_Third_Graph *gr, /* Graph for third part libs */
|
||||
ZOLTAN_Third_Geom *geo,
|
||||
ZOLTAN_Third_Part *prt,
|
||||
ZOLTAN_Third_Vsize *vsp,
|
||||
ZOLTAN_Output_Order *ord,
|
||||
ZOLTAN_Output_Part *part)
|
||||
{
|
||||
int ierr = ZOLTAN_OK;
|
||||
|
||||
static char * yo = "Zoltan_Postprocess_Graph";
|
||||
|
||||
if (gr->scatter > 0) { /* Graph has been scattered */
|
||||
indextype *rank = NULL;
|
||||
|
||||
if (ord) rank = ord->rank;
|
||||
else rank = NULL;
|
||||
ierr = Zoltan_Postprocess_UnScatter_Graph (zz, gr, prt, &rank);
|
||||
if (ierr) {
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL,
|
||||
"Error returned from Zoltan_Postprocess_UnScatter_Graph");
|
||||
}
|
||||
if (ord) ord->rank = rank;
|
||||
}
|
||||
|
||||
if (ord) { /* We have done ordering */
|
||||
ierr = Zoltan_Postprocess_Order (zz, gr, ord);
|
||||
if (ierr == ZOLTAN_FATAL) {
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL,
|
||||
"Error returned from Zoltan_Postprocess_Order");
|
||||
}
|
||||
}
|
||||
|
||||
if (part) { /* We have done partitioning */
|
||||
ierr = Zoltan_Postprocess_Partition (zz, gr, prt, part, global_ids, local_ids);
|
||||
if (ierr == ZOLTAN_FATAL) {
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL,
|
||||
"Error returned from Zoltan_Postprocess_Partition");
|
||||
}
|
||||
}
|
||||
|
||||
return (ierr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
Zoltan_Postprocess_UnScatter_Graph (ZZ *zz,
|
||||
ZOLTAN_Third_Graph *gr,
|
||||
ZOLTAN_Third_Part *prt,
|
||||
indextype **rank)
|
||||
{
|
||||
static char * yo = "Zoltan_Postprocess_UnScatter_Graph";
|
||||
|
||||
int ierr = ZOLTAN_FATAL;
|
||||
indextype *src;
|
||||
indextype *dst;
|
||||
|
||||
if (gr->scatter >0){
|
||||
gr->num_obj = gr->num_obj_orig;
|
||||
if (*rank) { /* We have to project back rank */
|
||||
dst = (indextype*) ZOLTAN_MALLOC(gr->num_obj*sizeof(indextype));
|
||||
src = *rank;
|
||||
}
|
||||
else {
|
||||
dst = prt->part_orig;
|
||||
src = prt->part;
|
||||
}
|
||||
|
||||
ierr = Zoltan_Comm_Do_Reverse(gr->comm_plan, TAG2, (char *) src,
|
||||
sizeof(indextype), NULL, (char *) dst);
|
||||
if ((ierr == ZOLTAN_FATAL) || (ierr == ZOLTAN_MEMERR)){
|
||||
ZOLTAN_THIRD_ERROR(ierr, "Zoltan_Comm_Do_Reverse returned error.");
|
||||
}
|
||||
Zoltan_Comm_Destroy(&gr->comm_plan); /* Destroy the comm. plan */
|
||||
/* We don't need the partition array with the scattered distribution
|
||||
* any more */
|
||||
ZOLTAN_FREE(&src);
|
||||
if (prt) {
|
||||
/* part is now the new partition array under the original distribution */
|
||||
prt->part = prt->part_orig;
|
||||
prt->part_orig = NULL;
|
||||
}
|
||||
else {
|
||||
*rank = dst;
|
||||
}
|
||||
|
||||
}
|
||||
return (ierr);
|
||||
}
|
||||
|
||||
static int
|
||||
Zoltan_Postprocess_Order (ZZ *zz,
|
||||
ZOLTAN_Third_Graph *gr,
|
||||
ZOLTAN_Output_Order *ord)
|
||||
{
|
||||
int ierr = ZOLTAN_OK;
|
||||
int i;
|
||||
const char *yo = "Zoltan_Postprocess_Order";
|
||||
|
||||
/* Ordering */
|
||||
/* ParMetis produces the rank vector in Zoltan lingo */
|
||||
|
||||
if (ord->rank != NULL) {
|
||||
/* Check if start_index != 0 */
|
||||
if (ord->order_opt && ord->order_opt->start_index) {
|
||||
int start_index;
|
||||
|
||||
start_index = ord->order_opt->start_index;
|
||||
for (i=0; i<gr->num_obj; i++){
|
||||
ord->rank[i] += start_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ZOLTAN_PRINT_WARN(zz->Proc, yo, "rank is NULL, no data returned");
|
||||
ierr = ZOLTAN_WARN;
|
||||
}
|
||||
|
||||
/* If we did local ordering via METIS, then we also have the inv. perm. */
|
||||
if ((gr->graph_type == LOCAL_GRAPH) && (ord->iperm != NULL)){
|
||||
int start_index;
|
||||
|
||||
start_index = ord->order_opt->start_index;
|
||||
for (i=0; i<gr->num_obj; i++){
|
||||
ord->iperm[i] += start_index;
|
||||
}
|
||||
/* EBEB: Return parameter that says we have computed both return args? */
|
||||
}
|
||||
|
||||
/* Fill in the Zoltan Order Struct */
|
||||
/* EBEB: For now, discard separator info */
|
||||
if (0){ /* DEBUG: Print separator sizes to file */
|
||||
FILE *fp;
|
||||
fp = fopen("separators.txt", "w");
|
||||
fprintf(fp, "%i\n", ord->num_part);
|
||||
for (i=0; i<ord->num_part; ++i){
|
||||
fprintf(fp, TPL_IDX_SPEC " ", ord->sep_sizes[i]);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
for (i=ord->num_part; i<2*ord->num_part-1; ++i){
|
||||
fprintf(fp, TPL_IDX_SPEC " ", ord->sep_sizes[i]);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return (ierr);
|
||||
}
|
||||
|
||||
static int
|
||||
Zoltan_Postprocess_Partition (ZZ *zz,
|
||||
ZOLTAN_Third_Graph *gr,
|
||||
ZOLTAN_Third_Part *prt,
|
||||
ZOLTAN_Output_Part *part,
|
||||
ZOLTAN_ID_PTR global_ids,
|
||||
ZOLTAN_ID_PTR local_ids)
|
||||
{
|
||||
static char * yo = "Zoltan_Postprocess_Partition";
|
||||
|
||||
int ierr = ZOLTAN_OK;
|
||||
int i, j, nsend;
|
||||
int *newproc, *tmp_part, *tmp_input_part;
|
||||
|
||||
int num_gid_entries = zz->Num_GID;
|
||||
int num_lid_entries = zz->Num_LID;
|
||||
|
||||
/* Partitioning */
|
||||
/* Determine new processor and number of objects to export */
|
||||
newproc = (int *) ZOLTAN_MALLOC(gr->num_obj * sizeof(int));
|
||||
if (gr->num_obj && !newproc){
|
||||
/* Not enough memory */
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Out of memory. ");
|
||||
}
|
||||
for (i=0; i<gr->num_obj; i++){
|
||||
newproc[i] = Zoltan_LB_Part_To_Proc(zz, (int)prt->part[i],
|
||||
&(global_ids[i*num_gid_entries]));
|
||||
if (newproc[i]<0){
|
||||
ZOLTAN_FREE(&newproc);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL,
|
||||
"Zoltan_LB_Part_To_Proc returned invalid processor number.");
|
||||
}
|
||||
}
|
||||
|
||||
if (zz->LB.Remap_Flag) {
|
||||
int new_map;
|
||||
|
||||
if (sizeof(indextype) == sizeof(int)){
|
||||
ierr = Zoltan_LB_Remap(zz, &new_map, gr->num_obj, newproc, (int *)prt->input_part,
|
||||
(int *)prt->part, 1);
|
||||
}
|
||||
else{
|
||||
tmp_part = (int *)ZOLTAN_MALLOC(sizeof(int) * gr->num_obj);
|
||||
tmp_input_part = (int *)ZOLTAN_MALLOC(sizeof(int) * gr->num_obj);
|
||||
|
||||
if (gr->num_obj && (!tmp_part || !tmp_input_part)){
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Not enough memory.");
|
||||
}
|
||||
for (i=0; i < gr->num_obj; i++){
|
||||
tmp_part[i] = (int)prt->part[i];
|
||||
tmp_input_part[i] = (int)prt->input_part[i];
|
||||
}
|
||||
ierr = Zoltan_LB_Remap(zz, &new_map, gr->num_obj, newproc, tmp_input_part, tmp_part, 1);
|
||||
|
||||
for (i=0; i < gr->num_obj; i++){
|
||||
prt->part[i] = (indextype)tmp_part[i];
|
||||
prt->input_part[i] = (indextype)tmp_input_part[i];
|
||||
}
|
||||
|
||||
ZOLTAN_FREE(&tmp_part);
|
||||
ZOLTAN_FREE(&tmp_input_part);
|
||||
}
|
||||
|
||||
if (ierr < 0) {
|
||||
ZOLTAN_FREE(&newproc);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL,
|
||||
"Error returned from Zoltan_LB_Remap");
|
||||
}
|
||||
}
|
||||
|
||||
nsend = 0;
|
||||
for (i=0; i<gr->num_obj; i++){
|
||||
if ((prt->part[i] != prt->input_part[i]) || ((!part->compute_only_part_changes) &&
|
||||
(newproc[i] != zz->Proc)))
|
||||
nsend++;
|
||||
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL)
|
||||
printf("[%1d] DEBUG: local object %1d: old part = " TPL_IDX_SPEC ", new part = " TPL_IDX_SPEC "\n",
|
||||
zz->Proc, i, prt->input_part[i], prt->part[i]);
|
||||
}
|
||||
|
||||
/* Create export lists */
|
||||
if (zz->LB.Return_Lists){
|
||||
if (zz->LB.Return_Lists == ZOLTAN_LB_CANDIDATE_LISTS) {
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_FATAL, "Candidate Lists not supported in GRAPH;"
|
||||
"change RETURN_LISTS parameter.");
|
||||
}
|
||||
part->num_exp = nsend;
|
||||
if (nsend > 0) {
|
||||
if (!Zoltan_Special_Malloc(zz,(void **)part->exp_gids,nsend,ZOLTAN_SPECIAL_MALLOC_GID)) {
|
||||
ZOLTAN_FREE(&newproc);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Not enough memory.");
|
||||
}
|
||||
if (!Zoltan_Special_Malloc(zz,(void **)part->exp_lids,nsend,ZOLTAN_SPECIAL_MALLOC_LID)) {
|
||||
Zoltan_Special_Free(zz,(void **)part->exp_gids,ZOLTAN_SPECIAL_MALLOC_GID);
|
||||
ZOLTAN_FREE(&newproc);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Not enough memory.");
|
||||
}
|
||||
if (!Zoltan_Special_Malloc(zz,(void **)part->exp_procs,nsend,ZOLTAN_SPECIAL_MALLOC_INT)) {
|
||||
Zoltan_Special_Free(zz,(void **)part->exp_lids,ZOLTAN_SPECIAL_MALLOC_LID);
|
||||
Zoltan_Special_Free(zz,(void **)part->exp_gids,ZOLTAN_SPECIAL_MALLOC_GID);
|
||||
ZOLTAN_FREE(&newproc);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Not enough memory.");
|
||||
}
|
||||
if (!Zoltan_Special_Malloc(zz,(void **)part->exp_part,nsend,ZOLTAN_SPECIAL_MALLOC_INT)) {
|
||||
Zoltan_Special_Free(zz,(void **)part->exp_lids,ZOLTAN_SPECIAL_MALLOC_LID);
|
||||
Zoltan_Special_Free(zz,(void **)part->exp_gids,ZOLTAN_SPECIAL_MALLOC_GID);
|
||||
Zoltan_Special_Free(zz,(void **)part->exp_procs,ZOLTAN_SPECIAL_MALLOC_INT);
|
||||
ZOLTAN_FREE(&newproc);
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Not enough memory.");
|
||||
}
|
||||
j = 0;
|
||||
for (i=0; i<gr->num_obj; i++){
|
||||
if ((prt->part[i] != prt->input_part[i]) || ((!part->compute_only_part_changes)
|
||||
&& (newproc[i] != zz->Proc))){
|
||||
/* Object should move to new partition or processor */
|
||||
ZOLTAN_SET_GID(zz, &((*(part->exp_gids))[j*num_gid_entries]),
|
||||
&(global_ids[i*num_gid_entries]));
|
||||
if (num_lid_entries)
|
||||
ZOLTAN_SET_LID(zz, &((*(part->exp_lids))[j*num_lid_entries]),
|
||||
&(local_ids[i*num_lid_entries]));
|
||||
(*(part->exp_part))[j] = (int)prt->part[i];
|
||||
(*(part->exp_procs))[j] = newproc[i];
|
||||
/* printf("[%1d] Debug: Move object %1d to part %1d, proc %1d\n", */
|
||||
/* zz->Proc, i, prt->part[i], newproc[i]); */
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ZOLTAN_FREE(&newproc);
|
||||
|
||||
return (ZOLTAN_OK);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Zoltan_Postprocess_FinalOutput (ZZ* zz, ZOLTAN_Third_Graph *gr,
|
||||
ZOLTAN_Third_Part *prt, ZOLTAN_Third_Vsize *vsp,
|
||||
int use_timers, realtype itr)
|
||||
{
|
||||
#define FOMAXDIM 10
|
||||
static char * yo = "Zoltan_Postprocess_FinalOutput";
|
||||
static int nRuns=0;
|
||||
static double balsum[FOMAXDIM], cutesum[FOMAXDIM];
|
||||
static double balmax[FOMAXDIM], cutemax[FOMAXDIM];
|
||||
static double balmin[FOMAXDIM], cutemin[FOMAXDIM];
|
||||
/* following variables are defined double to avoid overflow */
|
||||
static double cutlsum = 0.0, cutnsum = 0.0, movesum = 0.0, repartsum = 0.0;
|
||||
static float cutlmax = 0, cutnmax = 0;
|
||||
static double movemax = 0, repartmax = 0;
|
||||
static float cutlmin = (float)INT_MAX, cutnmin = (float)INT_MAX;
|
||||
static double movemin = 1e100, repartmin = 1e100;
|
||||
static int timer_final_output = -1;
|
||||
double bal[FOMAXDIM]; /* Balance: max / avg */
|
||||
double cute[FOMAXDIM]; /* Traditional weighted graph edge cuts */
|
||||
float cutl; /* Connnectivity cuts: sum_over_edges((npart-1)) */
|
||||
float cutn; /* Net cuts: sum_over_edges((nparts>1)) */
|
||||
double move = 0.0, gmove =0.0; /* migration cost */
|
||||
double repart; /* total repartitioning cost; cutl x multiplier + move */
|
||||
int *adjpart = NULL;
|
||||
int vdim;
|
||||
int edim;
|
||||
indextype *vsizeBACKUP = NULL;
|
||||
indextype *input_part;
|
||||
int i,rc;
|
||||
|
||||
/* #define UVC_DORUK_COMP_OBJSIZE */
|
||||
#ifdef UVC_DORUK_COMP_OBJSIZE
|
||||
double minD, maxD, gminD, gmaxD;
|
||||
#endif
|
||||
if (use_timers) {
|
||||
if (timer_final_output < 0)
|
||||
timer_final_output = Zoltan_Timer_Init(zz->ZTime, 1, "Final_Output");
|
||||
ZOLTAN_TIMER_START(zz->ZTime, timer_final_output, zz->Communicator);
|
||||
}
|
||||
if (nRuns == 0) {
|
||||
for (i = 0; i < FOMAXDIM; i++) {
|
||||
/* Initialize first time */
|
||||
balsum[i] = cutesum[i] = 0.0;
|
||||
balmax[i] = cutemax[i] = 0.0;
|
||||
balmin[i] = cutemin[i] = 1e100;
|
||||
}
|
||||
}
|
||||
|
||||
if (vsp && vsp->vsizeBACKUP)
|
||||
vsizeBACKUP = vsp->vsizeBACKUP;
|
||||
vdim = MAX(gr->obj_wgt_dim,1);
|
||||
edim = MAX(zz->Edge_Weight_Dim,1);
|
||||
|
||||
if (gr->obj_wgt_dim < FOMAXDIM && zz->Edge_Weight_Dim < FOMAXDIM) {
|
||||
if (gr->xadj[gr->num_obj]){
|
||||
adjpart = (int *) ZOLTAN_MALLOC(gr->xadj[gr->num_obj] * sizeof(int));
|
||||
if (!adjpart){
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR,
|
||||
"Error 1 returned from Zoltan_Postprocess_FinalOutput");
|
||||
}
|
||||
}
|
||||
|
||||
Compute_Bal(zz, gr->num_obj, gr->vwgt, gr->obj_wgt_dim, prt->part, bal);
|
||||
|
||||
rc = Compute_Adjpart(zz, gr->num_obj, gr->vtxdist, gr->xadj, gr->adjncy,
|
||||
gr->adjproc, prt->part, adjpart);
|
||||
|
||||
if (rc != ZOLTAN_OK){
|
||||
ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR,
|
||||
"Error 2 returned from Zoltan_Postprocess_FinalOutput");
|
||||
}
|
||||
Compute_EdgeCut(zz, gr->num_obj, gr->xadj, gr->float_ewgts,
|
||||
prt->part, adjpart, cute);
|
||||
cutl = Compute_ConCut(zz, gr->num_obj, gr->xadj, gr->float_ewgts,
|
||||
prt->part, adjpart);
|
||||
cutn = Compute_NetCut(zz, gr->num_obj, gr->xadj, gr->float_ewgts,
|
||||
prt->part, adjpart);
|
||||
|
||||
#ifdef UVC_DORUK_COMP_OBJSIZE
|
||||
if (vsizeBACKUP) {
|
||||
minD = vsizeBACKUP[0];
|
||||
maxD = vsizeBACKUP[0];
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gr->scatter != 0) { /* Project input part in the scatter graph */
|
||||
input_part = (indextype*) ZOLTAN_MALLOC(gr->num_obj * sizeof(int));
|
||||
Zoltan_Comm_Do(gr->comm_plan, TAG1, (char *) prt->input_part, sizeof(indextype),
|
||||
(char *) input_part);
|
||||
}
|
||||
else
|
||||
input_part = prt->input_part;
|
||||
|
||||
for (i=0; i<gr->num_obj; i++) {
|
||||
/*printf("obj[%d] = %d\n", i, vsize[i]);*/
|
||||
if (prt->part[i] != input_part[i]) {
|
||||
move += (double) ((vsizeBACKUP) ? vsizeBACKUP[i] : 1.0);
|
||||
}
|
||||
#ifdef UVC_DORUK_COMP_OBJSIZE
|
||||
if (vsizeBACKUP) {
|
||||
minD = minD < vsizeBACKUP[i] ? minD : vsizeBACKUP[i];
|
||||
maxD = maxD > vsizeBACKUP[i] ? maxD : vsizeBACKUP[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (gr->scatter != 0)
|
||||
ZOLTAN_FREE(&input_part);
|
||||
|
||||
#ifdef UVC_DORUK_COMP_OBJSIZE
|
||||
if (gr->showMoveVol) {
|
||||
MPI_Allreduce(&minD, &gminD, 1, MPI_DOUBLE, MPI_MIN, zz->Communicator);
|
||||
MPI_Allreduce(&maxD, &gmaxD, 1, MPI_DOUBLE, MPI_MAX, zz->Communicator);
|
||||
|
||||
if (zz->Proc == 0)
|
||||
printf("minD: %f, maxD: %f, gminD: %f, gmaxD: %f\n", minD, maxD, gminD, gmaxD);
|
||||
}
|
||||
#endif
|
||||
|
||||
MPI_Allreduce(&move, &gmove, 1, MPI_DOUBLE, MPI_SUM, zz->Communicator);
|
||||
|
||||
repart = (itr) * (double) cutl + gmove;
|
||||
repartsum += repart;
|
||||
if (repart > repartmax) repartmax = repart;
|
||||
if (repart < repartmin) repartmin = repart;
|
||||
movesum += gmove;
|
||||
if (gmove > movemax) movemax = gmove;
|
||||
if (gmove < movemin) movemin = gmove;
|
||||
cutlsum += cutl;
|
||||
if (cutl > cutlmax) cutlmax = cutl;
|
||||
if (cutl < cutlmin) cutlmin = cutl;
|
||||
cutnsum += cutn;
|
||||
if (cutn > cutnmax) cutnmax = cutn;
|
||||
if (cutn < cutnmin) cutnmin = cutn;
|
||||
for (i = 0; i < vdim; i++) {
|
||||
balsum[i] += bal[i];
|
||||
if (bal[i] > balmax[i]) balmax[i] = bal[i];
|
||||
if (bal[i] < balmin[i]) balmin[i] = bal[i];
|
||||
}
|
||||
for (i = 0; i < edim; i++) {
|
||||
cutesum[i] += cute[i];
|
||||
if (cute[i] > cutemax[i]) cutemax[i] = cute[i];
|
||||
if (cute[i] < cutemin[i]) cutemin[i] = cute[i];
|
||||
}
|
||||
nRuns++;
|
||||
|
||||
if (zz->Proc == 0) {
|
||||
for (i = 0; i < vdim; i++)
|
||||
printf("STATS Runs %d bal[%d] CURRENT %f MAX %f MIN %f AVG %f\n",
|
||||
nRuns, i, bal[i], balmax[i], balmin[i], balsum[i]/nRuns);
|
||||
printf("STATS Runs %d cutl CURRENT %f MAX %f MIN %f AVG %f\n",
|
||||
nRuns, cutl, cutlmax, cutlmin, cutlsum/nRuns);
|
||||
printf("STATS Runs %d cutn CURRENT %f MAX %f MIN %f AVG %f\n",
|
||||
nRuns, cutn, cutnmax, cutnmin, cutnsum/nRuns);
|
||||
for (i = 0; i < edim; i++)
|
||||
printf("STATS Runs %d cute[%d] CURRENT %f MAX %f MIN %f AVG %f\n",
|
||||
nRuns, i, cute[i], cutemax[i], cutemin[i], cutesum[i]/nRuns);
|
||||
printf("STATS Runs %d %s CURRENT %f MAX %f MIN %f AVG %f\n",
|
||||
nRuns, gr->showMoveVol ? "moveVol" : "moveCnt", gmove,
|
||||
movemax, movemin, movesum/nRuns);
|
||||
if (gr->showMoveVol)
|
||||
printf("STATS Runs %d repart CURRENT %f MAX %f MIN %f AVG %f\n",
|
||||
nRuns, repart, repartmax, repartmin, repartsum/nRuns);
|
||||
}
|
||||
ZOLTAN_FREE(&adjpart);
|
||||
}
|
||||
#undef FOMAXDIM
|
||||
if (use_timers)
|
||||
ZOLTAN_TIMER_STOP(zz->ZTime, timer_final_output, zz->Communicator);
|
||||
|
||||
return (ZOLTAN_OK);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
static int Compute_Bal(
|
||||
ZZ *zz,
|
||||
int nvtx,
|
||||
weighttype *vwgts,
|
||||
int obj_wgt_dim,
|
||||
indextype *parts,
|
||||
double *bal
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Compute the load balance of the computed partition.
|
||||
*/
|
||||
int i, j;
|
||||
int dim = MAX(obj_wgt_dim, 1);
|
||||
int size;
|
||||
float *sum = NULL, *gsum = NULL;
|
||||
float *tot = NULL, *max = NULL;
|
||||
|
||||
size = zz->LB.Num_Global_Parts * dim;
|
||||
sum = (float *) ZOLTAN_CALLOC(2 * size, sizeof(float));
|
||||
gsum = sum + size;
|
||||
tot = (float *) ZOLTAN_CALLOC(2 * dim, sizeof(float));
|
||||
max = tot + dim;
|
||||
|
||||
for (i = 0; i < nvtx; i++)
|
||||
for (j = 0; j < dim; j++)
|
||||
sum[parts[i]*dim + j] += (vwgts ? vwgts[i*dim + j] : 1.);
|
||||
|
||||
MPI_Allreduce(sum, gsum, size, MPI_FLOAT, MPI_SUM, zz->Communicator);
|
||||
|
||||
for (i = 0; i < zz->LB.Num_Global_Parts; i++)
|
||||
for (j = 0; j < dim; j++) {
|
||||
tot[j] += gsum[i*dim+j];
|
||||
if (gsum[i*dim+j] > max[j]) max[j] = gsum[i*dim+j];
|
||||
}
|
||||
|
||||
for (j = 0; j < dim; j++)
|
||||
if (tot[j] > 0.)
|
||||
bal[j] = zz->LB.Num_Global_Parts * max[j] / tot[j];
|
||||
|
||||
ZOLTAN_FREE(&sum);
|
||||
ZOLTAN_FREE(&tot);
|
||||
|
||||
return ZOLTAN_OK;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static int Compute_EdgeCut(
|
||||
ZZ *zz,
|
||||
int nvtx,
|
||||
indextype *xadj,
|
||||
float *ewgts,
|
||||
indextype *parts,
|
||||
int *nborparts,
|
||||
double *cute
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Compute total weight of cut graph edges w.r.t. partitions.
|
||||
*/
|
||||
indextype i, j, k;
|
||||
int dim = MAX(zz->Edge_Weight_Dim, 1);
|
||||
double *cut = NULL;
|
||||
|
||||
cut = (double *) ZOLTAN_CALLOC(dim, sizeof(double));
|
||||
|
||||
for (i = 0; i < nvtx; i++)
|
||||
for (j = xadj[i]; j < xadj[i+1]; j++)
|
||||
if (parts[i] != nborparts[j])
|
||||
for (k = 0; k < dim; k++)
|
||||
cut[k] += (ewgts ? ewgts[j*dim+k] : 1.);
|
||||
|
||||
MPI_Allreduce(cut, cute, dim, MPI_DOUBLE, MPI_SUM, zz->Communicator);
|
||||
ZOLTAN_FREE(&cut);
|
||||
return ZOLTAN_OK;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static float Compute_NetCut(
|
||||
ZZ *zz,
|
||||
int nvtx,
|
||||
indextype *xadj,
|
||||
float *ewgts,
|
||||
indextype *parts,
|
||||
int *nborparts
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Compute weight of hyperedges cut w.r.t. partitions.
|
||||
* Assume one hyperedge per vertex.
|
||||
* Equivalent to number of boundary vertices weighted by edge weights.
|
||||
*/
|
||||
indextype i, j;
|
||||
float cutn = 0., gcutn = 0.;
|
||||
int dim = zz->Edge_Weight_Dim;
|
||||
|
||||
for (i = 0; i < nvtx; i++) {
|
||||
|
||||
/* Compute the maximum graph edge weight of all edges incident to vertex */
|
||||
/* For now, use only first weight per edge. */
|
||||
float maxewgt = 0.;
|
||||
if (ewgts)
|
||||
for (j = xadj[i]; j < xadj[i+1]; j++)
|
||||
if (ewgts[j*dim] > maxewgt) maxewgt = ewgts[j*dim];
|
||||
|
||||
for (j = xadj[i]; j < xadj[i+1]; j++)
|
||||
if (parts[i] != nborparts[j]) {
|
||||
cutn += (ewgts ? maxewgt : 1.);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MPI_Allreduce(&cutn, &gcutn, 1, MPI_FLOAT, MPI_SUM, zz->Communicator);
|
||||
|
||||
return gcutn;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static float Compute_ConCut(
|
||||
ZZ *zz,
|
||||
int nvtx,
|
||||
indextype *xadj,
|
||||
float *ewgts,
|
||||
indextype *parts,
|
||||
int *nborparts
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Compute SUM over hyperedges( (#parts/hyperedge - 1)*ewgt);
|
||||
* Assume one hyperedge per vertex.
|
||||
*/
|
||||
indextype i, j;
|
||||
float cutl = 0., gcutl = 0.;
|
||||
indextype *used = NULL;
|
||||
int dim = zz->Edge_Weight_Dim;
|
||||
|
||||
used = (indextype *) ZOLTAN_MALLOC(zz->LB.Num_Global_Parts * sizeof(indextype));
|
||||
for (i = 0; i < zz->LB.Num_Global_Parts; i++) used[i] = -1;
|
||||
|
||||
for (i = 0; i < nvtx; i++) {
|
||||
/* Compute the maximum graph edge weight of all edges incident to vertex */
|
||||
/* For now, use only first weight per edge. */
|
||||
float maxewgt = 0.;
|
||||
if (ewgts)
|
||||
for (j = xadj[i]; j < xadj[i+1]; j++)
|
||||
if (ewgts[j*dim] > maxewgt) maxewgt = ewgts[j*dim];
|
||||
|
||||
used[parts[i]] = i;
|
||||
for (j = xadj[i]; j < xadj[i+1]; j++)
|
||||
if (used[nborparts[j]] < i) {
|
||||
used[nborparts[j]] = i;
|
||||
cutl += (ewgts ? maxewgt : 1.);
|
||||
}
|
||||
}
|
||||
ZOLTAN_FREE(&used);
|
||||
|
||||
MPI_Allreduce(&cutl, &gcutl, 1, MPI_FLOAT, MPI_SUM, zz->Communicator);
|
||||
|
||||
return gcutl;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static int Compute_Adjpart(
|
||||
ZZ *zz,
|
||||
int nvtx, /* Input: # vtxs in this processor */
|
||||
indextype *vtxdist, /* Input: Distribution of vertices across processors */
|
||||
indextype *xadj, /* Input: Index of adjncy: adjncy[xadj[i]] to
|
||||
adjncy[xadj[i]+1] are all edge nbors of vtx i. */
|
||||
indextype *adjncy, /* Input: Array of nbor vertices. */
|
||||
int *adjproc, /* Input: adjproc[j] == processor owning adjncy[j]. */
|
||||
indextype *part, /* Input: Partition assignments of vtxs. */
|
||||
int *adjpart /* Output: adjpart[j] == partition owning adjncy[j] */
|
||||
)
|
||||
{
|
||||
/* Given an adjacency list adjncy, find the partition number of each
|
||||
* vertex in adjncy. Return it in adjpart.
|
||||
*/
|
||||
ZOLTAN_COMM_OBJ *plan;
|
||||
int i;
|
||||
indextype start = vtxdist[zz->Proc]; /* First vertex on this processor */
|
||||
indextype *recv_gno= NULL;
|
||||
int *send_int=NULL;
|
||||
int nrecv;
|
||||
int tag = 24542;
|
||||
|
||||
Zoltan_Comm_Create(&plan, (int)xadj[nvtx], adjproc, zz->Communicator, tag++, &nrecv);
|
||||
|
||||
if (nrecv){
|
||||
recv_gno = (indextype *) ZOLTAN_MALLOC(nrecv * sizeof(indextype));
|
||||
send_int = (int *) ZOLTAN_MALLOC(nrecv * sizeof(int));
|
||||
if (!recv_gno || !send_int) {
|
||||
Zoltan_Comm_Destroy(&plan);
|
||||
ZOLTAN_FREE(&recv_gno);
|
||||
ZOLTAN_FREE(&send_int);
|
||||
return ZOLTAN_MEMERR;
|
||||
}
|
||||
}
|
||||
|
||||
Zoltan_Comm_Do(plan, tag++, (char *) adjncy, sizeof(indextype), (char *) recv_gno);
|
||||
|
||||
for (i = 0; i < nrecv; i++){
|
||||
send_int[i] = part[recv_gno[i] - start];
|
||||
}
|
||||
|
||||
ZOLTAN_FREE(&recv_gno);
|
||||
|
||||
Zoltan_Comm_Do_Reverse(plan, tag, (char *)send_int, sizeof(int), NULL, (char *) adjpart);
|
||||
|
||||
ZOLTAN_FREE(&send_int);
|
||||
|
||||
Zoltan_Comm_Destroy(&plan);
|
||||
|
||||
return ZOLTAN_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
1158
thirdParty/Zoltan/src/tpls/preprocessing.c
vendored
Normal file
1158
thirdParty/Zoltan/src/tpls/preprocessing.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
305
thirdParty/Zoltan/src/tpls/scatter_graph.c
vendored
Normal file
305
thirdParty/Zoltan/src/tpls/scatter_graph.c
vendored
Normal file
@ -0,0 +1,305 @@
|
||||
/*
|
||||
* @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 "third_library_const.h"
|
||||
#include "third_library_tools.h"
|
||||
#include "graph_util.h"
|
||||
|
||||
/*
|
||||
* Scatter a ParMetis-style graph to all processors such that each proc
|
||||
* gets an even chunk of vertices and corresponding edges.
|
||||
* The entire graph structure is shuffled around; no attempt is made
|
||||
* to keep data local. Processor i receives nodes i*n/p through (i+1)*n/p.
|
||||
* This routine is only useful if the distribution is highly imbalanced!
|
||||
*
|
||||
* The input graph structure is lost and fresh memory is allocated
|
||||
* for the new distributed graph.
|
||||
*
|
||||
* This routine can also handle geometry data. The graph data may be NULL.
|
||||
*
|
||||
* The vertex communication plan is returned so it may be used to compute
|
||||
* the export lists after partitioning.
|
||||
*
|
||||
* Currently the number of weights are inferred from zz->Obj_Weight_Dim
|
||||
* and zz->Edge_Weight_Dim. Perhaps these values should be input parameters.
|
||||
*/
|
||||
|
||||
int Zoltan_Scatter_Graph(
|
||||
indextype **vtxdist,
|
||||
indextype **xadj,
|
||||
indextype **adjncy,
|
||||
weighttype **vwgt,
|
||||
indextype **vsize,
|
||||
weighttype **adjwgt,
|
||||
realtype **xyz,
|
||||
int ndims, /* # dimensions of xyz geometry data */
|
||||
int vwgt_dim,
|
||||
ZZ *zz,
|
||||
ZOLTAN_COMM_OBJ **plan
|
||||
)
|
||||
{
|
||||
static char *yo = "Zoltan_Scatter_Graph";
|
||||
char msg[256];
|
||||
indextype *old_vtxdist, *old_adjncy;
|
||||
indextype *old_xadj;
|
||||
indextype *old_vsize;
|
||||
weighttype *old_vwgt, *old_adjwgt;
|
||||
realtype *old_xyz;
|
||||
int *ptr, *proclist = NULL, *proclist2 = NULL;
|
||||
int i, j, num_obj, old_num_obj, num_edges, nrecv;
|
||||
int use_graph; /* do we use graph data, or only the geometry? */
|
||||
int use_vsize; /* do we use the vsize array? */
|
||||
int ewgt_dim= zz->Edge_Weight_Dim;
|
||||
ZOLTAN_COMM_OBJ *plan2;
|
||||
|
||||
ZOLTAN_TRACE_ENTER(zz, yo);
|
||||
|
||||
/* Save pointers to "old" data distribution */
|
||||
old_adjncy = NULL;
|
||||
old_xadj = NULL;
|
||||
old_vwgt = old_adjwgt = NULL;
|
||||
old_vsize = NULL;
|
||||
old_xyz = NULL;
|
||||
|
||||
old_vtxdist = *vtxdist;
|
||||
|
||||
if (xadj)
|
||||
old_xadj = *xadj;
|
||||
if (adjncy)
|
||||
old_adjncy = *adjncy;
|
||||
if (vwgt)
|
||||
old_vwgt = *vwgt;
|
||||
if (vsize)
|
||||
old_vsize = *vsize;
|
||||
if (adjwgt)
|
||||
old_adjwgt = *adjwgt;
|
||||
if (xyz)
|
||||
old_xyz = *xyz;
|
||||
|
||||
old_num_obj = (int)(old_vtxdist[zz->Proc+1] - old_vtxdist[zz->Proc]);
|
||||
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL)
|
||||
printf("[%1d] Debug: Old number of objects = %d\n", zz->Proc, old_num_obj);
|
||||
|
||||
/* Compute new distribution, *vtxdist */
|
||||
(*vtxdist) = (indextype *)ZOLTAN_MALLOC((zz->Num_Proc+1)* sizeof(indextype));
|
||||
for (i=0; i<=zz->Num_Proc; i++){
|
||||
(*vtxdist)[i] = (i*old_vtxdist[zz->Num_Proc])/zz->Num_Proc;
|
||||
}
|
||||
|
||||
/* Check if any proc has graph data */
|
||||
i = (old_xadj != NULL);
|
||||
MPI_Allreduce(&i, &use_graph, 1, MPI_INT, MPI_LOR, zz->Communicator);
|
||||
j = (old_vsize != NULL);
|
||||
MPI_Allreduce(&j, &use_vsize, 1, MPI_INT, MPI_LOR, zz->Communicator);
|
||||
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL)
|
||||
printf("[%1d] Debug: use_graph = %1d, use_vsize = %1d\n", zz->Proc,
|
||||
use_graph, use_vsize);
|
||||
|
||||
/* Reset all data pointers to NULL for now */
|
||||
*xadj = NULL;
|
||||
*adjncy = NULL;
|
||||
*vwgt = *adjwgt = NULL;
|
||||
*xyz = NULL;
|
||||
if (use_vsize) *vsize = NULL;
|
||||
|
||||
/* Convert the xdj array so that it contains the degree of each vertex */
|
||||
if (use_graph){
|
||||
for (i=0; i<old_num_obj; i++){
|
||||
old_xadj[i] = old_xadj[i+1] - old_xadj[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate new space for vertex data */
|
||||
num_obj = (int)((*vtxdist)[zz->Proc+1] - (*vtxdist)[zz->Proc]);
|
||||
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL)
|
||||
printf("[%1d] Debug: New number of objects = %d\n", zz->Proc, num_obj);
|
||||
if (use_graph)
|
||||
*xadj = (indextype *) ZOLTAN_MALLOC((num_obj+1)*sizeof(indextype));
|
||||
if (vwgt_dim)
|
||||
*vwgt = (weighttype *) ZOLTAN_MALLOC(vwgt_dim*num_obj*sizeof(weighttype));
|
||||
if (use_vsize)
|
||||
*vsize = (indextype *) ZOLTAN_MALLOC(num_obj*sizeof(indextype));
|
||||
if (ndims)
|
||||
*xyz = (realtype *) ZOLTAN_MALLOC(ndims*num_obj*sizeof(realtype));
|
||||
|
||||
if (old_num_obj > 0) {
|
||||
/* Set up the communication plan for the vertex data */
|
||||
proclist = (int *) ZOLTAN_MALLOC(old_num_obj * sizeof(int));
|
||||
/* Let j be the new owner of vertex old_vtxdist[zz->Proc]+i */
|
||||
j = 0;
|
||||
while (old_vtxdist[zz->Proc] >= (*vtxdist)[j+1]) j++;
|
||||
for (i=0; i<old_num_obj; i++){
|
||||
if (old_vtxdist[zz->Proc]+i >= (*vtxdist)[j+1]) j++;
|
||||
proclist[i] = j;
|
||||
}
|
||||
}
|
||||
|
||||
Zoltan_Comm_Create(plan, old_num_obj, proclist, zz->Communicator, TAG1, &nrecv);
|
||||
|
||||
if (nrecv != num_obj){
|
||||
sprintf(msg,"Proc %d received %d object but expected %d.",
|
||||
zz->Proc, nrecv, num_obj);
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
|
||||
/* Free data */
|
||||
ZOLTAN_FREE(&proclist);
|
||||
ZOLTAN_TRACE_EXIT(zz, yo);
|
||||
return ZOLTAN_FATAL;
|
||||
}
|
||||
|
||||
/* Do the communication. To save memory, we do not pack all the data into
|
||||
* a buffer, but send directly from the old arrays to the new arrays.
|
||||
* We use the vertex communication plan for all the vertex-based arrays
|
||||
* and the edge communication plan for all the edge-based arrays.
|
||||
*/
|
||||
|
||||
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL)
|
||||
printf("[%1d] Debug: Starting vertex-based communication.\n", zz->Proc);
|
||||
|
||||
if (use_graph){
|
||||
Zoltan_Comm_Do( *plan, TAG2, (char *) old_xadj, sizeof(indextype), (char *) *xadj);
|
||||
}
|
||||
if (vwgt_dim){
|
||||
Zoltan_Comm_Do( *plan, TAG3, (char *) old_vwgt, vwgt_dim*sizeof(weighttype), (char *) *vwgt);
|
||||
}
|
||||
if (use_vsize){
|
||||
Zoltan_Comm_Do( *plan, TAG4, (char *) old_vsize, sizeof(indextype), (char *) *vsize);
|
||||
}
|
||||
if (ndims){
|
||||
Zoltan_Comm_Do( *plan, TAG5, (char *) old_xyz, ndims*sizeof(realtype), (char *) *xyz);
|
||||
}
|
||||
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL)
|
||||
printf("[%1d] Debug: Finished vertex-based communication.\n", zz->Proc);
|
||||
|
||||
if (use_graph){
|
||||
|
||||
/* Rebuild xadj from degrees */
|
||||
for (i=1; i<num_obj; i++)
|
||||
(*xadj)[i] += (*xadj)[i-1];
|
||||
for (i=num_obj; i>0; i--)
|
||||
(*xadj)[i] = (*xadj)[i-1];
|
||||
(*xadj)[0] = 0;
|
||||
|
||||
/* Allocate space for new edge data structures */
|
||||
num_edges = (*xadj)[num_obj];
|
||||
*adjncy = (indextype *) ZOLTAN_MALLOC(num_edges*sizeof(indextype));
|
||||
|
||||
if (ewgt_dim)
|
||||
*adjwgt = (weighttype *) ZOLTAN_MALLOC(ewgt_dim*num_edges*sizeof(weighttype));
|
||||
|
||||
/* Set up the communication plan for the edge data. */
|
||||
ptr = proclist2 = (int *) ZOLTAN_MALLOC(old_xadj[old_num_obj] * sizeof(int));
|
||||
for (i=0; i<old_num_obj; i++)
|
||||
for (j=0; j<old_xadj[i]; j++)
|
||||
*ptr++ = proclist[i];
|
||||
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL) {
|
||||
printf("[%1d] Debug: Allocated proclist of length " TPL_IDX_SPEC " for edges.\n",
|
||||
zz->Proc, old_xadj[old_num_obj]);
|
||||
}
|
||||
|
||||
Zoltan_Comm_Create(&plan2, (int)old_xadj[old_num_obj], proclist2, zz->Communicator,
|
||||
TAG1, &nrecv);
|
||||
|
||||
if (nrecv != num_edges){
|
||||
sprintf(msg,"Proc %d received %d edges but expected %d.",
|
||||
zz->Proc, nrecv, num_edges);
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo, msg);
|
||||
/* Free data */
|
||||
ZOLTAN_FREE(&proclist);
|
||||
ZOLTAN_FREE(&proclist2);
|
||||
ZOLTAN_FREE(&old_vtxdist);
|
||||
ZOLTAN_FREE(&old_xadj);
|
||||
ZOLTAN_FREE(&old_adjncy);
|
||||
ZOLTAN_FREE(&old_vwgt);
|
||||
ZOLTAN_FREE(&old_vsize);
|
||||
ZOLTAN_FREE(&old_adjwgt);
|
||||
ZOLTAN_FREE(&old_xyz);
|
||||
ZOLTAN_TRACE_EXIT(zz, yo);
|
||||
return ZOLTAN_FATAL;
|
||||
}
|
||||
|
||||
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL)
|
||||
printf("[%1d] Debug: Starting edge-based communication.\n", zz->Proc);
|
||||
|
||||
/* Do the communication. */
|
||||
Zoltan_Comm_Do( plan2, TAG2, (char *) old_adjncy, sizeof(indextype), (char *) *adjncy);
|
||||
if (ewgt_dim){
|
||||
Zoltan_Comm_Do( plan2, TAG3, (char *) old_adjwgt, ewgt_dim*sizeof(weighttype), (char *) *adjwgt);
|
||||
}
|
||||
|
||||
if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL)
|
||||
printf("[%1d] Debug: Finished edge-based communication.\n", zz->Proc);
|
||||
|
||||
/* Free the comm. plan for edge data */
|
||||
Zoltan_Comm_Destroy(&plan2);
|
||||
|
||||
} /* end of use_graph */
|
||||
|
||||
/* Free data structures */
|
||||
ZOLTAN_FREE(&proclist);
|
||||
ZOLTAN_FREE(&proclist2);
|
||||
ZOLTAN_FREE(&old_vtxdist);
|
||||
ZOLTAN_FREE(&old_xadj);
|
||||
ZOLTAN_FREE(&old_adjncy);
|
||||
ZOLTAN_FREE(&old_vwgt);
|
||||
ZOLTAN_FREE(&old_vsize);
|
||||
ZOLTAN_FREE(&old_adjwgt);
|
||||
ZOLTAN_FREE(&old_xyz);
|
||||
|
||||
ZOLTAN_TRACE_EXIT(zz, yo);
|
||||
return ZOLTAN_OK;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* closing bracket for extern "C" */
|
||||
#endif
|
1009
thirdParty/Zoltan/src/tpls/scotch_interface.c
vendored
Normal file
1009
thirdParty/Zoltan/src/tpls/scotch_interface.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
69
thirdParty/Zoltan/src/tpls/scotch_interface.h
vendored
Normal file
69
thirdParty/Zoltan/src/tpls/scotch_interface.h
vendored
Normal 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
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __SCOTCH_INTERFACE_H
|
||||
#define __SCOTCH_INTERFACE_H
|
||||
|
||||
#include <limits.h>
|
||||
#include "zoltan_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* if C++, define the rest of this header file as extern C */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int Zoltan_Scotch(
|
||||
ZZ *, float *, int *, ZOLTAN_ID_PTR *, ZOLTAN_ID_PTR *,
|
||||
int **, int **, int *, ZOLTAN_ID_PTR *, ZOLTAN_ID_PTR *,
|
||||
int **, int **);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* closing bracket for extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
67
thirdParty/Zoltan/src/tpls/scotch_interface_params.h
vendored
Normal file
67
thirdParty/Zoltan/src/tpls/scotch_interface_params.h
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* @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 __SCOTCH_INTERFACE_PARAMS_H
|
||||
#define __SCOTCH_INTERFACE_PARAMS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* if C++, define the rest of this header file as extern C */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/********** parameters structure for Scotch methods **********/
|
||||
static PARAM_VARS Scotch_params[] = {
|
||||
{ "SCOTCH_METHOD", NULL, "STRING", 0 },
|
||||
{ "SCOTCH_TYPE", NULL, "STRING", 0 },
|
||||
{ "SCOTCH_STRAT", NULL, "STRING", 0 },
|
||||
{ "SCOTCH_STRAT_FILE", NULL, "STRING", 0 },
|
||||
{ NULL, NULL, NULL, 0 } };
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
465
thirdParty/Zoltan/src/tpls/third_library.c
vendored
Normal file
465
thirdParty/Zoltan/src/tpls/third_library.c
vendored
Normal file
@ -0,0 +1,465 @@
|
||||
/*
|
||||
* @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 <ctype.h>
|
||||
#include "zz_const.h"
|
||||
#include "zz_util_const.h"
|
||||
#include "all_allo_const.h"
|
||||
#include "params_const.h"
|
||||
#include "order_const.h"
|
||||
#include "third_library.h"
|
||||
#include "third_library_params.h"
|
||||
|
||||
/**********************************************************/
|
||||
/* Interface routine for Graph methods. */
|
||||
/**********************************************************/
|
||||
|
||||
int Zoltan_Graph(
|
||||
ZZ *zz, /* Zoltan structure */
|
||||
float *part_sizes, /* Input: Array of size zz->Num_Global_Parts
|
||||
containing the percentage of work to be
|
||||
assigned to each part. */
|
||||
int *num_imp, /* number of objects to be imported */
|
||||
ZOLTAN_ID_PTR *imp_gids, /* global ids of objects to be imported */
|
||||
ZOLTAN_ID_PTR *imp_lids, /* local ids of objects to be imported */
|
||||
int **imp_procs, /* list of processors to import from */
|
||||
int **imp_to_part, /* list of partitions to which imported objects are
|
||||
assigned. */
|
||||
int *num_exp, /* number of objects to be exported */
|
||||
ZOLTAN_ID_PTR *exp_gids, /* global ids of objects to be exported */
|
||||
ZOLTAN_ID_PTR *exp_lids, /* local ids of objects to be exported */
|
||||
int **exp_procs, /* list of processors to export to */
|
||||
int **exp_to_part /* list of partitions to which exported objects are
|
||||
assigned. */
|
||||
)
|
||||
{
|
||||
static char* yo = "Zoltan_Graph";
|
||||
|
||||
char *defaultMethod= "PHG";
|
||||
char package[MAX_PARAM_STRING_LEN];
|
||||
int rc;
|
||||
|
||||
strcpy(package, defaultMethod);
|
||||
Zoltan_Bind_Param(Graph_Package_params, "GRAPH_PACKAGE", package);
|
||||
Zoltan_Assign_Param_Vals(zz->Params, Graph_Package_params, zz->Debug_Level,
|
||||
zz->Proc, zz->Debug_Proc);
|
||||
|
||||
if (!strcasecmp(package, "PARMETIS")){
|
||||
#ifdef ZOLTAN_PARMETIS
|
||||
rc = Zoltan_ParMetis(zz, part_sizes, num_imp, imp_gids, imp_lids,
|
||||
imp_procs, imp_to_part,
|
||||
num_exp, exp_gids, exp_lids, exp_procs, exp_to_part);
|
||||
#else
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo,
|
||||
"ParMETIS partitioning was requested but "
|
||||
"Zoltan was compiled without ParMETIS.\n");
|
||||
rc = ZOLTAN_FATAL;
|
||||
#endif /* ZOLTAN_PARMETIS */
|
||||
}
|
||||
else if (!strcasecmp(package, "METIS")){
|
||||
#ifdef ZOLTAN_METIS
|
||||
rc = Zoltan_ParMetis(zz, part_sizes, num_imp, imp_gids, imp_lids,
|
||||
imp_procs, imp_to_part,
|
||||
num_exp, exp_gids, exp_lids, exp_procs, exp_to_part);
|
||||
#else
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo,
|
||||
"METIS partitioning was requested but "
|
||||
"Zoltan was compiled without METIS.\n");
|
||||
rc = ZOLTAN_FATAL;
|
||||
#endif /* ZOLTAN_METIS */
|
||||
}
|
||||
else if (!strcasecmp(package, "SCOTCH")){
|
||||
#ifdef ZOLTAN_SCOTCH
|
||||
rc = Zoltan_Scotch(zz, part_sizes, num_imp, imp_gids, imp_lids,
|
||||
imp_procs, imp_to_part,
|
||||
num_exp, exp_gids, exp_lids, exp_procs, exp_to_part);
|
||||
#else
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo,
|
||||
"Scotch partitioning was requested but "
|
||||
"Zoltan was compiled without Scotch.\n");
|
||||
rc = ZOLTAN_FATAL;
|
||||
#endif /* ZOLTAN_SCOTCH */
|
||||
}
|
||||
else if (!strcasecmp(package, "ZOLTAN") ||
|
||||
!strcasecmp(package, "PHG")) {
|
||||
|
||||
rc = Zoltan_PHG(zz, part_sizes, num_imp, imp_gids, imp_lids,
|
||||
imp_procs, imp_to_part,
|
||||
num_exp, exp_gids, exp_lids, exp_procs, exp_to_part);
|
||||
}
|
||||
else{
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo,
|
||||
"Invalid value for GRAPH_PACKAGE parameter\n");
|
||||
rc = ZOLTAN_FATAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* Graph_Package parameter routine */
|
||||
/*********************************************************************/
|
||||
|
||||
int Zoltan_Graph_Package_Set_Param(
|
||||
char *name, /* name of variable */
|
||||
char *val) /* value of variable */
|
||||
{
|
||||
int status, i;
|
||||
PARAM_UTYPE result; /* value returned from Check_Param */
|
||||
int index; /* index returned from Check_Param */
|
||||
char *valid_methods[] = {
|
||||
"PARMETIS", "PHG", "ZOLTAN", "SCOTCH", "METIS",
|
||||
NULL };
|
||||
|
||||
status = Zoltan_Check_Param(name, val, Graph_Package_params,
|
||||
&result, &index);
|
||||
|
||||
if (status == 0){
|
||||
/* OK so far, do sanity check of parameter values */
|
||||
|
||||
if (strcmp(name, "GRAPH_PACKAGE") == 0){
|
||||
status = 2;
|
||||
for (i=0; valid_methods[i] != NULL; i++){
|
||||
if (strcmp(val, valid_methods[i]) == 0){
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
#define MEMFREE(ptr) do { if (ptr) ZOLTAN_FREE(&(ptr)); } while (0);
|
||||
|
||||
|
||||
void Zoltan_Third_Exit(ZOLTAN_Third_Graph *gr, ZOLTAN_Third_Geom *geo,
|
||||
ZOLTAN_Third_Part *prt, ZOLTAN_Third_Vsize *vsp,
|
||||
ZOLTAN_Output_Part *part, ZOLTAN_Output_Order *ord)
|
||||
{
|
||||
if (gr) {
|
||||
|
||||
Zoltan_Matrix2d_Free(&gr->graph.mtx);
|
||||
|
||||
MEMFREE(gr->vwgt);
|
||||
MEMFREE(gr->vtxdist);
|
||||
MEMFREE(gr->xadj);
|
||||
MEMFREE(gr->adjncy);
|
||||
MEMFREE(gr->ewgts);
|
||||
MEMFREE(gr->float_ewgts);
|
||||
MEMFREE(gr->adjproc);
|
||||
|
||||
Zoltan_ZG_Free(&gr->graph);
|
||||
}
|
||||
|
||||
if (geo) {
|
||||
MEMFREE(geo->xyz);
|
||||
}
|
||||
|
||||
if (prt) {
|
||||
MEMFREE(prt->part);
|
||||
MEMFREE(prt->input_part);
|
||||
MEMFREE(prt->part_orig);
|
||||
if (prt->part_sizes != prt->input_part_sizes)
|
||||
MEMFREE(prt->part_sizes);
|
||||
if (sizeof(realtype) != sizeof(float))
|
||||
MEMFREE(prt->input_part_sizes);
|
||||
}
|
||||
|
||||
if (vsp) {
|
||||
if (!vsp->vsize_malloc) {
|
||||
MEMFREE(vsp->vsize);
|
||||
}
|
||||
MEMFREE(vsp->vsizeBACKUP);
|
||||
}
|
||||
|
||||
if (ord) {
|
||||
MEMFREE(ord->sep_sizes);
|
||||
MEMFREE(ord->rank);
|
||||
MEMFREE(ord->iperm);
|
||||
}
|
||||
}
|
||||
|
||||
int Zoltan_Third_Init(ZOLTAN_Third_Graph *gr, ZOLTAN_Third_Part *prt, ZOLTAN_Third_Vsize *vsp, ZOLTAN_Output_Part *part,
|
||||
ZOLTAN_ID_PTR *imp_gids, ZOLTAN_ID_PTR *imp_lids, int **imp_procs, int **imp_to_part,
|
||||
ZOLTAN_ID_PTR *exp_gids, ZOLTAN_ID_PTR *exp_lids, int **exp_procs, int **exp_to_part)
|
||||
{
|
||||
|
||||
memset (gr, 0, sizeof(ZOLTAN_Third_Graph));
|
||||
memset (prt, 0, sizeof(ZOLTAN_Third_Part));
|
||||
memset (vsp, 0, sizeof(ZOLTAN_Third_Vsize));
|
||||
memset (part, 0, sizeof(ZOLTAN_Output_Part));
|
||||
|
||||
/* Initialize return-argument arrays to return arguments so that F90 works. */
|
||||
part->imp_gids = imp_gids;
|
||||
part->imp_lids = imp_lids;
|
||||
part->imp_procs = imp_procs;
|
||||
part->imp_part = imp_to_part;
|
||||
|
||||
part->exp_gids = exp_gids;
|
||||
part->exp_lids = exp_lids;
|
||||
part->exp_procs = exp_procs;
|
||||
part->exp_part = exp_to_part;
|
||||
|
||||
part->num_imp = part->num_exp = -1;
|
||||
|
||||
/* Most ParMetis methods use only graph data */
|
||||
gr->get_data = 1;
|
||||
|
||||
return (ZOLTAN_OK);
|
||||
}
|
||||
|
||||
/* export to user variables */
|
||||
int Zoltan_Third_Export_User(ZOLTAN_Output_Part *part,
|
||||
int *num_imp, ZOLTAN_ID_PTR *imp_gids, ZOLTAN_ID_PTR *imp_lids, int **imp_procs, int **imp_to_part,
|
||||
int *num_exp, ZOLTAN_ID_PTR *exp_gids, ZOLTAN_ID_PTR *exp_lids, int **exp_procs, int **exp_to_part)
|
||||
{
|
||||
/* Write results in user variables */
|
||||
*num_imp = part->num_imp;
|
||||
*imp_gids = *(part->imp_gids);
|
||||
*imp_lids = *(part->imp_lids);
|
||||
*imp_procs = *(part->imp_procs);
|
||||
*imp_to_part = *(part->imp_part);
|
||||
*num_exp = part->num_exp;
|
||||
*exp_gids = *(part->exp_gids);
|
||||
*exp_lids = *(part->exp_lids);
|
||||
*exp_procs = *(part->exp_procs);
|
||||
*exp_to_part = *(part->exp_part);
|
||||
|
||||
return (ZOLTAN_OK);
|
||||
}
|
||||
|
||||
int Zoltan_matrix_Print(Zoltan_matrix *m, char *s)
|
||||
{
|
||||
int i, j, k;
|
||||
float *wgts;
|
||||
|
||||
if (s) fprintf(stderr,"Zoltan_matrix, %s\n",s);
|
||||
fprintf(stderr,"\nOptions: enforceSquare %d, pinwgtop %s, randomize %d, pinwgt %d\n",
|
||||
m->opts.enforceSquare,
|
||||
((m->opts.pinwgtop == 0) ? "add weight" : ((m->opts.pinwgtop == 1) ? "max weight" : "cmp weight")),
|
||||
m->opts.randomize, m->opts.pinwgt);
|
||||
|
||||
fprintf(stderr,"Options: local %d, final_output %d, symmetrize %d keep_distribution %d speed %s\n",
|
||||
m->opts.local, m->opts.final_output, m->opts.symmetrize, m->opts.keep_distribution,
|
||||
((m->opts.speed == 0) ? "full dd" : ((m->opts.speed == 1) ? "fast" : "no redist")));
|
||||
|
||||
fprintf(stderr,"redist %d, completed %d, bipartite %d\n", m->redist, m->completed, m->bipartite);
|
||||
|
||||
fprintf(stderr,"globalX " ZOLTAN_GNO_SPEC ", globalY " ZOLTAN_GNO_SPEC ", nY %d, nY_ori %d, ywgtdim %d, nPins %d\n",
|
||||
m->globalX, m->globalY, m->nY, m->nY_ori, m->ywgtdim, m->nPins);
|
||||
fprintf(stderr,"Edges and non-zeroes:\n");
|
||||
wgts = m->pinwgt;
|
||||
if (m->yGNO && m->pinGNO){
|
||||
for (i=0; i < m->nY; i++){
|
||||
fprintf(stderr, ZOLTAN_GNO_SPEC ": ",m->yGNO[i]);
|
||||
for (j=m->ystart[i]; j < m->ystart[i+1]; j++){
|
||||
fprintf(stderr, ZOLTAN_GNO_SPEC " ", m->pinGNO[j]);
|
||||
if (wgts && (m->pinwgtdim > 0)){
|
||||
fprintf(stderr,"(");
|
||||
for (k=0; k < m->pinwgtdim; k++){
|
||||
fprintf(stderr,"%f ",*wgts++);
|
||||
}
|
||||
fprintf(stderr,") ");
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
}
|
||||
else{
|
||||
fprintf(stderr,"not set");
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
fflush(stderr);
|
||||
return ZOLTAN_OK;
|
||||
}
|
||||
|
||||
int Zoltan_ZG_Print(ZZ *zz, ZG *gr, char *s)
|
||||
{
|
||||
int i, me, proc;
|
||||
Zoltan_matrix_2d *m2d = &gr->mtx;
|
||||
Zoltan_matrix *m = &m2d->mtx;
|
||||
int nproc_x = m2d->comm->nProc_x;
|
||||
int nproc_y = m2d->comm->nProc_y;
|
||||
|
||||
me = zz->Proc;
|
||||
for (proc=0; proc < zz->Num_Proc; proc++){
|
||||
if (proc == me){
|
||||
if (proc == 0) fprintf(stderr,"\n%s\n",s);
|
||||
fprintf(stderr,"Process: %d) flags: bipartite %d fixObj %d, fixed vertices buffer %p:\n",
|
||||
zz->Proc, gr->bipartite, gr->fixObj, (void *)gr->fixed_vertices);
|
||||
fprintf(stderr,"GNO distribution in x direction: ");
|
||||
if (m2d->dist_x){
|
||||
for (i=0; i <= nproc_x; i++){
|
||||
fprintf(stderr, ZOLTAN_GNO_SPEC " ",m2d->dist_x[i]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
fprintf(stderr,"not set");
|
||||
}
|
||||
fprintf(stderr,"\nGNO distribution in y direction: ");
|
||||
if (m2d->dist_y){
|
||||
for (i=0; i <= nproc_y; i++){
|
||||
fprintf(stderr, ZOLTAN_GNO_SPEC " ",m2d->dist_y[i]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
fprintf(stderr,"not set");
|
||||
}
|
||||
|
||||
Zoltan_matrix_Print(m, NULL);
|
||||
|
||||
fflush(stderr);
|
||||
}
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
}
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
return ZOLTAN_OK;
|
||||
}
|
||||
int Zoltan_Third_Graph_Print(ZZ *zz, ZOLTAN_Third_Graph *gr, char *s)
|
||||
{
|
||||
int i, me, proc;
|
||||
indextype numvtx, offset, j;
|
||||
me = zz->Proc;
|
||||
|
||||
for (proc=0; proc < zz->Num_Proc; proc++){
|
||||
if (proc == me){
|
||||
if (proc == 0) fprintf(stderr,"\n%s\n",s);
|
||||
fprintf(stderr,"Process: %d) graph type %d, check graph %d, final output %d, showMoveVol %d, scatter %d\n",
|
||||
me, gr->graph_type, gr->check_graph, gr->final_output, gr->showMoveVol, gr->scatter);
|
||||
fprintf(stderr,"scatter min %d, get data %d, obj wgt dim %d, edge wgt dim %d\n",
|
||||
gr->scatter_min, gr->get_data, gr->obj_wgt_dim, gr->edge_wgt_dim);
|
||||
fprintf(stderr,"num obj %d, num obj orig %d, num edges %d\n",
|
||||
gr->num_obj, gr->num_obj_orig, gr->num_edges);
|
||||
|
||||
if (gr->vtxdist){
|
||||
numvtx = gr->vtxdist[proc+1] - gr->vtxdist[proc];
|
||||
offset = gr->vtxdist[proc];
|
||||
fprintf(stderr,"Num vertices: " TPL_IDX_SPEC "\n",numvtx);
|
||||
if (gr->xadj){
|
||||
fprintf(stderr,"Num edges: " TPL_IDX_SPEC "\n",gr->xadj[numvtx]);
|
||||
}
|
||||
|
||||
for (i=0; i < numvtx; i++){
|
||||
fprintf(stderr,TPL_IDX_SPEC ": ",i+offset);
|
||||
if (gr->xadj){
|
||||
for (j=gr->xadj[i];j < gr->xadj[i+1]; j++){
|
||||
if (gr->adjncy){
|
||||
fprintf(stderr,"gid " TPL_IDX_SPEC,gr->adjncy[j]);
|
||||
}
|
||||
if (gr->adjproc){
|
||||
fprintf(stderr," proc %d ",gr->adjproc[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
fprintf(stderr,"adjacency info is null");
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
}
|
||||
|
||||
fflush(stderr);
|
||||
}
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
}
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
return ZOLTAN_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Copy of Zoltan_Order_Init_Tree in order_tools.c which uses TPL data types
|
||||
*/
|
||||
#define CHECK_ZOLTAN_FREE(ptr) do { if ((ptr) != NULL) ZOLTAN_FREE(&(ptr)); } while (0)
|
||||
|
||||
int Zoltan_TPL_Order_Init_Tree (struct Zoltan_TPL_Order_Struct *order, indextype blocknbr, indextype leavesnbr)
|
||||
{
|
||||
Zoltan_TPL_Order_Free_Struct(order);
|
||||
|
||||
order->ancestor = (indextype *) ZOLTAN_MALLOC(blocknbr*sizeof(indextype));
|
||||
order->start = (indextype *) ZOLTAN_MALLOC((blocknbr+1)*sizeof(indextype));
|
||||
order->leaves = (indextype *) ZOLTAN_MALLOC((leavesnbr+1)*sizeof(indextype));
|
||||
|
||||
order->needfree = 1;
|
||||
if ((order->ancestor == NULL) || (order->start == NULL) || (order->leaves == NULL)) {
|
||||
Zoltan_TPL_Order_Free_Struct(order);
|
||||
return (ZOLTAN_MEMERR);
|
||||
}
|
||||
return (ZOLTAN_OK);
|
||||
}
|
||||
|
||||
void Zoltan_TPL_Order_Free_Struct(struct Zoltan_TPL_Order_Struct *order)
|
||||
{
|
||||
if (order->needfree == 0)
|
||||
return;
|
||||
|
||||
CHECK_ZOLTAN_FREE(order->start);
|
||||
CHECK_ZOLTAN_FREE(order->ancestor);
|
||||
CHECK_ZOLTAN_FREE(order->leaves);
|
||||
|
||||
order->needfree = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
214
thirdParty/Zoltan/src/tpls/third_library.h
vendored
Normal file
214
thirdParty/Zoltan/src/tpls/third_library.h
vendored
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* @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 __THIRD_LIBRARY_H
|
||||
#define __THIRD_LIBRARY_H
|
||||
|
||||
#include <limits.h>
|
||||
#include "zoltan_comm.h"
|
||||
#include "third_library_const.h"
|
||||
#include "graph.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* if C++, define the rest of this header file as extern C */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define INT_EPSILON (1e-5) /* How close we need to be to say it's an integer */
|
||||
|
||||
/* Macro for error handling */
|
||||
#define ZOLTAN_PARMETIS_ERROR(error,str) {ierr = error ; \
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo, str) ; goto End ;}
|
||||
|
||||
#define ZOLTAN_THIRD_ERROR(error,str) { \
|
||||
ZOLTAN_PRINT_ERROR(zz->Proc, yo , str) ; return(error) ;}
|
||||
|
||||
|
||||
/* Structure that defines a graph for third party libraries like ParMetis. */
|
||||
typedef struct ZOLTAN_Third_Graph_ {
|
||||
int graph_type; /* Type of the graph */
|
||||
int check_graph; /* We have to check graph consistency */
|
||||
int final_output; /* Do some output computations */
|
||||
int showMoveVol; /* How works the final output */
|
||||
int scatter; /* Graph has been scattered */
|
||||
int scatter_min; /* Minimum level of scatter */
|
||||
int get_data; /* Construct edge datas */
|
||||
int obj_wgt_dim; /* Number of weights by vertex */
|
||||
int edge_wgt_dim; /* Number of weights by edge */
|
||||
int num_obj; /* Local number of vertices */
|
||||
int num_obj_orig; /* Local number of vertices in original graph */
|
||||
int num_edges; /* Local number of edges */
|
||||
indextype *vtxdist; /* How vertices are distributed */
|
||||
indextype * xadj; /* Indexes on adjency array */
|
||||
indextype *adjncy; /* adjency array (CSR) */
|
||||
weighttype * vwgt; /* Array of vertex weights */
|
||||
weighttype * ewgts; /* Array of edge weights */
|
||||
float * float_ewgts;
|
||||
int * adjproc; /* Array of procs ? */
|
||||
ZOLTAN_COMM_OBJ *comm_plan; /* Communication plan used by scattering process */
|
||||
ZG graph;
|
||||
} ZOLTAN_Third_Graph;
|
||||
|
||||
/* Structure that defines a geometry for third party libraries like ParMetis. */
|
||||
typedef struct ZOLTAN_Third_Geom_ {
|
||||
int ndims; /* Number of dimensions */
|
||||
realtype *xyz; /* Coordinates */
|
||||
} ZOLTAN_Third_Geom;
|
||||
|
||||
/* Structure that defines a partition for third party libraries like ParMetis. */
|
||||
typedef struct ZOLTAN_Third_Part_ {
|
||||
indextype *part; /* Current partition */
|
||||
indextype *input_part;
|
||||
indextype *part_orig;
|
||||
realtype *part_sizes;
|
||||
realtype *input_part_sizes;
|
||||
} ZOLTAN_Third_Part;
|
||||
|
||||
typedef struct ZOLTAN_Third_Vsize_ {
|
||||
int vsize_malloc;
|
||||
indextype *vsize;
|
||||
indextype *vsizeBACKUP;
|
||||
} ZOLTAN_Third_Vsize;
|
||||
|
||||
/* Structure that defines an ordering output for third party libraries like ParMetis. */
|
||||
typedef struct ZOLTAN_Output_Order_ {
|
||||
int num_part;
|
||||
indextype start_index;
|
||||
indextype *rank; /* rank[i] is the rank of gids[i] */
|
||||
indextype *iperm; /* inverse permutation of rank */
|
||||
ZOOS *order_opt; /* ordering options */
|
||||
ZTPL_OS *order_info; /* ordering info */
|
||||
indextype *sep_sizes;
|
||||
} ZOLTAN_Output_Order;
|
||||
|
||||
/* Structure that describes a partitioning output in Zoltan lingo
|
||||
for third party libraries like ParMetis. */
|
||||
typedef struct ZOLTAN_Output_Part_ {
|
||||
int compute_only_part_changes;
|
||||
|
||||
int num_imp;
|
||||
ZOLTAN_ID_PTR* imp_gids;
|
||||
ZOLTAN_ID_PTR* imp_lids;
|
||||
int **imp_procs;
|
||||
int **imp_part;
|
||||
|
||||
int num_exp;
|
||||
ZOLTAN_ID_PTR *exp_gids;
|
||||
ZOLTAN_ID_PTR *exp_lids;
|
||||
int **exp_procs;
|
||||
int **exp_part;
|
||||
} ZOLTAN_Output_Part;
|
||||
|
||||
/*****************************
|
||||
* Functions which can be used to interface with third party libraries
|
||||
****************************************************************************/
|
||||
|
||||
/* Construct graph and associated datas in order to call third library */
|
||||
int Zoltan_Preprocess_Graph(
|
||||
ZZ *zz, /* Zoltan structure */
|
||||
ZOLTAN_ID_PTR *global_ids,
|
||||
ZOLTAN_ID_PTR *local_ids,
|
||||
ZOLTAN_Third_Graph *gr, /* Graph for third part libs */
|
||||
ZOLTAN_Third_Geom *geo,
|
||||
ZOLTAN_Third_Part *prt,
|
||||
ZOLTAN_Third_Vsize *vsp
|
||||
);
|
||||
|
||||
/* Activate timers if requested */
|
||||
int Zoltan_Preprocess_Timer(ZZ *zz, int *use_timer);
|
||||
|
||||
/* Display timing informations */
|
||||
void Zoltan_Third_DisplayTime(ZZ* zz, double* times);
|
||||
|
||||
/* Initialize Zoltan internal structures */
|
||||
int Zoltan_Third_Init(ZOLTAN_Third_Graph *gr, ZOLTAN_Third_Part *prt, ZOLTAN_Third_Vsize *vsp, ZOLTAN_Output_Part *part,
|
||||
ZOLTAN_ID_PTR *imp_gids, ZOLTAN_ID_PTR *imp_lids, int **imp_procs, int **imp_to_part,
|
||||
ZOLTAN_ID_PTR *exp_gids, ZOLTAN_ID_PTR *exp_lids, int **exp_procs, int **exp_to_part);
|
||||
|
||||
|
||||
/* export to user variables */
|
||||
int Zoltan_Third_Export_User(ZOLTAN_Output_Part *part,
|
||||
int *num_imp, ZOLTAN_ID_PTR *imp_gids, ZOLTAN_ID_PTR *imp_lids, int **imp_procs, int **imp_to_part,
|
||||
int *num_exp, ZOLTAN_ID_PTR *exp_gids, ZOLTAN_ID_PTR *exp_lids, int **exp_procs, int **exp_to_part);
|
||||
|
||||
|
||||
|
||||
/* Free temporary datas */
|
||||
void Zoltan_Third_Exit(ZOLTAN_Third_Graph *gr, ZOLTAN_Third_Geom *geo,
|
||||
ZOLTAN_Third_Part *prt, ZOLTAN_Third_Vsize *vsp,
|
||||
ZOLTAN_Output_Part *part, ZOLTAN_Output_Order *ord);
|
||||
|
||||
/* Do some postprocesing in order to exploit third party results in Zoltan */
|
||||
int Zoltan_Postprocess_Graph(
|
||||
ZZ *zz, /* Zoltan structure */
|
||||
ZOLTAN_ID_PTR global_ids,
|
||||
ZOLTAN_ID_PTR local_ids,
|
||||
ZOLTAN_Third_Graph *gr, /* Graph for third part libs */
|
||||
ZOLTAN_Third_Geom *geo,
|
||||
ZOLTAN_Third_Part *prt,
|
||||
ZOLTAN_Third_Vsize *vsp,
|
||||
ZOLTAN_Output_Order *ord,
|
||||
ZOLTAN_Output_Part *part);
|
||||
|
||||
int
|
||||
Zoltan_Postprocess_FinalOutput (ZZ* zz, ZOLTAN_Third_Graph *gr,
|
||||
ZOLTAN_Third_Part *prt, ZOLTAN_Third_Vsize *vsp,
|
||||
int use_timers, realtype itr);
|
||||
|
||||
|
||||
int Zoltan_matrix_Print(Zoltan_matrix *m, char *s);
|
||||
int Zoltan_Third_Graph_Print(ZZ *zz, ZOLTAN_Third_Graph *gr, char *s);
|
||||
int Zoltan_ZG_Print(ZZ *zz, ZG *gr, char *s);
|
||||
int Zoltan_Check_TPL_Data_Sizes(ZZ *, int);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
279
thirdParty/Zoltan/src/tpls/third_library_const.h
vendored
Normal file
279
thirdParty/Zoltan/src/tpls/third_library_const.h
vendored
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* @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 __THIRD_LIBRARY_CONST_H
|
||||
#define __THIRD_LIBRARY_CONST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* if C++, define the rest of this header file as extern C */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <float.h>
|
||||
#include "zoltan_util.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Include appropriate files for TPLs */
|
||||
#ifdef ZOLTAN_METIS
|
||||
#include "metis.h"
|
||||
#define __metis__ 1
|
||||
#else
|
||||
#define __metis__ 0
|
||||
#endif
|
||||
|
||||
#ifdef ZOLTAN_PARMETIS
|
||||
#include "parmetis.h"
|
||||
#define __parmetis__ 1
|
||||
#else
|
||||
#define __parmetis__ 0
|
||||
#endif
|
||||
|
||||
#ifdef ZOLTAN_PTSCOTCH
|
||||
#include "ptscotch.h"
|
||||
#define __ptscotch__ 1
|
||||
#else
|
||||
#define __ptscotch__ 0
|
||||
#endif
|
||||
|
||||
#ifdef ZOLTAN_SCOTCH
|
||||
#ifndef ZOLTAN_PTSCOTCH
|
||||
#include "scotch.h"
|
||||
#endif
|
||||
#define __scotch__ 1
|
||||
#else
|
||||
#define __scotch__ 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* TPL-Specific settings for data types */
|
||||
/*
|
||||
* "indextype" is the type used for global numbers and indices in the graph
|
||||
* data structure.
|
||||
* "weighttype" is the type used for weights.
|
||||
*
|
||||
* If there are no third party graph/ordering libraries, let indextype be
|
||||
* ZOLTAN_GNO_TYPE and let "weighttype" be float.
|
||||
*
|
||||
* If there is only one third party library used for graph algorithms,
|
||||
* define indextype and weighttype to match the types used by that library.
|
||||
*
|
||||
* If more than one library is linked in, arbitrarily choose one.
|
||||
* Check for compatibility between the libraries here; all should use the same
|
||||
* size integer for indices.
|
||||
*
|
||||
* At runtime, if
|
||||
* either the indextype or weighttype is not compatible with the graph library
|
||||
* API, return an error.
|
||||
*/
|
||||
|
||||
#define TPL_SCOTCH_DATATYPES 1
|
||||
#define TPL_METIS_DATATYPES 2
|
||||
#define TPL_ZOLTAN_DATATYPES 3
|
||||
|
||||
#undef TPL_USE_DATATYPE
|
||||
#undef indextype
|
||||
#undef weighttype
|
||||
|
||||
/* Select the data types to use */
|
||||
#if __parmetis__ + __metis__ + __ptscotch__ + __scotch__ == 0
|
||||
/* No graph TPLs used; use Zoltan values */
|
||||
#define TPL_USE_DATATYPE TPL_ZOLTAN_DATATYPES
|
||||
#define indextype ZOLTAN_GNO_TYPE
|
||||
#define weighttype float
|
||||
#define realtype float
|
||||
#define TPL_FLOAT_WEIGHT
|
||||
#define MAX_WGT_SUM (FLT_MAX/8)
|
||||
#define TPL_IDX_SPEC ZOLTAN_GNO_SPEC
|
||||
#define TPL_WGT_SPEC "%f"
|
||||
#elif (__ptscotch__ + __scotch__ > 0) && (__parmetis__ + __metis__ == 0)
|
||||
/* Using only Scotch/PTScotch */
|
||||
#define TPL_USE_DATATYPE TPL_SCOTCH_DATATYPES
|
||||
#elif (__parmetis__ + __metis__ > 0) && (__ptscotch__ + __scotch__ == 0)
|
||||
/* Using only METIS/ParMETIS */
|
||||
#define TPL_USE_DATATYPE TPL_METIS_DATATYPES
|
||||
|
||||
#else
|
||||
/* Using both METIS/ParMETIS and Scotch/PTScotch; let METIS datatypes rule */
|
||||
#define TPL_USE_DATATYPE TPL_METIS_DATATYPES
|
||||
#endif
|
||||
|
||||
|
||||
#if TPL_USE_DATATYPE == TPL_METIS_DATATYPES
|
||||
|
||||
#if (PARMETIS_MAJOR_VERSION == 4 || METIS_VER_MAJOR == 5)
|
||||
#define indextype idx_t
|
||||
#define weighttype idx_t
|
||||
#define realtype real_t
|
||||
#define TPL_INTEGRAL_WEIGHT
|
||||
#define MAX_WGT_SUM (IDX_MAX/8)
|
||||
#define TPL_IDX_SPEC "%"PRIDX
|
||||
#define TPL_WGT_SPEC "%"PRIDX
|
||||
#else
|
||||
/* Assume IDXTYPE_INT in ParMETIS v3.x */
|
||||
#ifndef IDXTYPE_INT
|
||||
/* typedef short idxtype; IDXTYPE_INT is not defined in parmetis.h */
|
||||
#error "ParMETIS short idxtype is not supported in Zoltan; define IDXTYPE_INT in parmetis.h."
|
||||
#endif
|
||||
#define indextype idxtype
|
||||
#define weighttype idxtype
|
||||
#define realtype float
|
||||
#define TPL_INTEGRAL_WEIGHT
|
||||
#define MAX_WGT_SUM (INT_MAX/8)
|
||||
#define TPL_IDX_SPEC "%d"
|
||||
#define TPL_WGT_SPEC "%d"
|
||||
#define IDXTYPEWIDTH 32
|
||||
#endif
|
||||
|
||||
#elif TPL_USE_DATATYPE == TPL_SCOTCH_DATATYPES
|
||||
|
||||
#define indextype SCOTCH_Num
|
||||
#define weighttype SCOTCH_Num
|
||||
#define realtype float
|
||||
#define MAX_WGT_SUM (SCOTCH_NUMMAX/8)
|
||||
#ifdef SCOTCH_NUMSTRING /* SCOTCH_NUMSTRING is only in later Scotch versions */
|
||||
#define TPL_IDX_SPEC SCOTCH_NUMSTRING
|
||||
#define TPL_WGT_SPEC SCOTCH_NUMSTRING
|
||||
#else
|
||||
#define TPL_IDX_SPEC "%d"
|
||||
#define TPL_WGT_SPEC "%d"
|
||||
#endif
|
||||
#define TPL_INTEGRAL_WEIGHT
|
||||
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Graph types, used as mask to set bit in graph_type */
|
||||
#define NO_GRAPH 0
|
||||
#define LOCAL_GRAPH 1
|
||||
#define TRY_FAST 2
|
||||
#define FORCE_FAST 3
|
||||
#define UNSYMMETRIC 4
|
||||
/* At this time, means A+At */
|
||||
#define SYMMETRIZE 5
|
||||
|
||||
#define SET_NO_GRAPH(gtype) do { (*(gtype)) &= ~(1<<NO_GRAPH); (*(gtype)) &= ~(1<<LOCAL_GRAPH); } while (0)
|
||||
#define SET_GLOBAL_GRAPH(gtype) do { (*(gtype)) &= ~(1<<LOCAL_GRAPH); (*(gtype)) &= ~(1<<NO_GRAPH); } while (0)
|
||||
#define SET_LOCAL_GRAPH(gtype) do { (*(gtype)) |= (1<<LOCAL_GRAPH); (*(gtype)) &= ~(1<<NO_GRAPH); } while (0)
|
||||
#define IS_NO_GRAPH(gtype) ((!((gtype)&(1<<LOCAL_GRAPH))) && (((gtype)&(1<<NO_GRAPH))))
|
||||
#define IS_GLOBAL_GRAPH(gtype) ((!((gtype)&(1<<NO_GRAPH))) && (!((gtype)&(1<<LOCAL_GRAPH))))
|
||||
#define IS_LOCAL_GRAPH(gtype) ((!((gtype)&(1<<NO_GRAPH))) && (((gtype)&(1<<LOCAL_GRAPH))))
|
||||
|
||||
|
||||
/* Misc. defs to be used with MPI */
|
||||
#define TAG1 32001
|
||||
#define TAG2 32002
|
||||
#define TAG3 32003
|
||||
#define TAG4 32004
|
||||
#define TAG5 32005
|
||||
#define TAG6 32006
|
||||
#define TAG7 32007
|
||||
|
||||
|
||||
/* Zoltan function prototypes */
|
||||
extern int Zoltan_Graph_Package_Set_Param(char *, char *);
|
||||
#ifdef ZOLTAN_PARMETIS
|
||||
extern int Zoltan_ParMetis_Set_Param(char *, char *);
|
||||
#endif /* ZOLTAN_PARMETIS */
|
||||
#ifdef ZOLTAN_SCOTCH
|
||||
extern int Zoltan_Scotch_Set_Param(char *, char *);
|
||||
#endif /* ZOLTAN_SCOTCH */
|
||||
extern int Zoltan_Third_Set_Param(char *, char *);
|
||||
|
||||
extern int Zoltan_Build_Graph(struct Zoltan_Struct *zz, int *graph_type, int check_graph,
|
||||
int num_obj, ZOLTAN_ID_PTR global_ids, ZOLTAN_ID_PTR local_ids,
|
||||
int obj_wgt_dim, int * edge_wgt_dim,
|
||||
ZOLTAN_GNO_TYPE **vtxdist, int **xadj, ZOLTAN_GNO_TYPE **adjncy, float **ewgts,
|
||||
int **adjproc);
|
||||
|
||||
extern int Zoltan_Get_Num_Edges_Per_Obj(struct Zoltan_Struct *, int, ZOLTAN_ID_PTR,
|
||||
ZOLTAN_ID_PTR, int **, int *, int *);
|
||||
|
||||
|
||||
/*==========================================================================
|
||||
* The ZOS structure copied from order/order_const.h, but using TPL datatypes.
|
||||
*/
|
||||
|
||||
struct Zoltan_TPL_Order_Struct {
|
||||
indextype needfree;
|
||||
indextype nbr_objects; /* # of objects (local) */
|
||||
ZOLTAN_ID_PTR gids; /* ptr to list of global ids */
|
||||
ZOLTAN_ID_PTR lids; /* ptr to list of local ids */
|
||||
indextype *rank; /* rank[i] is the rank of gids[i] */
|
||||
ZOLTAN_ID_PTR gidrank;
|
||||
indextype *iperm;
|
||||
indextype start_index;
|
||||
char method[MAX_PARAM_STRING_LEN]; /* Ordering method used */
|
||||
char order_type[MAX_PARAM_STRING_LEN]; /* Ordering method used */
|
||||
|
||||
/* Elimination Tree */
|
||||
indextype nbr_blocks; /* Out: number of ordering blocks */
|
||||
indextype *start; /* Out: start[i] is the first vertex of block i */
|
||||
indextype *ancestor; /* Out: father of block i */
|
||||
indextype *leaves; /* Out: list of all leaves */
|
||||
indextype nbr_leaves; /* Number of leaves */
|
||||
|
||||
indextype *vtxdist; /* How vertices are distributed accross processors */
|
||||
|
||||
/* Deprecated */
|
||||
indextype num_separators; /* Optional: # of separators. */
|
||||
indextype *sep_sizes; /* Optional: Separator sizes. */
|
||||
};
|
||||
|
||||
typedef struct Zoltan_TPL_Order_Struct ZTPL_OS;
|
||||
|
||||
int Zoltan_TPL_Order_Init_Tree (struct Zoltan_TPL_Order_Struct *order, indextype blocknbr, indextype leavesnbr);
|
||||
void Zoltan_TPL_Order_Free_Struct(struct Zoltan_TPL_Order_Struct *order);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* closing bracket for extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
71
thirdParty/Zoltan/src/tpls/third_library_params.h
vendored
Normal file
71
thirdParty/Zoltan/src/tpls/third_library_params.h
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* @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 __THIRD_LIBRARY_PARAMS_H
|
||||
#define __THIRD_LIBRARY_PARAMS_H
|
||||
|
||||
#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"
|
||||
#include "params_const.h"
|
||||
|
||||
/********** parameters structure used by PHG, ParMetis and Jostle **********/
|
||||
static PARAM_VARS Graph_Package_params[] = {
|
||||
{ "GRAPH_PACKAGE", NULL, "STRING", 0 },
|
||||
{ "ORDER_TYPE", NULL, "STRING", 0 },
|
||||
{ NULL, NULL, NULL, 0 } };
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
89
thirdParty/Zoltan/src/tpls/third_library_tools.h
vendored
Normal file
89
thirdParty/Zoltan/src/tpls/third_library_tools.h
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* @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 __THIRD_LIBRARY_TOOLS_H
|
||||
#define __THIRD_LIBRARY_TOOLS_H
|
||||
|
||||
#include <limits.h>
|
||||
#include "zoltan_comm.h"
|
||||
#include "third_library_const.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* if C++, define the rest of this header file as extern C */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Misc. local constants */
|
||||
#define CHUNKSIZE 20 /* Number of nodes to allocate in initial chunk. */
|
||||
#define REALLOC_FACTOR 1.5 /* Increase size by this factor if too small. */
|
||||
|
||||
|
||||
/* Data structures used in ParMetis interface routines */
|
||||
/* An array of this data structure works with a parallel array of
|
||||
* ZOLTAN_ID_PTR called proc_list_nbor containing the global IDs of the
|
||||
* neighboring object.
|
||||
* This separate array is needed to prevent individual mallocs of
|
||||
* neighboring global IDs.
|
||||
*/
|
||||
struct Edge_Info {
|
||||
ZOLTAN_ID_PTR my_gid; /* Pointer to the Global id of local vtx */
|
||||
int my_gno; /* Global number of local vtx */
|
||||
int nbor_proc; /* Proc id for the neighboring proc */
|
||||
int *adj; /* Pointer to adjcny array */
|
||||
};
|
||||
|
||||
struct Hash_Node {
|
||||
ZOLTAN_ID_PTR gid; /* Pointer to a Global id */
|
||||
int gno; /* Global number */
|
||||
struct Hash_Node * next;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __THIRD_LIBRARY_TOOLS_H */
|
574
thirdParty/Zoltan/src/tpls/verify_graph.c
vendored
Normal file
574
thirdParty/Zoltan/src/tpls/verify_graph.c
vendored
Normal file
@ -0,0 +1,574 @@
|
||||
/*
|
||||
* @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_util_const.h"
|
||||
#include "third_library_const.h"
|
||||
#include "third_library_tools.h"
|
||||
#include "graph_util.h"
|
||||
|
||||
/* comparison routine for bsearch */
|
||||
static int Zoltan_Compare_Indextypes(const void *key, const void *arg);
|
||||
|
||||
#include "zz_sort.h"
|
||||
|
||||
/*********************************************************************/
|
||||
/* Verify ParMetis graph structure. */
|
||||
/* */
|
||||
/* Input parameter graph_type specifies the type of graph: */
|
||||
/* LOCAL_GRAPH - each proc owns a local METIS style graph */
|
||||
/* GLOBAL_GRAPH - the procs share a global ParMETIS graph */
|
||||
/* */
|
||||
/* Input parameter check_graph specifies the level of verification: */
|
||||
/* 0 - perform no checks at all */
|
||||
/* 1 - verify on-processor part of graph */
|
||||
/* 2 - verify complete graph (requires communication) */
|
||||
/* */
|
||||
/* Input parameter output_level specifies the level of verbosity: */
|
||||
/* 0 - suppress warnings */
|
||||
/* 1 - print summary of warnings */
|
||||
/* 2 - detailed output for each warning */
|
||||
/* */
|
||||
/* Output: an error code (the same on all procs) */
|
||||
/* */
|
||||
/* Fatal error : */
|
||||
/* - non-symmetric graph */
|
||||
/* - incorrect vertex number */
|
||||
/* - negative vertex or edge weight */
|
||||
/* */
|
||||
/* Warning : */
|
||||
/* - no vertices or no edges in graph */
|
||||
/* - zero sum of vertex or edge weights */
|
||||
/* - self-edge */
|
||||
/* - multiple edges between a pair of vertices */
|
||||
/* - singletons (vertices with no edges) */
|
||||
/* - non-symmetric edge weights */
|
||||
/* */
|
||||
/*********************************************************************/
|
||||
|
||||
int Zoltan_Verify_Graph(MPI_Comm comm, indextype *vtxdist, indextype *xadj,
|
||||
indextype *adjncy, weighttype *vwgt, weighttype *adjwgt,
|
||||
int vwgt_dim, int ewgt_dim,
|
||||
int graph_type, int check_graph, int output_level)
|
||||
{
|
||||
int flag, cross_edges = 0, mesg_size, sum;
|
||||
int ierr; /* Error in the graph; always return the worst ierr found */
|
||||
int runerr;/* Error running this routine */
|
||||
int nprocs, proc, *proclist, errors, global_errors;
|
||||
int *perm=NULL;
|
||||
int free_adjncy_sort=0;
|
||||
ZOLTAN_COMM_OBJ *comm_plan;
|
||||
static char *yo = "Zoltan_Verify_Graph";
|
||||
char msg[256];
|
||||
ZOLTAN_GNO_TYPE num_obj;
|
||||
int nrecv;
|
||||
indextype *ptr, *ptr1, *ptr2;
|
||||
indextype global_i, global_j;
|
||||
indextype *sendgno=NULL, *recvgno=NULL, *adjncy_sort=NULL;
|
||||
weighttype *sendwgt, *recvwgt;
|
||||
ZOLTAN_GNO_TYPE num_duplicates, num_singletons;
|
||||
ZOLTAN_GNO_TYPE num_selfs, nedges, global_sum, num_zeros;
|
||||
ZOLTAN_GNO_TYPE i, j, ii, k;
|
||||
MPI_Datatype zoltan_gno_mpi_type;
|
||||
|
||||
ierr = ZOLTAN_OK;
|
||||
runerr = ZOLTAN_OK;
|
||||
zoltan_gno_mpi_type = Zoltan_mpi_gno_type();
|
||||
|
||||
/* Make sure all procs have same value of check_graph. */
|
||||
MPI_Allreduce(&check_graph, &i, 1, MPI_INT, MPI_MAX, comm);
|
||||
check_graph = i;
|
||||
|
||||
if (check_graph == 0) /* perform no error checking at all */
|
||||
return ierr;
|
||||
|
||||
/* Get number of procs and my rank */
|
||||
MPI_Comm_size(comm, &nprocs);
|
||||
MPI_Comm_rank(comm, &proc);
|
||||
|
||||
/* Check number of vertices (objects) */
|
||||
num_obj = (ZOLTAN_GNO_TYPE)(vtxdist[proc+1] - vtxdist[proc]);
|
||||
MPI_Reduce(&num_obj, &global_sum, 1, zoltan_gno_mpi_type, MPI_SUM, 0, comm);
|
||||
if ((proc==0) && (global_sum==0)){
|
||||
if (ierr == ZOLTAN_OK) ierr = ZOLTAN_WARN;
|
||||
if (output_level>0)
|
||||
ZOLTAN_PRINT_WARN(proc, yo, "No vertices in graph.");
|
||||
}
|
||||
|
||||
/* Verify that vertex weights are non-negative */
|
||||
num_zeros = 0;
|
||||
if (vwgt_dim){
|
||||
for (i=0; i<num_obj; i++){
|
||||
sum = 0;
|
||||
for (k=0; k<vwgt_dim; k++){
|
||||
if (vwgt[i*vwgt_dim+k] < 0) {
|
||||
sprintf(msg, "Negative object weight of " TPL_WGT_SPEC " for object " ZOLTAN_GNO_SPEC ".",
|
||||
vwgt[i*vwgt_dim+k], i);
|
||||
ZOLTAN_PRINT_ERROR(proc, yo, msg);
|
||||
ierr = ZOLTAN_FATAL;
|
||||
}
|
||||
sum += vwgt[i*vwgt_dim+k];
|
||||
}
|
||||
if (sum == 0){
|
||||
num_zeros++;
|
||||
if (output_level>1) {
|
||||
sprintf(msg, "Zero vertex (object) weights for object " ZOLTAN_GNO_SPEC ".", i);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
if (ierr == ZOLTAN_OK) ierr = ZOLTAN_WARN;
|
||||
}
|
||||
}
|
||||
MPI_Reduce(&num_zeros, &global_sum, 1, zoltan_gno_mpi_type, MPI_SUM, 0, comm);
|
||||
if ((proc==0) && (global_sum>0)){
|
||||
if (ierr == ZOLTAN_OK) ierr = ZOLTAN_WARN;
|
||||
if (output_level>0){
|
||||
sprintf(msg, ZOLTAN_GNO_SPEC " objects have zero weights.", global_sum);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check number of edges */
|
||||
nedges = (ZOLTAN_GNO_TYPE)xadj[num_obj];
|
||||
MPI_Reduce(&nedges, &global_sum, 1, zoltan_gno_mpi_type, MPI_SUM, 0, comm);
|
||||
if ((proc==0) && (global_sum==0)){
|
||||
if (ierr == ZOLTAN_OK) ierr = ZOLTAN_WARN;
|
||||
if (output_level>0)
|
||||
ZOLTAN_PRINT_WARN(proc, yo, "No edges in graph.");
|
||||
}
|
||||
|
||||
/* Verify that edge weights are non-negative */
|
||||
num_zeros = 0;
|
||||
if (ewgt_dim){
|
||||
for (j=0; j<nedges; j++){
|
||||
sum = 0;
|
||||
for (k=0; k<ewgt_dim; k++){
|
||||
if (adjwgt[j*ewgt_dim+k] < 0) {
|
||||
sprintf(msg, "Negative edge weight of " TPL_WGT_SPEC " in edge " ZOLTAN_GNO_SPEC ".",
|
||||
adjwgt[j*ewgt_dim+k], j);
|
||||
ZOLTAN_PRINT_ERROR(proc, yo, msg);
|
||||
ierr = ZOLTAN_FATAL;
|
||||
}
|
||||
sum += adjwgt[j*ewgt_dim+k];
|
||||
}
|
||||
if (sum == 0){
|
||||
num_zeros++;
|
||||
if (output_level>1) {
|
||||
sprintf(msg, "Zero edge (communication) weights for edge " ZOLTAN_GNO_SPEC ".", j);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
if (ierr == ZOLTAN_OK) ierr = ZOLTAN_WARN;
|
||||
}
|
||||
}
|
||||
|
||||
MPI_Reduce(&num_zeros, &global_sum, 1, zoltan_gno_mpi_type, MPI_SUM, 0, comm);
|
||||
if ((proc==0) && (global_sum>0)){
|
||||
if (ierr == ZOLTAN_OK) ierr = ZOLTAN_WARN;
|
||||
if (output_level>0){
|
||||
sprintf(msg, ZOLTAN_GNO_SPEC " edges have zero weights.", global_sum);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify that the graph is symmetric (edge weights, too) */
|
||||
/* Also check for self-edges and multi-edges */
|
||||
|
||||
/* Pre-processing: Check if edge lists are sorted. If not, */
|
||||
/* make a copy and sort so we can save time in the lookups. */
|
||||
flag = 0; /* Assume sorted. */
|
||||
for (i=0; (i<num_obj) && (flag==0); i++){
|
||||
for (ii=xadj[i]; ii<xadj[i+1]-1; ii++){
|
||||
if (adjncy[ii] > adjncy[ii+1]){
|
||||
flag = 1; /* Not sorted. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag){ /* Need to sort. */
|
||||
adjncy_sort = (indextype *) ZOLTAN_MALLOC(nedges*sizeof(indextype));
|
||||
perm = (int *) ZOLTAN_MALLOC(nedges*sizeof(int));
|
||||
free_adjncy_sort = 1;
|
||||
if (nedges && (!adjncy_sort || !perm)){
|
||||
/* Out of memory. */
|
||||
ZOLTAN_PRINT_ERROR(proc, yo, "Out of memory.");
|
||||
runerr = ZOLTAN_MEMERR;
|
||||
}
|
||||
else {
|
||||
for (k=0; k<nedges; k++){
|
||||
adjncy_sort[k] = adjncy[k];
|
||||
perm[k] = k;
|
||||
}
|
||||
if (sizeof(indextype) == sizeof(short)){
|
||||
for (i=0; i<num_obj; i++)
|
||||
Zoltan_quicksort_list_inc_short((short *)adjncy_sort, perm,
|
||||
(int)xadj[i], (int)xadj[i+1]-1);
|
||||
}
|
||||
else if (sizeof(indextype) == sizeof(int)){
|
||||
for (i=0; i<num_obj; i++)
|
||||
Zoltan_quicksort_list_inc_int((int *)adjncy_sort, perm,
|
||||
(int)xadj[i], (int)xadj[i+1]-1);
|
||||
}
|
||||
else if (sizeof(indextype) == sizeof(long)){
|
||||
for (i=0; i<num_obj; i++)
|
||||
Zoltan_quicksort_list_inc_long((long *)adjncy_sort, perm,
|
||||
(int)xadj[i], (int)xadj[i+1]-1);
|
||||
}
|
||||
else if (sizeof(indextype) == sizeof(int64_t)){
|
||||
for (i=0; i<num_obj; i++)
|
||||
Zoltan_quicksort_list_inc_long_long((int64_t*)adjncy_sort, perm,
|
||||
(int)xadj[i], (int)xadj[i+1]-1);
|
||||
}
|
||||
else{
|
||||
ZOLTAN_PRINT_ERROR(proc, yo,
|
||||
"Error in third party library data type support.");
|
||||
ierr = ZOLTAN_FATAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* Already sorted. */
|
||||
adjncy_sort = adjncy;
|
||||
}
|
||||
|
||||
/* First pass: Check on-processor edges and count # off-proc edges */
|
||||
cross_edges = 0;
|
||||
num_selfs = 0;
|
||||
num_duplicates = 0;
|
||||
num_singletons = 0;
|
||||
for (i=0; i<num_obj; i++){
|
||||
if (IS_GLOBAL_GRAPH(graph_type)){
|
||||
global_i = vtxdist[proc]+i;
|
||||
}
|
||||
else{ /* graph_type == LOCAL_GRAPH */
|
||||
global_i = i; /* A bit confusingly, global_i = i for local graphs */
|
||||
}
|
||||
/* Singleton? */
|
||||
if (xadj[i] == xadj[i+1]){
|
||||
num_singletons++;
|
||||
if (output_level>1){
|
||||
sprintf(msg, "Vertex " TPL_IDX_SPEC " has no edges.", global_i);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
}
|
||||
for (ii=xadj[i]; ii<xadj[i+1]; ii++){
|
||||
global_j = adjncy_sort[ii];
|
||||
/* Valid vertex number? */
|
||||
if ((IS_GLOBAL_GRAPH(graph_type) &&
|
||||
((global_j < vtxdist[0]) || (global_j >= vtxdist[nprocs])))
|
||||
|| (IS_LOCAL_GRAPH(graph_type) &&
|
||||
((global_j < 0) || (global_j >= num_obj)))){
|
||||
sprintf(msg, "Edge to invalid vertex " TPL_IDX_SPEC " detected.", global_j);
|
||||
ZOLTAN_PRINT_ERROR(proc, yo, msg);
|
||||
ierr = ZOLTAN_FATAL;
|
||||
}
|
||||
/* Self edge? */
|
||||
if (global_j == global_i){
|
||||
num_selfs++;
|
||||
if (output_level>1){
|
||||
sprintf(msg, "Self edge for vertex " TPL_IDX_SPEC " detected.", global_i);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
}
|
||||
/* Duplicate edge? */
|
||||
if ((ii+1<xadj[i+1]) && (adjncy_sort[ii]==adjncy_sort[ii+1])){
|
||||
num_duplicates++;
|
||||
if (output_level>1){
|
||||
sprintf(msg, "Duplicate edge (" TPL_IDX_SPEC "," TPL_IDX_SPEC ") detected.", global_i, global_j);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
}
|
||||
/* Is global_j a local vertex? */
|
||||
if (IS_LOCAL_GRAPH(graph_type) || (IS_GLOBAL_GRAPH(graph_type) &&
|
||||
(global_j >= vtxdist[proc]) && (global_j < vtxdist[proc+1]))){
|
||||
/* Check if (global_j, global_i) is an edge */
|
||||
if (IS_GLOBAL_GRAPH(graph_type))
|
||||
j = global_j - vtxdist[proc];
|
||||
else /* graph_type == LOCAL_GRAPH */
|
||||
j = global_j;
|
||||
/* Binary search for edge (global_j, global_i) */
|
||||
ptr = (indextype *)bsearch(&global_i, &adjncy_sort[xadj[j]], (int)(xadj[j+1]-xadj[j]),
|
||||
sizeof(indextype), Zoltan_Compare_Indextypes);
|
||||
if (ptr){
|
||||
/* OK, found edge (global_j, global_i) */
|
||||
if ((adjncy_sort==adjncy) && ewgt_dim){
|
||||
/* Compare weights */
|
||||
/* EBEB For now, don't compare weights if we sorted edge lists. */
|
||||
flag = 0;
|
||||
for (k=0; k<ewgt_dim; k++){
|
||||
if (adjwgt[(ptr-adjncy_sort)*ewgt_dim+k] !=
|
||||
adjwgt[ii*ewgt_dim+k]){
|
||||
/* Numerically nonsymmetric */
|
||||
flag = -1;
|
||||
if (ierr == ZOLTAN_OK) ierr = ZOLTAN_WARN;
|
||||
}
|
||||
}
|
||||
if (flag<0 && output_level>0){
|
||||
sprintf(msg, "Graph is numerically nonsymmetric "
|
||||
"in edge (" TPL_IDX_SPEC "," TPL_IDX_SPEC ")", global_i, global_j);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* bsearch failed */
|
||||
sprintf(msg, "Graph is not symmetric. "
|
||||
"Edge (" TPL_IDX_SPEC "," TPL_IDX_SPEC ") exists, but no edge (" TPL_IDX_SPEC "," TPL_IDX_SPEC ").",
|
||||
global_i, global_j, global_j, global_i);
|
||||
ZOLTAN_PRINT_ERROR(proc, yo, msg);
|
||||
ierr = ZOLTAN_FATAL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cross_edges++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sum up warnings so far. */
|
||||
MPI_Reduce(&num_selfs, &global_sum, 1, zoltan_gno_mpi_type, MPI_SUM, 0, comm);
|
||||
if ((proc==0) && (global_sum>0)){
|
||||
if (ierr == ZOLTAN_OK) ierr = ZOLTAN_WARN;
|
||||
if (output_level>0){
|
||||
sprintf(msg, ZOLTAN_GNO_SPEC " self-edges in graph.", global_sum);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
}
|
||||
MPI_Reduce(&num_duplicates, &global_sum, 1, zoltan_gno_mpi_type, MPI_SUM, 0, comm);
|
||||
if ((proc==0) && (global_sum>0)){
|
||||
if (ierr == ZOLTAN_OK) ierr = ZOLTAN_WARN;
|
||||
if (output_level>0){
|
||||
sprintf(msg, ZOLTAN_GNO_SPEC " duplicate edges in graph.", global_sum);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
}
|
||||
MPI_Reduce(&num_singletons, &global_sum, 1, zoltan_gno_mpi_type, MPI_SUM, 0, comm);
|
||||
if ((proc==0) && (global_sum>0)){
|
||||
if (ierr == ZOLTAN_OK) ierr = ZOLTAN_WARN;
|
||||
if (output_level>0){
|
||||
sprintf(msg, ZOLTAN_GNO_SPEC " vertices in the graph are singletons (have no edges).", global_sum);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check if any processor has encountered an error so far */
|
||||
errors = 0;
|
||||
if (ierr == ZOLTAN_WARN)
|
||||
errors |= 1;
|
||||
if (ierr == ZOLTAN_MEMERR)
|
||||
errors |= 2;
|
||||
if (ierr == ZOLTAN_FATAL)
|
||||
errors |= 4;
|
||||
|
||||
MPI_Allreduce(&errors, &global_errors, 1, MPI_INT, MPI_BOR, comm);
|
||||
|
||||
if (global_errors & 4){
|
||||
/* Fatal error: return now */
|
||||
if (free_adjncy_sort) ZOLTAN_FREE(&adjncy_sort);
|
||||
if (free_adjncy_sort) ZOLTAN_FREE(&perm);
|
||||
return ZOLTAN_FATAL;
|
||||
}
|
||||
|
||||
if ((IS_GLOBAL_GRAPH(graph_type)) && (check_graph >= 2)) {
|
||||
/* Test for consistency across processors. */
|
||||
|
||||
/* Allocate space for off-proc data */
|
||||
mesg_size = (2*sizeof(indextype)) + (ewgt_dim * sizeof(weighttype));
|
||||
sendgno = (indextype *) ZOLTAN_MALLOC(cross_edges*mesg_size);
|
||||
recvgno = (indextype *) ZOLTAN_MALLOC(cross_edges*mesg_size);
|
||||
proclist = (int *) ZOLTAN_MALLOC(cross_edges*sizeof(int));
|
||||
|
||||
if (cross_edges && !(sendgno && recvgno && proclist)){
|
||||
ZOLTAN_PRINT_ERROR(proc, yo, "Out of memory.");
|
||||
runerr = ZOLTAN_MEMERR;
|
||||
}
|
||||
else {
|
||||
|
||||
/* Second pass: Copy data to send buffer */
|
||||
nedges = 0;
|
||||
ptr1 = (indextype *) sendgno;
|
||||
for (i=0; i<num_obj; i++){
|
||||
global_i = vtxdist[proc]+i;
|
||||
for (ii=xadj[i]; ii<xadj[i+1]; ii++){
|
||||
global_j = adjncy[ii];
|
||||
/* Is global_j off-proc? */
|
||||
if ((global_j < vtxdist[proc]) || (global_j >= vtxdist[proc+1])){
|
||||
/* Add to list */
|
||||
k=0;
|
||||
while (global_j >= vtxdist[k+1]) k++;
|
||||
proclist[nedges++] = k;
|
||||
/* Copy (global_i,global_j) and corresponding weights to sendgno */
|
||||
*ptr1++ = global_i;
|
||||
*ptr1++ = global_j;
|
||||
for (k=0; k<ewgt_dim; k++){
|
||||
*ptr1++ = adjwgt[ii*ewgt_dim+k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do the irregular communication */
|
||||
runerr = Zoltan_Comm_Create(&comm_plan, cross_edges, proclist, comm,
|
||||
TAG1, &nrecv);
|
||||
if (runerr != ZOLTAN_OK && runerr != ZOLTAN_WARN) {
|
||||
sprintf(msg, "Error %s returned from Zoltan_Comm_Create.",
|
||||
(runerr == ZOLTAN_MEMERR ? "ZOLTAN_MEMERR" : "ZOLTAN_FATAL"));
|
||||
Zoltan_Comm_Destroy(&comm_plan);
|
||||
ZOLTAN_PRINT_ERROR(proc, yo, msg);
|
||||
}
|
||||
else {
|
||||
if (nrecv != cross_edges){
|
||||
sprintf(msg, "Incorrect number of edges to/from proc %d.", proc);
|
||||
ZOLTAN_PRINT_ERROR(proc, yo, msg);
|
||||
ierr = ZOLTAN_FATAL;
|
||||
}
|
||||
|
||||
runerr = Zoltan_Comm_Do(comm_plan, TAG2, (char *)sendgno, mesg_size,
|
||||
(char *)recvgno);
|
||||
Zoltan_Comm_Destroy(&comm_plan);
|
||||
if (runerr != ZOLTAN_OK && runerr != ZOLTAN_WARN) {
|
||||
sprintf(msg, "Error %s returned from Zoltan_Comm_Do.",
|
||||
(runerr == ZOLTAN_MEMERR ? "ZOLTAN_MEMERR" : "ZOLTAN_FATAL"));
|
||||
ZOLTAN_PRINT_ERROR(proc, yo, msg);
|
||||
}
|
||||
else {
|
||||
|
||||
/* Third pass: Compare on-proc data to off-proc data we received */
|
||||
/* sendgno and recvgno should contain the same data except (i,j) is */
|
||||
/* (j,i) */
|
||||
for (i=0, ptr1=sendgno; i<cross_edges; i++){
|
||||
flag = 0;
|
||||
sendwgt = (weighttype *)(ptr1 + 2);
|
||||
for (j=0, ptr2=recvgno; j<cross_edges; j++){
|
||||
recvwgt = (weighttype *)(ptr2 + 2);
|
||||
if ((ptr2[0] == ptr1[1]) && (ptr2[1] == ptr1[0])){
|
||||
/* Found matching edge */
|
||||
flag = 1;
|
||||
/* Check weights */
|
||||
for (k=0; k<ewgt_dim; k++){
|
||||
if (sendwgt[k] != recvwgt[k]){
|
||||
flag = -1;
|
||||
if (ierr == ZOLTAN_OK) ierr = ZOLTAN_WARN;
|
||||
}
|
||||
}
|
||||
if (flag<0 && output_level>0){
|
||||
sprintf(msg, "Edge weight (" TPL_IDX_SPEC "," TPL_IDX_SPEC ") is not symmetric",
|
||||
ptr1[0], ptr1[1]);
|
||||
ZOLTAN_PRINT_WARN(proc, yo, msg);
|
||||
}
|
||||
}
|
||||
ptr2 = (indextype *)(recvwgt + ewgt_dim);
|
||||
}
|
||||
if (!flag){
|
||||
sprintf(msg, "Graph is not symmetric. "
|
||||
"Edge (" TPL_IDX_SPEC "," TPL_IDX_SPEC ") exists, but not (" TPL_IDX_SPEC "," TPL_IDX_SPEC ").",
|
||||
ptr1[0], ptr1[1], ptr1[1], ptr1[0]);
|
||||
ZOLTAN_PRINT_ERROR(proc, yo, msg);
|
||||
ierr = ZOLTAN_FATAL;
|
||||
}
|
||||
ptr1 = (indextype *)(sendwgt + ewgt_dim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free memory */
|
||||
ZOLTAN_FREE(&sendgno);
|
||||
ZOLTAN_FREE(&recvgno);
|
||||
ZOLTAN_FREE(&proclist);
|
||||
}
|
||||
|
||||
if (free_adjncy_sort) ZOLTAN_FREE(&adjncy_sort);
|
||||
if (free_adjncy_sort) ZOLTAN_FREE(&perm);
|
||||
|
||||
/* Compute global error code */
|
||||
errors = 0;
|
||||
if (ierr == ZOLTAN_WARN)
|
||||
errors |= 1;
|
||||
if (ierr == ZOLTAN_MEMERR)
|
||||
errors |= 2;
|
||||
if (ierr == ZOLTAN_FATAL)
|
||||
errors |= 4;
|
||||
|
||||
MPI_Allreduce(&errors, &global_errors, 1, MPI_INT, MPI_BOR, comm);
|
||||
|
||||
if (global_errors & 4){
|
||||
return ZOLTAN_FATAL;
|
||||
}
|
||||
else if (global_errors & 2){
|
||||
return ZOLTAN_MEMERR;
|
||||
}
|
||||
else if (global_errors & 1){
|
||||
return ZOLTAN_WARN;
|
||||
}
|
||||
else {
|
||||
if (proc==0 && output_level>0){
|
||||
printf("ZOLTAN %s: The graph is valid with check_graph = %1d\n",
|
||||
yo, check_graph);
|
||||
}
|
||||
return ZOLTAN_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* comparison routine for bsearch */
|
||||
static int Zoltan_Compare_Indextypes(const void *key, const void *arg)
|
||||
{
|
||||
if ( *(indextype*) key > (*(indextype*) arg)) return 1;
|
||||
if ( *(indextype*) key < (*(indextype*) arg)) return -1;
|
||||
|
||||
return 0; /* equal */
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* closing bracket for extern "C" */
|
||||
#endif
|
Reference in New Issue
Block a user