26 namespace seqan3::detail
31 template <simd::simd_concept simd_t,
size_t... I>
34 return simd_t{((void)I, scalar)...};
39 template <simd::simd_concept simd_t,
typename scalar_t, scalar_t... I>
42 return simd_t{
static_cast<scalar_t
>(
offset + I)...};
59 template <
size_t divisor, simd_concept simd_t>
60 constexpr simd_t extract_impl(simd_t
const & src, uint8_t
const mask)
63 constexpr
size_t chunk = simd_traits<simd_t>::length / divisor;
64 size_t offset = chunk * mask;
65 for (
size_t i = 0; i < chunk; ++i)
66 dst[i] = src[i + offset];
79 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
80 constexpr target_simd_t upcast_signed(source_simd_t
const & src)
82 static_assert(simd_traits<target_simd_t>::max_length == simd_traits<source_simd_t>::max_length,
83 "Target vector has different byte size.");
85 if constexpr (simd_traits<source_simd_t>::max_length == 16)
86 return upcast_signed_sse4<target_simd_t>(src);
87 else if constexpr (simd_traits<source_simd_t>::max_length == 32)
88 return upcast_signed_avx2<target_simd_t>(src);
89 else if constexpr (simd_traits<source_simd_t>::max_length == 64)
90 return upcast_signed_avx512<target_simd_t>(src);
92 static_assert(simd_traits<source_simd_t>::max_length <= 32, "simd type is not supported.");
103 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
104 constexpr target_simd_t upcast_unsigned(source_simd_t const & src)
106 static_assert(simd_traits<target_simd_t>::max_length == simd_traits<source_simd_t>::max_length,
107 "Target vector has different byte size.");
109 if constexpr (simd_traits<source_simd_t>::max_length == 16)
110 return upcast_unsigned_sse4<target_simd_t>(src);
111 else if constexpr (simd_traits<source_simd_t>::max_length == 32)
112 return upcast_unsigned_avx2<target_simd_t>(src);
113 else if constexpr (simd_traits<source_simd_t>::max_length == 64)
114 return upcast_unsigned_avx512<target_simd_t>(src);
116 static_assert(simd_traits<source_simd_t>::max_length <= 32, "simd type is not supported.");
141 template <uint8_t index, simd::simd_concept simd_t>
142 constexpr simd_t extract_half(simd_t const & src)
144 static_assert(index < 2,
"The index must be in the range of [0, 1]");
146 return detail::extract_impl<2>(src, index);
150 template <u
int8_t index, simd::simd_concept simd_t>
151 requires detail::is_builtin_simd_v<simd_t> &&
152 detail::is_native_builtin_simd_v<simd_t>
153 constexpr simd_t extract_half(simd_t
const & src)
155 static_assert(index < 2,
"The index must be in the range of [0, 1]");
157 if constexpr (simd_traits<simd_t>::length < 2)
159 else if constexpr (simd_traits<simd_t>::max_length == 16)
160 return detail::extract_half_sse4<index>(src);
161 else if constexpr (simd_traits<simd_t>::max_length == 32)
162 return detail::extract_half_avx2<index>(src);
164 return detail::extract_impl<2>(src, index);
190 template <uint8_t index, simd::simd_concept simd_t>
191 constexpr simd_t extract_quarter(simd_t const & src)
193 static_assert(index < 4,
"The index must be in the range of [0, 1, 2, 3]");
195 return detail::extract_impl<4>(src, index);
199 template <u
int8_t index, simd::simd_concept simd_t>
200 requires detail::is_builtin_simd_v<simd_t> &&
201 detail::is_native_builtin_simd_v<simd_t>
202 constexpr simd_t extract_quarter(simd_t
const & src)
204 static_assert(index < 4,
"The index must be in the range of [0, 1, 2, 3]");
206 if constexpr (simd_traits<simd_t>::length < 4)
208 else if constexpr (simd_traits<simd_t>::max_length == 16)
209 return detail::extract_quarter_sse4<index>(src);
210 else if constexpr (simd_traits<simd_t>::max_length == 32)
211 return detail::extract_quarter_avx2<index>(src);
213 return detail::extract_impl<4>(src, index);
239 template <uint8_t index, simd::simd_concept simd_t>
240 constexpr simd_t extract_eighth(simd_t const & src)
242 return detail::extract_impl<8>(src, index);
246 template <u
int8_t index, simd::simd_concept simd_t>
247 requires detail::is_builtin_simd_v<simd_t> &&
248 detail::is_native_builtin_simd_v<simd_t>
249 constexpr simd_t extract_eighth(simd_t
const & src)
251 static_assert(index < 8,
"The index must be in the range of [0, 1, 2, 3, 4, 5, 6, 7]");
253 if constexpr (simd_traits<simd_t>::length < 8)
255 else if constexpr (simd_traits<simd_t>::max_length == 16)
256 return detail::extract_eighth_sse4<index>(src);
257 else if constexpr (simd_traits<simd_t>::max_length == 32)
258 return detail::extract_eighth_avx2<index>(src);
260 return detail::extract_impl<8>(src, index);
269 inline namespace simd
281 template <simd::simd_concept simd_t>
282 constexpr simd_t
fill(
typename simd_traits<simd_t>::scalar_type
const scalar) noexcept
284 constexpr
size_t length = simd_traits<simd_t>::length;
297 template <simd::simd_concept simd_t>
298 constexpr simd_t
iota(
typename simd_traits<simd_t>::scalar_type
const offset)
300 constexpr
size_t length = simd_traits<simd_t>::length;
301 using scalar_type =
typename simd_traits<simd_t>::scalar_type;
314 template <simd::simd_concept simd_t>
315 constexpr simd_t load(
void const * mem_addr)
317 assert(mem_addr !=
nullptr);
320 for (
size_t i = 0; i < simd_traits<simd_t>::length; ++i)
321 tmp[i] = *(
static_cast<typename simd_traits<simd_t>::scalar_type
const *
>(mem_addr) + i);
327 template <simd::simd_concept simd_t>
328 requires detail::is_builtin_simd_v<simd_t> &&
329 detail::is_native_builtin_simd_v<simd_t>
330 constexpr simd_t load(
void const * mem_addr)
332 assert(mem_addr !=
nullptr);
334 if constexpr (simd_traits<simd_t>::max_length == 16)
335 return detail::load_sse4<simd_t>(mem_addr);
336 else if constexpr (simd_traits<simd_t>::max_length == 32)
337 return detail::load_avx2<simd_t>(mem_addr);
338 else if constexpr (simd_traits<simd_t>::max_length == 64)
339 return detail::load_avx512<simd_t>(mem_addr);
341 static_assert(simd_traits<simd_t>::max_length >= 16 && simd_traits<simd_t>::max_length <= 64,
342 "Unsupported simd type.");
363 template <simd::simd_concept simd_t>
364 constexpr
void transpose(
std::array<simd_t, simd_traits<simd_t>::length> & matrix)
368 for (
size_t i = 0; i < matrix.size(); ++i)
369 for (
size_t j = 0; j < matrix.size(); ++j)
370 tmp[j][i] = matrix[i][j];
377 template <simd::simd_concept simd_t>
378 requires detail::is_builtin_simd_v<simd_t> &&
379 detail::is_native_builtin_simd_v<simd_t> &&
380 (simd_traits<simd_t>::max_length == simd_traits<simd_t>::length)
381 constexpr
void transpose(
std::array<simd_t, simd_traits<simd_t>::length> & matrix)
383 if constexpr (simd_traits<simd_t>::length == 16)
384 detail::transpose_matrix_sse4(matrix);
385 else if constexpr (simd_traits<simd_t>::length == 32)
386 detail::transpose_matrix_avx2(matrix);
400 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
401 constexpr target_simd_t upcast(source_simd_t const & src)
403 static_assert(simd_traits<target_simd_t>::length <= simd_traits<source_simd_t>::length,
404 "The length of the target simd type must be greater or equal than the length of the source simd type.");
407 for (
unsigned i = 0; i < simd_traits<target_simd_t>::length; ++i)
408 tmp[i] =
static_cast<typename simd_traits<target_simd_t>::scalar_type
>(src[i]);
414 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
415 requires detail::is_builtin_simd_v<target_simd_t> &&
416 detail::is_builtin_simd_v<source_simd_t> &&
417 detail::is_native_builtin_simd_v<source_simd_t>
418 constexpr target_simd_t upcast(source_simd_t
const & src)
420 static_assert(simd_traits<target_simd_t>::length <= simd_traits<source_simd_t>::length,
421 "The length of the target simd type must be greater or equal than the length of the source simd type.");
423 if constexpr (simd_traits<source_simd_t>::length == simd_traits<target_simd_t>::length)
425 static_assert(simd_traits<target_simd_t>::max_length == simd_traits<source_simd_t>::max_length,
426 "Target vector has a different byte size.");
427 return reinterpret_cast<target_simd_t
>(src);
429 else if constexpr (std::signed_integral<
typename simd_traits<source_simd_t>::scalar_type>)
431 return detail::upcast_signed<target_simd_t>(src);
435 static_assert(std::unsigned_integral<
typename simd_traits<source_simd_t>::scalar_type>,
436 "Expected unsigned scalar type.");
437 return detail::upcast_unsigned<target_simd_t>(src);
Provides seqan3::detail::builtin_simd, seqan3::detail::is_builtin_simd and seqan3::simd::simd_traits<...
Provides seqan3::simd::simd_concept.
@ offset
Sequence (SEQ) relative start position (0-based), unsigned value.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
SeqAn specific customisations in the standard namespace.
Provides specific algorithm implementations for AVX2 instruction set.
Provides specific algorithm implementations for AVX512 instruction set.
Provides specific algorithm implementations for SSE4 instruction set.
Provides seqan3::simd::simd_traits.