1

これを明確にしようと思います。

2 つのクラスがあります。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コードを含むカーネルテンプレートがありjinja2、初期化でテンプレート化が行われGPUます。そのテンプレート化されたSourceModuleオブジェクトが でオブジェクトに変換されてGPUに渡されるmultifuncかどうか、またはmultifunc同じことが起こるかどうかに関係なく。

Google はこの特定の問題に対してほとんど役に立ちませんでしたが、スタックに従って、Invalid Handle参照されているのはブロック ディメンションで起こっている奇妙なことではなく、カーネル関数ハンドルであると想定しています。

これが非常にまれな状況であることは承知していますが、私が見逃した問題を誰かが見ることができると確信しています。

4

2 に答える 2

4

その理由はコンテキスト アフィニティです。すべての CUDA 関数インスタンスはコンテキストに関連付けられており、移植できません (メモリ割り当てとテクスチャ参照にも同じことが当てはまります)。そのため、各コンテキストは関数インスタンスを個別にロードし、そのロード操作によって返された関数ハンドルを使用する必要があります。

メタプログラミングをまったく使用していない場合は、CUDA コードを cubin ファイルにコンパイルし、必要な関数を 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 の呼び出しを、cuda コンテキスト設定の下のスレッドの run 関数に移動しました。

他の誰かがより良い説明を持っていると確信しているので、これをしばらくそのままにしておきます!

于 2011-05-07T03:37:51.913 に答える