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.
159 lines
5.5 KiB
159 lines
5.5 KiB
/*
|
|
* Copyright(C) 1999-2020, 2022, 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 "defs.h" // for FALSE
|
|
#include "params.h" // for MAXSETS
|
|
#include "smalloc.h" // for sfree
|
|
#include "structs.h"
|
|
#include <stdio.h> // for printf, fprintf, NULL, FILE
|
|
struct bilist;
|
|
|
|
/* Think hard about space.
|
|
Put active list into each routine.
|
|
|
|
It may be possible to overlap dvals with active in kl, requiring
|
|
a total of nvtxs space.
|
|
*/
|
|
static void free_kl(
|
|
/* Free everything malloc'd for KL. */
|
|
struct bilist ****buckets, /* space for bucket sorts */
|
|
struct bilist **listspace, /* space for all bidirectional elements */
|
|
int **dvals, /* change in penalty for each possible move */
|
|
int **tops /* starting dval for each type of move */
|
|
);
|
|
|
|
void klspiff(struct vtx_data **graph, /* list of graph info for each vertex */
|
|
int nvtxs, /* number of vertices in graph */
|
|
int *sets, /* local partitioning of vtxs */
|
|
int nsets, /* number of sets at each level */
|
|
int (*hops)[MAXSETS], /* hop cost between sets */
|
|
double *goal, /* desired set sizes */
|
|
float *term_wgts[], /* weights for terminal propagation */
|
|
int max_dev, /* largest deviation from balance allowed */
|
|
double maxdeg, /* largest weighted vertex degree */
|
|
int using_ewgts, /* are edge weights being used? */
|
|
int **bndy_list, /* list of vertices on boundary (0 ends) */
|
|
double *weights /* vertex weights in each set */
|
|
)
|
|
{
|
|
extern FILE *Output_File; /* output file or null */
|
|
extern double CUT_TO_HOP_COST; /* relative importance of cuts/hops */
|
|
extern int DEBUG_TRACE; /* debug flag for Kernighan-Lin */
|
|
extern int DEBUG_KL; /* debug flag for Kernighan-Lin */
|
|
extern double kl_total_time;
|
|
extern double kl_init_time;
|
|
extern double nway_kl_time;
|
|
struct bilist ****buckets; /* space for bucket sorts */
|
|
struct bilist **listspace; /* space for all bidirectional elements */
|
|
float *twptr; /* loops through term_wgts */
|
|
int **dvals; /* change in penalty for each possible move */
|
|
int **tops; /* starting dval for each type of move */
|
|
double time, time1; /* timing variables */
|
|
float maxterm; /* largest terminal propagation preference */
|
|
int maxhop; /* maximum hops between sets */
|
|
int maxdval; /* largest transition cost for a vertex */
|
|
double cut_cost; /* relative importance of cuts/hops */
|
|
double hop_cost; /* relative importance of hops/cuts */
|
|
int error; /* out of space? */
|
|
int i, j; /* loop counters */
|
|
|
|
time = seconds();
|
|
|
|
if (DEBUG_TRACE > 0) {
|
|
printf("<Entering klspiff, nvtxs = %d>\n", nvtxs);
|
|
}
|
|
|
|
/* Find the largest hop value. */
|
|
maxhop = 0;
|
|
for (i = 0; i < nsets; i++) {
|
|
for (j = 0; j < nsets; j++) {
|
|
if (hops[i][j] > maxhop) {
|
|
maxhop = hops[i][j];
|
|
}
|
|
}
|
|
}
|
|
|
|
maxterm = 0;
|
|
cut_cost = hop_cost = 1;
|
|
if (term_wgts[1] != NULL) {
|
|
for (j = 1; j < nsets; j++) {
|
|
twptr = term_wgts[j];
|
|
for (i = nvtxs; i; i--) {
|
|
++twptr;
|
|
if (*twptr > maxterm) {
|
|
maxterm = *twptr;
|
|
}
|
|
else if (-*twptr > maxterm) {
|
|
maxterm = -*twptr;
|
|
}
|
|
}
|
|
}
|
|
if (CUT_TO_HOP_COST > 1) {
|
|
cut_cost = CUT_TO_HOP_COST;
|
|
}
|
|
else {
|
|
hop_cost = 1.0 / CUT_TO_HOP_COST;
|
|
}
|
|
}
|
|
|
|
maxdval = (2 * maxterm * hop_cost + .5) + (maxdeg * cut_cost + .5) * maxhop;
|
|
|
|
/* Allocate a bunch of space for KL. */
|
|
time1 = seconds();
|
|
error = kl_init(&buckets, &listspace, &dvals, &tops, nvtxs, nsets, maxdval);
|
|
kl_init_time += seconds() - time1;
|
|
|
|
if (!error) {
|
|
if (DEBUG_KL > 0) {
|
|
printf(" Before KL: ");
|
|
count(graph, nvtxs, sets, nsets, hops, FALSE, using_ewgts);
|
|
}
|
|
|
|
time1 = seconds();
|
|
error = nway_kl(graph, nvtxs, buckets, listspace, tops, dvals, sets, maxdval, nsets, goal,
|
|
term_wgts, hops, max_dev, using_ewgts, bndy_list, weights);
|
|
nway_kl_time += seconds() - time1;
|
|
|
|
if (DEBUG_KL > 1) {
|
|
printf(" After KL:");
|
|
count(graph, nvtxs, sets, nsets, hops, FALSE, using_ewgts);
|
|
}
|
|
}
|
|
|
|
if (error) {
|
|
printf("\nWARNING: No space to perform KL on graph with %d vertices.\n", nvtxs);
|
|
printf(" NO LOCAL REFINEMENT PERFORMED.\n\n");
|
|
|
|
if (Output_File != NULL) {
|
|
fprintf(Output_File, "\nWARNING: No space to perform KL on graph with %d vertices.\n", nvtxs);
|
|
fprintf(Output_File, " LOCAL REFINEMENT NOT PERFORMED.\n\n");
|
|
}
|
|
}
|
|
|
|
free_kl(buckets, listspace, dvals, tops);
|
|
|
|
kl_total_time += seconds() - time;
|
|
}
|
|
|
|
static void free_kl(
|
|
/* Free everything malloc'd for KL. */
|
|
struct bilist ****buckets, /* space for bucket sorts */
|
|
struct bilist **listspace, /* space for all bidirectional elements */
|
|
int **dvals, /* change in penalty for each possible move */
|
|
int **tops /* starting dval for each type of move */
|
|
)
|
|
{
|
|
|
|
sfree(dvals);
|
|
sfree(tops);
|
|
|
|
sfree(listspace[0]);
|
|
sfree(buckets[0][1]);
|
|
sfree(listspace);
|
|
sfree(buckets);
|
|
}
|
|
|