1

我会尽力说明这一点;

我有两节课;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

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

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

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

谷歌在这个特定问题上基本上没有用,但是按照堆栈,我假设Invalid Handle被引用的是内核函数句柄,而不是块尺寸发生的任何奇怪的事情。

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

4

2 回答 2

4

原因是上下文亲和力。每个 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")
于 2011-05-07T07:35:26.960 回答
1

典型的; 我一写出问题就解决了。

问题在于 SourceModule 在活动上下文之外运行。为了修复它,我将 SourceModule 调用移动到线程中的 run 函数中,在 cuda 上下文设置下方。

暂时搁置一下,因为我相信其他人有更好的解释!

于 2011-05-07T03:37:51.913 回答