【问题标题】:Why am I getting 'cuMemAlloc failed: not initialized' even though I am initializing correctly?即使我正确初始化,为什么我会收到“cuMemAlloc failed: not initialized”?
【发布时间】:2014-07-14 19:53:02
【问题描述】:

我的 Django/Celery/PyCuda 设置有问题。 我正在使用 PyCuda 在 Amazon EC2 G2 实例上进行一些图像处理。 这是我支持 Cuda 的 GRID K520 卡的信息: 检测到 1 个支持 CUDA 的设备

Device 0: "GRID K520"
CUDA Driver Version / Runtime Version          6.0 / 6.0
CUDA Capability Major/Minor version number:    3.0
Total amount of global memory:                 4096 MBytes (4294770688 bytes)
( 8) Multiprocessors, (192) CUDA Cores/MP:     1536 CUDA Cores
GPU Clock rate:                                797 MHz (0.80 GHz)
Memory Clock rate:                             2500 Mhz
Memory Bus Width:                              256-bit
L2 Cache Size:                                 524288 bytes
Maximum Texture Dimension Size (x,y,z)         1D=(65536), 2D=(65536, 65536), 3D=(4096, 4096, 4096)
Maximum Layered 1D Texture Size, (num) layers  1D=(16384), 2048 layers
Maximum Layered 2D Texture Size, (num) layers  2D=(16384, 16384), 2048 layers
Total amount of constant memory:               65536 bytes
Total amount of shared memory per block:       49152 bytes
Total number of registers available per block: 65536
Warp size:                                     32
Maximum number of threads per multiprocessor:  2048
Maximum number of threads per block:           1024
Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
Max dimension size of a grid size    (x,y,z): (2147483647, 65535, 65535)
Maximum memory pitch:                          2147483647 bytes
Texture alignment:                             512 bytes
Concurrent copy and kernel execution:          Yes with 2 copy engine(s)
Run time limit on kernels:                     No
Integrated GPU sharing Host Memory:            No
Support host page-locked memory mapping:       Yes
Alignment requirement for Surfaces:            Yes
Device has ECC support:                        Disabled
Device supports Unified Addressing (UVA):      Yes
Device PCI Bus ID / PCI location ID:           0 / 3
Compute Mode:
 < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >
deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 6.0, CUDA Runtime Version = 6.0,   NumDevs = 1, Device0 = GRID K520
Result = PASS

我正在使用一个开箱即用的 celery 配置。 我在 utils/tasks.py 中定义了一组任务,这些任务在尝试使用 PyCuda 之前已经过测试和工作。我通过 pip 安装了 PyCuda。

在我遇到问题的文件顶部,我执行标准导入:

from celery import task
# other imports
import os
try:
    import Image
except Exception:
    from PIL import Image
import time

#Cuda imports
import pycuda.autoinit
import pycuda.driver as cuda
from pycuda.compiler import SourceModule
import numpy

远程服务器启动一项任务,该任务遵循以下基本工作流程:

 @task()
 def photo_function(photo_id,...):
     print 'Got photo...'
     ... Do some stuff ...
     result = do_photo_manipulation(photo_id)
     return result

def do_photo_manipulation(photo_id):
    im = Image.open(inPath)
    px = numpy.array(im)
    px = px.astype(numpy.float32)
    d_px = cuda.mem_alloc(px.nbytes)
    ... (Do stuff with the pixel array) ...
    return new_image

如果我在 shell plus(即 ./manage.py shell_plus)中运行它并且如果我将它作为一个独立的、django-and-celery 之外的进程运行,这将有效。只有在这种情况下它才会失败,并出现错误: cuMemAlloc 失败:未初始化

我已经查看了一段时间的其他解决方案,并尝试将 import 语句放在函数本身中进行初始化。我还插入了一个 wait() 语句,以确保它不是 gpu 准备好工作的问题。

这是一个答案,表明错误来自未导入 pycuda.autoinit,我已经这样做了:http://comments.gmane.org/gmane.comp.python.cuda/1975

如有任何帮助,我们将不胜感激!

如果我需要提供更多信息,请告诉我!

编辑: 这是测试代码: def CudaImageShift(imageIn, mode = "luminosity" , log = 0):

    if log == 1 :
        print ("----------> CUDA CONVERSION")

#    print "ENVIRON: "
#    import os
#    print os.environ

    print 'AUTOINIT'
    print pycuda.autoinit

    print 'Making context...'
    context = make_default_context()
    print 'Context created.'
    totalT0 = time.time()

    print 'Doing test run...'
    a = numpy.random.randn(4,4)
    a = a.astype(numpy.float32)
    print 'Test mem alloc'
    a_gpu = cuda.mem_alloc(a.nbytes)
    print 'MemAlloc complete, test mem copy'
    cuda.memcpy_htod(a_gpu, a)
    print 'memcopy complete'


[2014-07-15 14:52:20,469: WARNING/Worker-1] cuDeviceGetCount failed: not initialized

【问题讨论】:

  • 会不会是用户权限问题?尝试切换到在 django 中运行的任何人,等等并正常运行?或者您的包含可能没有被处理。
  • 为什么不处理包含?我不认为这是一个权限错误,但我不完全确定如何检查。
  • 听起来您正在通过其他路径执行脚本,而不是直接从 python 解释器执行。因此,如果包含分布在多个文件中,则可能无法执行。他们也可能改变路径。
  • 问题是,即使我将包含在执行 CUDA 工作的函数中,也不会引发错误,并且所有内容都会被包含在内。我可以使用 Image(来自包含的 PIL 包)。包含 pycuda.autoinit 时不会引发导入错误。它似乎并没有真正执行它的初始化过程。

标签: python django cuda celery pycuda


【解决方案1】:

我相信您遇到的问题与 CUDA 上下文有关。从 CUDA 4.0 开始,每个进程和每个设备都需要一个 CUDA 上下文。

在幕后 celery 将为任务工作者生成进程。当进程/任务启动时,它将没有可用的上下文。在 pyCUDA 中,上下文创建发生在 autoinit 模块中。这就是为什么如果您将代码作为独立运行(没有创建额外的进程并且上下文有效)或者如果您将 import autoinit 放在 CUDA 任务中(现在进程/任务将有一个上下文,我相信你已经试过了)。

如果您想避免导入,您可以使用来自pycuda.tools 的make_default_context,尽管我不太熟悉 pyCUDA 以及它如何处理上下文管理。

from pycuda.tools import make_default_context

@task()
def photo_function(photo_id,...):
  ctx = make_default_context()
  print 'Got photo...'
  ... Do some stuff ...
  result = do_photo_manipulation(photo_id)
  return result

请注意,上下文创建是一个昂贵的过程。 CUDA 故意在上下文中预先加载大量工作,以避免以后出现意外的延迟。这就是为什么你有一堆上下文,你可以在主机线程之间(但不能在进程之间)推送/弹出。如果您的内核代码非常快,您可能会因为上下文创建/销毁过程而遇到延迟。

【讨论】:

  • 首先感谢您的回复。我真的很感激帮助!我在尝试手动初始化时仍然遇到同样的错误。实际上我昨天尝试过这个——我进入了 autoinit 函数并将这些行复制出来并直接复制到我的代码中,以手动初始化 PyCuda。没运气。查看我对代码运行和错误的编辑。
  • 您是否完全删除了代码开头的import autoinit? cuInit(0) 调用需要在调用 API 之前完成。尝试查询发生在 make_default_context 函数开头的设备数量时,您会收到错误消息。这暗示了驱动程序在那时根本没有初始化。同样从你的代码示例来看,这个函数内部的代码是用 celery @task 装饰的吗?
  • 我已经尝试过删除和未删除的 import autoinit。另外,我已经尝试使用 @task 装饰而不是在函数上装饰。都产生相同的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-20
  • 2022-06-10
相关资源
最近更新 更多