From db4a2d25a764a68e0969d6108037f04ffdc17fe5 Mon Sep 17 00:00:00 2001
From: Matthieu Schaller <matthieu.schaller@durham.ac.uk>
Date: Tue, 12 May 2015 20:49:25 +0100
Subject: [PATCH] Fully task-based version of FMM. The downpass is now also
 fully implemented using tasks.

---
 examples/multipoles.h |  2 --
 examples/test_fmm.c   | 44 +++++++++++++++++++++++++++++--------------
 2 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/examples/multipoles.h b/examples/multipoles.h
index 9c21143..546a6f3 100644
--- a/examples/multipoles.h
+++ b/examples/multipoles.h
@@ -353,8 +353,6 @@ static inline float applyFieldAcceleration(struct fieldTensor B, double dx, doub
   a += dy * B.F_010;
   a += dz * B.F_001;
 
-  //message("%f %f %f %f %f %f", B.F_100, B.F_010, B.F_001, dx, dy, dz);
-
 #ifdef QUADRUPOLES
   a += 0.5f * dx * dx * B.F_200;
   a += 0.5f * dy * dy * B.F_020;
diff --git a/examples/test_fmm.c b/examples/test_fmm.c
index eb56a76..8513dbc 100644
--- a/examples/test_fmm.c
+++ b/examples/test_fmm.c
@@ -46,6 +46,7 @@
 #define ICHECK -10000000
 #define SANITY_CHECKS
 #define COM_AS_TASK
+#define DOWN_AS_TASK
 #define COUNTERS
 #define QUADRUPOLES
 
@@ -235,10 +236,6 @@ void comp_com(struct cell *c) {
   c->new.M_101 = M_101 - imass * com[0] * com[2];
   c->new.M_011 = M_011 - imass * com[1] * com[2];
 #endif
-
-  initFieldTensor(c->field_x);
-  initFieldTensor(c->field_y);
-  initFieldTensor(c->field_z);
 }
 
 
@@ -255,6 +252,7 @@ void comp_down(struct cell *c) {
   double dx=0.f, dy=0.f, dz=0.f;
   struct part *parts = c->parts;
 
+
   if (c->split) {
 
     /* Loop over the siblings and propagate accelerations. */
@@ -270,9 +268,10 @@ void comp_down(struct cell *c) {
       shiftAndAddTensor(c->field_y, &cp->field_y, dx, dy, dz);
       shiftAndAddTensor(c->field_z, &cp->field_z, dx, dy, dz);
 
-
+#ifndef DOWN_AS_TASK
       /* Recurse */
       comp_down(cp);
+#endif
     }
 
   } else {
@@ -335,10 +334,11 @@ void cell_split(struct cell *c, struct qsched *s) {
     c->com_tid = qsched_addtask(s, task_type_com, task_flag_none, &c,
                                 sizeof(struct cell *), 1);
 #endif
-
-    //c->down_tid = qsched_addtask(s, task_type_down, task_flag_none, &c,
-    //                            sizeof(struct cell *), 1);
-    //qsched_addlock(s, c->down_tid, c->res);
+#ifdef DOWN_AS_TASK
+    c->down_tid = qsched_addtask(s, task_type_down, task_flag_none, &c,
+				 sizeof(struct cell *), 1);
+    qsched_addlock(s, c->down_tid, c->res);
+#endif
   }
 
   /* Does this cell need to be split? */
@@ -463,11 +463,11 @@ void cell_split(struct cell *c, struct qsched *s) {
 #endif
 
     /* Link the downward tasks. */
-    //#ifdef COM_AS_TASK
-    //for (k = 0; k < 8; k++)
-    //  if (progenitors[k]->count > 0)
-    //    qsched_addunlock(s, c->down_tid, progenitors[k]->down_tid);
-    //#endif
+#ifdef DOWN_AS_TASK
+    for (k = 0; k < 8; k++)
+     if (progenitors[k]->count > 0)
+       qsched_addunlock(s, c->down_tid, progenitors[k]->down_tid);
+#endif
 
 
   } /* does the cell need to be split? */
@@ -478,6 +478,10 @@ void cell_split(struct cell *c, struct qsched *s) {
   comp_com(c);
 #endif
 
+  initFieldTensor(c->field_x);
+  initFieldTensor(c->field_y);
+  initFieldTensor(c->field_z);
+
   /* Set this cell's resources ownership. */
   qsched_res_own(s, c->res,
                  s->nr_queues * (c->parts - root->parts) / root->count);
@@ -879,6 +883,11 @@ void create_tasks(struct qsched *s, struct cell *ci, struct cell *cj) {
 #ifdef COM_AS_TASK
       if (ci->split) qsched_addunlock(s, ci->com_tid, tid);
 #endif
+
+#ifdef DOWN_AS_TASK
+      if (ci->split) qsched_addunlock(s, tid, ci->down_tid);
+#endif
+
     }
 
     /* Otherwise, it's a pair. */
@@ -915,6 +924,10 @@ void create_tasks(struct qsched *s, struct cell *ci, struct cell *cj) {
       qsched_addunlock(s, ci->com_tid, tid);
 #endif
 
+#ifdef DOWN_AS_TASK
+      qsched_addunlock(s, tid, cj->down_tid);
+      qsched_addunlock(s, tid, ci->down_tid);
+#endif
      
     } else {  /* Otherwise, at least one of the cells is not split, build a direct
 	       * interaction. */
@@ -1394,7 +1407,9 @@ void test_bh(int N, int nr_threads, int runs, char *fileName) {
     /* Execute the tasks. */
     tic = getticks();
     qsched_run(&s, nr_threads, runner);
+#ifndef DOWN_AS_TASK
     comp_down(root);
+#endif
     toc_run = getticks();
     message("%ith run took %lli (= %e) ticks...", k, toc_run - tic,
             (float)(toc_run - tic));
@@ -1405,6 +1420,7 @@ void test_bh(int N, int nr_threads, int runs, char *fileName) {
   message("[check] root CoMx= %f %f", root->legacy.com[0], root->new.M_100);
   message("[check] root CoMy= %f %f", root->legacy.com[1], root->new.M_010);
   message("[check] root CoMz= %f %f", root->legacy.com[2], root->new.M_001);
+
 #ifdef QUADRUPOLES
   message("[check]     | %f %f %f |", root->new.M_200, root->new.M_110, root->new.M_101);
   message("[check] I = | %f %f %f |", root->new.M_110, root->new.M_020, root->new.M_011);
-- 
GitLab