Ich schreibe ein Cuda-Programm und versuche, mithilfe der printf-Funktion etwas innerhalb der Cuda-Kernel zu drucken. Aber wenn ich das Programm kompiliere, erhalte ich eine Fehlermeldung
error : calling a host function("printf") from a __device__/__global__ function("agent_movement_top") is not allowed
error MSB3721: The command ""C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\bin\nvcc.exe" -gencode=arch=compute_10,code=\"sm_10,compute_10\" --use-local-env --cl-version 2008 -ccbin "c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin" -I"C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 4.2\C\common\inc" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\include" -G --keep-dir "Debug" -maxrregcount=0 --machine 32 --compile -g -Xcompiler "/EHsc /nologo /Od /Zi /MDd " -o "Debug\test.cu.obj" "C:\Users\umdutta\Desktop\SANKHA_ALL_MATERIALS\PROGRAMMING_FOLDER\ABM_MODELLING_2D_3D\TRY_NUM_2\test_proj_test\test_proj\test_proj\test.cu"" exited with code 2.
Ich verwende die Karte GTX 560 ti mit einer Rechenkapazität von mehr als 2.0 und als ich ein wenig nach dem Drucken aus Cuda-Kerneln gesucht habe, habe ich auch gesehen, dass ich den Compiler von sm_10 auf sm_2.0 ändern muss, um alle Vorteile nutzen zu können die Karte. Einige schlugen auch vor, dass cuPrintf diesen Zweck erfüllt. Ich bin etwas verwirrt, was ich tun soll und wie ich die Ausdrucke am einfachsten und schnellsten auf den Bildschirm meiner Konsole bekomme. Was soll ich tun, wenn ich den NVCC-Compiler von 1.0 auf 2.0 ändern muss? Ich möchte noch etwas erwähnen, dass ich Windows 7.0 verwende und in Visual Studio 2010 programmiere. Vielen Dank für all Ihre Hilfe.
Es sollte funktionieren, wenn (1) Sie für die sm_21-Zielarchitektur kompilieren und (2) dies sicherstellen #include stdio.h. Die CUDA-Laufzeit umfasst die Geräteüberladung von printf für Kernel, aber die C-Standard-E/A-Bibliothek muss explizit eingebunden werden, damit dieser Mechanismus funktioniert.
– Talonmies
31. Dezember 2012 um 23:15 Uhr
HALLO! Die Standard-I/O-Header-Datei war immer enthalten und die Rechenleistung meiner Karte beträgt 2.1. Daher denke ich, dass es mit den sm_21-Funktionen des nvcc-Compilers kompiliert werden sollte. Ich habe meine Probleme jedoch mithilfe der cuPrintf-Funktion gelöst. Aber ich möchte immer noch wissen, wie ich meine standardmäßige nvcc 1.0-Rechenkapazität auf 2.1-Rechenkapazität ändern kann.
– duttasankha
31. Dezember 2012 um 23:28
@RogerDahl: Das ist perfekt und das funktioniert perfekt. Kannst du deine Antwort einfach posten, damit ich sie auch akzeptieren kann? Du hast meinen Tag gerettet. Danke vielmals.
– duttasankha
1. Januar 2013 um 0:56
Heba
Sie können diesen Code schreiben, um aus dem CUDA-Kernel heraus zu drucken, was Sie wollen:
# if __CUDA_ARCH__>=200
printf("%d \n", tid);
#endif
und schließen Sie < stdio.h > ein
Um die Verwendung von Plain zu ermöglichen printf() Auf Geräten mit einer Rechenleistung >= 2.0 ist es wichtig, für CC mindestens CC 2.0 zu kompilieren und die Standardeinstellung zu deaktivieren, die einen Build für CC 1.0 beinhaltet.
Klicken Sie mit der rechten Maustaste auf .cu Wählen Sie die gewünschte Datei in Ihrem Projekt aus Propertieswählen Configuration Properties | CUDA C/C++ | Device. Klick auf das Code Generation Linie, klicken Sie auf das Dreieck, wählen Sie aus Edit. Deaktivieren Sie im Dialogfeld „Codegenerierung“ das Kontrollkästchen Inherit from parent or project defaultsTyp compute_20,sm_20 Klicken Sie im oberen Fenster auf OK.
Funktioniert nicht. Beschwert sich immer noch darüber, dass printf nicht definiert ist. Meins ist CUDA 6.5 + VS2012 + Tesla2050
– Oh nein
11. März 2015 um 15:54
duttasankha
Eine Möglichkeit, dieses Problem zu lösen, ist die Verwendung der cuPrintf-Funktion, die aus den Kerneln drucken kann. Kopieren Sie die Dateien cuPrintf.cu Und cuPrintf.cuh aus dem Ordner
Wenn Sie dem oben beschriebenen Verfahren folgen, können Sie über die Gerätefunktion einen Ausdruck im Konsolenfenster erhalten. Obwohl ich meine Probleme auf die oben genannte Weise gelöst habe, habe ich immer noch keine Lösung für die Verwendung printf aus der Gerätefunktion. Wenn es wahr und absolut notwendig ist, muss ich meinen NVCC-Compiler von sm_10 auf sm_21 aktualisieren, um das zu aktivieren printf Funktion, dann wäre es sehr hilfreich, wenn mir jemand das Licht zeigen könnte. Vielen Dank für Ihre Mitarbeit
Ich verwende GTX 1650, GTX1050 und C++11. Für aktuelle Benutzer ist dies mein Vorschlag:
In der Hostfunktion:
#include<iostream>
using namespace std;
cout<< .....(anything you want) << endl;
Im Kernel:
if(threadIdx.x==0){
printf("ss=%4.2f \n", ss);
}
Beachten Sie, dass dieses „Wenn“ sehr wichtig ist und mir aufgefallen ist, dass dies niemand erwähnt hat. Weil Sie möglicherweise viele Threads verwenden und auf keinen Fall von jedem Thread zu viel drucken möchten. Auch 4.2f bedeutet 4 Punkte und 2 für Dezimalzahl. Dies kann verhindern, dass zu viel 00000 gedruckt wird. Vergessen Sie auch nicht, \n in die Zeile zu springen.
Sie können auch Folgendes in Betracht ziehen, um den Wert des gemeinsam genutzten Speichers zu drucken:
Es sollte funktionieren, wenn (1) Sie für die sm_21-Zielarchitektur kompilieren und (2) dies sicherstellen
#include stdio.h
. Die CUDA-Laufzeit umfasst die Geräteüberladung von printf für Kernel, aber die C-Standard-E/A-Bibliothek muss explizit eingebunden werden, damit dieser Mechanismus funktioniert.– Talonmies
31. Dezember 2012 um 23:15 Uhr
HALLO! Die Standard-I/O-Header-Datei war immer enthalten und die Rechenleistung meiner Karte beträgt 2.1. Daher denke ich, dass es mit den sm_21-Funktionen des nvcc-Compilers kompiliert werden sollte. Ich habe meine Probleme jedoch mithilfe der cuPrintf-Funktion gelöst. Aber ich möchte immer noch wissen, wie ich meine standardmäßige nvcc 1.0-Rechenkapazität auf 2.1-Rechenkapazität ändern kann.
– duttasankha
31. Dezember 2012 um 23:28
@RogerDahl: Das ist perfekt und das funktioniert perfekt. Kannst du deine Antwort einfach posten, damit ich sie auch akzeptieren kann? Du hast meinen Tag gerettet. Danke vielmals.
– duttasankha
1. Januar 2013 um 0:56