Drucken aus Cuda-Kerneln

Lesezeit: 5 Minuten

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

Hebas Benutzeravatar
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

duttasankhas Benutzeravatar
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

C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 4.2\C\src\simplePrintf

in den Projektordner. Fügen Sie dann die Header-Datei hinzu cuPrintf.cuh zu Ihrem Projekt hinzufügen und hinzufügen

#include "cuPrintf.cu"

zu Ihrem Code. Dann sollte Ihr Code in einem der unten genannten Formate geschrieben sein:

#include "cuPrintf.cu"
__global__ void testKernel(int val)
{
  cuPrintf("Value is: %d\n", val);
}

int main()
{
  cudaPrintfInit();
  testKernel<<< 2, 3 >>>(10);
  cudaPrintfDisplay(stdout, true);
  cudaPrintfEnd();
  return 0;
}

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:

if(threadIdx.x==0){
    for(int i=0;i<64;i++){
        for(int j=0;j<8; j++){
            printf("%4.2f  ", ashare[i*8+j]);
        }
        printf("\n");
    }
    printf("\n");
}

Dies kann den gemeinsamen Speicher wunderbar ausdrucken. Beachten Sie auch, dass die Einschränkung nur in threadIdx.x==0 erforderlich ist

1451880cookie-checkDrucken aus Cuda-Kerneln

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy