diff --git a/src/engine.c b/src/engine.c index 18882d2b0f62b14712e4dfbe2bd5d8a9c3a7f36a..eb96e5f10682339a99d58520a3be25fecbe3ab4f 100644 --- a/src/engine.c +++ b/src/engine.c @@ -878,14 +878,6 @@ void engine_repartition(struct engine *e) { e->policy & engine_policy_self_gravity); #endif - /* Release all cell sorting indices so we can keep memory usage down. */ - if (e->s->cells_top != NULL) { - threadpool_map(&e->threadpool, space_rebuild_recycle_mapper, - e->s->cells_top, e->s->nr_cells, sizeof(struct cell), - 0, e->s); - e->s->maxdepth = 0; - } - /* Clear the repartition flag. */ e->forcerepart = 0; @@ -897,6 +889,34 @@ void engine_repartition(struct engine *e) { partition_repartition(e->reparttype, e->nodeID, e->nr_nodes, e->s, e->sched.tasks, e->sched.nr_tasks); + /* Partitioning requires copies of the particles, so we need to reduce the + * memory in use to the minimum, we can free the sorting indices and the + * tasks as these will be regenerated at the next rebuild. */ + + /* Sorting indices. */ + if (e->s->cells_top != NULL) { + threadpool_map(&e->threadpool, space_rebuild_recycle_mapper, + e->s->cells_top, e->s->nr_cells, sizeof(struct cell), + 0, e->s); + e->s->maxdepth = 0; + } + + /* Tasks. */ + struct scheduler *s = &e->sched; + if (s->tasks != NULL) { + free(s->tasks); + s->tasks = NULL; + } + if (s->tasks_ind != NULL) { + free(s->tasks_ind); + s->tasks_ind = NULL; + } + if (s->tid_active != NULL) { + free(s->tid_active); + s->tid_active = NULL; + } + s->size = 0; + /* Now comes the tricky part: Exchange particles between all nodes. This is done in two steps, first allreducing a matrix of how many particles go from where to where, then re-allocating