engine_marktasks.c 33.5 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
97
98
#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_stars = cell_is_active_stars(ci, e);
      const int ci_active_black_holes = cell_is_active_black_holes(ci, e);
      
Pedro Gonnet's avatar
Pedro Gonnet committed
99
100
      /* Activate the hydro drift */
      if (t_type == task_type_self && t_subtype == task_subtype_density) {
101
        if (ci_active_hydro) {
Pedro Gonnet's avatar
Pedro Gonnet committed
102
103
          scheduler_activate(s, t);
          cell_activate_drift_part(ci, s);
104
          if (with_limiter) cell_activate_limiter(ci, s);
Pedro Gonnet's avatar
Pedro Gonnet committed
105
106
107
108
109
110
        }
      }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Pedro Gonnet's avatar
Pedro Gonnet committed
208
209
      /* Activate the gravity drift */
      else if (t_type == task_type_self && t_subtype == task_subtype_grav) {
210
        if (ci_active_gravity) {
Pedro Gonnet's avatar
Pedro Gonnet committed
211
212
213
214
215
216
217
218
          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) {
219
        if (ci_active_gravity) {
Pedro Gonnet's avatar
Pedro Gonnet committed
220
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
          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);
247

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

251
252
253
      const int ci_active_stars = cell_is_active_stars(ci, e);
      const int cj_active_stars = cell_is_active_stars(cj, e);

254
255
256
      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);

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

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

280
          /* And the limiter */
281
282
          if (ci_nodeID == nodeID && with_limiter) cell_activate_limiter(ci, s);
          if (cj_nodeID == nodeID && with_limiter) cell_activate_limiter(cj, s);
283

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

        }

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

297
298
      /* Stars density */
      else if ((t_subtype == task_subtype_stars_density) &&
299
300
301
               (ci_active_stars || cj_active_stars) &&
               (ci_nodeID == nodeID || cj_nodeID == nodeID)) {

loikki's avatar
loikki committed
302
        scheduler_activate(s, t);
303

Pedro Gonnet's avatar
Pedro Gonnet committed
304
305
306
        /* Set the correct sorting flags */
        if (t_type == task_type_pair) {

Loic Hausammann's avatar
Loic Hausammann committed
307
          /* Do ci */
loikki's avatar
loikki committed
308
          if (ci_active_stars) {
309

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

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

318
            /* Activate the drift tasks. */
319
320
            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
321

322
323
324
325
            /* 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
326
327

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

330
            /* hydro for ci */
331
            atomic_or(&ci->hydro.requires_sorts, 1 << t->flags);
332
            ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort;
333

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

338
            /* Activate the drift tasks. */
339
340
            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
341

342
343
344
345
            /* 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
346
347
348
        }

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

355
      /* Stars feedback */
356
      else if (t_subtype == task_subtype_stars_feedback) {
357

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

377
378
379
380
381
382
383
384
385
386
387
388
389
390
      /* 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. */
391
            if (ci_nodeID == nodeID) cell_activate_drift_bpart(ci, s);
392
393
394
395
396
397
398
399
            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);
400
            if (cj_nodeID == nodeID) cell_activate_drift_bpart(cj, s);
401
402
403
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
          }
        }

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

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

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

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

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

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

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

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

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

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

Pedro Gonnet's avatar
Pedro Gonnet committed
519
520
521
522
        } else if (cj_nodeID != nodeID) {

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

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

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

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

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

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

551
552
              scheduler_activate_send(s, ci->mpi.send, task_subtype_rho,
                                      cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
553
554

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

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

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

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

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

590
#ifdef WITH_MPI
591
592
593
594
        /* Activate the send/recv tasks. */
        if (ci_nodeID != nodeID) {

          if (cj_active_stars) {
595
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
596
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
597
598

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

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

          if (ci_active_stars) {
609
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_spart);
610
611

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

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

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

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

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

          if (cj_active_stars) {
643
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_spart);
644
645

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

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

            /* 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);
          }
        }
659
#endif
Pedro Gonnet's avatar
Pedro Gonnet committed
660
      }
661

662
663
664
665
666
667
668
669
670
671
672
673
      /* 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) {
674
675
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
676
677

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

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

          if (ci_active_black_holes) {
688
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart);
689
690

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

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

            /* 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) {
708
709
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
710
711

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

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

          if (cj_active_black_holes) {
722
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart);
723
724

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

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

            /* 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
741
      /* Only interested in gravity tasks as of here. */
742
      else if (t_subtype == task_subtype_grav) {
Pedro Gonnet's avatar
Pedro Gonnet committed
743
744
745
746
747
748

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

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

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

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

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

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

        } else if (cj_nodeID != nodeID) {

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

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

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

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

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

804
805
    /* End force for hydro ? */
    else if (t_type == task_type_end_hydro_force) {
Pedro Gonnet's avatar
Pedro Gonnet committed
806

807
808
809
810
811
812
813
      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
814
815
816
817
818
    }

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

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

    /* Feedback implicit tasks? */
    else if (t_type == task_type_stars_in || t_type == task_type_stars_out) {
876
      if (cell_is_active_stars(t->ci, e)) scheduler_activate(s, t);
Pedro Gonnet's avatar
Pedro Gonnet committed
877
878
    }

879
880
881
882
883
884
885
886
887
888
    /* 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
889
890
891
892
893
    /* Time-step? */
    else if (t_type == task_type_timestep) {
      t->ci->hydro.updated = 0;
      t->ci->grav.updated = 0;
      t->ci->stars.updated = 0;
894
895
896
897
      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
898
899
900
        scheduler_activate(s, t);
    }

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

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