OpenCL - GPU Vector Mathematics (Parallelism Learning Level)

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

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? Therefore, in the reduction example, I can do this:

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

Thanks.

0
source share
2 answers

As already mentioned, Austin comparison operators also apply to vectors.

Point d. Section 6.3 of the standard is the appropriate part for you. It says:

Relational operators larger than (>), less than (<), greater than or equal to (> =), and less than or equal to (<=) work on scalar and vector types.

he also explains the actual cases:

  • Two operands are scalars. (...)

  • One operand is a scalar, and the other is a vector. (...) The scalar type is then expanded to a vector that has the same number of components as the vector operand. The operation is performed on components, which leads to the same dimensional vector.

  • Two operands are vectors of the same type. In this case, the operation is performed on the components, which leads to the same size vector.

And finally, what do these comparison operators return:

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

For scalar types, relational operators should return 0 if the specified relation is false and 1 if the specified relation is true. For vector types, relational operators should return 0 if the specified relation is false and -1 (i.e. all bits are set) if the specified relation is true. Relational operators always return 0 if any argument is not a number (NaN).

EDIT:

To complete the bit part of the return value, especially after the comment @redrum; At first, it seems strange that the true value is -1 for vector types. However, since OCL behaves as much as possible, like C, this does not make a big change, since everything that differs from 0 is true.

As an example, you have a vector:

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

This statement will evaluate true and do something:

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

Now note that this is not allowed (not related to the returned value, but only because it is a vector):

 if(vect){ //do something } 

This does not compile, however you can use the all and any functions to evaluate all the elements of a vector in an "if" expression:

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

Please note that the return value (from the speed dial card):

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

Thus, any negative number will do.

But still, why not keep the value 1 as the return value when evaluating true?

I think the important part is that all the bits are set. My guess would be that you can easily perform bitwise control on vectors, for example, you want to remove elements smaller than a given value. Due to the fact that the value "true" is -1, that is, 111111 ... 111, you can do something like this:

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

and the elements of the result will be: 0, 3, 42, 0

on the other hand, if the return value is 1 for true, the result will be: 0, 1, 0, 0

+4
source

Khronos OpenCL 1.2 Reference Map Says Logical Operators:

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

+1
source

Source: https://habr.com/ru/post/1500697/


All Articles