(int)-1的CUDA内核printf使用%d说明符提供了错误的输出

(int)-1的CUDA内核printf使用%d说明符提供了错误的输出,cuda,printf,format-specifiers,Cuda,Printf,Format Specifiers,用C语言告诉我的电脑 printf("%d",(int)-1); 我确实期望并且通常也会得到一个'-1'响应。然而,在我的特斯拉M2090 Nvidia卡上,我用基于Ubuntu的Cuda 5.0与这个无辜的演示程序通话 /** cheese.cu */ #include <iostream> #include <cuda.h> #include <cstdio> using namespace std; template<typename T&g

用C语言告诉我的电脑

printf("%d",(int)-1);
我确实期望并且通常也会得到一个'-1'响应。然而,在我的特斯拉M2090 Nvidia卡上,我用基于Ubuntu的Cuda 5.0与这个无辜的演示程序通话

/** cheese.cu */
#include <iostream>
#include <cuda.h>
#include <cstdio>

using namespace std;

template<typename T> struct SpacePtr
  { size_t size; T* ptr; };

 __global__ void f(SpacePtr<int>* sp)
{
  printf("This _is_ a 'minus one' or ain't it: %d\n",(int)-1);
  // Note: All appears to work fine with %lu instead of %zd
  // Still: How does the size value affect the -1?
  printf("On DEV: Size: %zd, Minus One: %d\n",sp->size,(int)-1);
}

int main()
{
  SpacePtr<int> data; data.ptr = 0; data.size = 168;
  SpacePtr<int>* devPtr = 0;
  cudaMalloc(&devPtr,1);
  cudaMemcpy(devPtr,&data,sizeof(SpacePtr<int>),cudaMemcpyHostToDevice);
  f<<<1,1,0,0>>>(devPtr);
  cudaError_t err = cudaGetLastError();
  cout << "The last error code was " << err << " (" <<
    cudaGetErrorString(err) << ")" << endl;
  cudaDeviceSynchronize();
}
产生输出:

The last error code was 0 (no error)
This _is_ a 'minus one' or ain't it: -1
On DEV: Size: 168, Minus One: 10005640
最后一个数字实际上是某种随机数(两个子QENT调用返回不同的结果),就好像内存分配有问题一样。-1之前的(int)已经是反复试验。原来的程序没有它


问题是:有人知道为什么没有写-1吗?如果有,你能告诉我为什么吗?非常感谢,Markus。

基本问题似乎是设备printf不支持
%zd
格式说明符(我不确定它是否受支持)

编辑:

CUDA 5中printf的文档说明:

对于标准printf(),格式说明符的形式如下: %[标志][宽度][精度][大小]类型

支持以下字段(请参阅广泛可用的文档 对于所有行为的完整描述):

请注意,CUDA的printf()将接受标志、宽度、, 精度、尺寸和类型,无论它们是否构成有效的 格式说明符。换句话说,“%hd”将被接受并打印F 将在相应位置使用双精度变量 在参数列表中

因此,
%zd
不支持
大小\u t
的格式说明符。按如下方式修改内核:

__global__ void f(SpacePtr<int>* sp)
{
    const int minus_one = -1;
    printf("This _is_ a 'minus one' or ain't it: %d\n", minus_one);
    printf("On DEV: Size: %d, Minus One: %d\n",int(sp->size), minus_one);
}

将数据的全部内容从主机传输到设备。

基本问题似乎是设备printf不支持
%zd
格式说明符(我不确定它是否受支持)

编辑:

CUDA 5中printf的文档说明:

对于标准printf(),格式说明符的形式如下: %[标志][宽度][精度][大小]类型

支持以下字段(请参阅广泛可用的文档 对于所有行为的完整描述):

请注意,CUDA的printf()将接受标志、宽度、, 精度、尺寸和类型,无论它们是否构成有效的 格式说明符。换句话说,“%hd”将被接受并打印F 将在相应位置使用双精度变量 在参数列表中

因此,
%zd
不支持
大小\u t
的格式说明符。按如下方式修改内核:

__global__ void f(SpacePtr<int>* sp)
{
    const int minus_one = -1;
    printf("This _is_ a 'minus one' or ain't it: %d\n", minus_one);
    printf("On DEV: Size: %d, Minus One: %d\n",int(sp->size), minus_one);
}
将数据的全部内容从主机传输到设备。

如果查看CUDA C编程指南,您会发现
%zd
中的
z
修饰符不受支持。您必须强制转换为
无符号long
,并使用
%lu
作为格式说明符:

printf("On DEV: Size: %lu, Minus One: %d\n",(unsigned long)(sp->size), (int)-1);
如果查看CUDA C编程指南,您会发现
%zd
中的
z
修饰符不受支持。您必须强制转换为
无符号long
,并使用
%lu
作为格式说明符:

printf("On DEV: Size: %lu, Minus One: %d\n",(unsigned long)(sp->size), (int)-1);

由于
sp->size
的原因,唯一可能的未定义行为可能是内存分配。如果没有。不要忘记重新编译代码,然后执行。我猜:)显然,printf(“%d”,(int)-1)没有问题这里是对我自己问题的更新:如果我使用“%lu”表示大小\u t,使用“%d”表示臭名昭著的“-1”,那么它似乎有效。因此,可能是因为某种原因,该设备需要C90样式的%lu。仍然:在内核代码之外%zd和%d可以正常工作。我保留这个问题,因为我仍然不知道大小值的错误格式化程序会如何破坏-1的格式。由于
sp->size
的原因,唯一可能的未定义行为可能是内存分配。如果没有。不要忘记重新编译代码,然后执行。我猜:)显然,printf(“%d”,(int)-1)没有问题这里是对我自己问题的更新:如果我使用“%lu”表示大小\u t,使用“%d”表示臭名昭著的“-1”,那么它似乎有效。因此,可能是因为某种原因,该设备需要C90样式的%lu。仍然:在内核代码之外%zd和%d可以正常工作。我保留这个问题,因为我仍然不知道大小值的错误格式化程序会如何破坏-1的格式。我猜这就是打印文档时得到的结果,因此周围有一个过时的纸张变体。。。你的回答恢复了我的信心,让我相信没有在CUDA中发现一个错误,让我对整个事情保持信心!非常感谢!:-)我想这就是一个人打印文档所得到的,因此有一个过时的纸张变体在周围。。。你的回答恢复了我的信心,让我相信没有在CUDA中发现一个错误,让我对整个事情保持信心!非常感谢!:-)回答:也谢谢你。显然我应该更新我的文档。我使用Cuda 4.0手册。在内存分配上:Eeek。对在我的主程序中,我从中破解了这个演示,但它是正确的!;-)回答:也谢谢你。显然我应该更新我的文档。我使用Cuda 4.0手册。在内存分配上:Eeek。对在我的主程序中,我从中破解了这个演示,但它是正确的!;-)
printf("On DEV: Size: %lu, Minus One: %d\n",(unsigned long)(sp->size), (int)-1);