PyCUDA+Threading = 内核调用的无效句柄

Bol*_*ter 1 python multithreading cuda gpgpu pycuda

我会尽力澄清这一点;

我有两节课;GPU(Object),对于 GPU 功能的一般访问,multifunc(threading.Thread)对于特定的功能,我正在尝试多设备化。GPU包含所有后续用例所需的大部分“第一次”处理,因此通过将其实例作为参数传递(以及通常的队列等)multifunc来调用。GPUself__init__

不幸的是,multifunc废话:

File "/home/bolster/workspace/project/gpu.py", line 438, in run
    prepare(d_A,d_B,d_XTG,offset,grid=N_grid,block=N_block)
  File "/usr/local/lib/python2.7/dist-packages/pycuda-0.94.2-py2.7-linux-x86_64.egg/pycuda/driver.py", line 158, in function_call
    func.set_block_shape(*block)
LogicError: cuFuncSetBlockShape failed: invalid handle
Run Code Online (Sandbox Code Playgroud)

第一个停靠点当然是块尺寸,但它们完全在范围内(即使我强制block=(1,1,1),也会有相同的行为,同样 grid.

基本上,在 中multifunc,所有常见的 CUDA memalloc 等函数都可以正常工作(这意味着它不是上下文问题),因此问题必须出在SourceModule内核函数本身的问题上。

我有一个内核模板,其中包含文件范围内的所有 CUDA 代码,并且模板化是jinja2GPU初始化中完成的。无论该模板化对象是否转换为SourceModulein 中的对象GPU并传递给,或者是否发生相同的multifunc转换。multifunc

谷歌对于这个特定问题基本上没有用处,但根据堆栈,我假设所指Invalid Handle的是内核函数句柄,而不是块尺寸方面发生​​的任何奇怪的情况。

我知道这是一个非常极端的情况,但我确信有人可以看到我错过的问题。

tal*_*ies 5

原因是上下文亲和力。每个 CUDA 函数实例都与上下文相关联,并且它们不可移植(这同样适用于内存分配和纹理引用)。因此,每个上下文必须单独加载函数实例,然后使用该加载操作返回的函数句柄。

如果您根本不使用元编程,您可能会发现将 CUDA 代码编译到 cubin 文件,然后使用driver.module_from_file. 直接从我的一些生产代码中剪切和粘贴:

# Context establishment
try:
    if (autoinit):
        import pycuda.autoinit
        self.context = None
        self.device = pycuda.autoinit.device
        self.computecc = self.device.compute_capability()
    else:
        driver.init()
        self.context = tools.make_default_context()
        self.device = self.context.get_device()
        self.computecc = self.device.compute_capability()

    # GPU code initialization
    # load pre compiled CUDA code from cubin file
    # Select the cubin based on the supplied dtype
    # cubin names contain C++ mangling because of
    # templating. Ugly but no easy way around it
    if self.computecc == (1,3):
        self.fimcubin = "fim_sm13.cubin"
    elif self.computecc[0] == 2:
        self.fimcubin = "fim_sm20.cubin"
    else:
        raise NotImplementedError("GPU architecture not supported")

    fimmod = driver.module_from_file(self.fimcubin)

    IterateName32 = "_Z10fimIterateIfLj8EEvPKT_PKiPS0_PiS0_S0_S0_jjji"
    IterateName64 = "_Z10fimIterateIdLj8EEvPKT_PKiPS0_PiS0_S0_S0_jjji"

    if (self.dtype == np.float32):
        IterateName = IterateName32
    elif (self.dtype == np.float64):
        IterateName = IterateName64
    else:
        raise TypeError

    self.fimIterate = fimmod.get_function(IterateName)

except ImportError:
    warn("Could not initialise CUDA context")
Run Code Online (Sandbox Code Playgroud)