我可以在CUDA __global__函数的头文件中调用“类似函数的宏”吗?

时间:2010-07-28 16:03:57

标签: c macros cuda gpgpu

这是我的标头文件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];
}

这导致我出现以下错误消息:

  

错误:只允许在设备仿真模式下从__ device __ / __ global__函数调用主机函数

我有示例代码,程序员以这种方式完全调用宏。

我可以这样打电话,还是根本不可能?如果不是,我会理解一些关于重写宏并将所需值分配给S0的最佳方法的提示。

提前非常感谢!!!

3 个答案:

答案 0 :(得分:4)

我认为问题不在于宏本身 - nvcc用于CUDA代码的编译过程以通常的方式运行C预处理器,因此以这种方式使用头文件应该没问题。我认为问题在于您致电_lrotl_lrotr

您应该能够通过暂时删除这些呼叫来检查确实是问题。

您应该查看CUDA编程指南,了解更换这些要在GPU上运行的调用所需的功能。

答案 1 :(得分:2)

硬件没有内置的旋转指令,因此没有内在的暴露它(你不能暴露不存在的东西!)。

使用移位和掩码实现起来相当简单,例如,如果x是32位,那么可以左旋8位:

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

x << 8将所有内容都保留为8位(即丢弃最左边的8位),x >> 24将所有内容推送到正确的四位(即丢弃除最左边的8位之外的所有位),并按位将它们组合在一起可以得到您需要的结果。

// # 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))

答案 2 :(得分:0)

错误说明问题究竟是什么。您正在从CUDA函数内部调用另一个文件(属于CPU代码)中定义的函数/宏。这是不可能的!

您无法从GPU功能调用CPU 功能/宏/代码

您应该将您的定义( _lrotl()存在于CUDA中?)在由 nvcc 编译的同一文件中。