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_halve(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 simd_traits<simd_t>::max_length == 16
154 constexpr simd_t extract_halve(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)
161 return detail::extract_halve_sse4<index>(src);
187 template <uint8_t index, simd::simd_concept simd_t>
188 constexpr simd_t extract_quarter(simd_t const & src)
190 static_assert(index < 4,
"The index must be in the range of [0, 1, 2, 3]");
192 return detail::extract_impl<4>(src, index);
196 template <u
int8_t index, simd::simd_concept simd_t>
197 requires detail::is_builtin_simd_v<simd_t> &&
198 detail::is_native_builtin_simd_v<simd_t> &&
199 simd_traits<simd_t>::max_length == 16
200 constexpr simd_t extract_quarter(simd_t
const & src)
202 static_assert(index < 4,
"The index must be in the range of [0, 1, 2, 3]");
204 if constexpr (simd_traits<simd_t>::length < 4)
207 return detail::extract_quarter_sse4<index>(src);
233 template <uint8_t index, simd::simd_concept simd_t>
234 constexpr simd_t extract_eighth(simd_t const & src)
236 return detail::extract_impl<8>(src, index);
240 template <u
int8_t index, simd::simd_concept simd_t>
241 requires detail::is_builtin_simd_v<simd_t> &&
242 detail::is_native_builtin_simd_v<simd_t> &&
243 simd_traits<simd_t>::max_length == 16
244 constexpr simd_t extract_eighth(simd_t
const & src)
246 static_assert(index < 8,
"The index must be in the range of [0, 1, 2, 3, 4, 5, 6, 7]");
248 if constexpr (simd_traits<simd_t>::length < 8)
251 return detail::extract_eighth_sse4<index>(src);
260 inline namespace simd
272 template <simd::simd_concept simd_t>
273 constexpr simd_t
fill(
typename simd_traits<simd_t>::scalar_type
const scalar) noexcept
275 constexpr
size_t length = simd_traits<simd_t>::length;
288 template <simd::simd_concept simd_t>
289 constexpr simd_t
iota(
typename simd_traits<simd_t>::scalar_type
const offset)
291 constexpr
size_t length = simd_traits<simd_t>::length;
292 using scalar_type =
typename simd_traits<simd_t>::scalar_type;
305 template <simd::simd_concept simd_t>
306 constexpr simd_t load(
void const * mem_addr)
308 assert(mem_addr !=
nullptr);
311 for (
size_t i = 0; i < simd_traits<simd_t>::length; ++i)
312 tmp[i] = *(
static_cast<typename simd_traits<simd_t>::scalar_type
const *
>(mem_addr) + i);
318 template <simd::simd_concept simd_t>
319 requires detail::is_builtin_simd_v<simd_t> &&
320 detail::is_native_builtin_simd_v<simd_t>
321 constexpr simd_t load(
void const * mem_addr)
323 assert(mem_addr !=
nullptr);
325 if constexpr (simd_traits<simd_t>::max_length == 16)
326 return detail::load_sse4<simd_t>(mem_addr);
327 else if constexpr (simd_traits<simd_t>::max_length == 32)
328 return detail::load_avx2<simd_t>(mem_addr);
329 else if constexpr (simd_traits<simd_t>::max_length == 64)
330 return detail::load_avx512<simd_t>(mem_addr);
332 static_assert(simd_traits<simd_t>::max_length >= 16 && simd_traits<simd_t>::max_length <= 64,
333 "Unsupported simd type.");
354 template <simd::simd_concept simd_t>
355 constexpr
void transpose(
std::array<simd_t, simd_traits<simd_t>::length> & matrix)
359 for (
size_t i = 0; i < matrix.size(); ++i)
360 for (
size_t j = 0; j < matrix.size(); ++j)
361 tmp[j][i] = matrix[i][j];
367 template <simd::simd_concept simd_t>
368 requires detail::is_builtin_simd_v<simd_t> &&
369 detail::is_native_builtin_simd_v<simd_t> &&
370 simd_traits<simd_t>::max_length == 16 &&
371 simd_traits<simd_t>::length == 16
372 constexpr
void transpose(
std::array<simd_t, simd_traits<simd_t>::length> & matrix)
374 detail::transpose_matrix_sse4(matrix);
386 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
387 constexpr target_simd_t upcast(source_simd_t
const & src)
389 static_assert(simd_traits<target_simd_t>::length <= simd_traits<source_simd_t>::length,
390 "The length of the target simd type must be greater or equal than the length of the source simd type.");
393 for (
unsigned i = 0; i < simd_traits<target_simd_t>::length; ++i)
394 tmp[i] =
static_cast<typename simd_traits<target_simd_t>::scalar_type
>(src[i]);
400 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
401 requires detail::is_builtin_simd_v<target_simd_t> &&
402 detail::is_builtin_simd_v<source_simd_t> &&
403 detail::is_native_builtin_simd_v<source_simd_t>
404 constexpr target_simd_t upcast(source_simd_t
const & src)
406 static_assert(simd_traits<target_simd_t>::length <= simd_traits<source_simd_t>::length,
407 "The length of the target simd type must be greater or equal than the length of the source simd type.");
409 if constexpr (simd_traits<source_simd_t>::length == simd_traits<target_simd_t>::length)
411 static_assert(simd_traits<target_simd_t>::max_length == simd_traits<source_simd_t>::max_length,
412 "Target vector has a different byte size.");
413 return reinterpret_cast<target_simd_t
>(src);
417 return detail::upcast_signed<target_simd_t>(src);
422 "Expected unsigned scalar type.");
423 return detail::upcast_unsigned<target_simd_t>(src);
The concept std::unsigned_integral is satisfied if and only if T is an integral type and std::is_sign...
Provides seqan3::simd::simd_concept.
Provides seqan3::simd::simd_traits.
Provides specific algorithm implementations for AVX2 instruction set.
Provides specific algorithm implementations for AVX512 instruction set.
SeqAn specific customisations in the standard namespace.
The main SeqAn3 namespace.
Provides specific algorithm implementations for SSE4 instruction set.
The concept std::signed_integral is satisfied if and only if T is an integral type and std::is_signed...
Definition: aligned_sequence_concept.hpp:36
Sequence (SEQ) relative start position (0-based), unsigned value.
Provides seqan3::detail::builtin_simd, seqan3::detail::is_builtin_simd and seqan3::simd::simd_traits<...