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.
130 lines
4.1 KiB
130 lines
4.1 KiB
2 years ago
|
/*
|
||
|
* 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 "defs.h" // for TRUE
|
||
|
#include "smalloc.h" // for smalloc, sfree
|
||
|
#include "structs.h" // for vtx_data
|
||
|
|
||
|
void mapper(struct vtx_data **graph, /* data structure with vertex weights */
|
||
|
double **xvecs, /* continuous indicator vectors */
|
||
|
int nvtxs, /* number of vtxs in graph */
|
||
|
int *active, /* space for nmyvals ints */
|
||
|
int *sets, /* returned processor assignment for my vtxs */
|
||
|
int ndims, /* number of dimensions being divided into */
|
||
|
int cube_or_mesh, /* 0 => hypercube, d => d-dimensional mesh */
|
||
|
int nsets, /* number of sets to divide into */
|
||
|
int mediantype, /* type of eigenvector partitioning to use */
|
||
|
double *goal, /* desired set sizes */
|
||
|
int vwgt_max /* largest vertex weight */
|
||
|
)
|
||
|
{
|
||
|
double temp_goal[2]; /* combined set goals if using option 1. */
|
||
|
double wbelow; /* weight of vertices with negative values */
|
||
|
double wabove; /* weight of vertices with positive values */
|
||
|
int *temp_sets; /* sets vertices get assigned to */
|
||
|
int vweight; /* weight of a vertex */
|
||
|
int using_vwgts; /* are vertex weights being used? */
|
||
|
int bits; /* bits for assigning set numbers */
|
||
|
int i, j; /* loop counters */
|
||
|
|
||
|
/* NOTE: THIS EXPECTS XVECS, NOT YVECS! */
|
||
|
|
||
|
using_vwgts = (vwgt_max != 1);
|
||
|
|
||
|
if (ndims == 1 && mediantype == 1) {
|
||
|
mediantype = 3; /* simpler call than normal option 1. */
|
||
|
}
|
||
|
|
||
|
if (mediantype == 0) { /* Divide at zero instead of median. */
|
||
|
bits = 1;
|
||
|
temp_sets = smalloc((nvtxs + 1) * sizeof(int));
|
||
|
for (j = 1; j <= nvtxs; j++) {
|
||
|
sets[j] = 0;
|
||
|
}
|
||
|
|
||
|
for (i = 1; i <= ndims; i++) {
|
||
|
temp_goal[0] = temp_goal[1] = 0;
|
||
|
for (j = 0; j < (1 << ndims); j++) {
|
||
|
if (bits & j) {
|
||
|
temp_goal[1] += goal[j];
|
||
|
}
|
||
|
else {
|
||
|
temp_goal[0] += goal[j];
|
||
|
}
|
||
|
}
|
||
|
bits <<= 1;
|
||
|
|
||
|
wbelow = wabove = 0;
|
||
|
vweight = 1;
|
||
|
for (j = 1; j <= nvtxs; j++) {
|
||
|
if (using_vwgts) {
|
||
|
vweight = graph[j]->vwgt;
|
||
|
}
|
||
|
if (xvecs[i][j] < 0) {
|
||
|
wbelow += vweight;
|
||
|
}
|
||
|
else if (xvecs[i][j] > 0) {
|
||
|
wabove += vweight;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
median_assign(graph, xvecs[i], nvtxs, temp_goal, using_vwgts, temp_sets, wbelow, wabove, 0.0);
|
||
|
|
||
|
for (j = 1; j <= nvtxs; j++) {
|
||
|
sets[j] = (sets[j] << 1) + temp_sets[j];
|
||
|
}
|
||
|
}
|
||
|
sfree(temp_sets);
|
||
|
}
|
||
|
|
||
|
else if (mediantype == 1) { /* Divide using min-cost assignment. */
|
||
|
if (ndims == 2) {
|
||
|
map2d(graph, xvecs, nvtxs, sets, goal, vwgt_max);
|
||
|
}
|
||
|
else if (ndims == 3) {
|
||
|
map3d(graph, xvecs, nvtxs, sets, goal, vwgt_max);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else if (mediantype == 2) { /* Divide recursively using medians. */
|
||
|
rec_median_k(graph, xvecs, nvtxs, active, ndims, cube_or_mesh, goal, using_vwgts, sets);
|
||
|
}
|
||
|
|
||
|
else if (mediantype == 3) { /* Cut with independent medians => unbalanced. */
|
||
|
bits = 1;
|
||
|
temp_sets = smalloc((nvtxs + 1) * sizeof(int));
|
||
|
for (j = 1; j <= nvtxs; j++) {
|
||
|
sets[j] = 0;
|
||
|
}
|
||
|
|
||
|
for (i = 1; i <= ndims; i++) {
|
||
|
temp_goal[0] = temp_goal[1] = 0;
|
||
|
for (j = 0; j < (1 << ndims); j++) {
|
||
|
if (bits & j) {
|
||
|
temp_goal[1] += goal[j];
|
||
|
}
|
||
|
else {
|
||
|
temp_goal[0] += goal[j];
|
||
|
}
|
||
|
}
|
||
|
bits <<= 1;
|
||
|
|
||
|
median(graph, xvecs[i], nvtxs, active, temp_goal, using_vwgts, temp_sets);
|
||
|
for (j = 1; j <= nvtxs; j++) {
|
||
|
sets[j] = (sets[j] << 1) + temp_sets[j];
|
||
|
}
|
||
|
}
|
||
|
sfree(temp_sets);
|
||
|
}
|
||
|
|
||
|
if (mediantype == 4) { /* Stripe the domain. */
|
||
|
rec_median_1(graph, xvecs[1], nvtxs, active, cube_or_mesh, nsets, goal, using_vwgts, sets,
|
||
|
TRUE);
|
||
|
}
|
||
|
}
|