mpi4py.util.sync
Added in version 4.0.0.
The mpi4py.util.sync
module provides parallel synchronization
utilities.
Sequential execution
- class mpi4py.util.sync.Sequential
Sequential execution.
Context manager for sequential execution within a group of MPI processes.
The implementation is based in MPI-1 point-to-point communication. A process with rank i waits in a blocking receive until the previous process rank i-1 finish executing and signals the next rank i with a send.
- __init__(comm, tag=0)
Initialize sequential execution.
Global counter
- class mpi4py.util.sync.Counter
Parallel counter.
Produce consecutive values within a group of MPI processes. The counter interface is close to that of
itertools.count
.The implementation is based in MPI-3 one-sided operations. A root process (typically rank
0
) holds the counter, and its value is queried and incremented with an atomic RMA fetch-and-add operation.- __init__(comm, start=0, step=1, typecode='i', root=0, info=INFO_NULL)
Initialize counter object.
- next(incr=None)
Return current value and increment.
Mutual exclusion
- class mpi4py.util.sync.Mutex
Parallel mutex.
Establish a critical section or mutual exclusion among MPI processes. The mutex interface is close to that of
threading.Lock
. However, its intended uses and specific semantics are somewhat different:A mutex should be used within a group of MPI processes, not threads.
Once acquired, a mutex is held and owned by a process until released.
Trying to acquire a mutex already held raises
RuntimeError
.Trying to release a mutex not yet held raises
RuntimeError
.
This mutex implementation uses the scalable and fair spinlock algorithm from [mcs-paper] and took inspiration from the MPI-3 RMA implementation of [uam-book].
[mcs-paper]John M. Mellor-Crummey and Michael L. Scott. Algorithms for scalable synchronization on shared-memory multiprocessors. ACM Transactions on Computer Systems, 9(1):21-65, February 1991. https://doi.org/10.1145/103727.103729
[uam-book]William Gropp, Torsten Hoefler, Rajeev Thakur, Ewing Lusk. Using Advanced MPI - Modern Features of the Message-Passing Interface. Chapter 4, Section 4.7, Pages 130-131. The MIT Press, November 2014. https://mitpress.mit.edu/9780262527637/using-advanced-mpi/
- __init__(comm, info=INFO_NULL)
Initialize mutex object.
- acquire(blocking=True)
Acquire mutex, blocking or non-blocking.
- class mpi4py.util.sync.RMutex
Parallel recursive mutex.
Establish a critical section or mutual exclusion among MPI processes. The mutex interface is close to that of
threading.RLock
, allowing for recursive acquire and release operations. However, the mutex should be used within a group of MPI processes, not threads.The implementation is based on a
Mutex
providing mutual exclusion and a counter tracking the recursion level.- __init__(comm, info=INFO_NULL)
Initialize recursive mutex object.
- acquire(blocking=True)
Acquire mutex, blocking or non-blocking.
Examples
1from mpi4py import MPI
2from mpi4py.util.sync import Counter, Sequential
3
4comm = MPI.COMM_WORLD
5
6counter = Counter(comm)
7with Sequential(comm):
8 value = next(counter)
9counter.free()
10
11assert comm.rank == value
1from mpi4py import MPI
2from mpi4py.util.sync import Counter, Mutex
3
4comm = MPI.COMM_WORLD
5
6mutex = Mutex(comm)
7counter = Counter(comm)
8with mutex:
9 value = next(counter)
10counter.free()
11mutex.free()
12
13assert (
14 list(range(comm.size)) ==
15 sorted(comm.allgather(value))
16)