diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml index 9fdfc993c3f9ad125f4f588db159c6ef5c997c84..bb3662201b11b8b0a8f2bfb535a0c8916e250842 100644 --- a/examples/parameter_example.yml +++ b/examples/parameter_example.yml @@ -68,6 +68,7 @@ Scheduler: cell_extra_sparts: 400 # (Optional) Number of spare sparts per top-level allocated at rebuild time for on-the-fly creation. max_top_level_cells: 12 # (Optional) Maximal number of top-level cells in any dimension. The number of top-level cells will be the cube of this (this is the default value). tasks_per_cell: 0 # (Optional) The average number of tasks per cell. If not large enough the simulation will fail (means guess...). + links_per_tasks: 10 # (Optional) The average number of links per tasks (before splitting and communications). Defaults to 10. mpi_message_limit: 4096 # (Optional) Maximum MPI task message size to send non-buffered, KB. # Parameters governing the time integration (Set dt_min and dt_max to the same value for a fixed time-step run.) diff --git a/src/engine.c b/src/engine.c index 964c43cd57209a674ee5afb86cd97a752f1cdd36..6e3556f5ce6032047ffd8d08302ef5599b7f179c 100644 --- a/src/engine.c +++ b/src/engine.c @@ -145,7 +145,9 @@ void engine_addlink(struct engine *e, struct link **l, struct task *t) { /* Get the next free link. */ const size_t ind = atomic_inc(&e->nr_links); if (ind >= e->size_links) { - error("Link table overflow."); + error( + "Link table overflow. Increase the value of " + "`Scheduler:links_per_tasks`."); } struct link *res = &e->links[ind]; @@ -4661,6 +4663,10 @@ void engine_config(int restart, struct engine *e, struct swift_params *params, else maxtasks = engine_estimate_nr_tasks(e); + /* Estimated number of links per tasks */ + e->links_per_tasks = + parser_get_opt_param_int(params, "Scheduler:links_per_tasks", 10); + /* Init the scheduler. */ scheduler_init(&e->sched, e->s, maxtasks, nr_queues, (e->policy & scheduler_flag_steal), e->nodeID, &e->threadpool); diff --git a/src/engine.h b/src/engine.h index fea874435cd8160a4dfd37f6e7530f36318646d7..b2cacc86689436e578f2cbea35cc5c27ac12fa13 100644 --- a/src/engine.h +++ b/src/engine.h @@ -99,6 +99,7 @@ enum engine_step_properties { #define engine_parts_size_grow 1.05 #define engine_max_proxy_centre_frac 0.2 #define engine_redistribute_alloc_margin 1.2 +#define engine_rebuild_link_alloc_margin 1.2 #define engine_default_energy_file_name "energy" #define engine_default_timesteps_file_name "timesteps" #define engine_max_parts_per_ghost 1000 @@ -329,6 +330,11 @@ struct engine { * of the various task arrays. */ size_t tasks_per_cell; + /* Average number of links per tasks. This number is used before + the splitting and creation of communications so needs to be large + enough. */ + size_t links_per_tasks; + /* Are we talkative ? */ int verbose; diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c index d3a7e652533adcddf20b57845cd4a263aabe32aa..9ada0907303d187e5340f05c5368c855667fdc8a 100644 --- a/src/engine_maketasks.c +++ b/src/engine_maketasks.c @@ -2070,30 +2070,11 @@ void engine_maketasks(struct engine *e) { /* Free the old list of cell-task links. */ if (e->links != NULL) free(e->links); - e->size_links = 0; + e->size_links = e->sched.nr_tasks * e->links_per_tasks; -/* The maximum number of links is the - * number of cells (s->tot_cells) times the number of neighbours (26) times - * the number of interaction types, so 26 * 2 (density, force) pairs - * and 2 (density, force) self. - */ -#ifdef EXTRA_HYDRO_LOOP - const size_t hydro_tasks_per_cell = 27 * 3; -#else - const size_t hydro_tasks_per_cell = 27 * 2; -#endif - const size_t self_grav_tasks_per_cell = 125; - const size_t ext_grav_tasks_per_cell = 1; - const size_t stars_tasks_per_cell = 27; - - if (e->policy & engine_policy_hydro) - e->size_links += s->tot_cells * hydro_tasks_per_cell; - if (e->policy & engine_policy_external_gravity) - e->size_links += s->tot_cells * ext_grav_tasks_per_cell; - if (e->policy & engine_policy_self_gravity) - e->size_links += s->tot_cells * self_grav_tasks_per_cell; - if (e->policy & engine_policy_stars) - e->size_links += s->tot_cells * stars_tasks_per_cell; + /* Make sure that we have space for more links than last time. */ + if (e->size_links < e->nr_links * engine_rebuild_link_alloc_margin) + e->size_links = e->nr_links * engine_rebuild_link_alloc_margin; /* Allocate the new link list */ if ((e->links = (struct link *)malloc(sizeof(struct link) * e->size_links)) ==