Commit 5dd4aef0 by Matthieu Schaller

### Exchange the multipoles at the same time as the cells when running with gravity.

parent bd6ae8b6
 ... ... @@ -167,14 +167,19 @@ int cell_link_sparts(struct cell *c, struct spart *sparts) { * @param c The #cell. * @param pc Pointer to an array of packed cells in which the * cells will be packed. * @param with_gravity Are we running with gravity and hence need * to exchange multipoles? * * @return The number of packed cells. */ int cell_pack(struct cell *restrict c, struct pcell *restrict pc) { int cell_pack(struct cell *restrict c, struct pcell *restrict pc, const int with_gravity) { #ifdef WITH_MPI /* Start by packing the data of the current cell. */ if(with_gravity) pc->multipole = *(c->multipole); pc->h_max = c->h_max; pc->ti_hydro_end_min = c->ti_hydro_end_min; pc->ti_hydro_end_max = c->ti_hydro_end_max; ... ... @@ -196,7 +201,7 @@ int cell_pack(struct cell *restrict c, struct pcell *restrict pc) { for (int k = 0; k < 8; k++) if (c->progeny[k] != NULL) { pc->progeny[k] = count; count += cell_pack(c->progeny[k], &pc[count]); count += cell_pack(c->progeny[k], &pc[count], with_gravity); } else { pc->progeny[k] = -1; } ... ... @@ -251,15 +256,19 @@ int cell_pack_tags(const struct cell *c, int *tags) { * @param pc An array of packed #pcell. * @param c The #cell in which to unpack the #pcell. * @param s The #space in which the cells are created. * @param with_gravity Are we running with gravity and hence need * to exchange multipoles? * * @return The number of cells created. */ int cell_unpack(struct pcell *restrict pc, struct cell *restrict c, struct space *restrict s) { struct space *restrict s, const int with_gravity) { #ifdef WITH_MPI /* Unpack the current pcell. */ if(with_gravity) *(c->multipole) = pc->multipole; c->h_max = pc->h_max; c->ti_hydro_end_min = pc->ti_hydro_end_min; c->ti_hydro_end_max = pc->ti_hydro_end_max; ... ... @@ -304,7 +313,7 @@ int cell_unpack(struct pcell *restrict pc, struct cell *restrict c, temp->parent = c; c->progeny[k] = temp; c->split = 1; count += cell_unpack(&pc[pc->progeny[k]], temp, s); count += cell_unpack(&pc[pc->progeny[k]], temp, s, with_gravity); } /* Return the total number of unpacked cells. */ ... ...
 ... ... @@ -77,6 +77,12 @@ struct link { */ struct pcell { /*! This cell's gravity-related tensors */ struct gravity_tensors multipole; /*! Relative indices of the cell's progeny. */ int progeny[8]; /*! Maximal smoothing length. */ double h_max; ... ... @@ -116,9 +122,6 @@ struct pcell { /*! Number of #spart in this cell. */ int scount; /*! Relative indices of the cell's progeny. */ int progeny[8]; #ifdef SWIFT_DEBUG_CHECKS /* Cell ID (for debugging) */ int cellID; ... ... @@ -485,8 +488,8 @@ int cell_mlocktree(struct cell *c); void cell_munlocktree(struct cell *c); int cell_slocktree(struct cell *c); void cell_sunlocktree(struct cell *c); int cell_pack(struct cell *c, struct pcell *pc); int cell_unpack(struct pcell *pc, struct cell *c, struct space *s); int cell_pack(struct cell *c, struct pcell *pc, const int with_gravity); int cell_unpack(struct pcell *pc, struct cell *c, struct space *s, const int with_gravity); int cell_pack_tags(const struct cell *c, int *tags); int cell_unpack_tags(const int *tags, struct cell *c); int cell_pack_end_step(struct cell *c, struct pcell_step *pcell); ... ...
 ... ... @@ -1670,10 +1670,11 @@ void engine_exchange_cells(struct engine *e) { struct space *s = e->s; const int nr_proxies = e->nr_proxies; const int with_gravity = e->policy & engine_policy_self_gravity; const ticks tic = getticks(); /* Exchange the cell structure with neighbouring ranks. */ proxy_cells_exchange(e->proxies, e->nr_proxies, e->s); proxy_cells_exchange(e->proxies, e->nr_proxies, e->s, with_gravity); /* Count the number of particles we need to import and re-allocate the buffer if needed. */ ... ... @@ -3948,18 +3949,14 @@ void engine_rebuild(struct engine *e, int clean_smoothing_length_values) { /* If in parallel, exchange the cell structure, top-level and neighbouring * multipoles. */ #ifdef WITH_MPI engine_exchange_cells(e); if (e->policy & engine_policy_self_gravity) engine_exchange_top_multipoles(e); engine_exchange_cells(e); #endif /* Re-build the tasks. */ engine_maketasks(e); #ifdef WITH_MPI if (e->policy & engine_policy_self_gravity) engine_exchange_proxy_multipoles(e); #endif /* Make the list of top-level cells that have tasks */ space_list_cells_with_tasks(e->s); ... ... @@ -5400,8 +5397,17 @@ void engine_makeproxies(struct engine *e) { if (with_gravity) { /* Are we too close for M2L? */ if (!cell_can_use_pair_mm_rebuild(&cells[cid], &cells[cjd], e, s)) /* if (!cell_can_use_pair_mm_rebuild(&cells[cid], &cells[cjd], e, */ /* s)) */ if (((abs(ind[0] - ii) <= 5 || abs(ind[0] - ii - cdim[0]) <= 5 || abs(ind[0] - ii + cdim[0]) <= 5) && (abs(ind[1] - jj) <= 5 || abs(ind[1] - jj - cdim[1]) <= 5 || abs(ind[1] - jj + cdim[1]) <= 5) && (abs(ind[2] - kk) <= 5 || abs(ind[2] - kk - cdim[2]) <= 5 || abs(ind[2] - kk + cdim[2]) <= 5))) proxy_type |= (int)proxy_cell_type_gravity; } ... ...
 ... ... @@ -159,103 +159,6 @@ void proxy_tags_exchange(struct proxy *proxies, int num_proxies, #endif } /** * @brief Exchange the cell structures with all proxies. * * @param proxies The list of #proxy that will send/recv cells. * @param num_proxies The number of proxies. * @param s The space into which the particles will be unpacked. */ void proxy_cells_exchange(struct proxy *proxies, int num_proxies, struct space *s) { #ifdef WITH_MPI MPI_Request *reqs; if ((reqs = (MPI_Request *)malloc(sizeof(MPI_Request) * 2 * num_proxies)) == NULL) error("Failed to allocate request buffers."); MPI_Request *reqs_in = reqs; MPI_Request *reqs_out = &reqs[num_proxies]; /* Run through the cells and get the size of the ones that will be sent off. */ int count_out = 0; int offset[s->nr_cells]; for (int k = 0; k < s->nr_cells; k++) { offset[k] = count_out; if (s->cells_top[k].sendto) count_out += (s->cells_top[k].pcell_size = cell_getsize(&s->cells_top[k])); } /* Allocate the pcells. */ struct pcell *pcells = NULL; if (posix_memalign((void **)&pcells, SWIFT_CACHE_ALIGNMENT, sizeof(struct pcell) * count_out) != 0) error("Failed to allocate pcell buffer."); /* Pack the cells. */ for (int k = 0; k < s->nr_cells; k++) if (s->cells_top[k].sendto) { cell_pack(&s->cells_top[k], &pcells[offset[k]]); s->cells_top[k].pcell = &pcells[offset[k]]; } /* Launch the first part of the exchange. */ for (int k = 0; k < num_proxies; k++) { proxy_cells_exchange_first(&proxies[k]); reqs_in[k] = proxies[k].req_cells_count_in; reqs_out[k] = proxies[k].req_cells_count_out; } /* Wait for each count to come in and start the recv. */ for (int k = 0; k < num_proxies; k++) { int pid = MPI_UNDEFINED; MPI_Status status; if (MPI_Waitany(num_proxies, reqs_in, &pid, &status) != MPI_SUCCESS || pid == MPI_UNDEFINED) error("MPI_Waitany failed."); // message( "request from proxy %i has arrived." , pid ); proxy_cells_exchange_second(&proxies[pid]); } /* Wait for all the sends to have finished too. */ if (MPI_Waitall(num_proxies, reqs_out, MPI_STATUSES_IGNORE) != MPI_SUCCESS) error("MPI_Waitall on sends failed."); /* Set the requests for the cells. */ for (int k = 0; k < num_proxies; k++) { reqs_in[k] = proxies[k].req_cells_in; reqs_out[k] = proxies[k].req_cells_out; } /* Wait for each pcell array to come in from the proxies. */ for (int k = 0; k < num_proxies; k++) { int pid = MPI_UNDEFINED; MPI_Status status; if (MPI_Waitany(num_proxies, reqs_in, &pid, &status) != MPI_SUCCESS || pid == MPI_UNDEFINED) error("MPI_Waitany failed."); // message( "cell data from proxy %i has arrived." , pid ); for (int count = 0, j = 0; j < proxies[pid].nr_cells_in; j++) count += cell_unpack(&proxies[pid].pcells_in[count], proxies[pid].cells_in[j], s); } /* Wait for all the sends to have finished too. */ if (MPI_Waitall(num_proxies, reqs_out, MPI_STATUSES_IGNORE) != MPI_SUCCESS) error("MPI_Waitall on sends failed."); /* Clean up. */ free(reqs); free(pcells); #else error("SWIFT was not compiled with MPI support."); #endif } /** * @brief Exchange cells with a remote node, first part. * ... ... @@ -350,6 +253,105 @@ void proxy_cells_exchange_second(struct proxy *p) { #endif } /** * @brief Exchange the cell structures with all proxies. * * @param proxies The list of #proxy that will send/recv cells. * @param num_proxies The number of proxies. * @param s The space into which the particles will be unpacked. * @param with_gravity Are we running with gravity and hence need * to exchange multipoles? */ void proxy_cells_exchange(struct proxy *proxies, int num_proxies, struct space *s, const int with_gravity) { #ifdef WITH_MPI MPI_Request *reqs; if ((reqs = (MPI_Request *)malloc(sizeof(MPI_Request) * 2 * num_proxies)) == NULL) error("Failed to allocate request buffers."); MPI_Request *reqs_in = reqs; MPI_Request *reqs_out = &reqs[num_proxies]; /* Run through the cells and get the size of the ones that will be sent off. */ int count_out = 0; int offset[s->nr_cells]; for (int k = 0; k < s->nr_cells; k++) { offset[k] = count_out; if (s->cells_top[k].sendto) count_out += (s->cells_top[k].pcell_size = cell_getsize(&s->cells_top[k])); } /* Allocate the pcells. */ struct pcell *pcells = NULL; if (posix_memalign((void **)&pcells, SWIFT_CACHE_ALIGNMENT, sizeof(struct pcell) * count_out) != 0) error("Failed to allocate pcell buffer."); /* Pack the cells. */ for (int k = 0; k < s->nr_cells; k++) if (s->cells_top[k].sendto) { cell_pack(&s->cells_top[k], &pcells[offset[k]], with_gravity); s->cells_top[k].pcell = &pcells[offset[k]]; } /* Launch the first part of the exchange. */ for (int k = 0; k < num_proxies; k++) { proxy_cells_exchange_first(&proxies[k]); reqs_in[k] = proxies[k].req_cells_count_in; reqs_out[k] = proxies[k].req_cells_count_out; } /* Wait for each count to come in and start the recv. */ for (int k = 0; k < num_proxies; k++) { int pid = MPI_UNDEFINED; MPI_Status status; if (MPI_Waitany(num_proxies, reqs_in, &pid, &status) != MPI_SUCCESS || pid == MPI_UNDEFINED) error("MPI_Waitany failed."); // message( "request from proxy %i has arrived." , pid ); proxy_cells_exchange_second(&proxies[pid]); } /* Wait for all the sends to have finished too. */ if (MPI_Waitall(num_proxies, reqs_out, MPI_STATUSES_IGNORE) != MPI_SUCCESS) error("MPI_Waitall on sends failed."); /* Set the requests for the cells. */ for (int k = 0; k < num_proxies; k++) { reqs_in[k] = proxies[k].req_cells_in; reqs_out[k] = proxies[k].req_cells_out; } /* Wait for each pcell array to come in from the proxies. */ for (int k = 0; k < num_proxies; k++) { int pid = MPI_UNDEFINED; MPI_Status status; if (MPI_Waitany(num_proxies, reqs_in, &pid, &status) != MPI_SUCCESS || pid == MPI_UNDEFINED) error("MPI_Waitany failed."); // message( "cell data from proxy %i has arrived." , pid ); for (int count = 0, j = 0; j < proxies[pid].nr_cells_in; j++) count += cell_unpack(&proxies[pid].pcells_in[count], proxies[pid].cells_in[j], s, with_gravity); } /* Wait for all the sends to have finished too. */ if (MPI_Waitall(num_proxies, reqs_out, MPI_STATUSES_IGNORE) != MPI_SUCCESS) error("MPI_Waitall on sends failed."); /* Clean up. */ free(reqs); free(pcells); #else error("SWIFT was not compiled with MPI support."); #endif } /** * @brief Add a cell to the given proxy's input list. * ... ...
 ... ... @@ -102,9 +102,7 @@ void proxy_parts_exchange_second(struct proxy *p); void proxy_addcell_in(struct proxy *p, struct cell *c, int type); void proxy_addcell_out(struct proxy *p, struct cell *c, int type); void proxy_cells_exchange(struct proxy *proxies, int num_proxies, struct space *s); void proxy_cells_exchange_first(struct proxy *p); void proxy_cells_exchange_second(struct proxy *p); struct space *s, int with_gravity); void proxy_tags_exchange(struct proxy *proxies, int num_proxies, struct space *s); ... ...
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment