2015-02-19 2 views
0

У меня есть 2d массив, и я хочу, чтобы отсортировать его по строкам, означающего, что если массивСортировка 2D массив в Cuda с Thrust

3  2  2  3  2  2  3  3  3  3 
3  3  2  2  2  2  3  3  2  2 
3  2  2  3  2  2  3  3  3  2 
2  2  2  2  2  2  2  2  2  2 
3  2  2  2  2  2  3  2  2  2 
2  2  2  2  2  2  2  2  2  2 
3  3  2  3  2  2  3  3  2  3 
3  3  2  2  2  2  3  3  3  3 
3  2  2  3  2  2  3  3  2  3 
3  3  2  3  2  2  3  3  3  3 

Я хочу взять массив со

2  2  2  2  2  2  2  2  2  2 
2  2  2  2  2  2  2  2  2  2 
3  2  2  2  2  2  3  2  2  2 
3  2  2  3  2  2  3  3  2  3 
3  2  2  3  2  2  3  3  3  2 
3  2  2  3  2  2  3  3  3  3 
3  3  2  2  2  2  3  3  2  2 
3  3  2  2  2  2  3  3  3  3 
3  3  2  3  2  2  3  3  2  3 
3  3  2  3  2  2  3  3  3  3 

I проверили некоторые реализации сортировки radix в чистом CUDA, но они кажутся довольно сложными. Есть ли относительно простой способ сделать это с помощью Thrust?

+0

Итак, вы хотите перестроить строки по порядку их первого элемента? –

+0

Извините, я не дал понять ... Я только что создал более представительный пример ... Я хочу изменить их по порядку их первого элемента, затем второго и т. Д. – Controller

+0

Ваш пример все еще не имеет смысла для меня , Вход показывает 10 строк, а результат показан 9. –

ответ

3

Это можно сделать в тягу. Одним из возможных подходов было бы создание специального функтора сортировки, который пересекает строки, которые ему даны (скажем, строки идентифицируются по индексам, переданным функтору), а затем решает упорядочить эти строки.

Чтобы реализовать это, мы можем создать индексный массив, по одному индексу для каждой строки, который мы будем сортировать. Мы будем сортировать этот индексный массив на основе заданного массива данных (с использованием специализированного функтора сортировки, который упорядочивает строки).

В конце, единственное, что мы отсортировали, это индексный массив, но теперь он находится в порядке, необходимом для повторной компоновки строк, если это необходимо.

Вот полностью работал пример:

$ cat t631.cu 
#include <iostream> 
#include <thrust/device_vector.h> 
#include <thrust/host_vector.h> 
#include <thrust/sort.h> 
#include <thrust/sequence.h> 
#include <thrust/copy.h> 

#define DWIDTH 10 

typedef int mytype; 

struct my_sort_functor 
{ 
    int my_width; 
    mytype *my_data; 
    my_sort_functor(int _my_width, mytype * _my_data): my_width(_my_width), my_data(_my_data) {}; 

    __host__ __device__ 
    bool operator()(const int idx1, const int idx2) const 
    { 
     bool flip = false; 
     for (int col_idx = 0; col_idx < my_width; col_idx++){ 
     mytype d1 = my_data[(idx1*my_width)+col_idx]; 
     mytype d2 = my_data[(idx2*my_width)+col_idx]; 
     if (d1 > d2) break; 
     if (d1 < d2) {flip = true; break;} 
     } 
     return flip; 
    } 
}; 

int main(){ 

    mytype data[] = { 
    3,  2,  2,  3,  2,  2,  3,  3,  3,  3, 
    3,  3,  2,  2,  2,  2,  3,  3,  2,  2, 
    3,  2,  2,  3,  2,  2,  3,  3,  3,  2, 
    2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 
    3,  2,  2,  2,  2,  2,  3,  2,  2,  2, 
    2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 
    3,  3,  2,  3,  2,  2,  3,  3,  2,  3, 
    3,  3,  2,  2,  2,  2,  3,  3,  3,  3, 
    3,  2,  2,  3,  2,  2,  3,  3,  2,  3, 
    3,  3,  2,  3,  2,  2,  3,  3,  3,  3 }; 

    int cols = DWIDTH; 
    int dsize = sizeof(data)/sizeof(mytype); 
    int rows = dsize/cols; 
    thrust::host_vector<mytype> h_data(data, data+dsize); 
    thrust::device_vector<mytype> d_data = h_data; 
    thrust::device_vector<int> idxs(rows); 
    thrust::sequence(idxs.begin(), idxs.end()); 
    thrust::sort(idxs.begin(), idxs.end(), my_sort_functor(cols, thrust::raw_pointer_cast(d_data.data()))); 
    thrust::host_vector<int> h_idxs = idxs; 

    for (int i = 0; i<rows; i++){ 
    thrust::copy(h_data.begin()+h_idxs[i]*cols, h_data.begin()+(h_idxs[i]+1)*cols, std::ostream_iterator<mytype>(std::cout, ", ")); 
    std::cout << std::endl;} 
    return 0; 
} 

$ nvcc -o t631 t631.cu 
$ ./t631 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
3, 2, 2, 2, 2, 2, 3, 2, 2, 2, 
3, 2, 2, 3, 2, 2, 3, 3, 2, 3, 
3, 2, 2, 3, 2, 2, 3, 3, 3, 2, 
3, 2, 2, 3, 2, 2, 3, 3, 3, 3, 
3, 3, 2, 2, 2, 2, 3, 3, 2, 2, 
3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 
3, 3, 2, 3, 2, 2, 3, 3, 2, 3, 
3, 3, 2, 3, 2, 2, 3, 3, 3, 3, 
$ 

Я уверен, что это было бы значительно более эффективно, если эти данные могут быть доставлены в транспонированной форме, и переставить код для сортировки столбцов вместо строк (т.е. сортируйте индексный вектор на основе столбцов в массиве данных, а не в строках). Это будет более эффективно для базового доступа к данным, который будет управляться функтором sort.

Я опустил шаг, который фактически перемещает строки в их новые позиции, но, надеюсь, это должно быть просто. Общая методика намечена в методе для вывода результата, хотя это может быть сделано с помощью одного осевого вызова, если это необходимо.