Skip to content

Commit

Permalink
simd_dna4
Browse files Browse the repository at this point in the history
  • Loading branch information
eseiler committed Jun 21, 2022
1 parent b11753c commit 62bcff8
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 228 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

#pragma once

#include <vector>

#include <seqan3/alphabet/nucleotide/nucleotide_base.hpp>

// ------------------------------------------------------------------
Expand All @@ -24,18 +22,13 @@
namespace seqan3
{

class rna4;

class simdifyable_dna4 : public nucleotide_base<simdifyable_dna4, 256>
{
private:
using base_t = nucleotide_base<simdifyable_dna4, 256>;

friend base_t;
//!\cond \brief Befriend seqan3::alphabet_base.
friend base_t::base_t;
//!\endcond
friend rna4;

public:
constexpr simdifyable_dna4() noexcept = default;
Expand All @@ -46,52 +39,58 @@ class simdifyable_dna4 : public nucleotide_base<simdifyable_dna4, 256>
~simdifyable_dna4() noexcept = default;

using base_t::base_t;

template <std::same_as<rna4> t> // template parameter t to accept incomplete type
constexpr simdifyable_dna4(t const & r) noexcept
{
assign_rank(r.to_rank());
}
using base_t::to_rank;
using base_t::assign_rank;

static constexpr uint8_t alphabet_size = 4;

constexpr simdifyable_dna4 & assign_rank(rank_type const c) noexcept
{
base_t::assign_rank(c == 0 ? 'A' : (c == 1 ? 'C' : (c == 2 ? 'G' : 'T')));
return *this;
}

constexpr simdifyable_dna4 & assign_char(char_type const c) noexcept
{
base_t::assign_rank(c);
return *this;
char_type const upper_char = c & 0b0101'1111; // to_upper
rank_type rank = (upper_char == 'T') * 3 + (upper_char == 'G') * 2 + (upper_char == 'C');
return assign_rank(rank);
}

// Faster for single assign_char, slower for auto-vectorized
// constexpr simdifyable_dna4 & assign_char(char_type const c) noexcept
// {
// rank_type rank{static_cast<rank_type>(c)};
// rank |= (rank & 0b0001'0000) >> 1;
// rank += 1u;
// rank >>= 2;
// rank &= 0b0000'0011;
// return assign_rank(rank);
// }

constexpr char_type to_char() const noexcept
{
return base_t::to_rank();
rank_type const rank = to_rank();
switch (rank)
{
case 0u:
return 'A';
case 1u:
return 'C';
case 2u:
return 'G';
default:
return 'T';
}
}

constexpr rank_type to_rank() const noexcept
constexpr simdifyable_dna4 complement() const noexcept
{
char_type c{to_char()};
char_type upper_char = c & 0b0101'1111; // to_upper
rank_type rank{};
rank = (upper_char == 'T') * 3 + (upper_char == 'G') * 2 + (upper_char == 'C');
return rank;
rank_type rank{to_rank()};
rank ^= 0b11;
simdifyable_dna4 ret{};
return ret.assign_rank(rank);
}

constexpr simdifyable_dna4 complement() const noexcept
// For alphabet tests
static constexpr bool char_is_valid(char_type const) noexcept
{
char_type rank{to_char()};
rank ^= rank % 2 ? ('C' ^ 'G') : ('A' ^ 'T');

simdifyable_dna4 ret{};
static_cast<base_t &>(ret).assign_rank(rank);
return ret;
return false;
}
};

using simdifyable_dna4_vector = std::vector<simdifyable_dna4>;

} // namespace seqan3
2 changes: 1 addition & 1 deletion test/performance/alphabet/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ add_subdirectories ()

seqan3_benchmark (alphabet_assign_char_benchmark.cpp)
seqan3_benchmark (alphabet_assign_rank_benchmark.cpp)
seqan3_benchmark (alphabet_complement.cpp)
seqan3_benchmark (alphabet_complement_benchmark.cpp)
seqan3_benchmark (alphabet_to_char_benchmark.cpp)
seqan3_benchmark (alphabet_to_rank_benchmark.cpp)
2 changes: 2 additions & 0 deletions test/performance/alphabet/alphabet_assign_char_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <numeric>

#include <seqan3/alphabet/all.hpp>
#include <seqan3/test/performance/simdifyable_dna4.hpp>
#include <seqan3/test/seqan2.hpp>

#if SEQAN3_HAS_SEQAN2
Expand All @@ -38,6 +39,7 @@ void assign_char(benchmark::State & state)
BENCHMARK_TEMPLATE(assign_char, seqan3::gap);
BENCHMARK_TEMPLATE(assign_char, seqan3::dna4);
BENCHMARK_TEMPLATE(assign_char, seqan3::rna4);
BENCHMARK_TEMPLATE(assign_char, seqan3::simdifyable_dna4);
BENCHMARK_TEMPLATE(assign_char, seqan3::dna5);
BENCHMARK_TEMPLATE(assign_char, seqan3::rna5);
BENCHMARK_TEMPLATE(assign_char, seqan3::dna15);
Expand Down
2 changes: 2 additions & 0 deletions test/performance/alphabet/alphabet_assign_rank_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <cstring>

#include <seqan3/alphabet/all.hpp>
#include <seqan3/test/performance/simdifyable_dna4.hpp>
#include <seqan3/test/seqan2.hpp>

#if SEQAN3_HAS_SEQAN2
Expand Down Expand Up @@ -45,6 +46,7 @@ void assign_rank(benchmark::State & state)
BENCHMARK_TEMPLATE(assign_rank, seqan3::gap);
BENCHMARK_TEMPLATE(assign_rank, seqan3::dna4);
BENCHMARK_TEMPLATE(assign_rank, seqan3::rna4);
BENCHMARK_TEMPLATE(assign_rank, seqan3::simdifyable_dna4);
BENCHMARK_TEMPLATE(assign_rank, seqan3::dna5);
BENCHMARK_TEMPLATE(assign_rank, seqan3::rna5);
BENCHMARK_TEMPLATE(assign_rank, seqan3::dna15);
Expand Down
190 changes: 0 additions & 190 deletions test/performance/alphabet/alphabet_complement.cpp

This file was deleted.

Loading

0 comments on commit 62bcff8

Please sign in to comment.