[SCM] Gerris Flow Solver branch, upstream, updated. e8f73a07832050124d2b8bf6c6f35b33180e65a8
Stephane Popinet
popinet at users.sf.net
Tue Nov 24 12:24:37 UTC 2009
The following commit has been merged in the upstream branch:
commit 8b67813c3ba6b256f71ad0f190729b7d34c3901a
Author: Stephane Popinet <popinet at users.sf.net>
Date: Sat Jul 18 08:28:40 2009 +1000
GfsEventBalance flows can transfer more than one box at a time
darcs-hash:20090717222840-d4795-c48f9b416e0ec0c73ee56d66383c0f5699c1da32.gz
diff --git a/src/balance.c b/src/balance.c
index 81274ad..1c54cdc 100644
--- a/src/balance.c
+++ b/src/balance.c
@@ -136,45 +136,57 @@ static void balancing_flow_destroy (BalancingFlow * b)
g_free (b);
}
+static void reset_box_size (GfsBox * box)
+{
+ box->size = 0;
+}
+
typedef struct {
GfsBox * box;
- gint dest, n, min, neighboring;
+ gint dest, flow, min, neighboring;
} BoxData;
static void select_neighbouring_box (GfsBox * box, BoxData * b)
{
- gint neighboring = 0;
- FttDirection d;
-
- for (d = 0; d < FTT_NEIGHBORS; d++)
- if (GFS_IS_BOUNDARY_MPI (box->neighbor[d]) &&
- GFS_BOUNDARY_MPI (box->neighbor[d])->process == b->dest)
- neighboring++;
+ if (box->pid != b->dest) {
+ gint neighboring = 0;
+ FttDirection d;
+
+ for (d = 0; d < FTT_NEIGHBORS; d++)
+ if ((GFS_IS_BOUNDARY_MPI (box->neighbor[d]) &&
+ GFS_BOUNDARY_MPI (box->neighbor[d])->process == b->dest) ||
+ (GFS_IS_BOX (box->neighbor[d]) &&
+ GFS_BOX (box->neighbor[d])->pid == b->dest))
+ neighboring++;
- if (neighboring && neighboring >= b->neighboring) {
- box->size = 0;
- ftt_cell_traverse (box->root, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
- (FttCellTraverseFunc) count, &(box->size));
- if (neighboring > b->neighboring ||
- fabs (box->size - b->n) < fabs (b->box->size - b->n)) {
- b->box = box;
- b->neighboring = neighboring;
+ if (neighboring && neighboring >= b->neighboring) {
+ if (box->size == 0)
+ ftt_cell_traverse (box->root, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+ (FttCellTraverseFunc) count, &box->size);
+ if (neighboring > b->neighboring ||
+ fabs (box->size - b->flow) < fabs (b->box->size - b->flow)) {
+ b->box = box;
+ b->neighboring = neighboring;
+ }
}
}
}
-static void get_pid (GfsBox * box, guint * pid)
+static void get_pid (GfsBox * box, GArray * pid)
{
- pid[box->id - 1] = gfs_box_domain (box)->pid;
+ g_assert (box->id > 0 && box->id <= pid->len);
+ g_array_index (pid, guint, box->id - 1) = gfs_box_domain (box)->pid;
}
-static void update_box_pid (GfsBox * box, guint * pid)
+static void update_box_pid (GfsBox * box, GArray * pid)
{
FttDirection d;
for (d = 0; d < FTT_NEIGHBORS; d++)
- if (GFS_IS_BOUNDARY_MPI (box->neighbor[d]))
- GFS_BOUNDARY_MPI (box->neighbor[d])->process =
- pid[GFS_BOUNDARY_MPI (box->neighbor[d])->id - 1];
+ if (GFS_IS_BOUNDARY_MPI (box->neighbor[d])) {
+ guint id = GFS_BOUNDARY_MPI (box->neighbor[d])->id;
+ g_assert (id > 0 && id <= pid->len);
+ GFS_BOUNDARY_MPI (box->neighbor[d])->process = g_array_index (pid, guint, id - 1);
+ }
}
#endif /* HAVE_MPI */
@@ -220,29 +232,39 @@ static gboolean gfs_event_balance_event (GfsEvent * event, GfsSimulation * sim)
int modified = FALSE;
int i;
/* Send boxes */
+ gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) reset_box_size, NULL);
+ guint nb = gts_container_size (GTS_CONTAINER (domain));
for (i = 0; i < balance->n; i++)
if (balance->flow[i] > 0.) { /* largest subdomain */
+ /* we need to find the list of boxes which minimizes
+ |\sum n_i - n| where n_i is the size of box i. This is known in
+ combinatorial optimisation as a "knapsack problem". */
GSList * l = NULL;
- if (gts_container_size (GTS_CONTAINER (domain)) > 1) {
- BoxData b;
- b.box = NULL; b.neighboring = 0; b.n = balance->flow[i];
- b.dest = balance->pid[i];
- /* we need to find the list of boxes which minimizes
- |\sum n_i - n| where n_i is the size of box i. This is known in
- combinatorial optimisation as a "knapsack problem". */
+ BoxData b;
+ b.flow = balance->flow[i];
+ b.dest = balance->pid[i];
+ while (b.flow > 0 && nb > 1) {
+ b.box = NULL; b.neighboring = 0;
gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) select_neighbouring_box, &b);
- if (b.box && b.box->size <= 2*b.n) {
+ if (b.box && b.box->size <= 2*b.flow) {
l = g_slist_prepend (l, b.box);
+ b.box->pid = b.dest;
+ b.flow -= b.box->size;
+ nb--;
modified = TRUE;
}
+ else
+ b.flow = 0;
}
g_ptr_array_add (request, gfs_send_boxes (domain, l, balance->pid[i]));
g_slist_free (l);
}
/* Receive boxes */
for (i = 0; i < balance->n; i++)
- if (balance->flow[i] < 0.) /* smallest subdomain */
- g_slist_free (gfs_receive_boxes (domain, balance->pid[i]));
+ if (balance->flow[i] < 0.) { /* smallest subdomain */
+ GSList * l = gfs_receive_boxes (domain, balance->pid[i]);
+ g_slist_free (l);
+ }
/* Synchronize */
for (i = 0; i < request->len; i++)
gfs_wait (g_ptr_array_index (request, i));
@@ -254,12 +276,13 @@ static gboolean gfs_event_balance_event (GfsEvent * event, GfsSimulation * sim)
/* Updates the pid associated with each box */
guint nb = gts_container_size (GTS_CONTAINER (domain));
gfs_all_reduce (domain, nb, MPI_UNSIGNED, MPI_SUM);
- guint * pid = g_malloc0 (sizeof (guint)*nb);
+ GArray * pid = g_array_sized_new (FALSE, TRUE, sizeof (guint), nb);
+ g_array_set_size (pid, nb);
gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) get_pid, pid);
- MPI_Allreduce (pid, pid, nb, MPI_UNSIGNED, MPI_MAX, MPI_COMM_WORLD);
+ MPI_Allreduce (MPI_IN_PLACE, pid->data, nb, MPI_UNSIGNED, MPI_MAX, MPI_COMM_WORLD);
/* pid[id] now contains the current pid of box with index id */
gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) update_box_pid, pid);
- g_free (pid);
+ g_array_free (pid, TRUE);
gfs_domain_reshape (domain, gfs_domain_depth (domain));
}
#else /* not HAVE_MPI */
diff --git a/src/domain.c b/src/domain.c
index 03a85bb..d1355cf 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -382,17 +382,14 @@ static void convert_boundary_mpi_into_edges (GfsBox * box, GPtrArray * ids)
if (GFS_IS_BOUNDARY_MPI (box->neighbor[d])) {
GfsBoundaryMpi * b = GFS_BOUNDARY_MPI (box->neighbor[d]);
GfsBox * nbox;
- if ((pid < 0 || b->process == pid) /* This is an "internal" boundary */ &&
- b->id >= 0 && (nbox = g_ptr_array_index (ids, b->id - 1))) {
+ if (b->id >= 0 && b->id <= ids->len && (nbox = g_ptr_array_index (ids, b->id - 1))) {
FttDirection od = FTT_OPPOSITE_DIRECTION (d);
- if (nbox->pid != b->process)
- g_warning ("nbox->pid != b->process");
- else if (!GFS_IS_BOUNDARY_MPI (nbox->neighbor[od]))
+ if (!GFS_IS_BOUNDARY_MPI (nbox->neighbor[od]))
g_warning ("!GFS_IS_BOUNDARY_MPI (nbox->neighbor[FTT_OPPOSITE_DIRECTION (d)])");
else {
GfsBoundaryMpi * nb = GFS_BOUNDARY_MPI (nbox->neighbor[od]);
- if (box->pid != nb->process || box->id != nb->id)
- g_warning ("box->pid != nb->process || box->id != nb->id");
+ if (box->id != nb->id)
+ g_warning ("box->id != nb->id");
else {
gts_object_destroy (GTS_OBJECT (b));
gts_object_destroy (GTS_OBJECT (nb));
@@ -4034,6 +4031,8 @@ GSList * gfs_receive_objects (GfsDomain * domain, int src)
if (fp->type == GTS_ERROR)
g_error ("gfs_receive_object():%d:%d: %s", fp->line, fp->pos, fp->error);
list = g_slist_prepend (list, object);
+ while (fp->type == '\n')
+ gts_file_next_token (fp);
}
gts_file_destroy (fp);
fclose (f);
--
Gerris Flow Solver
More information about the debian-science-commits
mailing list