SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
simd_algorithm_avx512.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 <array>
16 
21 
22 //-----------------------------------------------------------------------------
23 // forward declare avx512 simd algorithms that use avx512 intrinsics
24 //-----------------------------------------------------------------------------
25 
26 namespace seqan3::detail
27 {
31 template <simd::simd_concept simd_t>
32 constexpr simd_t load_avx512(void const * mem_addr);
33 
37 template <simd::simd_concept simd_t>
39 
43 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
44 constexpr target_simd_t upcast_signed_avx512(source_simd_t const & src);
45 
49 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
50 constexpr target_simd_t upcast_unsigned_avx512(source_simd_t const & src);
51 
55 template <uint8_t index, simd::simd_concept simd_t>
56 constexpr simd_t extract_half_avx512(simd_t const & src);
57 
61 template <uint8_t index, simd::simd_concept simd_t>
62 constexpr simd_t extract_quarter_avx512(simd_t const & src);
63 
67 template <uint8_t index, simd::simd_concept simd_t>
68 constexpr simd_t extract_eighth_avx512(simd_t const & src);
69 
70 }
71 
72 //-----------------------------------------------------------------------------
73 // implementation
74 //-----------------------------------------------------------------------------
75 
76 #ifdef __AVX512F__
77 
78 namespace seqan3::detail
79 {
80 
81 template <simd::simd_concept simd_t>
82 constexpr simd_t load_avx512(void const * mem_addr)
83 {
84  return reinterpret_cast<simd_t>(_mm512_loadu_si512(mem_addr));
85 }
86 
87 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::simd::transpose
88 template <simd::simd_concept simd_t>
89 inline void transpose_matrix_avx512(std::array<simd_t, simd_traits<simd_t>::length> & matrix);
90 
91 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
92 constexpr target_simd_t upcast_signed_avx512(source_simd_t const & src)
93 {
94  __m512i const & tmp = reinterpret_cast<__m512i const &>(src);
95  if constexpr (simd_traits<source_simd_t>::length == 64) // cast from epi8 ...
96  {
97  if constexpr (simd_traits<target_simd_t>::length == 32) // to epi16
98  return reinterpret_cast<target_simd_t>(_mm512_cvtepi8_epi16(_mm512_castsi512_si256(tmp)));
99  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
100  return reinterpret_cast<target_simd_t>(_mm512_cvtepi8_epi32(_mm512_castsi512_si128(tmp)));
101  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
102  return reinterpret_cast<target_simd_t>(_mm512_cvtepi8_epi64(_mm512_castsi512_si128(tmp)));
103  }
104  else if constexpr (simd_traits<source_simd_t>::length == 32) // cast from epi16 ...
105  {
106  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
107  return reinterpret_cast<target_simd_t>(_mm512_cvtepi16_epi32(_mm512_castsi512_si256(tmp)));
108  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
109  return reinterpret_cast<target_simd_t>(_mm512_cvtepi16_epi64(_mm512_castsi512_si128(tmp)));
110  }
111  else // cast from epi32 to epi64
112  {
113  static_assert(simd_traits<source_simd_t>::length == 16, "Expected 32 bit scalar type.");
114  return reinterpret_cast<target_simd_t>(_mm512_cvtepi32_epi64(_mm512_castsi512_si256(tmp)));
115  }
116 }
117 
118 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
119 constexpr target_simd_t upcast_unsigned_avx512(source_simd_t const & src)
120 {
121  __m512i const & tmp = reinterpret_cast<__m512i const &>(src);
122  if constexpr (simd_traits<source_simd_t>::length == 64) // cast from epi8 ...
123  {
124  if constexpr (simd_traits<target_simd_t>::length == 32) // to epi16
125  return reinterpret_cast<target_simd_t>(_mm512_cvtepu8_epi16(_mm512_castsi512_si256(tmp)));
126  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
127  return reinterpret_cast<target_simd_t>(_mm512_cvtepu8_epi32(_mm512_castsi512_si128(tmp)));
128  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
129  return reinterpret_cast<target_simd_t>(_mm512_cvtepu8_epi64(_mm512_castsi512_si128(tmp)));
130  }
131  else if constexpr (simd_traits<source_simd_t>::length == 32) // cast from epi16 ...
132  {
133  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
134  return reinterpret_cast<target_simd_t>(_mm512_cvtepu16_epi32(_mm512_castsi512_si256(tmp)));
135  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
136  return reinterpret_cast<target_simd_t>(_mm512_cvtepu16_epi64(_mm512_castsi512_si128(tmp)));
137  }
138  else // cast from epi32 to epi64
139  {
140  static_assert(simd_traits<source_simd_t>::length == 16, "Expected 32 bit scalar type.");
141  return reinterpret_cast<target_simd_t>(_mm512_cvtepu32_epi64(_mm512_castsi512_si256(tmp)));
142  }
143 }
144 
145 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_half
146 template <uint8_t index, simd::simd_concept simd_t>
147 constexpr simd_t extract_half_avx512(simd_t const & src);
148 
149 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_quarter
150 template <uint8_t index, simd::simd_concept simd_t>
151 constexpr simd_t extract_quarter_avx512(simd_t const & src);
152 
153 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_eighth
154 template <uint8_t index, simd::simd_concept simd_t>
155 constexpr simd_t extract_eighth_avx512(simd_t const & src);
156 
157 } // namespace seqan3::detail
158 
159 #endif // __AVX512F__
Defines the requirements of a matrix (e.g. score matrices, trace matrices).
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
void transpose_matrix_avx512(std::array< simd_t, simd_traits< simd_t >::length > &matrix)
Transposes the given simd vector matrix.
constexpr simd_t extract_half_avx512(simd_t const &src)
Extracts one half of the given simd vector and stores the result in the lower half of the target vect...
constexpr simd_t load_avx512(void const *mem_addr)
Load simd_t size bits of integral data from memory.
constexpr target_simd_t upcast_signed_avx512(source_simd_t const &src)
Upcasts the given vector into the target vector using signed extension of packed values.
constexpr simd_t extract_quarter_avx512(simd_t const &src)
Extracts one quarter of the given simd vector and stores it in the lower quarter of the target vector...
constexpr target_simd_t upcast_unsigned_avx512(source_simd_t const &src)
Upcasts the given vector into the target vector using unsigned extension of packed values.
constexpr simd_t extract_eighth_avx512(simd_t const &src)
Extracts one eighth of the given simd vector and stores it in the lower eighth of the target vector.
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::detail::builtin_simd, seqan3::detail::is_builtin_simd and seqan3::simd::simd_traits<...
Provides intrinsics include for builtin simd.
Provides seqan3::simd::simd_traits.