Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.2-d6b3a29ca committed by Constantine Khrulev on 2025-03-28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages

◆ label_components_impl()

template<typename T >
void pism::label_components_impl ( const T &  input,
bool  mark_isolated_patches,
array::Scalar1 output 
)

Labels connected components in parallel, using a custom definition of "foreground" and "attached" grid cells.

Note that connected_components::details::label() below is a template function: this is why we have to include the implementation here.

The type T has to implement is_foreground(row, col) and is_attached(row, col).

Here's the idea:

  1. Identify connected components in each sub-domain.
  2. "Update ghosts" of output, then iterate over sub-domain edges to identify connections between patches in sub-domains that make up connected components spanning multiple sub-domains. This defines a graph: each patch on a sub-domain is a node, two nodes are connected by an edge if and only if they "touch".
  3. Gather graph description on all sub-domains that have at least one patch.
  4. Use breadth-first search to traverse this graph and compute final labels.
  5. Apply final labels.

This method communicates ghosts (once), number of graph edges per sub-domain (once) and then all graph edges (once, only to sub-domains that have at least one patch).

Graph traversal is done "redundantly", i.e. each participating sub-domain traverses the whole graph even if it contains one isolated node. This is needed to ensure that resulting labels use consecutive numbers. (Consecutive labels are useful for indexing elsewhere in the code).

We /could/ gather graph information on one MPI processor, traverse the graph to compute final labels, then scatter final labels. It is not clear if this would be better, though.

The current implementation uses

  • MPI_Allgather() to gather number of graph edges per subdomain (send 4 bytes, receive 4 bytes per subdomain).
  • MPI_Allgatherv() to gather edges to all participating subdomains (send 8 bytes per local edge, receive 8-16 bytes per edge).

The alternative implementation would use

  • MPI_Gather() to gather number of graph edges per sub-domain to one of sub-domains. (each sub-domain sends 4 bytes, one sub-domain receives 4 bytes per sub-domain).
  • MPI_Gatherv() to gather edges from all participating sub-domains. (All sub-domains send 8 bytes per local edge, one sub-domain receives 8 bytes per edge in the whole graph.)
  • MPI_Bcast() to scatter the mapping from old labels to new labels (8 bytes per local sub-domain).

TO DO: run benchmarks!

Definition at line 95 of file label_components_impl.hh.

References pism::details::final_labels(), pism::details::first_label(), pism::array::Array::grid(), and pism::details::relabel().

Referenced by pism::connected_components::label(), and pism::connected_components::label_isolated().