'MPI python program using mpi4py.futures.MPICommExecutor() does not complete execution

I'm trying to write a simple mpi-based parallel program in python using mpi4py that asynchronously distributes some number of jobs among some pool of worker processes and then collects the answers when they're all done. I have the following python program:

from mpi4py import MPI
from mpi4py.futures import MPICommExecutor
import math

def primefact(n):
     facts = [1]
     if n < 1:
          return []
     while n % 2 == 0: 
          facts.append(2) 
          n = n / 2
     for i in range(3,int(math.sqrt(n))+1,2): 
          while n % i== 0: 
               facts.append(i) 
               n = n / i 
     if n > 2: 
          facts.append(n)
     return facts

def test_primefact(nums):
     with MPICommExecutor(MPI.COMM_WORLD, root=0) as executor:
          if executor is None: 
               return
          jobs = [executor.submit(primefact,qq) for qq in nums]
          facts = [job.result() for job in jobs]
          for rslt in zip(nums,facts):
               print('{}: '.format(rslt[0]) + ', '.join([str(qq) for qq in rslt[1]]))

if __name__ == "__main__":
     nums = [qq for qq in range(1,201)]
     test_primefact(nums)

When I run the program using the command mpiexec -n 4 ./mpitest.py, the program execution will hang for an indefinite period of time. If I send a terminate signal by pressing Ctrl-C, the program will then print all of the output (so it did at some point do the calculations; I don't know if it did them before or after I sent the terminate signal), but it won't give me the command prompt back. If I send the terminate signal again, I'll get the command prompt back, but the processes that mpiexec spawned will still be running in the background and I have to manually kill them. Am I missing a line somewhere that lets MPICommExecutor know that everything is done processing so it can exit? As far as I can tell, I'm not doing anything materially different from the examples here and here.

  • mpi4py 3.0.0
  • python 3.6
  • Intel(R) MPI Library for Linux* OS, Version 2019 Update 1 Build 20181016


Solution 1:[1]

Assuming that the program is in a file called prim.py:

$ mpiexec -n 4 python3 -m mpi4py.futures prim.py

Seems to produce:

1: 1
2: 1, 2
3: 1, 3
4: 1, 2, 2
...
197: 1, 197
198: 1, 2, 3, 3, 11.0
199: 1, 199
200: 1, 2, 2, 2, 5, 5

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 richardec