Skip to content

Split comm method - #89

Closed
TomMelt wants to merge 9 commits into
mainfrom
split-comm-method
Closed

TomMelt wants to merge 9 commits into
mainfrom
split-comm-method

Conversation

@TomMelt

@TomMelt TomMelt commented Jun 25, 2026 •

Copy link
Copy Markdown
Contributor

WIP Do Not Merge

Two-stage tripolar domain decomposition using split MPI communicators

fixes #85

Summary

Implement two-stage tripolar domain decomposition: when the --tripolar flag is passed, the domain is split East/West by coordinate via MPI_Comm_split, each half is partitioned independently with Zoltan, and results are merged back into a single global partitioning. The base partition() flow is preserved for non-tripolar runs.

Changes

main.cpp

  • Add --tripolar (-t) CLI flag to enable split-communicator mode
  • Split MPI_COMM_WORLD into East/West sub-communicators using MPI_Comm_split (color = 0 West, 1 East, midpoint = globalExt[0] / 2)
  • Create a copy of the grid (subgrid) for sub-communicator work
  • Run partitioning on subgrid + subpartitioner within each sub-communicator, or fall through to standard single-communicator path
  • Merge sub-partitioner results back into the original partitioner: copy GlobalNew, LocalExtNew, and adjust ProcId offsets for the East half
  • Call discover_neighbours() after merge to rebuild neighbour info on the unified communicator
  • Clean up sub-communicator and subgrid resources

Grid.cpp / Grid.hpp

  • Replace deleted copy constructor with an explicit Grid(const Grid& other) copy ctor (needed for subgrid creation)
  • Add set_comm(), set_global(), set_globalExt() setters to allow reconfiguring a grid copy for sub-communicator use
  • Add recompute_ids() to regenerate _global_id / _local_id after the grid's bounding box changes (East/West halves get different global positions)
  • Add _ignore_mask member (defaults false) to control whether the land mask is applied during id recomputation

Partitioner.cpp / Partitioner.hpp

  • Move discover_neighbours() from protected to public
  • Add initialize(Grid&) virtual method to base Partitioner — extracts grid extents/bounding-box/periodicity into partitioner member variables, separating setup from partitioning
  • Add a large set of getter/setter accessors: setTotalNumProcs, setComm, get/setLocalExtNew, get/setGlobalNew, get/setGlobal, get/setGlobalExt, get/setProcId

ZoltanPartitioner.cpp / ZoltanPartitioner.hpp

  • Implement initialize(Grid&) by copying the grid setup logic previously inside partition()
  • Have partition(Grid&) call initialize(grid) first, preserving all original partitioning logic
  • Remove duplicate discover_neighbours() call from inside partition() (now called once after merge in main)

TomMelt and others added 8 commits June 16, 2026 17:05
- Implement Grid copy constructor (previously deleted)
- Add set_global(), set_globalExt(), and recompute_ids() to allow
modification of grid geometry after construction
- In tripolar mode, partition a subgrid copy with adjusted extents
instead of the original grid
Add setter/getter accessors for internal partitioning state (total
number of procs, communicator, global coordinates, local extents) on
both Partitioner and Grid classes.

Moves discover_neighbours() from private to public so it can be called
after partition results are populated.
For tripolar mode, create a separate subpartitioner for each sub-grid,
then merge the results into the main partitioner before calling
discover_neighbours().

This also enables metadata saving in tripolar mode by removing the
previous known limitation.
Move the 6 grid-loading statements from ZoltanPartitioner::partition()
into a new ZoltanPartitioner::initialize(Grid&) method. Add the
corresponding initialize() method to the Partitioner base class as a
pure virtual function so all future partitioners must implement it.

This improves separation of concerns: initialize() handles setting
method variables (_numProcs, _globalExt, _global, _localExt, _px, _py)
from the grid, while partition() focuses on the partitioning logic
itself.
Expose the process ID vector of the latest 2D domain decomposition
via getter and setter methods.
…ar mode

- Move the MPI color variable outside the tripolar conditional so it's
  available for downstream use.
- Add partitioner initialization for the tripolar case.
- Remove redundant setTotalNumProcs/setGlobalExt calls.
- Offset process IDs of the East half (color==1) by numProcs/2 to avoid
  duplicates when merging results from both sub-communicators.
- Restore mask and metadata saving for both tripolar and non-tripolar
  modes.
@TomMelt TomMelt added the ICCS label Jun 25, 2026
@TomMelt TomMelt moved this to Review required in neXtSIM_DG overview Jun 25, 2026
@TomMelt TomMelt self-assigned this Jul 6, 2026
@TomMelt
TomMelt marked this pull request as draft July 6, 2026 13:11
@Mikolaj-A-Kowalski

Copy link
Copy Markdown
Contributor

Since we have opted for not requiring the exact split in the middle of the domain and have a method to calculate the communication metadata for arbitrary tripolar decompositions (#96). I am closing this one.

We can always reopen if we need it again.

@github-project-automation github-project-automation Bot moved this from Review required to Done in neXtSIM_DG overview Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Development

Successfully merging this pull request may close these issues.

Manually split domain

2 participants