2016-07-28 9 views
1

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スタジオでのメモリ使用量のイメージです。

enter image description here

は、ここで私は-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のバッファを使うことによって。

+0

バッファに書き込む場所とカーネルをどこに呼び出すことができますか? CL_INVALID_MEM_OBJECT'私は 'clCreateBuffer'によってスローされたとは思いません。 – JavaProphet

+0

@JavaProphet私はwriteBufferとカーネルを追加しました。また、デシメートカーネルにも同じエラーがスローされます。そのエラーが発生したときに出力するログメッセージを追加しようとします。 – VedhaR

答えて

0

あなたのメモリオブジェクトは明示的に何かによって裏付けされておらず、それがあなたの問題かもしれません。私は、ホスト・ポインタを指定して、そのようCL_MEM_USE_HOST_PTRCL_MEM_COPY_HOST_PTR、またはCL_MEM_ALLOC_HOST_PTRなど

https://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateBuffer.html

からフラグを追加することをお勧めしたいです。 CL_MEM_USE_HOST_PTRを使用すると、バッファがホストメモリ内にある場合はバッファがホストに再度割り当てられず、メモリ使用量だけであれば問題が解決されます。

+0

私はあなたのアプローチを 'CL_MEM_COPY_HOST_PTR'で試してみました。最初に入力バッファーを試してみたところ、Interpolateカーネルが13ms飛躍したことに気付きました。私は出力バッファーのために同じを試みたとき、プログラムがクラッシュしました。補間カーネルは単純なカーネルに過ぎません。与えられた入力配列から配列のn番目の位置に要素を追加します。 – VedhaR

+0

@VedhaR 'CL_MEM_COPY_HOST_PTR'ではなく、' CL_MEM_USE_HOST_PTR'をお勧めしました。 – JavaProphet

+0

申し訳ありませんが、私は 'CL_MEM_USE_HOST_PTR'を使用しています。私はちょうど間違ってここにコピーしました – VedhaR

関連する問題