I have the following example problem using the allreduce function from mpi4py to find the minimum of each element in the lists across multiple processes. However, the resulting list is not correct. The output of allreduce is always one of the input lists. How can this be corrected?
Output
Rank 0: [2, 3, 6, 6, 10, 0, 9, 2, 4, 1]
Allreduce: [0, 0, 4, 4, 1, 0, 10, 10, 1, 5]
Rank 1: [4, 7, 8, 1, 3, 2, 1, 8, 2, 10]
Rank 2: [6, 2, 6, 3, 2, 3, 7, 6, 10, 4]
Rank 3: [7, 1, 0, 0, 3, 1, 6, 5, 9, 10]
Rank 4: [0, 0, 4, 4, 1, 0, 10, 10, 1, 5]
Rank 5: [1, 9, 3, 5, 9, 4, 9, 5, 4, 5]
Rank 6: [1, 4, 6, 10, 7, 2, 1, 2, 1, 3]
Rank 7: [8, 8, 8, 2, 7, 7, 9, 2, 1, 2]
Rank 8: [7, 2, 4, 10, 7, 7, 5, 2, 9, 1]
Rank 9: [3, 1, 1, 3, 5, 10, 7, 4, 2, 5]
Code
from mpi4py import MPI
import random
#MPI Parallelization
comm = MPI.COMM_WORLD # gets communication pool
rank = comm.Get_rank() # gets rank of current process
num_ranks = comm.Get_size() # total number of processes
r = [random.randint(0,10) for i in range(0,10)]
print("Rank " + str(rank) + ": " + str(r))
comm.Barrier()
rr = comm.allreduce(r, op=MPI.MIN)
if rank == 0:
print("Allreduce: " + str(rr))
Generally speaking, mpi4py
works best with numpy
.
Here is an allreduce example:
(do note with numpy
you should use Allreduce(...)
instead of allreduce(...)
from mpi4py import MPI
import random
import numpy as np
#MPI Parallelization
comm = MPI.COMM_WORLD # gets communication pool
rank = comm.Get_rank() # gets rank of current process
num_ranks = comm.Get_size() # total number of processes
r = np.random.randint(0, 100, 10)
rr = np.empty(10, dtype=int)
print("Rank " + str(rank) + ": " + str(r))
comm.Barrier()
comm.Allreduce([r, MPI.INT], [rr, MPI.INT], op=MPI.MIN)
if rank == 0:
print("Allreduce: " + str(rr))
In your case, I would suspect the outcome of MPI.MIN
applied to a python list is not a list with the minimum elements, and hence you would get the full buffer of a given rank.