SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
simd_algorithm_avx2.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 
18 
19 //-----------------------------------------------------------------------------
20 // forward declare avx2 simd algorithms that use avx2 intrinsics
21 //-----------------------------------------------------------------------------
22 
23 namespace seqan3::detail
24 {
28 template <simd::simd_concept simd_t>
29 constexpr simd_t load_avx2(void const * mem_addr);
30 
34 template <simd::simd_concept simd_t>
35 inline void transpose_matrix_avx2(std::array<simd_t, simd_traits<simd_t>::length> & matrix);
36 
40 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
41 constexpr target_simd_t upcast_signed_avx2(source_simd_t const & src);
42 
46 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
47 constexpr target_simd_t upcast_unsigned_avx2(source_simd_t const & src);
48 
52 template <uint8_t index, simd::simd_concept simd_t>
53 constexpr simd_t extract_halve_avx2(simd_t const & src);
54 
58 template <uint8_t index, simd::simd_concept simd_t>
59 constexpr simd_t extract_quarter_avx2(simd_t const & src);
60 
64 template <uint8_t index, simd::simd_concept simd_t>
65 constexpr simd_t extract_eighth_avx2(simd_t const & src);
66 
67 }
68 
69 //-----------------------------------------------------------------------------
70 // implementation
71 //-----------------------------------------------------------------------------
72 
73 #ifdef __AVX2__
74 
75 namespace seqan3::detail
76 {
77 
78 template <simd::simd_concept simd_t>
79 constexpr simd_t load_avx2(void const * mem_addr)
80 {
81  return reinterpret_cast<simd_t>(_mm256_loadu_si256(reinterpret_cast<__m256i const *>(mem_addr)));
82 }
83 
84 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::simd::transpose
85 template <simd::simd_concept simd_t>
86 inline void transpose_matrix_avx2(std::array<simd_t, simd_traits<simd_t>::length> & matrix);
87 
88 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
89 constexpr target_simd_t upcast_signed_avx2(source_simd_t const & src)
90 {
91  __m128i const & tmp = _mm256_castsi256_si128(reinterpret_cast<__m256i const &>(src));
92  if constexpr (simd_traits<source_simd_t>::length == 32) // cast from epi8 ...
93  {
94  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi16
95  return reinterpret_cast<target_simd_t>(_mm256_cvtepi8_epi16(tmp));
96  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi32
97  return reinterpret_cast<target_simd_t>(_mm256_cvtepi8_epi32(tmp));
98  if constexpr (simd_traits<target_simd_t>::length == 4) // to epi64
99  return reinterpret_cast<target_simd_t>(_mm256_cvtepi8_epi64(tmp));
100  }
101  else if constexpr (simd_traits<source_simd_t>::length == 16) // cast from epi16 ...
102  {
103  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi32
104  return reinterpret_cast<target_simd_t>(_mm256_cvtepi16_epi32(tmp));
105  if constexpr (simd_traits<target_simd_t>::length == 4) // to epi64
106  return reinterpret_cast<target_simd_t>(_mm256_cvtepi16_epi64(tmp));
107  }
108  else // cast from epi32 to epi64
109  {
110  static_assert(simd_traits<source_simd_t>::length == 8, "Expected 32 bit scalar type.");
111  return reinterpret_cast<target_simd_t>(_mm256_cvtepi32_epi64(tmp));
112  }
113 }
114 
115 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
116 constexpr target_simd_t upcast_unsigned_avx2(source_simd_t const & src)
117 {
118  __m128i const & tmp = _mm256_castsi256_si128(reinterpret_cast<__m256i const &>(src));
119  if constexpr (simd_traits<source_simd_t>::length == 32) // cast from epi8 ...
120  {
121  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi16
122  return reinterpret_cast<target_simd_t>(_mm256_cvtepu8_epi16(tmp));
123  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi32
124  return reinterpret_cast<target_simd_t>(_mm256_cvtepu8_epi32(tmp));
125  if constexpr (simd_traits<target_simd_t>::length == 4) // to epi64
126  return reinterpret_cast<target_simd_t>(_mm256_cvtepu8_epi64(tmp));
127  }
128  else if constexpr (simd_traits<source_simd_t>::length == 16) // cast from epi16 ...
129  {
130  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi32
131  return reinterpret_cast<target_simd_t>(_mm256_cvtepu16_epi32(tmp));
132  if constexpr (simd_traits<target_simd_t>::length == 4) // to epi64
133  return reinterpret_cast<target_simd_t>(_mm256_cvtepu16_epi64(tmp));
134  }
135  else // cast from epi32 to epi64
136  {
137  static_assert(simd_traits<source_simd_t>::length == 8, "Expected 32 bit scalar type.");
138  return reinterpret_cast<target_simd_t>(_mm256_cvtepu32_epi64(tmp));
139  }
140 }
141 
142 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_halve
143 template <uint8_t index, simd::simd_concept simd_t>
144 constexpr simd_t extract_halve_avx2(simd_t const & src);
145 
146 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_quarter
147 template <uint8_t index, simd::simd_concept simd_t>
148 constexpr simd_t extract_quarter_avx2(simd_t const & src);
149 
150 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_eighth
151 template <uint8_t index, simd::simd_concept simd_t>
152 constexpr simd_t extract_eighth_avx2(simd_t const & src);
153 
154 } // namespace seqan3::detail
155 
156 #endif // __AVX2__
concept.hpp
Provides seqan3::simd::simd_concept.
simd_traits.hpp
Provides seqan3::simd::simd_traits.
builtin_simd_intrinsics.hpp
Provides intrinsics include for builtin simd.
std::array