Image manipulation in Python using MPI
Question: I'm trying to do some image manipulation using MPI (mpi4py) in Python. This is
my code so far:

    
    
    from mpi4py import MPI
    from PIL import Image
    
    comm = MPI.COMM_WORLD
    size = comm.size #number of processors
    rank = comm.rank #calling process rank
    root = 0
    if rank == 0:
        print "rank = 0 \n"
        img = Image.open('dog.jpg')
        width, height = img.size
        pix = list(img.getdata())
        for i in range(len(pix)):
            pix[i] = list(pix[i])
        chunks = [[] for _ in range(size)]
        for i, chunk in enumerate(pix):
            chunks[i % size].append(chunk)
    else:
        print "rank != 0"
    
    data = comm.scatter(chunks, root)
    #do some pixel manipulations
    data = comm.gather(data, root)
    for i in range(len(pix)):
        pix[i] = tuple(data[0][i])
    image = Image.new("RGB", (width, height))
    image.putdata(pix)
    image.save("test.jpg")
    

When I try to run it with

    
    
    mpirun -np 1 python parallel.py
    

it works ok. But if i try to increase the number of processors, I get the
following error

    
    
    mpirun -np 3 python parallel.py
    rank = 1
    rank = 2
    rank = 0 
    
    Traceback (most recent call last):
      File "parallel.py", line 21, in <module>
        data = comm.scatter(chunks, root)
    NameError: name 'chunks' is not defined
    Traceback (most recent call last):
      File "parallel.py", line 21, in <module>
        data = comm.scatter(chunks, root)
    NameError: name 'chunks' is not defined
    

I'm running the code on a Ubuntu Virtual Machine using Virtual Box. Appreciate
your help!


Answer: This is not an MPI problem. `chunks` is undefined in the processes in which
the `else:` branch of the conditional is taken, i.e. in all processes except
rank 0. Simply add `chunks = None` there:

    
    
    ...
    if rank == 0:
        ...
    else:
        print "rank != 0"
        chunks = None
    ...
    

It works with one process since in that case there is only one rank (0) and
the else branch is never taken.

