Можно ли вызвать «подобный функции макрос» в заголовочном файле из функции CUDA __global__? - PullRequest
1 голос
/ 28 июля 2010

Это часть моего файла заголовка aes_locl.h:

.
.
# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) 
# define GETU32(p) SWAP(*((u32 *)(p))) 
# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } 
.
.

Теперь из файла .cu я объявил функцию __ global__ и включил файл заголовка следующим образом:

#include "aes_locl.h"
.....
__global__ void cudaEncryptKern(u32* _Te0, u32* _Te1, u32* _Te2, u32* _Te3, unsigned char* in, u32* rdk, unsigned long* length)
{
    u32 *rk = rdk;
    u32 s0, s1, s2, s3, t0, t1, t2, t3;

    s0 = GETU32(in + threadIdx.x*(i) ) ^ rk[0];
}

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

ошибка: вызов функции хоста из __ устройства __ / __ global__ функция разрешена только в режиме эмуляции устройства

У меня есть пример кода, где программист вызывает макрос именно таким образом.

Могу ли я назвать это так или это вообще невозможно?Если это не так, я буду признателен за некоторые советы о том, как лучше всего переписать макросы и назначить требуемое значение для S0.

Заранее большое спасибо !!!

Ответы [ 3 ]

4 голосов
/ 29 июля 2010

Я думаю, что проблема не в самих макросах - процесс компиляции, используемый nvcc для кода CUDA, запускает препроцессор C обычным образом, и поэтому использование заголовочных файлов таким способом должно быть нормальным.Я полагаю, что проблема заключается в ваших звонках на номера _lrotl и _lrotr.

. Вы должны иметь возможность проверить, действительно ли это проблема, временно удалив эти вызовы.

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

2 голосов
/ 03 августа 2010

Аппаратное обеспечение не имеет встроенной инструкции поворота, и поэтому не существует встроенного для его раскрытия (вы не можете выставить то, что не существует!).

Это довольно просто реализовать с помощью сдвигов и масок, хотя, например, если x 32-битный, то для поворота влево на восемь битов вы можете сделать:

((x << 8) | (x >> 24))

Где x << 8 будет выталкивать все оставленные восемь битов (т.е. отбрасывать самые левые восемь битов), x >> 24 будет выталкивать все правильные двадцать четыре бита (то есть отбрасывать все, кроме самых левых восьми бит), и побитовое ИЛИ их вместе дает результат, который вам нужен.

// # define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
# define SWAP(x) (((x << 8) | (x >> 24)) & 0x00ff00ff | ((x >> 8) | (x << 24)) & 0xff00ff00)

Конечно, вы могли бы сделать это более эффективным, признав, что вышесказанное является излишним:

# define SWAP(x) (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8))
0 голосов
/ 28 июля 2010

Ошибка говорит о том, в чем проблема на самом деле. Вы вызываете функцию / макрос, определенный в другом файле (который принадлежит коду ЦП), изнутри функции CUDA. Это невозможно!

Вы не можете вызывать функции CPU / 1003 * / макросы / код из функции графического процессора.

Вы должны поместить свои определения (* _lrotl () существует в CUDA?) В тот же файл, который будет скомпилирован с помощью nvcc .

...