engine.h 18.5 KB
Newer Older
Pedro Gonnet's avatar
Pedro Gonnet committed
1
/*******************************************************************************
2
 * This file is part of SWIFT.
3
 * Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
4 5 6 7 8
 *                    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)
9
 *
Pedro Gonnet's avatar
Pedro Gonnet committed
10 11 12 13
 * 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.
14
 *
Pedro Gonnet's avatar
Pedro Gonnet committed
15 16 17 18
 * 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.
19
 *
Pedro Gonnet's avatar
Pedro Gonnet committed
20 21
 * 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/>.
22
 *
Pedro Gonnet's avatar
Pedro Gonnet committed
23
 ******************************************************************************/
24 25
#ifndef SWIFT_ENGINE_H
#define SWIFT_ENGINE_H
Pedro Gonnet's avatar
Pedro Gonnet committed
26

27 28 29 30 31 32 33 34
/* Config parameters. */
#include "../config.h"

/* MPI headers. */
#ifdef WITH_MPI
#include <mpi.h>
#endif

Pedro Gonnet's avatar
Pedro Gonnet committed
35
/* Includes. */
36
#include "barrier.h"
37
#include "clocks.h"
38
#include "collectgroup.h"
Loikki's avatar
Loikki committed
39
#include "dump.h"
40
#include "mesh_gravity.h"
Matthieu Schaller's avatar
Matthieu Schaller committed
41
#include "parser.h"
42
#include "partition.h"
43
#include "potential.h"
Matthieu Schaller's avatar
Matthieu Schaller committed
44
#include "runner.h"
45
#include "scheduler.h"
Matthieu Schaller's avatar
Matthieu Schaller committed
46 47 48
#include "space.h"
#include "task.h"
#include "units.h"
49
#include "velociraptor_interface.h"
Pedro Gonnet's avatar
Pedro Gonnet committed
50

51 52
struct black_holes_properties;

53 54 55
/**
 * @brief The different policies the #engine can follow.
 */
56 57
enum engine_policy {
  engine_policy_none = 0,
58 59 60 61
  engine_policy_rand = (1 << 0),
  engine_policy_steal = (1 << 1),
  engine_policy_keep = (1 << 2),
  engine_policy_block = (1 << 3),
62 63 64 65 66 67 68 69
  engine_policy_cputight = (1 << 4),
  engine_policy_mpi = (1 << 5),
  engine_policy_setaffinity = (1 << 6),
  engine_policy_hydro = (1 << 7),
  engine_policy_self_gravity = (1 << 8),
  engine_policy_external_gravity = (1 << 9),
  engine_policy_cosmology = (1 << 10),
  engine_policy_drift_all = (1 << 11),
70
  engine_policy_reconstruct_mpoles = (1 << 12),
71 72
  engine_policy_temperature = (1 << 13),
  engine_policy_cooling = (1 << 14),
73
  engine_policy_stars = (1 << 15),
74
  engine_policy_structure_finding = (1 << 16),
Matthieu Schaller's avatar
Matthieu Schaller committed
75
  engine_policy_star_formation = (1 << 17),
James Willis's avatar
James Willis committed
76
  engine_policy_feedback = (1 << 18),
77
  engine_policy_black_holes = (1 << 19),
78
  engine_policy_fof = (1 << 20),
79
  engine_policy_timestep_limiter = (1 << 21),
Loic Hausammann's avatar
Loic Hausammann committed
80 81
  engine_policy_timestep_sync = (1 << 22),
  engine_policy_logger = (1 << 23),
82
};
Loic Hausammann's avatar
Loic Hausammann committed
83
#define engine_maxpolicy 24
Loic Hausammann's avatar
Loic Hausammann committed
84
extern const char *engine_policy_names[engine_maxpolicy + 1];
Pedro Gonnet's avatar
Pedro Gonnet committed
85

86 87 88 89 90 91 92 93 94
/**
 * @brief The different unusual events that can take place in a time-step.
 */
enum engine_step_properties {
  engine_step_prop_none = 0,
  engine_step_prop_rebuild = (1 << 0),
  engine_step_prop_redistribute = (1 << 1),
  engine_step_prop_repartition = (1 << 2),
  engine_step_prop_statistics = (1 << 3),
95
  engine_step_prop_snapshot = (1 << 4),
96
  engine_step_prop_restarts = (1 << 5),
97
  engine_step_prop_stf = (1 << 6),
98 99 100
  engine_step_prop_fof = (1 << 7),
  engine_step_prop_logger_index = (1 << 8),
  engine_step_prop_done = (1 << 9)
101 102 103
};

/* Some constants */
104
#define engine_maxproxies 64
105
#define engine_tasksreweight 1
106
#define engine_parts_size_grow 1.05
107
#define engine_max_proxy_centre_frac 0.2
108
#define engine_redistribute_alloc_margin 1.2
109
#define engine_rebuild_link_alloc_margin 1.2
110
#define engine_foreign_alloc_margin 1.05
111 112
#define engine_default_energy_file_name "energy"
#define engine_default_timesteps_file_name "timesteps"
113 114
#define engine_max_parts_per_ghost_default 1000
#define engine_max_sparts_per_ghost_default 1000
115
#define engine_star_resort_task_depth_default 2
116
#define engine_tasks_per_cell_margin 1.2
117 118
#define engine_default_stf_subdir_per_output ""
#define engine_default_snapshot_subdir ""
Pedro Gonnet's avatar
Pedro Gonnet committed
119

120 121 122
/**
 * @brief The rank of the engine as a global variable (for messages).
 */
123 124
extern int engine_rank;

125 126 127
/**
 * @brief The current step as a global variable (for messages).
 */
128
extern int engine_current_step;
129

Pedro Gonnet's avatar
Pedro Gonnet committed
130 131 132
/* Data structure for the engine. */
struct engine {

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
  /* Number of threads on which to run. */
  int nr_threads;

  /* The space with which the runner is associated. */
  struct space *s;

  /* The runner's threads. */
  struct runner *runners;

  /* The running policy. */
  int policy;

  /* The task scheduler. */
  struct scheduler sched;

148 149 150
  /* Common threadpool for all the engine's tasks. */
  struct threadpool threadpool;

151
  /* The minimum and maximum allowed dt */
152
  double dt_min, dt_max;
153

154 155 156 157 158 159
  /* Maximum time-step allowed by the RMS condition in cosmology runs. */
  double dt_max_RMS_displacement;

  /* Dimensionless factor for the RMS time-step condition. */
  double max_RMS_displacement_factor;

160
  /* Time of the simulation beginning */
161
  double time_begin;
162 163

  /* Time of the simulation end */
164
  double time_end;
165 166

  /* The previous system time. */
167
  double time_old;
168
  integertime_t ti_old;
169 170

  /* The current system time. */
171
  double time;
172
  integertime_t ti_current;
173

174 175 176
  /* The highest active bin at this time */
  timebin_t max_active_bin;

177 178 179
  /* The lowest active bin at this time */
  timebin_t min_active_bin;

180
  /* Time step */
181
  double time_step;
182

183
  /* Time base */
184 185
  double time_base;
  double time_base_inv;
186

187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
  /* Minimal hydro ti_end for the next time-step */
  integertime_t ti_hydro_end_min;

  /* Maximal hydro ti_end for the next time-step */
  integertime_t ti_hydro_end_max;

  /* Maximal hydro ti_beg for the next time-step */
  integertime_t ti_hydro_beg_max;

  /* Minimal gravity ti_end for the next time-step */
  integertime_t ti_gravity_end_min;

  /* Maximal gravity ti_end for the next time-step */
  integertime_t ti_gravity_end_max;

  /* Maximal gravity ti_beg for the next time-step */
  integertime_t ti_gravity_beg_max;

205 206 207 208 209 210 211 212 213
  /* Minimal stars ti_end for the next time-step */
  integertime_t ti_stars_end_min;

  /* Maximal stars ti_end for the next time-step */
  integertime_t ti_stars_end_max;

  /* Maximal stars ti_beg for the next time-step */
  integertime_t ti_stars_beg_max;

214 215 216 217 218 219 220 221
  /* Minimal black holes ti_end for the next time-step */
  integertime_t ti_black_holes_end_min;

  /* Maximal black holes ti_end for the next time-step */
  integertime_t ti_black_holes_end_max;

  /* Maximal black holes ti_beg for the next time-step */
  integertime_t ti_black_holes_beg_max;
222

223
  /* Minimal overall ti_end for the next time-step */
224
  integertime_t ti_end_min;
225

226
  /* Maximal overall ti_end for the next time-step */
Matthieu Schaller's avatar
Matthieu Schaller committed
227 228
  integertime_t ti_end_max;

229
  /* Maximal overall ti_beg for the next time-step */
Matthieu Schaller's avatar
Matthieu Schaller committed
230 231
  integertime_t ti_beg_max;

232
  /* Number of particles updated in the previous step */
233
  long long updates, g_updates, s_updates, b_updates;
234

235
  /* Number of updates since the last rebuild */
236 237 238
  long long updates_since_rebuild;
  long long g_updates_since_rebuild;
  long long s_updates_since_rebuild;
239
  long long b_updates_since_rebuild;
240

241
  /* Star formation logger information */
242
  struct star_formation_history_accumulator sfh;
243

244
  /* Properties of the previous step */
245
  int step_props;
246

247
  /* Total numbers of particles in the system. */
248 249 250 251
  long long total_nr_parts;
  long long total_nr_gparts;
  long long total_nr_sparts;
  long long total_nr_bparts;
252
  long long total_nr_DM_background_gparts;
253

254 255 256 257 258 259 260
  /* Total numbers of cells (top-level and sub-cells) in the system. */
  long long total_nr_cells;

  /* Total numbers of tasks in the system. */
  long long total_nr_tasks;

  /* The total number of inhibited particles in the system. */
261 262 263 264
  long long nr_inhibited_parts;
  long long nr_inhibited_gparts;
  long long nr_inhibited_sparts;
  long long nr_inhibited_bparts;
265

Matthieu Schaller's avatar
Matthieu Schaller committed
266 267
#ifdef SWIFT_DEBUG_CHECKS
  /* Total number of particles removed from the system since the last rebuild */
268 269 270 271
  long long count_inhibited_parts;
  long long count_inhibited_gparts;
  long long count_inhibited_sparts;
  long long count_inhibited_bparts;
Matthieu Schaller's avatar
Matthieu Schaller committed
272 273
#endif

274 275 276
  /* Total mass in the simulation */
  double total_mass;

277
  /* The internal system of units */
278
  const struct unit_system *internal_units;
Matthieu Schaller's avatar
Matthieu Schaller committed
279

280
  /* Snapshot information */
281 282 283
  double a_first_snapshot;
  double time_first_snapshot;
  double delta_time_snapshot;
Loic Hausammann's avatar
Loic Hausammann committed
284

285 286
  /* Output_List for the snapshots */
  struct output_list *output_list_snapshots;
287 288 289 290

  /* Integer time of the next snapshot */
  integertime_t ti_next_snapshot;

291
  char snapshot_base_name[PARSER_MAX_LINE_SIZE];
292
  char snapshot_subdir[PARSER_MAX_LINE_SIZE];
293
  int snapshot_compression;
294
  int snapshot_int_time_label_on;
295
  int snapshot_invoke_stf;
296 297
  struct unit_system *snapshot_units;
  int snapshot_output_count;
298

299
  /* Structure finding information */
300 301 302
  double a_first_stf_output;
  double time_first_stf_output;
  double delta_time_stf;
Matthieu Schaller's avatar
Matthieu Schaller committed
303

304 305
  /* Output_List for the structure finding */
  struct output_list *output_list_stf;
Loic Hausammann's avatar
Loic Hausammann committed
306

307
  /* Integer time of the next stf output */
308
  integertime_t ti_next_stf;
Matthieu Schaller's avatar
Matthieu Schaller committed
309

310
  char stf_config_file_name[PARSER_MAX_LINE_SIZE];
311
  char stf_base_name[PARSER_MAX_LINE_SIZE];
312
  char stf_subdir_per_output[PARSER_MAX_LINE_SIZE];
313
  int stf_output_count;
314

315 316 317 318 319 320 321 322
  /* FoF black holes seeding information */
  double a_first_fof_call;
  double time_first_fof_call;
  double delta_time_fof;

  /* Integer time of the next FoF black holes seeding call */
  integertime_t ti_next_fof;

323 324
  /* FOF information */
  int run_fof;
325

326
  /* Statistics information */
327 328 329 330
  double a_first_statistics;
  double time_first_statistics;
  double delta_time_statistics;

331 332
  /* Output_List for the stats */
  struct output_list *output_list_stats;
Loic Hausammann's avatar
Format  
Loic Hausammann committed
333

334 335 336 337
  /* Integer time of the next statistics dump */
  integertime_t ti_next_stats;

  /* File handle for the statistics */
338
  FILE *file_stats;
Pedro Gonnet's avatar
Pedro Gonnet committed
339

340
  /* File handle for the timesteps information */
Matthieu Schaller's avatar
Matthieu Schaller committed
341 342
  FILE *file_timesteps;

343 344 345
  /* File handle for the SFH logger file */
  FILE *sfh_logger;

346
  /* The current step number. */
347
  int step;
348 349

  /* Data for the threads' barrier. */
350 351
  swift_barrier_t wait_barrier;
  swift_barrier_t run_barrier;
352 353 354 355 356 357 358 359

  /* ID of the node this engine lives on. */
  int nr_nodes, nodeID;

  /* Proxies for the other nodes in this simulation. */
  struct proxy *proxies;
  int nr_proxies, *proxy_ind;

360 361
  /* Tic/toc at the start/end of a step. */
  ticks tic_step, toc_step;
362

363
#ifdef WITH_MPI
364 365 366
  /* CPU times that the tasks used in the last step. */
  double usertime_last_step;
  double systime_last_step;
367

368 369
  /* Step of last repartition. */
  int last_repartition;
370 371 372 373

  /* Use synchronous redistributes. */
  int syncredist;

374 375
#endif

376 377
  /* Wallclock time of the last time-step */
  float wallclock_time;
378

379 380 381
  /* Are we in the process of restaring a simulation? */
  int restarting;

382
  /* Force the engine to rebuild? */
383
  int forcerebuild;
384 385 386

  /* Force the engine to repartition ? */
  int forcerepart;
387
  struct repartition *reparttype;
388

Loic Hausammann's avatar
Loic Hausammann committed
389
  /* The particle logger */
Loic Hausammann's avatar
Loic Hausammann committed
390
  struct logger_writer *logger;
lhausamm's avatar
lhausamm committed
391

392 393 394 395 396
  /* How many steps have we done with the same set of tasks? */
  int tasks_age;

  /* Linked list for cell-task association. */
  struct link *links;
397
  size_t nr_links, size_links;
398

399
  /* Average number of tasks per cell. Used to estimate the sizes
400
   * of the various task arrays. Also the maximum from all ranks. */
401
  float tasks_per_cell;
402
  float tasks_per_cell_max;
403

404
  /* Average number of links per tasks. This number is used before
405
     the creation of communication tasks so needs to be large enough. */
406
  float links_per_tasks;
407

408 409
  /* Are we talkative ? */
  int verbose;
410 411

  /* Physical constants definition */
Matthieu Schaller's avatar
Matthieu Schaller committed
412
  const struct phys_const *physical_constants;
413

414 415 416
  /* The cosmological model */
  struct cosmology *cosmology;

417
  /* Properties of the hydro scheme */
418
  struct hydro_props *hydro_properties;
419

420 421
  /* Properties of the entropy floor */
  const struct entropy_floor_properties *entropy_floor;
422

Loic Hausammann's avatar
Loic Hausammann committed
423 424 425
  /* Properties of the star model */
  const struct stars_props *stars_properties;

426 427 428
  /* Properties of the black hole model */
  const struct black_holes_props *black_holes_properties;

429
  /* Properties of the self-gravity scheme */
430
  struct gravity_props *gravity_properties;
431

432 433 434
  /* The mesh used for long-range gravity forces */
  struct pm_mesh *mesh;

435
  /* Properties of external gravitational potential */
Matthieu Schaller's avatar
Matthieu Schaller committed
436
  const struct external_potential *external_potential;
437

438
  /* Properties of the cooling scheme */
Alexei Borissov's avatar
Alexei Borissov committed
439
  struct cooling_function_data *cooling_func;
440

441 442
  /* Properties of the starformation law */
  const struct star_formation *star_formation;
443

444
  /* Properties of the sellar feedback model */
445
  struct feedback_props *feedback_props;
446

447
  /* Properties of the chemistry model */
448
  const struct chemistry_global_data *chemistry;
449

450 451 452
  /*! The FOF properties data. */
  struct fof_props *fof_properties;

453
  /* The (parsed) parameter file */
lhausamm's avatar
lhausamm committed
454
  struct swift_params *parameter_file;
455 456 457 458

  /* Temporary struct to hold a group of deferable properties (in MPI mode
   * these are reduced together, but may not be required just yet). */
  struct collectgroup1 collect_group1;
Peter W. Draper's avatar
Peter W. Draper committed
459

460 461 462
  /* Whether to dump restart files. */
  int restart_dump;

463 464 465
  /* Whether to save previous generation of restart files. */
  int restart_save;

466 467 468
  /* Whether to dump restart files after the last step. */
  int restart_onexit;

Peter W. Draper's avatar
Peter W. Draper committed
469
  /* Name of the restart file. */
470
  const char *restart_file;
471 472 473 474 475 476

  /* Ticks between restart dumps. */
  ticks restart_dt;

  /* Time after which next dump will occur. */
  ticks restart_next;
477 478 479

  /* Maximum number of tasks needed for restarting. */
  int restart_max_tasks;
480

481 482 483
  /* The globally agreed runtime, in hours. */
  float runtime;

484 485
  /* Label of the run */
  char run_name[PARSER_MAX_LINE_SIZE];
486 487

  /* Has there been an stf this timestep? */
488
  char stf_this_timestep;
489 490 491 492

#ifdef SWIFT_GRAVITY_FORCE_CHECKS
  /* Run brute force checks only on steps when all gparts active? */
  int force_checks_only_all_active;
493 494 495 496 497 498 499

  /* Run brute force checks only during snapshot timesteps? */
  int force_checks_only_at_snapshots;

  /* Are all gparts active this timestep? */
  int all_gparts_active;

500 501
  /* Flag to tell brute force checks a snapshot was recently written. */
  int force_checks_snapshot_flag;
502
#endif
503
};
Pedro Gonnet's avatar
Pedro Gonnet committed
504

505
/* Function prototypes, engine.c. */
506
void engine_addlink(struct engine *e, struct link **l, struct task *t);
Pedro Gonnet's avatar
Pedro Gonnet committed
507
void engine_barrier(struct engine *e);
508
void engine_compute_next_snapshot_time(struct engine *e);
509
void engine_compute_next_stf_time(struct engine *e);
510
void engine_compute_next_fof_time(struct engine *e);
511
void engine_compute_next_statistics_time(struct engine *e);
512
void engine_recompute_displacement_constraint(struct engine *e);
513
void engine_unskip(struct engine *e);
514
void engine_unskip_timestep_communications(struct engine *e);
515
void engine_drift_all(struct engine *e, const int drift_mpoles);
516
void engine_drift_top_multipoles(struct engine *e);
517
void engine_reconstruct_multipoles(struct engine *e);
518
void engine_allocate_foreign_particles(struct engine *e);
519
void engine_print_stats(struct engine *e);
520
void engine_check_for_dumps(struct engine *e);
Loic Hausammann's avatar
Loic Hausammann committed
521
void engine_check_for_index_dump(struct engine *e);
522
void engine_collect_end_of_step(struct engine *e, int apply);
523
void engine_dump_snapshot(struct engine *e);
524
void engine_init_output_lists(struct engine *e, struct swift_params *params);
Matthieu Schaller's avatar
Matthieu Schaller committed
525 526
void engine_init(struct engine *e, struct space *s, struct swift_params *params,
                 long long Ngas, long long Ngparts, long long Nstars,
527 528
                 long long Nblackholes, long long Nbackground_gparts,
                 int policy, int verbose, struct repartition *reparttype,
Matthieu Schaller's avatar
Matthieu Schaller committed
529 530
                 const struct unit_system *internal_units,
                 const struct phys_const *physical_constants,
531
                 struct cosmology *cosmo, struct hydro_props *hydro,
532
                 const struct entropy_floor_properties *entropy_floor,
Loic Hausammann's avatar
Loic Hausammann committed
533
                 struct gravity_props *gravity, const struct stars_props *stars,
534
                 const struct black_holes_props *black_holes,
535
                 struct feedback_props *feedback, struct pm_mesh *mesh,
Matthieu Schaller's avatar
Matthieu Schaller committed
536
                 const struct external_potential *potential,
Alexei Borissov's avatar
Alexei Borissov committed
537
                 struct cooling_function_data *cooling_func,
538
                 const struct star_formation *starform,
539 540
                 const struct chemistry_global_data *chemistry,
                 struct fof_props *fof_properties);
541 542 543 544
void engine_config(int restart, int fof, struct engine *e,
                   struct swift_params *params, int nr_nodes, int nodeID,
                   int nr_threads, int with_aff, int verbose,
                   const char *restart_file);
Loikki's avatar
Loikki committed
545
void engine_dump_index(struct engine *e);
546
void engine_launch(struct engine *e, const char *call);
547
void engine_prepare(struct engine *e);
548
void engine_init_particles(struct engine *e, int flag_entropy_ICs,
549
                           int clean_h_values);
550
void engine_step(struct engine *e);
551
void engine_split(struct engine *e, struct partition *initial_partition);
552 553 554 555
void engine_exchange_strays(struct engine *e, const size_t offset_parts,
                            const int *ind_part, size_t *Npart,
                            const size_t offset_gparts, const int *ind_gpart,
                            size_t *Ngpart, const size_t offset_sparts,
556 557 558
                            const int *ind_spart, size_t *Nspart,
                            const size_t offset_bparts, const int *ind_bpart,
                            size_t *Nbpart);
559
void engine_rebuild(struct engine *e, int redistributed, int clean_h_values);
560
void engine_repartition(struct engine *e);
561
void engine_repartition_trigger(struct engine *e);
562 563
void engine_makeproxies(struct engine *e);
void engine_redistribute(struct engine *e);
Matthieu Schaller's avatar
Matthieu Schaller committed
564
void engine_print_policy(struct engine *e);
565
int engine_is_done(struct engine *e);
566 567
void engine_pin(void);
void engine_unpin(void);
Matthieu Schaller's avatar
Matthieu Schaller committed
568
void engine_clean(struct engine *e, const int fof, const int restart);
569
int engine_estimate_nr_tasks(const struct engine *e);
570
void engine_print_task_counts(const struct engine *e);
571 572
void engine_fof(struct engine *e, const int dump_results,
                const int seed_black_holes);
573
void engine_activate_gpart_comms(struct engine *e);
574

Pedro Gonnet's avatar
Pedro Gonnet committed
575
/* Function prototypes, engine_maketasks.c. */
576 577
void engine_maketasks(struct engine *e);

578 579 580
/* Function prototypes, engine_maketasks.c. */
void engine_make_fof_tasks(struct engine *e);

Pedro Gonnet's avatar
Pedro Gonnet committed
581 582 583
/* Function prototypes, engine_marktasks.c. */
int engine_marktasks(struct engine *e);

584 585 586
/* Function prototypes, engine_split_particles.c. */
void engine_split_gas_particles(struct engine *e);

587
#ifdef HAVE_SETAFFINITY
588
cpu_set_t *engine_entry_affinity(void);
589 590
#endif

591 592 593
/* Struct dump/restore support. */
void engine_struct_dump(struct engine *e, FILE *stream);
void engine_struct_restore(struct engine *e, FILE *stream);
594
void engine_dump_restarts(struct engine *e, int drifted_all, int final_step);
595

596
#endif /* SWIFT_ENGINE_H */