Ich habe erfolgreich einen Digital Down Converter mit OpenCL implementiert. Bei der Implementierung des Interpolationsteils kann ich nur einen maximalen Faktor von 146 einstellen. Jedes weitere führt dazu, dass das Programm abstürzt und ein Fehlercode von CL_INVALID_MEM_OBJECT -38
ausgelöst wird.OpenCL-Programm mit zu viel Speicher
Für diejenigen, die nicht wissen, Interpolation ist eine Methode zum Erstellen neuer Datenpunkte im Bereich der bekannten Datenpunkte. Der DDC (Digital Down Converter) wird verwendet, um die Abtastrate zu erhöhen oder zu verringern, während versucht wird, Datenpunkte mithilfe eines Rekonstruktionsfilters zu rekonstruieren.
Beachten Sie, dass die Datei, die ich verwende, eine 1,75 MB WAV-Datei als Eingabe ist. Es wird bei 44100 abgetastet und mein Ziel ist es, eine Abtastung bei 48000 zu machen (blaue Strahlenqualität). Dies ergibt einen Interpolations-/Dezimierungsfaktor von 160/147. Aber jeder Interpolationsfaktor über 146 stürzt die Treiber ab und das Programm und der Fehler für -38 werden wie oben gezeigt geworfen.
Ich denke, das Problem liegt wo ich die cl_mem
Puffer erstellen. Ich habe ungefähr 7 und hier sind wie sie initialisiert und verwendet werden. Angenommen, P 3 und Q 2, während NUM_ITEMS 918.222 Proben:
input = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
num_items * sizeof(float),
NULL,
&status);
output = clCreateBuffer(
context,
CL_MEM_WRITE_ONLY,
num_items * P * sizeof(float),
NULL,
&status);
//Lowpass kernel parameters
inputForLowpass = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
num_items * P * sizeof(float),
NULL,
&status);
outputFromLowpass = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
num_items * P * sizeof(float),
NULL,
&status);
//Decimate kernel parameters
inputForDecimate = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
num_items * P * sizeof(float),
NULL,
&status);
outputFromDecimate = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
(int)(num_items * (P*1.0/Q) * sizeof(float)),
NULL,
&status);
//numOfCoefficients for number of taps
coeff = clCreateBuffer(
context,
CL_MEM_READ_ONLY,
numOfCoefficients * sizeof(float),
NULL,
&status);
ich die Speicher-Debugger in Visual Studio verwendet, um herauszufinden, dass das Programm 602Mb verwendet (für Interpolationsfaktor von 160, bevor es abstürzt es um 120 MB verwendet. für einen Faktor von 3, noch viel!) Wie kann ich das runter bringen? Benutze ich die Puffer falsch?
Darüber hinaus habe ich drei weitere Speicherzuordnungen im Host-Code. Das 'Array' hält einfach die Werte in der wav-Datei, während OutputData und OutputData2 Werte von der gefilterten Eingabe bzw. der dezimierten Eingabe speichern.
Array = (float*)malloc(num_items * sizeof(float));
OutputData = (float*)malloc(num_items * P * sizeof(float));
OutputData2 = (float*)malloc((int)(num_items * (P*1.0/Q) * sizeof(float)));
Das folgende ist ein Bild der Speichernutzung in Visual Studio, wenn P = 3 (Array von einer Größe von 3 erhöht wird).
ist hier einer der Schreibpuffer, wo ich die -38-Code.
status = clEnqueueWriteBuffer(
cmdQueue,
inputForLowpass,
CL_FALSE,
0,
num_items * P * sizeof(float),
OutputData,
0,
NULL,
NULL);
printf("Input enqueueWriteBuffer for Lowpass Kernel status: %i \n", status);
Hier ist der Tiefpass kernel:
__kernel void lowpass(__global float *Array, __global float *coefficients, __global float *Output, __const int numOfCoefficients) {
int globalId = get_global_id(0);
float sum=0.0f;
int min_i= max((numOfCoefficients-1),globalId)-(numOfCoefficients-1);
int max_i= min_i+numOfCoefficients;
for (int i=min_i; i< max_i; i++)
{
sum +=Array[i]*coefficients[globalId-i];
}
//sum = min(., (0.999969482421875));
//sum = max(sum, -1.0f);
Output[globalId]=sum;
}
EDIT Fehler tritt auf, weil die Puffergröße I zuteilen 512 MB Arbeitsspeicher verfügt über verwendet werden. Das ist die maximale Größe eines Puffers, den ich haben kann. Um dieses Problem zu beheben, muss ich eine Art Speicherverwaltungssystem in meinen Code implementieren. Vielleicht mit einem 8 MB Puffer auf einmal.
Können Sie uns zeigen, wo Sie in diese Puffer schreiben und wo Sie Ihren Kernel aufrufen? (und Cleanup-Code könnte auch eine gute Idee sein) 'CL_INVALID_MEM_OBJECT' Ich denke nicht, dass' clCreateBuffer' geworfen wird. – JavaProphet
@JavaProphet Ich habe sowohl den WriteBuffer als auch den Kernel hinzugefügt. Es wirft auch den gleichen Fehler für den dezimierten Kernel. Ich werde versuchen, die Protokollmeldung hinzuzufügen, die ausgegeben wird, wenn dieser Fehler ebenfalls auftritt. – VedhaR