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
#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
      /* Only interested in black hole density tasks as of here. */
666
667
668
669
670
671
672
673
674
675
676
      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
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
678
679

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

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

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

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

            /* Is the foreign cell active and will need stuff from us? */
696
697
            scheduler_activate_send(s, cj->mpi.send, task_subtype_xv,
                                    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
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
709
710

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

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

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

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

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

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

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

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

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

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

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

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

        } else if (cj_nodeID != nodeID) {

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

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

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

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

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

801
802
    /* End force for hydro ? */
    else if (t_type == task_type_end_hydro_force) {
Pedro Gonnet's avatar
Pedro Gonnet committed
803

804
805
806
807
808
809
810
      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
811
812
813
814
815
    }

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

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

    /* Feedback implicit tasks? */
    else if (t_type == task_type_stars_in || t_type == task_type_stars_out) {
875
876
877
      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
878
879
    }

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

902
    /* Subgrid tasks: cooling */
Pedro Gonnet's avatar
Pedro Gonnet committed
903
    else if (t_type == task_type_cooling) {
904
905
906
907
      if (cell_is_active_hydro(t->ci, e)) scheduler_activate(s, t);
    }

    /* Subgrid tasks: star formation */
908
909
    else if (t_type == task_type_star_formation ||
             t_type == task_type_stars_resort) {
910
      if (cell_is_active_hydro(t->ci, e)) {
Pedro Gonnet's avatar
Pedro Gonnet committed
911
        scheduler_activate(s, t);
912
        cell_activate_super_spart_drifts(t->ci, s);
913
      }
Pedro Gonnet's avatar
Pedro Gonnet committed
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
940
941
    }
  }
}

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