thrust transform, дефиниращ персонализирана двоична функция

Опитвам се да напиша персонализирана функция за извършване на сума. Проследих този въпрос Cuda Thrust Custom function, за да направя справка. Ето как дефинирах своя функтор

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. Можете да превключите към версия на transform, която приема два входни вектора и произвежда един изход вектор и създайте двоична операция като функтор.

  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