Merge pull request #1504 from smharper/distrib_init

Speed up distribcell initialization
This commit is contained in:
Paul Romano 2020-03-04 07:05:36 -06:00 committed by GitHub
commit a90af303d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 11 deletions

View file

@ -86,11 +86,15 @@ void count_cell_instances(int32_t univ_indx);
//! Recursively search through universes and count universe instances.
//! \param search_univ The index of the universe to begin searching from.
//! \param target_univ_id The ID of the universe to be counted.
//! \param univ_count_memo Memoized counts that make this function faster for
//! large systems. The first call to this function for each target_univ_id
//! should start with an empty memo.
//! \return The number of instances of target_univ_id in the geometry tree under
//! search_univ.
//==============================================================================
int count_universe_instances(int32_t search_univ, int32_t target_univ_id);
int count_universe_instances(int32_t search_univ, int32_t target_univ_id,
std::unordered_map<int32_t, int32_t>& univ_count_memo);
//==============================================================================
//! Build a character array representing the path to a distribcell instance.

View file

@ -77,7 +77,8 @@ public:
{offsets_.resize(n_maps * universes_.size(), C_NONE);}
//! Populate the distribcell offset tables.
int32_t fill_offset_table(int32_t offset, int32_t target_univ_id, int map);
int32_t fill_offset_table(int32_t offset, int32_t target_univ_id, int map,
std::unordered_map<int32_t, int32_t>& univ_count_memo);
//! \brief Check lattice indices.
//! \param i_xyz[3] The indices for a lattice tile.

View file

@ -385,8 +385,10 @@ prepare_distribcell()
}
// Fill the cell and lattice offset tables.
#pragma omp parallel for
for (int map = 0; map < target_univ_ids.size(); map++) {
auto target_univ_id = target_univ_ids[map];
std::unordered_map<int32_t, int32_t> univ_count_memo;
for (const auto& univ : model::universes) {
int32_t offset = 0;
for (int32_t cell_indx : univ->cells_) {
@ -395,11 +397,13 @@ prepare_distribcell()
if (c.type_ == Fill::UNIVERSE) {
c.offset_[map] = offset;
int32_t search_univ = c.fill_;
offset += count_universe_instances(search_univ, target_univ_id);
offset += count_universe_instances(search_univ, target_univ_id,
univ_count_memo);
} else if (c.type_ == Fill::LATTICE) {
Lattice& lat = *model::lattices[c.fill_];
offset = lat.fill_offset_table(offset, target_univ_id, map);
offset = lat.fill_offset_table(offset, target_univ_id, map,
univ_count_memo);
}
}
}
@ -411,7 +415,6 @@ prepare_distribcell()
void
count_cell_instances(int32_t univ_indx)
{
const auto univ_counts = model::universe_cell_counts.find(univ_indx);
if (univ_counts != model::universe_cell_counts.end()) {
for (const auto& it : univ_counts->second) {
@ -442,30 +445,42 @@ count_cell_instances(int32_t univ_indx)
//==============================================================================
int
count_universe_instances(int32_t search_univ, int32_t target_univ_id)
count_universe_instances(int32_t search_univ, int32_t target_univ_id,
std::unordered_map<int32_t, int32_t>& univ_count_memo)
{
// If this is the target, it can't contain itself.
// If this is the target, it can't contain itself.
if (model::universes[search_univ]->id_ == target_univ_id) {
return 1;
}
// If we have already counted the number of instances, reuse that value.
auto search = univ_count_memo.find(search_univ);
if (search != univ_count_memo.end()) {
return search->second;
}
int count {0};
for (int32_t cell_indx : model::universes[search_univ]->cells_) {
Cell& c = *model::cells[cell_indx];
if (c.type_ == Fill::UNIVERSE) {
int32_t next_univ = c.fill_;
count += count_universe_instances(next_univ, target_univ_id);
count += count_universe_instances(next_univ, target_univ_id,
univ_count_memo);
} else if (c.type_ == Fill::LATTICE) {
Lattice& lat = *model::lattices[c.fill_];
for (auto it = lat.begin(); it != lat.end(); ++it) {
int32_t next_univ = *it;
count += count_universe_instances(next_univ, target_univ_id);
count += count_universe_instances(next_univ, target_univ_id,
univ_count_memo);
}
}
}
// Remember the number of instances in this universe.
univ_count_memo[search_univ] = count;
return count;
}

View file

@ -93,11 +93,12 @@ Lattice::adjust_indices()
//==============================================================================
int32_t
Lattice::fill_offset_table(int32_t offset, int32_t target_univ_id, int map)
Lattice::fill_offset_table(int32_t offset, int32_t target_univ_id, int map,
std::unordered_map<int32_t, int32_t>& univ_count_memo)
{
for (LatticeIter it = begin(); it != end(); ++it) {
offsets_[map * universes_.size() + it.indx_] = offset;
offset += count_universe_instances(*it, target_univ_id);
offset += count_universe_instances(*it, target_univ_id, univ_count_memo);
}
return offset;
}