From e10962592935e8e280c07394682db8bb44e81611 Mon Sep 17 00:00:00 2001 From: Johannes Holke Date: Wed, 17 Jul 2024 14:49:14 +0200 Subject: [PATCH 01/15] Change attribute offset computation of ghost attributes when commiting from stash --- src/CMakeLists.txt | 2 +- src/Makefile.am | 2 +- src/t8_cmesh/t8_cmesh_commit.cxx | 11 +- .../{t8_cmesh_trees.c => t8_cmesh_trees.cxx} | 121 +++++++++++++++--- src/t8_cmesh/t8_cmesh_trees.h | 4 +- .../t8_cmesh_new_hypercube_param.hxx | 2 +- 6 files changed, 116 insertions(+), 26 deletions(-) rename src/t8_cmesh/{t8_cmesh_trees.c => t8_cmesh_trees.cxx} (90%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4aaa647f93..9cc1d211d1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -76,7 +76,7 @@ target_sources( T8 PRIVATE t8_cmesh/t8_cmesh_vtk_reader.cxx t8_cmesh/t8_cmesh_save.cxx t8_cmesh/t8_cmesh_netcdf.c - t8_cmesh/t8_cmesh_trees.c + t8_cmesh/t8_cmesh_trees.cxx t8_cmesh/t8_cmesh_commit.cxx t8_cmesh/t8_cmesh_partition.cxx t8_cmesh/t8_cmesh_copy.c diff --git a/src/Makefile.am b/src/Makefile.am index e26283ad46..c05ca06d99 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -113,7 +113,7 @@ libt8_compiled_sources = \ src/t8_cmesh/t8_cmesh_vtk_reader.cxx \ src/t8_cmesh/t8_cmesh_save.cxx \ src/t8_cmesh/t8_cmesh_netcdf.c \ - src/t8_cmesh/t8_cmesh_trees.c src/t8_cmesh/t8_cmesh_commit.cxx \ + src/t8_cmesh/t8_cmesh_trees.cxx src/t8_cmesh/t8_cmesh_commit.cxx \ src/t8_cmesh/t8_cmesh_partition.cxx\ src/t8_cmesh/t8_cmesh_copy.c src/t8_data/t8_shmem.c \ src/t8_cmesh/t8_cmesh_geometry.cxx \ diff --git a/src/t8_cmesh/t8_cmesh_commit.cxx b/src/t8_cmesh/t8_cmesh_commit.cxx index 65dc12751c..5c6bb11b08 100644 --- a/src/t8_cmesh/t8_cmesh_commit.cxx +++ b/src/t8_cmesh/t8_cmesh_commit.cxx @@ -84,7 +84,7 @@ t8_cmesh_set_shmem_type (sc_MPI_Comm comm) } static void -t8_cmesh_add_attributes (const t8_cmesh_t cmesh, sc_hash_t *ghost_ids, size_t *attribute_data_offset) +t8_cmesh_add_attributes (const t8_cmesh_t cmesh, sc_hash_t *ghost_ids) { t8_stash_attribute_struct_t *attribute; const t8_stash_t stash = cmesh->stash; @@ -114,7 +114,7 @@ t8_cmesh_add_attributes (const t8_cmesh_t cmesh, sc_hash_t *ghost_ids, size_t *a if (sc_hash_lookup (ghost_ids, temp_facejoin, (void ***) &facejoin_pp)) { /* attribute is on a ghost tree */ t8_cmesh_trees_add_ghost_attribute (cmesh->trees, 0, attribute, (*facejoin_pp)->local_id, - (*facejoin_pp)->attr_id, attribute_data_offset); + (*facejoin_pp)->attr_id); (*facejoin_pp)->attr_id++; } } @@ -167,7 +167,7 @@ t8_cmesh_commit_replicated_new (t8_cmesh_t cmesh) t8_stash_attribute_sort (cmesh->stash); cmesh->num_trees = cmesh->num_local_trees = num_trees; cmesh->first_tree = 0; - t8_cmesh_add_attributes (cmesh, NULL, NULL); + t8_cmesh_add_attributes (cmesh, NULL); /* Set all face connections */ t8_cmesh_trees_set_all_boundary (cmesh, cmesh->trees); @@ -198,7 +198,6 @@ t8_cmesh_commit_partitioned_new (t8_cmesh_t cmesh, sc_MPI_Comm comm) t8_cghost_t ghost1; int F; size_t si; - size_t attribute_data_offset; #if T8_ENABLE_DEBUG sc_flopinfo_t fi, snapshot; @@ -375,7 +374,7 @@ t8_cmesh_commit_partitioned_new (t8_cmesh_t cmesh, sc_MPI_Comm comm) ghost1->att_offset += attribute->attr_size; } } - attribute_data_offset = t8_cmesh_trees_finish_part (cmesh->trees, 0); + t8_cmesh_trees_finish_part (cmesh->trees, 0); t8_cmesh_trees_set_all_boundary (cmesh, cmesh->trees); /* Go through all face_neighbour entries and parse every @@ -473,7 +472,7 @@ t8_cmesh_commit_partitioned_new (t8_cmesh_t cmesh, sc_MPI_Comm comm) * counting the attributes per tree. */ t8_stash_attribute_sort (cmesh->stash); - t8_cmesh_add_attributes (cmesh, ghost_ids, &attribute_data_offset); + t8_cmesh_add_attributes (cmesh, ghost_ids); /* compute global number of trees. id1 serves as buffer since * global number and local number have different datatypes */ diff --git a/src/t8_cmesh/t8_cmesh_trees.c b/src/t8_cmesh/t8_cmesh_trees.cxx similarity index 90% rename from src/t8_cmesh/t8_cmesh_trees.c rename to src/t8_cmesh/t8_cmesh_trees.cxx index 24e6765ef8..aab245c355 100644 --- a/src/t8_cmesh/t8_cmesh_trees.c +++ b/src/t8_cmesh/t8_cmesh_trees.cxx @@ -25,6 +25,8 @@ * TODO: document this file */ +#include +#include #include "t8_cmesh_stash.h" #include "t8_cmesh_trees.h" @@ -210,6 +212,49 @@ t8_cmesh_trees_start_part (const t8_cmesh_trees_t trees, const int proc, const t part->first_ghost_id = lfirst_ghost; } +/* Helper struct for sorting the number of ghost attributes by global id. + * In order to sort them, we need the part ghost id to access the global id. + * Thus, we store both the part id and the number of attributes. */ +typedef struct +{ + t8_locidx_t part_ghost_id; + t8_gloidx_t global_id; + int num_attributes; + int attribute_offset; +} t8_part_ghost_id_and_num_atts; + +/* Compare function for t8_part_ghost_id_and_num_atts to compare by global id. +* +* Return < 0 if global_id of if_A < global_id of id_B +* Return = 0 if equal +* Return > 0 if > +* */ +bool +t8_compare_id_and_att_by_global_id (t8_part_ghost_id_and_num_atts &id_A, t8_part_ghost_id_and_num_atts &id_B) +{ + return id_A.global_id - id_B.global_id; +} + +/* Compare function for t8_part_ghost_id_and_num_atts to compare by local id. +* +* Return < 0 if local id of if_A < local id of id_B +* Return = 0 if equal +* Return > 0 if > +* */ +bool +t8_compare_id_and_att_by_part_id (t8_part_ghost_id_and_num_atts &id_A, t8_part_ghost_id_and_num_atts &id_B) +{ + return id_A.part_ghost_id - id_B.part_ghost_id; +} + +static std::vector +t8_cmesh_allocate_ghost_num_atts_array (t8_locidx_t part_num_ghosts) +{ + // The offset sum will start at 0 so we need one additional entry. + std::vector num_attributes_of_ghosts (part_num_ghosts); + return num_attributes_of_ghosts; +} + /* After all classes of trees and ghosts have been set and after the * number of tree attributes was set and their total size (per tree) * stored temporarily in the att_offset variable @@ -218,7 +263,7 @@ t8_cmesh_trees_start_part (const t8_cmesh_trees_t trees, const int proc, const t /* The workflow can be: call start_part, set tree and ghost classes maually, call * init_attributes, call finish_part, successively call add_attributes * and also set all face neighbors (TODO: write function)*/ -size_t +void t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) { t8_part_tree_t part; @@ -226,13 +271,12 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) t8_cghost_t ghost; size_t tree_attr_bytes; size_t ghost_attr_bytes; - size_t face_neigh_bytes; /* count the total number of bytes needed for face_neighbor information */ - size_t first_face; /* offset of the first face neighbor information */ - size_t first_tree; /* offset of the first tree */ - size_t first_ghost; /* offset of the first ghost */ - size_t temp_offset; /* offset of the currently looked at tree/ghost */ - size_t num_tree_attributes; /* total number of tree attributes */ - size_t num_ghost_attributes; /* total number of ghost attributes */ + size_t face_neigh_bytes; /* count the total number of bytes needed for face_neighbor information */ + size_t first_face; /* offset of the first face neighbor information */ + size_t first_tree; /* offset of the first tree */ + size_t first_ghost; /* offset of the first ghost */ + size_t temp_offset; /* offset of the currently looked at tree/ghost */ + size_t num_tree_attributes; /* total number of tree attributes */ t8_attribute_info_struct_t *attr; t8_locidx_t it; #ifndef SC_ENABLE_REALLOC @@ -243,7 +287,7 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) part = t8_cmesh_trees_get_part (trees, proc); T8_ASSERT (part != NULL); - num_tree_attributes = num_ghost_attributes = 0; + num_tree_attributes = 0; tree_attr_bytes = ghost_attr_bytes = face_neigh_bytes = 0; /* The offset of the first tree */ first_tree = 0; @@ -252,7 +296,13 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) /* The offset of the first ghost face */ first_face = first_ghost + part->num_ghosts * sizeof (t8_cghost_struct_t); - /* First pass through ghosts to set the face neighbor offsets */ + /* First pass through ghosts to set the face neighbor offsets. */ + /* Additionally, we need to sort the number of attributes according to the global id in order + * to properly compute the attribute info offsets later. */ + + std::vector num_attributes_of_ghosts + = t8_cmesh_allocate_ghost_num_atts_array (part->num_ghosts); + temp_offset = first_ghost; for (it = 0; it < part->num_ghosts; it++) { ghost = t8_part_tree_get_ghost (part, it + part->first_ghost_id); @@ -264,7 +314,27 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) face_neigh_bytes += T8_ADD_PADDING (face_neigh_bytes); T8_ASSERT (face_neigh_bytes % T8_PADDING_SIZE == 0); temp_offset += sizeof (t8_cghost_struct_t); + + /* Add the number of attributes of this ghost to the array. */ + t8_part_ghost_id_and_num_atts &lid_and_num_atts_entry = num_attributes_of_ghosts[it]; + lid_and_num_atts_entry.part_ghost_id = it; + lid_and_num_atts_entry.num_attributes = ghost->num_attributes; + lid_and_num_atts_entry.global_id = ghost->treeid; + lid_and_num_atts_entry.attribute_offset = 0; } + /* We now sort the array of num attributes by global id */ + std::sort (num_attributes_of_ghosts.begin (), num_attributes_of_ghosts.end (), t8_compare_id_and_att_by_global_id); + + if (part->num_ghosts > 0) { + num_attributes_of_ghosts[0].attribute_offset = 0; + } + for (t8_locidx_t ighost = 1; ighost < part->num_ghosts; ++ighost) { + // Build the sum: 0 a a+b a+b+c a+b+c+d + num_attributes_of_ghosts[ighost].attribute_offset + = num_attributes_of_ghosts[ighost - 1].attribute_offset + num_attributes_of_ghosts[ighost - 1].num_attributes; + } + /* We now need to sort the offset sum by local id again. */ + std::sort (num_attributes_of_ghosts.begin (), num_attributes_of_ghosts.end (), t8_compare_id_and_att_by_part_id); /* First pass through trees to set the face neighbor offsets */ temp_offset = 0; @@ -294,14 +364,14 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) /* Second pass through ghosts to set attribute offsets */ temp_offset = first_ghost; + size_t num_ghost_attributes = 0; /* total number of ghost attributes */ for (it = 0; it < part->num_ghosts; it++) { ghost = t8_part_tree_get_ghost (part, it + part->first_ghost_id); ghost_attr_bytes += ghost->att_offset; /* att_offset temporarily stored the total size of the attributes */ /* The att_offset of the tree is the first_face plus the number of attribute * bytes used by previous trees minus the temp_offset */ ghost->att_offset = first_face - temp_offset + face_neigh_bytes + tree_attr_bytes - + num_ghost_attributes * sizeof (t8_attribute_info_struct_t); - num_ghost_attributes += ghost->num_attributes; + + num_attributes_of_ghosts[it].attribute_offset * sizeof (t8_attribute_info_struct_t); temp_offset += sizeof (t8_cghost_struct_t); } ghost_attr_bytes += num_ghost_attributes * sizeof (t8_attribute_info_struct_t); @@ -324,7 +394,11 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) attr = (t8_attribute_info_struct_t *) (part->first_tree + first_face + face_neigh_bytes); attr->attribute_offset = num_tree_attributes * sizeof (t8_attribute_info_struct_t); } - return num_ghost_attributes * sizeof (t8_attribute_info_struct_t); + if (num_ghost_attributes > 0) { + ghost = t8_part_tree_get_ghost (part, 0); + attr = (t8_attribute_info_struct_t *) T8_GHOST_FIRST_ATT (ghost); + attr->attribute_offset = num_ghost_attributes * sizeof (t8_attribute_info_struct_t); + } } void @@ -678,7 +752,7 @@ t8_cmesh_trees_add_attribute (const t8_cmesh_trees_t trees, const int proc, cons void t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc, const t8_stash_attribute_struct_t *attr, const t8_locidx_t local_ghost_id, - const size_t index, size_t *attribute_data_offset) + const size_t index) { t8_part_tree_t part; t8_cghost_t ghost; @@ -694,7 +768,7 @@ t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc ghost = t8_part_tree_get_ghost (part, local_ghost_id); attr_info = T8_GHOST_ATTR_INFO (ghost, index); - attr_info->attribute_offset = *attribute_data_offset; + //attr_info->attribute_offset = *attribute_data_offset; new_attr_data = T8_GHOST_ATTR (ghost, attr_info); memcpy (new_attr_data, attr->attr_data, attr->attr_size); @@ -704,10 +778,27 @@ t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc attr_info->package_id = attr->package_id; attr_info->attribute_size = attr->attr_size; +#if 0 *attribute_data_offset += attr->attr_size; if (index == (size_t) ghost->num_attributes - 1) { *attribute_data_offset -= ghost->num_attributes * sizeof (t8_attribute_info_struct_t); } +#endif + + /* If we are not yet at the last attribute of the part, + * get next attribute and set its offset*/ + if (!(index == (size_t) ghost->num_attributes - 1 && part->num_ghosts == local_ghost_id - 1)) { + /* Store offset of current attribute */ + const size_t offset = attr_info->attribute_offset; + attr_info = attr_info + 1; + attr_info->attribute_offset = offset + attr->attr_size; + /* if the current attribute was the last attribute of the tree + * the next attribute offset must be corrected by the size of + * the attribute infos of the current tree */ + if (index == (size_t) ghost->num_attributes - 1) { + attr_info->attribute_offset -= ghost->num_attributes * sizeof (t8_attribute_info_struct_t); + } + } } /* gets a key_id_pair as first argument and an attribute as second */ diff --git a/src/t8_cmesh/t8_cmesh_trees.h b/src/t8_cmesh/t8_cmesh_trees.h index 469da10694..e14a39bd6a 100644 --- a/src/t8_cmesh/t8_cmesh_trees.h +++ b/src/t8_cmesh/t8_cmesh_trees.h @@ -220,7 +220,7 @@ t8_cmesh_trees_start_part (t8_cmesh_trees_t trees, int proc, t8_locidx_t lfirst_ * \param [in,out] trees The trees structure to be updated. * \param [in] proc The number of the part to be finished. */ -size_t +void t8_cmesh_trees_finish_part (t8_cmesh_trees_t trees, int proc); /** Copy the tree_to_proc and ghost_to_proc arrays of one tree structure to @@ -435,7 +435,7 @@ t8_cmesh_trees_add_attribute (const t8_cmesh_trees_t trees, int proc, const t8_s void t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, int proc, const t8_stash_attribute_struct_t *attr, - t8_locidx_t local_ghost_id, size_t index, size_t *attribute_data_offset); + t8_locidx_t local_ghost_id, size_t index); /** Return the number of parts of a trees structure. * \param [in] trees The trees structure. diff --git a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx index 8d0a8ffc33..0f9b2b6c51 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx @@ -61,7 +61,7 @@ example_set *cmesh_example = (example_set *) new cmesh_cartesian_product_params< std::make_pair (periodic_eclasses.begin (), periodic_eclasses.end ()), std::make_pair (cmesh_params::my_comms.begin (), cmesh_params::my_comms.end ()), std::make_pair (cmesh_params::do_bcast.begin (), cmesh_params::do_bcast.end ()), - std::make_pair (cmesh_params::no_partition.begin (), cmesh_params::no_partition.end ()), + std::make_pair (cmesh_params::do_partition.begin (), cmesh_params::do_partition.end ()), std::make_pair (cmesh_params::periodic.begin (), cmesh_params::periodic.end ()), cmesh_wrapper, param_to_string, "t8_cmesh_new_hypercube_"); From 1f4eb08d8ec63b2a231b9070b01b5f243bc871eb Mon Sep 17 00:00:00 2001 From: Johannes Holke Date: Wed, 17 Jul 2024 16:55:35 +0200 Subject: [PATCH 02/15] Debugging Ghost attribute computation --- src/t8_cmesh/t8_cmesh_trees.cxx | 41 +++++++++++++------ src/t8_geometry/t8_geometry_with_vertices.cxx | 7 ++++ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/t8_cmesh/t8_cmesh_trees.cxx b/src/t8_cmesh/t8_cmesh_trees.cxx index aab245c355..8b495ef5b4 100644 --- a/src/t8_cmesh/t8_cmesh_trees.cxx +++ b/src/t8_cmesh/t8_cmesh_trees.cxx @@ -27,6 +27,7 @@ #include #include +#include #include "t8_cmesh_stash.h" #include "t8_cmesh_trees.h" @@ -272,9 +273,6 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) size_t tree_attr_bytes; size_t ghost_attr_bytes; size_t face_neigh_bytes; /* count the total number of bytes needed for face_neighbor information */ - size_t first_face; /* offset of the first face neighbor information */ - size_t first_tree; /* offset of the first tree */ - size_t first_ghost; /* offset of the first ghost */ size_t temp_offset; /* offset of the currently looked at tree/ghost */ size_t num_tree_attributes; /* total number of tree attributes */ t8_attribute_info_struct_t *attr; @@ -290,11 +288,11 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) num_tree_attributes = 0; tree_attr_bytes = ghost_attr_bytes = face_neigh_bytes = 0; /* The offset of the first tree */ - first_tree = 0; + const size_t first_tree = 0; /* The offset of the first ghost */ - first_ghost = first_tree + part->num_trees * sizeof (t8_ctree_struct_t); + const size_t first_ghost = first_tree + part->num_trees * sizeof (t8_ctree_struct_t); /* The offset of the first ghost face */ - first_face = first_ghost + part->num_ghosts * sizeof (t8_cghost_struct_t); + const size_t first_face = first_ghost + part->num_ghosts * sizeof (t8_cghost_struct_t); /* First pass through ghosts to set the face neighbor offsets. */ /* Additionally, we need to sort the number of attributes according to the global id in order @@ -336,6 +334,13 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) /* We now need to sort the offset sum by local id again. */ std::sort (num_attributes_of_ghosts.begin (), num_attributes_of_ghosts.end (), t8_compare_id_and_att_by_part_id); + t8_debugf ("Outputting vector: "); + for (const auto &att : num_attributes_of_ghosts) { + std::cout << att.global_id << ','; + std::cout << att.attribute_offset << ' '; + } + + t8_debugf ("DONE\n"); /* First pass through trees to set the face neighbor offsets */ temp_offset = 0; for (it = 0; it < part->num_trees; it++) { @@ -350,6 +355,7 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) /* Second pass through trees to set attribute offsets */ temp_offset = 0; + size_t next_tree_offset = 0; // Compute the offset of the next tree for (it = 0; it < part->num_trees; it++) { tree = t8_part_tree_get_tree (part, it + part->first_tree_id); tree_attr_bytes += tree->att_offset; /* att_offset temporarily stored the total size of the attributes */ @@ -357,22 +363,33 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) * bytes used by previous trees minus the temp_offset */ tree->att_offset = first_face - temp_offset + face_neigh_bytes + num_tree_attributes * sizeof (t8_attribute_info_struct_t); + T8_ASSERT (it == 0 || tree->att_offset == next_tree_offset); num_tree_attributes += tree->num_attributes; temp_offset += sizeof (t8_ctree_struct_t); + t8_debugf ("Offset of tree %i is %i\n", it, tree->att_offset); + next_tree_offset + = tree->att_offset + tree->num_attributes * sizeof (t8_attribute_info_struct_t) - sizeof (t8_ctree_struct_t); + t8_debugf ("Size of tree attributes: %i\n", tree->num_attributes * sizeof (t8_attribute_info_struct_t)); } + t8_debugf ("Size of tree: %i\n", sizeof (t8_ctree_struct_t)); tree_attr_bytes += num_tree_attributes * sizeof (t8_attribute_info_struct_t); /* Second pass through ghosts to set attribute offsets */ - temp_offset = first_ghost; - size_t num_ghost_attributes = 0; /* total number of ghost attributes */ + temp_offset = 0; + size_t num_ghost_attributes = 0; /* total number of ghost attributes */ + size_t first_ghost_offset = next_tree_offset; // Offset of the first Ghost attribute info for (it = 0; it < part->num_ghosts; it++) { ghost = t8_part_tree_get_ghost (part, it + part->first_ghost_id); ghost_attr_bytes += ghost->att_offset; /* att_offset temporarily stored the total size of the attributes */ - /* The att_offset of the tree is the first_face plus the number of attribute - * bytes used by previous trees minus the temp_offset */ - ghost->att_offset = first_face - temp_offset + face_neigh_bytes + tree_attr_bytes - + num_attributes_of_ghosts[it].attribute_offset * sizeof (t8_attribute_info_struct_t); + /* The att_offset of the ghost is the offset of the first ghost + the attribute + * offset of this ghost minus the size of all previous ghosts. */ + ghost->att_offset = first_ghost_offset + + num_attributes_of_ghosts[it].attribute_offset * sizeof (t8_attribute_info_struct_t) + - temp_offset; temp_offset += sizeof (t8_cghost_struct_t); + num_ghost_attributes += ghost->num_attributes; + t8_debugf ("Offset of ghost %i is %i\n", it, ghost->att_offset); + t8_debugf ("Size of ghost attributes is %i\n", ghost->num_attributes * sizeof (t8_attribute_info_struct_t)); } ghost_attr_bytes += num_ghost_attributes * sizeof (t8_attribute_info_struct_t); size_t attr_bytes = tree_attr_bytes + ghost_attr_bytes; diff --git a/src/t8_geometry/t8_geometry_with_vertices.cxx b/src/t8_geometry/t8_geometry_with_vertices.cxx index 9ef5d14c28..2738b1b3c5 100644 --- a/src/t8_geometry/t8_geometry_with_vertices.cxx +++ b/src/t8_geometry/t8_geometry_with_vertices.cxx @@ -59,6 +59,8 @@ t8_geometry_with_vertices::t8_geom_tree_negative_volume () const /* Only three dimensional eclass do have a volume */ return false; } + T8_ASSERT (t8_eclass_to_dimension[active_tree_class] + == 3); // Should we include 4 dimensional classes, we need to catch that here and implement it. T8_ASSERT (active_tree_class == T8_ECLASS_TET || active_tree_class == T8_ECLASS_HEX || active_tree_class == T8_ECLASS_PRISM || active_tree_class == T8_ECLASS_PYRAMID); @@ -103,6 +105,11 @@ t8_geometry_with_vertices::t8_geom_tree_negative_volume () const /* Compute sc_prod = */ sc_prod = t8_vec_dot (v_j, cross); + for (i = 0; i < 3; ++i) { + t8_debugf ("Vertex %i: %f %f %f\n", i, active_tree_vertices[3 * i], active_tree_vertices[3 * i + 1], + active_tree_vertices[3 * i + 2]); + } + T8_ASSERT (sc_prod != 0); return active_tree_class == T8_ECLASS_TET ? sc_prod > 0 : sc_prod < 0; } From 604f3aa1a75cd30cd0d2305b5c6663a657c76139 Mon Sep 17 00:00:00 2001 From: Johannes Holke Date: Thu, 18 Jul 2024 10:43:23 +0200 Subject: [PATCH 03/15] Update ghost att info offset computation and first att offset --- src/t8_cmesh/t8_cmesh_trees.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/t8_cmesh/t8_cmesh_trees.cxx b/src/t8_cmesh/t8_cmesh_trees.cxx index 8b495ef5b4..10530102a5 100644 --- a/src/t8_cmesh/t8_cmesh_trees.cxx +++ b/src/t8_cmesh/t8_cmesh_trees.cxx @@ -376,8 +376,10 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) /* Second pass through ghosts to set attribute offsets */ temp_offset = 0; - size_t num_ghost_attributes = 0; /* total number of ghost attributes */ - size_t first_ghost_offset = next_tree_offset; // Offset of the first Ghost attribute info + size_t num_ghost_attributes = 0; /* total number of ghost attributes */ + /* To get the offset of the first ghost attribute info, we have to add the bytes + * of all tree attributes. */ + size_t first_ghost_offset = next_tree_offset + tree_attr_bytes; for (it = 0; it < part->num_ghosts; it++) { ghost = t8_part_tree_get_ghost (part, it + part->first_ghost_id); ghost_attr_bytes += ghost->att_offset; /* att_offset temporarily stored the total size of the attributes */ @@ -413,7 +415,7 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) } if (num_ghost_attributes > 0) { ghost = t8_part_tree_get_ghost (part, 0); - attr = (t8_attribute_info_struct_t *) T8_GHOST_FIRST_ATT (ghost); + attr = (t8_attribute_info_struct_t *) (ghost + ghost->att_offset); attr->attribute_offset = num_ghost_attributes * sizeof (t8_attribute_info_struct_t); } } From 0e921a662bec6adac9aef8f57f5ab2e3cc7d1bac Mon Sep 17 00:00:00 2001 From: "Dreyer, Lukas" Date: Fri, 19 Jul 2024 15:19:04 +0200 Subject: [PATCH 04/15] Fixes for offset calculation --- src/t8_cmesh/t8_cmesh_commit.cxx | 7 ++- src/t8_cmesh/t8_cmesh_trees.cxx | 49 +++++++++++-------- src/t8_cmesh/t8_cmesh_trees.h | 6 ++- .../t8_cmesh/t8_gtest_multiple_attributes.cxx | 14 +++--- .../t8_cmesh_new_hypercube_param.hxx | 4 +- 5 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/t8_cmesh/t8_cmesh_commit.cxx b/src/t8_cmesh/t8_cmesh_commit.cxx index 5c6bb11b08..129eb68397 100644 --- a/src/t8_cmesh/t8_cmesh_commit.cxx +++ b/src/t8_cmesh/t8_cmesh_commit.cxx @@ -94,6 +94,7 @@ t8_cmesh_add_attributes (const t8_cmesh_t cmesh, sc_hash_t *ghost_ids) temp_facejoin = T8_ALLOC_ZERO (t8_ghost_facejoin_t, 1); + t8_locidx_t ghosts_inserted = 0; ltree = -1; for (si = 0, sj = 0; si < stash->attributes.elem_count; si++, sj++) { attribute = (t8_stash_attribute_struct_t *) sc_array_index (&stash->attributes, si); @@ -112,8 +113,12 @@ t8_cmesh_add_attributes (const t8_cmesh_t cmesh, sc_hash_t *ghost_ids) T8_ASSERT (ghost_ids != NULL); temp_facejoin->ghost_id = attribute->id; if (sc_hash_lookup (ghost_ids, temp_facejoin, (void ***) &facejoin_pp)) { + T8_ASSERT (sj == (*facejoin_pp)->attr_id); + if (sj == 0) { + ghosts_inserted++; + } /* attribute is on a ghost tree */ - t8_cmesh_trees_add_ghost_attribute (cmesh->trees, 0, attribute, (*facejoin_pp)->local_id, + t8_cmesh_trees_add_ghost_attribute (cmesh->trees, 0, attribute, (*facejoin_pp)->local_id, ghosts_inserted, (*facejoin_pp)->attr_id); (*facejoin_pp)->attr_id++; } diff --git a/src/t8_cmesh/t8_cmesh_trees.cxx b/src/t8_cmesh/t8_cmesh_trees.cxx index 10530102a5..26c67a7490 100644 --- a/src/t8_cmesh/t8_cmesh_trees.cxx +++ b/src/t8_cmesh/t8_cmesh_trees.cxx @@ -270,8 +270,8 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) t8_part_tree_t part; t8_ctree_t tree; t8_cghost_t ghost; - size_t tree_attr_bytes; - size_t ghost_attr_bytes; + size_t tree_attr_data_bytes; + size_t ghost_attr_data_bytes; size_t face_neigh_bytes; /* count the total number of bytes needed for face_neighbor information */ size_t temp_offset; /* offset of the currently looked at tree/ghost */ size_t num_tree_attributes; /* total number of tree attributes */ @@ -286,7 +286,7 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) T8_ASSERT (part != NULL); num_tree_attributes = 0; - tree_attr_bytes = ghost_attr_bytes = face_neigh_bytes = 0; + tree_attr_data_bytes = ghost_attr_data_bytes = face_neigh_bytes = 0; /* The offset of the first tree */ const size_t first_tree = 0; /* The offset of the first ghost */ @@ -358,7 +358,7 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) size_t next_tree_offset = 0; // Compute the offset of the next tree for (it = 0; it < part->num_trees; it++) { tree = t8_part_tree_get_tree (part, it + part->first_tree_id); - tree_attr_bytes += tree->att_offset; /* att_offset temporarily stored the total size of the attributes */ + tree_attr_data_bytes += tree->att_offset; /* att_offset temporarily stored the total size of the attributes */ /* The att_offset of the tree is the first_face plus the number of attribute * bytes used by previous trees minus the temp_offset */ tree->att_offset @@ -372,38 +372,45 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) t8_debugf ("Size of tree attributes: %i\n", tree->num_attributes * sizeof (t8_attribute_info_struct_t)); } t8_debugf ("Size of tree: %i\n", sizeof (t8_ctree_struct_t)); - tree_attr_bytes += num_tree_attributes * sizeof (t8_attribute_info_struct_t); + const size_t tree_attr_total_bytes = tree_attr_data_bytes + num_tree_attributes * sizeof (t8_attribute_info_struct_t); /* Second pass through ghosts to set attribute offsets */ temp_offset = 0; size_t num_ghost_attributes = 0; /* total number of ghost attributes */ /* To get the offset of the first ghost attribute info, we have to add the bytes * of all tree attributes. */ - size_t first_ghost_offset = next_tree_offset + tree_attr_bytes; + size_t first_ghost_offset = next_tree_offset + tree_attr_data_bytes; + t8_debugf ("next_tree_offset %li\n", next_tree_offset); + t8_debugf ("tree_attr_data_bytes %li\n", tree_attr_data_bytes); + t8_debugf ("first_ghost_offset %li\n", first_ghost_offset); for (it = 0; it < part->num_ghosts; it++) { ghost = t8_part_tree_get_ghost (part, it + part->first_ghost_id); - ghost_attr_bytes += ghost->att_offset; /* att_offset temporarily stored the total size of the attributes */ + t8_debugf ("global id of ghost %i\n", ghost->treeid); + ghost_attr_data_bytes += ghost->att_offset; /* att_offset temporarily stored the total size of the attributes */ /* The att_offset of the ghost is the offset of the first ghost + the attribute * offset of this ghost minus the size of all previous ghosts. */ + t8_debugf ("temp_offset %i\n", temp_offset); ghost->att_offset = first_ghost_offset + num_attributes_of_ghosts[it].attribute_offset * sizeof (t8_attribute_info_struct_t) - temp_offset; + t8_debugf ("Offset of ghost %i is %i\n", it, ghost->att_offset); + t8_debugf ("num_attributes_of_ghosts[it].attribute_offset %i\n", num_attributes_of_ghosts[it].attribute_offset); + t8_debugf ("num_attributes_of_ghosts[it].num_attributes %i\n", num_attributes_of_ghosts[it].num_attributes); temp_offset += sizeof (t8_cghost_struct_t); num_ghost_attributes += ghost->num_attributes; - t8_debugf ("Offset of ghost %i is %i\n", it, ghost->att_offset); - t8_debugf ("Size of ghost attributes is %i\n", ghost->num_attributes * sizeof (t8_attribute_info_struct_t)); } - ghost_attr_bytes += num_ghost_attributes * sizeof (t8_attribute_info_struct_t); - size_t attr_bytes = tree_attr_bytes + ghost_attr_bytes; + const size_t ghost_attr_total_bytes + = ghost_attr_data_bytes + num_ghost_attributes * sizeof (t8_attribute_info_struct_t); + const size_t attr_total_bytes = tree_attr_total_bytes + ghost_attr_total_bytes; /* Done setting all tree and ghost offsets */ - /* Allocate memory, first_face + attr_bytes + face_neigh_bytes gives the new total byte count */ + /* Allocate memory, first_face + attr_total_bytes + face_neigh_bytes gives the new total byte count */ #ifdef SC_ENABLE_REALLOC /* Since we use realloc and padding, memcmp will not work if we don't set everything to zero, solved with memset */ - SC_REALLOC (part->first_tree, char, first_face + attr_bytes + +face_neigh_bytes); - memset (part->first_tree + first_face, 0, attr_bytes + face_neigh_bytes) + SC_REALLOC (part->first_tree, char, first_face + attr_total_bytes + face_neigh_bytes); + memset (part->first_tree + first_face, 0, attr_total_bytes + face_neigh_bytes) #else - temp = T8_ALLOC_ZERO (char, first_face + attr_bytes + face_neigh_bytes); + temp = T8_ALLOC_ZERO (char, first_face + attr_total_bytes + face_neigh_bytes); memcpy (temp, part->first_tree, first_face); T8_FREE (part->first_tree); part->first_tree = temp; @@ -415,8 +422,10 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) } if (num_ghost_attributes > 0) { ghost = t8_part_tree_get_ghost (part, 0); - attr = (t8_attribute_info_struct_t *) (ghost + ghost->att_offset); + // t8_debugf("size of array:%li, offset: %li", first_face + attr_total_bytes + face_neigh_bytes, ) + attr = (t8_attribute_info_struct_t *) (part->first_tree + first_face + face_neigh_bytes + tree_attr_total_bytes); attr->attribute_offset = num_ghost_attributes * sizeof (t8_attribute_info_struct_t); + t8_debugf ("set attr_offset: %i\n", attr->attribute_offset); } } @@ -701,7 +710,7 @@ t8_cmesh_trees_copy_toproc (t8_cmesh_trees_t trees_dest, const t8_cmesh_trees_t void t8_cmesh_trees_init_attributes (const t8_cmesh_trees_t trees, const t8_locidx_t ltree_id, const size_t num_attributes, - const size_t attr_bytes) + const size_t attr_info_bytes) { int proc; t8_ctree_t tree; @@ -712,7 +721,7 @@ t8_cmesh_trees_init_attributes (const t8_cmesh_trees_t trees, const t8_locidx_t T8_ASSERT (proc >= 0 && proc < t8_cmesh_trees_get_num_procs (trees)); tree = t8_part_tree_get_tree (t8_cmesh_trees_get_part (trees, proc), ltree_id); - tree->att_offset = attr_bytes; /* This is only temporary until t8_cmesh_trees_finish_part + tree->att_offset = attr_info_bytes; /* This is only temporary until t8_cmesh_trees_finish_part is called */ tree->num_attributes = num_attributes; } @@ -771,7 +780,7 @@ t8_cmesh_trees_add_attribute (const t8_cmesh_trees_t trees, const int proc, cons void t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc, const t8_stash_attribute_struct_t *attr, const t8_locidx_t local_ghost_id, - const size_t index) + const t8_locidx_t ghosts_inserted, const size_t index) { t8_part_tree_t part; t8_cghost_t ghost; @@ -806,7 +815,7 @@ t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc /* If we are not yet at the last attribute of the part, * get next attribute and set its offset*/ - if (!(index == (size_t) ghost->num_attributes - 1 && part->num_ghosts == local_ghost_id - 1)) { + if (!(index == (size_t) ghost->num_attributes - 1 && part->num_ghosts == ghosts_inserted)) { /* Store offset of current attribute */ const size_t offset = attr_info->attribute_offset; attr_info = attr_info + 1; diff --git a/src/t8_cmesh/t8_cmesh_trees.h b/src/t8_cmesh/t8_cmesh_trees.h index e14a39bd6a..db868ddd9f 100644 --- a/src/t8_cmesh/t8_cmesh_trees.h +++ b/src/t8_cmesh/t8_cmesh_trees.h @@ -433,9 +433,13 @@ void t8_cmesh_trees_add_attribute (const t8_cmesh_trees_t trees, int proc, const t8_stash_attribute_struct_t *attr, t8_locidx_t tree_id, size_t index); +/** + * + * TODO: Document +*/ void t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, int proc, const t8_stash_attribute_struct_t *attr, - t8_locidx_t local_ghost_id, size_t index); + t8_locidx_t local_ghost_id, t8_locidx_t ghosts_inserted, size_t index); /** Return the number of parts of a trees structure. * \param [in] trees The trees structure. diff --git a/test/t8_cmesh/t8_gtest_multiple_attributes.cxx b/test/t8_cmesh/t8_gtest_multiple_attributes.cxx index 7e3fad23df..39462ebfb8 100644 --- a/test/t8_cmesh/t8_gtest_multiple_attributes.cxx +++ b/test/t8_cmesh/t8_gtest_multiple_attributes.cxx @@ -124,8 +124,7 @@ TEST_P (cmesh_multiple_attributes, multiple_attributes) t8_locidx_t num_ghosts = t8_cmesh_get_num_ghosts (cmesh_mult_at_from_stash); for (t8_locidx_t ltree_id = 0; ltree_id < num_local_trees + num_ghosts; ltree_id++) { const t8_gloidx_t gtree_id = t8_cmesh_get_global_id (cmesh_mult_at_from_stash, ltree_id); - const double *vertices_partition = (double *) t8_cmesh_get_attribute ( - cmesh_mult_at_from_stash, t8_get_package_id (), T8_CMESH_VERTICES_ATTRIBUTE_KEY, ltree_id); + const double *vertices_partition = t8_cmesh_get_tree_vertices (cmesh_mult_at_from_stash, ltree_id); const t8_eclass_t eclass = (ltree_id < num_local_trees) ? t8_cmesh_get_tree_class (cmesh_one_at, ltree_id) : t8_cmesh_get_ghost_class (cmesh_one_at, ltree_id - num_local_trees); @@ -133,9 +132,12 @@ TEST_P (cmesh_multiple_attributes, multiple_attributes) /* Compare vertices with reference vertices. */ for (int v_id = 0; v_id < 8; v_id++) { - EXPECT_EQ (vertices_partition[v_id * 3], vertices_ref[v_id * 3] + gtree_id); - EXPECT_EQ (vertices_partition[v_id * 3 + 1], vertices_ref[v_id * 3 + 1]); - EXPECT_EQ (vertices_partition[v_id * 3 + 2], vertices_ref[v_id * 3 + 2]); + EXPECT_EQ (vertices_partition[v_id * 3], vertices_ref[v_id * 3] + gtree_id) + << " at tree id " << ltree_id << " and vertex " << v_id; + EXPECT_EQ (vertices_partition[v_id * 3 + 1], vertices_ref[v_id * 3 + 1]) + << " at tree id " << ltree_id << " and rtex " << v_id; + EXPECT_EQ (vertices_partition[v_id * 3 + 2], vertices_ref[v_id * 3 + 2]) + << " at tree id " << ltree_id << " and vertex " << v_id; } /* Compare second attribute with global tree id. */ t8_locidx_t att; @@ -150,4 +152,4 @@ TEST_P (cmesh_multiple_attributes, multiple_attributes) } /* Test for different number of trees. */ -INSTANTIATE_TEST_SUITE_P (t8_gtest_multiple_attributes, cmesh_multiple_attributes, testing::Range (1, 4)); +INSTANTIATE_TEST_SUITE_P (t8_gtest_multiple_attributes, cmesh_multiple_attributes, testing::Range (1, 10)); diff --git a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx index 0f9b2b6c51..a7a6b94afe 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx @@ -61,7 +61,7 @@ example_set *cmesh_example = (example_set *) new cmesh_cartesian_product_params< std::make_pair (periodic_eclasses.begin (), periodic_eclasses.end ()), std::make_pair (cmesh_params::my_comms.begin (), cmesh_params::my_comms.end ()), std::make_pair (cmesh_params::do_bcast.begin (), cmesh_params::do_bcast.end ()), - std::make_pair (cmesh_params::do_partition.begin (), cmesh_params::do_partition.end ()), + std::make_pair (cmesh_params::partition.begin (), cmesh_params::partition.end ()), std::make_pair (cmesh_params::periodic.begin (), cmesh_params::periodic.end ()), cmesh_wrapper, param_to_string, "t8_cmesh_new_hypercube_"); @@ -72,7 +72,7 @@ example_set *cmesh_example_pyra = (example_set *) new cmesh_cartesian_product_pa std::make_pair (nonperiodic_eclasses.begin (), nonperiodic_eclasses.end ()), std::make_pair (cmesh_params::my_comms.begin (), cmesh_params::my_comms.end ()), std::make_pair (cmesh_params::do_bcast.begin (), cmesh_params::do_bcast.end ()), - std::make_pair (cmesh_params::no_partition.begin (), cmesh_params::no_partition.end ()), + std::make_pair (cmesh_params::partition.begin (), cmesh_params::partition.end ()), std::make_pair (cmesh_params::no_periodic.begin (), cmesh_params::no_periodic.end ()), cmesh_wrapper, param_to_string, "t8_cmesh_new_hypercube_"); } // namespace new_hypercube_cmesh From 6beab830db53d59f277735adce32501f72ad1b8a Mon Sep 17 00:00:00 2001 From: "Dreyer, Lukas" Date: Fri, 19 Jul 2024 15:19:35 +0200 Subject: [PATCH 05/15] Fix comparison operator --- src/t8_cmesh/t8_cmesh_trees.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/t8_cmesh/t8_cmesh_trees.cxx b/src/t8_cmesh/t8_cmesh_trees.cxx index 26c67a7490..02edba29dd 100644 --- a/src/t8_cmesh/t8_cmesh_trees.cxx +++ b/src/t8_cmesh/t8_cmesh_trees.cxx @@ -233,7 +233,7 @@ typedef struct bool t8_compare_id_and_att_by_global_id (t8_part_ghost_id_and_num_atts &id_A, t8_part_ghost_id_and_num_atts &id_B) { - return id_A.global_id - id_B.global_id; + return id_A.global_id < id_B.global_id; } /* Compare function for t8_part_ghost_id_and_num_atts to compare by local id. @@ -245,7 +245,7 @@ t8_compare_id_and_att_by_global_id (t8_part_ghost_id_and_num_atts &id_A, t8_part bool t8_compare_id_and_att_by_part_id (t8_part_ghost_id_and_num_atts &id_A, t8_part_ghost_id_and_num_atts &id_B) { - return id_A.part_ghost_id - id_B.part_ghost_id; + return id_A.part_ghost_id < id_B.part_ghost_id; } static std::vector From 6709bcd92ac570f1715d7351d9350f83ec45e87c Mon Sep 17 00:00:00 2001 From: "Dreyer, Lukas" Date: Fri, 19 Jul 2024 15:20:47 +0200 Subject: [PATCH 06/15] enable pyramid --- test/t8_cmesh/t8_gtest_cmesh_partition.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/t8_cmesh/t8_gtest_cmesh_partition.cxx b/test/t8_cmesh/t8_gtest_cmesh_partition.cxx index d5b41e8555..7c7f7667c7 100644 --- a/test/t8_cmesh/t8_gtest_cmesh_partition.cxx +++ b/test/t8_cmesh/t8_gtest_cmesh_partition.cxx @@ -45,7 +45,7 @@ class t8_cmesh_partition_class: public testing::TestWithParamname.find (std::string ("empty")); if (found != std::string::npos) { From dbe3d12b8df8f58545e7458595da9d2cc6f88759 Mon Sep 17 00:00:00 2001 From: "Dreyer, Lukas" Date: Fri, 19 Jul 2024 15:31:13 +0200 Subject: [PATCH 07/15] Fix compiler warning --- src/t8_cmesh/t8_cmesh_commit.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/t8_cmesh/t8_cmesh_commit.cxx b/src/t8_cmesh/t8_cmesh_commit.cxx index 129eb68397..ba0019cc60 100644 --- a/src/t8_cmesh/t8_cmesh_commit.cxx +++ b/src/t8_cmesh/t8_cmesh_commit.cxx @@ -113,7 +113,7 @@ t8_cmesh_add_attributes (const t8_cmesh_t cmesh, sc_hash_t *ghost_ids) T8_ASSERT (ghost_ids != NULL); temp_facejoin->ghost_id = attribute->id; if (sc_hash_lookup (ghost_ids, temp_facejoin, (void ***) &facejoin_pp)) { - T8_ASSERT (sj == (*facejoin_pp)->attr_id); + T8_ASSERT ((t8_locidx_t) sj == (t8_locidx_t) (*facejoin_pp)->attr_id); if (sj == 0) { ghosts_inserted++; } From 2fb47badc11d865a52758f630288754030da7b2c Mon Sep 17 00:00:00 2001 From: "Dreyer, Lukas" Date: Fri, 19 Jul 2024 15:37:54 +0200 Subject: [PATCH 08/15] make debug output pedantic --- src/t8_cmesh/t8_cmesh_trees.cxx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/t8_cmesh/t8_cmesh_trees.cxx b/src/t8_cmesh/t8_cmesh_trees.cxx index 02edba29dd..146c4a9680 100644 --- a/src/t8_cmesh/t8_cmesh_trees.cxx +++ b/src/t8_cmesh/t8_cmesh_trees.cxx @@ -366,12 +366,12 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) T8_ASSERT (it == 0 || tree->att_offset == next_tree_offset); num_tree_attributes += tree->num_attributes; temp_offset += sizeof (t8_ctree_struct_t); - t8_debugf ("Offset of tree %i is %i\n", it, tree->att_offset); + t8_debugf ("Offset of tree %i is %li\n", it, tree->att_offset); next_tree_offset = tree->att_offset + tree->num_attributes * sizeof (t8_attribute_info_struct_t) - sizeof (t8_ctree_struct_t); - t8_debugf ("Size of tree attributes: %i\n", tree->num_attributes * sizeof (t8_attribute_info_struct_t)); + t8_debugf ("Size of tree attributes: %li\n", tree->num_attributes * sizeof (t8_attribute_info_struct_t)); } - t8_debugf ("Size of tree: %i\n", sizeof (t8_ctree_struct_t)); + t8_debugf ("Size of tree: %li\n", sizeof (t8_ctree_struct_t)); const size_t tree_attr_total_bytes = tree_attr_data_bytes + num_tree_attributes * sizeof (t8_attribute_info_struct_t); /* Second pass through ghosts to set attribute offsets */ @@ -385,15 +385,15 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) t8_debugf ("first_ghost_offset %li\n", first_ghost_offset); for (it = 0; it < part->num_ghosts; it++) { ghost = t8_part_tree_get_ghost (part, it + part->first_ghost_id); - t8_debugf ("global id of ghost %i\n", ghost->treeid); + t8_debugf ("global id of ghost %li\n", ghost->treeid); ghost_attr_data_bytes += ghost->att_offset; /* att_offset temporarily stored the total size of the attributes */ /* The att_offset of the ghost is the offset of the first ghost + the attribute * offset of this ghost minus the size of all previous ghosts. */ - t8_debugf ("temp_offset %i\n", temp_offset); + t8_debugf ("temp_offset %li\n", temp_offset); ghost->att_offset = first_ghost_offset + num_attributes_of_ghosts[it].attribute_offset * sizeof (t8_attribute_info_struct_t) - temp_offset; - t8_debugf ("Offset of ghost %i is %i\n", it, ghost->att_offset); + t8_debugf ("Offset of ghost %i is %li\n", it, ghost->att_offset); t8_debugf ("num_attributes_of_ghosts[it].attribute_offset %i\n", num_attributes_of_ghosts[it].attribute_offset); t8_debugf ("num_attributes_of_ghosts[it].num_attributes %i\n", num_attributes_of_ghosts[it].num_attributes); temp_offset += sizeof (t8_cghost_struct_t); @@ -425,7 +425,7 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) // t8_debugf("size of array:%li, offset: %li", first_face + attr_total_bytes + face_neigh_bytes, ) attr = (t8_attribute_info_struct_t *) (part->first_tree + first_face + face_neigh_bytes + tree_attr_total_bytes); attr->attribute_offset = num_ghost_attributes * sizeof (t8_attribute_info_struct_t); - t8_debugf ("set attr_offset: %i\n", attr->attribute_offset); + t8_debugf ("set attr_offset: %li\n", attr->attribute_offset); } } From 6b1b13c701b505a65cb6cc7e958619f70d5321aa Mon Sep 17 00:00:00 2001 From: "Dreyer, Lukas" Date: Fri, 19 Jul 2024 16:38:02 +0200 Subject: [PATCH 09/15] fix errors --- src/t8_cmesh/t8_cmesh_examples.cxx | 2 +- src/t8_forest/t8_forest.cxx | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/t8_cmesh/t8_cmesh_examples.cxx b/src/t8_cmesh/t8_cmesh_examples.cxx index 45260908cc..d034b9356c 100644 --- a/src/t8_cmesh/t8_cmesh_examples.cxx +++ b/src/t8_cmesh/t8_cmesh_examples.cxx @@ -370,7 +370,7 @@ t8_cmesh_new_pyramid (sc_MPI_Comm comm) /* Use linear geometry */ t8_cmesh_register_geometry (cmesh, 3); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_PYRAMID); - t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 15); + t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 5); t8_cmesh_commit (cmesh, comm); return cmesh; } diff --git a/src/t8_forest/t8_forest.cxx b/src/t8_forest/t8_forest.cxx index c65c2dc14d..77226ce878 100644 --- a/src/t8_forest/t8_forest.cxx +++ b/src/t8_forest/t8_forest.cxx @@ -4158,6 +4158,17 @@ t8_forest_new_uniform (t8_cmesh_t cmesh, t8_scheme_cxx_t *scheme, const int leve /* Initialize the forest */ t8_forest_init (&forest); + + if (cmesh->set_partition) { + t8_cmesh_t cmesh_uniform_partition; + t8_cmesh_init (&cmesh_uniform_partition); + t8_cmesh_set_derive (cmesh_uniform_partition, cmesh); + t8_scheme_cxx_ref (scheme); + t8_cmesh_set_partition_uniform (cmesh_uniform_partition, level, scheme); + t8_cmesh_commit (cmesh_uniform_partition, comm); + cmesh = cmesh_uniform_partition; + } + /* Set the cmesh, scheme and level */ t8_forest_set_cmesh (forest, cmesh, comm); t8_forest_set_scheme (forest, scheme); From 2370cd207b9a2cadd040e16a835f1d1fa76dca10 Mon Sep 17 00:00:00 2001 From: "Dreyer, Lukas" Date: Mon, 22 Jul 2024 10:18:10 +0200 Subject: [PATCH 10/15] Disable cmesh_set_join test for partitioned cmeshes --- test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx b/test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx index d6fbd6d773..190d51dc43 100644 --- a/test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx +++ b/test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx @@ -445,11 +445,15 @@ class t8_cmesh_set_join_by_vertices_class: public testing::TestWithParamname.find (std::string ("bigmesh")); if (found != std::string::npos) { - /* skip bigmeshes as they get to large */ + /* skip bigmeshes as they do not have vertices from which to build the connectivity */ GTEST_SKIP (); } cmesh = GetParam ()->cmesh_create (); + if (cmesh->set_partition) { + /* skip partitioned cmeshes, as they do not have all necessary vertex information for the neighbors */ + GTEST_SKIP (); + } } void From b33836d66352965aeefec652d3fa3941501095aa Mon Sep 17 00:00:00 2001 From: Johannes Holke Date: Mon, 22 Jul 2024 15:57:57 +0200 Subject: [PATCH 11/15] Update comments --- src/t8_cmesh/t8_cmesh_trees.cxx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/t8_cmesh/t8_cmesh_trees.cxx b/src/t8_cmesh/t8_cmesh_trees.cxx index 146c4a9680..3474209c37 100644 --- a/src/t8_cmesh/t8_cmesh_trees.cxx +++ b/src/t8_cmesh/t8_cmesh_trees.cxx @@ -226,9 +226,8 @@ typedef struct /* Compare function for t8_part_ghost_id_and_num_atts to compare by global id. * -* Return < 0 if global_id of if_A < global_id of id_B -* Return = 0 if equal -* Return > 0 if > +* Return True if global_id of if_A < global_id of id_B +* Return False otherwise * */ bool t8_compare_id_and_att_by_global_id (t8_part_ghost_id_and_num_atts &id_A, t8_part_ghost_id_and_num_atts &id_B) @@ -238,9 +237,8 @@ t8_compare_id_and_att_by_global_id (t8_part_ghost_id_and_num_atts &id_A, t8_part /* Compare function for t8_part_ghost_id_and_num_atts to compare by local id. * -* Return < 0 if local id of if_A < local id of id_B -* Return = 0 if equal -* Return > 0 if > +* Return True if local id of if_A < local id of id_B +* Return False otherwise * */ bool t8_compare_id_and_att_by_part_id (t8_part_ghost_id_and_num_atts &id_A, t8_part_ghost_id_and_num_atts &id_B) @@ -251,7 +249,6 @@ t8_compare_id_and_att_by_part_id (t8_part_ghost_id_and_num_atts &id_A, t8_part_g static std::vector t8_cmesh_allocate_ghost_num_atts_array (t8_locidx_t part_num_ghosts) { - // The offset sum will start at 0 so we need one additional entry. std::vector num_attributes_of_ghosts (part_num_ghosts); return num_attributes_of_ghosts; } From 0a92d23cb40e0662523169191ca185e4da36cb1f Mon Sep 17 00:00:00 2001 From: Johannes Holke Date: Mon, 22 Jul 2024 16:02:45 +0200 Subject: [PATCH 12/15] Clean up - remove debug prints and comments --- src/t8_cmesh/t8_cmesh_trees.cxx | 20 ------------------- src/t8_geometry/t8_geometry_with_vertices.cxx | 5 ----- test/t8_cmesh/t8_gtest_cmesh_partition.cxx | 1 - 3 files changed, 26 deletions(-) diff --git a/src/t8_cmesh/t8_cmesh_trees.cxx b/src/t8_cmesh/t8_cmesh_trees.cxx index 3474209c37..9beee8ec12 100644 --- a/src/t8_cmesh/t8_cmesh_trees.cxx +++ b/src/t8_cmesh/t8_cmesh_trees.cxx @@ -331,13 +331,6 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) /* We now need to sort the offset sum by local id again. */ std::sort (num_attributes_of_ghosts.begin (), num_attributes_of_ghosts.end (), t8_compare_id_and_att_by_part_id); - t8_debugf ("Outputting vector: "); - for (const auto &att : num_attributes_of_ghosts) { - std::cout << att.global_id << ','; - std::cout << att.attribute_offset << ' '; - } - - t8_debugf ("DONE\n"); /* First pass through trees to set the face neighbor offsets */ temp_offset = 0; for (it = 0; it < part->num_trees; it++) { @@ -363,12 +356,9 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) T8_ASSERT (it == 0 || tree->att_offset == next_tree_offset); num_tree_attributes += tree->num_attributes; temp_offset += sizeof (t8_ctree_struct_t); - t8_debugf ("Offset of tree %i is %li\n", it, tree->att_offset); next_tree_offset = tree->att_offset + tree->num_attributes * sizeof (t8_attribute_info_struct_t) - sizeof (t8_ctree_struct_t); - t8_debugf ("Size of tree attributes: %li\n", tree->num_attributes * sizeof (t8_attribute_info_struct_t)); } - t8_debugf ("Size of tree: %li\n", sizeof (t8_ctree_struct_t)); const size_t tree_attr_total_bytes = tree_attr_data_bytes + num_tree_attributes * sizeof (t8_attribute_info_struct_t); /* Second pass through ghosts to set attribute offsets */ @@ -377,22 +367,14 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) /* To get the offset of the first ghost attribute info, we have to add the bytes * of all tree attributes. */ size_t first_ghost_offset = next_tree_offset + tree_attr_data_bytes; - t8_debugf ("next_tree_offset %li\n", next_tree_offset); - t8_debugf ("tree_attr_data_bytes %li\n", tree_attr_data_bytes); - t8_debugf ("first_ghost_offset %li\n", first_ghost_offset); for (it = 0; it < part->num_ghosts; it++) { ghost = t8_part_tree_get_ghost (part, it + part->first_ghost_id); - t8_debugf ("global id of ghost %li\n", ghost->treeid); ghost_attr_data_bytes += ghost->att_offset; /* att_offset temporarily stored the total size of the attributes */ /* The att_offset of the ghost is the offset of the first ghost + the attribute * offset of this ghost minus the size of all previous ghosts. */ - t8_debugf ("temp_offset %li\n", temp_offset); ghost->att_offset = first_ghost_offset + num_attributes_of_ghosts[it].attribute_offset * sizeof (t8_attribute_info_struct_t) - temp_offset; - t8_debugf ("Offset of ghost %i is %li\n", it, ghost->att_offset); - t8_debugf ("num_attributes_of_ghosts[it].attribute_offset %i\n", num_attributes_of_ghosts[it].attribute_offset); - t8_debugf ("num_attributes_of_ghosts[it].num_attributes %i\n", num_attributes_of_ghosts[it].num_attributes); temp_offset += sizeof (t8_cghost_struct_t); num_ghost_attributes += ghost->num_attributes; } @@ -422,7 +404,6 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) // t8_debugf("size of array:%li, offset: %li", first_face + attr_total_bytes + face_neigh_bytes, ) attr = (t8_attribute_info_struct_t *) (part->first_tree + first_face + face_neigh_bytes + tree_attr_total_bytes); attr->attribute_offset = num_ghost_attributes * sizeof (t8_attribute_info_struct_t); - t8_debugf ("set attr_offset: %li\n", attr->attribute_offset); } } @@ -793,7 +774,6 @@ t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc ghost = t8_part_tree_get_ghost (part, local_ghost_id); attr_info = T8_GHOST_ATTR_INFO (ghost, index); - //attr_info->attribute_offset = *attribute_data_offset; new_attr_data = T8_GHOST_ATTR (ghost, attr_info); memcpy (new_attr_data, attr->attr_data, attr->attr_size); diff --git a/src/t8_geometry/t8_geometry_with_vertices.cxx b/src/t8_geometry/t8_geometry_with_vertices.cxx index 2738b1b3c5..950057f8ca 100644 --- a/src/t8_geometry/t8_geometry_with_vertices.cxx +++ b/src/t8_geometry/t8_geometry_with_vertices.cxx @@ -105,11 +105,6 @@ t8_geometry_with_vertices::t8_geom_tree_negative_volume () const /* Compute sc_prod = */ sc_prod = t8_vec_dot (v_j, cross); - for (i = 0; i < 3; ++i) { - t8_debugf ("Vertex %i: %f %f %f\n", i, active_tree_vertices[3 * i], active_tree_vertices[3 * i + 1], - active_tree_vertices[3 * i + 2]); - } - T8_ASSERT (sc_prod != 0); return active_tree_class == T8_ECLASS_TET ? sc_prod > 0 : sc_prod < 0; } diff --git a/test/t8_cmesh/t8_gtest_cmesh_partition.cxx b/test/t8_cmesh/t8_gtest_cmesh_partition.cxx index 7c7f7667c7..63e8ed9ceb 100644 --- a/test/t8_cmesh/t8_gtest_cmesh_partition.cxx +++ b/test/t8_cmesh/t8_gtest_cmesh_partition.cxx @@ -45,7 +45,6 @@ class t8_cmesh_partition_class: public testing::TestWithParamname.find (std::string ("empty")); if (found != std::string::npos) { From a179fb8bb8f28ab4659a456007adabdd54b73f70 Mon Sep 17 00:00:00 2001 From: "Dreyer, Lukas" Date: Fri, 13 Sep 2024 14:41:04 +0200 Subject: [PATCH 13/15] Remove dead code --- src/t8_cmesh/t8_cmesh_trees.cxx | 8 -------- test/t8_cmesh/t8_gtest_cmesh_partition.cxx | 9 +-------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/t8_cmesh/t8_cmesh_trees.cxx b/src/t8_cmesh/t8_cmesh_trees.cxx index c6251df216..7290316624 100644 --- a/src/t8_cmesh/t8_cmesh_trees.cxx +++ b/src/t8_cmesh/t8_cmesh_trees.cxx @@ -401,7 +401,6 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) } if (num_ghost_attributes > 0) { ghost = t8_part_tree_get_ghost (part, 0); - // t8_debugf("size of array:%li, offset: %li", first_face + attr_total_bytes + face_neigh_bytes, ) attr = (t8_attribute_info_struct_t *) (part->first_tree + first_face + face_neigh_bytes + tree_attr_total_bytes); attr->attribute_offset = num_ghost_attributes * sizeof (t8_attribute_info_struct_t); } @@ -783,13 +782,6 @@ t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc attr_info->package_id = attr->package_id; attr_info->attribute_size = attr->attr_size; -#if 0 - *attribute_data_offset += attr->attr_size; - if (index == (size_t) ghost->num_attributes - 1) { - *attribute_data_offset -= ghost->num_attributes * sizeof (t8_attribute_info_struct_t); - } -#endif - /* If we are not yet at the last attribute of the part, * get next attribute and set its offset*/ if (!(index == (size_t) ghost->num_attributes - 1 && part->num_ghosts == ghosts_inserted)) { diff --git a/test/t8_cmesh/t8_gtest_cmesh_partition.cxx b/test/t8_cmesh/t8_gtest_cmesh_partition.cxx index 63e8ed9ceb..019f374ac4 100644 --- a/test/t8_cmesh/t8_gtest_cmesh_partition.cxx +++ b/test/t8_cmesh/t8_gtest_cmesh_partition.cxx @@ -39,14 +39,7 @@ class t8_cmesh_partition_class: public testing::TestWithParamparam_to_string (name); - - size_t found = name.find (std::string ("t8_cmesh_new_from_class__Pyramid_sc_MPI_COMM_WORLD")); - if (found != std::string::npos) { - /* Test not working for pyramids */ - } - found = GetParam ()->name.find (std::string ("empty")); + size_t found = GetParam ()->name.find (std::string ("empty")); if (found != std::string::npos) { /* Tests not working for empty cmeshes */ GTEST_SKIP (); From 37b835cf044ac0ec92b61b8786535a8d695974c6 Mon Sep 17 00:00:00 2001 From: "Dreyer, Lukas" Date: Fri, 13 Sep 2024 14:41:47 +0200 Subject: [PATCH 14/15] Document function and remove unused parameter --- src/t8_cmesh/t8_cmesh_trees.cxx | 8 ++++---- src/t8_cmesh/t8_cmesh_trees.h | 14 ++++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/t8_cmesh/t8_cmesh_trees.cxx b/src/t8_cmesh/t8_cmesh_trees.cxx index 7290316624..9c136c554f 100644 --- a/src/t8_cmesh/t8_cmesh_trees.cxx +++ b/src/t8_cmesh/t8_cmesh_trees.cxx @@ -755,9 +755,9 @@ t8_cmesh_trees_add_attribute (const t8_cmesh_trees_t trees, const int proc, cons } void -t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc, - const t8_stash_attribute_struct_t *attr, const t8_locidx_t local_ghost_id, - const t8_locidx_t ghosts_inserted, const size_t index) +t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const t8_stash_attribute_struct_t *attr, + const t8_locidx_t local_ghost_id, const t8_locidx_t ghosts_inserted, + const size_t index) { t8_part_tree_t part; t8_cghost_t ghost; @@ -769,7 +769,7 @@ t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc T8_ASSERT (attr->attr_data != NULL || attr->attr_size == 0); T8_ASSERT (attr->id >= 0); - part = t8_cmesh_trees_get_part (trees, proc); + part = t8_cmesh_trees_get_part (trees, 0); ghost = t8_part_tree_get_ghost (part, local_ghost_id); attr_info = T8_GHOST_ATTR_INFO (ghost, index); diff --git a/src/t8_cmesh/t8_cmesh_trees.h b/src/t8_cmesh/t8_cmesh_trees.h index 6036e2eaf7..60bbc74ac7 100644 --- a/src/t8_cmesh/t8_cmesh_trees.h +++ b/src/t8_cmesh/t8_cmesh_trees.h @@ -433,12 +433,18 @@ void t8_cmesh_trees_add_attribute (const t8_cmesh_trees_t trees, int proc, const t8_stash_attribute_struct_t *attr, t8_locidx_t tree_id, size_t index); -/** - * - * TODO: Document +/** Add the next ghost attribute from stash to the correct position in the char pointer structure + * Since it is created from stash, all attributes are added to part 0. + * The following attribute offset gets updated already. + * \param [in,out] trees The trees structure, whose char array is updated. + * \param [in] attr The stash attribute that is added. + * \param [in] local_ghost_id The local ghost id. + * \param [in] ghosts_inserted The number of ghost that were already inserted, so that we do not write over the end. + * \param [in] index The attribute index of the attribute to be added. */ + void -t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, int proc, const t8_stash_attribute_struct_t *attr, +t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const t8_stash_attribute_struct_t *attr, t8_locidx_t local_ghost_id, t8_locidx_t ghosts_inserted, size_t index); /** Return the number of parts of a trees structure. From 2a7903f55ed0c4190e3cd4f15bd324f05d3d3e66 Mon Sep 17 00:00:00 2001 From: "Dreyer, Lukas" Date: Fri, 13 Sep 2024 14:46:19 +0200 Subject: [PATCH 15/15] Adapt function call to new interface --- src/t8_cmesh/t8_cmesh_commit.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/t8_cmesh/t8_cmesh_commit.cxx b/src/t8_cmesh/t8_cmesh_commit.cxx index ba0019cc60..1e2abb2089 100644 --- a/src/t8_cmesh/t8_cmesh_commit.cxx +++ b/src/t8_cmesh/t8_cmesh_commit.cxx @@ -118,7 +118,7 @@ t8_cmesh_add_attributes (const t8_cmesh_t cmesh, sc_hash_t *ghost_ids) ghosts_inserted++; } /* attribute is on a ghost tree */ - t8_cmesh_trees_add_ghost_attribute (cmesh->trees, 0, attribute, (*facejoin_pp)->local_id, ghosts_inserted, + t8_cmesh_trees_add_ghost_attribute (cmesh->trees, attribute, (*facejoin_pp)->local_id, ghosts_inserted, (*facejoin_pp)->attr_id); (*facejoin_pp)->attr_id++; }