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

时间:2011-05-07 03:33:36

标签: python multithreading cuda gpgpu pycuda

我会尽力说清楚;

我有两节课; GPU(Object),用于对GPU功能的一般访问,multifunc(threading.Thread)用于特定功能,我正在尝试使用多设备。 GPU包含所有后续用例所需的大部分“首次”处理,因此从multifunc调用GPU,其self实例作为__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

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

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

我有一个内核模板,其中包含我的所有CUDA代码,这些代码都是文件范围的,并且在jinja2初始化中使用GPU完成了模板化。无论该模板化对象是否转换为SourceModule中的GPU对象并传递给multifunc,或者如果它在multifunc中转换,同样的事情都会发生。

谷歌在这个特定问题上基本没用,但是在堆栈之后,我假设被引用的Invalid Handle是内核函数句柄,而不是块大小的任何奇怪的事情。

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

2 个答案:

答案 0 :(得分:3)

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

如果您根本不使用元编程,您可能会发现将CUDA代码编译为cubin文件更简单,然后使用driver.module_from_file将所需的函数从cubin加载到每个上下文。直接从我的一些生产代码中切割和粘贴:

# 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")

答案 1 :(得分:0)

典型;一旦我写出问题,我就会解决这个问题。

问题是让SourceModule在活动上下文之外运行。为了解决这个问题,我将SourceModule调用移动到了cuda上下文设置下面的线程中的run函数。

暂时搁置一段时间因为我确信其他人有更好的解释!