Итераторы тяговых устройств не работают

Я не знаю, почему приведенный ниже код не выводит 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

Другие вопросы по тегам