1

私のアプリケーションは、大量の計算に CUDA カーネルを使用しています。正当な理由から (この質問の範囲外)、共有オブジェクト/リンク モデルを使用して、それぞれが 1 つのホスト関数と 1 つの CUDA カーネルを含むオブジェクト ファイルを動的に読み込みます。externカーネルはそのようなカーネルの基本構造になることはできないため、次のようになります。

__global__ kernel() { ...code... }

extern "C" void call_kernel() {
  <<<GRID,BLOCK,SHMEM>>>kernel();
}

カーネルを呼び出すことを唯一の目的とするホスト関数を使用します。私が使用する共有オブジェクトを構築するために:

nvcc -arch=sm_20 -m64 --compiler-options -fPIC,-shared -link -o kernel0.o kernel0.cu

アプリ全体でこれらのカーネルを大量に使用し、dlopen(). すべて (ビルド/ロード/実行) が 1 台のマシン A にとどまっている場合、全体が正常に機能します。

しかし、共有オブジェクトをマシン B (cuda 4.1、NVIDIA C2050) でコンパイル/ビルドし、dlopen後でマシン A (cuda 4.0、GTX 480) でコンパイル/ビルドすると、共有オブジェクトもビルドされた場合と同じ結果が得られません。マシン A で。

それは私には奇妙に聞こえます。.o特定の GPU アーキテクチャに依存しない命令を含むCUBIN オブジェクトがファイルに埋め込まれていませんか?

ビルドとリンクに同じコンパイラ バージョンを使用することをお勧めします。繰り返しになりますが、共有オブジェクトを実行するのと同じマシン上でビルドしないのには十分な理由があります。

4

1 に答える 1

3

最初のポイントは、アプリケーションで CUBIN ファイルをまったく使用しておらず、CUDA ファット バイナリ オブジェクトを使用していることです。2つのことは同じではありません。

しかし、それはあなたの問題の原因ではありません。問題は CUDA ランタイム ライブラリにあります。ランタイム API はバージョン管理されており、特定のランタイム API バージョン用にコンパイルされたコードは、そのバージョンで実行する必要があります。さらに、ランタイム API ライブラリのバージョンには、ドライバーの最小バージョン要件があります。CUDA 4.1 ライブラリに対してビルドされたアプリケーションを取得して、CUDA 4.0 ライブラリを備えたマシンで実行することを期待することはできません。ランタイム API コードを配布する NVIDIA の推奨方法は、ランタイム API ライブラリ (libcudart) をアプリケーションと共に配布し、コードに必要な最小ドライバー バージョンを指定することです。これにより、アプリケーションが正しく実行されることが保証されます (最小ドライバー バージョンは最小 CUDA ドライバー API バージョンをもたらし、分散ランタイム API ライブラリは完全な要件をもたらします)。

別の方法は、cubin ファイルを実際に使用し、CUDA ドライバー API を使用することです。移植性がはるかに高くなります (ドライバーの最小バージョン要件内) が、ホスト コードでの作業も多くなります。選択はあなた次第です。

于 2012-05-07T11:48:13.920 に答える