diff --git a/src/con-unique-vertices.c b/src/con-unique-vertices.c index f610dc8b..7ca3069f 100644 --- a/src/con-unique-vertices.c +++ b/src/con-unique-vertices.c @@ -357,9 +357,9 @@ static slong number_segments(struct array *local, struct array *shared, return st + lt; } -static int number_points(struct array *elems, const struct array *local, - const struct array *shared, const struct comm *c, - buffer *bfr) { +static void number_points(struct array *elems, const struct array *local, + const struct array *shared, const struct comm *c, + buffer *bfr) { // First number local points and then number shared points. slong out[2][1], wrk[2][1], in = local->n; comm_scan(out, c, gs_long, gs_add, &in, 1, wrk); diff --git a/src/laplacian.c b/src/laplacian.c index db0b84ba..5973a166 100644 --- a/src/laplacian.c +++ b/src/laplacian.c @@ -90,31 +90,6 @@ static int par_csr_init(struct laplacian *l, const struct rsb_element *elems, return 0; } -static int par_csc_init(struct laplacian *l, const struct rsb_element *elems, - const uint nelt, const int nv, const struct comm *c, - buffer *bfr) { - struct crystal cr; - crystal_init(&cr, c); - - struct array nbrs, eij; - find_nbrs_rsb(&nbrs, elems, nelt, nv, c, &cr, bfr); - compress_nbrs(&eij, &nbrs, bfr); - - struct csr_laplacian *L = l->data = tcalloc(struct csr_laplacian, 1); - struct par_mat *M = L->M = par_csc_setup_ext(&eij, 1, bfr); - L->gsh = setup_Q(L->M, c, bfr); - - uint nnz = M->rn > 0 ? M->adj_off[M->rn] + M->rn : 0; - L->buf = tcalloc(scalar, nnz); - - crystal_free(&cr); - - array_free(&nbrs); - array_free(&eij); - - return 0; -} - static int par_csr(scalar *v, const struct laplacian *l, scalar *u, buffer *bfr) { struct csr_laplacian *L = (struct csr_laplacian *)l->data; @@ -125,20 +100,6 @@ static int par_csr(scalar *v, const struct laplacian *l, scalar *u, return 1; } -static int par_csc(scalar *v, const struct laplacian *l, scalar *u, - buffer *bfr) { -#if 0 - struct csr_laplacian *L = (struct csr_laplacian *)l->data; - if (L != NULL) { - mat_vec_csr(v, u, L->M, L->gsh, L->buf, bfr); - return 0; - } - return 1; -#else - return 1; -#endif -} - static int par_csr_free(struct laplacian *l) { if (l->data != NULL) { struct csr_laplacian *L = (struct csr_laplacian *)l->data; @@ -217,7 +178,7 @@ static int gs_weighted_free(struct laplacian *l) { if (gl->diag != NULL) free(gl->diag); gs_free(gl->gsh); - free(l->data); + free(l->data), l->data = NULL; return 0; } @@ -233,8 +194,6 @@ struct laplacian *laplacian_init(struct rsb_element *elems, uint nel, int nv, if (type & CSR) par_csr_init(l, elems, nel, nv, c, buf); - else if (type & CSC) - par_csc_init(l, elems, nel, nv, c, buf); else if (type & GS) gs_weighted_init(l, elems, nel, nv, c, buf); else @@ -246,8 +205,6 @@ struct laplacian *laplacian_init(struct rsb_element *elems, uint nel, int nv, int laplacian(scalar *v, struct laplacian *l, scalar *u, buffer *buf) { if (l->type & CSR) par_csr(v, l, u, buf); - else if (l->type & CSC) - par_csc(v, l, u, buf); else if (l->type & GS) gs_weighted(v, l, u, buf); else diff --git a/src/parrsb-impl.h b/src/parrsb-impl.h index e34319e2..3fa90d59 100644 --- a/src/parrsb-impl.h +++ b/src/parrsb-impl.h @@ -63,7 +63,6 @@ uint get_components_v2(sint *component, struct array *elems, unsigned nv, // #define GS 1 #define CSR 2 -#define CSC 4 struct laplacian; struct laplacian *laplacian_init(struct rsb_element *elems, uint nel, int nv, diff --git a/src/rcb.c b/src/rcb.c index 5defa8c5..802c5ced 100644 --- a/src/rcb.c +++ b/src/rcb.c @@ -143,9 +143,7 @@ int rcb(struct array *elements, size_t unit_size, int ndim, struct comm *ci, struct comm c, t; comm_dup(&c, ci); - int size = c.np; - int rank = c.id; - + int size = c.np, rank = c.id; while (size > 1) { rcb_level(elements, unit_size, ndim, &c, bfr); diff --git a/src/rib.c b/src/rib.c index 1aac9031..889848b6 100644 --- a/src/rib.c +++ b/src/rib.c @@ -2,18 +2,14 @@ #include "sort.h" extern int power_serial(double *y, int N, double *A, int verbose); +extern int inv_power_serial(double *y, uint N, double *A, int verbose); -static void get_rib_axis(char *elems, uint nel, size_t unit_size, int ndim, +static void get_rib_proj(char *elems, uint nel, size_t unit_size, int ndim, struct comm *c) { - double avg[3]; - avg[0] = avg[1] = avg[2] = 0.0; - struct rcb_element *elem; - uint i; - for (i = 0; i < nel; i++) { - elem = (struct rcb_element *)(elems + i * unit_size); - avg[0] += elem->coord[0]; - avg[1] += elem->coord[1]; - avg[2] += elem->coord[2]; + double avg[3] = {0, 0, 0}; + for (uint i = 0; i < nel; i++) { + struct rcb_element *ei = (struct rcb_element *)(elems + i * unit_size); + avg[0] += ei->coord[0], avg[1] += ei->coord[1], avg[2] += ei->coord[2]; } slong nelg = nel; @@ -23,37 +19,44 @@ static void get_rib_axis(char *elems, uint nel, size_t unit_size, int ndim, comm_allreduce(c, gs_long, gs_add, &nelg, 1, buf); } - avg[0] /= nelg; - avg[1] /= nelg; - avg[2] /= nelg; + avg[0] /= nelg, avg[1] /= nelg, avg[2] /= nelg; - double I[3][3]; - for (i = 0; i < 3; i++) - I[i][0] = I[i][1] = I[i][2] = 0.0; + double I[9]; + for (unsigned i = 0; i < 9; i++) + I[i] = 0; double x, y, z; - for (i = 0; i < nel; i++) { - elem = (struct rcb_element *)(elems + i * unit_size); - x = elem->coord[0] - avg[0]; - y = elem->coord[1] - avg[1]; - z = elem->coord[2] - avg[2]; - I[0][0] += x * x, I[0][1] += x * y, I[0][2] += x * z; - I[1][0] += y * x, I[1][1] += y * y, I[1][2] += y * z; - I[2][0] += z * x, I[2][1] += z * y, I[2][2] += z * z; + for (uint i = 0; i < nel; i++) { + struct rcb_element *ei = (struct rcb_element *)(elems + i * unit_size); + x = ei->coord[0] - avg[0]; + y = ei->coord[1] - avg[1]; + z = ei->coord[2] - avg[2]; + I[0] += x * x, I[1] += x * y, I[2] += x * z; + I[3] += y * x, I[4] += y * y, I[5] += y * z; + I[6] += z * x, I[7] += z * y, I[8] += z * z; } if (c != NULL) comm_allreduce(c, gs_double, gs_add, I, 9, buf); - double ev[3]; // ev[2] = 0 if 2D - power_serial(ev, ndim, (double *)I, 0); // FIXME: 2D does not work + // FIXME: 2D does not work + double ev[3]; + power_serial(ev, ndim, (double *)I, 0); - for (i = 0; i < nel; i++) { - elem = (struct rcb_element *)(elems + i * unit_size); - x = elem->coord[0] - avg[0]; - y = elem->coord[1] - avg[1]; - z = elem->coord[2] - avg[2]; - elem->fiedler = x * ev[0] + y * ev[1] + z * ev[2]; + double norm = 0; + for (unsigned i = 0; i < ndim; i++) + norm += ev[i] * ev[i]; + norm = sqrt(norm); + + for (unsigned i = 0; i < ndim; i++) + ev[i] /= norm; + + for (uint i = 0; i < nel; i++) { + struct rcb_element *ei = (struct rcb_element *)(elems + i * unit_size); + x = ei->coord[0] - avg[0]; + y = ei->coord[1] - avg[1]; + z = ei->coord[2] - avg[2]; + ei->fiedler = x * ev[0] + y * ev[1] + z * ev[2]; } } @@ -64,7 +67,7 @@ void rib_local(struct array *a, size_t unit_size, uint start, uint end, return; char *st = (char *)a->ptr + unit_size * start; - get_rib_axis(st, size, unit_size, ndim, NULL); + get_rib_proj(st, size, unit_size, ndim, NULL); if (unit_size == sizeof(struct rcb_element)) sarray_sort(struct rcb_element, st, size, fiedler, 3, buf); @@ -81,7 +84,7 @@ static int rib_level(struct array *a, size_t unit_size, int ndim, if (c->np == 1) return 0; - get_rib_axis((char *)a->ptr, a->n, unit_size, ndim, c); + get_rib_proj((char *)a->ptr, a->n, unit_size, ndim, c); if (unit_size == sizeof(struct rcb_element)) parallel_sort(struct rcb_element, a, fiedler, gs_double, 0, 1, c, bfr); @@ -93,26 +96,23 @@ static int rib_level(struct array *a, size_t unit_size, int ndim, int rib(struct array *elements, size_t unit_size, int ndim, struct comm *ci, buffer *bfr) { - struct comm c; + struct comm c, t; comm_dup(&c, ci); - int size = c.np; - int rank = c.id; - + int size = c.np, rank = c.id; while (size > 1) { rib_level(elements, unit_size, ndim, &c, bfr); - int p = (size + 1) / 2; - int bin = (rank >= p); + int bin = 1; + if (rank < (size + 1) / 2) + bin = 0; - MPI_Comm comm_rib; - MPI_Comm_split(c.c, bin, rank, &comm_rib); + comm_split(&c, bin, rank, &t); comm_free(&c); - comm_init(&c, comm_rib); - MPI_Comm_free(&comm_rib); + comm_dup(&c, &t); + comm_free(&t); - size = c.np; - rank = c.id; + size = c.np, rank = c.id; } comm_free(&c); diff --git a/src/rsb.c b/src/rsb.c index d38da260..fc0d5573 100644 --- a/src/rsb.c +++ b/src/rsb.c @@ -10,6 +10,8 @@ extern int rsb(struct array *elements, int nv, int check, parrsb_options *options, struct comm *gc, buffer *bfr); extern int rcb(struct array *elements, size_t unit_size, int ndim, struct comm *ci, buffer *bfr); +extern int rib(struct array *elements, size_t unit_size, int ndim, + struct comm *ci, buffer *bfr); parrsb_options parrsb_default_options = { // General options @@ -99,11 +101,11 @@ static size_t load_balance(struct array *elist, uint nel, int nv, double *coord, unit_size = sizeof(struct rsb_element); array_init_(elist, nel, unit_size, __FILE__, __LINE__); + elist->n = 0; + int ndim = (nv == 8) ? 3 : 2; struct rcb_element *pe = (struct rcb_element *)calloc(1, unit_size); pe->origin = c->id; - - int ndim = (nv == 8) ? 3 : 2; for (uint e = 0; e < nel; ++e) { slong eg = pe->globalId = start + e + 1; if (nstar == 0)