SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
policy_optimum_tracker_simd.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
15 #include <limits>
16 #include <seqan3/std/ranges>
17 
24 
25 namespace seqan3::detail
26 {
27 
44 struct max_score_updater_simd_global
45 {
46 
63  template <typename score_t, typename coordinate_t>
65  requires (std::assignable_from<score_t &, score_t const &> &&
66  requires (coordinate_t coordinate)
67  {
68  requires simd_concept<decltype(coordinate.col)>;
69  requires simd_concept<decltype(coordinate.row)>;
70  })
72  void operator()(score_t & optimal_score,
73  coordinate_t const & optimal_coordinate,
74  score_t current_score,
75  coordinate_t const & current_coordinate) const noexcept
76  {
77  auto mask = (optimal_coordinate.col == current_coordinate.col) &&
78  (optimal_coordinate.row == current_coordinate.row);
79  optimal_score = (mask) ? std::move(current_score) : optimal_score;
80  }
81 };
82 
87 template <typename alignment_configuration_t, std::semiregular optimum_updater_t>
89  requires is_type_specialisation_of_v<alignment_configuration_t, configuration> &&
90  std::invocable<optimum_updater_t,
91  typename alignment_configuration_traits<alignment_configuration_t>::score_type &,
92  typename alignment_configuration_traits<alignment_configuration_t>::matrix_coordinate_type &,
93  typename alignment_configuration_traits<alignment_configuration_t>::score_type,
94  typename alignment_configuration_traits<alignment_configuration_t>::matrix_coordinate_type>
96 class policy_optimum_tracker_simd :
97  protected policy_optimum_tracker<alignment_configuration_t, optimum_updater_t>
98 {
99 protected:
101  using base_policy_t = policy_optimum_tracker<alignment_configuration_t, optimum_updater_t>;
102 
103  // Import the configured score type.
104  using typename base_policy_t::traits_type;
105  using typename base_policy_t::score_type;
106 
108  using scalar_type = typename simd::simd_traits<score_type>::scalar_type;
110  using original_score_type = typename traits_type::original_score_type;
111 
112  static_assert(simd_concept<score_type>, "Must be a simd type!");
113 
114  // Import base variables into class scope.
115  using base_policy_t::compare_and_set_optimum;
116  using base_policy_t::optimal_score;
117  using base_policy_t::optimal_coordinate;
120 
124  policy_optimum_tracker_simd() = default;
125  policy_optimum_tracker_simd(policy_optimum_tracker_simd const &) = default;
126  policy_optimum_tracker_simd(policy_optimum_tracker_simd &&) = default;
127  policy_optimum_tracker_simd & operator=(policy_optimum_tracker_simd const &) = default;
128  policy_optimum_tracker_simd & operator=(policy_optimum_tracker_simd &&) = default;
129  ~policy_optimum_tracker_simd() = default;
130 
139  policy_optimum_tracker_simd(alignment_configuration_t const & config) : base_policy_t{config}
140  {
141  base_policy_t::test_last_row_cell = true;
142  base_policy_t::test_last_column_cell = true;
143  }
145 
147  void reset_optimum()
148  {
149  optimal_score = simd::fill<score_type>(std::numeric_limits<scalar_type>::lowest());
150  }
151 
198  template <std::ranges::input_range sequence1_collection_t, std::ranges::input_range sequence2_collection_t>
199  void initialise_tracker(sequence1_collection_t & sequence1_collection,
200  sequence2_collection_t & sequence2_collection)
201  {
202  using index_t = typename traits_type::matrix_index_type;
203  using scalar_index_t = typename simd_traits<index_t>::scalar_type;
204 
205  scalar_index_t largest_sequence1_size{};
206  scalar_index_t largest_sequence2_size{};
207  alignas(alignof(index_t)) std::array<scalar_index_t, traits_type::alignments_per_vector> sequence1_sizes{};
208  alignas(alignof(index_t)) std::array<scalar_index_t, traits_type::alignments_per_vector> sequence2_sizes{};
209 
210  // First, get all dimensions from the sequences and keep track of the maximal size in either dimension.
211  size_t sequence_count{};
212  for (auto && [sequence1, sequence2] : views::zip(sequence1_collection, sequence2_collection))
213  {
214  sequence1_sizes[sequence_count] = std::ranges::distance(sequence1);
215  sequence2_sizes[sequence_count] = std::ranges::distance(sequence2);
216  largest_sequence1_size = std::max(largest_sequence1_size, sequence1_sizes[sequence_count]);
217  largest_sequence2_size = std::max(largest_sequence2_size, sequence2_sizes[sequence_count]);
218  ++sequence_count;
219  }
220 
221  // Second, determine the offset for each individual end-coordinate which is used to project the cell to the
222  // last row or column of the global alignment matrix. Choose the smallest distance as the correct offset
223  // to the projected cell.
224  for (size_t index = 0; index != sequence_count; ++index)
225  {
226  assert(sequence1_sizes[index] <= largest_sequence1_size);
227  assert(sequence2_sizes[index] <= largest_sequence2_size);
228 
229  padding_offsets[index] = std::min(largest_sequence1_size - sequence1_sizes[index],
230  largest_sequence2_size - sequence2_sizes[index]);
231  sequence1_sizes[index] += padding_offsets[index];
232  sequence2_sizes[index] += padding_offsets[index];
233  }
234 
235  // Load the target coordinate indices from the respective arrays.
236  optimal_coordinate.col = simd::load<index_t>(sequence1_sizes.data());
237  optimal_coordinate.row = simd::load<index_t>(sequence2_sizes.data());
238  }
239 };
240 } // namespace seqan3::detail
zip.hpp
Provides seqan3::views::zip.
policy_optimum_tracker.hpp
Provides seqan3::detail::policy_optimum_tracker.
simd_algorithm.hpp
Provides algorithms to modify seqan3::simd::simd_type.
simd.hpp
Provides seqan3::simd::simd_type.
seqan3::views::move
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
simd_traits.hpp
Provides seqan3::simd::simd_traits.
std::array
std::min
T min(T... args)
ranges
Adaptations of concepts from the Ranges TS.
limits
std::max
T max(T... args)
std::numeric_limits
lazy.hpp
Provides lazy template instantiation traits.