# UME::SIMD Tutorial 2: Calculations

## Horizontal vs. Vertical vectorization

Once the SIMD vectors are initialized with data, they will be operated upon. When operating on vectors, we need to distinguish two directions of operations: horizontal and vertical. The easiest way to understand the difference is by looking at a following diagram: In the diagram we can distinguish two directions relating to either data orientation or instruction orientation. Vertical vectorization will be a process of operating in an elementwise manner on elements of each vector. For the first ADD operation, the result will be, as if we executed following list of operations:

```c0=a0+b0;
c1=a1+b1;
c2=a2+b2;
c3=a3+b3;
```

Mind that vertical operations can also operate on a single vector, the same way as SQRT operation:

```f0=sqrt(e0);
f1=sqrt(e1);
f2=sqrt(e2);
f3=sqrt(e3);
```

A horizontal operation, or a reduction , is one involving applying an operator between elements of a vector. From the example above this would be HADD operation, which would have the same meaning as:

```x=f0+f1+f2+f3;
```

Another way of remembering the distinction between horizontal and vertical operations is as follows: vertical operation always returns a vector, while horizontal always returns a scalar. By convention names of hoirzontal operations are prefixed with H- letter, such as in HADD.

## Invoking operations in UME::SIMD

When operating on vectors simply use overloaded operators, as if you were working with scalars:

```UME::SIMD::SIMDVec<float, 4> a, b, c, d, e, f;
...
c = a + b;
e = c * d;
```

For additional operations, the ones that don’t have an equivalent C++ operator, you can either use a special namespace UME::SIMD::FUNCTIONS or a Member Function Interface (MFI) invocation convention:

```f = UME::SIMD::FUNCTIONS::sqrt(e); // or
f = e.sqrt(); // MFI call
```

MFI invocation convention is especially useful when using UME::SIMD as a code generation target, as it allows invoking every operation supported by the library in the same way. For regular development I advise using operators and functions as this will result in better code readability.

Invocation of a horizontal operation cannot be done using operator syntax, as the concept of reduction operation is not present in current C++ language. You have to therefor use either FUNCTIONS namespace or MFI:

```float x = UME::SIMD::FUNCTIONS::hadd(f); // or
float x = e.hadd(); // MFI call
```

Which syntax convention to use is up to you.