
Re: Possible bug with any() function containing a scalar expression
LeeHowes Oct 11, 2012 12:51 PM (in response to settle)1 of 1 people found this helpfulI think what you are seeing is a quirk of booleans in OpenCL C that has been on my list of annoyances since the first version was released. You see, truth for vectors is 1, truth for scalars is 1.
The result then would be that:
if dfdx is 0
dfdx != 0 == 1
any(1) is false
However, if you had int2(dfdx)
int2(dfdx) != int2(0,0) == (1, 1)
any((1, 1)) == true
See 6.12.6:
"The functions isequal, isnotequal, isgreater, isgreaterequal, isless, islessequal, islessgreater,
isfinite, isinf, isnan, isnormal, isordered, isunordered and signbit described in table 6.14 shall
return a 0 if the specified relation is false and a 1 if the specified relation is true for scalar
argument types. These functions shall return a 0 if the specified relation is false and a –1 (i.e. all
bits set) if the specified relation is true for vector argument types"

Re: Possible bug with any() function containing a scalar expression
settle Oct 12, 2012 8:02 AM (in response to LeeHowes)Hi Lee,
Thank you for pointing out that subtlety in the specification. I now recall reading it once a long time ago, but this is the first time it really hit me. Do you happen to know why it is defined this way? I guess for compatibility that we're stuck with this annoyance.
I've been thinking of an alternative we could use to get the desired effect for intn, n = 1, ..., 16.
intn dfdx;
...
if any( select((intn)(0), (intn)(1), dfdx != 0) )
; // Do something
else
; // Do something else
What do you think?
By the way, due to the above subtlety I just realized that fast_normalize(0.f)I assume also normalize(0.f)is implementation dependent, whereas fast_normalize( (float2)(0.f) ), etc., are strictly defined to be within 8192 ulps of (float2)(0.f), see Table 6.13 Scalar and Vector Argument Builtin Geometric Function Table.
floatn fast_normalize (floatn p)
Returns a vector in the same direction as p but with a length of 1. fast_normalize is computed as:
p * half_rsqrt (p.x2 + p.y2 + … )
The result shall be within 8192 ulps error from the infinitely precise result of
if (all(p == 0.0f))
result = p;
else
result = p / sqrt (p.x2 + p.y2 + ... );
with the following exceptions:
...
the implementation may return back p.
Cheers,
Sean

Re: Possible bug with any() function containing a scalar expression
drallan Oct 12, 2012 5:28 AM (in response to settle)1 of 1 people found this helpfulI've been thinking of an alternative we could use to get the desired effect for intn, n = 1, ..., 16.
If you left shift the boolean expression 31 bits it should work for both "truth systems", where 1 or 1 equal "true".
This will work with variables or with comparisons like below. I've had the same problems!
if (any((dfdx !=0)<<31))
; // Do something
else
; // Do something else

Re: Possible bug with any() function containing a scalar expression
settle Oct 12, 2012 8:09 AM (in response to drallan)I like the shifting idea as well, but we would have to be a little more careful for it to work in general for a templated dfdx. If dfdx is longn, ulongn, or doublen, then as shown above the shift would be 32 bits too few, and similarly for charn, ucharn, short, or ushort, except 16 bits too many (although I don't recall if shifting by too many bits is a compile error).
if ( any( (dfdx != 0) << (8 * sizeof(dfdx) / vec_step(dfdx)  1) ) )
; // Do something
else
; // Do something else
However, the above won't work for user created data types, and maybe neither for bool or half. I think we can all agree that this is overly complicated for something that should be intuitive.

Re: Possible bug with any() function containing a scalar expression
drallan Oct 12, 2012 9:30 AM (in response to settle)I like the shifting idea as well, but we would have to be a little more careful for it to work in general for a templated dfdx. If dfdx is longn, ulongn, or doublen, then as shown above the shift would be 32 bits too few, and similarly for charn, ucharn, short, or ushort, except 16 bits too many
No (or yes! ), if will work with any data type because the compiler converts the conditional expression inside the parens ( 0 ! = any_var ) to a logical or boolean type, which is 32 bits on the opencl platform. You can check by evaluating sizeof(bool);
I think we can all agree that this is overly complicated for something that should be intuitive.
Agreed. When I first saw the any() function, I thought now that's simple.........



Re: Possible bug with any() function containing a scalar expression
LeeHowes Oct 12, 2012 8:51 AM (in response to settle)I presume it's done that way because someone felt it would be a good idea for OpenCL vectors to map trivially to SSE intrinsics but for the rest of OpenCL C to map directly to C standard operations. Beyond that I don't understand it, I originally reported it as a bug when I found the issue just like you did in this thread.

