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)
67 dst[i] = src[i + offset];
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> &&
153 detail::is_native_builtin_simd_v<simd_t>
154constexpr simd_t extract_half(simd_t
const & src)
156 static_assert(index < 2,
"The index must be in the range of [0, 1]");
158 if constexpr (simd_traits<simd_t>::length < 2)
160 else if constexpr (simd_traits<simd_t>::max_length == 16)
161 return detail::extract_half_sse4<index>(src);
162 else if constexpr (simd_traits<simd_t>::max_length == 32)
163 return detail::extract_half_avx2<index>(src);
165 return detail::extract_impl<2>(src, index);
191template <u
int8_t index, simd::simd_concept simd_t>
192constexpr simd_t extract_quarter(simd_t
const & src)
194 static_assert(index < 4,
"The index must be in the range of [0, 1, 2, 3]");
196 return detail::extract_impl<4>(src, index);
200template <u
int8_t index, simd::simd_concept simd_t>
201 requires detail::is_builtin_simd_v<simd_t> &&
202 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);
214 return detail::extract_impl<4>(src, index);
240template <u
int8_t index, simd::simd_concept simd_t>
241constexpr simd_t extract_eighth(simd_t
const & src)
243 return detail::extract_impl<8>(src, index);
247template <u
int8_t index, simd::simd_concept simd_t>
248 requires detail::is_builtin_simd_v<simd_t> &&
249 detail::is_native_builtin_simd_v<simd_t>
250constexpr simd_t extract_eighth(simd_t
const & src)
252 static_assert(index < 8,
"The index must be in the range of [0, 1, 2, 3, 4, 5, 6, 7]");
254 if constexpr (simd_traits<simd_t>::length < 8)
256 else if constexpr (simd_traits<simd_t>::max_length == 16)
257 return detail::extract_eighth_sse4<index>(src);
258 else if constexpr (simd_traits<simd_t>::max_length == 32)
259 return detail::extract_eighth_avx2<index>(src);
261 return detail::extract_impl<8>(src, index);
282template <simd::simd_concept simd_t>
283constexpr simd_t
fill(
typename simd_traits<simd_t>::scalar_type
const scalar)
noexcept
285 constexpr size_t length = simd_traits<simd_t>::length;
298template <simd::simd_concept simd_t>
299constexpr simd_t
iota(
typename simd_traits<simd_t>::scalar_type
const offset)
301 constexpr size_t length = simd_traits<simd_t>::length;
302 using scalar_type =
typename simd_traits<simd_t>::scalar_type;
315template <simd::simd_concept simd_t>
316constexpr simd_t load(
void const * mem_addr)
318 assert(mem_addr !=
nullptr);
321 for (
size_t i = 0; i < simd_traits<simd_t>::length; ++i)
322 tmp[i] = *(
static_cast<typename simd_traits<simd_t>::scalar_type
const *
>(mem_addr) + i);
328template <simd::simd_concept simd_t>
329 requires detail::is_builtin_simd_v<simd_t> &&
330 detail::is_native_builtin_simd_v<simd_t>
331constexpr simd_t load(
void const * mem_addr)
333 assert(mem_addr !=
nullptr);
335 if constexpr (simd_traits<simd_t>::max_length == 16)
336 return detail::load_sse4<simd_t>(mem_addr);
337 else if constexpr (simd_traits<simd_t>::max_length == 32)
338 return detail::load_avx2<simd_t>(mem_addr);
339 else if constexpr (simd_traits<simd_t>::max_length == 64)
340 return detail::load_avx512<simd_t>(mem_addr);
342 static_assert(simd_traits<simd_t>::max_length >= 16 && simd_traits<simd_t>::max_length <= 64,
343 "Unsupported simd type.");
357template <simd::simd_concept simd_t>
358constexpr void store(
void * mem_addr, simd_t
const & simd_vec)
360 assert(mem_addr !=
nullptr);
361 using scalar_t =
typename simd_traits<simd_t>::scalar_type;
363 for (
size_t i = 0; i < simd_traits<simd_t>::length; ++i)
364 *(
static_cast<scalar_t *
>(mem_addr) + i) = simd_vec[i];
368template <simd::simd_concept simd_t>
369 requires detail::is_builtin_simd_v<simd_t> &&
370 detail::is_native_builtin_simd_v<simd_t>
371constexpr void store(
void * mem_addr, simd_t
const & simd_vec)
373 assert(mem_addr !=
nullptr);
375 if constexpr (simd_traits<simd_t>::max_length == 16)
376 detail::store_sse4<simd_t>(mem_addr, simd_vec);
377 else if constexpr (simd_traits<simd_t>::max_length == 32)
378 detail::store_avx2<simd_t>(mem_addr, simd_vec);
379 else if constexpr (simd_traits<simd_t>::max_length == 64)
380 detail::store_avx512<simd_t>(mem_addr, simd_vec);
382 static_assert(simd_traits<simd_t>::max_length >= 16 && simd_traits<simd_t>::max_length <= 64,
383 "Unsupported simd type.");
404template <simd::simd_concept simd_t>
405constexpr void transpose(
std::array<simd_t, simd_traits<simd_t>::length> & matrix)
409 for (
size_t i = 0; i < matrix.size(); ++i)
410 for (
size_t j = 0; j < matrix.size(); ++j)
411 tmp[j][i] = matrix[i][j];
418template <simd::simd_concept simd_t>
419 requires detail::is_builtin_simd_v<simd_t> &&
420 detail::is_native_builtin_simd_v<simd_t> &&
421 (simd_traits<simd_t>::max_length == simd_traits<simd_t>::length)
422constexpr void transpose(
std::array<simd_t, simd_traits<simd_t>::length> & matrix)
424 if constexpr (simd_traits<simd_t>::length == 16)
425 detail::transpose_matrix_sse4(matrix);
426 else if constexpr (simd_traits<simd_t>::length == 32)
427 detail::transpose_matrix_avx2(matrix);
441template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
442constexpr target_simd_t upcast(source_simd_t
const & src)
444 static_assert(simd_traits<target_simd_t>::length <= simd_traits<source_simd_t>::length,
445 "The length of the target simd type must be greater or equal than the length of the source simd type.");
448 for (
unsigned i = 0; i < simd_traits<target_simd_t>::length; ++i)
449 tmp[i] =
static_cast<typename simd_traits<target_simd_t>::scalar_type
>(src[i]);
455template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
456 requires detail::is_builtin_simd_v<target_simd_t> &&
457 detail::is_builtin_simd_v<source_simd_t> &&
458 detail::is_native_builtin_simd_v<source_simd_t>
459constexpr target_simd_t upcast(source_simd_t
const & src)
461 static_assert(simd_traits<target_simd_t>::length <= simd_traits<source_simd_t>::length,
462 "The length of the target simd type must be greater or equal than the length of the source simd type.");
464 if constexpr (simd_traits<source_simd_t>::length == simd_traits<target_simd_t>::length)
466 static_assert(simd_traits<target_simd_t>::max_length == simd_traits<source_simd_t>::max_length,
467 "Target vector has a different byte size.");
468 return reinterpret_cast<target_simd_t
>(src);
470 else if constexpr (std::signed_integral<typename simd_traits<source_simd_t>::scalar_type>)
472 return detail::upcast_signed<target_simd_t>(src);
476 static_assert(std::unsigned_integral<typename simd_traits<source_simd_t>::scalar_type>,
477 "Expected unsigned scalar type.");
478 return detail::upcast_unsigned<target_simd_t>(src);
Provides seqan3::detail::builtin_simd, seqan3::detail::is_builtin_simd and seqan3::simd::simd_traits<...
The <concepts> header from C++20's standard library.
@ offset
Sequence (seqan3::field::seq) relative start position (0-based), unsigned value.
constexpr auto chunk
A chunk view.
Definition: chunk.hpp:29
The main SeqAn3 namespace.
Definition: cigar_operation_table.hpp:2
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.