5

I tried to use cupy in two parts of my program, one of them being parallelized with a pool. I managed to reproduce it with a simple example:

import cupy
import numpy as np
from multiprocessing import pool


def f(x):
    return cupy.asnumpy(2*cupy.array(x))



input = np.array([1,2,3,4])
print(cupy.asnumpy(cupy.array(input)))


print(np.array(list(map(f, input))))

p = pool.Pool(4)
output = p.map(f, input)
p.close()
p.join()
print(output)

The output is the following:

[1 2 3 4]
[2 4 6 8]
Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3.6/multiprocessing/pool.py", line 489, in _handle_results
    task = get()
  File "/usr/lib/python3.6/multiprocessing/connection.py", line 251, in recv
    return _ForkingPickler.loads(buf.getbuffer())
  File "cupy/cuda/runtime.pyx", line 126, in cupy.cuda.runtime.CUDARuntimeError.__init__
TypeError: an integer is required

also, the code freezes and doesn't exit but I think it's not related to cupy.

And my config is this one:

CuPy Version          : 5.2.0
CUDA Root             : /usr/local/cuda-10.0
CUDA Build Version    : 10000
CUDA Driver Version   : 10000
CUDA Runtime Version  : 10000
cuDNN Build Version   : 7301
cuDNN Version         : 7301
NCCL Build Version    : 2307

2 Answers2

6

This issue is not specific to CuPy. Due to the limitation of CUDA, processes cannot be forked after CUDA initialization.

You need to use multiprocessing.set_start_method('spawn') (or forkserver), or avoid initializing CUDA (i.e., do not use CuPy API except import cupy) until you fork child processes.

kmaehashi
  • 879
  • 6
  • 10
0

When I tried multiprocessing with cupy before, I needed to use spawn context.

ctx = multiprocessing.get_context('spawn')
pool = ctx.Pool(4)

I don't know this resolves your problem but can you try it?

corochann
  • 1,604
  • 1
  • 13
  • 24
  • 1
    Thank you for your answer. Your proposition seems to be a good idea. It works for the example I gave, but the problem of the spawn methode is that it doesn't give you the contexte of the main thread in the created threads. For exemple you can't get your logging config. I still think that it's an issue (not being able to fork your thread), but I'll try to work on my personal case with your solution. – Jérémy Gayard Feb 21 '19 at 17:15
  • Hi @Jérémy Gayard, this might be a long shot as your question was posted awhile back, but I was wondering if you managed to find a solution for this? – Leockl Aug 10 '20 at 10:03