diff --git a/src/engine.c b/src/engine.c index 009779111703511ee2c1617013fb21b8e3f3553c..d2f4af3de19ad6fdcbef8f9ee5fee48fdb7102c7 100644 --- a/src/engine.c +++ b/src/engine.c @@ -4440,6 +4440,7 @@ void engine_reconstruct_multipoles(struct engine *e) { void engine_makeproxies(struct engine *e) { #ifdef WITH_MPI + const int nodeID = e->nodeID; const int *cdim = e->s->cdim; const struct space *s = e->s; struct cell *cells = s->cells_top; @@ -4487,6 +4488,22 @@ void engine_makeproxies(struct engine *e) { /* Get the cell ID. */ const int cjd = cell_getid(cdim, ii, jj, kk); + /* Early abort (same cell) */ + if(cid == cjd) + continue; + + /* Early abort (both same node) */ + if(cells[cid].nodeID == nodeID && + cells[cjd].nodeID == nodeID) + continue; + + /* Early abort (both foreign node) */ + if(cells[cid].nodeID != nodeID && + cells[cjd].nodeID != nodeID) + continue; + + char proxy_type = proxy_cell_type_none; + /* In the gravity case, check distances using the MAC. */ if (with_gravity) { @@ -4509,25 +4526,32 @@ void engine_makeproxies(struct engine *e) { } const double r2 = dx * dx + dy * dy + dz * dz; - if (gravity_M2L_accept(r_max_i, r_max_j, theta_crit2, r2)) - continue; + /* Are we too close for M2L? */ + if (!gravity_M2L_accept(r_max_i, r_max_j, theta_crit2, r2)) + proxy_type |= proxy_cell_type_gravity; } - /* In the hydro case, only carre about neighbours */ - else if (with_hydro) { - - if (!((abs(i - ii) <= 1 || abs(i - ii - cdim[0]) <= 1 || - abs(i - ii + cdim[0]) <= 1) && - (abs(j - jj) <= 1 || abs(j - jj - cdim[1]) <= 1 || - abs(j - jj + cdim[1]) <= 1) && - (abs(k - kk) <= 1 || abs(k - kk - cdim[2]) <= 1 || - abs(k - kk + cdim[2]) <= 1))) - continue; + /* In the hydro case, only care about neighbours */ + if (with_hydro) { + + /* This is super-ugly but checks for direct neighbours */ + /* with periodic BC */ + if (((abs(i - ii) <= 1 || abs(i - ii - cdim[0]) <= 1 || + abs(i - ii + cdim[0]) <= 1) && + (abs(j - jj) <= 1 || abs(j - jj - cdim[1]) <= 1 || + abs(j - jj + cdim[1]) <= 1) && + (abs(k - kk) <= 1 || abs(k - kk - cdim[2]) <= 1 || + abs(k - kk + cdim[2]) <= 1))) + proxy_type |= proxy_cell_type_hydro; } + /* Abort if not in range at all */ + if(proxy_type == proxy_cell_type_none) + continue; + /* Add to proxies? */ - if (cells[cid].nodeID == e->nodeID && - cells[cjd].nodeID != e->nodeID) { + if (cells[cid].nodeID == nodeID && + cells[cjd].nodeID != nodeID) { /* Do we already have a relationship with this node? */ int pid = e->proxy_ind[cells[cjd].nodeID]; @@ -4535,7 +4559,7 @@ void engine_makeproxies(struct engine *e) { if (e->nr_proxies == engine_maxproxies) error("Maximum number of proxies exceeded."); - /* Ok, start a new proxy for this pair */ + /* Ok, start a new proxy for this pair of nodes */ proxy_init(&proxies[e->nr_proxies], e->nodeID, cells[cjd].nodeID); @@ -4546,16 +4570,16 @@ void engine_makeproxies(struct engine *e) { } /* Add the cell to the proxy */ - proxy_addcell_in(&proxies[pid], &cells[cjd]); - proxy_addcell_out(&proxies[pid], &cells[cid]); + proxy_addcell_in(&proxies[pid], &cells[cjd], proxy_type); + proxy_addcell_out(&proxies[pid], &cells[cid], proxy_type); /* Store info about where to send the cell */ cells[cid].sendto |= (1ULL << pid); } /* Same for the symmetric case? */ - if (cells[cjd].nodeID == e->nodeID && - cells[cid].nodeID != e->nodeID) { + if (cells[cjd].nodeID == nodeID && + cells[cid].nodeID != nodeID) { /* Do we already have a relationship with this node? */ int pid = e->proxy_ind[cells[cid].nodeID]; @@ -4563,7 +4587,7 @@ void engine_makeproxies(struct engine *e) { if (e->nr_proxies == engine_maxproxies) error("Maximum number of proxies exceeded."); - /* Ok, start a new proxy for this pair */ + /* Ok, start a new proxy for this pair of nodes */ proxy_init(&proxies[e->nr_proxies], e->nodeID, cells[cid].nodeID); @@ -4574,8 +4598,8 @@ void engine_makeproxies(struct engine *e) { } /* Add the cell to the proxy */ - proxy_addcell_in(&proxies[pid], &cells[cid]); - proxy_addcell_out(&proxies[pid], &cells[cjd]); + proxy_addcell_in(&proxies[pid], &cells[cid], proxy_type); + proxy_addcell_out(&proxies[pid], &cells[cjd], proxy_type); /* Store info about where to send the cell */ cells[cjd].sendto |= (1ULL << pid); diff --git a/src/proxy.c b/src/proxy.c index dd6faa3055cb17a0a3050d9e62d107d7489a4326..b34d80c6eba143e38961e21308111ffec2657ada 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -124,8 +124,9 @@ void proxy_cells_exch2(struct proxy *p) { * * @param p The #proxy. * @param c The #cell. + * @param type Why is this cell in the proxy (hdro, gravity, ...) ? */ -void proxy_addcell_in(struct proxy *p, struct cell *c) { +void proxy_addcell_in(struct proxy *p, struct cell *c, char type) { /* Check if the cell is already registered with the proxy. */ for (int k = 0; k < p->nr_cells_in; k++) @@ -133,17 +134,29 @@ void proxy_addcell_in(struct proxy *p, struct cell *c) { /* Do we need to grow the number of in cells? */ if (p->nr_cells_in == p->size_cells_in) { + + message("Increasing proxy size"); + p->size_cells_in *= proxy_buffgrow; - struct cell **temp; - if ((temp = malloc(sizeof(struct cell *) * p->size_cells_in)) == NULL) + + struct cell **temp_cell; + if ((temp_cell = malloc(sizeof(struct cell *) * p->size_cells_in)) == NULL) error("Failed to allocate incoming cell list."); - memcpy(temp, p->cells_in, sizeof(struct cell *) * p->nr_cells_in); + memcpy(temp_cell, p->cells_in, sizeof(struct cell *) * p->nr_cells_in); free(p->cells_in); - p->cells_in = temp; + p->cells_in = temp_cell; + + char *temp_type; + if ((temp_type = malloc(sizeof(char) * p->size_cells_in)) == NULL) + error("Failed to allocate incoming cell type list."); + memcpy(temp_type, p->cells_in_type, sizeof(char) * p->nr_cells_in); + free(p->cells_in_type); + p->cells_in_type = temp_type; } /* Add the cell. */ p->cells_in[p->nr_cells_in] = c; + p->cells_in_type[p->nr_cells_in] = type; p->nr_cells_in += 1; } @@ -152,8 +165,9 @@ void proxy_addcell_in(struct proxy *p, struct cell *c) { * * @param p The #proxy. * @param c The #cell. + * @param type Why is this cell in the proxy (hdro, gravity, ...) ? */ -void proxy_addcell_out(struct proxy *p, struct cell *c) { +void proxy_addcell_out(struct proxy *p, struct cell *c, char type) { /* Check if the cell is already registered with the proxy. */ for (int k = 0; k < p->nr_cells_out; k++) @@ -162,16 +176,25 @@ void proxy_addcell_out(struct proxy *p, struct cell *c) { /* Do we need to grow the number of out cells? */ if (p->nr_cells_out == p->size_cells_out) { p->size_cells_out *= proxy_buffgrow; - struct cell **temp; - if ((temp = malloc(sizeof(struct cell *) * p->size_cells_out)) == NULL) + + struct cell **temp_cell; + if ((temp_cell = malloc(sizeof(struct cell *) * p->size_cells_out)) == NULL) error("Failed to allocate outgoing cell list."); - memcpy(temp, p->cells_out, sizeof(struct cell *) * p->nr_cells_out); + memcpy(temp_cell, p->cells_out, sizeof(struct cell *) * p->nr_cells_out); free(p->cells_out); - p->cells_out = temp; + p->cells_out = temp_cell; + + char *temp_type; + if ((temp_type = malloc(sizeof(char) * p->size_cells_out)) == NULL) + error("Failed to allocate outgoing cell type list."); + memcpy(temp_type, p->cells_out_type, sizeof(char) * p->nr_cells_out); + free(p->cells_out_type); + p->cells_out_type = temp_type; } /* Add the cell. */ p->cells_out[p->nr_cells_out] = c; + p->cells_out_type[p->nr_cells_out] = type; p->nr_cells_out += 1; } @@ -433,6 +456,9 @@ void proxy_init(struct proxy *p, int mynodeID, int nodeID) { if ((p->cells_in = (struct cell **)malloc(sizeof(void *) * p->size_cells_in)) == NULL) error("Failed to allocate cells_in buffer."); + if ((p->cells_in_type = + (char *)malloc(sizeof(char) * p->size_cells_in)) == NULL) + error("Failed to allocate cells_in_type buffer."); } p->nr_cells_in = 0; if (p->cells_out == NULL) { @@ -440,6 +466,9 @@ void proxy_init(struct proxy *p, int mynodeID, int nodeID) { if ((p->cells_out = (struct cell **)malloc(sizeof(void *) * p->size_cells_out)) == NULL) error("Failed to allocate cells_out buffer."); + if ((p->cells_out_type = + (char *)malloc(sizeof(char) * p->size_cells_out)) == NULL) + error("Failed to allocate cells_out_type buffer."); } p->nr_cells_out = 0; diff --git a/src/proxy.h b/src/proxy.h index a245077193878bb669b474944965badceffcee80..144c291fc02dc865747802c91b140354743d010f 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -36,6 +36,15 @@ #define proxy_tag_sparts 4 #define proxy_tag_cells 5 +/** + * @brief The different reasons a cell can be in a proxy + */ +enum proxy_cell_type { + proxy_cell_type_none = 0, + proxy_cell_type_hydro = (1<<0), + proxy_cell_type_gravity = (1<<1) +}; + /* Data structure for the proxy. */ struct proxy { @@ -44,11 +53,13 @@ struct proxy { /* Incoming cells. */ struct cell **cells_in; + char *cells_in_type; struct pcell *pcells_in; int nr_cells_in, size_cells_in, size_pcells_in; /* Outgoing cells. */ struct cell **cells_out; + char *cells_out_type; struct pcell *pcells_out; int nr_cells_out, size_cells_out, size_pcells_out; @@ -87,8 +98,8 @@ void proxy_gparts_load(struct proxy *p, const struct gpart *gparts, int N); void proxy_sparts_load(struct proxy *p, const struct spart *sparts, int N); void proxy_parts_exch1(struct proxy *p); void proxy_parts_exch2(struct proxy *p); -void proxy_addcell_in(struct proxy *p, struct cell *c); -void proxy_addcell_out(struct proxy *p, struct cell *c); +void proxy_addcell_in(struct proxy *p, struct cell *c, char type); +void proxy_addcell_out(struct proxy *p, struct cell *c, char type); void proxy_cells_exch1(struct proxy *p); void proxy_cells_exch2(struct proxy *p);