engine_marktasks.c 35.4 KB
Newer Older
Pedro Gonnet's avatar
Pedro Gonnet committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*******************************************************************************
 * This file is part of SWIFT.
 * Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
 *                    Matthieu Schaller (matthieu.schaller@durham.ac.uk)
 *               2015 Peter W. Draper (p.w.draper@durham.ac.uk)
 *                    Angus Lepper (angus.lepper@ed.ac.uk)
 *               2016 John A. Regan (john.a.regan@durham.ac.uk)
 *                    Tom Theuns (tom.theuns@durham.ac.uk)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/

/* Config parameters. */
#include "../config.h"

/* Some standard headers. */
#include <stdlib.h>
#include <unistd.h>

/* MPI headers. */
#ifdef WITH_MPI
#include <mpi.h>
#endif

/* Load the profiler header, if needed. */
#ifdef WITH_PROFILER
#include <gperftools/profiler.h>
#endif

/* This object's header. */
#include "engine.h"

/* Local headers. */
#include "active.h"
#include "atomic.h"
#include "cell.h"
#include "clocks.h"
#include "cycle.h"
#include "debug.h"
#include "error.h"
#include "proxy.h"
#include "timers.h"

/**
 * @brief Mark tasks to be un-skipped and set the sort flags accordingly.
 *        Threadpool mapper function.
 *
 * @param map_data pointer to the tasks
 * @param num_elements number of tasks
 * @param extra_data pointer to int that will define if a rebuild is needed.
 */
void engine_marktasks_mapper(void *map_data, int num_elements,
                             void *extra_data) {
  /* Unpack the arguments. */
  struct task *tasks = (struct task *)map_data;
  size_t *rebuild_space = &((size_t *)extra_data)[1];
  struct scheduler *s = (struct scheduler *)(((size_t *)extra_data)[2]);
  struct engine *e = (struct engine *)((size_t *)extra_data)[0];
  const int nodeID = e->nodeID;
72
  const int with_limiter = e->policy & engine_policy_limiter;
73
  const int with_star_formation = e->policy & engine_policy_star_formation;
74
#ifdef WITH_MPI
75
76
  const int with_feedback = e->policy & engine_policy_feedback;
#endif
Pedro Gonnet's avatar
Pedro Gonnet committed
77
78
79
80
81
82
83
84
85
86
87
88
89
90

  for (int ind = 0; ind < num_elements; ind++) {

    /* Get basic task information */
    struct task *t = &tasks[ind];
    const enum task_types t_type = t->type;
    const enum task_subtypes t_subtype = t->subtype;

    /* Single-cell task? */
    if (t_type == task_type_self || t_type == task_type_sub_self) {

      /* Local pointer. */
      struct cell *ci = t->ci;

91
#ifdef SWIFT_DEBUG_CHECKS
92
      if (ci->nodeID != nodeID) error("Non-local self task found");
93
94
95
96
#endif
      const int ci_active_hydro = cell_is_active_hydro(ci, e);
      const int ci_active_gravity = cell_is_active_gravity(ci, e);
      const int ci_active_black_holes = cell_is_active_black_holes(ci, e);
97
98
99
      const int ci_active_stars = cell_is_active_stars(ci, e) ||
                                  (with_star_formation && ci_active_hydro);

Pedro Gonnet's avatar
Pedro Gonnet committed
100
101
      /* Activate the hydro drift */
      if (t_type == task_type_self && t_subtype == task_subtype_density) {
102
        if (ci_active_hydro) {
Pedro Gonnet's avatar
Pedro Gonnet committed
103
104
          scheduler_activate(s, t);
          cell_activate_drift_part(ci, s);
105
          if (with_limiter) cell_activate_limiter(ci, s);
Pedro Gonnet's avatar
Pedro Gonnet committed
106
107
108
109
110
111
        }
      }

      /* Store current values of dx_max and h_max. */
      else if (t_type == task_type_sub_self &&
               t_subtype == task_subtype_density) {
112
        if (ci_active_hydro) {
Pedro Gonnet's avatar
Pedro Gonnet committed
113
114
          scheduler_activate(s, t);
          cell_activate_subcell_hydro_tasks(ci, NULL, s);
115
          if (with_limiter) cell_activate_limiter(ci, s);
Pedro Gonnet's avatar
Pedro Gonnet committed
116
117
118
119
        }
      }

      else if (t_type == task_type_self && t_subtype == task_subtype_force) {
120
        if (ci_active_hydro) scheduler_activate(s, t);
Pedro Gonnet's avatar
Pedro Gonnet committed
121
122
123
124
      }

      else if (t_type == task_type_sub_self &&
               t_subtype == task_subtype_force) {
125
        if (ci_active_hydro) scheduler_activate(s, t);
Pedro Gonnet's avatar
Pedro Gonnet committed
126
127
      }

128
129
      else if (t->type == task_type_self &&
               t->subtype == task_subtype_limiter) {
130
        if (ci_active_hydro) scheduler_activate(s, t);
131
132
133
134
      }

      else if (t->type == task_type_sub_self &&
               t->subtype == task_subtype_limiter) {
135
        if (ci_active_hydro) scheduler_activate(s, t);
136
137
      }

Pedro Gonnet's avatar
Pedro Gonnet committed
138
      else if (t_type == task_type_self && t_subtype == task_subtype_gradient) {
139
        if (ci_active_hydro) scheduler_activate(s, t);
Pedro Gonnet's avatar
Pedro Gonnet committed
140
141
142
143
      }

      else if (t_type == task_type_sub_self &&
               t_subtype == task_subtype_gradient) {
144
        if (ci_active_hydro) scheduler_activate(s, t);
Pedro Gonnet's avatar
Pedro Gonnet committed
145
146
147
148
149
      }

      /* Activate the star density */
      else if (t_type == task_type_self &&
               t_subtype == task_subtype_stars_density) {
150
        if (ci_active_stars) {
Pedro Gonnet's avatar
Pedro Gonnet committed
151
152
          scheduler_activate(s, t);
          cell_activate_drift_part(ci, s);
Loic Hausammann's avatar
Loic Hausammann committed
153
          cell_activate_drift_spart(ci, s);
Pedro Gonnet's avatar
Pedro Gonnet committed
154
155
156
157
158
159
        }
      }

      /* Store current values of dx_max and h_max. */
      else if (t_type == task_type_sub_self &&
               t_subtype == task_subtype_stars_density) {
160
        if (ci_active_stars) {
Pedro Gonnet's avatar
Pedro Gonnet committed
161
          scheduler_activate(s, t);
162
          cell_activate_subcell_stars_tasks(ci, NULL, s, with_star_formation);
Pedro Gonnet's avatar
Pedro Gonnet committed
163
164
165
        }
      }

Alexei Borissov's avatar
Alexei Borissov committed
166
167
      else if (t_type == task_type_self &&
               t_subtype == task_subtype_stars_feedback) {
168
        if (ci_active_stars) {
Alexei Borissov's avatar
Alexei Borissov committed
169
170
171
172
173
174
          scheduler_activate(s, t);
        }
      }

      else if (t_type == task_type_sub_self &&
               t_subtype == task_subtype_stars_feedback) {
175
        if (ci_active_stars) scheduler_activate(s, t);
Alexei Borissov's avatar
Alexei Borissov committed
176
177
      }

178
179
180
      /* Activate the black hole density */
      else if (t_type == task_type_self &&
               t_subtype == task_subtype_bh_density) {
181
        if (ci_active_black_holes) {
182
183
184
185
186
187
188
189
190
          scheduler_activate(s, t);
          cell_activate_drift_part(ci, s);
          cell_activate_drift_bpart(ci, s);
        }
      }

      /* Store current values of dx_max and h_max. */
      else if (t_type == task_type_sub_self &&
               t_subtype == task_subtype_bh_density) {
191
        if (ci_active_black_holes) {
192
          scheduler_activate(s, t);
193
          cell_activate_subcell_black_holes_tasks(ci, NULL, s);
194
195
196
        }
      }

197
198
199
200
201
202
203
204
205
206
207
208
209
      else if (t_type == task_type_self &&
               t_subtype == task_subtype_bh_swallow) {
        if (ci_active_black_holes) {
          scheduler_activate(s, t);
        }
      }

      else if (t_type == task_type_sub_self &&
               t_subtype == task_subtype_bh_swallow) {
        if (ci_active_black_holes) scheduler_activate(s, t);
      }

      else if (t_type == task_type_self &&
210
               t_subtype == task_subtype_do_gas_swallow) {
211
212
213
214
215
216
        if (ci_active_black_holes) {
          scheduler_activate(s, t);
        }
      }

      else if (t_type == task_type_sub_self &&
217
218
219
220
221
222
223
224
225
226
227
228
229
               t_subtype == task_subtype_do_gas_swallow) {
        if (ci_active_black_holes) scheduler_activate(s, t);
      }

      else if (t_type == task_type_self &&
               t_subtype == task_subtype_do_bh_swallow) {
        if (ci_active_black_holes) {
          scheduler_activate(s, t);
        }
      }

      else if (t_type == task_type_sub_self &&
               t_subtype == task_subtype_do_bh_swallow) {
230
231
232
        if (ci_active_black_holes) scheduler_activate(s, t);
      }

233
234
      else if (t_type == task_type_self &&
               t_subtype == task_subtype_bh_feedback) {
235
        if (ci_active_black_holes) {
236
237
238
239
240
241
          scheduler_activate(s, t);
        }
      }

      else if (t_type == task_type_sub_self &&
               t_subtype == task_subtype_bh_feedback) {
242
        if (ci_active_black_holes) scheduler_activate(s, t);
243
244
      }

Pedro Gonnet's avatar
Pedro Gonnet committed
245
246
      /* Activate the gravity drift */
      else if (t_type == task_type_self && t_subtype == task_subtype_grav) {
247
        if (ci_active_gravity) {
Pedro Gonnet's avatar
Pedro Gonnet committed
248
249
250
251
252
253
254
255
          scheduler_activate(s, t);
          cell_activate_subcell_grav_tasks(t->ci, NULL, s);
        }
      }

      /* Activate the gravity drift */
      else if (t_type == task_type_self &&
               t_subtype == task_subtype_external_grav) {
256
        if (ci_active_gravity) {
Pedro Gonnet's avatar
Pedro Gonnet committed
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
          scheduler_activate(s, t);
          cell_activate_drift_gpart(t->ci, s);
        }
      }

#ifdef SWIFT_DEBUG_CHECKS
      else {
        error("Invalid task type / sub-type encountered");
      }
#endif
    }

    /* Pair? */
    else if (t_type == task_type_pair || t_type == task_type_sub_pair) {

      /* Local pointers. */
      struct cell *ci = t->ci;
      struct cell *cj = t->cj;
#ifdef WITH_MPI
      const int ci_nodeID = ci->nodeID;
      const int cj_nodeID = cj->nodeID;
#else
      const int ci_nodeID = nodeID;
      const int cj_nodeID = nodeID;
#endif
      const int ci_active_hydro = cell_is_active_hydro(ci, e);
      const int cj_active_hydro = cell_is_active_hydro(cj, e);
284

Pedro Gonnet's avatar
Pedro Gonnet committed
285
286
      const int ci_active_gravity = cell_is_active_gravity(ci, e);
      const int cj_active_gravity = cell_is_active_gravity(cj, e);
287

288
289
290
      const int ci_active_black_holes = cell_is_active_black_holes(ci, e);
      const int cj_active_black_holes = cell_is_active_black_holes(cj, e);

291
292
293
294
295
      const int ci_active_stars = cell_is_active_stars(ci, e) ||
                                  (with_star_formation && ci_active_hydro);
      const int cj_active_stars = cell_is_active_stars(cj, e) ||
                                  (with_star_formation && cj_active_hydro);

Pedro Gonnet's avatar
Pedro Gonnet committed
296
297
298
      /* Only activate tasks that involve a local active cell. */
      if ((t_subtype == task_subtype_density ||
           t_subtype == task_subtype_gradient ||
299
           t_subtype == task_subtype_limiter ||
Pedro Gonnet's avatar
Pedro Gonnet committed
300
301
302
303
304
305
306
           t_subtype == task_subtype_force) &&
          ((ci_active_hydro && ci_nodeID == nodeID) ||
           (cj_active_hydro && cj_nodeID == nodeID))) {

        scheduler_activate(s, t);

        /* Set the correct sorting flags */
Loic Hausammann's avatar
Loic Hausammann committed
307
        if (t_type == task_type_pair && t_subtype == task_subtype_density) {
Pedro Gonnet's avatar
Pedro Gonnet committed
308
309
310
311
312
313
314
315
316
317
318

          /* Store some values. */
          atomic_or(&ci->hydro.requires_sorts, 1 << t->flags);
          atomic_or(&cj->hydro.requires_sorts, 1 << t->flags);
          ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort;
          cj->hydro.dx_max_sort_old = cj->hydro.dx_max_sort;

          /* Activate the hydro drift tasks. */
          if (ci_nodeID == nodeID) cell_activate_drift_part(ci, s);
          if (cj_nodeID == nodeID) cell_activate_drift_part(cj, s);

319
          /* And the limiter */
320
321
          if (ci_nodeID == nodeID && with_limiter) cell_activate_limiter(ci, s);
          if (cj_nodeID == nodeID && with_limiter) cell_activate_limiter(cj, s);
322

Pedro Gonnet's avatar
Pedro Gonnet committed
323
          /* Check the sorts and activate them if needed. */
324
325
          cell_activate_hydro_sorts(ci, t->flags, s);
          cell_activate_hydro_sorts(cj, t->flags, s);
Pedro Gonnet's avatar
Pedro Gonnet committed
326
327
328
329
330

        }

        /* Store current values of dx_max and h_max. */
        else if (t_type == task_type_sub_pair &&
Loic Hausammann's avatar
Loic Hausammann committed
331
                 t_subtype == task_subtype_density) {
Pedro Gonnet's avatar
Pedro Gonnet committed
332
333
334
335
          cell_activate_subcell_hydro_tasks(t->ci, t->cj, s);
        }
      }

336
337
      /* Stars density */
      else if ((t_subtype == task_subtype_stars_density) &&
338
339
340
               (ci_active_stars || cj_active_stars) &&
               (ci_nodeID == nodeID || cj_nodeID == nodeID)) {

loikki's avatar
loikki committed
341
        scheduler_activate(s, t);
342

Pedro Gonnet's avatar
Pedro Gonnet committed
343
344
345
        /* Set the correct sorting flags */
        if (t_type == task_type_pair) {

Loic Hausammann's avatar
Loic Hausammann committed
346
          /* Do ci */
loikki's avatar
loikki committed
347
          if (ci_active_stars) {
348

349
            /* stars for ci */
350
            atomic_or(&ci->stars.requires_sorts, 1 << t->flags);
351
            ci->stars.dx_max_sort_old = ci->stars.dx_max_sort;
Loic Hausammann's avatar
Loic Hausammann committed
352

353
            /* hydro for cj */
354
            atomic_or(&cj->hydro.requires_sorts, 1 << t->flags);
355
            cj->hydro.dx_max_sort_old = cj->hydro.dx_max_sort;
Pedro Gonnet's avatar
Pedro Gonnet committed
356

357
            /* Activate the drift tasks. */
358
359
            if (ci_nodeID == nodeID) cell_activate_drift_spart(ci, s);
            if (cj_nodeID == nodeID) cell_activate_drift_part(cj, s);
Pedro Gonnet's avatar
Pedro Gonnet committed
360

361
362
363
364
            /* Check the sorts and activate them if needed. */
            cell_activate_hydro_sorts(cj, t->flags, s);
            cell_activate_stars_sorts(ci, t->flags, s);
          }
Loic Hausammann's avatar
Loic Hausammann committed
365
366

          /* Do cj */
loikki's avatar
loikki committed
367
          if (cj_active_stars) {
Loic Hausammann's avatar
Loic Hausammann committed
368

369
            /* hydro for ci */
370
            atomic_or(&ci->hydro.requires_sorts, 1 << t->flags);
371
            ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort;
372

373
            /* stars for cj */
374
            atomic_or(&cj->stars.requires_sorts, 1 << t->flags);
375
            cj->stars.dx_max_sort_old = cj->stars.dx_max_sort;
Loic Hausammann's avatar
Loic Hausammann committed
376

377
            /* Activate the drift tasks. */
378
379
            if (ci_nodeID == nodeID) cell_activate_drift_part(ci, s);
            if (cj_nodeID == nodeID) cell_activate_drift_spart(cj, s);
Loic Hausammann's avatar
Loic Hausammann committed
380

381
382
383
384
            /* Check the sorts and activate them if needed. */
            cell_activate_hydro_sorts(ci, t->flags, s);
            cell_activate_stars_sorts(cj, t->flags, s);
          }
Pedro Gonnet's avatar
Pedro Gonnet committed
385
386
387
        }

        /* Store current values of dx_max and h_max. */
388
        else if (t_type == task_type_sub_pair &&
389
                 t_subtype == task_subtype_stars_density) {
390
          cell_activate_subcell_stars_tasks(ci, cj, s, with_star_formation);
Pedro Gonnet's avatar
Pedro Gonnet committed
391
392
393
        }
      }

394
      /* Stars feedback */
395
      else if (t_subtype == task_subtype_stars_feedback) {
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
        /* We only want to activate the task if the cell is active and is
           going to update some gas on the *local* node */
        if ((ci_nodeID == nodeID && cj_nodeID == nodeID) &&
            (ci_active_stars || cj_active_stars)) {

          scheduler_activate(s, t);

        } else if ((ci_nodeID == nodeID && cj_nodeID != nodeID) &&
                   (cj_active_stars)) {

          scheduler_activate(s, t);

        } else if ((ci_nodeID != nodeID && cj_nodeID == nodeID) &&
                   (ci_active_stars)) {

          scheduler_activate(s, t);
        }
414
      }
415

416
      /* Black_Holes density */
417
418
      else if ((t_subtype == task_subtype_bh_density ||
                t_subtype == task_subtype_bh_swallow ||
419
                t_subtype == task_subtype_do_gas_swallow ||
420
                t_subtype == task_subtype_do_bh_swallow ||
421
                t_subtype == task_subtype_bh_feedback) &&
422
423
424
425
426
427
               (ci_active_black_holes || cj_active_black_holes) &&
               (ci_nodeID == nodeID || cj_nodeID == nodeID)) {

        scheduler_activate(s, t);

        /* Set the correct sorting flags */
428
429
430
        if (t_type == task_type_pair && t_subtype == task_subtype_bh_density) {
          if (ci_nodeID == nodeID) cell_activate_drift_bpart(ci, s);
          if (ci_nodeID == nodeID) cell_activate_drift_part(ci, s);
431

432
433
          if (cj_nodeID == nodeID) cell_activate_drift_part(cj, s);
          if (cj_nodeID == nodeID) cell_activate_drift_bpart(cj, s);
434
435
436
437
438
439
440
441
442
        }

        /* Store current values of dx_max and h_max. */
        else if (t_type == task_type_sub_pair &&
                 t_subtype == task_subtype_bh_density) {
          cell_activate_subcell_black_holes_tasks(ci, cj, s);
        }
      }

443
      /* Gravity */
444
      else if ((t_subtype == task_subtype_grav) &&
445
446
               ((ci_active_gravity && ci_nodeID == nodeID) ||
                (cj_active_gravity && cj_nodeID == nodeID))) {
Pedro Gonnet's avatar
Pedro Gonnet committed
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466

        scheduler_activate(s, t);

        if (t_type == task_type_pair && t_subtype == task_subtype_grav) {
          /* Activate the gravity drift */
          cell_activate_subcell_grav_tasks(t->ci, t->cj, s);
        }

#ifdef SWIFT_DEBUG_CHECKS
        else if (t_type == task_type_sub_pair &&
                 t_subtype == task_subtype_grav) {
          error("Invalid task sub-type encountered");
        }
#endif
      }

      /* Only interested in density tasks as of here. */
      if (t_subtype == task_subtype_density) {

        /* Too much particle movement? */
Alexei Borissov's avatar
Alexei Borissov committed
467
        if (cell_need_rebuild_for_hydro_pair(ci, cj)) *rebuild_space = 1;
Pedro Gonnet's avatar
Pedro Gonnet committed
468
469
470
471
472
473
474

#ifdef WITH_MPI
        /* Activate the send/recv tasks. */
        if (ci_nodeID != nodeID) {

          /* If the local cell is active, receive data from the foreign cell. */
          if (cj_active_hydro) {
475
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
Pedro Gonnet's avatar
Pedro Gonnet committed
476
            if (ci_active_hydro) {
477
              scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
Pedro Gonnet's avatar
Pedro Gonnet committed
478
#ifdef EXTRA_HYDRO_LOOP
479
              scheduler_activate_recv(s, ci->mpi.recv, task_subtype_gradient);
Pedro Gonnet's avatar
Pedro Gonnet committed
480
481
482
483
484
#endif
            }
          }

          /* If the foreign cell is active, we want its ti_end values. */
485
486
          if (ci_active_hydro)
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_part);
Pedro Gonnet's avatar
Pedro Gonnet committed
487
488
489

          /* Is the foreign cell active and will need stuff from us? */
          if (ci_active_hydro) {
490
            struct link *l = scheduler_activate_send(
491
                s, cj->mpi.send, task_subtype_xv, ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
492
493
494
495
496
497
498
499

            /* Drift the cell which will be sent at the level at which it is
               sent, i.e. drift the cell specified in the send task (l->t)
               itself. */
            cell_activate_drift_part(l->t->ci, s);

            /* If the local cell is also active, more stuff will be needed. */
            if (cj_active_hydro) {
500
501
              scheduler_activate_send(s, cj->mpi.send, task_subtype_rho,
                                      ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
502
503

#ifdef EXTRA_HYDRO_LOOP
504
505
              scheduler_activate_send(s, cj->mpi.send, task_subtype_gradient,
                                      ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
506
507
508
509
510
511
#endif
            }
          }

          /* If the local cell is active, send its ti_end values. */
          if (cj_active_hydro)
512
513
            scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_part,
                                    ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
514

515
516
517
518
          /* Propagating new star counts? */
          if (with_star_formation && with_feedback) {
            if (ci_active_hydro && ci->hydro.count > 0) {
              scheduler_activate_recv(s, ci->mpi.recv, task_subtype_sf_counts);
519
              scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_spart);
520
521
522
523
            }
            if (cj_active_hydro && cj->hydro.count > 0) {
              scheduler_activate_send(s, cj->mpi.send, task_subtype_sf_counts,
                                      ci_nodeID);
524
525
              scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart,
                                      ci_nodeID);
526
527
528
            }
          }

Pedro Gonnet's avatar
Pedro Gonnet committed
529
530
531
532
        } else if (cj_nodeID != nodeID) {

          /* If the local cell is active, receive data from the foreign cell. */
          if (ci_active_hydro) {
533

534
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
Pedro Gonnet's avatar
Pedro Gonnet committed
535
            if (cj_active_hydro) {
536
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
Pedro Gonnet's avatar
Pedro Gonnet committed
537
#ifdef EXTRA_HYDRO_LOOP
538
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_gradient);
Pedro Gonnet's avatar
Pedro Gonnet committed
539
540
541
542
543
#endif
            }
          }

          /* If the foreign cell is active, we want its ti_end values. */
544
545
          if (cj_active_hydro)
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_part);
Pedro Gonnet's avatar
Pedro Gonnet committed
546
547
548
549

          /* Is the foreign cell active and will need stuff from us? */
          if (cj_active_hydro) {

550
            struct link *l = scheduler_activate_send(
551
                s, ci->mpi.send, task_subtype_xv, cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
552
553
554
555
556
557
558
559
560

            /* Drift the cell which will be sent at the level at which it is
               sent, i.e. drift the cell specified in the send task (l->t)
               itself. */
            cell_activate_drift_part(l->t->ci, s);

            /* If the local cell is also active, more stuff will be needed. */
            if (ci_active_hydro) {

561
562
              scheduler_activate_send(s, ci->mpi.send, task_subtype_rho,
                                      cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
563
564

#ifdef EXTRA_HYDRO_LOOP
565
566
              scheduler_activate_send(s, ci->mpi.send, task_subtype_gradient,
                                      cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
567
568
569
570
571
572
#endif
            }
          }

          /* If the local cell is active, send its ti_end values. */
          if (ci_active_hydro)
573
574
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_part,
                                    cj_nodeID);
575
576
577
578
579

          /* Propagating new star counts? */
          if (with_star_formation && with_feedback) {
            if (cj_active_hydro && cj->hydro.count > 0) {
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_sf_counts);
580
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_spart);
581
582
583
584
            }
            if (ci_active_hydro && ci->hydro.count > 0) {
              scheduler_activate_send(s, ci->mpi.send, task_subtype_sf_counts,
                                      cj_nodeID);
585
586
              scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart,
                                      cj_nodeID);
587
588
            }
          }
Pedro Gonnet's avatar
Pedro Gonnet committed
589
590
591
592
593
        }
#endif
      }

      /* Only interested in stars_density tasks as of here. */
594
      else if (t->subtype == task_subtype_stars_density) {
595
596
597
598
599

        /* Too much particle movement? */
        if (cell_need_rebuild_for_stars_pair(ci, cj)) *rebuild_space = 1;
        if (cell_need_rebuild_for_stars_pair(cj, ci)) *rebuild_space = 1;

600
#ifdef WITH_MPI
601
602
603
604
        /* Activate the send/recv tasks. */
        if (ci_nodeID != nodeID) {

          if (cj_active_stars) {
605
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
606
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
607
608

            /* If the local cell is active, more stuff will be needed. */
609
            scheduler_activate_send(s, cj->mpi.send, task_subtype_spart,
610
                                    ci_nodeID);
611
612
613
            cell_activate_drift_spart(cj, s);

            /* If the local cell is active, send its ti_end values. */
614
615
            scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart,
                                    ci_nodeID);
616
617
618
          }

          if (ci_active_stars) {
619
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_spart);
620
621

            /* If the foreign cell is active, we want its ti_end values. */
622
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_spart);
623
624

            /* Is the foreign cell active and will need stuff from us? */
625
            scheduler_activate_send(s, cj->mpi.send, task_subtype_xv,
626
                                    ci_nodeID);
627
            scheduler_activate_send(s, cj->mpi.send, task_subtype_rho,
628
                                    ci_nodeID);
629
630
631
632
633
634
635
636
637
638

            /* Drift the cell which will be sent; note that not all sent
               particles will be drifted, only those that are needed. */
            cell_activate_drift_part(cj, s);
          }

        } else if (cj_nodeID != nodeID) {

          /* If the local cell is active, receive data from the foreign cell. */
          if (ci_active_stars) {
639
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
640
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
641
642

            /* If the local cell is active, more stuff will be needed. */
643
            scheduler_activate_send(s, ci->mpi.send, task_subtype_spart,
644
                                    cj_nodeID);
645
646
647
            cell_activate_drift_spart(ci, s);

            /* If the local cell is active, send its ti_end values. */
648
649
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart,
                                    cj_nodeID);
650
651
652
          }

          if (cj_active_stars) {
653
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_spart);
654
655

            /* If the foreign cell is active, we want its ti_end values. */
656
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_spart);
657
658

            /* Is the foreign cell active and will need stuff from us? */
659
            scheduler_activate_send(s, ci->mpi.send, task_subtype_xv,
660
                                    cj_nodeID);
661
            scheduler_activate_send(s, ci->mpi.send, task_subtype_rho,
662
                                    cj_nodeID);
663
664
665
666
667
668

            /* Drift the cell which will be sent; note that not all sent
               particles will be drifted, only those that are needed. */
            cell_activate_drift_part(ci, s);
          }
        }
669
#endif
Pedro Gonnet's avatar
Pedro Gonnet committed
670
      }
671

672
      /* Only interested in black hole density tasks as of here. */
673
674
675
676
677
678
      else if (t->subtype == task_subtype_bh_density) {

        /* Too much particle movement? */
        if (cell_need_rebuild_for_black_holes_pair(ci, cj)) *rebuild_space = 1;
        if (cell_need_rebuild_for_black_holes_pair(cj, ci)) *rebuild_space = 1;

679
680
681
        scheduler_activate(s, ci->hydro.super->black_holes.swallow_ghost[0]);
        scheduler_activate(s, cj->hydro.super->black_holes.swallow_ghost[0]);

682
683
684
685
#ifdef WITH_MPI
        /* Activate the send/recv tasks. */
        if (ci_nodeID != nodeID) {

686
687
688
689
          /* Receive the foreign parts to compute BH accretion rates and do the
           * swallowing */
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_part_swallow);
690
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart_merger);
691

692
693
694
695
696
697
          /* Send the local BHs to tag the particles to swallow and to do
           * feedback */
          scheduler_activate_send(s, cj->mpi.send, task_subtype_bpart_rho,
                                  ci_nodeID);
          scheduler_activate_send(s, cj->mpi.send, task_subtype_bpart_feedback,
                                  ci_nodeID);
698

699
700
          /* Drift before you send */
          cell_activate_drift_bpart(cj, s);
701

702
703
704
          /* Send the new BH time-steps */
          scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_bpart,
                                  ci_nodeID);
705

706
707
708
709
          /* Receive the foreign BHs to tag particles to swallow and for
           * feedback */
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart_rho);
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart_feedback);
710

711
712
          /* Receive the foreign BH time-steps */
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_bpart);
713

714
715
716
717
          /* Send the local part information */
          scheduler_activate_send(s, cj->mpi.send, task_subtype_rho, ci_nodeID);
          scheduler_activate_send(s, cj->mpi.send, task_subtype_part_swallow,
                                  ci_nodeID);
718
719
          scheduler_activate_send(s, cj->mpi.send, task_subtype_bpart_merger,
                                  ci_nodeID);
720
721
722
723

          /* Drift the cell which will be sent; note that not all sent
             particles will be drifted, only those that are needed. */
          cell_activate_drift_part(cj, s);
724
725
726

        } else if (cj_nodeID != nodeID) {

727
728
729
730
          /* Receive the foreign parts to compute BH accretion rates and do the
           * swallowing */
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_part_swallow);
731
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart_merger);
732

733
734
735
736
737
738
          /* Send the local BHs to tag the particles to swallow and to do
           * feedback */
          scheduler_activate_send(s, ci->mpi.send, task_subtype_bpart_rho,
                                  cj_nodeID);
          scheduler_activate_send(s, ci->mpi.send, task_subtype_bpart_feedback,
                                  cj_nodeID);
739

740
741
          /* Drift before you send */
          cell_activate_drift_bpart(ci, s);
742

743
744
745
          /* Send the new BH time-steps */
          scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_bpart,
                                  cj_nodeID);
746

747
748
749
750
          /* Receive the foreign BHs to tag particles to swallow and for
           * feedback */
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart_rho);
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart_feedback);
751

752
753
          /* Receive the foreign BH time-steps */
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_bpart);
754

755
756
757
758
          /* Send the local part information */
          scheduler_activate_send(s, ci->mpi.send, task_subtype_rho, cj_nodeID);
          scheduler_activate_send(s, ci->mpi.send, task_subtype_part_swallow,
                                  cj_nodeID);
759
760
          scheduler_activate_send(s, ci->mpi.send, task_subtype_bpart_merger,
                                  cj_nodeID);
761
762
763
764

          /* Drift the cell which will be sent; note that not all sent
             particles will be drifted, only those that are needed. */
          cell_activate_drift_part(ci, s);
765
766
767
768
        }
#endif
      }

Pedro Gonnet's avatar
Pedro Gonnet committed
769
      /* Only interested in gravity tasks as of here. */
770
      else if (t_subtype == task_subtype_grav) {
Pedro Gonnet's avatar
Pedro Gonnet committed
771
772
773
774
775
776

#ifdef WITH_MPI
        /* Activate the send/recv tasks. */
        if (ci_nodeID != nodeID) {

          /* If the local cell is active, receive data from the foreign cell. */
777
778
          if (cj_active_gravity)
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_gpart);
Pedro Gonnet's avatar
Pedro Gonnet committed
779
780

          /* If the foreign cell is active, we want its ti_end values. */
781
782
          if (ci_active_gravity)
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_gpart);
Pedro Gonnet's avatar
Pedro Gonnet committed
783
784
785
786

          /* Is the foreign cell active and will need stuff from us? */
          if (ci_active_gravity) {

787
            struct link *l = scheduler_activate_send(
788
                s, cj->mpi.send, task_subtype_gpart, ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
789
790
791
792
793
794
795
796
797

            /* Drift the cell which will be sent at the level at which it is
               sent, i.e. drift the cell specified in the send task (l->t)
               itself. */
            cell_activate_drift_gpart(l->t->ci, s);
          }

          /* If the local cell is active, send its ti_end values. */
          if (cj_active_gravity)
798
799
            scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_gpart,
                                    ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
800
801
802
803

        } else if (cj_nodeID != nodeID) {

          /* If the local cell is active, receive data from the foreign cell. */
804
805
          if (ci_active_gravity)
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_gpart);
Pedro Gonnet's avatar
Pedro Gonnet committed
806
807

          /* If the foreign cell is active, we want its ti_end values. */
808
809
          if (cj_active_gravity)
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_gpart);
Pedro Gonnet's avatar
Pedro Gonnet committed
810
811
812
813

          /* Is the foreign cell active and will need stuff from us? */
          if (cj_active_gravity) {

814
            struct link *l = scheduler_activate_send(
815
                s, ci->mpi.send, task_subtype_gpart, cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
816
817
818
819
820
821
822
823
824

            /* Drift the cell which will be sent at the level at which it is
               sent, i.e. drift the cell specified in the send task (l->t)
               itself. */
            cell_activate_drift_gpart(l->t->ci, s);
          }

          /* If the local cell is active, send its ti_end values. */
          if (ci_active_gravity)
825
826
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_gpart,
                                    cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
827
828
829
830
831
        }
#endif
      }
    }

832
833
    /* End force for hydro ? */
    else if (t_type == task_type_end_hydro_force) {
Pedro Gonnet's avatar
Pedro Gonnet committed
834

835
836
837
838
839
840
841
      if (cell_is_active_hydro(t->ci, e)) scheduler_activate(s, t);
    }

    /* End force for gravity ? */
    else if (t_type == task_type_end_grav_force) {

      if (cell_is_active_gravity(t->ci, e)) scheduler_activate(s, t);
Pedro Gonnet's avatar
Pedro Gonnet committed
842
843
844
845
846
    }

    /* Kick ? */
    else if (t_type == task_type_kick1 || t_type == task_type_kick2) {

847
848
849
      if (cell_is_active_hydro(t->ci, e) || cell_is_active_gravity(t->ci, e) ||
          cell_is_active_stars(t->ci, e) ||
          cell_is_active_black_holes(t->ci, e))
Pedro Gonnet's avatar
Pedro Gonnet committed
850
851
852
853
854
855
856
857
858
859
860
861
        scheduler_activate(s, t);
    }

    /* Hydro ghost tasks ? */
    else if (t_type == task_type_ghost || t_type == task_type_extra_ghost ||
             t_type == task_type_ghost_in || t_type == task_type_ghost_out) {
      if (cell_is_active_hydro(t->ci, e)) scheduler_activate(s, t);
    }

    /* logger tasks ? */
    else if (t->type == task_type_logger) {
      if (cell_is_active_hydro(t->ci, e) || cell_is_active_gravity(t->ci, e) ||
862
          cell_is_active_stars(t->ci, e))
Pedro Gonnet's avatar
Pedro Gonnet committed
863
864
865
866
867
868
869
870
        scheduler_activate(s, t);
    }

    /* Gravity stuff ? */
    else if (t_type == task_type_grav_down || t_type == task_type_grav_mesh ||
             t_type == task_type_grav_long_range ||
             t_type == task_type_init_grav ||
             t_type == task_type_init_grav_out ||
871
             t_type == task_type_drift_gpart_out ||
Pedro Gonnet's avatar
Pedro Gonnet committed
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
             t_type == task_type_grav_down_in) {
      if (cell_is_active_gravity(t->ci, e)) scheduler_activate(s, t);
    }

    /* Multipole - Multipole interaction task */
    else if (t_type == task_type_grav_mm) {

      /* Local pointers. */
      const struct cell *ci = t->ci;
      const struct cell *cj = t->cj;
#ifdef WITH_MPI
      const int ci_nodeID = ci->nodeID;
      const int cj_nodeID = (cj != NULL) ? cj->nodeID : -1;
#else
      const int ci_nodeID = nodeID;
      const int cj_nodeID = nodeID;
#endif
      const int ci_active_gravity = cell_is_active_gravity_mm(ci, e);
      const int cj_active_gravity = cell_is_active_gravity_mm(cj, e);

      if ((ci_active_gravity && ci_nodeID == nodeID) ||
          (cj_active_gravity && cj_nodeID == nodeID))
        scheduler_activate(s, t);
    }

    /* Star ghost tasks ? */
898
    else if (t_type == task_type_stars_ghost) {
899
900
901
      if (cell_is_active_stars(t->ci, e) ||
          (with_star_formation && cell_is_active_hydro(t->ci, e)))
        scheduler_activate(s, t);
902
903
904
905
    }

    /* Feedback implicit tasks? */
    else if (t_type == task_type_stars_in || t_type == task_type_stars_out) {
906
907
908
      if (cell_is_active_stars(t->ci, e) ||
          (with_star_formation && cell_is_active_hydro(t->ci, e)))
        scheduler_activate(s, t);
Pedro Gonnet's avatar
Pedro Gonnet committed
909
910
    }

911
    /* Black hole ghost tasks ? */
912
913
    else if (t_type == task_type_bh_density_ghost ||
             t_type == task_type_bh_swallow_ghost1 ||
914
915
             t_type == task_type_bh_swallow_ghost2 ||
             t_type == task_type_bh_swallow_ghost3) {
916
917
918
919
920
921
922
923
      if (cell_is_active_black_holes(t->ci, e)) scheduler_activate(s, t);
    }

    /* Black holes implicit tasks? */
    else if (t_type == task_type_bh_in || t_type == task_type_bh_out) {
      if (cell_is_active_black_holes(t->ci, e)) scheduler_activate(s, t);
    }

Pedro Gonnet's avatar
Pedro Gonnet committed
924
925
926
927
928
    /* Time-step? */
    else if (t_type == task_type_timestep) {
      t->ci->hydro.updated = 0;
      t->ci->grav.updated = 0;
      t->ci->stars.updated = 0;
929
930
931
932
      t->ci->black_holes.updated = 0;
      if (cell_is_active_hydro(t->ci, e) || cell_is_active_gravity(t->ci, e) ||
          cell_is_active_stars(t->ci, e) ||
          cell_is_active_black_holes(t->ci, e))
Pedro Gonnet's avatar
Pedro Gonnet committed
933
934
935
        scheduler_activate(s, t);
    }

936
    /* Subgrid tasks: cooling */
Pedro Gonnet's avatar
Pedro Gonnet committed
937
    else if (t_type == task_type_cooling) {
938
939
940
941
942
943
      if (cell_is_active_hydro(t->ci, e)) scheduler_activate(s, t);
    }

    /* Subgrid tasks: star formation */
    else if (t_type == task_type_star_formation) {
      if (cell_is_active_hydro(t->ci, e)) {
Pedro Gonnet's avatar
Pedro Gonnet committed
944
        scheduler_activate(s, t);
945
        cell_activate_super_spart_drifts(t->ci, s);
946
      }
Pedro Gonnet's avatar
Pedro Gonnet committed
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
    }
  }
}

/**
 * @brief Mark tasks to be un-skipped and set the sort flags accordingly.
 *
 * @return 1 if the space has to be rebuilt, 0 otherwise.
 */
int engine_marktasks(struct engine *e) {

  struct scheduler *s = &e->sched;
  const ticks tic = getticks();
  int rebuild_space = 0;

  /* Run through the tasks and mark as skip or not. */
  size_t extra_data[3] = {(size_t)e, (size_t)rebuild_space, (size_t)&e->sched};
  threadpool_map(&e->threadpool, engine_marktasks_mapper, s->tasks, s->nr_tasks,
                 sizeof(struct task), 0, extra_data);
  rebuild_space = extra_data[1];

  if (e->verbose)
    message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
            clocks_getunit());

  /* All is well... */
  return rebuild_space;
}