Problem with comparing numbers non-real values make it impossible to find min and max

Hello everyone,

I wrote a kernel which has to find the index of the minimum and maximum of a float array (parallel reduction). It works quite fine, but now I stumbled towards a problem for this input:

[2.94375E+019, 1.09146E+019, 2.9629E+019, 1.#INF, 3.08097E+019, 1.#INF, 2.95379E+019, 3.92105E+019, 2.95379E+019, -1.#IND, 3.06701E+019, 1.#INF, 1.#INF]

Problem is, whenever at least one value in the array is -1.#IND, the kernel returns wrong results. That’s because if one value is compared against -1.#IND, it’s neither less, equal, or greater…the partial min/max gets set to the first value, which produces unwanted output.

The -1.#IND probably is a result of a function computing something like exp(, ), I can’t avoid it.

Is there any elegant way to prefer the non-complex value in such a comparison? If not, what do you think would be the best way to make the kernel work the way one would expect it? (maybe checking each value when it’s loaded to shared mem, and setting -1.#IND to infinity?)

Which operator do you base your reduction on?

If you use fminf and fmaxf, NaN values should not propagate.

Thanks for answering. I use the normal < and > as reduction operators. I already read about fminf and fmaxf, unfortunately it doesn’t help me, since I am interested in finding the index of the greatest and smallest value, but not in the value itself.

Then you will need to add a test like this:

if(value[index1] > value[index2] || isnan(value[index2]))

	return index1;

else

	return index2;

Ah, isnan() … the function I needed and never have seen before. Well, thanks very much :)

if(x != x) works well too.
NaN is the only value that is different than itself. :)