преобразование тяги, определяющее пользовательскую двоичную функцию

Я пытаюсь написать пользовательскую функцию для выполнения суммы. Я следил за этим вопросом Пользовательская функция Cuda Thrust, чтобы взять ссылку. Вот как я определил свой функтор

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::operator()" не может быть вызвана с заданным списком аргументов

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

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

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


person Kumar Rajput    schedule 13.02.2014    source источник


Ответы (1)


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

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

Поскольку вы прошли:

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

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

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

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

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

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

person Robert Crovella    schedule 13.02.2014
comment
Упс, ты прав. Я использовал другую версию преобразования, которая использует бинарную функцию. Теперь он работает нормально. Спасибо. Что касается создания указателя устройства, в документации они сделали malloc для необработанного указателя, а затем обернули необработанный указатель устройством ptr. Я пропустил шаг malloc, чтобы просто объявить массив. - person Kumar Rajput; 13.02.2014
comment
Не могли бы вы указать в документации, где в указателе есть malloc, за которым следует обертка этого указателя device_ptr? (Или вы имеете в виду cudaMalloc ?) - person Robert Crovella; 14.02.2014
comment
Нет, я имел в виду malloc, на самом деле я прочитал это как malloc вместо cudaMalloc в документации. Понял вашу точку зрения, еще раз спасибо за указание на это. Я трижды читал этот комментарий ранее в документации, в которой говорилось о необработанном указателе на память устройства, и не смог понять, как с помощью malloc он может получить указатель на память устройства. Ранее я думал, что шаг упаковки (хотя и странный) делает то же самое. - person Kumar Rajput; 16.02.2014