I am teaching myself the Python mpi4py module for programming in multiple processes. I have written the following piece of code to practice scatter.
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
if rank == 0:
data = [i for i in range(8)]
else:
data = None
data = comm.scatter(data, root=0)
print str(rank) + ': ' + str(data)
Running the above code with 8 processes works great. However, when I run it with 4 processes, I get an error:
Traceback (most recent call last):
File "scatter.py", line 11, in <module>
data = comm.scatter(data, root=0)
File "Comm.pyx", line 874, in mpi4py.MPI.Comm.scatter (src/mpi4py.MPI.c:68023)
File "pickled.pxi", line 656, in mpi4py.MPI.PyMPI_scatter (src/mpi4py.MPI.c:32402)
File "pickled.pxi", line 127, in mpi4py.MPI._p_Pickle.dumpv (src/mpi4py.MPI.c:26813)
ValueError: expecting 4 items, got 8
What does this error mean? My intention is to break up my large array of 8 items into small arrays of 8 / 4 = 2 items and send each process one such subarray. How do I do that? I would also like to generalize if possible to numbers of processes that do not divide evenly into 8 such as 3.
It seems that comm.scatter
can not take count
as an argument and expects a list of exactly comm.size
elements as data to be scattered; so you need to distribute your data between processes yourself. Something like this will do:
if rank == 0:
data = [i for i in range(8)]
# dividing data into chunks
chunks = [[] for _ in range(size)]
for i, chunk in enumerate(data):
chunks[i % size].append(chunk)
else:
data = None
chunks = None
data = comm.scatter(chunks, root=0)
print str(rank) + ': ' + str(data)
[physics@tornado] ~/utils> mpirun -np 3 ./mpi.py
2: [2, 5]
0: [0, 3, 6]
1: [1, 4, 7]
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With