ape  0.5.0
Audio Programming Environment
simd.h
Go to the documentation of this file.
1 #ifndef CPPAPE_SIMD_H
2 #define CPPAPE_SIMD_H
3 
4 #include <complex>
5 #include <climits>
6 #include "misc.h"
7 #include <vector>
8 
9 namespace ape
10 {
11 #ifndef __CPPAPE_NATIVE_VECTOR_BIT_WIDTH__
12 #define __CPPAPE_NATIVE_VECTOR_BIT_WIDTH__ 128
13 #endif
14 
15 #define __CPPAPE_NATIVE_VECTOR_BYTES__ (__CPPAPE_NATIVE_VECTOR_BIT_WIDTH__ / CHAR_BIT)
16 
20  template<typename T>
21  using vector_register = T __attribute__((ext_vector_type(__CPPAPE_NATIVE_VECTOR_BYTES__ / sizeof(T))));
22 
26  template<typename V>
28  {
32  typedef decltype(V()[0]) value_type;
36  static constexpr std::size_t lanes = sizeof(V) / sizeof(value_type);
37  };
38 
39  template<typename T>
40  inline std::complex<vector_register<T>> operator * (std::complex<vector_register<T>> a, std::complex<vector_register<T>> b)
41  {
42  return { a.real() * b.real() - a.imag() * b.imag(), a.real() * b.imag() + a.imag() * b.real() };
43  }
44 
48  template<typename T>
50  {
51  constexpr auto mask = __CPPAPE_NATIVE_VECTOR_BYTES__ - 1;
52 
53  assert((static_cast<std::uintptr_t>(input.data()) & mask) == 0 && "Input array not sufficiently aligned");
54  assert(input.size() * sizeof(T) % sizeof(vector_register<T>) == 0 && "Whole number of machine vector registers does not fit in array");
55 
56  return { reinterpret_cast<vector_register<T>>(input.data(), (sizeof(T) * input.size()) / sizeof(vector_register<T>)) };
57  }
58 
62  template<typename T>
63  inline uarray<std::complex<vector_register<T>>> as_vectors(uarray<std::complex<T>> input)
64  {
65  constexpr auto mask = __CPPAPE_NATIVE_VECTOR_BYTES__ - 1;
66 
67  assert((reinterpret_cast<std::uintptr_t>(input.data()) & mask) == 0 && "Input array not sufficiently aligned");
68  assert(input.size() * sizeof(T) % sizeof(std::complex<vector_register<T>>) == 0 && "Whole number of machine vector registers does not fit in array");
69 
70  return { reinterpret_cast<std::complex<vector_register<T>>*>(input.data()), (sizeof(std::complex<T>) * input.size()) / sizeof(std::complex<vector_register<T>>) };
71  }
72 
76  template<typename T>
77  inline uarray<vector_register<T>> as_vectors(std::vector<T>& input)
78  {
79  return as_vectors(as_uarray(input));
80  }
81 
85  template<typename T>
86  inline uarray<std::complex<vector_register<T>>> as_vectors(std::vector<std::complex<T>>& input)
87  {
88  return as_vectors(as_uarray(input));
89  }
90 }
91 
92 #endif
ape::vector_traits
Traits for vector_register
Definition: simd.h:27
ape::as_uarray
uarray< T > as_uarray(std::vector< T > &vec)
Definition: misc.h:681
ape::vector_traits::lanes
static constexpr std::size_t lanes
How many lanes (or "width") of the register there is
Definition: simd.h:36
misc.h
ape::uarray
An unowned array wrapper - a mutable "view" of something else, that cannot be resized....
Definition: misc.h:24
ape
Definition: audiofile.h:7
ape::as_vectors
uarray< vector_register< T > > as_vectors(uarray< T > input)
Reinterprets the input as a array of SIMD vectors
Definition: simd.h:49
ape::vector_register
T __attribute__((ext_vector_type(__CPPAPE_NATIVE_VECTOR_BYTES__/sizeof(T)))) vector_register
A machine sized SIMD register with as many lanes as possible for the given T
Definition: simd.h:21
ape::uarray::size
std::size_t size() const noexcept
Returns the size of the array pointed to by this uarray
Definition: misc.h:113
ape::uarray::data
T * data() noexcept
Retrieve a raw pointer to the array pointed to
Definition: misc.h:104
ape::vector_traits::value_type
decltype(V()[0]) typedef value_type
The type of the element in the vector_register
Definition: simd.h:32