dune-common 2.12-git
Loading...
Searching...
No Matches
SIMD Abstraction Implementation for Vc
Collaboration diagram for SIMD Abstraction Implementation for Vc:

Files

file  vc.hh
 SIMD abstractions for Vc.
 

Functions

template<class T , int N>
fixed_size_simd< T, N > Vc::max (const fixed_size_simd< T, N > &a, const fixed_size_simd< T, N > &b)
 Binary maximum of two Vc::fixed_size_simd, found by ADL.
 
template<class T , int N>
fixed_size_simd< T, N > Vc::min (const fixed_size_simd< T, N > &a, const fixed_size_simd< T, N > &b)
 Binary minimum of two Vc::fixed_size_simd, found by ADL.
 

Detailed Description

This implements the vectorization interface for Vc types, namely Vc::Vector, Vc::Mask, Vc::SimdArray, Vc::SimdMaskArray, Vc::fixed_size_simd and Vc::fixed_size_simd_mask. It requires Vc 1.4.1 or newer.

For a fixed number of lanes, prefer Vc::fixed_size_simd<T, N> (and Vc::fixed_size_simd_mask<T, N>) over Vc::SimdArray<T, N>. Since Vc 1.4 the operations on SimdArray return fixed_size_simd, and Simd::Rebind and Simd::Mask produce fixed_size_simd and fixed_size_simd_mask for all Vc types. SimdArray and SimdMaskArray are still supported as input types.

As an application developer, you need to #include <dune/common/simd/vc.hh>. You need to make sure that HAVE_VC is true before doing so:

You also need to make sure that the compiler uses the correct flags and that the linker can find the library. (The compilation flags include one that ensures a name mangling scheme that can distinguish the compiler-intrinsic vector types from non-vector types is used.)

There should be no need to explicitly call find_package(Vc) in your CMakeLists.txt, dune-common already does that. If your module can't live without Vc, you may however want to do something like this in your cmake/modules/YourModuleMacros.cmake:

if(NOT Vc_FOUND)
message(SEND_ERROR "This module requires Vc")
endif(NOT Vc_FOUND)

If you just want to compile dune, and have Vc installed to a location where cmake is not looking by default, you need to add that location to CMAKE_PREFIX_PATH. E.g. pass -DCMAKE_PREFIX_PATH=$VCDIR to cmake, for instance by including that in the variable CMAKE_FLAGS in the options file that you pass to dunecontrol. $VCDIR should be the same directory that you passed in -DCMAKE_INSTALL_PREFIX=... to cmake when you compiled Vc, i.e. Vc's main include file should be found under $VCDIR/include/Vc/Vc, and the library under $VCDIR/lib/libVc.a or similar.

Restrictions

During thorough testing of the Vc abstraction implementation it turned out that certain operations were not supported, or were buggy. This meant that the tests had to be relaxed, and/or some restrictions had to made as to how things must be done through the SIMD abstraction, see Limitations of the Abstraction Layer.

For future reference, here is a detailed list of things that certain Vc types do or don't support. s denotes a scalar object/expression (i.e. of type double or in the case of masks bool). v denotes a vector/mask object/expression. sv means that both scalar and vector arguments are accepted. V denotes a vector/mask type. @ means any applicable operator that is not otherwise listed.

| | Vector | Vector | SimdArray | SimdArray | Masks[4] |
| | <double> AVX | <int> SSE | <double,4> | <int,4> | |
|-------------------------+--------------+-----------+------------+-----------+-----------|
| V v(s); | y | y | y | y | y |
| V v = s; | y | y | y | y | *N* |
| V v{s}; | *N* | y | *N* | *N* | y |
| V v = {s}; | *N* | y | *N* | *N* | *N* |
|-------------------------+--------------+-----------+------------+-----------+-----------|
| v = s; | y | y | y | y | *N* |
| v = {s}; | *N* | *N* | *N* | *N* | *N* |
|-------------------------+--------------+-----------+------------+-----------+-----------|
| v++; ++v; | y | y | *N* | *N* | y(n/a)[2] |
| v--; --v; | y | y | *N* | *N* | n/a |
|-------------------------+--------------+-----------+------------+-----------+-----------|
| +v; -v; | y | y | y | y | *N* |
| !v; | y | y | y | y | y |
| ~v; | n/a | y | n/a | y | *N* |
|-------------------------+--------------+-----------+------------+-----------+-----------|
| sv @ sv; but see below | y | y | y | y | *N* |
|-------------------------+--------------+-----------+------------+-----------+-----------|
| s << v; s >> v; | n/a | *N* | n/a | *N* | *N* |
|-------------------------+--------------+-----------+------------+-----------+-----------|
| v == v; v != v; | y | y | y | y | *N* [1] |
|-------------------------+--------------+-----------+------------+-----------+-----------|
| v & v; v ^ v; v ¦ v; | n/a | y | n/a | y | y |
| sv && sv; sv ¦¦ sv; | y | y | *N* | *N* | *N* |
| v && v; v ¦¦ v; | y | y | *N* | *N* | y |
|-------------------------+--------------+-----------+------------+-----------+-----------|
| v @= sv; but see below | y | y | y | y | *N* |
| v &= v; v ^= v; v ¦= v; | n/a | y | n/a | y | y |
|-------------------------+--------------+-----------+------------+-----------+-----------|
| v, v;[3] | *N* | *N* | y | y | y |

Notes:

Support levels:

Each operation was tested with the full set of combinations of possible const/non-const lvalue/xvalue arguments. Each combination of constness and value category was applied to the scalar type and the operation tried in an SFINAE context; combinations that failed here were skipped for vector arguments too.

Function Documentation

◆ max()

template<class T , int N>
fixed_size_simd< T, N > Vc::max ( const fixed_size_simd< T, N > &  a,
const fixed_size_simd< T, N > &  b 
)

Binary maximum of two Vc::fixed_size_simd, found by ADL.

Vc declares the binary max() only for Vc::SimdArray. For the derived Vc::fixed_size_simd, generic code of the form

using std::max;
auto m = max(a, b);
fixed_size_simd< T, N > max(const fixed_size_simd< T, N > &a, const fixed_size_simd< T, N > &b)
Binary maximum of two Vc::fixed_size_simd, found by ADL.
Definition simd/vc.hh:715
T max(T... args)

would then select std::max(), which cannot use the mask returned by <. This overload is found by argument-dependent lookup and forwards to Vc's implementation for SimdArray. The SIMD interface requires this for all vector types, see Dune::Simd::max().

Note
It is declared in Vc's (versioned) namespace, since that is the only namespace argument-dependent lookup searches for this type.

◆ min()

template<class T , int N>
fixed_size_simd< T, N > Vc::min ( const fixed_size_simd< T, N > &  a,
const fixed_size_simd< T, N > &  b 
)

Binary minimum of two Vc::fixed_size_simd, found by ADL.

The counterpart of max() for fixed_size_simd, see there.