SeqAn3 3.3.0-rc.1
The Modern C++ library for sequence analysis.
 
Loading...
Searching...
No Matches
simd_find_optimum_policy.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, 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 <type_traits>
16
23
24namespace seqan3::detail
25{
26
38template <simd::simd_concept simd_t>
40{
42 simd_t score_offset{};
48 simd_t last_row_mask{};
49};
50
77template <typename alignment_algorithm_t, simd::simd_concept simd_t>
79{
80private:
83
87 bool test_every_cell{false};
89 bool test_last_row_cell{false};
92
96 constexpr simd_find_optimum_policy() = default;
102
104 template <typename configuration_t>
105 simd_find_optimum_policy(configuration_t const & config)
106 {
107 if constexpr (configuration_t::template exists<align_cfg::method_local>())
108 test_every_cell = true;
109
110 is_global_alignment = configuration_t::template exists<align_cfg::method_global>();
111
112 auto method_global_config = config.get_or(align_cfg::method_global{});
113
114 test_last_row_cell = method_global_config.free_end_gaps_sequence1_trailing || is_global_alignment;
115 test_last_column_cell = method_global_config.free_end_gaps_sequence2_trailing || is_global_alignment;
116 }
118
119protected:
121 template <typename cell_t, typename score_t>
122 constexpr void check_score_of_cell([[maybe_unused]] cell_t const & current_cell,
123 [[maybe_unused]] alignment_algorithm_state<score_t> & state) const noexcept
124 {
125 if (test_every_cell)
126 check_and_update(current_cell, state);
127 }
128
130 template <typename other_alignment_algorithm_t, simd_concept score_t, typename is_local_t>
132
134 template <typename other_alignment_algorithm_t>
136
138 template <typename cell_t, typename score_t>
139 constexpr void
140 check_score_of_last_row_cell([[maybe_unused]] cell_t const & last_row_cell,
141 [[maybe_unused]] alignment_algorithm_state<score_t> & state) const noexcept
142 {
143 // Only search in last row if requested and not done already.}
145 {
147 check_and_update<true>(last_row_cell, state);
148 else
149 check_and_update(last_row_cell, state);
150 }
151 }
152
154 template <typename alignment_column_t, typename score_t>
155 constexpr void
156 check_score_of_cells_in_last_column([[maybe_unused]] alignment_column_t && last_column,
157 [[maybe_unused]] alignment_algorithm_state<score_t> & state) const noexcept
158 {
159 // Only check last cell if not done before.
161 {
162 for (auto && cell : last_column)
163 {
165 check_and_update<false>(cell, state);
166 else
167 check_and_update(cell, state);
168 }
169 }
170 }
171
173 template <typename cell_t, typename score_t>
174 constexpr void check_score_of_last_cell([[maybe_unused]] cell_t const & last_cell,
175 [[maybe_unused]] alignment_algorithm_state<score_t> & state) const noexcept
176 {
177 // Only check last cell if not done before.
179 check_and_update(last_cell, state);
180 }
181
194 template <std::ranges::forward_range sequence1_collection_t,
195 std::ranges::forward_range sequence2_collection_t,
196 arithmetic score_t>
197 void initialise_find_optimum_policy([[maybe_unused]] sequence1_collection_t && sequence1_collection,
198 [[maybe_unused]] sequence2_collection_t && sequence2_collection,
199 [[maybe_unused]] score_t const padding_score)
200 {
202 {
203 assert(std::ranges::distance(sequence1_collection) == std::ranges::distance(sequence2_collection));
204
205 constexpr size_t simd_size = simd_traits<simd_t>::length;
206 // First get global size.
207 std::array<size_t, simd_size> sequence1_sizes{};
208 std::array<size_t, simd_size> sequence2_sizes{};
209
210 std::ptrdiff_t max_sequence1_size{};
211 std::ptrdiff_t max_sequence2_size{};
212
213 size_t array_index{};
214 for (auto && [sequence1, sequence2] : views::zip(sequence1_collection, sequence2_collection))
215 {
216 sequence1_sizes[array_index] = std::ranges::distance(sequence1);
217 sequence2_sizes[array_index] = std::ranges::distance(sequence2);
218 max_sequence1_size = std::max<std::ptrdiff_t>(sequence1_sizes[array_index], max_sequence1_size);
219 max_sequence2_size = std::max<std::ptrdiff_t>(sequence2_sizes[array_index], max_sequence2_size);
220 ++array_index;
221 }
222
223 // The global diagonal ending in the sink of the outer alignment matrix.
224 std::ptrdiff_t global_diagonal = max_sequence1_size - max_sequence2_size;
225
226 for (size_t simd_index = 0; simd_index < simd_size; ++simd_index)
227 {
228 if (std::ptrdiff_t local_diagonal = sequence1_sizes[simd_index] - sequence2_sizes[simd_index];
229 local_diagonal < global_diagonal)
230 { // optimum is stored in last row.
231 this->last_row_mask[simd_index] = max_sequence1_size - (global_diagonal - local_diagonal);
232 this->last_column_mask[simd_index] = max_sequence2_size + 1;
233 this->coordinate_offset[simd_index] = max_sequence2_size - sequence2_sizes[simd_index];
234 this->score_offset[simd_index] = padding_score * this->coordinate_offset[simd_index];
235 }
236 else // optimum is stored in last column
237 {
238 this->last_column_mask[simd_index] = max_sequence2_size - (local_diagonal - global_diagonal);
239 this->last_row_mask[simd_index] = max_sequence1_size + 1;
240 this->coordinate_offset[simd_index] = max_sequence1_size - sequence1_sizes[simd_index];
241 this->score_offset[simd_index] = padding_score * this->coordinate_offset[simd_index];
242 }
243 }
244 }
245 // else no-op
246 }
247
248private:
257 template <typename cell_t, typename score_t>
258 constexpr void check_and_update(cell_t const & cell, alignment_algorithm_state<score_t> & state) const noexcept
259 {
260 assert(!is_global_alignment); // This function should not be called for the global alignment.
261
262 auto const & [score_cell, trace_cell] = cell;
263 state.optimum.update_if_new_optimal_score(score_cell.current,
264 column_index_type{trace_cell.coordinate.first},
265 row_index_type{trace_cell.coordinate.second});
266 }
267
284 template <bool in_last_row, typename cell_t, typename score_t>
285 constexpr void check_and_update(cell_t const & cell, alignment_algorithm_state<score_t> & state) const noexcept
286 {
287 assert(is_global_alignment); // This function should only be called for the global alignment.
288
289 using simd_mask_t = typename simd_traits<simd_t>::mask_type;
290 auto const & [score_cell, trace_cell] = cell;
291 simd_t column_positions = simd::fill<simd_t>(trace_cell.coordinate.first);
292 simd_t row_positions = simd::fill<simd_t>(trace_cell.coordinate.second);
293
294 simd_mask_t mask{};
295
296 if constexpr (in_last_row) // Check if column was masked
297 mask = (column_positions == this->last_row_mask);
298 else // Check if row was masked
299 mask = (row_positions == this->last_column_mask);
300
301 // In global alignment we are only interested in the position not the max of the scores.
302 // In addition, the scores need to be corrected in order to track the right score.
303 state.optimum.score = mask ? score_cell.current - this->score_offset : state.optimum.score;
304 state.optimum.column_index = mask ? column_positions - this->coordinate_offset : state.optimum.column_index;
305 state.optimum.row_index = mask ? row_positions - this->coordinate_offset : state.optimum.row_index;
306 }
307};
308
309} // namespace seqan3::detail
Provides seqan3::detail::alignment_algorithm_state.
Provides seqan3::detail::alignment_optimum.
Sets the global alignment method.
Definition: align_config_method.hpp:122
The CRTP-policy that implements the initialisation of the dynamic programming matrix with affine gaps...
Definition: affine_gap_init_policy.hpp:37
The CRTP-policy that computes a batch of cells in the alignment matrix using simd instructions.
Definition: simd_affine_gap_policy.hpp:54
The CRTP-policy to determine the optimum of the dynamic programming matrix.
Definition: simd_find_optimum_policy.hpp:79
constexpr void check_score_of_cells_in_last_column(alignment_column_t &&last_column, alignment_algorithm_state< score_t > &state) const noexcept
Checks all cells of the last alignment column for a new alignment optimum.
Definition: simd_find_optimum_policy.hpp:156
~simd_find_optimum_policy()=default
Defaulted.
constexpr simd_find_optimum_policy & operator=(simd_find_optimum_policy &&)=default
Defaulted.
constexpr void check_and_update(cell_t const &cell, alignment_algorithm_state< score_t > &state) const noexcept
Tests if the score in the current cell is greater than the current alignment optimum.
Definition: simd_find_optimum_policy.hpp:258
constexpr simd_find_optimum_policy & operator=(simd_find_optimum_policy const &)=default
Defaulted.
constexpr void check_score_of_last_cell(cell_t const &last_cell, alignment_algorithm_state< score_t > &state) const noexcept
Checks if the last cell of the alignment matrix is a new optimum in the alignment.
Definition: simd_find_optimum_policy.hpp:174
constexpr simd_find_optimum_policy(simd_find_optimum_policy &&)=default
Defaulted.
constexpr simd_find_optimum_policy(simd_find_optimum_policy const &)=default
Defaulted.
void initialise_find_optimum_policy(sequence1_collection_t &&sequence1_collection, sequence2_collection_t &&sequence2_collection, score_t const padding_score)
Initialises the global alignment state for the current batch of sequences.
Definition: simd_find_optimum_policy.hpp:197
friend alignment_algorithm_t
Befriends the derived class to grant it access to the private members.
Definition: simd_find_optimum_policy.hpp:82
constexpr void check_score_of_cell(cell_t const &current_cell, alignment_algorithm_state< score_t > &state) const noexcept
Checks if a given cell is a new optimum in the alignment.
Definition: simd_find_optimum_policy.hpp:122
bool test_every_cell
Whether every cell of the alignment matrix shall be tracked.
Definition: simd_find_optimum_policy.hpp:87
constexpr void check_and_update(cell_t const &cell, alignment_algorithm_state< score_t > &state) const noexcept
Tests if the current row, respectively column, is part of a global alignment to track.
Definition: simd_find_optimum_policy.hpp:285
bool test_last_column_cell
Whether cells of the last column shall be tracked.
Definition: simd_find_optimum_policy.hpp:91
simd_find_optimum_policy(configuration_t const &config)
Initialise the policy.
Definition: simd_find_optimum_policy.hpp:105
constexpr void check_score_of_last_row_cell(cell_t const &last_row_cell, alignment_algorithm_state< score_t > &state) const noexcept
Checks if a cell in the last row of the alignment matrix is a new optimum in the alignment.
Definition: simd_find_optimum_policy.hpp:140
constexpr simd_find_optimum_policy()=default
Defaulted.
bool test_last_row_cell
Whether cells of the last row shall be tracked.
Definition: simd_find_optimum_policy.hpp:89
bool is_global_alignment
A flag to check if global alignment is computed.
Definition: simd_find_optimum_policy.hpp:85
Implementation of a masked alphabet to be used for tuple composites..
Definition: mask.hpp:38
Provides seqan3::detail::empty_type.
Provides seqan3::detail::find_optimum_policy.
constexpr auto zip
A view adaptor that takes several views and returns tuple-like values from every i-th element of each...
Definition: zip.hpp:573
A type that satisfies std::is_arithmetic_v<t>.
Refines the seqan3::simd::simd_concept requiring the underlying scalar type to model std::integral.
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
Local state for the standard alignment algorithm.
Definition: alignment_algorithm_state.hpp:35
A strong type for designated initialisation of the column index of a matrix.
Definition: matrix_coordinate.hpp:32
A strong type for designated initialisation of the row index of a matrix.
Definition: matrix_coordinate.hpp:61
A state that is only used for global alignments.
Definition: simd_find_optimum_policy.hpp:40
simd_t coordinate_offset
A coordinate offset that needs to be subtracted for every alignment to get the correct end position.
Definition: simd_find_optimum_policy.hpp:44
simd_t score_offset
The score offset that needs to be subtracted for every alignment to get the correct result.
Definition: simd_find_optimum_policy.hpp:42
simd_t last_row_mask
A mask vector storing the column indices for alignments that end in the last row of the global matrix...
Definition: simd_find_optimum_policy.hpp:48
simd_t last_column_mask
A mask vector storing the row indices for alignments that end in the last column of the global matrix...
Definition: simd_find_optimum_policy.hpp:46
seqan3::simd::simd_traits is the trait class that provides uniform interface to the properties of sim...
Definition: simd_traits.hpp:41
Provides seqan3::simd::simd_concept.
Provides seqan3::views::zip.