1

This article talks about the optimization of code and discusses Instruction level parallelism. They give an example of GPU vector math where the float4 vector math can be performed on the vector rather than the individual scalars. Example given:

float4 x_neighbor = center.xyxy + float4(-1.0f, 0.0f, 1.0f, 0.0f);

Now my question is can it be used for comparison purposes as well? So in the reduction example, can I do this:

accumulator.xyz = (accumulator.xyz < element.xyz) ? accumulator.xyz : element.xyz;

Thank you.

shunyo
  • 1,277
  • 15
  • 32
  • You can't compare a vector with another vector, unless you do it element by element. If you want to compare in distance, then use the length operator first. – DarkZeros Aug 30 '13 at 15:03
  • I thought the code above compares element by element. Doesnt it? – shunyo Aug 30 '13 at 15:04
  • For me that code does not make sense, if it where "==", then thats fine. But being "<" is not aplicable to a float4, since what is "less"? Each element? The distance in a 4D space? You have other operators like "select()" and "length()" that are not as ambiguous. I wouldn't trust the code above even if it compiles. – DarkZeros Aug 30 '13 at 23:41

2 Answers2

5

As already stated by Austin comparison operators apply on vectors as well.

The point d. in the section 6.3 of the standard is the relevant part for you. It says:

The relational operators greater than (>), less than (<), greater than or equal (>=), and less than or equal (<=) operate on scalar and vector types.

it explains as well the valid cases:

  • The two operands are scalars. (...)

  • One operand is a scalar, and the other is a vector. (...) The scalar type is then widened to a vector that has the same number of components as the vector operand. The operation is done component-wise resulting in the same size vector.

  • The two operands are vectors of the same type. In this case, the operation is done component-wise resulting in the same size vector.

And finally, what these comparison operators return:

The result is a scalar signed integer of type int if the source operands are scalar and a vector signed integer type of the same size as the source operands if the source operands are vector types.

For scalar types, the relational operators shall return 0 if the specified relation is false and 1 if the specified relation is true. For vector types, the relational operators shall return 0 if the specified relation is false and –1 (i.e. all bits set) if the specified relation is true. The relational operators always return 0 if either argument is not a number (NaN).

EDIT:

To complete a bit the return value part, especially after @redrum's comment; It seems odd at first that the true value is -1 for the vector types. However, since OCL behaves as much as possible like C, it doesn't make a big change since everything that is different than 0 is true.

As an example is you have the vector:

int2 vect = (int2)(0, -1);

This statement will evaluate to true and do something:

if(vect.y){
    //Do something 
}

Now, note that this isn't valid (not related to the value returned, but only to the fact it is a vector):

if(vect){
    //do something
}

This won't compile, however, you can use the function all and any to evaluate all elements of a vector in an "if statement":

if(any(vect){
    //this will evaluate to true in our example
}

Note that the returned value is (from the quick reference card):

int any (Ti x): 1 if MSB in component of x is set; else 0

So any negative number will do.

But still, why not keep 1 as the returned value when evaluated to true?

I think that the important part is the fact that all bits are set. My guess, would be that like that you can make easily bitwise operation on vectors, like say you want to eliminate the elements smaller than a given value. Thanks to the fact that the value "true" is -1, i.e. 111111...111, you can do something like that:

int4 vect = (int4)(75, 3, 42, 105);
int ref = 50;
int4 result = (vect < ref) & vect;

and result's elements will be: 0, 3, 42, 0

in the other hand if the returned value was 1 for true, the result would be: 0, 1, 0, 0

CaptainObvious
  • 2,525
  • 20
  • 26
  • Thank you Captain. That was not obvious! – shunyo Aug 31 '13 at 13:01
  • @CaptainObvious: It's a bit annoying that scalars return 1 if the condition is true and vectors return -1. Why have the asymmetry? If there was no asymmetry than you could treat e.g. intn the same for n=1, 2, 4,... instead int1 (int) must be handled different than all the others. – Z boson Sep 02 '13 at 09:47
1

The OpenCL 1.2 Reference Card from Khronos says that logical operators:

Operators [6.3] These operators behave similarly as in C99 except that operands may include vector types when possible: + - * % / -- ++ == != & ~ ^ > < >= <= | ! && || ?: >> << = , op= sizeof

Austin
  • 1,018
  • 9
  • 20