2017-08-07 1 views
0

Ich schreibe ein OpenCL-Programm, und habe festgestellt, dass ich einen Puffer als alle Nullen lesen. Beim Eintauchen in die Intel SDK-Ablaufverfolgung habe ich festgestellt, dass ich einen CL_INVALID_ARG_VALUE beim EINSTELLEN der Pufferargumente erhalte. (Das Setzen von Skalarargumenten erzeugt keinen Fehler.)CL_INVALID_ARG_VALUE beim Setzen von Pufferargumenten

Ich benutze die OpenCL C++ Bindings (cl.hpp).

Da mein Code lang ist, habe ich das Problem mit einem Testprogramm repliziert.

cl::CommandQueue queue(context, devices.front()); 

cl::Buffer resultsBuf(context, CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, sizeof(cl_short) * 2048); 
cl::Buffer inputBuf(context, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_uchar) * 2048, input.data()); 

queue.enqueueWriteBuffer(inputBuf, CL_TRUE, 0, sizeof(cl_uchar) * 2048, input.data()); 

// Execution of the following two lines produces CL_INVALID_ARG_VALUE for both. 
err = kernel.setArg(0, resultsBuf); 
err = kernel.setArg(1, inputBuf); 

// Execution of the following line produces CL_INVALID_KERNEL_ARGS 
err = queue.enqueueTask(kernel); 

vector<cl_short> result(2048); 
err = queue.enqueueReadBuffer(resultsBuf, CL_TRUE, 0, sizeof(cl_short) * 2048, result.data()); 

und der Code Kernel:

__kernel void myKernel(
    __local short* resultsBuf, 
    __local uchar* inputBuf 
) { 
    for (int i = 0; i < 2048; ++i) { 
     resultsBuf[i] = -3; 
    } 
} 

input ist ein vector<cl_uchar>(2048) mit einigen Testdaten gefüllt ist, wird es noch nicht für alles verwendet. Alles, was ich von diesem Testfall erwarte, ist das Zurücklesen eines Puffers, der mit dem Wert -3 gefüllt ist.

Ich habe meinen Code mit anderen Samples verglichen, die ich online gefunden habe, und nichts springt mir als seltsam vor, ich habe verschiedene kleine Anpassungen ausprobiert (wie das Ändern der Mem-Flags) und ich kann mich nicht verbessern die Situation.

Gibt es etwas, das ich über Puffer übersehen habe?

(neugierig ist mein Testprogramm result mit einem paar Junk-Bytes füllen?)

Antwort

3

Daten dort zu übergeben und zurück zwischen Host und GPU Sie globale Speicher verwenden. Das scheint auf der Host-Seite OK zu sein, aber in Ihrem Kernel verwenden Sie __local Speicheradressenspezifizierer, der wie der Name sagt, lokal im Kernel verwendet werden soll. Korrigiert Kernel zu verwenden __global:

__kernel void myKernel(
    __global short* resultsBuf, 
    __global uchar* inputBuf 
) { 
    for (int i = 0; i < 2048; ++i) { 
     resultsBuf[i] = -3; 
    } 
} 
+0

Danke. Ich dachte ehrlich, ich hätte eine Wahl. – braks

+0

Wissen Sie, wenn ich die Kernargs auf __private setze, bekomme ich den Fehler: "Zeigerargumente zu Kernfunktionen müssen sich in '__global', '__constant' oder '__local' Adressraum befinden." Dies scheint zu implizieren, dass es möglich wäre, __local zu verwenden? – braks

+0

Es scheint, dass ich für inputBuf es ohne Fehler __constant machen kann. Ich denke, es gibt verschiedene Fälle. Es gibt mehr über __local hier: https://stackoverflow.com/questions/30249801/passing-arguments-through-local-memory-in-opencl – braks

Verwandte Themen