Reputation: 507
I've encountered a problem where my previous array elements get overwritten with the new values.
What the code is attempting to do
I originally had an array with 100 elements (all from a sine function, this was my input). It is essentially to act as a FIFO buffer and computer the average of the array as new inputs is pushed into the FIFO. The reason I am doing this is because I am trying to implement a moving average filter.
However, what happens is the output tends to overwrite the previous values. For example, if the first element of the FIFO buffer was 1 (that would currently mean that the rest of the buffer has 0 in it), the output array at position 0 would have 0.01 as the value. The next time around, if the next input value was 0.9, the output value at index 1 would have (0.01+0.009). BUT this is where the value of index 0 also gets overwritten to the same value as index 1.
I decided to write the same code in java and it works perfectly fine. If anyone can figure out the issue I would really appreciate it.
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;
}
}
Note I have the for loops set to 3 for debugging purposes. From tracing the code, it should not be doing this. But then again, I could be missing something small.
**ALSO i have removed alot of the variables such as queueIn for debugging reasons, I just need to make the array not overwrite previous values.
Example output from cmd
Java code
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]);
}
}
Upvotes: 0
Views: 716
Reputation: 8484
The first part of your kernel is implemented for being run as NDRange and the main part when the calculations are done for Task (to be run as single work item) therefore each work item is overwriting the values.
Based on your Java implementation the NDRange kernel implementation should be something like this:
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;
}
Upvotes: 3