SeqAn3
builtin_simd.hpp
Go to the documentation of this file.
1 // ============================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ============================================================================
4 //
5 // Copyright (c) 2006-2018, Knut Reinert & Freie Universitaet Berlin
6 // Copyright (c) 2016-2018, Knut Reinert & MPI Molekulare Genetik
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
25 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 //
33 // ============================================================================
34 
41 #pragma once
42 
43 #include <type_traits>
44 
50 
51 namespace seqan3::detail
52 {
53 
79 template <typename scalar_t, size_t length>
80 struct builtin_simd;
81 
84 template <typename scalar_t, size_t length>
86  requires is_power_of_two(length)
88 struct builtin_simd<scalar_t, length>
89 {
91 #if SEQAN3_DOXYGEN_ONLY(1)0
92  using type = scalar_t __attribute__((vector_size(sizeof(scalar_t) * length))));
93  // doxygen 1.8.13 does not support c++11 attributes, thus this doxygen-only definition
94 #elif defined(__clang__)
95  using type = scalar_t __attribute__((ext_vector_type(length)));
96 #else
97  using type [[gnu::vector_size(sizeof(scalar_t) * length)]] = scalar_t;
98 #endif
99 };
100 
105 template <typename builtin_simd_t>
106 struct builtin_simd_traits_helper : std::false_type
107 {};
108 
113 template <typename builtin_simd_t>
115  requires requires (builtin_simd_t simd) { {simd[0]}; }
117 struct builtin_simd_traits_helper<builtin_simd_t>
118 {
120  using scalar_type = std::remove_reference_t<decltype(std::declval<builtin_simd_t>()[0])>;
122  static constexpr auto length = min_viable_uint_v<sizeof(builtin_simd_t) / sizeof(scalar_type)>;
123 
126  static constexpr bool value = is_power_of_two(length) && std::is_same_v<builtin_simd_t, transformation_trait_or_t<builtin_simd<scalar_type, length>, void>>;
127 };
128 
138 template <typename builtin_simd_t>
139 struct is_builtin_simd : std::bool_constant<builtin_simd_traits_helper<builtin_simd_t>::value>
140 {};
141 
150 template <>
151 constexpr auto default_simd_max_length<builtin_simd> = []()
152 {
153 #if defined(__AVX512F__)
154  return min_viable_uint_v<64u>;
155 #elif defined(__AVX2__)
156  return min_viable_uint_v<32u>;
157 #elif defined(__SSE4_1__) && defined(__SSE4_2__)
158  return min_viable_uint_v<16u>;
159 #else
160  return min_viable_uint_v<0u>;
161 #endif
162 }();
163 
164 } // namespace seqan3::detail
165 
166 namespace seqan3
167 {
168 
169 inline namespace simd
170 {
171 
177 template <typename builtin_simd_t>
178 // \cond
179  requires detail::is_builtin_simd<builtin_simd_t>::value
180 // \endcond
181 struct simd_traits<builtin_simd_t>
182 {
184  using scalar_type = typename detail::builtin_simd_traits_helper<builtin_simd_t>::scalar_type;
186  static constexpr auto length = detail::builtin_simd_traits_helper<builtin_simd_t>::length;
188  static constexpr auto max_length = length == 1u ? length : sizeof(scalar_type) * length;
189 
190  static_assert(std::is_integral_v<scalar_type>, "For now we assume that builtin simd can only be integers");
192  using mask_type = typename detail::builtin_simd<std::make_signed_t<scalar_type>, length>::type;
194  using swizzle_type = typename detail::builtin_simd<uint8_t, max_length>::type;
195 };
196 
197 } // inline namespace simd
198 
199 } // namespace seqan3
Contains seqan3::simd::simd_traits.
typename detail::builtin_simd< uint8_t, max_length >::type swizzle_type
The type used to define how to swizzle a simd vector (is not defined if simd_t does not satisfy seqan...
Definition: builtin_simd.hpp:194
Contains metaprogramming utilities for integer types.
Provides seqan3::detail::transformation_trait_or.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:58
typename detail::builtin_simd_traits_helper< builtin_simd_t >::scalar_type scalar_type
The underlying type of a simd vector (is not defined if simd_t does not satisfy seqan3::simd::simd_co...
Definition: builtin_simd.hpp:184
Definition: aligned_sequence_concept.hpp:288
seqan3::simd::simd_traits is the trait class that provides uniform interface to the properties of sim...
Definition: simd_traits.hpp:65
Provides C++20 additions to the type_traits header.
Provides utility functions for bit twiddling.
typename detail::builtin_simd< std::make_signed_t< scalar_type >, length >::type mask_type
The type returned by comparison operators (is not defined if simd_t does not satisfy seqan3::simd::si...
Definition: builtin_simd.hpp:192
Contains seqan3::detail::default_simd_length and seqan3::detail::default_simd_max_length.