/* attach constraints to bodies after reading */ static void dom_attach_constraints (DOM *dom) { BODY *bod; CON *con; for (bod = dom->bod; bod; bod = bod->next) SET_Free (&dom->setmem, &bod->con); for (con = dom->con; con; con = con->next) { if (con->master) { ASSERT_DEBUG (MAP_Find_Node (dom->idb, (void*) (long) con->master->id, NULL), "Invalid master id"); SET_Insert (&dom->setmem, &con->master->con, con, NULL); } if (con->slave) { ASSERT_DEBUG (MAP_Find_Node (dom->idb, (void*) (long) con->slave->id, NULL), "Invalid slave id"); SET_Insert (&dom->setmem, &con->slave->con, con, NULL); } } }
/* pick leaves overlapping the extents */ void KDT_Pick_Extents (KDT *kd, double *extents, SET **leaves) { if (kd->d < 0) /* leaf */ { SET_Insert (NULL, leaves, kd, NULL); } else if (extents [kd->d+3] <= kd->p [kd->d]) KDT_Pick_Extents (kd->l, extents, leaves); else if (extents [kd->d] > kd->p [kd->d]) KDT_Pick_Extents (kd->r, extents, leaves); else { KDT_Pick_Extents (kd->l, extents, leaves); KDT_Pick_Extents (kd->r, extents, leaves); } }
/* receive reactions updated by middle nodes */ static void receive_middle_reactions (DOM *dom, COMDATA *recv, int nrecv, MEM *setmem, SET **midupd) { COMDATA *ptr; int i, j, *k; CON *con; for (i = 0, ptr = recv; i < nrecv; i ++, ptr ++) { for (j = 0, k = ptr->i; j < ptr->ints; j ++, k ++) { ASSERT_DEBUG_EXT (con = MAP_Find (dom->conext, (void*) (long) (*k), NULL), "Invalid constraint id"); SET_Insert (setmem, midupd, con, NULL); } } }
/* read domain state */ void dom_read_state (DOM *dom, PBF *bf) { BODY *bod, *next; int ncon; /* clear contacts */ MAP_Free (&dom->mapmem, &dom->idc); MEM_Release (&dom->conmem); dom->con = NULL; dom->ncon = 0; /* read all bodies if needed */ if (!dom->allbodiesread) read_new_bodies (dom, bf); /* mark all bodies as absent */ for (bod = dom->bod; bod; bod = bod->next) bod->flags |= BODY_ABSENT; SET *usedlabel = NULL; for (; bf; bf = bf->next) { if (PBF_Label (bf, "DOM")) { /* read iover */ int iover = 2; if (PBF_Label (bf, "IOVER")) { PBF_Int (bf, &iover, 1); } /* read time step */ ASSERT (PBF_Label (bf, "STEP"), ERR_FILE_FORMAT); PBF_Double (bf, &dom->step, 1); /* read constraints merit */ ASSERT (PBF_Label (bf, "MERIT"), ERR_FILE_FORMAT); PBF_Double (bf, &dom->merit, 1); /* read body states */ ASSERT (PBF_Label (bf, "BODS"), ERR_FILE_FORMAT); int nbod; PBF_Int (bf, &nbod, 1); for (int n = 0; n < nbod; n ++) { unsigned int id; PBF_Uint (bf, &id, 1); bod = MAP_Find (dom->idb, (void*) (long) id, NULL); if (bod == NULL) /* pick from all bodies set */ { ASSERT_DEBUG_EXT (bod = MAP_Find (dom->allbodies, (void*) (long) id, NULL), "Body id invalid"); if (bod->label) { MAP *node = MAP_Find_Node (dom->lab, bod->label, (MAP_Compare)strcmp); if (node) { node->data = bod; /* body fregments can inherit labels */ SET_Insert (NULL, &usedlabel, bod->label, (SET_Compare)strcmp); } else MAP_Insert (&dom->mapmem, &dom->lab, bod->label, bod, (MAP_Compare) strcmp); } MAP_Insert (&dom->mapmem, &dom->idb, (void*) (long) bod->id, bod, NULL); bod->next = dom->bod; if (dom->bod) dom->bod->prev = bod; dom->bod = bod; bod->dom = dom; dom->nbod ++; } BODY_Read_State (bod, bf, iover); bod->flags &= ~BODY_ABSENT; } /* read constraints */ ASSERT (PBF_Label (bf, "CONS"), ERR_FILE_FORMAT); PBF_Int (bf, &ncon, 1); for (int n = 0; n < ncon; n ++) { CON *con; con = read_constraint (dom, iover, bf); MAP_Insert (&dom->mapmem, &dom->idc, (void*) (long) con->id, con, NULL); con->next = dom->con; if (dom->con) dom->con->prev = con; dom->con = con; } dom->ncon += ncon; } } /* remove absent bodies */ for (bod = dom->bod; bod; bod = next) { next = bod->next; if (bod->flags & BODY_ABSENT) { if (bod->label && !SET_Contains (usedlabel, bod->label, (SET_Compare)strcmp)) MAP_Delete (&dom->mapmem, &dom->lab, bod->label, (MAP_Compare) strcmp); MAP_Delete (&dom->mapmem, &dom->idb, (void*) (long) bod->id, NULL); if (bod->next) bod->next->prev = bod->prev; if (bod->prev) bod->prev->next = bod->next; else dom->bod = bod->next; dom->nbod --; } } SET_Free (NULL, &usedlabel); /* attach constraints to bodies */ dom_attach_constraints (dom); }
/* create rank coloring using adjacency graph between processors derived from the W graph */ static int* processor_coloring (GAUSS_SEIDEL *gs, LOCDYN *ldy) { int i, n, m, ncpu, rank, *color, *size, *disp, *adj; SET *adjcpu, *item; MEM setmem; DIAB *dia; OFFB *blk; CON *con; adjcpu = NULL; rank = ldy->dom->rank; ncpu = ldy->dom->ncpu; MEM_Init (&setmem, sizeof (SET), 128); ERRMEM (color = MEM_CALLOC (ncpu * sizeof (int))); ERRMEM (disp = malloc (sizeof (int [ncpu + 1]))); ERRMEM (size = malloc (sizeof (int [ncpu]))); /* collaps W adjacency into processor adjacency */ for (dia = ldy->dia; dia; dia = dia->n) { for (blk = dia->adjext; blk; blk = blk->n) { con = (CON*) blk->dia; SET_Insert (&setmem, &adjcpu, (void*) (long) con->rank, NULL); } } n = SET_Size (adjcpu); MPI_Allgather (&n, 1, MPI_INT, size, 1, MPI_INT, MPI_COMM_WORLD); for (i = disp [0] = 0; i < ncpu - 1; i ++) disp [i+1] = disp [i] + size [i]; for (i = 0, item = SET_First (adjcpu); item; i ++, item = SET_Next (item)) color [i] = (int) (long) item->data; m = disp [ncpu] = (disp [ncpu-1] + size [ncpu-1]); ERRMEM (adj = malloc (sizeof (int [m]))); MPI_Allgatherv (color, n, MPI_INT, adj, size, disp, MPI_INT, MPI_COMM_WORLD); /* gather graph adjacency */ for (i = 0; i < ncpu; i ++) color [i] = 0; /* zero colors */ for (i = 0; i < ncpu; i ++) /* simple BFS coloring */ { int *j, *k; do { color [i] ++; /* start from first color */ for (j = &adj[disp[i]], k = &adj[disp[i+1]]; j < k; j ++) /* for each adjacent vertex */ { if (color [*j] == color [i]) break; /* see whether the trial color exists in the adjacency */ } } while (j < k); /* if so try next color */ } for (m = i = 0; i < ncpu; i ++) m = MAX (m, color [i]); /* compute number of colors */ gs->colors = m; /* record number of colors */ if (rank == 0 && ldy->dom->verbose && gs->verbose) { #if DEBUG for (i = 0; i < ncpu; i ++) { int *j, *k; printf ("GAUSS_SEIDEL: RANK %d [%d] ADJCPU:", i, color [i]); for (j = &adj[disp[i]], k = &adj[disp[i+1]]; j < k; j ++) printf (" %d [%d]", *j, color [*j]); printf ("\n"); } #endif printf ("GAUSS_SEIDEL: PROCESSOR COLORS = %d\n", m); } MEM_Release (&setmem); free (size); free (disp); free (adj); return color; }
static void overlap (void *data, BOX *one, BOX *two) { SET_Insert (NULL, (SET**)&one->body, two, NULL); SET_Insert (NULL, (SET**)&two->body, one, NULL); }