Experimental::simd
#
Header File: Kokkos_SIMD.hpp
Usage:
Kokkos::Experimental::simd
is an abstraction over platform-specific vector datatypes and calls platform-specific vector intrinsics.
It is based on the simd
type proposed for ISO C++ in this document
Interface#
namespace Experimental {
template <class T, class Abi>
class simd;
}
Template Parameters#
The first template parameter T
should be a C++ fundamental type for which the current platform supports vector intrinsics. Kokkos supports the following types for T
:
float
double
std::int32_t
std::int64_t
std::uint32_t
std::uint64_t
The second template parameter Abi
is one of the pre-defined ABI types in the namespace Kokkos::Experimental::simd_abi
. This type determines the size of the vector and what architecture-specific intrinsics will be used. The following types are always available in that namespace:
scalar
: a fallback ABI which always has vector size of 1 and uses no special intrinsics.native
: the “best” ABI for the architecture for which Kokkos was compiled.
Typedefs#
value_type
: Equal toT
reference
: This type should be convertible tovalue_type
andvalue_type
should be assignable toreference
. It may be a plain reference or it may be an implementation-defined type that calls vector intrinsics to extract or fill in one vector lane.mask_type
: Equal tosimd_mask<T, Abi>
abi_type
: Equal toAbi
Width#
static constexpr std::size_t size()
:simd<T, Abi>::size()
is a compile-time constant of the width of the vector, i.e. the number of values of typeT
in the vector.
Constructors#
simd()
: Default Constructor. The vector values are not initialized by this constructor.template <class U> simd(U&&)
: Single-value constructor. The argument will be converted tovalue_type
and all the vector values will be set equal to that value.template <class G> simd(G&& gen)
: Generator constructor. The generatorgen
should be a callable type (e.g. functor) that can acceptstd::integral_constant<std::size_t, i>()
as an argument and return something convertible tovalue_type
. Vector lanei
will be initialized to the value ofgen(std::integral_constant<std::size_t, i>())
.
Load/Store Methods#
template <class U, class Flags> void copy_from(const U* mem, Flags flags)
: Loads the full vector of contiguous values starting at the addressmem
.Flags
is thesimd_flags
that is used to describe the alignment at the addressmem
.template <class U, class Flags> void copy_to(U* mem, Flags flags)
: Stores the full vector of contiguous values starting at the addressmem
.Flags
is thesimd_flags
that is used to describe the alignment at the addressmem
.
Simd Flags#
Available
simd_flags
aresimd_flag_default
andsimd_flag_aligned
.For backward compatibility,
Kokkos::Experimental::element_aligned_tag
andKokkos::Experimental::vector_aligned_tag
types are available.Kokkos::Experimental::element_aligned_tag
is a type alias fordecltype(simd_flag_default)
andKokkos::Experimental::vector_aligned_tag
is a type alias fordecltype(simd_flag_aligned)
.
Value Access Methods#
reference operator[](std::size_t)
: returns a reference to vector valuei
that can be modified.value_type operator[](std::size_t) const
: returns the vector valuei
.
Arithmetic Operators#
simd simd::operator-() const
simd operator+(const simd& lhs, const simd& rhs)
simd operator-(const simd& lhs, const simd& rhs)
simd operator*(const simd& lhs, const simd& rhs)
simd operator/(const simd& lhs, const simd& rhs)
simd operator>>(const simd& lhs, const simd& rhs)
simd operator>>(const simd& lhs, int rhs)
simd operator<<(const simd& lhs, const simd& rhs)
simd operator<<(const simd& lhs, int rhs)
simd operator+=(simd& lhs, const simd& rhs)
simd operator-=(simd& lhs, const simd& rhs)
simd operator*=(simd& lhs, const simd& rhs)
simd operator/=(simd& lhs, const simd& rhs)
Comparison Operators#
mask_type operator==(const simd& lhs, const simd& rhs)
mask_type operator!=(const simd& lhs, const simd& rhs)
mask_type operator>=(const simd& lhs, const simd& rhs)
mask_type operator<=(const simd& lhs, const simd& rhs)
mask_type operator>(const simd& lhs, const simd& rhs)
mask_type operator<(const simd& lhs, const simd& rhs)
Rounding Functions#
simd Kokkos::floor(const simd& lhs)
simd Kokkos::ceil(const simd& lhs)
simd Kokkos::round(const simd& lhs)
simd Kokkos::trunc(const simd& lhs)
Min/Max Functions#
simd Kokkos::min(const simd& lhs, const simd& rhs)
simd Kokkos::max(const simd& lhs, const simd& rhs)
<cmath>
Functions#
simd Kokkos::abs(const simd& lhs)
simd Kokkos::exp(const simd& lhs)
simd Kokkos::exp2(const simd& lhs)
simd Kokkos::log(const simd& lhs)
simd Kokkos::log10(const simd& lhs)
simd Kokkos::sqrt(const simd& lhs)
simd Kokkos::cbrt(const simd& lhs)
simd Kokkos::sin(const simd& lhs)
simd Kokkos::cos(const simd& lhs)
simd Kokkos::tan(const simd& lhs)
simd Kokkos::asin(const simd& lhs)
simd Kokkos::acos(const simd& lhs)
simd Kokkos::atan(const simd& lhs)
simd Kokkos::sinh(const simd& lhs)
simd Kokkos::cosh(const simd& lhs)
simd Kokkos::tanh(const simd& lhs)
simd Kokkos::asinh(const simd& lhs)
simd Kokkos::acosh(const simd& lhs)
simd Kokkos::atanh(const simd& lhs)
simd Kokkos::erf(const simd& lhs)
simd Kokkos::erfc(const simd& lhs)
simd Kokkos::tgamma(const simd& lhs)
simd Kokkos::lgamma(const simd& lhs)
simd Kokkos::pow(const simd& lhs, const simd& rhs)
simd Kokkos::hypot(const simd& x, const simd& y)
simd Kokkos::hypot(const simd& x, const simd& y, const simd& z)
simd Kokkos::atan2(const simd& x, const simd& y)
simd Kokkos::copysign(const simd& mag, const simd& sgn)
simd Kokkos::fma(const simd& x, const simd& y, const simd& z)
These functions are only defined in AVX2
and AVX512
for value_type=float
and value_type=double
simd Kokkos::cbrt(simd& lhs)
simd Kokkos::exp(simd& lhs)
simd Kokkos::log(simd& lhs)
Global Typedefs#
template <class T> Kokkos::Experimental::native_simd
: Alias forKokkos::Experimental::simd<T, Kokkos::Experimental::simd_abi::native<T>>
.Kokkos::Experimental::element_aligned_tag
: Alias forKokkos::Experimental::simd_flags<>
Kokkos::Experimental::vector_aligned_tag
: Alias forKokkos::Experimental::simd_flags<simd_alignment_vector_aligned>
Examples#
#include <Kokkos_SIMD.hpp>
#include <cstdio>
int main(int argc, char* argv[]) {
Kokkos::initialize(argc,argv);
{
using simd_type = Kokkos::Experimental::native_simd<double>;
simd_type a([] (std::size_t i) { return 0.1 * i; });
simd_type b(2.0);
simd_type c = Kokkos::sqrt(a * a + b * b);
for (std::size_t i = 0; i < simd_type::size(); ++i) {
printf("[%zu] = %g\n", i, c[i]);
}
}
Kokkos::finalize();
}