Search code examples
pythonmultithreadingmultiprocessingkeyerror

KeyError: 0 using multiprocessing in python


I have the following code inwhich I try to call a function compute_cluster which do some computations and write the results in a txt file (each process write its results in different txt files independently), however, when I run the following code:

def main():
  p = Pool(19)
  p.map(compute_cluster, [(l, r) for l in range(6, 25) for r in range(1, 4)]) 
  p.close()
if __name__ == "__main__":
   main()                

it crashes with the following errors:

File "RMSD_calc.py", line 124, in <module>
  main()                
File "RMSD_calc.py", line 120, in main
  p.map(compute_cluster, [(l, r) for l in range(6, 25) for r in range(1, 4)]) 
File "/usr/local/lib/python2.7/multiprocessing/pool.py", line 225, in map
  return self.map_async(func, iterable, chunksize).get()
File "/usr/local/lib/python2.7/multiprocessing/pool.py", line 522, in get
  raise self._value
  KeyError: 0

and when I searched online for the meaning of "KeyError: 0" i didn't find anything helpful so any suggestions why this error happens is highly appreciated


Solution

  • KeyError happens in compute_cluster() in a child process and p.map() reraises it for you in the parent:

    from multiprocessing import Pool
    
    def f(args):
        d = {}
        d[0] # <-- raises KeyError
    
    if __name__=="__main__":
        p = Pool()
        p.map(f, [None])
    

    Output

    Traceback (most recent call last):
      File "raise-exception-in-child.py", line 9, in <module>
        p.map(f, [None])
      File "/usr/lib/python2.7/multiprocessing/pool.py", line 227, in map
        return self.map_async(func, iterable, chunksize).get()
      File "/usr/lib/python2.7/multiprocessing/pool.py", line 528, in get
        raise self._value
    KeyError: 0
    

    To see the full traceback, catch the exception in the child process:

    import logging
    from multiprocessing import Pool
    
    def f(args):
        d = {}
        d[0] # <-- raises KeyError
    
    def f_mp(args):
        try:
            return f(args)
        except Exception:
            logging.exception("f(%r) failed" % (args,))
    
    if __name__=="__main__":
        p = Pool()
        p.map(f_mp, [None])
    

    Output

    ERROR:root:f(None) failed
    Traceback (most recent call last):
      File "raise-exception-in-child.py", line 10, in f_mp
        return f(args)
      File "raise-exception-in-child.py", line 6, in f
        d[0] # <-- raises KeyError
    KeyError: 0
    

    It shows that d[0] caused the exception.