OpenCLを使用してDigital Down Converterを実装しました。補間部分を実装するとき、最大係数を146に設定することができます。それ以上の場合、プログラムがクラッシュし、エラーコードCL_INVALID_MEM_OBJECT -38
がスローされます。あまりにも多くのメモリを使用するOpenCLプログラム
わからない人には、補間は、既知のデータ点の範囲内で新しいデータ点を構築する方法です。 DDCまたはデジタルダウンコンバータは、再構成フィルタを使用してデータポイントを再構築しようとする際に、サンプリングレートをすべて増減させるために使用されます。
私が使用しているファイルは、入力として1.75Mbのwavファイルです。それは44100でサンプリングされ、私の目標は48000(ブルーレイの品質)でサンプリングすることです。これにより、補間/間引き係数が160/147になります。しかし、146以上の補間係数はドライバとプログラムをクラッシュさせ、上記のように-38のエラーがスローされます。
私はcl_mem
バッファを作成する場所に問題があると思います。私は約7を持っています、そして、ここで彼らがどのように初期化され使用されています。想定Pが3で、アイテム数は918222個のサンプルである一方、Qは2:
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);
私はプログラムが602Mbを使用していることを見つけるために、Visual Studioでメモリデバッガを使用
(160の補間係数のためにそれがクラッシュする前に、それは120MBの周りに使用しました。 3の要素のために、まだたくさん!)これをどうやって落とすことができますか?私は間違った方法でバッファーを使用していますか?
これに加えて、私は3つの他のメモリ割り当てをホストコードに持っています。 'Array'はwavファイルの値を保持し、OutputDataとOutputData2はそれぞれフィルタリングされた入力とデシメートされた入力の値を格納します。
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)));
以下は、P = 3(配列はサイズが3ずつ増加する)のときのVisualスタジオでのメモリ使用量のイメージです。
は、ここで私は-38コードを取得writeBuffersの一つです。
ここ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);
ローパス・カーネルである:私は割り当てバッファサイズが512MBのメモリが使用されて上に持っているので
__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 エラーが発生します。それは私が持つことができるバッファの最大サイズです。この問題を解決するには、私のコードにある種のメモリ管理システムを実装する必要があります。多分、一度に8Mbのバッファを使うことによって。
バッファに書き込む場所とカーネルをどこに呼び出すことができますか? CL_INVALID_MEM_OBJECT'私は 'clCreateBuffer'によってスローされたとは思いません。 – JavaProphet
@JavaProphet私はwriteBufferとカーネルを追加しました。また、デシメートカーネルにも同じエラーがスローされます。そのエラーが発生したときに出力するログメッセージを追加しようとします。 – VedhaR