这是我的标头文件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
的最佳方法的提示。
提前非常感谢!!!
答案 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 编译的同一文件中。