2017-02-01 20 views
-1

Есть ли способ найти ранг элемента в строке матрицы отдельно, используя CUDA или любые функции для того же, что и NVidia?Ранг каждого элемента в строке матрицы с использованием CUDA

+0

могли бы вы описать свой вопрос более подробно? – Soeren

+0

Детальная информация о проблеме: Например: Элементы строки = [4,1,7,1], ranks = [1,0,2,0] Тот же ранг будет присвоен равным значениям. –

ответ

1

Я не знаю о встроенной функции ранжирования или argsort в CUDA или в любой из библиотек, с которыми я знаком.

Вы можете, конечно, создать такую ​​функцию из операций нижнего уровня, используя, например, тягу.

Вот (не оптимизировано) очертание возможного подхода решения с использованием тяги:

$ 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

спасибо. Почему он не оптимизирован? Если я не ошибаюсь, ваше решение основано на векторе. Поскольку я хочу выполнить вышеупомянутую задачу в строке матрицы, ваше решение работает в этом случае? Могу ли я использовать его в pyCUDA? –

+0

Это не оптимизировано, потому что я не думал обо всех различных способах создания такой функции, поэтому я думаю, что есть более оптимальные способы. Даже с тем, что показано, может быть умное применение слияния с целью повышения производительности. Описанный метод - попытка показать, как функция ранжирования строк может быть реализована как эскиз концепции. Если вы хотите расширить его для работы с матричными рядами сразу, я предполагаю, что это можно сделать, поскольку операции тяги могут быть расширены таким образом (посмотрите на примеры тяги). Что касается pyCUDA, если вы google «thrust pycuda», вы найдете примеры взаимодействия. –