2013-08-01 9 views
7

Ich möchte ein lokales Array innerhalb meines OpenCL-Kerns erstellen, dessen Größe von einem Parameter des Kernels abhängt. Es scheint, dass das nicht erlaubt ist - zumindest mit AMD APP.Array-Deklaration variabler Länge in OpenCL nicht erlaubt - warum?

Ist Ihre Erfahrung anders? Vielleicht ist es nur die APP? Oder gibt es hier ein paar Gründe?

Edit: Ich würde jetzt vorschlagen, dass Arrays variabler Länge auch im CPU-seitigen Code erlaubt sein sollten, und es war ein unglücklicher Ruf des C-Standardkomitees; aber die Frage steht.

Antwort

4

Sie können die Größe eines lokalen Blocks dynamisch zuweisen. Sie müssen es als Parameter für Ihren Kernel verwenden und seine Größe definieren, wenn Sie clSetKernelArg aufrufen.

Definition Beispiel:

__kernel void kernelName(__local float* myLocalFloats, ...) 

Host-Code:

clSetKernelArg(kernel, 0, myLocalFloatCount * sizeof(float), NULL); // <-- set the size to the correct number of bytes to allocate, but use NULL for the data. 

Stellen Sie sicher wissen, was die Grenze für den lokalen Speicher auf dem Gerät ist, bevor Sie dies tun. Rufen Sie clGetDeviceInfo auf und rufen Sie den Wert "CL_DEVICE_LOCAL_MEM_SIZE" ab.

+1

Dies ist die Problemumgehung, die ich benutze, aber - da dies möglich ist, warum sollte ich nicht nur in der Lage sein, ein lokales Array entweder durch die Deklaration eines Array variabler Länge oder Aufruf einer OpenCL malloc-ähnliche Funktion zuzuweisen? – einpoklum

+0

Ich denke, es hat mit vielen der heutigen Geräte zu tun, die diese Informationen im Voraus wissen müssen, damit sie sicher validieren und zuweisen können. Ich weiß noch nicht, dass AMDs GCN-Architektur gpu-seitige malloc-Aufrufe unterstützen wird. – mfa

+0

Wenn das erlaubt war, dann sollten Sie in der Lage sein, den Gerätespeicher dynamisch innerhalb des Kernels zuzuordnen, Zuweisungsfehler zurückzugeben, etc ... Und das ist in der GPU nicht möglich. Auf der Kernel-Ebene muss alles statisch sein. Wie sie sagten, besteht die einzige Möglichkeit darin, sie aus dem Host-Code zu setzen. – DarkZeros

3

Nicht sicher, warum Leute sagen, dass Sie das nicht tun können, da es etwas ist, was viele Leute mit OpenCL tun (Ja, ich verstehe, dass es nicht genau das gleiche ist, aber es funktioniert gut genug für viele Fälle).

Da OpenCL-Kernel zur Laufzeit kompiliert werden, können Sie einfach wie bei Text die Größe auf die von Ihnen gewünschte Größe einstellen und dann Ihren Kernel neu kompilieren. Dies ist natürlich nicht perfekt in Fällen, in denen Sie große Variabilität in den Größen haben, aber normalerweise kompiliere ich mehrere verschiedene Größen beim Start und dann rufen Sie einfach die richtige bei Bedarf (in Ihrem Fall basierend auf dem Kernel-Argument). Wenn ich eine neue Größe bekomme, habe ich keinen Kernel, ich kompiliere ihn dann und speichere den Kernel, falls er wieder auftaucht.

+0

Hmm. Ja, das eröffnet einige interessante Möglichkeiten. Obwohl, ich muss sagen, ich verstehe nicht wirklich, warum OpenCL-Kernel zur Laufzeit kompiliert werden. Wenn ich meinen Host-Code kompilieren kann im Voraus und nehme an, dass es funktioniert, obwohl es hardwarespezifisch sein könnte (x86_64 vs x86 etc.), sehe ich nicht, warum das nicht der Fall für meinen GPU-Code sein sollte. Wie auch immer, du bekommst deine Upvote. – einpoklum

+0

Ich glaube, es ist die Flexibilität, diese Art von Dingen zu tun, wenn die Hardware oder der Treiber nicht kann.OpenCL funktioniert sehr gut, wenn Sie mit nur mäßigem Aufwand nach größeren Leistungssteigerungen suchen und wenn möglich das theoretische Maximum erreichen wollen. (Fahrer sind ein bisschen Kopfschmerzen, aber das ist immer ein Problem mit diesen Dingen und Sie herausfinden, ihre Macken). –

Verwandte Themen