27namespace seqan3::detail
32template <simd::simd_concept simd_t,
size_t... I>
35 return simd_t{((void)I, scalar)...};
40template <simd::simd_concept simd_t,
typename scalar_t, scalar_t... I>
43 return simd_t{
static_cast<scalar_t
>(
offset + I)...};
60template <
size_t divisor, simd_concept simd_t>
61constexpr simd_t extract_impl(simd_t
const & src, uint8_t
const mask)
64 constexpr size_t chunk = simd_traits<simd_t>::length / divisor;
66 for (
size_t i = 0; i <
chunk; ++i)
80template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
81constexpr target_simd_t upcast_signed(source_simd_t
const & src)
83 static_assert(simd_traits<target_simd_t>::max_length == simd_traits<source_simd_t>::max_length,
84 "Target vector has different byte size.");
86 if constexpr (simd_traits<source_simd_t>::max_length == 16)
87 return upcast_signed_sse4<target_simd_t>(src);
88 else if constexpr (simd_traits<source_simd_t>::max_length == 32)
89 return upcast_signed_avx2<target_simd_t>(src);
90 else if constexpr (simd_traits<source_simd_t>::max_length == 64)
91 return upcast_signed_avx512<target_simd_t>(src);
93 static_assert(simd_traits<source_simd_t>::max_length <= 32,
"simd type is not supported.");
104template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
105constexpr target_simd_t upcast_unsigned(source_simd_t
const & src)
107 static_assert(simd_traits<target_simd_t>::max_length == simd_traits<source_simd_t>::max_length,
108 "Target vector has different byte size.");
110 if constexpr (simd_traits<source_simd_t>::max_length == 16)
111 return upcast_unsigned_sse4<target_simd_t>(src);
112 else if constexpr (simd_traits<source_simd_t>::max_length == 32)
113 return upcast_unsigned_avx2<target_simd_t>(src);
114 else if constexpr (simd_traits<source_simd_t>::max_length == 64)
115 return upcast_unsigned_avx512<target_simd_t>(src);
117 static_assert(simd_traits<source_simd_t>::max_length <= 32,
"simd type is not supported.");
142template <u
int8_t index, simd::simd_concept simd_t>
143constexpr simd_t extract_half(simd_t
const & src)
145 static_assert(index < 2,
"The index must be in the range of [0, 1]");
147 return detail::extract_impl<2>(src, index);
151template <u
int8_t index, simd::simd_concept simd_t>
152 requires detail::is_builtin_simd_v<simd_t> && detail::is_native_builtin_simd_v<simd_t>
153constexpr 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);
163 else if constexpr (simd_traits<simd_t>::max_length == 64)
164 return detail::extract_half_avx512<index>(src);
166 return detail::extract_impl<2>(src, index);
192template <u
int8_t index, simd::simd_concept simd_t>
193constexpr simd_t extract_quarter(simd_t
const & src)
195 static_assert(index < 4,
"The index must be in the range of [0, 1, 2, 3]");
197 return detail::extract_impl<4>(src, index);
201template <u
int8_t index, simd::simd_concept simd_t>
202 requires detail::is_builtin_simd_v<simd_t> && detail::is_native_builtin_simd_v<simd_t>
203constexpr simd_t extract_quarter(simd_t
const & src)
205 static_assert(index < 4,
"The index must be in the range of [0, 1, 2, 3]");
207 if constexpr (simd_traits<simd_t>::length < 4)
209 else if constexpr (simd_traits<simd_t>::max_length == 16)
210 return detail::extract_quarter_sse4<index>(src);
211 else if constexpr (simd_traits<simd_t>::max_length == 32)
212 return detail::extract_quarter_avx2<index>(src);
213#if defined(__AVX512DQ__)
214 else if constexpr (simd_traits<simd_t>::max_length == 64)
215 return detail::extract_quarter_avx512<index>(src);
218 return detail::extract_impl<4>(src, index);
244template <u
int8_t index, simd::simd_concept simd_t>
245constexpr simd_t extract_eighth(simd_t
const & src)
247 return detail::extract_impl<8>(src, index);
251template <u
int8_t index, simd::simd_concept simd_t>
252 requires detail::is_builtin_simd_v<simd_t> && detail::is_native_builtin_simd_v<simd_t>
253constexpr simd_t extract_eighth(simd_t
const & src)
255 static_assert(index < 8,
"The index must be in the range of [0, 1, 2, 3, 4, 5, 6, 7]");
257 if constexpr (simd_traits<simd_t>::length < 8)
259 else if constexpr (simd_traits<simd_t>::max_length == 16)
260 return detail::extract_eighth_sse4<index>(src);
261 else if constexpr (simd_traits<simd_t>::max_length == 32)
262 return detail::extract_eighth_avx2<index>(src);
263#if defined(__AVX512DQ__)
264 else if constexpr (simd_traits<simd_t>::max_length == 64)
265 return detail::extract_eighth_avx512<index>(src);
268 return detail::extract_impl<8>(src, index);
273template <simd::simd_concept simd_t>
274constexpr void transpose(
std::array<simd_t, simd_traits<simd_t>::length> & matrix)
278 for (
size_t i = 0; i < matrix.size(); ++i)
279 for (
size_t j = 0; j < matrix.size(); ++j)
280 tmp[j][i] = matrix[i][j];
302template <simd::simd_concept simd_t>
303constexpr simd_t
fill(
typename simd_traits<simd_t>::scalar_type
const scalar)
noexcept
305 constexpr size_t length = simd_traits<simd_t>::length;
318template <simd::simd_concept simd_t>
319constexpr simd_t
iota(
typename simd_traits<simd_t>::scalar_type
const offset)
321 constexpr size_t length = simd_traits<simd_t>::length;
322 using scalar_type =
typename simd_traits<simd_t>::scalar_type;
335template <simd::simd_concept simd_t>
336constexpr simd_t load(
void const * mem_addr)
338 assert(mem_addr !=
nullptr);
341 for (
size_t i = 0; i < simd_traits<simd_t>::length; ++i)
342 tmp[i] = *(
static_cast<typename simd_traits<simd_t>::scalar_type
const *
>(mem_addr) + i);
348template <simd::simd_concept simd_t>
349 requires detail::is_builtin_simd_v<simd_t> && detail::is_native_builtin_simd_v<simd_t>
350constexpr simd_t load(
void const * mem_addr)
352 assert(mem_addr !=
nullptr);
354 if constexpr (simd_traits<simd_t>::max_length == 16)
355 return detail::load_sse4<simd_t>(mem_addr);
356 else if constexpr (simd_traits<simd_t>::max_length == 32)
357 return detail::load_avx2<simd_t>(mem_addr);
358 else if constexpr (simd_traits<simd_t>::max_length == 64)
359 return detail::load_avx512<simd_t>(mem_addr);
361 static_assert(simd_traits<simd_t>::max_length >= 16 && simd_traits<simd_t>::max_length <= 64,
362 "Unsupported simd type.");
376template <simd::simd_concept simd_t>
377constexpr void store(
void * mem_addr, simd_t
const & simd_vec)
379 assert(mem_addr !=
nullptr);
380 using scalar_t =
typename simd_traits<simd_t>::scalar_type;
382 for (
size_t i = 0; i < simd_traits<simd_t>::length; ++i)
383 *(
static_cast<scalar_t *
>(mem_addr) + i) = simd_vec[i];
387template <simd::simd_concept simd_t>
388 requires detail::is_builtin_simd_v<simd_t> && detail::is_native_builtin_simd_v<simd_t>
389constexpr void store(
void * mem_addr, simd_t
const & simd_vec)
391 assert(mem_addr !=
nullptr);
393 if constexpr (simd_traits<simd_t>::max_length == 16)
394 detail::store_sse4<simd_t>(mem_addr, simd_vec);
395 else if constexpr (simd_traits<simd_t>::max_length == 32)
396 detail::store_avx2<simd_t>(mem_addr, simd_vec);
397 else if constexpr (simd_traits<simd_t>::max_length == 64)
398 detail::store_avx512<simd_t>(mem_addr, simd_vec);
400 static_assert(simd_traits<simd_t>::max_length >= 16 && simd_traits<simd_t>::max_length <= 64,
401 "Unsupported simd type.");
422template <simd::simd_concept simd_t>
423constexpr void transpose(
std::array<simd_t, simd_traits<simd_t>::length> & matrix)
425 detail::transpose(matrix);
430template <simd::simd_concept simd_t>
431 requires detail::is_builtin_simd_v<simd_t> && detail::is_native_builtin_simd_v<simd_t>
432 && (simd_traits<simd_t>::max_length == simd_traits<simd_t>::length)
433constexpr void transpose(
std::array<simd_t, simd_traits<simd_t>::length> & matrix)
435 if constexpr (simd_traits<simd_t>::length == 16)
436 detail::transpose_matrix_sse4(matrix);
437 else if constexpr (simd_traits<simd_t>::length == 32)
438 detail::transpose_matrix_avx2(matrix);
439#if defined(__AVX512BW__)
440 else if constexpr (simd_traits<simd_t>::length == 64)
441 detail::transpose_matrix_avx512(matrix);
444 detail::transpose(matrix);
456template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
457constexpr target_simd_t upcast(source_simd_t
const & src)
460 simd_traits<target_simd_t>::length <= simd_traits<source_simd_t>::length,
461 "The length of the target simd type must be greater or equal than the length of the source simd type.");
464 for (
unsigned i = 0; i < simd_traits<target_simd_t>::length; ++i)
465 tmp[i] =
static_cast<typename simd_traits<target_simd_t>::scalar_type
>(src[i]);
471template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
472 requires detail::is_builtin_simd_v<target_simd_t> && detail::is_builtin_simd_v<source_simd_t>
473 && detail::is_native_builtin_simd_v<source_simd_t>
474constexpr target_simd_t upcast(source_simd_t
const & src)
477 simd_traits<target_simd_t>::length <= simd_traits<source_simd_t>::length,
478 "The length of the target simd type must be greater or equal than the length of the source simd type.");
480 if constexpr (simd_traits<source_simd_t>::length == simd_traits<target_simd_t>::length)
482 static_assert(simd_traits<target_simd_t>::max_length == simd_traits<source_simd_t>::max_length,
483 "Target vector has a different byte size.");
484 return reinterpret_cast<target_simd_t
>(src);
486 else if constexpr (std::signed_integral<typename simd_traits<source_simd_t>::scalar_type>)
488 return detail::upcast_signed<target_simd_t>(src);
492 static_assert(std::unsigned_integral<typename simd_traits<source_simd_t>::scalar_type>,
493 "Expected unsigned scalar type.");
494 return detail::upcast_unsigned<target_simd_t>(src);
Provides seqan3::detail::builtin_simd, seqan3::detail::is_builtin_simd and seqan3::simd::simd_traits<...
@ offset
Sequence (seqan3::field::seq) relative start position (0-based), unsigned value.
seqan::std::views::chunk chunk
A view adaptor that divides a range into chunks. <dl class="no-api">This entity is not part of the Se...
Definition: chunk.hpp:26
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
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.
Provides seqan3::simd::simd_concept.