我不认为我是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
由于这个问题,我已经完成了生活......已完成。请在屋顶上给我一个答案。
答案 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
的输出存储在固定大小的循环缓冲区中。并且此缓冲区仅刷新用于:
最简单的“ Hello world”示例:
#include <stdio.h>
__global__ void hello() {
printf("Hello from GPU);
}
int main() {
hello<<<1, 1>>>();
cudaDeviceSynchronize();
}
参考: