Генерация последовательности повторяющихся, восходящих целых чисел, используя список, содержащий количество повторений для каждого, с толчком - PullRequest
0 голосов
/ 01 марта 2019

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

thrust::device_vector<int> reps {3, 2, 5, 1};
//This vector should yield a resulting list:
// {0,0,0, 1,1, 2,2,2,2,2, 3}

В идеале я хотел бы сделать это с помощью API-интерфейса тяги.

Я рассмотрел этот подход:

  1. Префикс суммирует список повторений, чтобы получить совокупный список повторений.
  2. Выделите результирующий целочисленный вектор, используя последний элемент в совокупных повторенияхlist.
  3. Используя ядро, запустите поток для каждого элемента списка повторений и выполните цикл из i = 0 : reps[tid], сохраняя tid в cumulative_reps[tid]+i.

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

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

1 Ответ

0 голосов
/ 01 марта 2019

Вы можете сделать это чисто с помощью тяги, используя подход, аналогичный вашему.

  1. Введите префиксную сумму на входе, чтобы определить размер результата для шага 2, и индексы разброса для шага 3
  2. Создать выходной вектор для хранения результата
  3. разбросать по соответствующим местам в выходном векторе, заданном индексами из шага 1
  4. сделать сумму префикса на выходеvector.

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

Вот рабочий пример:

$ cat t404.cu
#include <thrust/scan.h>
#include <thrust/device_vector.h>
#include <thrust/copy.h>
#include <thrust/iterator/constant_iterator.h>
#include <thrust/iterator/permutation_iterator.h>
#include <iostream>

int main(){

  int host_reps[] = {3, 2, 5, 1};
  int ds = sizeof(host_reps)/sizeof(int);
  thrust::device_vector<int> reps(host_reps, host_reps+ds);
  thrust::inclusive_scan(reps.begin(), reps.end(), reps.begin());
  thrust::device_vector<int> result(reps[reps.size()-1]);
  thrust::copy_n(thrust::constant_iterator<int>(1), reps.size()-1, thrust::make_permutation_iterator(result.begin(), reps.begin()));
  thrust::inclusive_scan(result.begin(), result.end(), result.begin());
  thrust::copy_n(result.begin(), result.size(), std::ostream_iterator<int>(std::cout, ","));
  std::cout << std::endl;
}
$ nvcc -o t404 t404.cu
$ ./t404
0,0,0,1,1,2,2,2,2,2,3,
$
...