Итераторы тяговых устройств не работают
Я не знаю, почему приведенный ниже код не выводит 1,2, а некоторые случайные числа
#include <thrust/set_operations.h>
#include <thrust/device_vector.h>
#include <ostream>
int main() {
int a[]= { 1,2,3,4,5,6};
int b[] = {1,2,8};
int *ga, *gb,*gr;
cudaMalloc((void**)&ga, 6* sizeof(int));
cudaMalloc((void**)&gb, 3* sizeof(int));
cudaMalloc((void**)&gr, 3* sizeof(int));
cudaMemcpy(ga, a, 6 * sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(gb, b, 3 * sizeof(int), cudaMemcpyHostToDevice);
thrust::device_ptr<int> end;
thrust::device_ptr<int> gaptr(ga);
thrust::device_ptr<int> gbptr(gb);
thrust::device_ptr<int> grptr(gr);
end = thrust::set_intersection(gaptr, gaptr+6, gbptr, gbptr+3,grptr);
printf("%d ", *grptr);
grptr++;
printf("%d ", *grptr);
getchar();
return 0;
}
Более того, как использовать начало и конец1 для перебора всех значений в массиве результатов
1 ответ
Вы пытаетесь перебрать массив целых чисел с помощью итератора для device_vector. Это невозможно. Указатель похож на итератор для массивов в том смысле, что вы можете продвигать указатель с помощью оператора ++ и получать доступ к значению, на которое он указывает, с помощью *. Вы можете использовать grptr напрямую, вместо того, чтобы пытаться создать итератор.
Просто это работает:
std::cout << *grptr << " ";
grptr++;
std::cout << *grptr << std::endl;
Другие заметки, не используйте printf, если вы включаете. Будьте последовательны и используйте cout. Также, если вы действительно хотите попробовать тягу, вы можете сделать это, используя реальные векторы тяги вместо того, чтобы создавать массивы, копировать их вручную и оборачивать их в указатели устройства (если только вы не пытаетесь изучить взаимодействие между тяги и API времени выполнения cuda).
редактировать: я попробовал ваш отредактированный код и действительно printf не работает, пока cout работает. Дело в том, что thrust::device_ptr - это класс, у которого перегружен унарный оператор *, а его типом возврата является thrust::device_reference.
Из документации:
template<typename T> __host__ __device__ reference thrust::device_ptr<T>::operator*(void) const
Этот метод разыменовывает этот device_ptr.
Возвращает: device_reference, ссылающийся на объект, на который указывает этот device_ptr.
Чтобы он правильно вывел желаемое значение, вы можете просто привести его к int:
printf("%d ", (int)*grptr);
grptr++;
printf("%d ", (int)*grptr);
В первоначальном описании класса thrust:: device_reference они приводят пример с printf о том, что решение является приведением. Вы можете проверить это здесь http://wiki.thrust.googlecode.com/hg/html/classthrust_1_1device__reference.html