SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
Views

SIMD related views. More...

+ Collaboration diagram for Views:

Classes

class  seqan3::detail::counted_simd_iterator< index_simd_t >
 Implements a special version of a counted iterator over a simd vector. More...
 
class  seqan3::detail::iota_simd_view< index_simd_t >
 The simd iota view. More...
 
struct  seqan3::detail::iota_simd_view_fn< index_simd_t >
 The view adaptor returning the seqan3::detail::iota_simd_view. More...
 
struct  seqan3::detail::to_simd_fn< simd_t >
 views::to_simd's range adaptor closure object type. More...
 
class  seqan3::detail::view_to_simd< urng_t, simd_t >
 Transforms a range of ranges into chunks of seqan3::simd vectors. More...
 

Variables

template<simd_concept index_simd_t>
constexpr detail::iota_simd_view_fn< index_simd_t > seqan3::views::iota_simd
 An iota view over a simd vector.
 
template<simd::simd_concept simd_t>
constexpr auto seqan3::views::to_simd
 A view that transforms a range of ranges into chunks of seqan3::simd vectors.
 

Detailed Description

SIMD related views.

See also
SIMD

Variable Documentation

◆ iota_simd

template<simd_concept index_simd_t>
constexpr detail::iota_simd_view_fn<index_simd_t> seqan3::views::iota_simd
inlineconstexpr

An iota view over a simd vector.

Template Parameters
index_simd_tThe represented index type; must model seqan3::simd::simd_concept.

This view is an equivalent implementation to:

// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: CC0-1.0
#include <ranges>
// The simd type with 8 unsigned shorts.
int main()
{
// Generate ascending simd index using a iota view in combination with a transform view.
auto simd_iota_view = std::views::iota(0, 10)
| std::views::transform(
[](uint16_t const idx)
{
return seqan3::simd::fill<uint16x8_t>(idx);
});
for (auto && simd_id : simd_iota_view)
seqan3::debug_stream << simd_id << '\n'; // [0, 0, ..., 0], [1, 1, ..., 1], ... [9, 9, ..., 9]
return 0;
}
Provides seqan3::debug_stream and related types.
Provides seqan3::debug_stream overload for seqan3::simd::simd_type.
debug_stream_type debug_stream
A global instance of seqan3::debug_stream_type.
Definition debug_stream.hpp:37
typename simd_type< scalar_t, length, simd_backend >::type simd_type_t
Helper type of seqan3::simd::simd_type.
Definition simd.hpp:56
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
Meta-header for the Utility / SIMD submodule .

However, benchmarks showed that increasing a simd vector is faster than constructing it every time (up-to 2x speed-up). This speed-up justifies an own class that does this task more efficiently.

This view is a lightweight wrapper around a seqan3::detail::counted_simd_iterator pair. Note the regular std::views::iota view cannot be used with two simd types:

std::views::iota(simd_begin, simd_end);

because the return type of the comparison of two simd vector types is not convertible to bool.

View properties

Concepts and traits rrng_t (returned range type)
std::ranges::input_range guaranteed
std::ranges::forward_range guaranteed
std::ranges::bidirectional_range lost
std::ranges::random_access_range lost
std::ranges::contiguous_range lost
std::ranges::viewable_range guaranteed
std::ranges::view guaranteed
std::ranges::sized_range guaranteed
std::ranges::common_range guaranteed
std::ranges::output_range lost
std::ranges::borrowed_range guaranteed
seqan3::const_iterable_range guaranteed
std::ranges::range_reference_t index_simd_t

This is a source view. For more details, see views.

Example

// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: CC0-1.0
// The simd type with 8 unsigned shorts.
int main()
{
// Generate ascending simd index.
for (auto && simd_id : seqan3::views::iota_simd<uint16x8_t>(0, 10))
seqan3::debug_stream << simd_id << '\n'; // [0, 0, ..., 0], [1, 1, ..., 1], ... [9, 9, ..., 9]
return 0;
}
constexpr detail::iota_simd_view_fn< index_simd_t > iota_simd
An iota view over a simd vector.
Definition iota_simd.hpp:271

◆ to_simd

template<simd::simd_concept simd_t>
constexpr auto seqan3::views::to_simd
inlineconstexpr

A view that transforms a range of ranges into chunks of seqan3::simd vectors.

Template Parameters
urng_tThe type of the range being processed.
simd_tThe target simd vector type.
Parameters
[in]urangeThe range being processed.
[in]paddingAn optional padding value.
Returns
A range of ranges with the original sequences transformed into simd vectors.

Header File

#include <seqan3/utility/simd/views/to_simd.hpp>

This view can be used to transform a collection of sequences into chunks of simd vectors. This transformation is also known as Array-of-Structure to Structure-of-Array transformation. It is used to transform the memory layout of the sequences to a more efficient form when used in vectorised algorithms. The number of sequences contained in the range to be transformed cannot be larger than the number of elements stored in the target simd vector, i.e. the size of urange <= simd_traits<simd_t>::length. After applying the transformation one column of the outer range is transposed into a simd vector. This means that the characters of all sequences at a given position x are stored in a simd vector retaining the original order. The returned range itself is a range-of-ranges. When dereferencing the iterator a std::span over a std::array with at most simd length many vectors is returned. If a sequence is empty or ends before the largest sequence in the collection, it can be padded with an optional value.

View properties

Concepts and traits urng_t (underlying range type) rrng_t (returned range type)
std::ranges::input_range required preserved
std::ranges::forward_range required lost
std::ranges::bidirectional_range lost
std::ranges::random_access_range lost
std::ranges::contiguous_range lost
std::ranges::viewable_range required guaranteed
std::ranges::view guaranteed
std::ranges::sized_range preserved (iff std::ranges::sized_range<std::ranges::range_value_t<urng_t>> is true)
std::ranges::common_range lost
std::ranges::output_range lost
seqan3::const_iterable_range lost
std::ranges::range_reference_t std::span<simd_t>
  • urng_t is the type of the range modified by this view (input).
  • the expression std::ranges::input_range<std::ranges::range_value_t<urng_t> must evaluate to true
  • the expression std::default_initializable<std::ranges::range_value_t<urng_t>> must evaluate to true
  • the expression semialphabet<std::ranges::range_value_t<std::ranges::range_value_t<urng_t>>> must evaluate to true
  • rrng_type is the type of the range returned by this view.
  • for more details, see views.

Example

// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: CC0-1.0
#include <vector>
int main()
{
using namespace seqan3::literals;
// Adds 7 sequences. The eighth will be set to a default value.
batch.push_back("ACGTACGTACGTACGATCG"_dna4);
batch.push_back("AGTGAGCTACGGACTAGCTACGACT"_dna4);
batch.push_back("GACTAGCACGAGCGAGATCG"_dna4);
batch.push_back("GGATCGACGGACTAGC"_dna4);
batch.push_back("ACGTACGACGGACGTACGAGCGAGCTACGAGC"_dna4);
batch.push_back("ACGATCGACGACTAGCGAC"_dna4);
batch.push_back("GTACGGATGGTAAACCGCACAT"_dna4);
// Applies lazy transformation using `8` as a padding symbol if a sequence ends early.
auto to_soa = batch | seqan3::views::to_simd<uint16x8_t>(8);
size_t chunk_count = 0;
for (auto && chunk : to_soa)
{
seqan3::debug_stream << "Chunk " << chunk_count++ << ":\n";
for (auto & vec : chunk)
seqan3::debug_stream << vec << '\n';
}
return 0;
}
Provides seqan3::dna4, container aliases and string literals.
seqan::stl::views::chunk chunk
A view adaptor that divides a range into chunks. <dl class="no-api">This entity is not part of the Se...
Definition chunk.hpp:23
The SeqAn namespace for literals.
T push_back(T... args)

The output is as follows:

Chunk 0:
[0,0,2,2,0,0,2,8]
[1,2,0,2,1,1,3,8]
[2,3,1,0,2,2,0,8]
[3,2,3,3,3,0,1,8]
[0,0,0,1,0,3,2,8]
[1,2,2,2,1,1,2,8]
[2,1,1,0,2,2,0,8]
[3,3,0,1,0,0,3,8]
Chunk 1:
[0,0,1,2,1,1,2,8]
[1,1,2,2,2,2,2,8]
[2,2,0,0,2,0,3,8]
[3,2,2,1,0,1,0,8]
[0,0,1,3,1,3,0,8]
[1,1,2,0,2,0,0,8]
[2,3,0,2,3,2,1,8]
[0,0,2,1,0,1,1,8]
Chunk 2:
[3,2,0,8,1,2,2,8]
[1,1,3,8,2,0,1,8]
[2,3,1,8,0,1,0,8]
[8,0,2,8,2,8,1,8]
[8,1,8,8,1,8,0,8]
[8,2,8,8,2,8,3,8]
[8,0,8,8,0,8,8,8]
[8,1,8,8,2,8,8,8]
Chunk 3:
[8,3,8,8,1,8,8,8]
[8,8,8,8,3,8,8,8]
[8,8,8,8,0,8,8,8]
[8,8,8,8,1,8,8,8]
[8,8,8,8,2,8,8,8]
[8,8,8,8,0,8,8,8]
[8,8,8,8,2,8,8,8]
[8,8,8,8,1,8,8,8]
Hide me