Printf() CUDA 中的 45 个参数

问题描述 投票:0回答:2

由于线程触发的顺序,并行打印使得跟踪变量变得非常困难。

因此,我在一行中打印了许多变量进行测试。

我正在尝试从 printf 中的 bool 数组打印 45 个索引,如下所示:

printf( "[%hu%hu%hu%hu%hu][%hu%hu%hu%hu%hu][%hu%hu%hu%hu%hu]\n"
        "[%hu%hu%hu%hu%hu][%hu%hu%hu%hu%hu][%hu%hu%hu%hu%hu]\n"
        "[%hu%hu%hu%hu%hu][%hu%hu%hu%hu%hu][%hu%hu%hu%hu%hu]\n\n",
u[0],
u[1],
u[2],
u[3],
u[4],
u[5],
u[6],
u[7],
u[8],
u[9],
u[10],
u[11],
u[12],
u[13],
u[14],
u[15],
u[16],
u[17],
u[18],
u[19]
u[20],
u[21],
u[22],
u[23],
u[24],
u[25],
u[26],
u[27],
u[28],
u[29],
u[30],
u[31],
u[32],
u[33],
u[34],
u[35],
u[36],
u[37],
u[38],
u[39],
u[40],
u[41],
u[42],
u[43],
u[44],
u[45]);

这显然是在内核中运行的,并且它可以工作,但输出如下:

[11111][11111][11111]
[11111][11111][11111]
[1195633005623389][266612392595893005626661][95899589300563005626661]

[11111][11111][11111]
[11111][11111][11111]
[1195633005623389][266612392595893005626661][95899589300563005626661]

[11111][11111][11111]
[11111][11111][11111]
[1195633005623389][266612392595893005626661][95899589300563005626661]

[11111][11111][11111]
[11111][11111][11111]
[1195633005623389][266612392595893005626661][95899589300563005626661]

[11111][11111][11111]
[11111][11111][11111]
[1195633005623389][266612392595893005626661][95899589300563005626661]

[11111][11111][11111]
[11111][11111][11111]
[1195633005623389][266612392595893005626661][95899589300563005626661]

[11111][11111][11111]
[11111][11111][11111]
[1195633005623389][266612392595893005626661][95899589300563005626661]

[11111][11111][11111]
[11111][11111][11111]
[1195633005623389][266612392595893005626661][95899589300563005626661]

[11111][11111][11111]
[11111][11111][11111]
[1195633005623389][266612392595893005626661][95899589300563005626661]

这里的每个线程输出都用双线分隔。

到目前为止我尝试过的:

  • printf 在内核之外工作得非常好
  • 我改变了索引的顺序,只有最后 15 个参数像垃圾一样出现
  • 我尝试增加 printf 缓冲区大小并使用短裤 %hu
    size_t sz = 1048576 * 10000;
    cudaDeviceSetLimit(cudaLimitPrintfFifoSize, sz);

不知道为什么我最后会得到垃圾值——我最好的猜测是堆栈本身已经耗尽了内存?

有谁知道如何在 cuda 内核中 printf 45 个参数?

注意:我只使用纯 C 版本,直接使用 nvcc 和 Visual Studio 的 cl.exe 进行编译

cuda printf
2个回答
0
投票

我自己想通了——但没有解决办法吗?

除了格式之外,printf() 命令最多可接受 32 个参数 细绳。除此之外的其他参数将被忽略,并且格式说明符 按原样输出

enter image description here

这是图片链接


0
投票

正如其他人提到的,cuda 设备的参数限制为 32 个

printf

AFAICT,您使用如此多的参数执行

printf
的唯一原因是您希望给定线程
printf
有一行。并且能够将输出与各个线程分开。

有一种解决方法......

对于多处理环境中的调试打印,[我发现]它将消息与时间戳和线程标识符相关联。还可以选择函数名称和行号。

警告:我一般对cuda只是稍微熟悉一点,但我过去做过类似的调试...

对于 cuda 设备,

clock64
返回时间戳计数器值。并且,
threadIdx.x
是某种线程标识符。

AFAICT,因为cuda没有

vprintf
,我们应该使用宏。宽松:

编辑:根据paleonix调整

#if MY_CUDA_DEBUG
#define dbgprt(_fmt,_av...) \
    printf("[%llu/%u.%u] " _fmt, \
        clock64(),blockIdx.x,threadIdx.x,_av)
#else
#define dbgprt(_fmt,_av...) \
    do { } while (0)
#endif

dbgprt("hello %s\n","world");

预处理器输出为:

printf("[%llu/%u.%u] " "hello %s\n", clock64(),blockIdx.x,threadIdx.x,"world");

我们将所有

printf
输出转移到文件中。然后,运行后,在主机上我们可以使用后处理脚本通过解析每行前缀信息将各种消息分离到每线程日志文件中。

当然,这只是一个简单的例子。根据需要调整消息的

[]
部分中显示的内容。

© www.soinside.com 2019 - 2024. All rights reserved.