Это можно сделать в тягу. Одним из возможных подходов было бы создание специального функтора сортировки, который пересекает строки, которые ему даны (скажем, строки идентифицируются по индексам, переданным функтору), а затем решает упорядочить эти строки.
Чтобы реализовать это, мы можем создать индексный массив, по одному индексу для каждой строки, который мы будем сортировать. Мы будем сортировать этот индексный массив на основе заданного массива данных (с использованием специализированного функтора сортировки, который упорядочивает строки).
В конце, единственное, что мы отсортировали, это индексный массив, но теперь он находится в порядке, необходимом для повторной компоновки строк, если это необходимо.
Вот полностью работал пример:
$ 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.
Я опустил шаг, который фактически перемещает строки в их новые позиции, но, надеюсь, это должно быть просто. Общая методика намечена в методе для вывода результата, хотя это может быть сделано с помощью одного осевого вызова, если это необходимо.
Итак, вы хотите перестроить строки по порядку их первого элемента? –
Извините, я не дал понять ... Я только что создал более представительный пример ... Я хочу изменить их по порядку их первого элемента, затем второго и т. Д. – Controller
Ваш пример все еще не имеет смысла для меня , Вход показывает 10 строк, а результат показан 9. –