qlat.mpi_utils — MPI Initialization and Data Distribution¶
Source: qlat/qlat/mpi_utils.py
Note: Update this document when updating the source file.
Outline¶
Overview¶
mpi_utils handles MPI setup and teardown for qlat. When qlat runs in
parallel it must know the 4-D Cartesian grid of MPI ranks (size_node);
this module maps the world communicator to such a grid automatically.
The key entry points are:
begin_with_mpi— initialize MPI and the qlat C++ runtime.end_with_mpi— finalize both.get_mpi_chunk— split a list across MPI ranks for distributed work.
The module also stores a module-level comm object (an mpi4py
communicator) that other qlat modules use for collective operations.
MPI Lifecycle Functions¶
begin_with_mpi(size_node_list=None)¶
Initialize MPI and the qlat C++ runtime.
Calls
MPI.COMM_WORLDto obtain the world communicator.Looks up the number of MPI ranks (
comm.size) and tries to match it againstsize_node_list(a list of[n0, n1, n2, n3]orCoordinateobjects). The user-supplied list is prepended todefault_size_node_list.Calls
q.begin(id_node, size_node)to initialize the C++ layer.
Raises Exception if no matching grid is found for the current num_node.
begin_with_mpi(size_node_list=None)
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Candidate 4-D node grids to try before the built-in defaults |
end_with_mpi(is_preserving_cache=False)¶
Finalize the qlat C++ runtime (q.end) and call MPI.Finalize().
end_with_mpi(is_preserving_cache=False)
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
If |
Communication and Diagnostics¶
get_comm() -> mpi4py.MPI.Intracomm¶
Return the module-level MPI communicator set by begin_with_mpi.
set_comm(x)¶
Set the module-level MPI communicator. Rarely called directly.
show_machine()¶
Print a diagnostic line showing the current rank ID, total ranks, and
Cartesian coordinates of this node. Decorated with @timer_verbose.
Data Distribution¶
get_mpi_chunk(total_list, *, rng_state=None) -> list¶
Distribute total_list across MPI ranks. Each rank receives one chunk of
the list. The assignment is deterministic when rng_state is None; pass
an RngState for reproducible shuffling before chunking.
get_mpi_chunk(total_list, *, rng_state=None)
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
— |
The full list to distribute |
|
|
|
Optional RNG for shuffling (must be identical on all ranks) |
Returns the chunk assigned to the current rank (may be [] if there are
more ranks than items).
Internally uses qlat_utils.get_chunk_list with chunk_number=get_num_node().
Default Node Grid¶
default_size_node_list contains 27 pre-defined 4-D grids for common
node counts from 1 to 512. The list includes:
Nodes |
Grid (n0 x n1 x n2 x n3) |
|---|---|
1 |
1 x 1 x 1 x 1 |
2 |
1 x 1 x 1 x 2 |
4 |
1 x 1 x 2 x 2 |
8 |
1 x 2 x 2 x 2 |
16 |
2 x 2 x 2 x 2 |
32 |
2 x 2 x 2 x 4 |
64 |
2 x 2 x 4 x 4 |
128 |
2 x 4 x 4 x 4 |
256 |
4 x 4 x 4 x 4 |
512 |
4 x 4 x 4 x 8 |
… |
(see source for full list) |
Grids with a factor of 3 in the last dimension (3, 6, 12) are also included for anisotropic lattice geometries.
Examples¶
Basic MPI Setup and Teardown¶
import qlat as q
q.begin_with_mpi([[1, 1, 1, 1]])
q.mpi_utils.show_machine()
q.end_with_mpi()
Distributing Work Across Ranks¶
import qlat as q
q.begin_with_mpi([[1, 1, 1, 1]])
full_list = list(range(100))
my_chunk = q.mpi_utils.get_mpi_chunk(full_list)
print(f"Rank {q.get_id_node()} processing {len(my_chunk)} items")
q.end_with_mpi()
Custom Node Grid¶
import qlat as q
# Use a 2x2x2x4 grid for 32 ranks
q.begin_with_mpi([[2, 2, 2, 4]])
print(f"size_node = {q.get_size_node()}")
q.end_with_mpi()