C OpenCL IMac - ATI 48xx

MPi

Cadet 2nd Year
Registriert
Mai 2011
Beiträge
23
Hallo zusammen,

ich arbeite zur Zeit an einem kleinen Programm auf PC und Mac das OpenCL nutzen soll. Auf dem Mac (OpenCL 1.0) habe ich ein Problem, eigentlich 2, die ich überhaupt nicht verstehe:

(Hinweis: Die Kernels laufen auf dem PC auf CPU und GPU (sowohl Nvidia und ATI) einwandfrei, auf dem Mac laufen die Kernels bei CPU Nutzung auch einwandfrei)

Nr 1: OpenCL Kernel
void __kernel contrast(const uint sizex, const uint sizey, __global float* source, __global float* dest)
{
int x=get_global_id(0);
int y=get_global_id(1);

float4 color = {0.f, 0.f, 0.f, 0.f};
float param1=1.5f;

color = GetPixel(x, y, sizex, source);

color = color * param1; //<-- die Problemzeile, die auf Mac auf der Gpu dazu führt, dass das Bild immer Schwarz wird

color = clamp(color,0.0f,1.0f);

dest[(y*sizex + x)*3 + 0] = color.x;
dest[(y*sizex + x)*3 + 1] = color.y;
dest[(y*sizex + x)*3 + 2] = color.z;
}

Wenn ich die rote Zeile komponentenweise schreibe, läuft es, also:
color.x = color.x * param1;
color.y = color.y * param1;
color.z = color.z * param1;

Das würde bedeuten man kann auf der Mac-GPU unter OpenCL keine Vektor <--> Skalar Multiplikation machen?!

Nr 2: OpenCL Kernel
void __kernel MP_calcMandelbrot(const uint sizex, const uint sizey, __global float* source, __global float* dest)
{
int x=get_global_id(0);
int y=get_global_id(1);

float4 color = {0.f, 0.f, 0.f, 0.f};

float xmin=-2.1f, xmax= 1.0f, float ymin=-1.3f, ymax= 1.3f;
float xdelta=(xmax-xmin)/(float)sizex, ydelta=(ymax-ymin)/(float)sizey;

float xx,x1,y1;
int iteration;
itermax = 256;

float xp=xmin+x*xdelta;
float yp=ymin+y*ydelta;

x1=0.0f;
y1=0.0f;
for (iteration=1; iteration<itermax; iteration++)
{
xx = x1*x1-y1*y1+xp;
y1 = 2.0f*x1*y1+yp;
x1 = xx;
if (!(x1*x1+y1*y1<4.0f))
{
color.x=(float)iteration;
color.y=(float)iteration;
color.z=(float)iteration;
}

if (!(x1*x1+y1*y1<4.0f)) iteration=itermax; //<-- die Problemzeile
}

//Pixel schreiben
dest[y*sizex + x] = color;
}

Wenn ich die rote Zeile auskommentiere, funktioniert der Kernel, sobald ich sie einfüge, kommt überhaupt nichts mehr bei "dest[..]" an.
Eine While Schleife habe ich auch probiert, diverse varianten der Abbruchbedingungen, immer mit dem gleichen Ergebnis.

Hat irgendjemand eine Idee, was ich auf dem Mac bei GPU-Nutzung falsch mache?

Danke Euch!
 
Zuletzt bearbeitet:
Kenn mich mit OpenCL nicht aus, aber mit CUDA. Und bei Cuda war eine große Fehlerquelle immer das Reinlaufen in Race Conditions. Und da ich keine Syncs in deinem Code sehe, könnte es daran liegen. Außerdem treten Raceconditions nur auf einzelnen Systemen auf und können weggehen (scheinbar), durch das rauskommentieren scheinbar irrelevanter Zeilen.
Ergänzung ()

Außerdem könnte es auch sein, dass der Bildschirmtreiber vllt nur eine bestimmte Zeit OpenCL zulässt. Auch das gibts zumindest bei CUDA. Und damit der Bildschirm weiter bedient werden kann, wird der OpenCL Prozess gekillt. Das würde nen schwarzen Bildschirm erklären, falls der Treiber crasht, bzw. leere Ergebnisse, falls der Prozess gekillt wird.
Mehr Ideen hab ich nicht, der Code sieht ok aus :)
 
Zuletzt bearbeitet:
Zuerst: Es gibt as CODE Tag.

Vektorrechnung müsste OpenCL schon können.

Was passiert bei GetPixel? Ich kenns nur als GDI Funktion^^.

Zu Problem 2:
Warum nicht ein break und warum machst du zweimal den gleichen Vergleich?
Und was heißt "kommt überhaupt nix mehr an", bei mir stürtzt ne Endlosschleife immer ab (inkl. GPU-Reset).
 
Danke für Eure Antworten!

@Misu:
RaceConditions kann ich eigentlich ausschliessen, aber ich werde es auch nochmal mit Syncs probieren.

Die Zulässigkeit einer bestimmten Zeit auf der GPU habe ich auch schon in Erwägung gezogen, sollte aber bei Zeiten um insg. < 20ms eigentlich nicht vorkommen, oder doch?


@Blitzmerker:
Die getPixel Funktion ist eine eigene Funktion, die auch bei Tests die richtigen Ergebnisse liefert:

float4 GetPixel(int x, int y, int sizex, __global float* textur)
{
float4 color = {0.f, 0.f, 0.f, 0.f};
int ia;

ia=(y*sizex + x)*3;
color.x=textur[ia ];
color.y=textur[ia + 1];
color.z=textur[ia + 2];

return(color);
}


zu Problem 2:
Ich habe hier alle erdenklichen Varianten ausprobiert, breaks, for und while schleife, ein/zwei If-Bedingungen, alle führten zu dem gleichen Ergebnis. Die zwei Vergleiche sind schlicht der letzte Stand der Verzweiflung ^^
"kommt überhaupt nix mehr an" heisst, dass der Pixel in der letzten Zeile gar nicht mehr geschrieben wird. Er kommt an dieser Zeile gar nicht mehr an, kein Absturz, kein Compilerfehler, kein Laufzeitfehler, es passiert nach der Schleife einfach "nichts" mehr.
 
Zuletzt bearbeitet:
@Blitzmerker:
Du hast natürlich recht... ich hab leider in den Beiträgen oben aus unterschiedlichen Sourceversionen kopiert (ich Depp!), ich korrigiere die Sourcen oben eben entsprechend. Sorry dafür!

Edit: Sources korrigiert

@Blitzmerker:
Ja, mit dem ShaderAnalyzer ist alles ok, auf PC Win7 auf CPU und GPU auch, und auf Mac Os 10.6 und CPU auch, nur auf der GPU nicht ^^
 
Zuletzt bearbeitet:
Wie siehst mit Updates vom Grafiktreiber aus (ich weiß, doofe Frage bei Mac, aber vielleicht hat sich da was getan), da die Funktionen komplett ohne Seiteneffekte sind (aus meiner Sicht) und daher nicht ein so stark anderes Verhalten erzeugen dürfen.

Sonst bin ich mit meine Wissen dann am Ende...
 
So langsam bekomme ich auch den Verdacht, dass es entweder mit der Karte selbst oder mit dem Treiber zusammenhängt. Zumindest die arithmetischen Operationen sollte ja funktionieren.
Ich werd mal nach einem Update auf die Suche gehen.

Danke Dir!
 

Ähnliche Themen

Zurück
Oben