References:
It works exactly like standard MPI, every process has to call the routine.
def reduce(
sendobj: Any, #Data to be reduced
op: Op | ((Any, Any) -> Any) = SUM, #Reduce operation
root: int = 0 #Root rank
) -> (Any | None)
#Returns reduced data for the root process and none for the other processes.
def Reduce(
sendbuf: BufSpec | InPlace, #Data to be reduced
recvbuf: BufSpec | None, #Reduced data for the root, none for others
op: Op = SUM, #Reduce operation
root: int = 0 #Root rank
) -> None
The default possible operations are the same as in standard MPI, and you can see all of them here: https://learn.microsoft.com/en-us/message-passing-interface/mpi-op-enumeration. However, for Python objects, you can pass custom reduce functions instead of using a default operation with the 'reduce' function.
Python object example:
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
parsedSquaredRank = (rank+1)**2
print('Process ' + str(rank) + ' sending: ' + str(parsedSquaredRank))
reducedData = comm.reduce(parsedSquaredRank, MPI.SUM)
if(rank == 0):
print('Reduced data: ', end="")
print(reducedData)
Output:
Python object example (with custom reduce function):
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
parsedSquaredRank = (rank+1)**2
print('Process ' + str(rank) + ' sending: ' + str(parsedSquaredRank))
reducedData = comm.reduce(parsedSquaredRank, lambda a,b: a+b)
if(rank == 0):
print('Reduced data: ', end="")
print(reducedData)
Output:
Buffer-like object example:
from mpi4py import MPI
import numpy
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
parsedSquaredRank = numpy.array([(rank+1)**2], dtype='i')
print('Process ' + str(rank) + ' sending: ' + str(parsedSquaredRank))
reducedData = numpy.empty(1, dtype='i')
comm.Reduce(parsedSquaredRank, reducedData, MPI.SUM)
if(rank == 0):
print('Reduced data: ', end="")
print(reducedData)
Output: