2014-02-13 4 views
0

Я пытаюсь написать пользовательскую функцию для выполнения суммы. Я последовал за этот вопрос Cuda Thrust Custom function принять reference.Here как я определил мой функторпреобразование тяги, определяющее пользовательскую двоичную функцию

struct hashElem 
{ 
    int freq; 
    int error; 
}; 
//basically this function adds some value to to the error field of each element 
struct hashErrorAdd{ 
    const int error; 

    hashErrorAdd(int _error): error(_error){} 

    __host__ __device__ 
    struct hashElem operator()(const hashElem& o1,const int& o2) 
    { 
      struct hashElem o3; 
      o3.freq = o1.freq; 
      o3.error = o1.error + (NUM_OF_HASH_TABLE-o2)*error; //NUM_OF_HASH_TABLE is a constant 
      return o3; 
    } 
}; 

struct hashElem freqError[SIZE_OF_HASH_TABLE*NUM_OF_HASH_TABLE]; 
int count[SIZE_OF_HASH_TABLE*NUM_OF_HASH_TABLE]; 

thrust::device_ptr<struct hashElem> d_freqError(freqError); 
thrust::device_ptr<int> d_count(count); 

thrust::transform(thrust::device,d_freqError,d_freqError+new_length,d_count,hashErrorAdd(perThreadLoad)); //new_length is a constant 

Этот код на компиляции выдает следующую ошибку:

ошибка: функция «hashErrorAdd :: оператор()» не может быть вызывается с списком аргументов

типы аргументов: (hashElem)

тип объекта: hashErrorAdd

Может кто-нибудь объяснить мне, почему я получаю эту ошибку? и как я могу это разрешить. Прошу прокомментировать, если я не могу четко объяснить проблему. Спасибо.

ответ

2

Похоже, что вы хотите передать два входных вектора на thrust::transform, а затем сделать преобразование на месте (т. Е. Не указан выходной вектор).

Там нет такого воплощения thrust::transform

Так как вы прошли:

thrust::transform(vector_first, vector_last, vector_first, operator); 

Ближайший подходящий прототип представляет собой вариант преобразования, который принимает один входной вектор и создает один выходной вектор. В этом случае вам нужно будет передать унарный op, который принимает тип входного вектора (hashElem) только в качестве аргумента и возвращает тип, подходящий для выходного вектора, который в этом случае равен int, то есть, как вы написали это (не как ваше намерение). Ваш operator() этого не делает, и он не может быть вызван с аргументами, которые тяга ожидает передать ему.

Как я понимаю, у вас есть несколько вариантов:

  1. Вы можете переключиться на version of transform, который принимает два входных векторов и производит один выходной вектор, и создать двоичный цит как функтор.

  2. Вы можете объединить два входных вектора и сделать in-place transform, если это то, что вы хотите. Тогда ваш функтор был бы унарным оператором, но в качестве аргумента потребовался бы какой-либо кортеж из разыменования входного вектора, и ему пришлось бы возвращать или изменять один и тот же тип кортежа.

Как в стороне, ваш способ создания указателей устройств непосредственно из массивов хостов выглядит нарушенным для меня. Вы можете рассмотреть тягу quick start guide.

+0

Ой, вы правы. Я использовал другую версию преобразования, которая использует двоичную функцию. Теперь он работает отлично. Спасибо. Что касается создания указателя устройства, в документации они сделали malloc на необработанном указателе, а затем взломали необработанный указатель с устройством ptr. Я пропустил шаг malloc, чтобы просто объявить массив. –

+0

Не могли бы вы указать в документации, где есть указатель 'malloc' на указателе, за которым следует упаковка этого указателя с помощью' device_ptr'? (Или вы имеете в виду 'cudaMalloc'?) –

+0

Нет Я имел в виду malloc, на самом деле я прочитал его как malloc вместо« cudaMalloc »в документации. Получил ваш момент, Еще раз спасибо за указание.Я прочитал этот комментарий трижды ранее в документации, в которой говорилось «необработанный указатель на память устройства» и не смог понять, как с помощью malloc он может получить указатель на «память устройства». Раньше я думал, что этот шаг обертывания (хотя и странный) делает это. –

Смежные вопросы