engine_marktasks.c 33.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_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
        }
      }

      else if (t_type == task_type_self &&
               t_subtype == task_subtype_bh_feedback) {
199
        if (ci_active_black_holes) {
200
201
202
203
204
205
          scheduler_activate(s, t);
        }
      }

      else if (t_type == task_type_sub_self &&
               t_subtype == task_subtype_bh_feedback) {
206
        if (ci_active_black_holes) scheduler_activate(s, t);
207
208
      }

Pedro Gonnet's avatar
Pedro Gonnet committed
209
210
      /* Activate the gravity drift */
      else if (t_type == task_type_self && t_subtype == task_subtype_grav) {
211
        if (ci_active_gravity) {
Pedro Gonnet's avatar
Pedro Gonnet committed
212
213
214
215
216
217
218
219
          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) {
220
        if (ci_active_gravity) {
Pedro Gonnet's avatar
Pedro Gonnet committed
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
          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);
248

Pedro Gonnet's avatar
Pedro Gonnet committed
249
250
      const int ci_active_gravity = cell_is_active_gravity(ci, e);
      const int cj_active_gravity = cell_is_active_gravity(cj, e);
251

252
253
254
      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);

255
256
257
258
259
      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
260
261
262
      /* Only activate tasks that involve a local active cell. */
      if ((t_subtype == task_subtype_density ||
           t_subtype == task_subtype_gradient ||
263
           t_subtype == task_subtype_limiter ||
Pedro Gonnet's avatar
Pedro Gonnet committed
264
265
266
267
268
269
270
           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
271
        if (t_type == task_type_pair && t_subtype == task_subtype_density) {
Pedro Gonnet's avatar
Pedro Gonnet committed
272
273
274
275
276
277
278
279
280
281
282

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

283
          /* And the limiter */
284
285
          if (ci_nodeID == nodeID && with_limiter) cell_activate_limiter(ci, s);
          if (cj_nodeID == nodeID && with_limiter) cell_activate_limiter(cj, s);
286

Pedro Gonnet's avatar
Pedro Gonnet committed
287
          /* Check the sorts and activate them if needed. */
288
289
          cell_activate_hydro_sorts(ci, t->flags, s);
          cell_activate_hydro_sorts(cj, t->flags, s);
Pedro Gonnet's avatar
Pedro Gonnet committed
290
291
292
293
294

        }

        /* Store current values of dx_max and h_max. */
        else if (t_type == task_type_sub_pair &&
Loic Hausammann's avatar
Loic Hausammann committed
295
                 t_subtype == task_subtype_density) {
Pedro Gonnet's avatar
Pedro Gonnet committed
296
297
298
299
          cell_activate_subcell_hydro_tasks(t->ci, t->cj, s);
        }
      }

300
301
      /* Stars density */
      else if ((t_subtype == task_subtype_stars_density) &&
302
303
304
               (ci_active_stars || cj_active_stars) &&
               (ci_nodeID == nodeID || cj_nodeID == nodeID)) {

loikki's avatar
loikki committed
305
        scheduler_activate(s, t);
306

Pedro Gonnet's avatar
Pedro Gonnet committed
307
308
309
        /* Set the correct sorting flags */
        if (t_type == task_type_pair) {

Loic Hausammann's avatar
Loic Hausammann committed
310
          /* Do ci */
loikki's avatar
loikki committed
311
          if (ci_active_stars) {
312

313
            /* stars for ci */
314
            atomic_or(&ci->stars.requires_sorts, 1 << t->flags);
315
            ci->stars.dx_max_sort_old = ci->stars.dx_max_sort;
Loic Hausammann's avatar
Loic Hausammann committed
316

317
            /* hydro for cj */
318
            atomic_or(&cj->hydro.requires_sorts, 1 << t->flags);
319
            cj->hydro.dx_max_sort_old = cj->hydro.dx_max_sort;
Pedro Gonnet's avatar
Pedro Gonnet committed
320

321
            /* Activate the drift tasks. */
322
323
            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
324

325
326
327
328
            /* 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
329
330

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

333
            /* hydro for ci */
334
            atomic_or(&ci->hydro.requires_sorts, 1 << t->flags);
335
            ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort;
336

337
            /* stars for cj */
338
            atomic_or(&cj->stars.requires_sorts, 1 << t->flags);
339
            cj->stars.dx_max_sort_old = cj->stars.dx_max_sort;
Loic Hausammann's avatar
Loic Hausammann committed
340

341
            /* Activate the drift tasks. */
342
343
            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
344

345
346
347
348
            /* 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
349
350
351
        }

        /* Store current values of dx_max and h_max. */
352
        else if (t_type == task_type_sub_pair &&
353
                 t_subtype == task_subtype_stars_density) {
354
          cell_activate_subcell_stars_tasks(ci, cj, s, with_star_formation);
Pedro Gonnet's avatar
Pedro Gonnet committed
355
356
357
        }
      }

358
      /* Stars feedback */
359
      else if (t_subtype == task_subtype_stars_feedback) {
360

361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
        /* 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);
        }
378
      }
379

380
381
382
383
384
385
386
387
388
389
390
391
392
393
      /* Black_Holes density */
      else if ((t_subtype == task_subtype_bh_density) &&
               (ci_active_black_holes || cj_active_black_holes) &&
               (ci_nodeID == nodeID || cj_nodeID == nodeID)) {

        scheduler_activate(s, t);

        /* Set the correct sorting flags */
        if (t_type == task_type_pair) {

          /* Do ci */
          if (ci_active_black_holes) {

            /* Activate the drift tasks. */
394
            if (ci_nodeID == nodeID) cell_activate_drift_bpart(ci, s);
395
396
397
398
399
400
401
402
            if (cj_nodeID == nodeID) cell_activate_drift_part(cj, s);
          }

          /* Do cj */
          if (cj_active_black_holes) {

            /* Activate the drift tasks. */
            if (ci_nodeID == nodeID) cell_activate_drift_part(ci, s);
403
            if (cj_nodeID == nodeID) cell_activate_drift_bpart(cj, s);
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
          }
        }

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

      /* Black_Holes feedback */
      else if (t_subtype == task_subtype_bh_feedback) {

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

          scheduler_activate(s, t);

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

          scheduler_activate(s, t);

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

          scheduler_activate(s, t);
        }
      }

436
      /* Gravity */
437
      else if ((t_subtype == task_subtype_grav) &&
438
439
               ((ci_active_gravity && ci_nodeID == nodeID) ||
                (cj_active_gravity && cj_nodeID == nodeID))) {
Pedro Gonnet's avatar
Pedro Gonnet committed
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459

        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
460
        if (cell_need_rebuild_for_hydro_pair(ci, cj)) *rebuild_space = 1;
Pedro Gonnet's avatar
Pedro Gonnet committed
461
462
463
464
465
466
467

#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) {
468
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
Pedro Gonnet's avatar
Pedro Gonnet committed
469
            if (ci_active_hydro) {
470
              scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
Pedro Gonnet's avatar
Pedro Gonnet committed
471
#ifdef EXTRA_HYDRO_LOOP
472
              scheduler_activate_recv(s, ci->mpi.recv, task_subtype_gradient);
Pedro Gonnet's avatar
Pedro Gonnet committed
473
474
475
476
477
#endif
            }
          }

          /* If the foreign cell is active, we want its ti_end values. */
478
479
          if (ci_active_hydro)
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_part);
Pedro Gonnet's avatar
Pedro Gonnet committed
480
481
482

          /* Is the foreign cell active and will need stuff from us? */
          if (ci_active_hydro) {
483
            struct link *l = scheduler_activate_send(
484
                s, cj->mpi.send, task_subtype_xv, ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
485
486
487
488
489
490
491
492

            /* 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) {
493
494
              scheduler_activate_send(s, cj->mpi.send, task_subtype_rho,
                                      ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
495
496

#ifdef EXTRA_HYDRO_LOOP
497
498
              scheduler_activate_send(s, cj->mpi.send, task_subtype_gradient,
                                      ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
499
500
501
502
503
504
#endif
            }
          }

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

508
509
510
511
          /* 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);
512
              scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_spart);
513
514
515
516
            }
            if (cj_active_hydro && cj->hydro.count > 0) {
              scheduler_activate_send(s, cj->mpi.send, task_subtype_sf_counts,
                                      ci_nodeID);
517
518
              scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart,
                                      ci_nodeID);
519
520
521
            }
          }

Pedro Gonnet's avatar
Pedro Gonnet committed
522
523
524
525
        } else if (cj_nodeID != nodeID) {

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

527
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
Pedro Gonnet's avatar
Pedro Gonnet committed
528
            if (cj_active_hydro) {
529
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
Pedro Gonnet's avatar
Pedro Gonnet committed
530
#ifdef EXTRA_HYDRO_LOOP
531
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_gradient);
Pedro Gonnet's avatar
Pedro Gonnet committed
532
533
534
535
536
#endif
            }
          }

          /* If the foreign cell is active, we want its ti_end values. */
537
538
          if (cj_active_hydro)
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_part);
Pedro Gonnet's avatar
Pedro Gonnet committed
539
540
541
542

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

543
            struct link *l = scheduler_activate_send(
544
                s, ci->mpi.send, task_subtype_xv, cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
545
546
547
548
549
550
551
552
553

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

554
555
              scheduler_activate_send(s, ci->mpi.send, task_subtype_rho,
                                      cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
556
557

#ifdef EXTRA_HYDRO_LOOP
558
559
              scheduler_activate_send(s, ci->mpi.send, task_subtype_gradient,
                                      cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
560
561
562
563
564
565
#endif
            }
          }

          /* If the local cell is active, send its ti_end values. */
          if (ci_active_hydro)
566
567
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_part,
                                    cj_nodeID);
568
569
570
571
572

          /* 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);
573
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_spart);
574
575
576
577
            }
            if (ci_active_hydro && ci->hydro.count > 0) {
              scheduler_activate_send(s, ci->mpi.send, task_subtype_sf_counts,
                                      cj_nodeID);
578
579
              scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart,
                                      cj_nodeID);
580
581
            }
          }
Pedro Gonnet's avatar
Pedro Gonnet committed
582
583
584
585
586
        }
#endif
      }

      /* Only interested in stars_density tasks as of here. */
587
      else if (t->subtype == task_subtype_stars_density) {
588
589
590
591
592

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

593
#ifdef WITH_MPI
594
595
596
597
        /* Activate the send/recv tasks. */
        if (ci_nodeID != nodeID) {

          if (cj_active_stars) {
598
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
599
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
600
601

            /* If the local cell is active, more stuff will be needed. */
602
            scheduler_activate_send(s, cj->mpi.send, task_subtype_spart,
603
                                    ci_nodeID);
604
605
606
            cell_activate_drift_spart(cj, s);

            /* If the local cell is active, send its ti_end values. */
607
608
            scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart,
                                    ci_nodeID);
609
610
611
          }

          if (ci_active_stars) {
612
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_spart);
613
614

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

            /* Is the foreign cell active and will need stuff from us? */
618
            scheduler_activate_send(s, cj->mpi.send, task_subtype_xv,
619
                                    ci_nodeID);
620
            scheduler_activate_send(s, cj->mpi.send, task_subtype_rho,
621
                                    ci_nodeID);
622
623
624
625
626
627
628
629
630
631

            /* 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) {
632
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
633
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
634
635

            /* If the local cell is active, more stuff will be needed. */
636
            scheduler_activate_send(s, ci->mpi.send, task_subtype_spart,
637
                                    cj_nodeID);
638
639
640
            cell_activate_drift_spart(ci, s);

            /* If the local cell is active, send its ti_end values. */
641
642
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart,
                                    cj_nodeID);
643
644
645
          }

          if (cj_active_stars) {
646
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_spart);
647
648

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

            /* Is the foreign cell active and will need stuff from us? */
652
            scheduler_activate_send(s, ci->mpi.send, task_subtype_xv,
653
                                    cj_nodeID);
654
            scheduler_activate_send(s, ci->mpi.send, task_subtype_rho,
655
                                    cj_nodeID);
656
657
658
659
660
661

            /* 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);
          }
        }
662
#endif
Pedro Gonnet's avatar
Pedro Gonnet committed
663
      }
664

665
666
667
668
669
670
671
672
673
674
675
676
      /* Only interested in stars_density tasks as of here. */
      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;

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

          if (cj_active_black_holes) {
677
678
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
679
680

            /* If the local cell is active, more stuff will be needed. */
681
682
            scheduler_activate_send(s, cj->mpi.send, task_subtype_bpart,
                                    ci_nodeID);
683
            cell_activate_drift_bpart(cj, s);
684
685

            /* If the local cell is active, send its ti_end values. */
686
687
            scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_bpart,
                                    ci_nodeID);
688
689
690
          }

          if (ci_active_black_holes) {
691
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart);
692
693

            /* If the foreign cell is active, we want its ti_end values. */
694
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_bpart);
695
696

            /* Is the foreign cell active and will need stuff from us? */
697
698
699
700
            scheduler_activate_send(s, cj->mpi.send, task_subtype_xv,
                                    ci_nodeID);
            scheduler_activate_send(s, cj->mpi.send, task_subtype_rho,
                                    ci_nodeID);
701
702
703
704
705
706
707
708
709
710

            /* 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_black_holes) {
711
712
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
713
714

            /* If the local cell is active, more stuff will be needed. */
715
716
            scheduler_activate_send(s, ci->mpi.send, task_subtype_bpart,
                                    cj_nodeID);
717
            cell_activate_drift_bpart(ci, s);
718
719

            /* If the local cell is active, send its ti_end values. */
720
721
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_bpart,
                                    cj_nodeID);
722
723
724
          }

          if (cj_active_black_holes) {
725
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart);
726
727

            /* If the foreign cell is active, we want its ti_end values. */
728
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_bpart);
729
730

            /* Is the foreign cell active and will need stuff from us? */
731
732
733
734
            scheduler_activate_send(s, ci->mpi.send, task_subtype_xv,
                                    cj_nodeID);
            scheduler_activate_send(s, ci->mpi.send, task_subtype_rho,
                                    cj_nodeID);
735
736
737
738
739
740
741
742
743

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

Pedro Gonnet's avatar
Pedro Gonnet committed
744
      /* Only interested in gravity tasks as of here. */
745
      else if (t_subtype == task_subtype_grav) {
Pedro Gonnet's avatar
Pedro Gonnet committed
746
747
748
749
750
751

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

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

          /* If the foreign cell is active, we want its ti_end values. */
756
757
          if (ci_active_gravity)
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_gpart);
Pedro Gonnet's avatar
Pedro Gonnet committed
758
759
760
761

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

762
            struct link *l = scheduler_activate_send(
763
                s, cj->mpi.send, task_subtype_gpart, ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
764
765
766
767
768
769
770
771
772

            /* 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)
773
774
            scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_gpart,
                                    ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
775
776
777
778

        } else if (cj_nodeID != nodeID) {

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

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

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

789
            struct link *l = scheduler_activate_send(
790
                s, ci->mpi.send, task_subtype_gpart, cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
791
792
793
794
795
796
797
798
799

            /* 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)
800
801
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_gpart,
                                    cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
802
803
804
805
806
        }
#endif
      }
    }

807
808
    /* End force for hydro ? */
    else if (t_type == task_type_end_hydro_force) {
Pedro Gonnet's avatar
Pedro Gonnet committed
809

810
811
812
813
814
815
816
      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
817
818
819
820
821
    }

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

822
823
824
      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
825
826
827
828
829
830
831
832
833
834
835
836
        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) ||
837
          cell_is_active_stars(t->ci, e))
Pedro Gonnet's avatar
Pedro Gonnet committed
838
839
840
841
842
843
844
845
        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 ||
846
             t_type == task_type_drift_gpart_out ||
Pedro Gonnet's avatar
Pedro Gonnet committed
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
             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 ? */
873
    else if (t_type == task_type_stars_ghost) {
874
875
876
      if (cell_is_active_stars(t->ci, e) ||
          (with_star_formation && cell_is_active_hydro(t->ci, e)))
        scheduler_activate(s, t);
877
878
879
880
    }

    /* Feedback implicit tasks? */
    else if (t_type == task_type_stars_in || t_type == task_type_stars_out) {
881
882
883
      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
884
885
    }

886
887
888
889
890
891
892
893
894
895
    /* Black hole ghost tasks ? */
    else if (t_type == task_type_bh_ghost) {
      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
896
897
898
899
900
    /* Time-step? */
    else if (t_type == task_type_timestep) {
      t->ci->hydro.updated = 0;
      t->ci->grav.updated = 0;
      t->ci->stars.updated = 0;
901
902
903
904
      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
905
906
907
        scheduler_activate(s, t);
    }

908
    /* Subgrid tasks: cooling */
Pedro Gonnet's avatar
Pedro Gonnet committed
909
    else if (t_type == task_type_cooling) {
910
911
912
913
914
915
      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
916
        scheduler_activate(s, t);
917
        cell_activate_super_spart_drifts(t->ci, s);
918
      }
Pedro Gonnet's avatar
Pedro Gonnet committed
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
    }
  }
}

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