You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
5.7 KiB
155 lines
5.7 KiB
/*
|
|
* Copyright(C) 1999-2020, 2023 National Technology & Engineering Solutions
|
|
* of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
|
|
* NTESS, the U.S. Government retains certain rights in this software.
|
|
*
|
|
* See packages/seacas/LICENSE for details
|
|
*/
|
|
|
|
#include "params.h" // for MAXSETS
|
|
#include "structs.h" // for vtx_data, bilist
|
|
#include <stdio.h> // for NULL
|
|
|
|
/* Idea:
|
|
'buckets[i][j]' is a set of buckets to sort moves from i to j.
|
|
listspace[i] is space for lists in buckets[i][j].
|
|
Loop through all nonequal pairs [i][j], taking the first element
|
|
in each list. Compare them all to find the largest allowed move.
|
|
Make that move, and save it in movelist.
|
|
*/
|
|
|
|
/* Routine slightly streamlined for case with only two sets. */
|
|
|
|
void bucketsorts_bi(struct vtx_data **graph, /* graph data structure */
|
|
int nvtxs, /* number of vertices */
|
|
struct bilist ****buckets, /* array of lists for bucket sort */
|
|
struct bilist **listspace, /* list data structure for each vertex */
|
|
int **dvals, /* d-values for each vertex for removing */
|
|
int *sets, /* processor each vertex is assigned to */
|
|
float *term_wgts[], /* weights for terminal propagation */
|
|
int maxdval, /* maximum possible dvalue for a vertex */
|
|
int nsets, /* number of sets being divided into */
|
|
int parity, /* work in forward or backward direction? */
|
|
int (*hops)[MAXSETS], /* hop cost between sets */
|
|
int *bspace, /* indices for randomly ordering vtxs */
|
|
int list_length, /* number of values in bspace to work with */
|
|
int npass, /* which pass through KL is this? */
|
|
int using_ewgts /* are edge weights being used? */
|
|
)
|
|
{
|
|
extern int KL_RANDOM; /* use randomness in KL? */
|
|
extern int KL_UNDO_LIST; /* only sort vertices who have moved. */
|
|
extern double CUT_TO_HOP_COST; /* ..if so, relative cut/hop importance */
|
|
struct bilist **bptr = NULL; /* loops through set of buckets */
|
|
struct bilist *lptr = NULL; /* pointer to an element in listspace */
|
|
float *ewptr = NULL; /* loops through edge weights */
|
|
float *twptr = NULL; /* weights for terminal propagation */
|
|
int *bsptr = NULL; /* loops through bspace */
|
|
int *edges = NULL; /* edge list for a vertex */
|
|
int myset; /* set current vertex belongs to */
|
|
int other_set; /* set current vertex doesn't belong to */
|
|
int set; /* set that neighboring vertex belongs to */
|
|
int weight; /* edge weight for a particular edge */
|
|
int vtx; /* vertex in graph */
|
|
int val; /* terminal propagation rounded value */
|
|
double cut_cost; /* relative cut/hop importance */
|
|
double hop_cost; /* relative hop/cut importance */
|
|
int myhop; /* hops associated with current vertex */
|
|
int i, j; /* loop counters */
|
|
|
|
/* For each vertex, compute d-values for each possible transition. */
|
|
/* Then store them in each appropriate bucket. */
|
|
|
|
if (npass == 1 || !KL_UNDO_LIST || list_length == nvtxs) {
|
|
/* Empty all the buckets. */
|
|
/* Last clause catches case where lists weren't undone. */
|
|
bptr = buckets[0][1];
|
|
for (i = nsets * (nsets - 1) * (2 * maxdval + 1); i; i--) {
|
|
*bptr++ = NULL;
|
|
}
|
|
}
|
|
|
|
/* Randomize the order of the vertices */
|
|
|
|
if ((KL_UNDO_LIST && list_length == nvtxs) || !KL_UNDO_LIST) {
|
|
list_length = nvtxs;
|
|
bsptr = bspace;
|
|
if (parity) {
|
|
for (i = 1; i <= nvtxs; i++) {
|
|
*bsptr++ = i;
|
|
}
|
|
}
|
|
else {
|
|
for (i = nvtxs; i; i--) {
|
|
*bsptr++ = i;
|
|
}
|
|
}
|
|
}
|
|
if (KL_RANDOM) {
|
|
randomize(bspace - 1, list_length);
|
|
}
|
|
|
|
/* Now compute d-vals by seeing which sets neighbors belong to. */
|
|
cut_cost = hop_cost = 1;
|
|
if (term_wgts[1] != NULL) {
|
|
if (CUT_TO_HOP_COST > 1) {
|
|
cut_cost = CUT_TO_HOP_COST;
|
|
}
|
|
else {
|
|
hop_cost = 1.0 / CUT_TO_HOP_COST;
|
|
}
|
|
}
|
|
|
|
weight = cut_cost + .5;
|
|
|
|
bsptr = bspace;
|
|
twptr = term_wgts[1];
|
|
for (i = 0; i < list_length; i++) { /* Loop through vertices. */
|
|
vtx = *bsptr++;
|
|
myset = sets[vtx];
|
|
other_set = !myset;
|
|
|
|
/* Initialize all the preference values. */
|
|
if (twptr != NULL) {
|
|
/* Using terminal propagation. Round to integer value. */
|
|
if (twptr[vtx] < 0) {
|
|
val = -twptr[vtx] * hop_cost + .5;
|
|
val = -val;
|
|
}
|
|
else {
|
|
val = twptr[vtx] * hop_cost + .5;
|
|
}
|
|
if (myset == 0) {
|
|
dvals[vtx][0] = val;
|
|
}
|
|
else {
|
|
dvals[vtx][0] = -val;
|
|
}
|
|
}
|
|
else {
|
|
dvals[vtx][0] = 0;
|
|
}
|
|
|
|
/* First count the neighbors in each set. */
|
|
edges = graph[vtx]->edges;
|
|
if (using_ewgts) {
|
|
ewptr = graph[vtx]->ewgts;
|
|
}
|
|
for (j = graph[vtx]->nedges - 1; j; j--) {
|
|
set = sets[*(++edges)];
|
|
if (set < 0) {
|
|
set = -set - 1;
|
|
}
|
|
if (using_ewgts) {
|
|
weight = *(++ewptr) * cut_cost + .5;
|
|
}
|
|
myhop = hops[myset][set];
|
|
|
|
dvals[vtx][0] += weight * (myhop - hops[other_set][set]);
|
|
}
|
|
|
|
/* Now add to appropriate buckets. */
|
|
lptr = listspace[0];
|
|
add2bilist(&lptr[vtx], &buckets[myset][other_set][dvals[vtx][0] + maxdval]);
|
|
}
|
|
}
|
|
|