[英]Cuda Hello World printf not working even with -arch=sm_20
我不認為我是 Cuda 的完整新手,但顯然我是。
我最近將我的 cuda 設備升級到了功能 1.3 到 2.1 (Geforce GT 630)。 我還想對 Cuda 工具包 5.0 進行全面升級。
我可以編譯一般的 cuda 內核,但 printf 即使設置了 -arch=sm_20 也無法工作。
代碼:
#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
由於這個問題,我的生活即將結束……完成了。 請從屋頂上告訴我答案。
如果您在內核中使用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;
}
在內核中 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
}
__CUDA_ARCH__
符號在為計算能力 2.0 或高目標構建時只會 >= 200,這將允許您為計算能力 1.x 設備編譯此代碼而不會遇到語法錯誤。
當為正確的架構編譯並且沒有輸出時,您還需要確保內核完成並且驅動程序刷新輸出緩沖區。 為此,請在主機代碼中的內核啟動后添加同步調用
例如:
int main( int argc, char** argv )
{
test<<<1,1>>>();
cudaDeviceSynchronize();
return 0;
}
[免責聲明:所有代碼在瀏覽器中編寫,從未編譯,使用風險自負]
如果你同時做這兩件事,你應該能夠編譯、運行並查看輸出。
只需使用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();
}
參考:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.