OS X 10.8上的PyCuda/多处理问题

2024-05-29 03:38:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个项目中,我将计算任务分配给多个python进程,每个进程都与它自己的CUDA设备相关。在

生成子流程时,我使用以下代码:

import pycuda.driver as cuda

class ComputeServer(object):
    def _init_workers(self):
        self.workers = []
        cuda.init()
        for device_id in range(cuda.Device.count()):
            print "initializing device {}".format(device_id)
            worker = CudaWorker(device_id)
            worker.start()
            self.workers.append(worker)

同事在另一个文件中的定义如下:

^{pr2}$

当我在Windows7或Linux上运行这段代码时,我没有问题。在装有OSX 10.8.2、Cuda 5.0和PyCuda 2012.1的MacBook Pro上运行代码时,出现以下错误:

Process CudaWorker-1:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/Users/tombnorwood/pymodules/computeserver/worker.py", line 32, in run
    self._init_cuda_context()
  File "/Users/tombnorwood/pymodules/computeserver/worker.py", line 38, in _init_cuda_context
    cuda.init()
RuntimeError: cuInit failed: no device

在我的Mac上运行PyCuda脚本而不分叉新进程,我没有问题。我只有在生成新进程时才会遇到这个问题。在

以前有人遇到过这个问题吗?在


Tags: 代码inpyselfpycudaid进程init
1条回答
网友
1楼 · 发布于 2024-05-29 03:38:20

根据我的经验,这只是一个有根据的猜测,但是我怀疑CUDA(或者可能是PyCuda)的OS X实现依赖于一些在fork之后无法安全使用的api,而linux实现则没有。*因为multiprocessing的POSIX实现使用fork而没有exec来创建子进程,因此可以解释为什么它在OSX上失败,而不是在linux上。(在Windows上,没有fork,只是一个spawn的等价物,所以这不是问题。)

最简单的解决方案是删除multiprocessing。如果CUDA和PyCUDA是线程安全的(我不知道它们是否是线程安全的),并且您的代码不是CPU绑定的(只是GPU绑定的),那么您可以直接插入threading.Thread来代替{}并完成它。或者,您可以考虑为multiprocessing提供类似api的其他并行处理库之一。(有些人使用pp仅仅因为它总是execs…)

然而,很容易将multiprocessing修改成exec/spawn一个新的Python解释器,然后执行Windows风格而不是POSIX风格的所有操作。(使每个用例都正确是很困难的,但是正确地获得一个特定的用例是很容易的。)

或者,如果你看一下bug #8713,一般来说,有一些工作要做。还有工作补丁。这些贴片是3.3版的,不是2.7版的,所以你可能需要做一些按摩,但不应该太多。因此,只需cp $MY_PYTHON_LIB/multiprocessing.py $MY_PROJECT_DIR/mymultiprocessing.py,对其进行修补,使用mymultiprocessing代替{},并添加适当的调用来选择spawn/fork+exec/无论最新补丁中调用的模式是什么,然后再做其他操作。在


*OP说他怀疑同样的事情,所以我可能不需要向他解释这一点,但是为了将来的读者:这不是关于达尔文和其他Unix之间的区别,而是关于苹果发布了很多非Unix-y的中级库,比如核心基础.framework, 加速.framework, 等等,使用不安全的fork后功能(或者只是断言在fork之后没有使用它们,因为苹果不想在他们说“asto10.X,Foo.框架叉后安全”)。另外,如果你比较一下OSX和linux处理图形和其他硬件的方式,在OSX中每个进程用户空间中都有更多的中级用户空间

相关问题 更多 >

    热门问题