cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

Raistmer
Adept II

Returning single boolean result from kernel - will it work?

I need to do some transformation on 2D array and return another 2D array from kernel and single boolean value that will show if some additional postprocessing needed for this data block or not.
Currently 2D array processed in gather + ordinary streams, not scatter.

Smth like
kernel void kernel_A(float4 input[][], out float4 output<>);

that boolean value will be 1 if any of elements in output array meets some condition.

The question:
can I use such kernel:

kernel void kernel_B(float4[][], out float4 output<>, out int condition[]);
where condition stream defined as
unsigned ssize=1;
brook::Stream< int > condition(1,&ssize);

and do next thing in kernel:

if(result.x>threshold){
condition[0]=1;
}
output.x=result.x;


Will I get required behavior in this case? (that is, condition will be zero if nothing in 2D array was above thrreshold and condition will be 1 if any of 2D elements was above threshold) Can I assume that if no writes in scatter array were done it will be zero ?
0 Likes
11 Replies
gaurav_garg
Adept I

Returning single boolean result from kernel - will it work?

I think this should work. You can initialize condition stream with 0 using streamRead.

As in this kernel, multiple threads will write the same value or won't write anything, data-race would not be a problem.

0 Likes
Raistmer
Adept II

Returning single boolean result from kernel - will it work?

It seems it doesn't work....

In listed kernel second if condition chosen deliberatly that way it never can be true.
But was_pulse still contains some big number (last thread in block or smth close to last thread).

First condition can be true only for first element of array.

Whe I changes j<1 to j< -10, that is both conditions became false, was_pulse contained zero as it should be.

Brook+ can't correctly process logical expressions like A < B && C < D correctly or ?...

Why I recived such results ?

kernel void GPU_fetch_array_kernel10(int sizes[],float src[],int offsets[][],float freq[],int thresholds[][],out float4 dest<>,out int was_pulse[]){ int j=instance().y; int threadID=instance().x; float threshold=(float)thresholds[0][threadID];//R: fetch always starts with zero coadd level int k=0; int l=0; float4 acc=float4(0.f,0.f,0.f,0.f); float f=freq[threadID]; //double period=periods[threadID];//(double)sub_buffer_size/(double)f; int n_per=(int)f; for(k=0;k<n_per;k++){ l=offsets[threadID]; l+=(4*j);//R: index to data array computed acc.x+=src; acc.y+=src[l+1]; acc.z+=src[l+2]; acc.w+=src[l+3]; } if (j < 1 && acc.x < -10 ){ was_pulse[0]=threadID; } /* if(4*j+1<1){ if(acc.y<0){ was_pulse[0]=threadID; } } if(4*j+2<1){ if(acc.z<0){ was_pulse[0]=threadID; } } if(4*j+3<1){ if(acc.w<0){ was_pulse[0]=threadID; } } */ dest=acc; }

0 Likes
Raistmer
Adept II

Returning single boolean result from kernel - will it work?

It seems Brook+ kernel writes in scatter array always
But sometimes it writes some trash....
0 Likes
gaurav_garg
Adept I

Returning single boolean result from kernel - will it work?

First condition can be true only for first element of array.


It will be true for the first row.

What are the dimensions of dest stream you are using?

PS: Also, can you try nested if blocks instead of &&, in case your doubt is correct.

0 Likes
Raistmer
Adept II

Returning single boolean result from kernel - will it work?

Originally posted by: gaurav.garg

First condition can be true only for first element of array.



It will be true for the first row.


What are the dimensions of dest stream you are using?


PS: Also, can you try nested if blocks instead of &&, in case your doubt is correct.


I meant first element of each 1D array from matrix, sorry.
2D array I use actually is collection of many 1D independed arrays joined into 2D array only for diminish kernel call overhead, algorithm work on 1D, not 2D structures.

About nested block - actually I beginned with nested blocks as you can see in my another post about kernel call error (there was just another modification of the same kernel).
Nested blocks gave same result too.

Actually I came to such expression (attached) but still got non-zero was_pulse.

The only case when I got zero was_pulse was situation where both conditions were false for each element of 2D stream.
That is j < -10 && acc.x < -10
That condition never calls scatter stream write indeed.

It was increasely strange to recive something like 2244 in scatter element for this code:
if (j < 1 && acc.x < -10.f ){
was_pulse[ 0 ]=( int ) acc.x;
}
positive value was assigned when condition says "do assing only for negative values"....


I would really appreciate info about how to update scatter stream only whae needed cause it would save me ~ 1/3 of all kernel calls and greatly increase (as I hope) app performance...
For now I should call separate kernel just to check if newly generated power values lower than threshold or not. This kernel attempted to merge new power value producing with checking if it exceed threshold or not (in vast majority of cases it will not exceed threshold, pulse above threshold considered as rare event for my app).

if ( j < 1){A=1;} else{A=0;} if(acc.x < -10.f ){B=1;} else{B=0;} if(A*B==1){ C=1; }else{ C=0; } if(C==1){ was_pulse[0]=(int)acc.x; }

0 Likes
Raistmer
Adept II

Returning single boolean result from kernel - will it work?

Originally posted by: gaurav.garg

What are the dimensions of dest stream you are using?




Answerring on this your question:

dest stream has 8192 elements along X-axis, but kernel called 8 temes on execution domains 1024 element along X axis each (it appeared to do 8 kernel calls with Sleep() between saves more CPU than one big kernel call - fact strange by itself.

Y-dimension has variable size. It can be ~400 for example.


0 Likes
youplaboom
Journeyman III

Returning single boolean result from kernel - will it work?

A similar brook+ code with a single element scatter stream, written on condition only, works fine on my machine.

Are you sure you first initialized your stream 'was_pulse' with a stream read?

0 Likes
Raistmer
Adept II

Returning single boolean result from kernel - will it work?

Originally posted by: youplaboom

A similar brook+ code with a single element scatter stream, written on condition only, works fine on my machine.


Are you sure you first initialized your stream 'was_pulse' with a stream read?


Yes, I'm pretty sure. Cause there was case when I've seen zero as it should be.
+ I see changes when I assign different values inside kernel, it's not just trash leaved in uninitialized stream.

Do you use single condition or 2 conditions as I do ?
I could check if it will pass something like
if( j< -10 && (j+1) < -10 ) for example.
My current "theory": brook can't properly handle 2 condition statements and goes both paths even condition in total never met.
0 Likes
youplaboom
Journeyman III

Returning single boolean result from kernel - will it work?

I always use parentheses in multiple conditions statements; but for the sack of argument I tried without them and it was still working.

Try that:

if ((j< -10) && ((j+1) < -10))

0 Likes