OpenCL



  • Sorry, klappt doch. Problem nur, daß dummy einmal klein und Dummy einmal groß geschrieben ist. 🙂


  • Administrator



  • // to mark a point
    void mark (float3 p, float3 ref, int nx, int ny, int nz, float grid_delta, __global char* resultcloud)
    {
    	//Postpone in reference point.
    	float3 c=p-ref;
    	int xxx;
    	int yyy;
    	int zzz;
    
    	//Strech according to grid_delta.
    	c=c/grid_delta;
    
    	xxx=(int) c.x;
    	yyy=(int) c.y;
    	zzz=(int) c.z;
    
    	//Calculate position in array to be marked.
    	if (xxx<nx)
    	if (yyy<ny)
    	if (zzz<nz)
    	if (xxx>=0)
    	if (yyy>=0)
    	if (zzz>=0) ;;;
    	//resultcloud [ (xxx+yyy*nx+zzz*nx*ny)]=1;
    }
    

    Wo könnte mein Fehler liegen? Ich möchte falsche Punkte rausfiltern, damit mein
    OpenCl nicht abbricht. Obiger Code ist in der selben OpenCl *.cl Datei.



  • Vernunftmensch schrieb:

    [code]
    Wo könnte mein Fehler liegen?

    uns den fehler nicht zu nennen den du beheben moechtest ist der einzige den ich entdecken kann. ansonsten sieht es fehlerfrei aus ;).



  • Die Prozedure umgehe ich jetzt.
    Der Fehler bleibt.
    Unter bestimmten Voraussetzungen (die ich noch nicht kenne) wird schon resultcloud[100]=1; nicht mehr von OpenCl akzeptiert.
    Ich hoffe, daß nicht die Größe des Codeblocks bzw. die Größe der interngenutzten Variablen überschritten wird.

    Gibt ja leider keine Fehlermeldung 😞


  • Administrator

    Was heisst "Fehler"? Was heisst "nicht mehr von OpenCL aktzeptiert"?

    Vernunftmensch schrieb:

    Gibt ja leider keine Fehlermeldung 😞

    Doch, gibt es verschiedentlich. Jede Funktion gibt Fehlercodes zurück, welche man prüfen kann. Zudem gibt es, wie in meinem letzten Beitrag hier erwähnt, auch ein Buildlog.

    Aber solange du uns nicht sagst, was deine Erwartungen vom Programm sind und was du stattdessen erhälst, bzw. was stattdessen passiert, uns somit beschreibst, was du als Fehler siehst, können wir dir unmöglich helfen.

    Grüssli



  • Folgender Code ist innerhalb der richtigen *.cl und läuft.

    Nehme ich aber wesentlich größere Werte als 10*10*10 sehe ich kurz schwarz, der NVIDIA-Treiber lädt neu und dann FAILED beim Zurückschreiben den Ergebnisbuffers.

    min_gew.x=min_gew.y=min_gew.z=0;
    	max_gew.x=10;	max_gew.y=10;	max_gew.z=10;
    
    	x=(int)min_gew.x;
    	while (x<max_gew.x)
    	{
    
    		y=(int)min_gew.y;
    		while (y<max_gew.y)
    		{
    			z=(int)min_gew.z;
    			while (z<max_gew.z)
    			{
    
    				//Calculate point 
    				c.x=(x);
    				c.y=(y);
    				c.z=(z);
    				//std::cout << c;
    
    				//Calculating
    				realpoint=ref+c*grid_delta;
    
    				t=(dotproduct(realpoint,pointc)-fest_oben)/fest_unten;
    
    				quermittelpunkt=pointa+t*pointc;
    
    		         if (t>=0)
    				 if (t<=1)
    					if (vectorlength(realpoint-quermittelpunkt)<=r)
    				      {
    
    						resultcloud [x+y*nx+z*nx*ny]=1;
    
    			          };
    
    				z++;
    			};
    			y++;
    		};
    
    		x++;
    	};
    

    Warum funktioniert hier 10*10*10, aber mehr nicht? Oder baue ich hier zu OpenCl unbemerkt ein Feld auf oder sowas?


  • Administrator

    Und wie rufst du den Kernel auf? Was übergibst du? Wie hast du die verschiedenen Grössen gesetzt? Kannst du es in einem KLEINEN Projekt reproduzieren? usw.

    Sollen wir hellsehen? Da muss ich dich leider enttäuschen. Der GROSSADMINISTRATOR hat alle Glaskugeln konfisziert.

    Grüssli



  • Ich möchte meine CL-Datei posten. Wie kann man hier einen Dateianhang machen?

    Na, gut. Erstmal hier direkt:

    /*
                                                                 ********************************************
                                                                 OpenCl distributor by xxx
    	                                                         ********************************************
     */
    
    // E
    float3 einsvektor()
    {
        float3 e;
    	e.x=e.y=e.z=1;
    	return e;
    }
    
    float vectorlength (float3 a)
    {
        return sqrt(a.x * a.x + a.y * a.y + a.z * a.z); 
    }
    
    /*
    // length
    float operator~(float3 a)
    {
        return sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
    }
    */
    
    // dot product
    float dotproduct (float3 a, float3 b)
    {
         return (a.x * b.x+ a.y * b.y+ a.z * b.z);
    }
    /*
    float operator*(float3 a, float3 b)
    {
        return (a.x * b.x+ a.y * b.y+ a.z * b.z);
    }
    */
    
    void _unmarklinearway (float3 pointa, float3 pointb, 
    	            //float3 ref, 
                    int nx, int ny, 
    				int nz, float r, 
    				float grid_delta,
    				__global char* resultcloud)
    {
    
    	// vector of move of sphere
    	float3 pointc=pointb-pointa;
    
    	float fest_oben=dotproduct(pointa,pointc);
    	//Konstante
    
    	float fest_unten=dotproduct(pointc,pointc);
    	//Konstante
    
    	float r_gew;
    	float3 mz1_gew;
    	float3 mz2_gew;
    	float3 min_gew;
    	float3 max_gew;
    	float3 ref;
    
    	int x,y,z; //Arraypoint.
        float3 c; //Point to calculate.
    	float3 realpoint; //Real point.
    	float3 quermittelpunkt; //Ref point.
    
    	float t;
    
    	// in case of no move betreen last discrete times
    	if (vectorlength(pointc)==0)
    		return;
    
    	ref.x=ref.y=ref.z=0;
    
    	//What to calculate?
        r_gew=r/grid_delta;
    	mz1_gew=(pointa-ref)/grid_delta; //epicenter one
    	mz2_gew=(pointb-ref)/grid_delta; //epicenter two
    	min_gew=mz1_gew; //Really minimums?
    	if (min_gew.x>mz2_gew.x) min_gew.x=(mz2_gew.x);
    	if (min_gew.y>mz2_gew.y) min_gew.y=(mz2_gew.y);
    	if (min_gew.z>mz2_gew.z) min_gew.z=(mz2_gew.z);//Now amen.
    	max_gew=mz1_gew; //Really maximums?
    	if (max_gew.x<mz2_gew.x) max_gew.x=(mz2_gew.x);
    	if (max_gew.y<mz2_gew.y) max_gew.y=(mz2_gew.y);
    	if (max_gew.z<mz2_gew.z) max_gew.z=(mz2_gew.z);//Now amen.
    	max_gew+=einsvektor()+r_gew*einsvektor();
        min_gew-=einsvektor()+r_gew*einsvektor(); //To high or too deep?
    	if (min_gew.x<0) min_gew.x=(0);
    	if (min_gew.y<0) min_gew.y=(0);
    	if (min_gew.z<0) min_gew.z=(0);
    	if (max_gew.x>nx) max_gew.x=(nx);
    	if (max_gew.y>ny) max_gew.y=(ny);
    	if (max_gew.z>nz) max_gew.z=(nz);
    
    	min_gew.x=min_gew.y=min_gew.z=0;
    	max_gew.x=10;	max_gew.y=10;	max_gew.z=10;
    
    	x=(int)min_gew.x;
    	while (x<max_gew.x)
    	{
    
    		y=(int)min_gew.y;
    		while (y<max_gew.y)
    		{
    			z=(int)min_gew.z;
    			while (z<max_gew.z)
    			{
    
    				//Calculate point 
    				c.x=(x);
    				c.y=(y);
    				c.z=(z);
    				//std::cout << c;
    
    				//Calculating
    				realpoint=ref+c*grid_delta;
    
    				t=(dotproduct(realpoint,pointc)-fest_oben)/fest_unten;
    
    				quermittelpunkt=pointa+t*pointc;
    
    		         if (t>=0)
    				 if (t<=1)
    					if (vectorlength(realpoint-quermittelpunkt)<=r)
    				      {
    
    						resultcloud [x+y*nx+z*nx*ny]=1;
    
    			          };
    
    				z++;
    			};
    			y++;
    		};
    
    		x++;
    	};
    };
    
    void _unmarksphere (float3 msphere, 
    	            //float3 ref, 
                    int nx, int ny, 
    				int nz, float r, 
    				float grid_delta,
    				__global char* resultcloud)
    {
         float3 ref;
    	 ref.x=0;
    	 ref.y=0;
    	 ref.z=0;
        float r_gew;
    	int x,y,z; //Arraypoint.
    	float3 realpoint;//Real point.
    
    	//What to calculate?
    	float3 c;
    	float3 m_gew;//Rel. point cloud vector;
    	float3 m_gew2;//Rel. point cloud vector;
    
    	m_gew=msphere-ref;
    	m_gew=m_gew/grid_delta;
    	 r_gew=r/grid_delta;
    
    	m_gew2=m_gew+r_gew*einsvektor()+einsvektor();
    
    	if (m_gew2.x>nx) m_gew2.x=(nx);
    	if (m_gew2.y>ny) m_gew2.y=(ny);
    	if (m_gew2.z>nz) m_gew2.z=(nz);
    
    	x=(int) (m_gew.x-r_gew-1);
    	if (x<0)
    	x=0;
    	while (x<m_gew2.x)
    	{
    	    y=(int) (m_gew.y-r_gew-1);
    	    if (y<0)
    		y=0;
    		while (y<m_gew2.y)
    		{
    
    			z=(int) (m_gew.z-r_gew-1);
    	        if (z<0)
    			z=0;
    			while (z<m_gew2.z)
    			{
    
    				//Calculate actuall rel. cloude-vector.
    				c.x=(x);c.y=(y);c.z=(z);
    
    				//All points are c to check.
    				realpoint=ref+c*grid_delta;
    
    				if (vectorlength(realpoint-msphere)<=r)
    				resultcloud [x+y*nx+z*nx*ny]=1;
    
    				z++;
    			};
    			y++;
    
    		};
    
    		x++;
    	};
    }
    
    void _unmarkconnected (__global const float3* epicenters, 
    	            //float3 ref, 
                    int nx, int ny, 
    				int nz, float r, 
    				float grid_delta,
    				__global char* resultcloud , int igid)
    {
    
    	// unmark the actual sphere
    	_unmarksphere (epicenters[igid], 1000, 500, 100, 5, 1, resultcloud);
    
    	// is there an epicenter before the actual one?
    	if (igid == 0)
    	{
    	 return;
    	};
    
    	// unmark the actual linear way.
    	_unmarklinearway (epicenters[igid-1], epicenters[igid], 1000, 500, 100, 5, 1, resultcloud);
    
    };
    
      // OpenCL Kernel Function for element by element vector addition
    __kernel void moveofsphere(__global const float3* epicenters, __global char* resultcloud, int iNumElements)
    //__kernel void moveofsphereold (__global const float3* epicenters,__global char* resultcloud, int iNumElements, int nx, int ny, int nz, float sphereRad, float delta, float3 refPoint)			
    {
    	// get index into global data array
    	int iGID = get_global_id(0);
    
    	// bound check (Is there another epicenter?) 
    	if (iGID >= iNumElements)
    	{
    		return;
    	};
    
    	_unmarkconnected (epicenters, 1000, 500, 100, 5, 1, resultcloud, iGID);
    }
    

    Ich vermute stark, daß OpenCL versucht, die while-Schleifen selbst zu parallelisieren. Anders kann ich mir nicht erklären, daß es einen Unterschied macht, von wo bis wo gezählt wird. 😞



  • Nein, ich mußte nur einfach mehr Platz zum Arbeiten organisieren.

    OpenCl liefert bei mir jetzt perfekte Ergebnisse.


  • Administrator

    Vernunftmensch schrieb:

    Nein, ich mußte nur einfach mehr Platz zum Arbeiten organisieren.

    ...

    Du gehst die Sache nicht wirklich mit viel Vernunft an ...

    Grüssli


Anmelden zum Antworten