2012-05-05 5 views
0

私はNVidia CUDA/Thrustを学ぶために単純なものをプログラミングしようとしています。私は全然ノブです。私がやろうとしているのは、find_ifをカスタム述語とともに使用することです。私の述語は現時点ではすべてを真実に戻すので、すべての入力を得ようとしています。私は最終的にいくつかの文字列Xでファンクタを初期化し、GPUが一致するすべての文字列を見つけることを可能にする文字列を検索したいと思います。ベクトルと反復子によるNVidia推力プログラミング - 基本的な質問

私はここでいくつかの点を混乱させる。

私は、私の文字列へのポインタでいっぱいのdevice_vectorを埋めて、それを私のMemCmp述語に対して実行しようとしています。

最初に、device_vectorがメインメモリからGPUメモリに文字列をコピーすることを「知っている」か、単にポインタ値をコピーしますか?

第2に、「count = d_inputVector.end() - iter;」という行で、 find_ifの結果であるイテレータの項目数である12を返します。これは間違っていませんか?私がiterを試してみると、d_inputVector.begin()はゼロを返します。これはどこでも取得できません。

最後に、自分の小さなプログラムの結果を正しく取得する方法はありますか?私はthrust :: copyを使ってメモリをhost_vectorにコピーしていますか?最後のもののようなループで結果を見るには十分でしょうか?

ご意見をいただければ幸いです。おかげで、

MJ

struct MemCmp 
{ 
    __host__ __device__ 
    bool operator()(char *data) 
    { 
     bool rv = false; 
     rv = true; 

     return rv; 
    } 
}; 

.... 

// I initialize a device_vector and then copy pointers from main memory into the device_vector. 
thrust::device_vector<char*> d_inputVector(itemCount); 

for(int i=0; i<itemCount; i++){ 
    d_inputVector[i] = inputData[i]; 
} 

thrust::device_vector<char*>::iterator iter; 
iter = thrust::find_if(d_inputVector.begin(), d_inputVector.end(), MemCmp()); 

    // this is the count that I think is wrong. 
count = d_inputVector.end() - iter; 

thrust::host_vector<char*> results(count); 

thrust::copy(d_inputVector.begin(), iter, results.begin()); 

for(thrust::host_vector<char *>::iterator it = results.begin(); it != results.end(); it++){ 
    char* foo = *it; 
} 

答えて

2

find_ifは一致するすべての文字列を見つけるための良い機能ではありません。それは、単に一致する最初の最初の要素を見つけます。 copy_ifをご覧ください。

まず、device_vectorが私の文字列をメインメモリからGPUメモリにコピーすることを「知っている」か、ポインタ値をコピーするだけですか?

GPUで意味のないポインタ値になります。

C++では、CPU上で実行するには、std::stringを使用して文字列を格納します。したがって、std::vector<std::string>になります。問題は、デバイスの実装がstringでないという事実によって複雑になるため、GPUにそれらをコピーすることはできません。

さらに、多くのSTLアルゴリズム(これはthrustと同じです)では、ベクトルの要素であるオブジェクトに作業コピーコンストラクタと代入演算子が必要です。コンパイラは基本型のものを提供しますが、charの配列は提供しません。

CUDA/Trustを学ぶための簡単な練習はそれほど簡単ではないかもしれません。私はと思う固定サイズの文字配列をカプセル化し、必要な演算子のデバイス関数を実装するC++クラスが必要です。

device_vectorに割り当てる各割り当てによって、ホストからデバイスメモリへの別のコピーがバックグラウンドで実行されるため、このように多くの項目を含むベクターをデバイスメモリに移動することは非常に非効率的です。代わりに、host_vectorを入力し、host_vectordevice_vectorに割り当てます。その後、ホストからデバイスメモリへのコピーが1つだけ実行されます。

第2に、「count = d_inputVector.end() - iter;」という行で、 find_ifの結果であるイテレータの項目数である12を返します。これは間違っていませんか?私がiterを試してみると、d_inputVector.begin()はゼロを返します。これはどこでも取得できません。

式はcount = d_inputVector.begin() - iter;である必要があります。ベクトルの最初の要素がfindと一致するため、式は0を返す必要があります。

最後に、私の小さなプログラムの結果を正しく取得する方法はありますか?私はthrust :: copyを使ってメモリをhost_vectorにコピーしていますか?最後のもののようなループで結果を見るには十分でしょうか?

あなたの結果とdevice_vectorを作成した後、単に単一の操作でメモリをホストするために、それを動かすためにhost_vectorに割り当てます。

thrust::host_vector<char*> H = D; 
+0

返信いただきありがとうございます。追加の質問は、char配列のようなメモリのセクションをコピーする適切な方法は何ですか? thrust :: device_vector = char [1000];私のC++を許して、それはしばらくしています。 –

+0

回答にセクションを追加しましたが、必要なものに対してはまだ不十分です。私は別の質問にこの部分を壊すことをお勧めします。つまり、推力を使用して文字列のベクトルを処理する方法(一致するすべての文字列を見つける方法など)です。ここには非常に知識のある人が答えられるはずです。 –

+0

もう一度ありがとうございます。 mj –