Итераторы тяговых устройств не работают - PullRequest
0 голосов
/ 27 октября 2011

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

0 голосов
/ 27 октября 2011

Вы пытаетесь перебрать массив целых чисел с помощью итератора для device_vector.Это невозможно.Указатель подобен итератору для массивов в том смысле, что вы можете продвигать указатель с помощью оператора ++ и получать доступ к значению, на которое он указывает, с помощью *.Вы можете использовать grptr напрямую, вместо того, чтобы пытаться создать итератор.

Просто это работает:

std::cout << *grptr << " ";
grptr++;
std::cout << *grptr << std::endl;

Другие примечания, не используйте printf, если вы включаете.Будьте последовательны и используйте cout.Также, если вы действительно хотите попробовать тягу, вы можете сделать это, используя настоящие векторы тяги вместо того, чтобы создавать массивы, копировать их вручную и оборачивать их в указатели устройств (если только вы не пытаетесь научиться взаимодействию между тяги и API времени выполнения cuda).

edit: я пробовал ваш отредактированный код и действительно 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

...