Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid unnecessary locally_relevant_dofs in mg_transfer_internal #14020

Merged
merged 2 commits into from
Jun 28, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
81 changes: 31 additions & 50 deletions source/multigrid/mg_transfer_internal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,17 @@ namespace internal
copy_indices.resize(n_levels);
copy_indices_global_mine.resize(n_levels);
copy_indices_level_mine.resize(n_levels);
IndexSet globally_relevant;
DoFTools::extract_locally_relevant_dofs(dof_handler, globally_relevant);
const IndexSet &owned_dofs = dof_handler.locally_owned_dofs();

const unsigned int dofs_per_cell = dof_handler.get_fe().n_dofs_per_cell();
std::vector<types::global_dof_index> global_dof_indices(dofs_per_cell);
std::vector<types::global_dof_index> level_dof_indices(dofs_per_cell);

for (unsigned int level = 0; level < n_levels; ++level)
{
std::vector<bool> dof_touched(globally_relevant.n_elements(), false);
std::vector<bool> dof_touched(owned_dofs.n_elements(), false);
const IndexSet & owned_level_dofs =
dof_handler.locally_owned_mg_dofs(level);

// for the most common case where copy_indices are locally owned
// both globally and on the level, we want to skip collecting pairs
Expand All @@ -119,9 +120,8 @@ namespace internal
numbers::artificial_subdomain_id))
continue;

unrolled_copy_indices.resize(
dof_handler.locally_owned_dofs().n_elements(),
numbers::invalid_dof_index);
unrolled_copy_indices.resize(owned_dofs.n_elements(),
numbers::invalid_dof_index);

// get the dof numbers of this cell for the global and the
// level-wise numbering
Expand All @@ -141,53 +141,36 @@ namespace internal
// and the level one. This check involves locally owned
// indices which often consist only of a single range, so
// they are cheap to look up.
const types::global_dof_index global_index_in_set =
owned_dofs.index_within_set(global_dof_indices[i]);
bool global_mine =
dof_handler.locally_owned_dofs().is_element(
global_dof_indices[i]);
global_index_in_set != numbers::invalid_dof_index;
bool level_mine =
dof_handler.locally_owned_mg_dofs(level).is_element(
level_dof_indices[i]);
owned_level_dofs.is_element(level_dof_indices[i]);

if (global_mine && level_mine)
{
// we own both the active dof index and the level one ->
// set them into the vector, indexed by the local index
// range of the active dof
unrolled_copy_indices[dof_handler.locally_owned_dofs()
.index_within_set(
global_dof_indices[i])] =
unrolled_copy_indices[global_index_in_set] =
level_dof_indices[i];
}
else if (global_mine &&
dof_touched[global_index_in_set] == false)
{
copy_indices_global_mine[level].emplace_back(
global_dof_indices[i], level_dof_indices[i]);

// send this to the owner of the level_dof:
send_data_temp.emplace_back(level,
global_dof_indices[i],
level_dof_indices[i]);
dof_touched[global_index_in_set] = true;
}
else
{
// Get the relevant dofs index - this might be more
// expensive to look up than the active indices, so we
// only do it for the local-remote case within this loop.
const types::global_dof_index relevant_idx =
globally_relevant.index_within_set(
global_dof_indices[i]);

// Work on this dof if we haven't already (on this or a
// coarser level)
if (dof_touched[relevant_idx] == false)
{
if (global_mine)
{
copy_indices_global_mine[level].emplace_back(
global_dof_indices[i], level_dof_indices[i]);

// send this to the owner of the level_dof:
send_data_temp.emplace_back(level,
global_dof_indices[i],
level_dof_indices[i]);
}
else
{
// somebody will send those to me
}

dof_touched[relevant_idx] = true;
}
// somebody will send those to me
}
}
}
Expand All @@ -203,14 +186,13 @@ namespace internal
if (copy_indices_global_mine[level].empty())
copy_indices[level].reserve(unrolled_copy_indices.size());

// locally_owned_dofs().nth_index_in_set(i) in this query is
// owned_dofs.nth_index_in_set(i) in this query is
// usually cheap to look up as there are few ranges in
// dof_handler.locally_owned_dofs()
// the locally owned part
for (unsigned int i = 0; i < unrolled_copy_indices.size(); ++i)
if (unrolled_copy_indices[i] != numbers::invalid_dof_index)
copy_indices[level].emplace_back(
dof_handler.locally_owned_dofs().nth_index_in_set(i),
unrolled_copy_indices[i]);
owned_dofs.nth_index_in_set(i), unrolled_copy_indices[i]);
}
}

Expand Down Expand Up @@ -260,7 +242,7 @@ namespace internal

for (unsigned int level = 0; level < n_levels; ++level)
{
const IndexSet &is_local =
const IndexSet &owned_level_dofs =
dof_handler.locally_owned_mg_dofs(level);

std::vector<types::global_dof_index> level_dof_indices;
Expand All @@ -272,15 +254,15 @@ namespace internal
global_dof_indices.push_back(dofpair.global_dof_index);
}

IndexSet is_ghost(is_local.size());
IndexSet is_ghost(owned_level_dofs.size());
is_ghost.add_indices(level_dof_indices.begin(),
level_dof_indices.end());

AssertThrow(level_dof_indices.size() == is_ghost.n_elements(),
ExcMessage("Size does not match!"));

const auto index_owner =
Utilities::MPI::compute_index_owner(is_local,
Utilities::MPI::compute_index_owner(owned_level_dofs,
is_ghost,
tria->get_communicator());

Expand Down Expand Up @@ -691,8 +673,7 @@ namespace internal
setup_element_info(elem_info, *fe, dof_handler);


// -------------- 2. Extract and match dof indices between child and
// parent
// ---------- 2. Extract and match dof indices between child and parent
const unsigned int n_levels = tria.n_global_levels();
level_dof_indices.resize(n_levels);
parent_child_connect.resize(n_levels - 1);
Expand Down