2013-03-25 9 views
7

Die Thrust-Bibliothek kann zum Sortieren von Daten verwendet werden. Der Aufruf könnte wie folgt aussehen (mit Tasten und Werte Vektor):CUDA: Wie benutzt man schub :: sort_by_key direkt auf der GPU?

thrust::sort_by_key(d_keys.begin(), d_keys.end(), d_values.begin()); 

auf der CPU aufgerufen, mit d_keys und d_values im CPU-Speicher sind; und der Großteil der Ausführung findet auf der GPU statt.

Allerdings sind meine Daten bereits auf der GPU? Wie kann ich die Thrust-Bibliothek verwenden, um effizientes Sortieren direkt auf der GPU durchzuführen, d. H. Um die sort_by_key-Funktion von einem Kernel aus aufzurufen?

Auch besteht meine Daten von Schlüsseln, die entweder unsigned long long int oder unsigned int und Daten sind, die immer unsigned int ist. Wie soll ich den Schub für diese Typen machen?

Antwort

6

Wie in der Frage Talonmies angegeben, können Sie Thrust nicht von einer CUDA-Funktion aufrufen (z. B. __device__ oder __global__). Dies bedeutet jedoch nicht, dass Sie Daten, die Sie bereits im Gerätespeicher haben, nicht mit Thrust verwenden können. Stattdessen rufen Sie die gewünschten Thrust-Funktionen vom Host auf, indem Sie Thrust-Vektoren verwenden, die Ihre Rohdaten umschließen. z.B.

//raw pointer to device memory 
unsigned int * raw_data; 
unsigned int * raw_keys; 
//allocate device memory for data and keys 
cudaMalloc((void **) &raw_data, N_data * sizeof(int)); 
cudaMalloc((void **) &raw_keys, N_keys * sizeof(int)); 

//populate your device pointers in your kernel 
kernel<<<...>>>(raw_data, raw_keys, ...); 

... 

//wrap raw pointer with a device_ptr to use with Thrust functions 
thrust::device_ptr<unsigned int> dev_data_ptr(raw_data); 
thrust::device_ptr<unsigned int> dev_keys_ptr(raw_keys); 

//use the device memory with a thrust call 
thrust::sort_by_key(d_keys, d_keys + N_keys, dev_data_ptr); 

Der Gerätespeicher, auf den raw_data und raw_keys sind noch im Gerätespeicher, wenn Sie sie mit Thrust::device_ptr wickeln, so, während Sie die Schubfunktion vom Host anrufen, es keine Speicher zu kopieren hat von Host zu Gerät oder umgekehrt. Das heißt, Sie sortieren direkt auf der GPU mithilfe des Gerätespeichers. Der einzige Overhead, den Sie haben würden, ist, den Thrust-Kernel zu starten und die unformatierten Device-Pointer einzupacken.

Und natürlich können Sie Ihre RAW-Zeiger zurück, wenn man sie in einem regelmäßigen CUDA Kernel verwenden müssen danach:

unsigned int * raw_ptr = thrust::raw_pointer_cast(dev_data_ptr); 

Was entweder unsigned long long int oder unsigned int als Ihre Schlüssel mit Daten verwenden, die unsigned int ist, Das ist kein Problem, da Thrust templated ist. Das heißt, die Signatur für sort_by_key ist

template<typename RandomAccessIterator1 , typename RandomAccessIterator2 > 
void thrust::sort_by_key(   
    RandomAccessIterator1 keys_first, 
    RandomAccessIterator1 keys_last, 
    RandomAccessIterator2 values_first) 

was bedeutet, dass Sie verschiedene Typen für die Schlüssel und Daten haben. Solange alle Ihre Schlüsseltypen für einen bestimmten Anruf homogen sind, sollte Thrust in der Lage sein, automatisch auf die Typen zu schließen und Sie müssen nichts Besonderes tun. Hoffentlich macht das Sinn

+0

@ user1760748: Beantwortet diese Antwort unten Sie? Wenn nicht, bitte geben Sie an, ob ein Problem damit besteht ... – einpoklum

Verwandte Themen