2016-05-16 4 views
0

以前の配列要素が新しい値で上書きされるという問題が発生しました。OpenCL - 上書きされる配列の値

コードが

を行うことを試みている何

私はもともと(これは私の入力された、正弦関数からのすべての)100個の要素を持つ配列を持っていました。基本的にFIFOバッファーとして機能し、新しい入力がFIFOにプッシュされるときにコンピューターの配列の平均値が計算されます。私がこれをやっているのは、移動平均フィルタを実装しようとしているからです。

しかし、出力は以前の値を上書きする傾向があります。 たとえば、FIFOバッファの最初の要素が1(バッファの残りの部分に0があることを意味する)の場合、位置0の出力配列の値は0.01になります。次回の入力値が0.9の場合、インデックス1の出力値は(0.01 + 0.009)になります。しかし、インデックス0の値もインデックス1と同じ値に上書きされます。

私は同じコードをJavaで書くことにしました。誰かが問題を理解できるなら、私は本当にそれを感謝します。

kernel void lowpass(__global float *Array, __global float *Output) { 
    float fifo[100]; 
    int queueIn; 
    float tempVal; 
    queueIn = 0; 
    int idx = get_global_id(0); 
    Output[idx] = 0; 
    fifo[idx] = 0; 

    for(int i = queueIn; i < 3; i++){ 
     fifo[i] = Array[i]; 
     tempVal = (float)0; 
     for(int j = 0; j < 3; j++){ 
      tempVal = (float) (fifo[j]*(.01) + tempVal); 
     } 
     Output[queueIn] = tempVal; 
     queueIn = queueIn + 1; 
    } 
} 

メモ私は、デバッグの目的でforループを3に設定しています。コードをトレースすることから、これを行うべきではありません。しかし、再び、私は何か小さいものを逃すことができました。

**また、デバッグのためにqueueInなどの変数を削除しました。以前の値を上書きしないようにする必要があります。カーネルの最初の部分は計算がタスクのために行われNDRangeと主要一部として実行されるために実装されているCMD

enter image description here

Javaコード

public static void main(String[] args) { 
    // TODO Auto-generated method stub 

    //Input,output and fifo arrays 
    float [] fifo = new float[100]; 
    float [] input = new float[100]; 
    float [] output = new float[100]; 

    //temporary value to hold computed result 
    float temp = 0; 

    //initialize array values to 0 
    for(int i =0;i<100;i++){ 
     fifo[i] = 0; 
     input[i] = 0; 
     output[i] = 0; 
    } 

    //I know this produces a constant result, but its just 
    //proof of concept. this array will have values of .707 throughout it 
    for(int i =0;i<100;i++){ 
     temp = (float) Math.sin(Math.toRadians(45)); 
     input[i] = temp; 
    } 

    int queueIn; 
    float tempVal; 
    tempVal=0; 
    queueIn = 0; 
    //Insert one value at a time into the fifo buffer (first for loop) 
    for(int i = queueIn; i < 100; i++){ 
     fifo[i] = input[i]; 

     //reset to 0 so it can reaccumilate 
     tempVal = 0; 

     //accumilate the values in the array multiplied by a coefficient one value in 
     //the array changes every time the first for loop executes. 
     for(int j = 0; j < 100; j++){ 
      tempVal = (float) (fifo[j]*(0.01) + tempVal); 

     } 
     //store the value in the current index of the output array. 
     output[queueIn] = tempVal; 
     queueIn = queueIn + 1; 
    } 

    //verify results 
    for(int i =0;i<100;i++){ 
     System.out.println(output[i]); 
    } 

} 
+0

。あなたはJavaコードを投稿できますか?あなたが何をしようとしているのか分かりません。 –

+0

ちょうどコードを掲載しました。主な部分はこれです、私は2つのループを持っています。最初のforループは、一度に1つの要素をFIFO循環バッファに挿入します。次のforループは、要素が追加された後にキックインされ、配列全体の平均に係数を乗算して再計算されます。最終目標は、信号の移動平均フィルタを実装することです。 – VedhaR

+0

'0.01'ではなく、'(fifo [j] *(.01)+ tempVal) 'で' 1.0/4'を期待しています。 – chux

答えて

3

から

出力例(単一の作業項目として実行される)ため、各作業項目は値を上書きします。

あなたのJavaの実装に基づいてNDRangeカーネルの実装は次のようなものでなければなりません:あなたは、それはJavaで動作すると言う

kernel void lowpass(__global float *Array, __global float *Output) { 
    int idx = get_global_id(0); 

    float tempVal = 0.0f; 
    for(int j = 0; j < idx+1; j++){ 
     tempVal += Array[j] * 0.01f; 
    } 

    Output[idx] = tempVal; 
} 
+0

ありがとうございました!それは素晴らしい作品です。あなたが「NDRangeとして実行されているために実装されている」という意味を少し混乱させます。 – VedhaR

+1

NDRangeは多くの作業項目を実行することを意味し、カーネルの先頭には、NDRangeタイプのカーネルを示唆する 'int idx = get_global_id(0); 'を使用しました。シングルワークアイテムカーネルの場合は、その必要はありません。 – doqtor

+0

NDRangeタイプなしで同じ機能をコーディングすることは可能でしょうか?私はget_global_id(0)を削除しようとしましたが、それは同じことをやります。 – VedhaR

関連する問題