2017-02-01 1 views
-1

Gibt es eine Möglichkeit, den Rang eines Elements in einer Matrixzeile separat mit CUDA oder anderen von NVidia bereitgestellten Funktionen zu finden?Rang jedes Elements in einer Matrixzeile mit CUDA

+0

könnten Sie bitte Ihre Frage genauer beschreiben? – Soeren

+0

Details des Problems: Zum Beispiel: Zeilenelemente = [4,1,7,1], Ränge = [1,0,2,0] Der gleiche Rang wird den gleichen Werten zugewiesen. –

Antwort

1

Ich kenne keine eingebaute Ranking oder Argsort-Funktion in CUDA oder einer der mir bekannten Bibliotheken.

Sie könnten eine solche Funktion sicherlich aus Operationen auf niedrigerer Ebene erstellen, die beispielsweise Schub verwenden.

Hier ist eine (nicht optimierten) Skizzierung eines möglichen Lösungsansatz Schub mit:

$ cat t84.cu 
#include <thrust/device_vector.h> 
#include <thrust/copy.h> 
#include <thrust/sort.h> 
#include <thrust/sequence.h> 
#include <thrust/functional.h> 
#include <thrust/adjacent_difference.h> 
#include <thrust/transform.h> 
#include <thrust/iterator/permutation_iterator.h> 
#include <iostream> 

typedef int mytype; 

struct clamp 
{ 
    template <typename T> 
    __host__ __device__ 
    T operator()(T data){ 
    if (data == 0) return 0; 
    return 1;} 
}; 

int main(){ 

    mytype data[] = {4,1,7,1}; 
    int dsize = sizeof(data)/sizeof(data[0]); 
    thrust::device_vector<mytype> d_data(data, data+dsize); 
    thrust::device_vector<int> d_idx(dsize); 
    thrust::device_vector<int> d_result(dsize); 

    thrust::sequence(d_idx.begin(), d_idx.end()); 

    thrust::sort_by_key(d_data.begin(), d_data.end(), d_idx.begin(), thrust::less<mytype>()); 
    thrust::device_vector<int> d_diff(dsize); 
    thrust::adjacent_difference(d_data.begin(), d_data.end(), d_diff.begin()); 
    d_diff[0] = 0; 
    thrust::transform(d_diff.begin(), d_diff.end(), d_diff.begin(), clamp()); 
    thrust::inclusive_scan(d_diff.begin(), d_diff.end(), d_diff.begin()); 

    thrust::copy(d_diff.begin(), d_diff.end(), thrust::make_permutation_iterator(d_result.begin(), d_idx.begin())); 
    thrust::copy(d_result.begin(), d_result.end(), std::ostream_iterator<int>(std::cout, ",")); 
    std::cout << std::endl; 
} 

$ nvcc -arch=sm_61 -o t84 t84.cu 
$ ./t84 
1,0,2,0, 
$ 
+0

danke. Warum ist es nicht optimiert? Wenn ich nicht falsch liege, basiert deine Lösung auf Vektor. Da ich die obige Aufgabe in einer Matrixzeile ausführen möchte, funktioniert Ihre Lösung für diesen Fall? Kann ich es in pyCUDA verwenden? –

+0

Es ist nicht optimiert, weil ich nicht über die verschiedenen Möglichkeiten nachgedacht habe, eine solche Funktion zu erstellen, also stelle ich mir vor, dass es bessere Möglichkeiten gibt. Selbst mit dem, was gezeigt wird, kann eine schlaue Verwendung der Schubfusion zur Verbesserung der Leistung möglich sein. Die beschriebene Methode ist ein Versuch zu zeigen, wie die Zeilenrangierungsfunktion als Konzeptskizze implementiert werden kann. Wenn Sie es auf Matrixreihen gleichzeitig erweitern möchten, stelle ich mir vor, es könnte getan werden, da Schuboperationen auf diese Weise erweitert werden können (siehe die Schubbeispiele). In Bezug auf pyCUDA finden Sie, wenn Sie "Schub-pycuda" googlen, Interop-Beispiele. –

Verwandte Themen