Skip to content

Commit

Permalink
IOSS: Reduce memory usage of line decomp
Browse files Browse the repository at this point in the history
  • Loading branch information
gdsjaar committed Jun 12, 2024
1 parent 8ef4dbf commit 2d2a558
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 20 deletions.
3 changes: 2 additions & 1 deletion packages/seacas/libraries/ioss/src/Ioss_ChainGenerator.C
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@ namespace Ioss {
{
debug = debug_level;
size_t numel = region.get_property("element_count").get_int();
Ioss::chain_t<INT> element_chains(numel);

// Determine which element block(s) are adjacent to the faceset specifying "lines"
// The `adjacent_blocks` contains the names of all element blocks that are adjacent to the
Expand Down Expand Up @@ -225,6 +224,7 @@ namespace Ioss {
Ioss::FaceGenerator face_generator(region);
face_generator.generate_block_faces(adjacent_blocks, (INT)0, true);

Ioss::chain_t<INT> element_chains(numel);
for (const auto *block : adjacent_blocks) {
// Get the offset into the element_chains vector...
auto offset = block->get_offset() + 1;
Expand All @@ -239,6 +239,7 @@ namespace Ioss {
connectivity_t face_connectivity(count);
generate_face_connectivity(face_generator.faces(block), static_cast<int>(offset),
face_connectivity);
face_generator.clear(block);

// For each face on the "front" (at the beginning the boundary sideset faces)
// Set `element_chains` to the `face` "ID"
Expand Down
43 changes: 28 additions & 15 deletions packages/seacas/libraries/ioss/src/Ioss_FaceGenerator.C
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,7 @@ namespace {
eb->get_field_data("connectivity_raw", connectivity);

std::vector<INT> elem_ids;
if (local_ids) {
elem_ids.resize(eb->entity_count());
std::iota(elem_ids.begin(), elem_ids.end(), static_cast<INT>(eb->get_offset() + 1));
}
else {
if (!local_ids) {
eb->get_field_data("ids", elem_ids);
}

Expand All @@ -90,17 +86,18 @@ namespace {
size_t num_elem = eb->entity_count();

for (size_t elem = 0, offset = 0; elem < num_elem; elem++, offset += num_node_per_elem) {
auto elem_id = local_ids ? eb->get_offset() + elem + 1 : elem_ids[elem];
for (int face = 0; face < num_face_per_elem; face++) {
size_t id = 0;
assert(face_node_count[face] <= 4);
std::array<size_t, 4> conn = {{0, 0, 0, 0}};
for (int j = 0; j < face_node_count[face]; j++) {
size_t fnode = offset + face_conn[face][j];
size_t lnode = connectivity[fnode]; // local since "connectivity_raw"
conn[j] = ids[lnode - 1]; // Convert to global
conn[j] = local_ids ? lnode : ids[lnode - 1]; // Convert to global
id += hash_ids[lnode - 1];
}
create_face(faces, id, conn, elem_ids[elem], face);
create_face(faces, id, conn, elem_id, face);
}
}
}
Expand Down Expand Up @@ -333,6 +330,12 @@ namespace Ioss {
return faces_[name];
}

void FaceGenerator::clear(const Ioss::ElementBlock *block)
{
auto name = block->name();
faces_[name].clear();
}

template IOSS_EXPORT void FaceGenerator::generate_faces(int, bool, bool);
template IOSS_EXPORT void FaceGenerator::generate_faces(int64_t, bool, bool);

Expand All @@ -356,6 +359,14 @@ namespace Ioss {
}
}

void FaceGenerator::hash_local_node_ids(size_t count)
{
hashIds_.reserve(count);
for (size_t i = 1; i <= count; i++) {
hashIds_.push_back(id_hash(i));
}
}

template IOSS_EXPORT void FaceGenerator::generate_block_faces(const Ioss::ElementBlockContainer &,
int, bool);
template IOSS_EXPORT void FaceGenerator::generate_block_faces(const Ioss::ElementBlockContainer &,
Expand All @@ -368,27 +379,27 @@ namespace Ioss {
// Convert ids into hashed-ids
Ioss::NodeBlock *nb = region_.get_node_blocks()[0];

#if DO_TIMING
auto starth = std::chrono::steady_clock::now();
#endif
std::vector<INT> ids;
if (local_ids) {
ids.resize(nb->entity_count());
std::iota(ids.begin(), ids.end(), 1);
hash_local_node_ids(nb->entity_count());
}
else {
nb->get_field_data("ids", ids);
hash_node_ids(ids);
}
#if DO_TIMING
auto starth = std::chrono::steady_clock::now();
#endif
hash_node_ids(ids);
#if DO_TIMING
auto endh = std::chrono::steady_clock::now();
auto endh = std::chrono::steady_clock::now();
#endif

for (const auto &eb : ebs) {
const std::string &name = eb->name();
size_t numel = eb->entity_count();
size_t reserve = 3.2 * numel;
size_t reserve = 2.0 * numel;
faces_[name].reserve(reserve);
faces_[name].max_load_factor(0.9);
internal_generate_faces(eb, faces_[name], ids, hashIds_, local_ids, (INT)0);
}

Expand Down Expand Up @@ -426,6 +437,7 @@ namespace Ioss {
fmt::print("Total time: \t{:.6} ms\n\n",
std::chrono::duration<double, std::milli>(endp - starth).count());
#endif
hashIds_.clear();
}

template <typename INT> void FaceGenerator::generate_model_faces(INT /*dummy*/, bool local_ids)
Expand Down Expand Up @@ -487,6 +499,7 @@ namespace Ioss {
fmt::print("Total time: \t{:.3f} ms\n\n",
std::chrono::duration<double, std::milli>(endp - starth).count());
#endif
hashIds_.clear();
}
} // namespace Ioss

Expand Down
12 changes: 8 additions & 4 deletions packages/seacas/libraries/ioss/src/Ioss_FaceGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ namespace Ioss {
#if defined FG_USE_STD
using FaceUnorderedSet = std::unordered_set<Face, FaceHash, FaceEqual>;
#elif defined FG_USE_HOPSCOTCH
using FaceUnorderedSet = tsl::hopscotch_set<Face, FaceHash, FaceEqual>;
// using FaceUnorderedSet = tsl::hopscotch_pg_set<Face, FaceHash, FaceEqual>;
//using FaceUnorderedSet = tsl::hopscotch_set<Face, FaceHash, FaceEqual>;
using FaceUnorderedSet = tsl::hopscotch_pg_set<Face, FaceHash, FaceEqual>;
#elif defined FG_USE_ROBIN
using FaceUnorderedSet = tsl::robin_set<Face, FaceHash, FaceEqual>;
// using FaceUnorderedSet = tsl::robin_pg_set<Face, FaceHash, FaceEqual>;
// using FaceUnorderedSet = tsl::robin_set<Face, FaceHash, FaceEqual>;
using FaceUnorderedSet = tsl::robin_pg_set<Face, FaceHash, FaceEqual>;
#endif
class IOSS_EXPORT FaceGenerator
{
Expand All @@ -130,11 +130,15 @@ namespace Ioss {
FaceUnorderedSet &faces(const std::string &name = "ALL") { return faces_[name]; }
FaceUnorderedSet &faces(const ElementBlock *block);

void clear(const std::string &name) {faces_[name].clear();}
void clear(const ElementBlock *block);

//! Given a local node id (0-based), return the hashed value.
size_t node_id_hash(size_t local_node_id) const { return hashIds_[local_node_id]; }

private:
template <typename INT> void hash_node_ids(const std::vector<INT> &node_ids);
void hash_local_node_ids(size_t count);
template <typename INT> void generate_model_faces(INT /*dummy*/, bool local_ids);

Ioss::Region &region_;
Expand Down

0 comments on commit 2d2a558

Please sign in to comment.