Cuda Hello World printf即使用-arch = sm_20也无法正常工作

时间:2013-03-27 21:26:32

标签: c++ cuda

我不认为我是Cuda的完全新手,但显然我是。

我最近将我的cuda设备升级到1.3到2.1(Geforce GT 630)。我还想完全升级到Cuda toolkit 5.0。

我可以编译一般的cuda内核,但是即使设置-arch = sm_20,printf也不能正常工作。

代码:

#include <stdio.h>
#include <assert.h>
#include <cuda.h>
#include <cuda_runtime.h>

__global__ void test(){

    printf("Hi Cuda World");
}

int main( int argc, char** argv )
{

    test<<<1,1>>>();
        return 0;
}

编译器:

Error   2   error MSB3721: The command ""C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\bin\nvcc.exe" -gencode=arch=compute_10,code=\"sm_20,compute_10\" --use-local-env --cl-version 2010 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin"  -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\include"  -G   --keep-dir "Debug" -maxrregcount=0  --machine 32 --compile -arch=sm_20  -g   -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MDd  " -o "Debug\main.cu.obj" "d:\userstore\documents\visual studio 2010\Projects\testCuda\testCuda\main.cu"" exited with code 2.  C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\BuildCustomizations\CUDA 5.0.targets  592 10  testCuda
Error   1   error : calling a __host__ function("printf") from a __global__ function("test") is not allowed d:\userstore\documents\visual studio 2010\Projects\testCuda\testCuda\main.cu    9   1   testCuda

由于这个问题,我已经完成了生活......已完成。请在屋顶上给我一个答案。

3 个答案:

答案 0 :(得分:17)

如果您在内核中使用printf,则应使用cudaDeviceSynchronize()

#include <stdio.h>
#include <assert.h>
#include <cuda.h>
#include <cuda_runtime.h>

__global__ void test(){
    printf("Hi Cuda World");
}

int main( int argc, char** argv )
{
    test<<<1,1>>>();
    cudaDeviceSynchronize();
    return 0;
}

答案 1 :(得分:7)

在内核中,printf仅支持计算能力2或更高版本的硬件。因为您的项目设置为计算功能1.0和计算2.1的构建,所以nvcc会多次编译代码并构建一个多架构的fatbinary对象。在计算能力1.0编译周期期间,正在生成错误,因为printf调用不支持用于该架构

如果从项目中删除了计算能力1.0构建目标,则错误将消失。

你也可以像这样编写内核:

__global__ void test()
{
#if __CUDA_ARCH__ >= 200
    printf("Hi Cuda World");
#endif
}

[免责声明:用浏览器编写,永不编译,自担风险使用]

在为计算能力2.0或高目标构建时,__CUDA_ARCH__符号仅为> = 200,这将允许您为计算能力1.x设备编译此代码而不会遇到语法错误。

答案 2 :(得分:1)

只需使用cudaDeviceSynchronize()。作为@Tomasz答案的补充。

具有计算能力2.x或更高版本的设备支持从CUDA内核中调用printf。

printf的输出存储在固定大小的循环缓冲区中。并且此缓冲区仅刷新用于:

  • 内核启动的开始
  • 同步(例如cudaDeviceSynchronize())
  • 阻止内存副本(例如cudaMemcpy(...))
  • 模块加载/卸载
  • 上下文破坏

最简单的“ Hello world”示例:

#include <stdio.h>

__global__ void hello() {
    printf("Hello from GPU);
}

int main() {
    hello<<<1, 1>>>();
    cudaDeviceSynchronize();
}

参考: