在cuda设备功能中使用省略号

时间:2014-02-25 22:51:01

标签: c cuda nvcc ptx

我正在尝试将一些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编译器文档以试图理解它。

How can I call a ptx function from CUDA C?

我在Ubuntu 12.04上使用的是GTX660,我相信它是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是设备函数中的有效类型。

1 个答案:

答案 0 :(得分:1)

正如@JaredHoberock所说(我想如果我创建一个答案我不介意):

__device__函数不能有省略号参数;这就是您收到编译器错误消息的原因。

内置printf函数是一种特殊情况,并不表示对省略号的一般支持。

有一些替代方案可以提及,但我所知道的都没有允许真正的通用变量参数支持。例如,正如Jared所说,您可以简单地定义一些参数,其中一些/大多数都指定了默认值,因此不需要显式传递它们。

您也可以像cuPrintf sample code中那样使用模板玩游戏来尝试和模拟变量参数,但这也不是任意可扩展的,我不认为。