OpenGL - OpenCL Interaktion [gelöst]



  • Hi,

    ich möchte mit OpenCL die Farbwerte einer Textur (Eines Bildes) verändern und dieses mit OpenGL anzeigen.

    Für die Interaktion zwischen OpenGL und CL verwende ich

    clCreateFromGLTexture2D
    

    um einen Zugriff von OpenCl auf eine OpenGL Textur zu erhalten.

    Zum Test setze ich alle Farkanäle des OpenGL Bildes auf 255, also (255,255,255,255) = weis.
    nun soll der Kernel einfach die Farbe (1.0,0.0,0.0,1.0) setzen.

    Dieses findet jedoch nicht statt, das Bild wird nur weiß angezeigt.

    Ich erhalte den Errorcode -5 bei clEnqueueReleaseGLObjects
    Welcher undokumentiert und hier nicht aufgeführt ist:
    http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clEnqueueReleaseGLObjects.html

    Kommt bei euch der selbe Fehler vor, wenn ihr das Programm ausführt?
    (Wenn nein könnte es ein Treiberproblem sein)

    Habt ihr es schon geschafft ein Programm mit dem Befehl clCreateFromGLTexture2D unter Windows erfolgreich auszuführen?
    (Wenn ja schreibt doch bitte den code ins Forum)

    Oder wo habe ich einen Fehler im Programm?

    #include <windows.h>
    #include <gl/gl.h>
    #include <GL/glut.h>
    #include <CL/cl.h>
    #include <CL/cl_gl.h>
    #include <iostream>
    
    cl_int err;
    cl_uint selectedPlatform;
    cl_device_id selectedDeviceID; 
    cl_context  context;
    cl_command_queue commands;
    cl_program program;
    cl_kernel kernel;
    cl_mem imageOutObject;
    
    GLuint myTexture;
    GLuint textureWidth;
    GLuint textureHeight;
    
    void InitGL(void);
    void InitCL(void);
    
    void Render(void);
    void Resize(int width, int height);
    void SpecialKey(int key, int x, int y);  
    
    int wnd_width  = 800;
    int wnd_height = 600; 
    
    float rotX=0;
    float rotY=0;
    
    int main(int argc, char **argv)
    {
       //initialise OpenGL
       glutInit(&argc, argv);              
       glutInitDisplayMode(  GLUT_DOUBLE | GLUT_DEPTH  | GLUT_RGB);    
       glutInitWindowSize(wnd_width,wnd_height);           
    
       glutCreateWindow("OpenGL-CL interraction!");        
       InitGL(); 
       InitCL(); 
    
       glutDisplayFunc(&Render); 
       glutReshapeFunc(&Resize); 
       glutSpecialFunc(&SpecialKey);
       glutMainLoop();             
    }
    void InitGL(void)
    {
       glClearColor(0.0,0.0,0.0,0.0);          
       glEnable(GL_DEPTH_TEST);
       glEnable(GL_TEXTURE_2D);   
    
       //make OpenGL texture
       textureWidth = 256;
       textureHeight = 256;
       char *buffer = new char[textureWidth * textureHeight * 4];
       for (unsigned int i = 0; i < textureWidth * textureHeight * 4; i++)
       {
          buffer[i] = (char)255;   // RGBA = (255,255,255,255) = white
       }
    
       glGenTextures(1, &myTexture);   
       glBindTexture(GL_TEXTURE_2D, myTexture);
       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );   
       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth,  textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
       glBindTexture(GL_TEXTURE_2D, 0);
    }
    
    void InitCL(void)
    {
       //Get all Platforms and select a GPU one
       cl_uint numPlatforms;
       clGetPlatformIDs (65536, NULL, &numPlatforms); 
       std::cout << "Platforms detected: " << numPlatforms << std::endl;
    
       cl_platform_id* platformIDs;
       platformIDs = new cl_platform_id[numPlatforms];
    
       err = clGetPlatformIDs(numPlatforms, platformIDs, NULL);
       if(err != CL_SUCCESS)
       {
          std::cout << "error at clGetPlatformIDs :" << err << std::endl;
    
       }
    
       selectedPlatform=0;  // simply take first platform(index 0), code for taking correct one is long and not postet here
    
       cl_platform_id selectedPlatformID = platformIDs[selectedPlatform];
       delete[] platformIDs;    
    
       //Select a GPU device
       err = clGetDeviceIDs(selectedPlatformID, CL_DEVICE_TYPE_GPU, 1, &selectedDeviceID, NULL);
       if(err != CL_SUCCESS)
       {
          std::cout << "error at clGetDeviceIDs :" << err << std::endl;      
       }
    
       char cDeviceNameBuffer[1024];
       clGetDeviceInfo (selectedDeviceID, CL_DEVICE_NAME, sizeof(char) *  1024, cDeviceNameBuffer, NULL);
       std::cout  <<": Device Name: "      << cDeviceNameBuffer << std::endl; 
       std::cout << std::endl;
    
       //Get a context with OpenGL connection
       cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),  CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties) selectedPlatformID, 0};
    
       context = clCreateContext(props,1, &selectedDeviceID, NULL, NULL, &err);
       if(!context || err!= CL_SUCCESS)
       {
          std::cout << "error at clCreateContext :" << err << std::endl;   
    
       }
    
       //create a command queue
       commands = clCreateCommandQueue(context, selectedDeviceID, 0,&err);
       if(!commands || err!= CL_SUCCESS)
       {
          std::cout << "error at clCreateCommandQueue :" << err << std::endl;   
       }
    
       //use  the kernel-source code to create a program
       char* kernelSource = "  \
        __kernel void kernel1(write_only image2d_t output)            \n\
       {                                                              \n\
          int2 coordi = (int2)( get_global_id(0), get_global_id(1) ); \n\
           float4 color;                                              \n\
           color = (float4)(1.0,0.0,0.0,1.0);                         \n\
           write_imagef( output,coordi , color );                     \n\
       }";  
    
       int szKernelLength = strlen(kernelSource); 
       program = clCreateProgramWithSource(context, 1,(const char**)& kernelSource, NULL, &err);
       if (!program)
       {   
          std::cout << "error at clCreateProgramWithSource :" << err << std::endl;   
          if (kernelSource) {delete[] kernelSource;}
       }
    
       //Compile the kernel and get errors if exits
       err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
       if(err != CL_SUCCESS)
       {
          size_t len;
          char buffer[2048];
    
          std::cout << "error at clBuildProgram :" << err << std::endl;   
          clGetProgramBuildInfo(program, selectedDeviceID, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len);
          std::cout << "The kernel has bugs: "<< std::endl << buffer << std::endl;
       }
    
       //select the kernel name
       kernel = clCreateKernel(program, "kernel1", &err);
       if (!kernel || err != CL_SUCCESS)
       {
          std::cout << "error at  clCreateKernel :" << err << std::endl;   
       }
    
       //Get an image Object from the OpenGL texture
       imageOutObject= clCreateFromGLTexture2D( context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D,0, myTexture,  &err);
       if (err != CL_SUCCESS)
       {
          std::cout << "error at  clCreateFromGLTexture2D:" << err << std::endl;    
       }
    }
    
    // Interaction to make the program to draw the OpenGL window again
    void SpecialKey(int key, int x, int y)
    {
       switch (key) {
      case GLUT_KEY_UP:
         rotX -= 5;
         break;
      case GLUT_KEY_DOWN:
         rotX += 5;
         break;
      case GLUT_KEY_LEFT:
         rotY -= 5;
         break;
      case GLUT_KEY_RIGHT:
         rotY += 5;
         break;
      default:
         return;
       }
       glutPostRedisplay();
    }
    void Resize(int width, int height)
    {
       glViewport(0, 0, (GLint)width, (GLint)height); 
       wnd_width = width;
       wnd_height= height;
    }
    void Render(void)
    {
       //The OpenCL Part
       size_t localWorkSize[2] = { 8, 8 };
       size_t globalWorkSize[2] =  {textureWidth, textureHeight};
    
       err = clSetKernelArg( kernel, 0, sizeof( imageOutObject ), &imageOutObject );
       if(err != CL_SUCCESS)
       {
          std::cout << "error at clSetKernelArg: " << err << std::endl;    
       }
    
       err = clEnqueueAcquireGLObjects(commands,1,&imageOutObject,0,NULL,NULL);
       if(err != CL_SUCCESS)
       {
          std::cout << "error at clEnqueueAcquireGLObjects: " << err << std::endl;
       }
    
       err = clEnqueueNDRangeKernel(commands, kernel, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL);
       if(err != CL_SUCCESS)
       {
          std::cout << "error at clEnqueueNDRangeKernel: " << err << std::endl;
       }
    
       err = clEnqueueReleaseGLObjects(commands,1,&imageOutObject,0,NULL,NULL);
       if(err != CL_SUCCESS) 
       {
          std::cout << "error at clEnqueueReleaseGLObjects: " << err << std::endl;   
       }
       clFinish(commands);
    
       //The OpenGL Part (simply a quad with the texture)
       glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
       gluPerspective(60.0, 1.0, 1.0, 200.0);     
    
       glMatrixMode(GL_MODELVIEW);
       glLoadIdentity();
    
       glTranslatef (0.0, 0.0 ,-4.0);   
       glRotatef (rotX, 1.0, 0.0, 0.0);   
       glRotatef (rotY, 0.0, 1.0, 0.0);  
       glTranslatef (-0.5, -0.5 , -0.5); 
    
       glBindTexture(GL_TEXTURE_2D, myTexture);
    
       glBegin (GL_QUADS);
       glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
       glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
       glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
       glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
       glEnd ();
       glBindTexture(GL_TEXTURE_2D, 0);
    
       glFinish();
       glutSwapBuffers();
    }
    

  • Administrator

    Andreas XXL schrieb:

    Ich erhalte den Errorcode -5 bei clEnqueueReleaseGLObjects
    Welcher undokumentiert und hier nicht aufgeführt ist:
    http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clEnqueueReleaseGLObjects.html

    Kein Wunder, du schaust dir auch die falsche Dokumentation an. Wir sind inzwischen beim OpenCL 1.1 Standard:
    http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueReleaseGLObjects.html

    -5 ist laut meinem OpenCL 1.1 Header von Nvidia ein CL_OUT_OF_RESOURCES .

    Darf ich mal fragen, wieso du diese Bearbeitung mit OpenCL machst? Wenn ich mich recht erinnere, wäre doch für sowas ein Shader zuständig.
    Und wieso verwendest du nicht die offizielle OpenCL C++ Bibliothek? Sie ist zwar nicht ganz perfekt, ich arbeite aktuell an einer besseren, aber sie erleichtert einem definitiv schon einiges an Arbeit 🙂
    http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.1.pdf
    http://www.khronos.org/registry/cl/api/1.1/cl.hpp

    Grüssli



  • Dravere schrieb:

    Andreas XXL schrieb:

    Ich erhalte den Errorcode -5 bei clEnqueueReleaseGLObjects
    Welcher undokumentiert und hier nicht aufgeführt ist:
    http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clEnqueueReleaseGLObjects.html

    Kein Wunder, du schaust dir auch die falsche Dokumentation an. Wir sind inzwischen beim OpenCL 1.1 Standard:
    http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueReleaseGLObjects.html

    -5 ist laut meinem OpenCL 1.1 Header von Nvidia ein CL_OUT_OF_RESOURCES .

    Darf ich mal fragen, wieso du diese Bearbeitung mit OpenCL machst? Wenn ich mich recht erinnere, wäre doch für sowas ein Shader zuständig.
    Und wieso verwendest du nicht die offizielle OpenCL C++ Bibliothek? Sie ist zwar nicht ganz perfekt, ich arbeite aktuell an einer besseren, aber sie erleichtert einem definitiv schon einiges an Arbeit 🙂
    http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.1.pdf
    http://www.khronos.org/registry/cl/api/1.1/cl.hpp

    Grüssli

    Ich arbeite nicht mit shadern, weil OpenCL deutlich mehr Freiheit bietet.
    Dieses Programm ist nur ein Test. Es soll mal eine Bearbeitung von großen Bilddaten werden (Bilderkennung...), bei der die Ergebnisse der Teilberechnungen sofort angezeigt werden sollen.

    Die offizielle Bibliothek hatte ich noch nicht entdeckt und werde sie jetzt ausprobieren. (Das aktuelle Projekt war mein erster Versuch OpenCl zu verwenden)

    Der Code funktioniert nicht auf meiner Geforce gtx 560 ti.

    Ich habe rausgefunden, dass der selbe Code auf einer Geforce gtx 260 ohne Probleme funktioniert.

    Im Internet haben einige Leute Probleme mit diesem Befehl und Grafikkarten der gtx 5xx Serie. Wenn es auch mit der neuen offiziellen Bibliothek nicht funktioniert (Vielen Dank dafür, ich hatte diese noch nicht entdeckt) ist es ein GPU oder Treiber Problem der 5xx Serie.

    Nachtrag:
    Mit der "http://www.khronos.org/registry/cl/api/1.1/cl.hpp" ist es ganz genauso.
    Es läuft nicht auf der gtx 560 ti aber ohne Probleme auf der 260 gtx.

    Nachtrag2:
    Verwendet man clCreateFromGLBuffer um auf VBOs zuzugreifen, funktioniert es bei beiden Grafikkarten. Das Problem scheint wirklich nur bei dem clCreateFromGLTexture2D Befehl vorhanden zu sein.

    Nachtrag3:
    Mit einer Geforce 9600 läuft das Program ebenfalls problemlos. Mit der gtx 560 ti weiterhin nicht. (Alle Tests mit dem selben Computer ohne Windows oder OpenCL Treiber zu verändern)
    Jetzt muss ich erst mal meinen Bekannten ihre Grafikkarten zurückgeben. Und ich habe auch schon Jemanden gefunden, der seine gtx 260 für ne Weile gegen meine gtx 560 ti tauscht 😃


  • Administrator

    Hast du bei denen Vergleichtests auch sichergestellt, dass überall die gleichen Treiber laufen? Könnte auch am Treiber liegen, mit welchem auch OpenCL kommt.

    Andreas XXL schrieb:

    Nachtrag:
    Mit der "http://www.khronos.org/registry/cl/api/1.1/cl.hpp" ist es ganz genauso.
    Es läuft nicht auf der gtx 560 ti aber ohne Probleme auf der 260 gtx.

    Hätte mich erstaunt, wenn es anders gewesen wäre. Die C++ Sepzifikation ist ja nur ein Wrapper um die C Schnittstelle. Ging mir nur darum, weil du sowieso C++ verwendest (-> <iostream> ), wieso du dir nicht gleich das Leben erleichterst, mit der OpenCL C++ Version 😉

    Grüssli



  • Dravere schrieb:

    Hast du bei denen Vergleichtests auch sichergestellt, dass überall die gleichen Treiber laufen? Könnte auch am Treiber liegen, mit welchem auch OpenCL kommt.

    Andreas XXL schrieb:

    Nachtrag:
    Mit der "http://www.khronos.org/registry/cl/api/1.1/cl.hpp" ist es ganz genauso.
    Es läuft nicht auf der gtx 560 ti aber ohne Probleme auf der 260 gtx.

    Hätte mich erstaunt, wenn es anders gewesen wäre. Die C++ Sepzifikation ist ja nur ein Wrapper um die C Schnittstelle. Ging mir nur darum, weil du sowieso C++ verwendest (-> <iostream> ), wieso du dir nicht gleich das Leben erleichterst, mit der OpenCL C++ Version 😉

    Grüssli

    Die Wrapperklasse kannte ich noch nicht.
    Aber ich habe schon so viel selbst gebastelt (in einer Woche, seit dem ich mich mit OpenCL befasse), dass ich jetzt bei meinen Klassen bleibe. Dieses kleine Testprogramm habe ich nur so zwischendurch gebaut, da ich das minimalste Programm hier posten wollte, welches den Fehler zeigt.
    (Und 3 Tage habe damit verbracht den Fehler zu suchen, der aber dann bei der Grafikkarte lag 🙄 . Warum ich auf die Idee gekommen bin, das nicht funktionierende Programm mit einer anderen Grafikkarte zu testen... keine Ahnung, aber zum Glück habe ich es gemacht. 😃 )

    Für den Test habe ich keinen anderen Treiber installiert. Der Geforce Treiber scheint entweder universell zu sein oder Windows hat selbst passende Treiber gehabt. Ich habe einfach nur die Karten ausgetauscht Windows neu getstartet und das Programm funktionierte. Dann zum Test die alte Karte wieder rein, wieder neu gestartet und es ging wieder nicht mehr. Dann bin ich natürlich bei der gtx 260 geblieben. Es war auch nicht sonderlich schwer meinen Kollegen, der ein leidenschaftlicher Shooter Liebhaber ist (Crysis etc.) zu überreden, für eine längere Zeit meine gtx 560 ti gegen seine gtx 260 zu tauschen.

    Der OpenCL (Cuda) Treiber ist aber definitiv gleich geblieben.

    Zum Spielen ist die Grafikkarte ja echt gut, aber für OpenCl ein echter Albtraum... bis man auf die Idee kommt, dass der Fehler an der Karte (oder Treiber) liegt. 😉

    Auf jeden Fall baue ich jetzt zwei Renderwege ein. Einmal mit clCreateFromGLTexture2D() und einmal mit klassischem Kopierend er Daten über die CPU, Neuerstellen des Texturobjektes und Zurückkopieren in die GPU.

    Das Coole-Neue was ich in den 3 Tagen der Suche entdeckt habe ist, dass bei CPU OpenCL Implementationen direkte printf Ausgaben aus dem Kernel heraus möglich sind. Das kann man gut für das Debuggen verwenden. Alleine dafür lohnt sich der zweite Renderweg schon, denn CPU Implementationen können clCreateFromGLTexture2D() sowieso nicht. Und die Vereinfachung des Debuggens gleicht auch die 3 Tage investierte Zeit locker aus.

    Ich finde es aber erstaunlich welches Potenzial OpenCL hat. Neben der wissenschaftlichen Anwendung auch für Computerspiele. Vertices nicht nur verschoben anzuzeigen wie mit den Shadern, sondern die Verschiebung auch in den VBOs zu speichern. Oder Texturen zur Laufzeit dauerhaft zu verändern man man man.. das wird noch zu Erstaunlichem führen. So könnte bei einer Spielfigur z.B. ein Befehl "klettere über den Zaun" der CPU an die Grafikkarte, die es mit OpenCL umsetzt, ausreichen um die gesamte Animation anzuzeigen, inclusive z.B. der Kollisionstests usw. Die KI von tausenden NPCs könnte in der GPU ablaufen. Der Flaschenhals des Busses kann so entgültig abgeschaft werden.
    In kürze wird man lachen über Crysis. Sah zwar toll aus aber selbst dort war die Umgebung immer noch statisch. Gut man kann Bäume umholzen und manchmal rennt auch nen Krebs am Strand rum. Aber in Zukunft können Landschaften richtig "lebendig" werden. Angefangen von hunderten Fischen im Wasser bis zum Ameisenhaufen mit tausenden von animierten Insekten. Ja ganze Ökosysteme: Ganze Rinderherden die von Löwen gejagt werden, Städte mit Personen in jedem Raum, die einen richtigen Tagesablauf simulieren, Blattschneiderameisen, die ganze Bäume entblättern und die Stücke zum Nest tragen, Fledermausschwärme am Nachthimmel bei dem sogar die Positionen der Sterne simuliert werden. Die Möglichkeiten sind endlos. 👍

    -5 ist laut meinem OpenCL 1.1 Header von Nvidia ein CL_OUT_OF_RESOURCES.

    Dort steht: "CL_OUT_OF_RESOURCES if there is a failure to allocate resources required by the OpenCL implementation on the device. "

    Komisch... wenn man das Wort "required" wegläßt, passt es sogar auf meinen Fall :p


  • Administrator

    Andreas XXL schrieb:

    Ich finde es aber erstaunlich welches Potenzial OpenCL hat. Neben der wissenschaftlichen Anwendung auch für Computerspiele. Vertices nicht nur verschoben anzuzeigen wie mit den Shadern, sondern die Verschiebung auch in den VBOs zu speichern. Oder Texturen zur Laufzeit dauerhaft zu verändern man man man.. das wird noch zu Erstaunlichem führen. So könnte bei einer Spielfigur z.B. ein Befehl "klettere über den Zaun" der CPU an die Grafikkarte, die es mit OpenCL umsetzt, ausreichen um die gesamte Animation anzuzeigen, inclusive z.B. der Kollisionstests usw. Die KI von tausenden NPCs könnte in der GPU ablaufen. Der Flaschenhals des Busses kann so entgültig abgeschaft werden.
    In kürze wird man lachen über Crysis. Sah zwar toll aus aber selbst dort war die Umgebung immer noch statisch. Gut man kann Bäume umholzen und manchmal rennt auch nen Krebs am Strand rum. Aber in Zukunft können Landschaften richtig "lebendig" werden. Angefangen von hunderten Fischen im Wasser bis zum Ameisenhaufen mit tausenden von animierten Insekten. Ja ganze Ökosysteme: Ganze Rinderherden die von Löwen gejagt werden, Städte mit Personen in jedem Raum, die einen richtigen Tagesablauf simulieren, Blattschneiderameisen, die ganze Bäume entblättern und die Stücke zum Nest tragen, Fledermausschwärme am Nachthimmel bei dem sogar die Positionen der Sterne simuliert werden. Die Möglichkeiten sind endlos. 👍

    Ja, was ist daran neu? Daran arbeitet man schon länger. Ein Vorgänger war PhysX, was von Nvidia aufgekauft wurde. Inzwischen läuft PhysX auf der Basis von CUDA, was ja nicht viel anderes als ein proprietäres OpenCL ist. Vor ein paar Jahren hiess es sogar, Nvidia plane PhysX auf OpenCL umzustellen. Ich weiss allerdings nicht, wie weit sie damit sind.
    Es gibt aber auch andere freie Physik-Gameengines, welche OpenCL einsetzen.

    Es sind schlussendlich trotzdem Grenzen gesetzt. Du kannst ja nicht die Graphikkarte nur für die Physiksimulation oder anderes verwenden, sondern musst auch noch die Graphik darstellen. Zudem kann man nicht alles parallelisieren. Auch sind die Streamprozessoren sehr beschränkt in ihrem Befehlssatz.

    Die Entwicklung wird weitergehen, daran ist definitiv nichts neues. Und es wird immer so sein, dass das Zeug von heute, was wir als unglaublich gut ansehen, in ein paar Jahren als völlig veraltet dastehen wird. Erinnere dich zurück, sofern du genug alt bist 😃

    Grüssli


  • Mod

    Andreas XXL schrieb:

    Das Coole-Neue was ich in den 3 Tagen der Suche entdeckt habe ist, dass bei CPU OpenCL Implementationen direkte printf Ausgaben aus dem Kernel heraus möglich sind. Das kann man gut für das Debuggen verwenden.

    deswegen hab ich immer opencl+cuda, bei cuda funzt printf auch 🙂

    ich habe auch mit meiner 560/580 probleme mit opencl, auf 460/480 laeuft es problemlos. auch der opencl 1.1 beta treiber im developer forum scheint nur fur die alte generation ausgelegt zu sein 😞

    Dravere schrieb:

    In kürze wird man lachen über Crysis. Sah zwar toll aus aber selbst dort war die Umgebung immer noch statisch. Gut man kann Bäume umholzen und manchmal rennt auch nen Krebs am Strand rum. Aber in Zukunft können Landschaften richtig "lebendig" werden.

    bist also noch nicht mit nem panzer durch die ganzen huetten dort gefahren, eh? 😛

    Angefangen von hunderten Fischen im Wasser bis zum Ameisenhaufen mit tausenden von animierten Insekten. Ja ganze Ökosysteme: Ganze Rinderherden die von Löwen gejagt werden, Städte mit Personen in jedem Raum, die einen richtigen Tagesablauf simulieren, Blattschneiderameisen, die ganze Bäume entblättern und die Stücke zum Nest tragen, Fledermausschwärme am Nachthimmel bei dem sogar die Positionen der Sterne simuliert werden. Die Möglichkeiten sind endlos. 👍

    lol, es waere wohl guenstiger jedem den joint dafuer mitzuliefern, statt das wirklich in ein spiel einzubauen. Content ist heutzutage das problem, nicht technik!

    Auch sind die Streamprozessoren sehr beschränkt in ihrem Befehlssatz.

    wie meinst du das? hast du ein beispiel? an sich hat man alle moeglichkeiten von c++


  • Administrator

    @rapso,
    Du solltest deine Zitate etwas korrigieren, da kam wohl einiges durcheinander 😃
    Zudem wäre mir neu, dass die CryEngine bereits OpenCL oder CUDA verwendet. Ich dachte, die hätten das erst für die nächste Version in Planung.

    rapso schrieb:

    wie meinst du das? hast du ein beispiel? an sich hat man alle moeglichkeiten von c++

    Die OpenCL C Programmiersprache für die Kernel basiert auf einer eingeschränkten Version von C99. C++ kannst du in keinen der Kernel packen. Siehe dazu auf Seite 193 (6.8 Restrictions):
    http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf

    Streamprozessoren können lesen, rechnen, schreiben und das ist alles.

    Grüssli



  • Dravere schrieb:

    Die OpenCL C Programmiersprache für die Kernel basiert auf einer eingeschränkten Version von C99. C++ kannst du in keinen der Kernel packen. Siehe dazu auf Seite 193 (6.8 Restrictions):
    http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf

    Das ist aber eine Frage des Compilers. Der CUDA C Compiler unterstützt mittlerweile weite Teile von C++, inkl. templates, Vererbung, new/delete, virtuelle Methoden, ...

    Natürlich unterscheidet sich die Art und Weise wie man GPUs programmiert stark davon, wie man CPUs programmiert. Es handelt sich eben um zwei ziemlich orthogonale Programmiermodelle. Aber rein prinzipiell braucht es nicht wirklich mehr als lesen, schreiben, rechnen und den ein oder anderen Jump, um C++ zu supporten (wenn wir mal von der Standardlibrary absehen, Dinge wie Dateizugriff machen auf der GPU natürlich keinen Sinn) 😉


  • Administrator

    @dot,
    Naja, man kann ja C++ eigentlich komplett in C übersetzen und von daher auch kompilieren lassen. Ist mir allerdings neu, dass CUDA C++ in den Kernels versteht. Dies könnte noch zu einem Problem für mich werden.*
    Was mich aber schon etwas stutzig macht, ist die Unterstützung von new/delete. Bist du dir da sicher? Gerade bei der Speicherverwaltung, dachte ich, lägen verschiedene Einschränkungen vor.

    Hast du womöglich ein Dokument dazu?

    Ich arbeite mich nämlich seit ein paar Wochen in OpenCL und CUDA ein. Ich nehme alles was ich lesen kann: Deutsch, Französisch, Englisch 😉

    Wobei eigentlich habe ich bereits eine riesige Sammlung von Dokumenten, welche ich endlich sortieren sollte. Ich suche immer noch das Dokument, wo drin stand, wie sich Streamprozessoren im Vergleich zu normalen CPUs unterscheiden. Irgendwo hatte ich dies doch im Detail gelesen ... bloss wo? 😕 😃

    Edit zu *:
    Ich korrigiere, es ist ein Problem. Mist!
    Und sehe nun auch, dass da new und delete verwendet werden. Das wird schwieriger als erwartet. Obermist!

    Grüssli



  • Dravere schrieb:

    Gerade bei der Speicherverwaltung, dachte ich, lägen verschiedene Einschränkungen vor.

    Natürlich ist so ein new oder delete, vor allem in einer derart hochparallelen Umgebung, jetzt nicht unbedingt die effizienteste aller möglichen Operationen. Aber machbar ist es.

    Dravere schrieb:

    Hast du womöglich ein Dokument dazu?

    Wie wärs mit dem aktuellen CUDA Prgoramming Guide 😉

    Dravere schrieb:

    Ich suche immer noch das Dokument, wo drin stand, wie sich Streamprozessoren im Vergleich zu normalen CPUs unterscheiden. Irgendwo hatte ich dies doch im Detail gelesen ... bloss wo? 😕 😃

    Vermutlich im aktuellen CUDA Programming Guide 😉
    Dass sich die Architektur so einer GPU fundamental von der einer CPU unterscheidet, zweifelt ja auch niemand an. Trotzdem gibt es keinen Grund, wieso man nicht beide in C++ bzw. zumindest einem Subset von C++ programmieren könnte 😉

    Dravere schrieb:

    Ich korrigiere, es ist ein Problem. Mist!
    Und sehe nun auch, dass da new und delete verwendet werden. Das wird schwieriger als erwartet. Obermist!

    Was genau ist denn an new und delete so kompliziert? Es gibt natürlich auch malloc() und free() :p


  • Administrator

    dot schrieb:

    Was genau ist denn an new und delete so kompliziert? Es gibt natürlich auch malloc() und free() :p

    malloc und free stehen in einem Kernel in OpenCL nicht zur Verfügung. Siehe dazu den Punkt f unter Restrictions:

    f. The library functions defined in the C99 standard headers assert.h, ctype.h, complex.h, errno.h, fenv.h, float.h, inttypes.h, limits.h, locale.h, setjmp.h, signal.h, stdarg.h, stdio.h, stdlib.h, string.h, tgmath.h, time.h, wchar.h and wctype.h are not available and cannot be included by a program.

    Ich muss eine CUDA Bibliothek nach OpenCL portieren. Hatte gestern Abend etwas Panik geschoben, als ich von euch erfahren habe, dass in CUDA C++ verwendet werden kann. Es gab leider die letzten paar Tage etwas Verwirrung über den CUDA Quellcode und habe erst vor kurzem nun den endgültigen Code erhalten. Hatte noch nicht viel Zeit den zu analysieren. In den bisher gelieferten Quellcodes wurde nur C im Kernel verwendet. Wie ich nun aber festgestellt habe, hat sich daran nichts verändert. Dafür habe ich erneut einen Unterschied zwischen CUDA und OpenCL gelernt. In CUDA tut man Host-Code und Device-Code mischen; der Kompiler wird die Trennung vornehmen. In OpenCL trennt man den Host- und Device-Code in separate Dateien auf.

    Und nein, ich habe es ganz sicher nicht im CUDA Programming Guide gelesen. Bisher habe ich mich hauptsächlich mit OpenCL auseinander gesetzt. CUDA kam bisher nur am Rande zum Zug.

    Grüssli

    PS: Sorry für das Off-Topic hier 🙂
    Aber solche Diskussionen finde ich immer wieder gut, dann kann ich mein Wissen testen und dabei etwas lernen.


  • Mod

    Dravere schrieb:

    @rapso,
    Du solltest deine Zitate etwas korrigieren, da kam wohl einiges durcheinander 😃

    sehe nichts falsches

    Zudem wäre mir neu, dass die CryEngine bereits OpenCL oder CUDA verwendet. Ich dachte, die hätten das erst für die nächste Version in Planung.

    hab ich auch nicht behauptet. ich sagte lediglich, dass deine auffassung nicht nachvollziehen kann, in crysis kann man sehr viel kaputt machen, nicht nur baeume.

    rapso schrieb:

    wie meinst du das? hast du ein beispiel? an sich hat man alle moeglichkeiten von c++

    Die OpenCL C Programmiersprache für die Kernel basiert auf einer eingeschränkten Version von C99. C++ kannst du in keinen der Kernel packen.

    du sprachst vom befehlssatz der streamprozessoren, nicht vom sprachumfang von opencl.
    opencl ist sehr limitiert, die hardware kann weit aus mehr, wie mit cuda zu sehen ist. jeder bereich hat einen addressraum (also auch konstanten und local store), du kannst function pointer nutzen, exceptions werfen usw.

    Streamprozessoren können lesen, rechnen, schreiben und das ist alles.

    sie koennen genau das, was die cpu deines rechners auf user ebene auch kann. du kannst dir den PTX assembler anschauen (gibt eine documentation von nvidia, leicht zu ergooglen), da wirst du nichts vermissen, denke ich.


  • Mod

    Dravere schrieb:

    Dafür habe ich erneut einen Unterschied zwischen CUDA und OpenCL gelernt. In CUDA tut man Host-Code und Device-Code mischen; der Kompiler wird die Trennung vornehmen. In OpenCL trennt man den Host- und Device-Code in separate Dateien auf.

    du kannst auch in cuda explicit arbeiten, wie bei opencl. aber cuda bietet dir dennoch die anderen moeglichkeiten weiterhin an.
    cuda 4.0 erlaubt auch eine art MPI/cluster umgebung zu nutzen, das heisst, dass du auf einer karte irgendwo im netzwerk auf die daten von einer ganz anderen zugreifen kannst, einfach ueber einen pointer, und die cuda runtime kuemmert sich um den ganzen daten sync. es ist schon ziemlich genial, man arbeitet am ende wie auf einem rechner, hat aber ein cluster versklavt 🙂

    Und nein, ich habe es ganz sicher nicht im CUDA Programming Guide gelesen. Bisher habe ich mich hauptsächlich mit OpenCL auseinander gesetzt. CUDA kam bisher nur am Rande zum Zug.

    lohnt sich CUDA zu lesen, opencl ist zwar hinterher, wird aber auch die moeglichkeiten bieten wie cuda (vielleicht nicht ganz vom sprachumfang, wegen kompatibilitaet, aber was addressraum usw angeht).

    PS: Sorry für das Off-Topic hier 🙂

    ich druecke dir die daumen dass das kein mod sieht 😉


  • Administrator

    rapso schrieb:

    Dravere schrieb:

    @rapso,
    Du solltest deine Zitate etwas korrigieren, da kam wohl einiges durcheinander 😃

    sehe nichts falsches

    Wirklich nicht? Ich helf dir mal auf die Sprünge: Nur das letzte Zitat war von mir, der Rest ist von Andreas XXL. Du hast zwei Zitate mir zugeordnet, obwohl sie das nicht sind.

    Zum Beispiel:

    ich sagte lediglich, dass deine auffassung nicht nachvollziehen kann, in crysis kann man sehr viel kaputt machen, nicht nur baeume.

    Ich habe nie etwas darüber ausgesagt, was man in Crysis kaputt machen kann. Diese Aussage kam von Andreas XXL. Zudem weiss ich selber zu genüge was man alles kaputt machen kann. Mir hat die Demo mit dem Editor damals schon fast gereicht. Da hatte ich zum Teil manchmal schon ein paar Zweifel an meiner psychischen Verfassung 😃

    rapso schrieb:

    lohnt sich CUDA zu lesen, opencl ist zwar hinterher, wird aber auch die moeglichkeiten bieten wie cuda (vielleicht nicht ganz vom sprachumfang, wegen kompatibilitaet, aber was addressraum usw angeht).

    Werde ich definitiv machen, sobald dieses Projekt durch ist. Aber aktuell liegt der Schwerpunkt auf OpenCL.

    rapso schrieb:

    ich druecke dir die daumen dass das kein mod sieht 😉

    Danke. Immer diese bösen Mods von denen man sich in acht nehmen muss. Schon schlimm 🤡

    Grüssli



  • Kann man CUDA und OpenCL gemischt einsetzen?
    Wenn ja, wie?



  • Inwiefern willst du es denn mischen?



  • dot schrieb:

    Inwiefern willst du es denn mischen?

    Das prinf wäre als Debug-Ausgabe schön ^^
    (Ich habe es so verstanden, das es bei CUDA auch bei GPUs funktioniert und nicht nur bei CPUs wie bei OpenCL)



  • Du kannst natürlich CUDA und OpenCL in der selben Anwendung verwenden, sind ja am Ende nur zwei Libraries. Wobei gleichzeitig CUDA und OpenCL verwenden normalerweise eher sinnlos wäre. Du kannst nicht einfach CUDA Code mit OpenCL Code mischen. CUDA läuft auch nur auf NVIDIA Karten...


Anmelden zum Antworten