CUDA: сортировка вектора & lt; вектор & л; Int & GT; & GT; на ГПУ

Я реализовал свой собственный компаратор для STL sort функция, которая помогает сортировать std::vector< std::vector<int> > на ЦПУ.
Пользователь дает в качестве входа std::vector< std::vector<int> > а также строковую переменную, как, например, 021, При наличии этой строки сортировка выполняется сначала по первому столбцу, затем по третьему столбцу, а затем по второму столбцу. Пример:

  1 2 3
3 2 1
1 1 1
1 1 2

Допустим, строка 10

Выход будет

  1 1 1
1 1 2
1 2 3
3 2 1

Моя реализация процессора использует класс под названием Sortingэтот класс реализован со следующими двумя файлами:

Sorting.h

class Sorting{

private:

public:

Sorting();
~Sorting();
std::vector<std::vector<int>> applySort(std::vector<std::vector<int>>
data,const std::string& attr);

};

Sorting.cpp

 Sorting::Sorting(){}

Sorting::~Sorting(){}std::vector<std::vector<int>> Sorting::applySort(
std::vector<std::vector<int>> data, const std::string& attr){

std::sort(data.begin(), data.begin()+data.size(), Comparator(attr));

return data;
}

Comparator.h

   class Comparator{

private:
std::string attr;

public:
Comparator(const std::string& attr) { this->attr = attr; }

bool operator()(const std::vector<int>& first, const std::vector<int>&
second){

size_t i;
for(i=0;i<attr.size();i++){
if(first[attr.at(i) - '0'] < second[attr.at(i) - '0']) return true;
else if(first[attr.at(i) - '0'] > second[attr.at(i)-'0'])
return  false;
}
return false;
}

};

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

Первоначально я думал, потому что моя цель немного сбивает с толку, может быть, изменение уже известной реализации для сортировки в GPU сделает мою работу. Однако я начал искать много реализаций, подобных описанной здесь: http://blogs.nvidia.com/2012/09/how-tesla-k20-speeds-up-quicksort-a-familiar-comp-sci-code/ и это заставило меня понять, что это будет что-то трудное для достижения.

Я не уверен, что это лучший курс действий. Я начал искать библиотеки и нашел Thrust, Тем не менее, хотя Thrust позволяет вам определить свой собственный компаратор, в вопрос Я спросил вчера, я узнал, что невозможно создать host_vector < host_vector<int> >,

И я думаю, что преобразование моего вектора векторов в один вектор не очень мне поможет, потому что я понятия не имею, как мне тогда реализовать класс компаратора.

Я хотел бы услышать ваше мнение по этому вопросу:

  1. как мне подойти к этой проблеме?
  2. Можно ли добиться этого с Thrust?
  3. Будет ли это делать в GPU намного лучше для моего общего кода? Обратите внимание, что вектор векторов может быть огромным, миллионы строк, но только несколько (5-10) столбцов.
  4. Было бы лучше спроектировать мою собственную сортировку или изменить функцию сортировки, которая уже доступна? Хотя это звучит как хорошая идея, на практике я чувствую, что мне потребуется много усилий, чтобы достичь. Использование простого компаратора и функции сортировки из библиотеки было бы лучшим для меня, однако ограничения Thrust не позволяй мне сделать это

заранее спасибо

2

Решение

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

PS: посмотрите на реализацию lexicographic_sort.cu в коде примера тяги (я тоже его подправил, но этот тоже отстает)
Функция компаратора, которая может вам понадобиться для проверки из двух разных мест в одномерном векторе (который содержит все данные), приведена в списке (кстати, этот метод намного медленнее, чем ЦП), но кто знает, что у вас может возникнуть идея улучшить или использовать его лучше, чем я

struct arbitrary_functor
{
template <typename Tuple>   __host__ __device__
void operator()(Tuple t)
{
if(thrust::get<0>(t)>thrust::get<1>(t))
thrust::get<2>(t) = 1;
else
thrust::get<2>(t) = 0;
}
};

int checkLexo_1vec(const thrust::device_vector<char> & A, int bv1, int bv2, int N){
int i;

thrust::device_vector<char> temp(N);
thrust::device_vector<char> sum(N);

thrust::for_each(thrust::make_zip_iterator(
thrust::make_tuple(A.begin()+bv2, A.begin()+bv1,temp.begin())),
thrust::make_zip_iterator(
thrust::make_tuple(A.end()+(bv2+N),A.end()+(bv1+N), temp.end())),
arbitrary_functor());thrust::inclusive_scan(temp.begin(),temp.end(),sum.begin());

int a = thrust::lower_bound(sum.begin(),sum.end(),1) - sum.begin();

thrust::for_each(thrust::make_zip_iterator(
thrust::make_tuple(A.begin()+bv1, A.begin()+bv2, temp.begin())),
thrust::make_zip_iterator(
thrust::make_tuple(A.end()+(bv1+N), A.end()+(bv2+N),temp.end())),
arbitrary_functor());

thrust::inclusive_scan(temp.begin(),temp.end(),sum.begin());

int b = thrust::lower_bound(sum.begin(),sum.end(),1) - sum.begin();

if(a<=b)
return 1;
else
return 0;
}
1

Другие решения

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

Хорошо, что в этой версии время работы этой функции составляет около 2 мс. с очень большим количеством данных, таких как N = 1000000 to N = 1000В любом случае я публикую код функции и сообщу, если вы обнаружите, что кто-то из пользователей нашел другие улучшения, которые могут сократить общее время работы.

template<typename Ivec>
int lexoMM(Ivec vec, int bv1, int bv2, int N){

typedef thrust::device_vector<int>::iterator Iterator;
thrust::pair<Iterator,Iterator> result;

result = thrust::mismatch(vec.begin()+bv1, vec.begin()+(bv1+N-1), vec.begin()+bv2);

if(result.first == vec.end()){
//cout<<"Both are equal (right order)"<<endl;
return 1;
}
else if(result.first>result.second){
//cout<<"Wrong order"<<endl;
//cout<<*result.first<<","<<*result.second;
return 0;
}
else{
//cout<<"Right order"<<endl;
//cout<<*result.first<<","<<*result.second;
return 1;
}

}

PS: я чувствую, что действительно потратил впустую свое время, чтобы реализовать свою версию этой же вещи, но thrust это круто 🙂

0

По вопросам рекламы [email protected]