58template <std::ranges::view urng_t, simd::simd_concept simd_t>
59class view_to_simd :
public std::ranges::view_interface<view_to_simd<urng_t, simd_t>>
63 static_assert(std::ranges::forward_range<urng_t>,
64 "The underlying range must model forward_range.");
65 static_assert(std::ranges::input_range<std::ranges::range_value_t<urng_t>>,
66 "Expects the value type of the underlying range to be an input_range.");
67 static_assert(std::default_initializable<std::ranges::iterator_t<std::ranges::range_value_t<urng_t>>>,
68 "Expects the inner range iterator to be default initializable.");
69 static_assert(std::default_initializable<std::ranges::sentinel_t<std::ranges::range_value_t<urng_t>>>,
70 "Expects the inner range sentinel to be default initializable.");
72 "Expects semi-alphabet as value type of the inner range.");
88 static constexpr bool fast_load = std::ranges::contiguous_range<inner_range_type> &&
89 std::sized_sentinel_for<std::ranges::iterator_t<inner_range_type>,
90 std::ranges::sentinel_t<inner_range_type>> &&
100 static constexpr auto alphabet_size = seqan3::alphabet_size<std::ranges::range_value_t<inner_range_type>>;
129 throw std::invalid_argument{
"The size of the underlying range must be less than or equal to the size of "
130 "the given simd type!"};
134 template <
typename other_urng_t>
136 requires (!std::same_as<std::remove_cvref_t<other_urng_t>,
view_to_simd>) &&
137 (!std::same_as<other_urng_t, urng_t>) &&
138 std::ranges::viewable_range<other_urng_t>
155 constexpr void begin() const noexcept = delete;
158 constexpr
std::default_sentinel_t
end() noexcept
160 return std::default_sentinel;
164 constexpr void end() const noexcept = delete;
168 constexpr
bool empty() const noexcept
175 return std::ranges::empty(rng);
185 constexpr size_t size() const noexcept
190 auto it = std::ranges::max_element(
urng, [] (
auto & lhs,
auto & rhs)
213template <std::ranges::view urng_t, simd::simd_concept simd_t>
250 for (
auto it = std::ranges::begin(this_view.
urng); it != std::ranges::end(this_view.
urng); ++it, ++seq_id)
252 cached_iter[seq_id] = std::ranges::begin(*it);
253 cached_sentinel[seq_id] = std::ranges::end(*it);
263 auto sentinel_it = std::ranges::next(cached_iter[0], cached_sentinel[0]);
266 cached_iter[seq_id] = sentinel_it;
267 cached_sentinel[seq_id] = cached_sentinel[0];
271 final_chunk = all_iterators_reached_sentinel();
284 assert(this_view !=
nullptr);
285 return std::span{this_view->cached_simd_chunks[current_chunk_pos].
begin(),
286 (current_chunk_pos == final_chunk_pos) ? final_chunk_size :
chunk_size};
298 if (current_chunk_pos == final_chunk_pos)
301 current_chunk_pos = 0;
329 constexpr bool operator==(std::default_sentinel_t
const &)
const noexcept
341 constexpr bool operator!=(std::default_sentinel_t
const &)
const noexcept
368 return std::array{simd::upcast<simd_t>(extract_half<0>(
row)),
369 simd::upcast<simd_t>(extract_half<1>(
row))};
373 return std::array{simd::upcast<simd_t>(extract_quarter<0>(
row)),
374 simd::upcast<simd_t>(extract_quarter<1>(
row)),
375 simd::upcast<simd_t>(extract_quarter<2>(
row)),
376 simd::upcast<simd_t>(extract_quarter<3>(
row))};
380 return std::array{simd::upcast<simd_t>(extract_eighth<0>(
row)),
381 simd::upcast<simd_t>(extract_eighth<1>(
row)),
382 simd::upcast<simd_t>(extract_eighth<2>(
row)),
383 simd::upcast<simd_t>(extract_eighth<3>(
row)),
384 simd::upcast<simd_t>(extract_eighth<4>(
row)),
385 simd::upcast<simd_t>(extract_eighth<5>(
row)),
386 simd::upcast<simd_t>(extract_eighth<6>(
row)),
387 simd::upcast<simd_t>(extract_eighth<7>(
row))};
407 auto apply_padding = [
this] (simd_t
const vec)
409 return (vec == simd::fill<simd_t>(
static_cast<uint8_t
>(~0))) ? this_view->padding_simd_vector : vec;
413 for (uint8_t
row = 0; row < static_cast<uint8_t>(
matrix.size()); ++
row)
418 if constexpr (chunked_row.size() == 1)
420 this_view->cached_simd_chunks[0][
row] = apply_padding(std::move(chunked_row[0]));
424 static_assert(chunked_row.size() ==
chunks_per_load,
"Expected chunks_per_load many simd vectors.");
429 this_view->cached_simd_chunks[idx][
row %
chunk_size] = apply_padding(std::move(chunked_row[
chunk]));
444 return get<0>(iterator_sentinel_pair) == get<1>(iterator_sentinel_pair);
461 simd_t simd_column{};
462 for (
size_t idx = 0u; idx <
chunk_size; ++idx)
464 if (cached_iter[idx] == cached_sentinel[idx])
466 simd_column[idx] = this_view->padding_value;
487 template <
typename array_t>
490 size_t max_distance = 0;
491 for (
auto && [it, sent] :
views::zip(iterators_before_update, cached_sentinel))
492 max_distance = std::max<size_t>(std::ranges::distance(it, sent), max_distance);
494 assert(max_distance > 0);
500 final_chunk_size = (max_distance %
chunk_size) + 1;
509 at_end = final_chunk;
537 decltype(cached_iter) iterators_before_update{cached_iter};
539 for (uint8_t sequence_pos = 0; sequence_pos <
chunk_size; ++sequence_pos)
543 uint8_t pos = chunk_pos *
chunk_size + sequence_pos;
544 if (cached_sentinel[sequence_pos] - cached_iter[sequence_pos] >= max_size)
551 matrix[pos] = simd::fill<max_simd_type>(~0);
552 auto & sequence_it = cached_iter[sequence_pos];
553 for (int8_t idx = 0; sequence_it != cached_sentinel[sequence_pos]; ++sequence_it, ++idx)
560 final_chunk = all_iterators_reached_sentinel();
563 update_final_chunk_position(iterators_before_update);
566 split_into_sub_matrices(std::move(
matrix));
575 at_end = final_chunk;
579 decltype(cached_iter) iterators_before_update{cached_iter};
581 this_view->cached_simd_chunks[0][i] = convert_single_column();
583 final_chunk = all_iterators_reached_sentinel();
586 update_final_chunk_position(iterators_before_update);
600 uint8_t current_chunk_pos{0};
602 bool final_chunk{
true};
619template <simd::simd_concept simd_t>
644 template <std::ranges::range urng_t>
647 static_assert(std::ranges::forward_range<urng_t>,
648 "The underlying range in views::to_simd must model std::ranges::forward_range.");
649 static_assert(std::ranges::viewable_range<urng_t>,
650 "The underlying range in views::to_simd must model std::ranges::viewable_range.");
651 static_assert(std::ranges::input_range<std::ranges::range_value_t<urng_t>>,
652 "The value type of the underlying range must model std::ranges::input_range.");
654 "The value type of the inner ranges must model seqan3::semialphabet.");
663 template <std::ranges::range urng_t>
666 static_assert(std::ranges::forward_range<urng_t>,
667 "The underlying range in views::to_simd must model std::ranges::forward_range.");
668 static_assert(std::ranges::viewable_range<urng_t>,
669 "The underlying range in views::to_simd must model std::ranges::viewable_range.");
670 static_assert(std::ranges::input_range<std::ranges::range_value_t<urng_t>>,
671 "The value type of the underlying range must model std::ranges::input_range.");
673 "The value type of the inner ranges must model seqan3::semialphabet.");
679 template <std::ranges::range urng_t>
682 return me(std::forward<urng_t>(urange));
792template <simd::simd_concept simd_t>
Provides seqan3::detail::adaptor_from_functor.
Provides algorithms to modify seqan3::simd::simd_type.
Core alphabet concept and free function/type trait wrappers.
Template for range adaptor closure objects that store arguments and wrap a proto-adaptor.
Definition: adaptor_from_functor.hpp:57
Iterator that transposes the underlying range of ranges and transforms that to SIMD types.
Definition: to_simd.hpp:215
auto unpack(max_simd_type const &row) const
Unpacks one row of the transposed byte matrix using simd instructions.
Definition: to_simd.hpp:364
ptrdiff_t difference_type
The difference type.
Definition: to_simd.hpp:223
constexpr void update_final_chunk_position(array_t const &iterators_before_update) noexcept
Updates the end of the final chunk and sets the index of the final chunk.
Definition: to_simd.hpp:488
constexpr void split_into_sub_matrices(std::array< max_simd_type, simd_traits< max_simd_type >::length > matrix) const
Unpacks the matrix of simd types and caches the respective chunk entries.
Definition: to_simd.hpp:405
constexpr iterator_type & operator=(iterator_type &&)=default
Defaulted.
void pointer
The pointer type.
Definition: to_simd.hpp:222
constexpr void underflow()
Fetches the next available chunk(s).
Definition: to_simd.hpp:504
constexpr value_type operator++(int)
Advances the iterator to the next chunk and returns the previous pointed-to value.
Definition: to_simd.hpp:317
friend constexpr bool operator!=(std::default_sentinel_t const &, iterator_type const &rhs) noexcept
Returns true if iterator did not reach the end yet, otherwise false.
Definition: to_simd.hpp:347
constexpr bool all_iterators_reached_sentinel() const noexcept
Checks if all sequence iterators reached the end.
Definition: to_simd.hpp:438
constexpr simd_t convert_single_column() noexcept
Convert a single column into a simd vector.
Definition: to_simd.hpp:458
constexpr bool operator!=(std::default_sentinel_t const &) const noexcept
Returns true if iterator did not reach the end yet, otherwise false.
Definition: to_simd.hpp:341
~iterator_type()=default
Defaulted.
constexpr iterator_type(iterator_type &&)=default
Defaulted.
constexpr iterator_type()=default
Defaulted.
constexpr reference operator*() const noexcept
Returns a reference to the current chunk of simd vectors.
Definition: to_simd.hpp:282
constexpr iterator_type(view_to_simd &this_view)
Construction from the associated range.
Definition: to_simd.hpp:246
friend constexpr bool operator==(std::default_sentinel_t const &, iterator_type const &rhs) noexcept
Returns true if iterator reached the end, otherwise false.
Definition: to_simd.hpp:335
constexpr iterator_type & operator=(iterator_type const &)=default
Defaulted.
constexpr bool operator==(std::default_sentinel_t const &) const noexcept
Returns true if iterator reached the end, otherwise false.
Definition: to_simd.hpp:329
constexpr iterator_type & operator++()
Advances the iterator to the next chunk.
Definition: to_simd.hpp:294
constexpr iterator_type(iterator_type const &)=default
Defaulted.
Transforms a range of ranges into chunks of seqan3::simd vectors.
Definition: to_simd.hpp:60
constexpr iterator_type begin() noexcept
The iterator to begin of this range.
Definition: to_simd.hpp:149
constexpr bool empty() const noexcept
Checks whether the range is empty.
Definition: to_simd.hpp:168
static constexpr uint8_t chunk_size
The size of one chunk. Equals the number of elements in the simd vector.
Definition: to_simd.hpp:94
scalar_type padding_value
The padding value used to fill the corresponding simd vector element.
Definition: to_simd.hpp:203
constexpr std::default_sentinel_t end() noexcept
A sentinel representing the end of this range.
Definition: to_simd.hpp:158
static constexpr bool fast_load
Check if fast load is enabled.
Definition: to_simd.hpp:88
static constexpr uint8_t total_chunks
The total number of chunks that can be cached.
Definition: to_simd.hpp:98
constexpr view_to_simd(other_urng_t &&urng, scalar_type const padding_value=alphabet_size)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: to_simd.hpp:140
constexpr void end() const noexcept=delete
Const iteration is disabled.
static constexpr uint8_t chunks_per_load
The number of chunks that can be gathered with a single load.
Definition: to_simd.hpp:96
simd_t padding_simd_vector
A cached simd vector with the padding symbol.
Definition: to_simd.hpp:202
std::ranges::range_value_t< urng_t > inner_range_type
The inner range type.
Definition: to_simd.hpp:77
static constexpr auto alphabet_size
The alphabet size.
Definition: to_simd.hpp:100
constexpr view_to_simd()=default
Defaulted.
urng_t urng
The underlying range.
Definition: to_simd.hpp:200
std::array< chunk_type, total_chunks > cached_simd_chunks
The cached chunks of transformed simd vectors.
Definition: to_simd.hpp:201
constexpr void begin() const noexcept=delete
Const iteration is disabled.
simd_type_t< uint8_t, simd_traits< simd_t >::max_length > max_simd_type
The SIMD type with maximal number of lanes for the current arch.
Definition: to_simd.hpp:81
typename simd_traits< simd_t >::scalar_type scalar_type
Definition: to_simd.hpp:79
constexpr size_t size() const noexcept
Returns the size of this range.
Definition: to_simd.hpp:185
Provides various transformation traits used by the range module.
@ row
The corresponding alignment coordinate will be incrementable/decrementable in the row index.
decltype(seqan3::to_rank(std::declval< semi_alphabet_type >())) alphabet_rank_t
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: concept.hpp:166
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:154
constexpr auto to_simd
A view that transforms a range of ranges into chunks of seqan3::simd vectors.
Definition: to_simd.hpp:793
constexpr void transpose(std::array< simd_t, simd_traits< simd_t >::length > &matrix)
Transposes the given simd vector matrix.
Definition: algorithm.hpp:428
typename simd_type< scalar_t, length, simd_backend >::type simd_type_t
Helper type of seqan3::simd::simd_type.
Definition: simd.hpp:59
constexpr bool all_of(unary_predicate_t &&fn)
Tests whether a given predicate evaluates to true for each type in a seqan3::type_list.
Definition: type_list_algorithm.hpp:112
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:151
constexpr auto chunk
A chunk view.
Definition: chunk.hpp:29
constexpr auto zip
A zip view.
Definition: zip.hpp:29
constexpr auto type_reduce
A view adaptor that behaves like std::views::all, but type erases certain ranges.
Definition: type_reduce.hpp:153
Defines the requirements of a matrix (e.g. score matrices, trace matrices).
The basis for seqan3::alphabet, but requires only rank interface (not char).
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
The SeqAn namespace for views.
Definition: char_strictly_to.hpp:22
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: configuration.hpp:429
SeqAn specific customisations in the standard namespace.
The <ranges> header from C++20's standard library.
Provides seqan3::simd::simd_type.
Provides seqan3::simd::simd_traits.
views::to_simd's range adaptor closure object type.
Definition: to_simd.hpp:621
typename simd_traits< simd_t >::scalar_type padding_t
The type of a padding value.
Definition: to_simd.hpp:623
constexpr auto operator()(urng_t &&urange) const noexcept
Call the view's constructor with the underlying std::ranges::viewable_range as argument.
Definition: to_simd.hpp:664
constexpr auto operator()(urng_t &&urange, padding_t const padding_value) const noexcept
Call the view's constructor with the underlying std::ranges::viewable_range as argument.
Definition: to_simd.hpp:645
constexpr friend auto operator|(urng_t &&urange, to_simd_fn const &me)
Overloaded bit-operator to allow chaining with other ranges.
Definition: to_simd.hpp:680
constexpr auto operator()() const noexcept
Returns a range adaptor object.
Definition: to_simd.hpp:634
constexpr auto operator()(padding_t const padding_value) const noexcept
Returns a range adaptor closure object with the given parameter.
Definition: to_simd.hpp:628
seqan3::simd::simd_traits is the trait class that provides uniform interface to the properties of sim...
Definition: simd_traits.hpp:41
Provides type traits for working with templates.
Provides seqan3::views::type_reduce.
Provides seqan3::simd::simd_concept.
Provides seqan3::views::zip.