diff --git a/src/cell.c b/src/cell.c index 8bd26b32343f2307673c5f0d9c3abfd68172c187..66f7453667e202494515e0eb45ab7028e75a8303 100644 --- a/src/cell.c +++ b/src/cell.c @@ -1386,12 +1386,14 @@ void cell_check_sort_flags(const struct cell *c) { const int do_stars_sub_sort = cell_get_flag(c, cell_flag_do_stars_sub_sort); if (do_hydro_sub_sort) - error("cell %d has a hydro sub_sort flag set. Node=%d depth=%d maxdepth=%d", - c->cellID, c->nodeID, c->depth, c->maxdepth); + error( + "cell %lld has a hydro sub_sort flag set. Node=%d depth=%d maxdepth=%d", + c->cellID, c->nodeID, c->depth, c->maxdepth); if (do_stars_sub_sort) - error("cell %d has a stars sub_sort flag set. Node=%d depth=%d maxdepth=%d", - c->cellID, c->nodeID, c->depth, c->maxdepth); + error( + "cell %lld has a stars sub_sort flag set. Node=%d depth=%d maxdepth=%d", + c->cellID, c->nodeID, c->depth, c->maxdepth); if (c->split) { for (int k = 0; k < 8; ++k) { diff --git a/src/cell.h b/src/cell.h index d80d11b8229032795a64b2c862d3dc0bc310de70..b6d9bb9ad66ca30bbd55839d59f40986d404e224 100644 --- a/src/cell.h +++ b/src/cell.h @@ -62,6 +62,11 @@ struct scheduler; /* Global variables. */ extern int cell_next_tag; +/*! Counter for cell IDs (when exceeding max values for uniqueness) */ +#if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) +extern long long last_cell_id; +#endif + /* Struct to temporarily buffer the particle locations and bin id. */ struct cell_buff { double x[3]; @@ -225,7 +230,7 @@ struct pcell { #ifdef SWIFT_DEBUG_CHECKS /* Cell ID (for debugging) */ - int cellID; + long long cellID; #endif } SWIFT_STRUCT_ALIGN; @@ -452,7 +457,7 @@ struct cell { #if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) /* Cell ID (for debugging) */ - int cellID; + long long cellID; #endif #ifdef SWIFT_DEBUG_CHECKS @@ -1279,4 +1284,95 @@ __attribute__((always_inline)) INLINE static struct task *cell_get_recv( #endif } +/** + * @brief Generate the cell ID for top level cells. Only used for debugging. + * + * Cell IDs are stored in the long long `cell->cellID`. Top level cells get + * their index according to their location on the top level grid, and are + * marked with a minus sign. + * We have 15 bits set aside in `cell->cellID` for the top level cells. Hence + * if we have more that 32^3 top level cells, the cell IDs won't be guaranteed + * to be unique. Top level cells will still be recognizable by the minus sign. + */ +__attribute__((always_inline)) INLINE void cell_assign_top_level_cell_index( + struct cell *c, int cdim[3], double dim[3], double width[3]) { + +#if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) + if (c->depth != 0) { + error("assigning top level cell index to cell with depth > 0"); + } else { + if (cdim[0] * cdim[1] * cdim[2] > 32 * 32 * 32) { + /* print warning only once */ + if (last_cell_id == 1) { + message( + "Warning: Got %d x %d x %d top level cells." + "Cell IDs are only guaranteed to be unique if count is < 32^3", + cdim[0], cdim[1], cdim[2]); + } + c->cellID = -last_cell_id; + atomic_inc(&last_cell_id); + } + + int i = (int)(c->loc[0] / width[0]); + int j = (int)(c->loc[1] / width[1]); + int k = (int)(c->loc[2] / width[2]); + c->cellID = -(long long)(cell_getid(cdim, i, j, k) + 1); + } +#endif +} + +/** + * @brief Generate the cell ID for progeny cells. Only used for debugging. + * + * Cell IDs are stored in the long long `cell->cellID`. + * We have 15 bits set aside in `cell->cellID` for the top level cells, and + * one for a minus sign to mark top level cells. The remaining 48 bits are + * for all other cells. Each progeny cell gets a unique ID by inheriting + * its parent ID and adding 3 bits on the right side, which are set according + * to the progeny's location within its parent cell. Hence we can store up to + * 16 levels of depth uniquely. + * If the depth exceeds 16, we use the old scheme where we just add up a + * counter. This gives us 32^3 new unique cell IDs, previously reserved for + * top level cells, but the IDs won't be thread safe and will vary each run. + * After the 32^3 cells are filled, we reach degeneracy. + */ +__attribute__((always_inline)) INLINE void cell_assign_cell_index( + struct cell *c, const struct cell *parent) { + +#if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) + if (c->depth == 0) { + error("assigning progeny cell index to top level cell."); + } else if (c->depth > 16 || last_cell_id > 1) { + /* last_cell_id > 1 => too many top level cells for clever IDs */ + /* print warning only once */ + if (last_cell_id == 1) { + message( + "Warning: Got depth %d > 16." + "IDs are only guaranteed unique if depth <= 16", + c->depth); + } + c->cellID = last_cell_id; + atomic_inc(&last_cell_id); + } else { + /* we're good to go for unique IDs */ + /* first inherit the parent's ID and mark it as not top-level*/ + long long child_id = llabs(parent->cellID); + + /* make place for new bits */ + /* parent's ID needs to be leading bits, so 000 children still + * change the value of the cellID */ + child_id <<= 3; + + /* get progeny index in parent cell */ + if (c->loc[0] > parent->loc[0]) child_id |= 1LL; + if (c->loc[1] > parent->loc[1]) child_id |= 2LL; + if (c->loc[2] > parent->loc[2]) child_id |= 4LL; + + /* add progeny index to cell index */ + c->cellID = child_id; + } + +#endif +} + #endif /* SWIFT_CELL_H */ diff --git a/src/runner_doiact_functions_stars.h b/src/runner_doiact_functions_stars.h index 7e802d6f4afd885697c3915d475d38a4e5da7a73..b8bea6fa2125bbddb0deb013c46876e97ec61927 100644 --- a/src/runner_doiact_functions_stars.h +++ b/src/runner_doiact_functions_stars.h @@ -1098,7 +1098,7 @@ void DOSELF1_BRANCH_STARS(struct runner *r, struct cell *c) { "ci->nodeID=%d d=%e sort_j[pjd].d=%e cj->" #TYPE \ ".dx_max_sort=%e " \ "cj->" #TYPE \ - ".dx_max_sort_old=%e, cellID=%i super->cellID=%i" \ + ".dx_max_sort_old=%e, cellID=%lld super->cellID=%lld" \ "cj->depth=%d cj->maxdepth=%d", \ cj->nodeID, ci->nodeID, d, sort_j[pjd].d, cj->TYPE.dx_max_sort, \ cj->TYPE.dx_max_sort_old, cj->cellID, cj->hydro.super->cellID, \ diff --git a/src/runner_others.c b/src/runner_others.c index f684b1714f4eaad4d5c8b9c87c162d7f9ef89b21..479da517a7e435d91161ba4397d7acda9dbd76fe 100644 --- a/src/runner_others.c +++ b/src/runner_others.c @@ -313,7 +313,7 @@ void runner_do_star_formation(struct runner *r, struct cell *c, int timer) { /* Did we get a star? (Or did we run out of spare ones?) */ if (sp != NULL) { - /* message("We formed a star id=%lld cellID=%d", sp->id, + /* message("We formed a star id=%lld cellID=%lld", sp->id, * c->cellID); */ /* Copy the properties of the gas particle to the star particle */ diff --git a/src/runner_time_integration.c b/src/runner_time_integration.c index 656490bd3491a5166936af682623e6de668b28fc..db7f4a23ba743683137308680381ff86cc5608ba 100644 --- a/src/runner_time_integration.c +++ b/src/runner_time_integration.c @@ -1178,7 +1178,7 @@ void runner_do_limiter(struct runner *r, struct cell *c, int force, /* Bip, bip, bip... wake-up time */ if (p->limiter_data.wakeup != time_bin_not_awake) { - // message("Limiting particle %lld in cell %d", p->id, c->cellID); + // message("Limiting particle %lld in cell %lld", p->id, c->cellID); /* Apply the limiter and get the new end of time-step */ const integertime_t ti_end_new = timestep_limit_part(p, xp, e); diff --git a/src/space.c b/src/space.c index 6747524f4fc0c33d5eb9b0392ba88cb8a85a78ae..5a5e11e541d599589a352aa0b32cb6564b474fad 100644 --- a/src/space.c +++ b/src/space.c @@ -94,9 +94,9 @@ int engine_star_resort_task_depth = engine_star_resort_task_depth_default; /*! Expected maximal number of strays received at a rebuild */ int space_expected_max_nr_strays = space_expected_max_nr_strays_default; -/*! Counter for cell IDs (when debugging) */ +/*! Counter for cell IDs (when debugging + max vals for unique IDs exceeded) */ #if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) -int last_cell_id; +long long last_cell_id; #endif /** @@ -2412,24 +2412,24 @@ void space_write_cell(const struct space *s, FILE *f, const struct cell *c) { if (c == NULL) return; /* Get parent ID */ - int parent = root_cell_id; + long long parent = root_cell_id; if (c->parent != NULL) parent = c->parent->cellID; /* Get super ID */ char superID[100] = ""; - if (c->super != NULL) sprintf(superID, "%i", c->super->cellID); + if (c->super != NULL) sprintf(superID, "%lld", c->super->cellID); /* Get hydro super ID */ char hydro_superID[100] = ""; if (c->hydro.super != NULL) - sprintf(hydro_superID, "%i", c->hydro.super->cellID); + sprintf(hydro_superID, "%lld", c->hydro.super->cellID); /* Write line for current cell */ - fprintf(f, "%i,%i,%i,", c->cellID, parent, c->nodeID); + fprintf(f, "%lld,%lld,%i,", c->cellID, parent, c->nodeID); fprintf(f, "%i,%i,%i,%s,%s,%g,%g,%g,%g,%g,%g, ", c->hydro.count, c->stars.count, c->grav.count, superID, hydro_superID, c->loc[0], c->loc[1], c->loc[2], c->width[0], c->width[1], c->width[2]); - fprintf(f, "%g, %g %i %i\n", c->hydro.h_max, c->stars.h_max, c->depth, + fprintf(f, "%g, %g, %i, %i\n", c->hydro.h_max, c->stars.h_max, c->depth, c->maxdepth); /* Write children */ @@ -2466,9 +2466,9 @@ void space_write_cell_hierarchy(const struct space *s, int j) { /* Write root data */ fprintf(f, "%i, ,-1,", root_id); - fprintf(f, "%li,%li,%li, , , , , , , , , ", s->nr_parts, s->nr_sparts, + fprintf(f, "%li,%li,%li, , , , , , , , ,", s->nr_parts, s->nr_sparts, s->nr_gparts); - fprintf(f, ",\n"); + fprintf(f, " , , ,\n"); } /* Write all the top level cells (and their children) */ diff --git a/src/space_rebuild.c b/src/space_rebuild.c index f456be124731830a7c91f65caca4d1517644d701..0b68ca2b0cf9cfaea16ba95908fa38cacff71a25 100644 --- a/src/space_rebuild.c +++ b/src/space_rebuild.c @@ -35,7 +35,7 @@ extern int space_expected_max_nr_strays; /*! Counter for cell IDs (when debugging) */ #if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) -extern int last_cell_id; +extern long long last_cell_id; #endif /** @@ -911,8 +911,7 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { c->black_holes.ti_old_part = ti_current; #if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) - c->cellID = -last_cell_id; - last_cell_id++; + cell_assign_top_level_cell_index(c, s->cdim, s->dim, s->width); #endif const int is_local = (c->nodeID == engine_rank); diff --git a/src/space_regrid.c b/src/space_regrid.c index b20a3b4894bf3ce6418cd288f74fe91cedc36ab7..035c3f92096ab16c9334c7e56e791bf06b53c528 100644 --- a/src/space_regrid.c +++ b/src/space_regrid.c @@ -30,11 +30,6 @@ #include "engine.h" #include "scheduler.h" -/*! Counter for cell IDs (when debugging) */ -#if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) -extern int last_cell_id; -#endif - /** * @brief Re-build the top-level cell grid. * @@ -321,8 +316,7 @@ void space_regrid(struct space *s, int verbose) { #endif // WITH_MPI if (s->with_self_gravity) c->grav.multipole = &s->multipoles_top[cid]; #if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) - c->cellID = -last_cell_id; - last_cell_id++; + cell_assign_top_level_cell_index(c, s->cdim, s->dim, s->width); #endif } diff --git a/src/space_split.c b/src/space_split.c index 728c6f8984b3476bfc0729546059477c3d1f38cf..38d75ad48b3e10c21d7047bb6471f41ee16bd881 100644 --- a/src/space_split.c +++ b/src/space_split.c @@ -33,11 +33,6 @@ #include "star_formation_logger.h" #include "threadpool.h" -/*! Counter for cell IDs (when debugging) */ -#if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) -extern int last_cell_id; -#endif - /** * @brief Recursively split a cell. * @@ -250,7 +245,7 @@ void space_split_recursive(struct space *s, struct cell *c, cp->mpi.tag = -1; #endif // WITH_MPI #if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) - cp->cellID = last_cell_id++; + cell_assign_cell_index(cp, c); #endif }