4

CUDA Thrust での計算に 2 枚のグラフィック カードを使用したいと考えています。

私は2枚のグラフィックカードを持っています。std::vector に 2 つの device_vector を格納している場合でも、1 枚のカードで実行すると、両方のカードで問題なく動作します。

両方のカードを同時に使用すると、ループの最初のサイクルが機能し、エラーは発生しません。最初の実行後にエラーが発生します。これはおそらく、デバイス ポインタが無効であるためです。

正確な問題が何であるか、または両方のカードを計算に使用する方法がわかりません。

最小限のコード サンプル:

std::vector<thrust::device_vector<float> > TEST() {
    std::vector<thrust::device_vector<float> > vRes;

    unsigned int iDeviceCount   = GetCudaDeviceCount();
    for(unsigned int i = 0; i < iDeviceCount; i++) {
        checkCudaErrors(cudaSetDevice(i) ); 
        thrust::host_vector<float> hvConscience(1024);

                // first run works, runs afterwards cause errors ..
        vRes.push_back(hvConscience); // this push_back causes the error on exec

    }
    return vRes;
}

実行時のエラー メッセージ:

terminate called after throwing an instance of 'thrust::system::system_error'
what():  invalid argument
4

1 に答える 1

6

ここでの問題は、(呼び出しdevice_vectorのため) 異なる GPU コンテキストに存在するペア間でデータのコピーのデバイス間を実行しようとしていることです。cudaSetDeviceおそらく見落としているのは、この一連の操作です。

thrust::host_vector<float> hvConscience(1024);
vRes.push_back(hvConscience);

各ループ反復でコピー元を実行しています。hvConscienceスラスト バックエンドは、ソース メモリと宛先メモリが同じ GPU コンテキストにあることを想定しています。この場合、そうではないため、エラーが発生します。

おそらくやりたいことは、代わりにポインターのベクトルを操作することです。たとえば、次のようになりますdevice_vector

typedef thrust::device_vector< float > vec;
typedef vec *p_vec;
std::vector< p_vec > vRes;

unsigned int iDeviceCount   = GetCudaDeviceCount();
for(unsigned int i = 0; i < iDeviceCount; i++) {
    cudaSetDevice(i); 
    p_vec hvConscience = new vec(1024);
    vRes.push_back(hvConscience);
}

[免責事項: ブラウザーで記述されたコードで、コンパイルもテストもされていません。自己責任で行ってください]

この方法では、正しい GPU コンテキストで各ベクトルを 1 回だけ作成し、ホスト ポインターを割り当ててコピーします。これにより、メモリ空間全体でデバイス側のコピーがトリガーされません。

于 2013-06-03T11:49:12.670 に答える