[SCM] Gerris Flow Solver branch, upstream, updated. e8f73a07832050124d2b8bf6c6f35b33180e65a8
Stephane Popinet
popinet at users.sf.net
Tue Nov 24 12:24:21 UTC 2009
The following commit has been merged in the upstream branch:
commit 2144b2a653e20b057b4bfac08a29b9f9d1915c43
Author: Stephane Popinet <popinet at users.sf.net>
Date: Thu Jul 9 10:39:14 2009 +1000
EventBalance implements dynamic load balancing on 2 PEs only
darcs-hash:20090709003914-d4795-eae9b6a9c4c295841d1fd00248aafdcc953337db.gz
diff --git a/src/event.c b/src/event.c
index 8f7b1a7..cda9a48 100644
--- a/src/event.c
+++ b/src/event.c
@@ -27,6 +27,7 @@
#include "event.h"
#include "solid.h"
#include "output.h"
+#include "mpi_boundary.h"
/**
* gfs_event_next:
@@ -1717,6 +1718,42 @@ static void gfs_event_balance_read (GtsObject ** o, GtsFile * fp)
s->max = gfs_read_constant (fp, domain);
}
+static void count (FttCell * cell, int * n)
+{
+ (*n)++;
+}
+
+typedef struct {
+ GfsBox * box;
+ gint dest, n, min, neighboring;
+} BoxData;
+
+#define LAMBDA 0.3
+
+static void select_neighbouring_box (GfsBox * box, BoxData * b)
+{
+ gint neighboring = 0;
+ FttDirection d;
+
+ for (d = 0; d < FTT_NEIGHBORS && !neighboring; d++)
+ if (GFS_IS_BOUNDARY_MPI (box->neighbor[d]) &&
+ GFS_BOUNDARY_MPI (box->neighbor[d])->process == b->dest)
+ neighboring++;
+
+ if (neighboring) {
+ box->size = 0;
+ ftt_cell_traverse (box->root, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+ (FttCellTraverseFunc) count, &(box->size));
+ if (!b->box ||
+ (fabs (box->size - b->n) < (1. - LAMBDA)*fabs (b->box->size - b->n)) ||
+ (fabs (box->size - b->n) < (1. + LAMBDA)*fabs (b->box->size - b->n) &&
+ neighboring > b->neighboring)) {
+ b->box = box;
+ b->neighboring = neighboring;
+ }
+ }
+}
+
static gboolean gfs_event_balance_event (GfsEvent * event, GfsSimulation * sim)
{
if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_balance_class ())->parent_class)->event)
@@ -1727,22 +1764,41 @@ static gboolean gfs_event_balance_event (GfsEvent * event, GfsSimulation * sim)
gfs_domain_stats_balance (domain, &size, &boundary, &mpiwait);
if (size.max/size.min > s->max) {
- g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE,
- "EventBalance: unbalance limit reached (exiting)");
- g_slist_free (domain->variables_io);
- domain->variables_io = NULL;
- GSList * i = domain->variables;
- while (i) {
- if (GFS_VARIABLE1 (i->data)->name)
- domain->variables_io = g_slist_append (domain->variables_io, i->data);
- i = i->next;
- }
- FILE * fp = fopen ("unbalanced.gfs", "w");
- if (fp) {
- gfs_simulation_write (GFS_SIMULATION (domain), -1, fp);
- fclose (fp);
- }
- exit (2);
+#ifdef HAVE_MPI
+ int n, other;
+ MPI_Comm_size (MPI_COMM_WORLD, &n);
+ if (n != 2)
+ g_assert_not_implemented ();
+
+ n = 0;
+ gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+ (FttCellTraverseFunc) count, &n);
+ other = (domain->pid + 1) % 2;
+ if (n > size.mean) { /* largest subdomain */
+ if (gts_container_size (GTS_CONTAINER (domain)) < 2)
+ gfs_send_boxes (domain, NULL, other);
+ else {
+ n -= size.mean;
+
+ BoxData b;
+ b.box = NULL; b.n = n;
+ b.dest = other;
+ /* 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". */
+ gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) select_neighbouring_box, &b);
+ if (b.box && b.box->size <= size.max - size.min) {
+ GSList * l = g_slist_prepend (NULL, b.box);
+ gfs_send_boxes (domain, l, other);
+ g_slist_free (l);
+ }
+ else
+ gfs_send_boxes (domain, NULL, other);
+ }
+ }
+ else /* smallest subdomain */
+ g_slist_free (gfs_receive_boxes (domain, other));
+#endif
}
return TRUE;
}
--
Gerris Flow Solver
More information about the debian-science-commits
mailing list