engine_marktasks.c 36.3 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
/*******************************************************************************
 * 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"
54
#include "task_order.h"
Pedro Gonnet's avatar
Pedro Gonnet committed
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#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;
73
74
  const int with_timestep_limiter = e->policy & engine_policy_timestep_limiter;
  const int with_timestep_sync = e->policy & engine_policy_timestep_sync;
75
  const int with_star_formation = e->policy & engine_policy_star_formation;
76
#ifdef WITH_MPI
77
78
  const int with_feedback = e->policy & engine_policy_feedback;
#endif
Pedro Gonnet's avatar
Pedro Gonnet committed
79
80
81
82
83
84
85
86
87
88
89
90
91
92

  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;

93
#ifdef SWIFT_DEBUG_CHECKS
94
      if (ci->nodeID != nodeID) error("Non-local self task found");
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_black_holes = cell_is_active_black_holes(ci, e);
99
100
101
      const int ci_active_stars = cell_is_active_stars(ci, e) ||
                                  (with_star_formation && ci_active_hydro);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      else if (t_type == task_type_self &&
213
               t_subtype == task_subtype_do_gas_swallow) {
214
215
216
217
218
219
        if (ci_active_black_holes) {
          scheduler_activate(s, t);
        }
      }

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

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

      else if (t_type == task_type_sub_self &&
               t_subtype == task_subtype_do_bh_swallow) {
233
234
235
        if (ci_active_black_holes) scheduler_activate(s, t);
      }

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

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

Pedro Gonnet's avatar
Pedro Gonnet committed
248
249
      /* Activate the gravity drift */
      else if (t_type == task_type_self && t_subtype == task_subtype_grav) {
250
        if (ci_active_gravity) {
Pedro Gonnet's avatar
Pedro Gonnet committed
251
252
253
254
255
256
257
258
          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) {
259
        if (ci_active_gravity) {
Pedro Gonnet's avatar
Pedro Gonnet committed
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
          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);
287

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

291
292
293
      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);

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

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

322
          /* And the limiter */
323
324
325
326
          if (ci_nodeID == nodeID && with_timestep_limiter)
            cell_activate_limiter(ci, s);
          if (cj_nodeID == nodeID && with_timestep_limiter)
            cell_activate_limiter(cj, s);
327

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

        }

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

341
342
      /* Stars density */
      else if ((t_subtype == task_subtype_stars_density) &&
343
344
345
               (ci_active_stars || cj_active_stars) &&
               (ci_nodeID == nodeID || cj_nodeID == nodeID)) {

loikki's avatar
loikki committed
346
        scheduler_activate(s, t);
347

Pedro Gonnet's avatar
Pedro Gonnet committed
348
349
350
        /* Set the correct sorting flags */
        if (t_type == task_type_pair) {

Loic Hausammann's avatar
Loic Hausammann committed
351
          /* Do ci */
loikki's avatar
loikki committed
352
          if (ci_active_stars) {
353

354
            /* stars for ci */
355
            atomic_or(&ci->stars.requires_sorts, 1 << t->flags);
356
            ci->stars.dx_max_sort_old = ci->stars.dx_max_sort;
Loic Hausammann's avatar
Loic Hausammann committed
357

358
            /* hydro for cj */
359
            atomic_or(&cj->hydro.requires_sorts, 1 << t->flags);
360
            cj->hydro.dx_max_sort_old = cj->hydro.dx_max_sort;
Pedro Gonnet's avatar
Pedro Gonnet committed
361

362
            /* Activate the drift tasks. */
363
364
            if (ci_nodeID == nodeID) cell_activate_drift_spart(ci, s);
            if (cj_nodeID == nodeID) cell_activate_drift_part(cj, s);
365
            if (cj_nodeID == nodeID && with_timestep_sync)
366
              cell_activate_sync_part(cj, s);
Pedro Gonnet's avatar
Pedro Gonnet committed
367

368
369
370
371
            /* 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
372
373

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

376
            /* hydro for ci */
377
            atomic_or(&ci->hydro.requires_sorts, 1 << t->flags);
378
            ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort;
379

380
            /* stars for cj */
381
            atomic_or(&cj->stars.requires_sorts, 1 << t->flags);
382
            cj->stars.dx_max_sort_old = cj->stars.dx_max_sort;
Loic Hausammann's avatar
Loic Hausammann committed
383

384
            /* Activate the drift tasks. */
385
386
            if (ci_nodeID == nodeID) cell_activate_drift_part(ci, s);
            if (cj_nodeID == nodeID) cell_activate_drift_spart(cj, s);
387
            if (ci_nodeID == nodeID && with_timestep_sync)
388
              cell_activate_sync_part(ci, s);
Loic Hausammann's avatar
Loic Hausammann committed
389

390
391
392
393
            /* 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
394
395
396
        }

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

403
      /* Stars feedback */
404
      else if (t_subtype == task_subtype_stars_feedback) {
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
        /* 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);
        }
423
      }
424

425
      /* Black_Holes density */
426
427
      else if ((t_subtype == task_subtype_bh_density ||
                t_subtype == task_subtype_bh_swallow ||
428
                t_subtype == task_subtype_do_gas_swallow ||
429
                t_subtype == task_subtype_do_bh_swallow ||
430
                t_subtype == task_subtype_bh_feedback) &&
431
432
433
434
435
               (ci_active_black_holes || cj_active_black_holes) &&
               (ci_nodeID == nodeID || cj_nodeID == nodeID)) {

        scheduler_activate(s, t);

436
        /* Set the correct drifting flags */
437
438
439
        if (t_type == task_type_pair && t_subtype == task_subtype_bh_density) {
          if (ci_nodeID == nodeID) cell_activate_drift_bpart(ci, s);
          if (ci_nodeID == nodeID) cell_activate_drift_part(ci, s);
440

441
442
          if (cj_nodeID == nodeID) cell_activate_drift_part(cj, s);
          if (cj_nodeID == nodeID) cell_activate_drift_bpart(cj, s);
443
444
445
446
447
448
449
450
451
        }

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

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

        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
476
        if (cell_need_rebuild_for_hydro_pair(ci, cj)) *rebuild_space = 1;
Pedro Gonnet's avatar
Pedro Gonnet committed
477
478
479
480
481
482
483

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

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

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

            /* 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) {
509
510
              scheduler_activate_send(s, cj->mpi.send, task_subtype_rho,
                                      ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
511
512

#ifdef EXTRA_HYDRO_LOOP
513
514
              scheduler_activate_send(s, cj->mpi.send, task_subtype_gradient,
                                      ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
515
516
517
518
519
520
#endif
            }
          }

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

524
525
526
          /* Propagating new star counts? */
          if (with_star_formation && with_feedback) {
            if (ci_active_hydro && ci->hydro.count > 0) {
527
              if (task_order_star_formation_before_feedback) {
Loic Hausammann's avatar
Format    
Loic Hausammann committed
528
529
                scheduler_activate_recv(s, ci->mpi.recv,
                                        task_subtype_sf_counts);
530
              }
531
              scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_spart);
532
533
            }
            if (cj_active_hydro && cj->hydro.count > 0) {
534
535
              if (task_order_star_formation_before_feedback) {
                scheduler_activate_send(s, cj->mpi.send, task_subtype_sf_counts,
Loic Hausammann's avatar
Format    
Loic Hausammann committed
536
                                        ci_nodeID);
537
              }
538
539
              scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart,
                                      ci_nodeID);
540
541
542
            }
          }

Pedro Gonnet's avatar
Pedro Gonnet committed
543
544
545
546
        } else if (cj_nodeID != nodeID) {

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

548
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
Pedro Gonnet's avatar
Pedro Gonnet committed
549
            if (cj_active_hydro) {
550
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
Pedro Gonnet's avatar
Pedro Gonnet committed
551
#ifdef EXTRA_HYDRO_LOOP
552
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_gradient);
Pedro Gonnet's avatar
Pedro Gonnet committed
553
554
555
556
557
#endif
            }
          }

          /* If the foreign cell is active, we want its ti_end values. */
558
559
          if (cj_active_hydro)
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_part);
Pedro Gonnet's avatar
Pedro Gonnet committed
560
561
562
563

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

564
            struct link *l = scheduler_activate_send(
565
                s, ci->mpi.send, task_subtype_xv, cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
566
567
568
569
570
571
572
573
574

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

575
576
              scheduler_activate_send(s, ci->mpi.send, task_subtype_rho,
                                      cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
577
578

#ifdef EXTRA_HYDRO_LOOP
579
580
              scheduler_activate_send(s, ci->mpi.send, task_subtype_gradient,
                                      cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
581
582
583
584
585
586
#endif
            }
          }

          /* If the local cell is active, send its ti_end values. */
          if (ci_active_hydro)
587
588
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_part,
                                    cj_nodeID);
589
590
591
592

          /* Propagating new star counts? */
          if (with_star_formation && with_feedback) {
            if (cj_active_hydro && cj->hydro.count > 0) {
593
              if (task_order_star_formation_before_feedback) {
Loic Hausammann's avatar
Format    
Loic Hausammann committed
594
595
                scheduler_activate_recv(s, cj->mpi.recv,
                                        task_subtype_sf_counts);
596
              }
597
              scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_spart);
598
599
            }
            if (ci_active_hydro && ci->hydro.count > 0) {
600
601
602
603
              if (task_order_star_formation_before_feedback) {
                scheduler_activate_send(s, ci->mpi.send, task_subtype_sf_counts,
                                        cj_nodeID);
              }
604
605
              scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart,
                                      cj_nodeID);
606
607
            }
          }
Pedro Gonnet's avatar
Pedro Gonnet committed
608
609
610
611
612
        }
#endif
      }

      /* Only interested in stars_density tasks as of here. */
613
      else if (t->subtype == task_subtype_stars_density) {
614
615
616
617
618

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

619
#ifdef WITH_MPI
620
621
622
623
        /* Activate the send/recv tasks. */
        if (ci_nodeID != nodeID) {

          if (cj_active_stars) {
624
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
625
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
626
627

            /* If the local cell is active, more stuff will be needed. */
628
            scheduler_activate_send(s, cj->mpi.send, task_subtype_spart,
629
                                    ci_nodeID);
630
631
632
            cell_activate_drift_spart(cj, s);

            /* If the local cell is active, send its ti_end values. */
633
634
            scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart,
                                    ci_nodeID);
635
636
637
          }

          if (ci_active_stars) {
638
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_spart);
639
640

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

            /* Is the foreign cell active and will need stuff from us? */
644
            scheduler_activate_send(s, cj->mpi.send, task_subtype_xv,
645
                                    ci_nodeID);
646
            scheduler_activate_send(s, cj->mpi.send, task_subtype_rho,
647
                                    ci_nodeID);
648
649
650
651
652
653
654
655
656
657

            /* 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) {
658
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
659
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
660
661

            /* If the local cell is active, more stuff will be needed. */
662
            scheduler_activate_send(s, ci->mpi.send, task_subtype_spart,
663
                                    cj_nodeID);
664
665
666
            cell_activate_drift_spart(ci, s);

            /* If the local cell is active, send its ti_end values. */
667
668
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart,
                                    cj_nodeID);
669
670
671
          }

          if (cj_active_stars) {
672
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_spart);
673
674

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

            /* Is the foreign cell active and will need stuff from us? */
678
            scheduler_activate_send(s, ci->mpi.send, task_subtype_xv,
679
                                    cj_nodeID);
680
            scheduler_activate_send(s, ci->mpi.send, task_subtype_rho,
681
                                    cj_nodeID);
682
683
684
685
686
687

            /* 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);
          }
        }
688
#endif
Pedro Gonnet's avatar
Pedro Gonnet committed
689
      }
690

691
      /* Only interested in black hole density tasks as of here. */
692
693
694
695
696
697
      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;

698
699
700
        scheduler_activate(s, ci->hydro.super->black_holes.swallow_ghost[0]);
        scheduler_activate(s, cj->hydro.super->black_holes.swallow_ghost[0]);

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

705
706
707
708
          /* Receive the foreign parts to compute BH accretion rates and do the
           * swallowing */
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_part_swallow);
709
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart_merger);
710

711
712
713
714
715
716
          /* Send the local BHs to tag the particles to swallow and to do
           * feedback */
          scheduler_activate_send(s, cj->mpi.send, task_subtype_bpart_rho,
                                  ci_nodeID);
          scheduler_activate_send(s, cj->mpi.send, task_subtype_bpart_feedback,
                                  ci_nodeID);
717

718
719
          /* Drift before you send */
          cell_activate_drift_bpart(cj, s);
720

721
722
723
          /* Send the new BH time-steps */
          scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_bpart,
                                  ci_nodeID);
724

725
726
727
728
          /* Receive the foreign BHs to tag particles to swallow and for
           * feedback */
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart_rho);
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart_feedback);
729

730
731
          /* Receive the foreign BH time-steps */
          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_bpart);
732

733
734
735
736
          /* Send the local part information */
          scheduler_activate_send(s, cj->mpi.send, task_subtype_rho, ci_nodeID);
          scheduler_activate_send(s, cj->mpi.send, task_subtype_part_swallow,
                                  ci_nodeID);
737
738
          scheduler_activate_send(s, cj->mpi.send, task_subtype_bpart_merger,
                                  ci_nodeID);
739
740
741
742

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

        } else if (cj_nodeID != nodeID) {

746
747
748
749
          /* Receive the foreign parts to compute BH accretion rates and do the
           * swallowing */
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_part_swallow);
750
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart_merger);
751

752
753
754
755
756
757
          /* Send the local BHs to tag the particles to swallow and to do
           * feedback */
          scheduler_activate_send(s, ci->mpi.send, task_subtype_bpart_rho,
                                  cj_nodeID);
          scheduler_activate_send(s, ci->mpi.send, task_subtype_bpart_feedback,
                                  cj_nodeID);
758

759
760
          /* Drift before you send */
          cell_activate_drift_bpart(ci, s);
761

762
763
764
          /* Send the new BH time-steps */
          scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_bpart,
                                  cj_nodeID);
765

766
767
768
769
          /* Receive the foreign BHs to tag particles to swallow and for
           * feedback */
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart_rho);
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart_feedback);
770

771
772
          /* Receive the foreign BH time-steps */
          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_bpart);
773

774
775
776
777
          /* Send the local part information */
          scheduler_activate_send(s, ci->mpi.send, task_subtype_rho, cj_nodeID);
          scheduler_activate_send(s, ci->mpi.send, task_subtype_part_swallow,
                                  cj_nodeID);
778
779
          scheduler_activate_send(s, ci->mpi.send, task_subtype_bpart_merger,
                                  cj_nodeID);
780
781
782
783

          /* 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);
784
785
786
787
        }
#endif
      }

Pedro Gonnet's avatar
Pedro Gonnet committed
788
      /* Only interested in gravity tasks as of here. */
789
      else if (t_subtype == task_subtype_grav) {
Pedro Gonnet's avatar
Pedro Gonnet committed
790
791
792
793
794
795

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

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

          /* If the foreign cell is active, we want its ti_end values. */
800
801
          if (ci_active_gravity)
            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_gpart);
Pedro Gonnet's avatar
Pedro Gonnet committed
802
803
804
805

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

806
            struct link *l = scheduler_activate_send(
807
                s, cj->mpi.send, task_subtype_gpart, ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
808
809
810
811
812
813
814
815
816

            /* 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)
817
818
            scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_gpart,
                                    ci_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
819
820
821
822

        } else if (cj_nodeID != nodeID) {

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

          /* If the foreign cell is active, we want its ti_end values. */
827
828
          if (cj_active_gravity)
            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_gpart);
Pedro Gonnet's avatar
Pedro Gonnet committed
829
830
831
832

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

833
            struct link *l = scheduler_activate_send(
834
                s, ci->mpi.send, task_subtype_gpart, cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
835
836
837
838
839
840
841
842
843

            /* 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)
844
845
            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_gpart,
                                    cj_nodeID);
Pedro Gonnet's avatar
Pedro Gonnet committed
846
847
848
849
850
        }
#endif
      }
    }

851
852
    /* End force for hydro ? */
    else if (t_type == task_type_end_hydro_force) {
Pedro Gonnet's avatar
Pedro Gonnet committed
853

854
855
856
857
858
859
860
      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
861
862
863
864
865
    }

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

866
867
868
      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
869
870
871
872
873
874
875
876
877
878
879
880
        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) ||
881
          cell_is_active_stars(t->ci, e))
Pedro Gonnet's avatar
Pedro Gonnet committed
882
883
884
885
886
887
888
889
        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 ||
890
             t_type == task_type_drift_gpart_out ||
Pedro Gonnet's avatar
Pedro Gonnet committed
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
             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 ? */
917
    else if (t_type == task_type_stars_ghost) {
918
919
920
      if (cell_is_active_stars(t->ci, e) ||
          (with_star_formation && cell_is_active_hydro(t->ci, e)))
        scheduler_activate(s, t);
921
922
923
924
    }

    /* Feedback implicit tasks? */
    else if (t_type == task_type_stars_in || t_type == task_type_stars_out) {
925
926
927
      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
928
929
    }

930
    /* Black hole ghost tasks ? */
931
932
    else if (t_type == task_type_bh_density_ghost ||
             t_type == task_type_bh_swallow_ghost1 ||
933
934
             t_type == task_type_bh_swallow_ghost2 ||
             t_type == task_type_bh_swallow_ghost3) {
935
936
937
938
939
940
941
942
      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
943
944
945
946
947
    /* Time-step? */
    else if (t_type == task_type_timestep) {
      t->ci->hydro.updated = 0;
      t->ci->grav.updated = 0;
      t->ci->stars.updated = 0;
948
949
950
951
      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
952
953
954
        scheduler_activate(s, t);
    }

955
    /* Subgrid tasks: cooling */
Pedro Gonnet's avatar
Pedro Gonnet committed
956
    else if (t_type == task_type_cooling) {
957
958
959
960
      if (cell_is_active_hydro(t->ci, e)) scheduler_activate(s, t);
    }

    /* Subgrid tasks: star formation */
961
    else if (t_type == task_type_star_formation) {
962
      if (cell_is_active_hydro(t->ci, e)) {
963
        cell_activate_star_formation_tasks(t->ci, s);
964
        cell_activate_super_spart_drifts(t->ci, s);
965
      }
Pedro Gonnet's avatar
Pedro Gonnet committed
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
    }
  }
}

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