T-SIMD v31.1.0
A C++ template SIMD library
Loading...
Searching...
No Matches
vec.H
1// ===========================================================================
2//
3// generic template for Vec
4//
5// This source code file is part of the following software:
6//
7// - the low-level C++ template SIMD library
8// - the SIMD implementation of the MinWarping and the 2D-Warping methods
9// for local visual homing.
10//
11// The software is provided based on the accompanying license agreement in the
12// file LICENSE.md.
13// The software is provided "as is" without any warranty by the licensor and
14// without any liability of the licensor, and the software may not be
15// distributed by the licensee; see the license agreement for details.
16//
17// (C) Ralf Möller
18// Computer Engineering
19// Faculty of Technology
20// Bielefeld University
21// www.ti.uni-bielefeld.de
22//
23// ===========================================================================
24
25// 13. Feb 23 (Jonas Keller): removed "SIMD"-prefix from most types
26// (versions with "SIMD"-prefix are still available for backward
27// compatibility in SIMDBackwardCompat.H)
28
29// 09. Mar 23 (Jonas Keller): added doxygen documentation
30
31#pragma once
32#ifndef SIMD_VEC_H_
33#define SIMD_VEC_H_
34
35#include "defs.H"
36#include "types.H"
37
38#include <algorithm>
39#include <cstddef>
40#include <type_traits>
41
45namespace simd {
46
47// TODO: - absdiff also for unsigned types -> SSE lecture vecintrin66
48// TODO: - bitwise shift: what about float?
49// TODO: - loadr / storer
50// TODO: - element-wise rotation in a vector using alignre
51// TODO: - functions for rsqrt, rcp Newton *steps*?
52// TODO: - add to names rcp, rsqrt something with "estimate"?
53// TODO: - NEON has a "set1" with immediate arguments (vmovq_n), so it would
54// TODO: be nice to have a set1const function with template argument, but
55// TODO: this only works for integers since float template parameter are not
56// TODO: allowed by the standard
57
58// ===========================================================================
59// generic template for Vec and Mask
60// ===========================================================================
61
62// 30. Sep 19 (rm): Mask support contributed by Markus Vieth
63
64// specialized for type of elements and number of bytes in the SIMD vector
72template <typename T, size_t SIMD_WIDTH_DEFAULT_NATIVE>
73class Vec
74#ifdef DOXYGEN
75{
76public:
80 static constexpr size_t elements = SIMD_WIDTH / sizeof(T);
81
85 static constexpr size_t elems = elements;
86
90 static constexpr size_t bytes = SIMD_WIDTH;
91
92 // 05. Sep 23 (Jonas Keller): added allocator
104}
105#endif
106;
107
116template <typename T, size_t SIMD_WIDTH_DEFAULT_NATIVE>
117class Mask
118#ifdef DOXYGEN
119{
120public:
127 explicit SIMD_INLINE Mask<T, SIMD_WIDTH>(const Vec<T, SIMD_WIDTH> &x);
128
134 explicit SIMD_INLINE Mask<T, SIMD_WIDTH>(const uint64_t x);
135
144 explicit SIMD_INLINE operator Vec<T, SIMD_WIDTH>() const { return mask; };
145
153 explicit SIMD_INLINE operator uint64_t() const;
154
161 SIMD_INLINE bool operator[](const size_t i) const;
162
169 SIMD_INLINE bool operator==(const Mask<T, SIMD_WIDTH> &other) const;
170}
171#endif
172;
173
174// ===========================================================================
175// helper functions for templates converting from Tin to Tout
176// ===========================================================================
177
178// numInVecs() and numOutVecs() assume that either
179// - a single vector is extended into multiple vectors or
180// - multiple vectors are packed into a single vector
181//
182// numSIMDVecsElements encodes the number of elements in *all* input / all
183// output vectors
184//
185// removed: numSIMDVecElements encodes the number of elements in each vector
186// (or use Vec::elements instead)
187//
188// removed: numInputSIMDVecElements/numOutputSIMDVecElements encode
189// the number of elements in *each* input / output vector
190
200template <typename Tout, typename Tin>
201static constexpr SIMD_INLINE size_t numInVecs()
202{
203 return (sizeof(Tout) < sizeof(Tin)) ? (sizeof(Tin) / sizeof(Tout)) : 1;
204}
205
215template <typename Tout, typename Tin>
216static constexpr SIMD_INLINE size_t numOutVecs()
217{
218 return (sizeof(Tout) > sizeof(Tin)) ? (sizeof(Tout) / sizeof(Tin)) : 1;
219}
220
230template <typename Tout, typename Tin, size_t SIMD_WIDTH>
231static constexpr SIMD_INLINE size_t numSIMDVecsElements()
232{
233 return (sizeof(Tout) > sizeof(Tin)) ? Vec<Tin, SIMD_WIDTH>::elems :
235}
236
237// 13. May 23 (Jonas Keller): added BigEnoughFloat
238
239namespace internal {
240namespace vec {
241// std::max and std::min are not constexpr in C++11, so we need to provide our
242// own, since we need them in a constexpr context
243template <typename T>
244constexpr const T &max(const T &a, const T &b)
245{
246 return (a < b) ? b : a;
247}
248
249template <typename T>
250constexpr const T &min(const T &a, const T &b)
251{
252 return (a < b) ? a : b;
253}
254} // namespace vec
255} // namespace internal
256
265template <typename Tout, typename Tin>
267#ifdef SIMD_64BIT_TYPES
268 typename std::conditional<internal::vec::max(sizeof(Tout), sizeof(Tin)) <=
269 sizeof(Float),
270 Float, Double>::type;
271#else
272 Float;
273#endif
274
275// 22. Jan 23 (Jonas Keller): removed primary template functions, as they are
276// not needed anymore due to a wrapper layer
277
278} // namespace simd
279
280#endif
SIMD mask class consisting of as many bits as the corresponding Vec has elements.
Definition vec.H:119
bool operator[](const size_t i) const
Returns the Mask bit at the given index.
Mask(const Vec< T, SIMD_WIDTH > &x)
Constructs a Mask from a Vec.
bool operator==(const Mask< T, SIMD_WIDTH > &other) const
Compares the Mask with another Mask.
SIMD vector class, holds multiple elements of the same type.
Definition vec.H:75
static constexpr size_t elems
Number of elements in the vector. Alias for elements.
Definition vec.H:85
static constexpr size_t bytes
Number of bytes in the vector.
Definition vec.H:90
static constexpr size_t elements
Number of elements in the vector.
Definition vec.H:80
Aligned allocator.
Definition alloc.H:132
float Float
Single-precision floating point number (32-bit)
Definition types.H:56
double Double
Double-precision floating point number (64-bit)
Definition types.H:57
typename std::conditional< internal::vec::max(sizeof(Tout), sizeof(Tin))<= sizeof(Float), Float, Double >::type BigEnoughFloat
Smallest floating point type that is at least as big as the input and output types.
Definition vec.H:266
static constexpr size_t numInVecs()
Number of input vectors for functions that potentially change the size of the elements but not the nu...
Definition vec.H:201
static constexpr size_t numOutVecs()
Number of output vectors for functions that potentially change the size of the elements but not the n...
Definition vec.H:216
static constexpr size_t numSIMDVecsElements()
Number of elements in all input vectors for functions that potentially change the size of the element...
Definition vec.H:231
Namespace for T-SIMD.
Definition time_measurement.H:161