Vc  1.4.2
SIMD Vector Classes for C++
Vector Class Reference

Detailed Description

The main vector class for expressing data parallelism.

are specializations of this class. For most cases there are no API differences for the specializations. Make use of Vector<T> for generic programming, otherwise you might prefer to use the *_v aliases.

See also
Vc::float_v, Vc::double_v, Vc::int_v, Vc::uint_v, Vc::short_v, Vc::ushort_v
Mask

Definition at line 53 of file fwddecl.h.

#include <Vc/vector.h>

Public Types

using abi = Abi
 The ABI tag type of the current template instantiation.
 
using EntryType = typename VectorTraits< T, Abi >::EntryType
 The type of the entries in the vector.
 
using value_type = EntryType
 The type of the entries in the vector. More...
 
using MaskType = Vc::Mask< T, Abi >
 The type of the mask used for masked operations and returned from comparisons.
 
using mask_type = MaskType
 The type of the mask used for masked operations and returned from comparisons. More...
 
using IndexType = Vc::fixed_size_simd< int, VectorTraits< T, Abi >::size()>
 The type of the vector used for indexes in gather and scatter operations.
 
using index_type = IndexType
 The type of the vector used for indexes in gather and scatter operations. More...
 

Public Member Functions

void setZero ()
 Set all entries to zero.
 
void setZero (MaskType mask)
 Set all entries to zero where the mask is set. More...
 
void setZeroInverted (MaskType mask)
 Set all entries to zero where the mask is not set. More...
 
void setQnan ()
 Set all entries to the bit representation of a QNaN.
 
void setQnan (MaskType mask)
 Set all entries to the bit representation of a QNaN where the mask is set. More...
 
Common::WriteMaskedVector< Vector, MaskTypeoperator() (MaskType mask)
 Writemask the vector before an assignment. More...
 
Vector sorted () const
 Return a sorted copy of the vector. More...
 
Compile-Time Constant Initialization
 Vector ()=default
 Construct a zero-initialized vector object. More...
 
 Vector (VectorSpecialInitializerZero)
 Construct a vector with the entries initialized to zero. More...
 
 Vector (VectorSpecialInitializerOne)
 Construct a vector with the entries initialized to one. More...
 
 Vector (VectorSpecialInitializerIndexesFromZero)
 Construct a vector with the entries initialized to 0, 1, 2, 3, 4, 5, ... More...
 
Conversion/Broadcast Constructors
template<typename U >
 Vector (Vector< U, abi > x, enable_if< Traits::is_implicit_cast_allowed< U, T >::value >=nullarg)
 Implict conversion from compatible Vector<U, Abi> types.
 
template<typename U >
 Vector (Vector< U, abi > x, enable_if<!Traits::is_implicit_cast_allowed< U, T >::value >=nullarg)
 Explicit conversion (i.e. More...
 
 Vector (EntryType a)
 Broadcast Constructor. More...
 
template<typename U >
 Vector (U a, enable_if< std::is_same< U, int >::value &&!std::is_same< U, EntryType >::value >=nullarg)
 
Scalar Subscript Operators
reference operator[] (size_t index) noexcept
 This operator can be used to modify scalar entries of the vector. More...
 
EntryType operator[] (size_t index) const noexcept
 This operator can be used to read scalar entries of the vector. More...
 
Unary Operators
MaskType operator! () const
 Determine where the vector is null. More...
 
Vector operator~ () const
 Inverts all bits. More...
 
Vector operator- () const
 Returns a new vector object with all entries negated.
 
Vector operator+ () const
 Returns a copy of the vector object.
 
Increment and Decrement Operators

The increment and decrement operators apply the increment/decrement operation per component.

The semantics are equal to the semantics of the fundamental arithmetics type T.

Note
Over-/Underflow of signed integral types is undefined behavior and may actually break your code.
Vectoroperator++ ()
 
Vector operator++ (int)
 
Vectoroperator-- ()
 
Vector operator-- (int)
 
Arithmetic Operations

The arithmetic operations are implemented as component-wise application of the operator on the two vector objects.

Example:

void foo(float_v a, float_v b) {
const float_v product = a * b;
const float_v difference = a - b;
a += b;
auto quotient = a / b;
auto modulo = static_cast<int_v>(a) % static_cast<int_v>(b);
}
Parameters
xThe vector to add, subtract, multiply, or divide by.
Returns
A vector object of the same type with the components filled according to a component-wise application of the operator.
Note
If a signed integral vector operation overflows the result is undefined. (which is in agreement to the behavior of the fundamental signed integral types in C++)
Vector operator+ (const Vector &x) const
 
Vc_PURE Vector operator- (const Vector &x) const
 
Vc_PURE Vector operator* (const Vector &x) const
 
Vc_PURE Vector operator/ (const Vector &x) const
 
Vc_PURE Vector operator% (const Vector &x) const
 
Binary Operations

The binary operations are implemented as component-wise application of the operator on the two vector objects.

Example:

void foo(int_v a, int_v b) {
const int_v combined_bits = a | b;
const int_v masked_bits = a & b;
a ^= b; // flipped bits
}
Returns
A vector object of the same type with the components filled according to a component-wise application of the operator.
Vector operator| (const Vector &x) const
 
Vc_PURE Vector operator& (const Vector &x) const
 
Vc_PURE Vector operator^ (const Vector &x) const
 
Shift Operations

The shift operations are implemented as component-wise application of the operator on the two vector objects.

Example:

void foo(int_v a, int_v b) {
const int_v right = a >> b;
a <<= b;
}
Returns
A vector object of the same type with the components filled according to a component-wise application of the operator.
Vector operator<< (const Vector &x) const
 
Vc_PURE Vector operator>> (const Vector &x) const
 
Comparisons

All comparison operators return a mask object.

Example:

void foo(const float_v &a, const float_v &b) {
const float_m mask = a < b;
...
}
Parameters
xThe vector to compare against.
Returns
A mask object. Its components contain the boolean results of the component-wise compare operation.
MaskType operator== (const Vector &x) const
 
Vc_PURE MaskType operator!= (const Vector &x) const
 
Vc_PURE MaskType operator<= (const Vector &x) const
 
Vc_PURE MaskType operator>= (const Vector &x) const
 
Vc_PURE MaskType operator< (const Vector &x) const
 
Vc_PURE MaskType operator> (const Vector &x) const
 
Horizontal Reduction Operations

Horizontal operations can be used to reduce the values of a vector to a scalar value.

Example:

void foo(const float_v &v) {
float min = v.min(); // smallest value in v
float sum = v.sum(); // sum of all values in v
}
EntryType min () const
 Returns the smallest entry in the vector.
 
EntryType max () const
 Returns the largest entry in the vector.
 
EntryType product () const
 Returns the product of all entries in the vector.
 
EntryType sum () const
 Returns the sum of all entries in the vector.
 
Vector partialSum () const
 Returns a vector containing the sum of all entries with smaller index.
 
EntryType min (MaskType mask) const
 Returns the smallest entry of the vector components selected by mask.
 
EntryType max (MaskType mask) const
 Returns the largest entry of the vector components selected by mask.
 
EntryType product (MaskType mask) const
 Returns the product of the vector components selected by mask.
 
EntryType sum (MaskType mask) const
 Returns the sum of the vector components selected by mask.
 
Shift and Rotate

These functions allow to shift or rotate the entries in a vector.

All functions with an amount parameter support positive and negative numbers for the shift/rotate value.

Example:

using namespace Vc;
int_v foo = int_v::IndexesFromZero() + 1; // e.g. [1, 2, 3, 4] with SSE
x = foo.shifted( 1); // [2, 3, 4, 0]
x = foo.shifted( 2); // [3, 4, 0, 0]
x = foo.shifted( 3); // [4, 0, 0, 0]
x = foo.shifted( 4); // [0, 0, 0, 0]
x = foo.shifted(-1); // [0, 1, 2, 3]
x = foo.shifted(-2); // [0, 0, 1, 2]
x = foo.shifted(-3); // [0, 0, 0, 1]
x = foo.shifted(-4); // [0, 0, 0, 0]
x = foo.rotated( 1); // [2, 3, 4, 1]
x = foo.rotated( 2); // [3, 4, 1, 2]
x = foo.rotated( 3); // [4, 1, 2, 3]
x = foo.rotated( 4); // [1, 2, 3, 4]
x = foo.rotated(-1); // [4, 1, 2, 3]
x = foo.rotated(-2); // [3, 4, 1, 2]
x = foo.rotated(-3); // [2, 3, 4, 1]
x = foo.rotated(-4); // [1, 2, 3, 4]

These functions are slightly related to the above swizzles. In any case, they are often useful for communication between SIMD lanes or binary decoding operations.

Warning
Use of these functions leads to less portable code. Consider the scalar implementation where every vector has only one entry. The shift and rotate functions have no useful task to fulfil there and you will almost certainly not get any useful results. It is recommended to add a static_assert for the assumed minimum vector size.
Vector shifted (int amount) const
 Shift vector entries to the left by amount; shifting in zeros.
 
Vector shifted (int amount, Vector shiftIn) const
 Shift vector entries to the left by amount; shifting in values from shiftIn (instead of zeros). More...
 
Vector rotated (int amount) const
 Rotate vector entries to the left by amount.
 
Vector reversed () const
 Returns a vector with all components reversed.
 
Apply/Call/Fill Functions

There are still many situations where the code needs to switch from SIMD operations to scalar execution. In this case you can, of course rely on operator[]. But there are also a number of functions that can help with common patterns.

The apply functions expect a function that returns a scalar value, i.e. a function of the form "T f(T)". The call functions do not return a value and thus the function passed does not need a return value. The fill functions are used to serially set the entries of the vector from the return values of a function.

Example:

void foo(float_v v) {
float_v logarithm = v.apply(std::log);
float_v exponential = v.apply(std::exp);
}

Of course, you can also use lambdas here:

float_v power = v.apply([](float f) { return std::pow(f, 0.6f); })
Parameters
fA functor: this can either be a function or an object that implements operator().
template<typename F >
void callWithValuesSorted (F &&f)
 Call f sequentially, starting with the minimum up to the maximum value.
 
template<typename F >
void call (F &&f) const
 Call f with the scalar entries of the vector.
 
template<typename F >
void call (F &&f, MaskType mask) const
 As above, but skip the entries where mask is not set.
 
template<typename F >
Vector apply (F &&f) const
 Call f on every entry of the vector and return the results as a new vector.
 
template<typename F >
Vector apply (F &&f, MaskType mask) const
 As above, but skip the entries where mask is not set.
 
template<typename IndexT >
void fill (EntryType(&f)(IndexT))
 Fill the vector with the values [f(0), f(1), f(2), ...].
 
void fill (EntryType(&f)())
 Fill the vector with the values [f(), f(), f(), ...].
 
new/delete overloads for correct alignment
void * operator new (size_t size)
 Allocates correctly aligned memory.
 
Vc_ALWAYS_INLINE void * operator new (size_t, void *p)
 Returns p.
 
Vc_ALWAYS_INLINE void * operator new[] (size_t size)
 Allocates correctly aligned memory.
 
Vc_ALWAYS_INLINE void * operator new[] (size_t, void *p)
 Returns p.
 
Vc_ALWAYS_INLINE void operator delete (void *ptr, size_t)
 Frees aligned memory.
 
Vc_ALWAYS_INLINE void operator delete (void *, void *)
 Does nothing.
 
Vc_ALWAYS_INLINE void operator delete[] (void *ptr, size_t)
 Frees aligned memory.
 
Vc_ALWAYS_INLINE void operator delete[] (void *, void *)
 Does nothing.
 

Static Public Member Functions

static constexpr size_t size ()
 Returns the number of scalar components ( \(\mathcal{W}_\mathtt{T}\)) in a vector of this type. More...
 
Generators
static Vector Zero ()
 Returns a vector with the entries initialized to zero.
 
static Vector One ()
 Returns a vector with the entries initialized to one.
 
static Vector IndexesFromZero ()
 Returns a vector with the entries initialized to 0, 1, 2, 3, 4, 5, ...
 
static Vector Random ()
 Returns a vector with pseudo-random entries. More...
 
template<typename G >
static Vector generate (G gen)
 Generate a vector object from return values of gen (static variant of fill).
 

Static Public Attributes

static constexpr size_t MemoryAlignment = VectorTraits<T, Abi>::memoryAlignment()
 Specifies the alignment requirement for aligned load and store calls for objects of this vector type.
 

Deprecated Members

static constexpr size_t Size = VectorTraits<T, Abi>::size()
 Returns the number of scalar components ( \(\mathcal{W}_\mathtt{T}\)) in a vector of this type. More...
 
Vector exponent () const
 Returns the exponents of the floating-point values in the vector. More...
 
MaskType isNegative () const
 Returns whether a value is negative. More...
 
template<typename V2 >
V2 staticCast () const
 Casts the current object to V2. More...
 
template<typename V2 >
V2 reinterpretCast () const
 reinterpret_cast the vector components to construct a vector of type V2. More...
 
Vector copySign (Vector reference) const
 Copies the signs of the components of reference to the components of the current vector, returning the result. More...
 

Member Typedef Documentation

◆ value_type

The type of the entries in the vector.

Definition at line 156 of file vector.h.

◆ mask_type

The type of the mask used for masked operations and returned from comparisons.

Definition at line 171 of file vector.h.

◆ index_type

The type of the vector used for indexes in gather and scatter operations.

Definition at line 179 of file vector.h.

Constructor & Destructor Documentation

◆ Vector() [1/6]

Vector ( )
inlinedefault

Construct a zero-initialized vector object.

This constructor follows the behavior of the underlying arithmetic type T in that the expression T() zero-initializes the object. On the other hand the variable x in T x; is uninitialized. Since, for class types, both expressions call the default constructor Vector<T> x must zero-initialize x as well.

◆ Vector() [2/6]

Vector ( VectorSpecialInitializerZero  )
inlineexplicit

Construct a vector with the entries initialized to zero.

See also
Vc::Zero, Zero()

◆ Vector() [3/6]

Vector ( VectorSpecialInitializerOne  )
inlineexplicit

Construct a vector with the entries initialized to one.

See also
Vc::One, One()

◆ Vector() [4/6]

Vector ( VectorSpecialInitializerIndexesFromZero  )
inlineexplicit

Construct a vector with the entries initialized to 0, 1, 2, 3, 4, 5, ...

See also
Vc::IndexesFromZero, IndexesFromZero()

◆ Vector() [5/6]

Vector ( Vector< U, abi x,
enable_if<!Traits::is_implicit_cast_allowed< U, T >::value >  = nullarg 
)
inlineexplicit

Explicit conversion (i.e.

static_cast) from the remaining Vector<U, Abi> types.

Parameters
xA vector object to use for initialization of the new vector object. If x contains more entries than the new object the high components will be ignored. If x contains fewer entries than the new object the high components of the new object will be zero-initialized. Type conversion is done according to the standard conversion rules for the underlying fundamental arithmetic types.

◆ Vector() [6/6]

Vector ( EntryType  a)
inline

Broadcast Constructor.

Constructs a vector with all entries of the vector filled with the given value.

Parameters
aThe scalar value to broadcast to all entries of the constructed vector.

Member Function Documentation

◆ size()

static constexpr size_t size ( )
inlinestaticconstexpr

Returns the number of scalar components ( \(\mathcal{W}_\mathtt{T}\)) in a vector of this type.

The size of the vector. I.e. the number of scalar entries in the vector. Do not make any assumptions about the size of vectors. If you need vectors of float and int types use Vector::IndexType or SimdArray.

You can easily use if clauses to compare Vector sizes. The compiler can statically evaluate and fully optimize dead code away (very much like #ifdef, but with syntax checking).

Returns
The number of components (i.e. \(\mathcal{W}_\mathtt{T}\)) objects of this vector type store and manipulate.

Definition at line 142 of file vector.h.

◆ Random()

static Vector Random ( )
inlinestatic

Returns a vector with pseudo-random entries.

Currently the state of the random number generator cannot be modified and starts off with the same state. Thus you will get the same sequence of numbers for the same sequence of calls.

Returns
a new random vector. Floating-point values will be in the 0-1 range. Integers will use the full range the integer representation allows.
Note
This function may use a very small amount of state and thus will be a weak random number generator.

◆ setZero()

void setZero ( MaskType  mask)
inline

Set all entries to zero where the mask is set.

A 4-vector with a mask of [0111] therefore would set the last three entries to 0.

Parameters
maskSelects the entries to be set to zero.

◆ setZeroInverted()

void setZeroInverted ( MaskType  mask)
inline

Set all entries to zero where the mask is not set.

A 4-vector with a mask of [0111] therefore would set only the first entry to 0.

Parameters
maskSelects the entries to not be set to zero.

◆ setQnan()

void setQnan ( MaskType  mask)
inline

Set all entries to the bit representation of a QNaN where the mask is set.

Parameters
maskSelects the entries to be set to QNaN.

◆ operator[]() [1/2]

reference operator[] ( size_t  index)
inlinenoexcept

This operator can be used to modify scalar entries of the vector.

Parameters
indexA value between 0 and Size. This value is not checked internally so you must make/be sure it is in range.
Returns
a reference to the vector entry at the given index.
Warning
The use of this function may result in suboptimal performance. Please check whether you can find a more vector-friendly way to do what you intended.
Note
the returned object models the concept of a reference and as such it can exist longer than the data it is referencing.
to avoid lifetime issues, we strongly advice not to store any reference objects.

◆ operator[]() [2/2]

EntryType operator[] ( size_t  index) const
inlinenoexcept

This operator can be used to read scalar entries of the vector.

Parameters
indexA value between 0 and Size. This value is not checked internally so you must make/be sure it is in range.
Returns
a copy of the vector entry at the given index.

◆ operator!()

MaskType operator! ( ) const
inline

Determine where the vector is null.

Returns
a mask which denotes the zero entries of this vector object.

◆ operator~()

Vector operator~ ( ) const
inline

Inverts all bits.

Returns
a new vector which has all bits inverted. I.e. v & ~v == 0.
Note
This operator is only defined for integral types T.

◆ operator()()

Common::WriteMaskedVector<Vector, MaskType> operator() ( MaskType  mask)
inline

Writemask the vector before an assignment.

Parameters
maskThe writemask to be used.
Returns
an object that can be used for any kind of masked assignment.

The returned object is only to be used for assignments and should not be assigned to a variable.

Examples:

float_v v = float_v::Zero(); // v = [0, 0, 0, 0]
int_v v2 = int_v::IndexesFromZero(); // v2 = [0, 1, 2, 3]
v(v2 < 2) = 1.f; // v = [1, 1, 0, 0]
v(v2 < 3) += 1.f; // v = [2, 2, 1, 0]
++v2(v < 1.f); // v2 = [0, 1, 2, 4]

◆ shifted()

Vector shifted ( int  amount,
Vector  shiftIn 
) const
inline

Shift vector entries to the left by amount; shifting in values from shiftIn (instead of zeros).

This function can be used to create vectors from unaligned memory locations.

Example:

for (int i = 0; i < 256; ++i) { mem[i] = i + 1; }
int_v a = mem.vectorAt(0);
int_v x = a.shifted(1, b);
// now x == mem.vectorAt(1, Vc::Unaligned)
Parameters
amountThe number of entries to shift by. amount must be between -Size and Size, otherwise the result is undefined.
shiftInThe vector of values to shift in.
Returns
A new vector with values from this and shiftIn concatenated and then shifted by amount.

◆ sorted()

Vector sorted ( ) const
inline

Return a sorted copy of the vector.

Returns
a sorted vector. The returned values are in ascending order:
v[0] <= v[1] <= v[2] <= v[3] ...
Note
If the vector contains NaNs the result is undefined.

Example:

int_v s = v.sorted();
std::cout << v << '\n' << s << '\n';

With SSE the output would be:

[1513634383, -963914658, 1763536262, -1285037745]
[-1285037745, -963914658, 1513634383, 1763536262]

With the Scalar implementation:

[1513634383]
[1513634383]

◆ exponent()

Vector exponent ( ) const
inline

Returns the exponents of the floating-point values in the vector.

Returns
A new vector object of the same type containing the exponents.
Deprecated:
use Vc::exponent instead.

◆ isNegative()

MaskType isNegative ( ) const
inline

Returns whether a value is negative.

Returns
A new mask object indicating the sign of each vector element.
Deprecated:
use Vc::isnegative instead.

◆ staticCast()

V2 staticCast ( ) const
inline

Casts the current object to V2.

Returns
a converted object of type Vc.
Deprecated:
Use Vc::simd_cast instead.

◆ reinterpretCast()

V2 reinterpretCast ( ) const
inline

reinterpret_cast the vector components to construct a vector of type V2.

Returns
An object of type V2 with the smae bit-representation.
Deprecated:
use Vc::reinterpret_components_cast instead.

◆ copySign()

Vector copySign ( Vector  reference) const
inline

Copies the signs of the components of reference to the components of the current vector, returning the result.

Parameters
referenceA vector object that determines the sign of the the result.
Returns
A new vector with sign taken from reference and absolute value taken from the current vector object.
Deprecated:
Use Vc::copysign instead.

Member Data Documentation

◆ Size

constexpr size_t Size = VectorTraits<T, Abi>::size()
staticconstexpr

Returns the number of scalar components ( \(\mathcal{W}_\mathtt{T}\)) in a vector of this type.

The size of the vector. I.e. the number of scalar entries in the vector. Do not make any assumptions about the size of vectors. If you need vectors of float and int types use Vector::IndexType or SimdArray.

You can easily use if clauses to compare Vector sizes. The compiler can statically evaluate and fully optimize dead code away (very much like #ifdef, but with syntax checking).

Returns
The number of components (i.e. \(\mathcal{W}_\mathtt{T}\)) objects of this vector type store and manipulate.
Deprecated:
Use Vc::Vector::size instead.

Definition at line 771 of file vector.h.

Referenced by Vc::operator<<().


The documentation for this class was generated from the following files:
Vc::Common::MemoryBase< V, Memory< V, Size1, Size2, InitPadding >, 2, Memory< V, Size2, 0, false > >::vectorAt
vector_reference< Flags > vectorAt(size_t i, Flags flags=Flags())
Definition: memorybase.h:483
Vc::Common::Memory
Definition: memory.h:71
Vc
Vector Classes Namespace.
Definition: dox.h:586
Vc::Vector::product
EntryType product() const
Returns the product of all entries in the vector.
Vc::Vector
Definition: fwddecl.h:53
Vc::exp
fixed_size_simd< T, N > exp(const SimdArray< T, N, V, M > &x)
Applies the std:: exp function component-wise and concurrently.
Definition: simdarray.h:1813
Vc::Vector::IndexesFromZero
static Vector IndexesFromZero()
Returns a vector with the entries initialized to 0, 1, 2, 3, 4, 5, ...
Vc::Vector::Random
static Vector Random()
Returns a vector with pseudo-random entries.
Vc::int_v
Vector< int > int_v
vector of signed integers
Definition: vector.h:56
Vc::Vector::rotated
Vector rotated(int amount) const
Rotate vector entries to the left by amount.
Vc::Vector::sum
EntryType sum() const
Returns the sum of all entries in the vector.
Vc::float_v
Vector< float > float_v
vector of single precision
Definition: vector.h:54
Vc::log
fixed_size_simd< T, N > log(const SimdArray< T, N, V, M > &x)
Applies the std:: log function component-wise and concurrently.
Definition: simdarray.h:1839
Vc::Vector::min
EntryType min() const
Returns the smallest entry in the vector.
Vc::Vector::Size
static constexpr size_t Size
Returns the number of scalar components ( ) in a vector of this type.
Definition: vector.h:771
Vc::Vector::Zero
static Vector Zero()
Returns a vector with the entries initialized to zero.
Vc::Vector::shifted
Vector shifted(int amount) const
Shift vector entries to the left by amount; shifting in zeros.
Vc::float_m
Mask< float > float_m
mask type for float_v vectors
Definition: vector.h:89