我正在尝试将一些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文档似乎有处理变量参数的工具(注意文档中说它不支持这些参数,然后提供了一个带有支持函数和示例的段落)。也许,有一个拼写错误?).I在下面定义的整个过程中得到了一个简单的PTX文件,但在最后一条评论中遇到了可执行问题。我计划阅读nvcc编译器文档来尝试理解这一点。
How can I call a ptx function from CUDA C?
我使用的是GTX660,我相信它是Ubuntu12.04上的3.0级和CUDA5.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是设备功能中的有效类型。
最佳答案
正如@JaredHoberock所说(我想他不会介意我做一个回答):__device__
函数不能有省略号参数;这就是接收编译器错误消息的原因。
内置的printf
函数是一个特例,并不表示一般支持省略。
有一些替代方案可以提及,但没有一个我知道允许真正的通用变量参数支持。例如,正如Jared所说,您可以简单地定义一些参数,其中一些/大多数参数都指定了默认值,因此不需要显式地传递它们。
您也可以像在cuPrintf sample code中那样使用模板来尝试和模拟变量参数,但这也不是任意可扩展的,我不认为。
关于c - 在Cuda设备功能中使用省略号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22027955/