我正在尝试将一些 C 代码移植到 cuda 内核。我移植的代码普遍使用省略号。当我尝试在如下所示的设备函数中使用省略号时,我收到一条错误消息,指出设备函数中不允许使用省略号。
__device__ int add(int a, ...){}
但是,cuda 支持在主机和设备函数中使用 printf,并在自己的代码中使用省略号,如下 common_functions.h 中所示。
extern "C"
{
extern _CRTIMP __host__ __device__ __device_builtin__ __cudart_builtin__ int __cdecl printf(const char*, ...);
extern _CRTIMP __host__ __device__ __device_builtin__ __cudart_builtin__ int __cdecl fprintf(FILE*, const char*, ...);
extern _CRTIMP __host__ __device__ __cudart_builtin__ void* __cdecl malloc(size_t) __THROW;
extern _CRTIMP __host__ __device__ __cudart_builtin__ void __cdecl free(void*) __THROW;
}
有没有办法在设备函数中使用省略号?
我不想硬编码最大数量的参数,然后更改所有调用。
我也不想编写自定义可变参数函数方法。
我还尝试创建一个 PTX 文件,我可以用它来替换省略号的用法,因为 ISA PTX 文档似乎具有处理可变参数的工具(请注意,文档说它不支持它们,然后提供了一个带有支持功能和示例的段落.也许,有一个错字?)。在下面定义的过程中,我一直得到一个简单的 PTX 文件,但在最后一条评论中遇到了可执行问题。我计划阅读 nvcc 编译器文档以尝试理解这一点。
我正在使用 GTX660,我认为它是 Ubuntu 12.04 上的 3.0 级和 cuda 5.0 工具包。
关于下面提到的“魔法”的更新:
在我看来,编译器中一定发生了一些特别的事情来限制省略号的使用并做一些特别的事情。当我如下调用 printf 时:
printf("The result = %i from adding %i numbers.", result, 2);
我很惊讶在 ptx 中发现了这个:
.extern .func (.param .b32 func_retval0) vprintf
(
.param .b64 vprintf_param_0,
.param .b64 vprintf_param_1
)
然后
add.u64 %rd2, %SP, 0;
st.u32 [%SP+0], %r5;
mov.u32 %r6, 2;
st.u32 [%SP+4], %r6;
// Callseq Start 1
{
.reg .b32 temp_param_reg;
.param .b64 param0;
st.param.b64 [param0+0], %rd1;
.param .b64 param1;
st.param.b64 [param1+0], %rd2;
.param .b32 retval0;
call.uni (retval0),
vprintf,
(
param0,
param1
);
在我看来,编译器接受 printf 的省略号,但随后交换对 vprintf 的调用并手动动态创建 va_list。va_list 是设备函数中的有效类型。