engine_marktasks.c 35.9 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_timestep_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);
154
          if (with_limiter) cell_activate_sync_part(ci, s);
Pedro Gonnet's avatar
Pedro Gonnet committed
155
156
157
158
159
160
        }
      }

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

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

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

179
180
181
      /* Activate the black hole density */
      else if (t_type == task_type_self &&
               t_subtype == task_subtype_bh_density) {
182
        if (ci_active_black_holes) {
183
184
185
186
187
188
189
190
191
          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) {
192
        if (ci_active_black_holes) {
193
          scheduler_activate(s, t);
194
          cell_activate_subcell_black_holes_tasks(ci, NULL, s);
195
196
197
        }
      }

198
199
200
201
202
203
204
205
206
207
208
209
210
      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 &&
211
               t_subtype == task_subtype_do_gas_swallow) {
212
213
214
215
216
217
        if (ci_active_black_holes) {
          scheduler_activate(s, t);
        }
      }

      else if (t_type == task_type_sub_self &&
218
219
220
221
222
223
224
225
226
227
228
229
230
               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) {
231
232
233
        if (ci_active_black_holes) scheduler_activate(s, t);
      }

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

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

Pedro Gonnet's avatar
Pedro Gonnet committed
246
247
      /* Activate the gravity drift */
      else if (t_type == task_type_self && t_subtype == task_subtype_grav) {
248
        if (ci_active_gravity) {
Pedro Gonnet's avatar
Pedro Gonnet committed
249
250
251
252
253
254
255
256
          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) {
257
        if (ci_active_gravity) {
Pedro Gonnet's avatar
Pedro Gonnet committed
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
284
          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);
285

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

289
290
291
      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);

292
293
294
295
296
      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
297
298
299
      /* Only activate tasks that involve a local active cell. */
      if ((t_subtype == task_subtype_density ||
           t_subtype == task_subtype_gradient ||
300
           t_subtype == task_subtype_limiter ||
Pedro Gonnet's avatar
Pedro Gonnet committed
301
302
303
304
305
306
307
           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
308
        if (t_type == task_type_pair && t_subtype == task_subtype_density) {
Pedro Gonnet's avatar
Pedro Gonnet committed
309
310
311
312
313
314
315
316
317
318
319

          /* 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);

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

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

        }

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

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

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

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

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

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

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

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

364
365
366
367
            /* 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
368
369

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

372
            /* hydro for ci */
373
            atomic_or(&ci->hydro.requires_sorts, 1 << t->flags);
374
            ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort;
375

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

380
            /* Activate the drift tasks. */
381
382
            if (ci_nodeID == nodeID) cell_activate_drift_part(ci, s);
            if (cj_nodeID == nodeID) cell_activate_drift_spart(cj, s);
383
384
            if (ci_nodeID == nodeID && with_limiter)
              cell_activate_sync_part(ci, s);
Loic Hausammann's avatar
Loic Hausammann committed
385

386
387
388
389
            /* 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
390
391
392
        }

        /* Store current values of dx_max and h_max. */
393
        else if (t_type == task_type_sub_pair &&
394
                 t_subtype == task_subtype_stars_density) {
395
          cell_activate_subcell_stars_tasks(ci, cj, s, with_star_formation);
Pedro Gonnet's avatar
Pedro Gonnet committed
396
397
398
        }
      }

399
      /* Stars feedback */
400
      else if (t_subtype == task_subtype_stars_feedback) {
401

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
        /* 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);
        }
419
      }
420

421
      /* Black_Holes density */
422
423
      else if ((t_subtype == task_subtype_bh_density ||
                t_subtype == task_subtype_bh_swallow ||
424
                t_subtype == task_subtype_do_gas_swallow ||
425
                t_subtype == task_subtype_do_bh_swallow ||
426
                t_subtype == task_subtype_bh_feedback) &&
427
428
429
430
431
               (ci_active_black_holes || cj_active_black_holes) &&
               (ci_nodeID == nodeID || cj_nodeID == nodeID)) {

        scheduler_activate(s, t);

432
        /* Set the correct drifting flags */
433
434
435
        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);
436

437
438
          if (cj_nodeID == nodeID) cell_activate_drift_part(cj, s);
          if (cj_nodeID == nodeID) cell_activate_drift_bpart(cj, s);
439
440
441
442
443
444
445
446
447
        }

        /* 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);
        }
      }

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

        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
472
        if (cell_need_rebuild_for_hydro_pair(ci, cj)) *rebuild_space = 1;
Pedro Gonnet's avatar
Pedro Gonnet committed
473
474
475
476
477
478
479

#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) {
480
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
Pedro Gonnet's avatar
Pedro Gonnet committed
481
            if (ci_active_hydro) {
482
              scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
Pedro Gonnet's avatar
Pedro Gonnet committed
483
#ifdef EXTRA_HYDRO_LOOP
484
              scheduler_activate_recv(s, ci->mpi.recv, task_subtype_gradient);
Pedro Gonnet's avatar
Pedro Gonnet committed
485
486
487
488
489
#endif
            }
          }

          /* If the foreign cell is active, we want its ti_end values. */
490
491
          if (ci_active_hydro)
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_part);
Pedro Gonnet's avatar
Pedro Gonnet committed
492
493
494

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

            /* 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) {
505
506
              scheduler_activate_send(s, cj->mpi.send, task_subtype_rho,
                                      ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
507
508

#ifdef EXTRA_HYDRO_LOOP
509
510
              scheduler_activate_send(s, cj->mpi.send, task_subtype_gradient,
                                      ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
511
512
513
514
515
516
#endif
            }
          }

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

520
521
522
523
          /* 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);
524
              scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_spart);
525
526
527
528
            }
            if (cj_active_hydro && cj->hydro.count > 0) {
              scheduler_activate_send(s, cj->mpi.send, task_subtype_sf_counts,
                                      ci_nodeID);
529
530
              scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart,
                                      ci_nodeID);
531
532
533
            }
          }

Pedro Gonnet's avatar
Pedro Gonnet committed
534
535
536
537
        } else if (cj_nodeID != nodeID) {

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

539
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
Pedro Gonnet's avatar
Pedro Gonnet committed
540
            if (cj_active_hydro) {
541
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
Pedro Gonnet's avatar
Pedro Gonnet committed
542
#ifdef EXTRA_HYDRO_LOOP
543
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_gradient);
Pedro Gonnet's avatar
Pedro Gonnet committed
544
545
546
547
548
#endif
            }
          }

          /* If the foreign cell is active, we want its ti_end values. */
549
550
          if (cj_active_hydro)
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_part);
Pedro Gonnet's avatar
Pedro Gonnet committed
551
552
553
554

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

555
            struct link *l = scheduler_activate_send(
556
                s, ci->mpi.send, task_subtype_xv, cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
557
558
559
560
561
562
563
564
565

            /* 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) {

566
567
              scheduler_activate_send(s, ci->mpi.send, task_subtype_rho,
                                      cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
568
569

#ifdef EXTRA_HYDRO_LOOP
570
571
              scheduler_activate_send(s, ci->mpi.send, task_subtype_gradient,
                                      cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
572
573
574
575
576
577
#endif
            }
          }

          /* If the local cell is active, send its ti_end values. */
          if (ci_active_hydro)
578
579
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_part,
                                    cj_nodeID);
580
581
582
583
584

          /* 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);
585
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_spart);
586
587
588
589
            }
            if (ci_active_hydro && ci->hydro.count > 0) {
              scheduler_activate_send(s, ci->mpi.send, task_subtype_sf_counts,
                                      cj_nodeID);
590
591
              scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart,
                                      cj_nodeID);
592
593
            }
          }
Pedro Gonnet's avatar
Pedro Gonnet committed
594
595
596
597
598
        }
#endif
      }

      /* Only interested in stars_density tasks as of here. */
599
      else if (t->subtype == task_subtype_stars_density) {
600
601
602
603
604

        /* 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;

605
#ifdef WITH_MPI
606
607
608
609
        /* Activate the send/recv tasks. */
        if (ci_nodeID != nodeID) {

          if (cj_active_stars) {
610
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
611
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
612
613

            /* If the local cell is active, more stuff will be needed. */
614
            scheduler_activate_send(s, cj->mpi.send, task_subtype_spart,
615
                                    ci_nodeID);
616
617
618
            cell_activate_drift_spart(cj, s);

            /* If the local cell is active, send its ti_end values. */
619
620
            scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart,
                                    ci_nodeID);
621
622
623
          }

          if (ci_active_stars) {
624
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_spart);
625
626

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

            /* Is the foreign cell active and will need stuff from us? */
630
            scheduler_activate_send(s, cj->mpi.send, task_subtype_xv,
631
                                    ci_nodeID);
632
            scheduler_activate_send(s, cj->mpi.send, task_subtype_rho,
633
                                    ci_nodeID);
634
635
636
637
638
639
640
641
642
643

            /* 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) {
644
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
645
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
646
647

            /* If the local cell is active, more stuff will be needed. */
648
            scheduler_activate_send(s, ci->mpi.send, task_subtype_spart,
649
                                    cj_nodeID);
650
651
652
            cell_activate_drift_spart(ci, s);

            /* If the local cell is active, send its ti_end values. */
653
654
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart,
                                    cj_nodeID);
655
656
657
          }

          if (cj_active_stars) {
658
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_spart);
659
660

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

            /* Is the foreign cell active and will need stuff from us? */
664
            scheduler_activate_send(s, ci->mpi.send, task_subtype_xv,
665
                                    cj_nodeID);
666
            scheduler_activate_send(s, ci->mpi.send, task_subtype_rho,
667
                                    cj_nodeID);
668
669
670
671
672
673

            /* 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);
          }
        }
674
#endif
Pedro Gonnet's avatar
Pedro Gonnet committed
675
      }
676

677
      /* Only interested in black hole density tasks as of here. */
678
679
680
681
682
683
      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;

684
685
686
        scheduler_activate(s, ci->hydro.super->black_holes.swallow_ghost[0]);
        scheduler_activate(s, cj->hydro.super->black_holes.swallow_ghost[0]);

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

691
692
693
694
          /* 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);
695
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart_merger);
696

697
698
699
700
701
702
          /* 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);
703

704
705
          /* Drift before you send */
          cell_activate_drift_bpart(cj, s);
706

707
708
709
          /* Send the new BH time-steps */
          scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_bpart,
                                  ci_nodeID);
710

711
712
713
714
          /* 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);
715

716
717
          /* Receive the foreign BH time-steps */
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_bpart);
718

719
720
721
722
          /* 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);
723
724
          scheduler_activate_send(s, cj->mpi.send, task_subtype_bpart_merger,
                                  ci_nodeID);
725
726
727
728

          /* 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);
729
730
731

        } else if (cj_nodeID != nodeID) {

732
733
734
735
          /* 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);
736
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart_merger);
737

738
739
740
741
742
743
          /* 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);
744

745
746
          /* Drift before you send */
          cell_activate_drift_bpart(ci, s);
747

748
749
750
          /* Send the new BH time-steps */
          scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_bpart,
                                  cj_nodeID);
751

752
753
754
755
          /* 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);
756

757
758
          /* Receive the foreign BH time-steps */
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_bpart);
759

760
761
762
763
          /* 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);
764
765
          scheduler_activate_send(s, ci->mpi.send, task_subtype_bpart_merger,
                                  cj_nodeID);
766
767
768
769

          /* 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);
770
771
772
773
        }
#endif
      }

Pedro Gonnet's avatar
Pedro Gonnet committed
774
      /* Only interested in gravity tasks as of here. */
775
      else if (t_subtype == task_subtype_grav) {
Pedro Gonnet's avatar
Pedro Gonnet committed
776
777
778
779
780
781

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

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

          /* If the foreign cell is active, we want its ti_end values. */
786
787
          if (ci_active_gravity)
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_gpart);
Pedro Gonnet's avatar
Pedro Gonnet committed
788
789
790
791

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

792
            struct link *l = scheduler_activate_send(
793
                s, cj->mpi.send, task_subtype_gpart, ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
794
795
796
797
798
799
800
801
802

            /* 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)
803
804
            scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_gpart,
                                    ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
805
806
807
808

        } else if (cj_nodeID != nodeID) {

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

          /* If the foreign cell is active, we want its ti_end values. */
813
814
          if (cj_active_gravity)
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_gpart);
Pedro Gonnet's avatar
Pedro Gonnet committed
815
816
817
818

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

819
            struct link *l = scheduler_activate_send(
820
                s, ci->mpi.send, task_subtype_gpart, cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
821
822
823
824
825
826
827
828
829

            /* 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)
830
831
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_gpart,
                                    cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
832
833
834
835
836
        }
#endif
      }
    }

837
838
    /* End force for hydro ? */
    else if (t_type == task_type_end_hydro_force) {
Pedro Gonnet's avatar
Pedro Gonnet committed
839

840
841
842
843
844
845
846
      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
847
848
849
850
851
    }

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

852
853
854
      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
855
856
857
858
859
860
861
862
863
864
865
866
        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) ||
867
          cell_is_active_stars(t->ci, e))
Pedro Gonnet's avatar
Pedro Gonnet committed
868
869
870
871
872
873
874
875
        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 ||
876
             t_type == task_type_drift_gpart_out ||
Pedro Gonnet's avatar
Pedro Gonnet committed
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
             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 ? */
903
    else if (t_type == task_type_stars_ghost) {
904
905
906
      if (cell_is_active_stars(t->ci, e) ||
          (with_star_formation && cell_is_active_hydro(t->ci, e)))
        scheduler_activate(s, t);
907
908
909
910
    }

    /* Feedback implicit tasks? */
    else if (t_type == task_type_stars_in || t_type == task_type_stars_out) {
911
912
913
      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
914
915
    }

916
    /* Black hole ghost tasks ? */
917
918
    else if (t_type == task_type_bh_density_ghost ||
             t_type == task_type_bh_swallow_ghost1 ||
919
920
             t_type == task_type_bh_swallow_ghost2 ||
             t_type == task_type_bh_swallow_ghost3) {
921
922
923
924
925
926
927
928
      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);
    }

929
930
931
932
933
934
    /* Limiter implicit tasks? */
    else if (t_type == task_type_limiter_in ||
             t_type == task_type_limiter_out) {
      if (cell_is_active_hydro(t->ci, e)) scheduler_activate(s, t);
    }

Pedro Gonnet's avatar
Pedro Gonnet committed
935
936
937
938
939
    /* Time-step? */
    else if (t_type == task_type_timestep) {
      t->ci->hydro.updated = 0;
      t->ci->grav.updated = 0;
      t->ci->stars.updated = 0;
940
941
942
943
      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
944
945
946
        scheduler_activate(s, t);
    }

947
    /* Subgrid tasks: cooling */
Pedro Gonnet's avatar
Pedro Gonnet committed
948
    else if (t_type == task_type_cooling) {
949
950
951
952
      if (cell_is_active_hydro(t->ci, e)) scheduler_activate(s, t);
    }

    /* Subgrid tasks: star formation */
953
    else if (t_type == task_type_star_formation) {
954
      if (cell_is_active_hydro(t->ci, e)) {
955
        cell_activate_star_formation_tasks(t->ci, s);
956
        cell_activate_super_spart_drifts(t->ci, s);
957
      }
Pedro Gonnet's avatar
Pedro Gonnet committed
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
    }
  }
}

/**
 * @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;
}